diff options
Diffstat (limited to 'grammar/grammar.go')
-rw-r--r-- | grammar/grammar.go | 70 |
1 files changed, 18 insertions, 52 deletions
diff --git a/grammar/grammar.go b/grammar/grammar.go index 368ede6..2e0c8f4 100644 --- a/grammar/grammar.go +++ b/grammar/grammar.go @@ -1,10 +1,8 @@ package grammar import ( - "encoding/json" "fmt" "io" - "os" "strings" mlcompiler "github.com/nihei9/maleeni/compiler" @@ -1287,18 +1285,18 @@ func (b *GrammarBuilder) genPrecAndAssoc(symTab *symbolTable, errSym symbol, pro } type compileConfig struct { - reportFileName string + isReportingEnabled bool } type CompileOption func(config *compileConfig) -func EnableReporting(fileName string) CompileOption { +func EnableReporting() CompileOption { return func(config *compileConfig) { - config.reportFileName = fileName + config.isReportingEnabled = true } } -func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error) { +func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, *spec.Report, error) { config := &compileConfig{} for _, opt := range opts { opt(config) @@ -1313,9 +1311,9 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error fmt.Fprintf(&b, "\n") writeCompileError(&b, cerr) } - return nil, fmt.Errorf(b.String()) + return nil, nil, fmt.Errorf(b.String()) } - return nil, err + return nil, nil, err } kind2Term := make([]int, len(lexSpec.KindNames)) @@ -1330,7 +1328,7 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error sym, ok := gram.symbolTable.toSymbol(k.String()) if !ok { - return nil, fmt.Errorf("terminal symbol '%v' was not found in a symbol table", k) + return nil, nil, fmt.Errorf("terminal symbol '%v' was not found in a symbol table", k) } kind2Term[i] = sym.num().Int() term2Kind[sym.num()] = i @@ -1346,7 +1344,7 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error terms, err := gram.symbolTable.terminalTexts() if err != nil { - return nil, err + return nil, nil, err } kindAliases := make([]string, gram.symbolTable.termNum.Int()) @@ -1356,24 +1354,25 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error nonTerms, err := gram.symbolTable.nonTerminalTexts() if err != nil { - return nil, err + return nil, nil, err } firstSet, err := genFirstSet(gram.productionSet) if err != nil { - return nil, err + return nil, nil, err } lr0, err := genLR0Automaton(gram.productionSet, gram.augmentedStartSymbol, gram.errorSymbol) if err != nil { - return nil, err + return nil, nil, err } var tab *ParsingTable + var report *spec.Report { lalr1, err := genLALR1Automaton(lr0, gram.productionSet, firstSet) if err != nil { - return nil, err + return nil, nil, err } b := &lrTableBuilder{ @@ -1387,48 +1386,15 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error } tab, err = b.build() if err != nil { - return nil, err - } - - report, err := b.genReport(tab, gram) - if err != nil { - return nil, err + return nil, nil, err } - if config.reportFileName != "" { - f, err := os.OpenFile(config.reportFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if config.isReportingEnabled { + report, err = b.genReport(tab, gram) if err != nil { - return nil, err - } - defer f.Close() - - d, err := json.Marshal(report) - if err != nil { - return nil, err - } - - _, err = f.Write(d) - if err != nil { - return nil, fmt.Errorf("failed to write a report: %w", err) + return nil, nil, err } } - - var implicitlyResolvedCount int - for _, s := range report.States { - for _, c := range s.SRConflict { - if c.ResolvedBy == ResolvedByShift.Int() { - implicitlyResolvedCount++ - } - } - for _, c := range s.RRConflict { - if c.ResolvedBy == ResolvedByProdOrder.Int() { - implicitlyResolvedCount++ - } - } - } - if implicitlyResolvedCount > 0 { - fmt.Fprintf(os.Stderr, "%v conflicts\n", implicitlyResolvedCount) - } } action := make([]int, len(tab.actionTable)) @@ -1499,7 +1465,7 @@ func Compile(gram *Grammar, opts ...CompileOption) (*spec.CompiledGrammar, error ASTAction: &spec.ASTAction{ Entries: astActEnties, }, - }, nil + }, report, nil } func writeCompileError(w io.Writer, cErr *mlcompiler.CompileError) { |