Skip to content

Commit

Permalink
Stop supporting SLR(1) and always use LALR(1)
Browse files Browse the repository at this point in the history
  • Loading branch information
nihei9 committed May 22, 2022
1 parent 24fd805 commit b5ad1d3
Show file tree
Hide file tree
Showing 20 changed files with 67 additions and 1,182 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# vartan

vartan is a parser generator for golang and supports LALR(1) and SLR(1). vartan also provides a command to perform syntax analysis to allow easy debugging of your grammar.
vartan is an LALR(1) parser generator for golang. vartan also provides a command to perform syntax analysis to allow easy debugging of your grammar.

[![Test](https://github.com/nihei9/vartan/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/nihei9/vartan/actions/workflows/test.yml)

Expand Down
16 changes: 1 addition & 15 deletions cmd/vartan/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

var compileFlags = struct {
output *string
class *string
}{}

func init() {
Expand All @@ -28,7 +27,6 @@ func init() {
RunE: runCompile,
}
compileFlags.output = cmd.Flags().StringP("output", "o", "", "output file path (default stdout)")
compileFlags.class = cmd.Flags().StringP("class", "", "lalr", "LALR or SLR")
rootCmd.AddCommand(cmd)
}

Expand Down Expand Up @@ -92,19 +90,7 @@ func runCompile(cmd *cobra.Command, args []string) (retErr error) {
reportFileName = fmt.Sprintf("%v-report.json", strings.TrimSuffix(grmFileName, ".vartan"))
}

opts := []grammar.CompileOption{
grammar.EnableReporting(reportFileName),
}
switch strings.ToLower(*compileFlags.class) {
case "slr":
opts = append(opts, grammar.SpecifyClass(grammar.ClassSLR))
case "lalr":
opts = append(opts, grammar.SpecifyClass(grammar.ClassLALR))
default:
return fmt.Errorf("invalid class: %v", *compileFlags.class)
}

cgram, err := grammar.Compile(gram, opts...)
cgram, err := grammar.Compile(gram, grammar.EnableReporting(reportFileName))
if err != nil {
return err
}
Expand Down
6 changes: 1 addition & 5 deletions cmd/vartan/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ func readReport(path string) (*spec.Report, error) {
return report, nil
}

const reportTemplate = `# Class
{{ .Class }}
# Conflicts
const reportTemplate = `# Conflicts
{{ printConflictSummary . }}
Expand Down
2 changes: 1 addition & 1 deletion driver/conflict_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ assign: '=';
t.Fatal(err)
}

cg, err := grammar.Compile(g, grammar.SpecifyClass(grammar.ClassSLR))
cg, err := grammar.Compile(g)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion driver/lac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ d: 'd';
t.Fatal(err)
}

gram, err := grammar.Compile(g, grammar.SpecifyClass(grammar.ClassLALR))
gram, err := grammar.Compile(g)
if err != nil {
t.Fatal(err)
}
Expand Down
9 changes: 1 addition & 8 deletions driver/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
)

type Grammar interface {
// Class returns a class of grammar.
Class() string

// InitialState returns the initial state of a parser.
InitialState() int

Expand Down Expand Up @@ -88,7 +85,7 @@ type SyntaxError struct {

type ParserOption func(p *Parser) error

// DisableLAC disables LAC (lookahead correction). When the grammar has the LALR class, LAC is enabled by default.
// DisableLAC disables LAC (lookahead correction). LAC is enabled by default.
func DisableLAC() ParserOption {
return func(p *Parser) error {
p.disableLAC = true
Expand Down Expand Up @@ -121,10 +118,6 @@ func NewParser(toks TokenStream, gram Grammar, opts ...ParserOption) (*Parser, e
stateStack: &stateStack{},
}

if p.gram.Class() != "lalr" {
p.disableLAC = true
}

for _, opt := range opts {
err := opt(p)
if err != nil {
Expand Down
117 changes: 55 additions & 62 deletions driver/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,70 +725,63 @@ bar: 'bar';
},
}

classes := []grammar.Class{
grammar.ClassSLR,
grammar.ClassLALR,
}

for i, tt := range tests {
for _, class := range classes {
t.Run(fmt.Sprintf("#%v", i), func(t *testing.T) {
ast, err := spec.Parse(strings.NewReader(tt.specSrc))
if err != nil {
t.Fatal(err)
}

b := grammar.GrammarBuilder{
AST: ast,
}
g, err := b.Build()
if err != nil {
t.Fatal(err)
}

cg, err := grammar.Compile(g, grammar.SpecifyClass(class))
if err != nil {
t.Fatal(err)
}

toks, err := NewTokenStream(cg, strings.NewReader(tt.src))
if err != nil {
t.Fatal(err)
}

gram := NewGrammar(cg)
tb := NewDefaultSyntaxTreeBuilder()
var opt []ParserOption
switch {
case tt.ast != nil:
opt = append(opt, SemanticAction(NewASTActionSet(gram, tb)))
case tt.cst != nil:
opt = append(opt, SemanticAction(NewCSTActionSet(gram, tb)))
}
p, err := NewParser(toks, gram, opt...)
if err != nil {
t.Fatal(err)
}

err = p.Parse()
if err != nil {
t.Fatal(err)
}

if !tt.synErr && len(p.SyntaxErrors()) > 0 {
for _, synErr := range p.SyntaxErrors() {
t.Fatalf("unexpected syntax errors occurred: %v", synErr)
}
}

switch {
case tt.ast != nil:
testTree(t, tb.Tree(), tt.ast)
case tt.cst != nil:
testTree(t, tb.Tree(), tt.cst)
t.Run(fmt.Sprintf("#%v", i), func(t *testing.T) {
ast, err := spec.Parse(strings.NewReader(tt.specSrc))
if err != nil {
t.Fatal(err)
}

b := grammar.GrammarBuilder{
AST: ast,
}
g, err := b.Build()
if err != nil {
t.Fatal(err)
}

cg, err := grammar.Compile(g)
if err != nil {
t.Fatal(err)
}

toks, err := NewTokenStream(cg, strings.NewReader(tt.src))
if err != nil {
t.Fatal(err)
}

gram := NewGrammar(cg)
tb := NewDefaultSyntaxTreeBuilder()
var opt []ParserOption
switch {
case tt.ast != nil:
opt = append(opt, SemanticAction(NewASTActionSet(gram, tb)))
case tt.cst != nil:
opt = append(opt, SemanticAction(NewCSTActionSet(gram, tb)))
}
p, err := NewParser(toks, gram, opt...)
if err != nil {
t.Fatal(err)
}

err = p.Parse()
if err != nil {
t.Fatal(err)
}

if !tt.synErr && len(p.SyntaxErrors()) > 0 {
for _, synErr := range p.SyntaxErrors() {
t.Fatalf("unexpected syntax errors occurred: %v", synErr)
}
})
}
}

switch {
case tt.ast != nil:
testTree(t, tb.Tree(), tt.ast)
case tt.cst != nil:
testTree(t, tb.Tree(), tt.cst)
}
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion driver/semantic_action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ char
t.Fatal(err)
}

gram, err := grammar.Compile(g, grammar.SpecifyClass(grammar.ClassLALR))
gram, err := grammar.Compile(g)
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 0 additions & 4 deletions driver/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ func NewGrammar(g *spec.CompiledGrammar) *grammarImpl {
}
}

func (g *grammarImpl) Class() string {
return g.g.ParsingTable.Class
}

func (g *grammarImpl) InitialState() int {
return g.g.ParsingTable.InitialState
}
Expand Down
2 changes: 1 addition & 1 deletion driver/syntax_error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ c
t.Fatal(err)
}

gram, err := grammar.Compile(g, grammar.SpecifyClass(grammar.ClassLALR))
gram, err := grammar.Compile(g)
if err != nil {
t.Fatal(err)
}
Expand Down
5 changes: 0 additions & 5 deletions driver/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ func GenParser(cgram *spec.CompiledGrammar, pkgName string) ([]byte, error) {

var b strings.Builder
err = t.Execute(&b, map[string]interface{}{
"class": cgram.ParsingTable.Class,
"initialState": cgram.ParsingTable.InitialState,
"startProduction": cgram.ParsingTable.StartProduction,
"terminalCount": cgram.ParsingTable.TerminalCount,
Expand Down Expand Up @@ -167,10 +166,6 @@ func NewGrammar() *grammarImpl {
}
}
func (g *grammarImpl) Class() string {
return "{{ .class }}"
}
func (g *grammarImpl) InitialState() int {
return {{ .initialState }}
}
Expand Down
Loading

0 comments on commit b5ad1d3

Please sign in to comment.