diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-05 20:01:51 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-08-05 20:56:01 +0900 |
commit | 7b4ed6608ea338c77e89b06bb20efae15491fcbc (patch) | |
tree | f4d3d2f5e5e49f56d86aa9b0f0ba77832d2f8217 | |
parent | Avoid the growth of slices when constructing trees (diff) | |
download | urubu-7b4ed6608ea338c77e89b06bb20efae15491fcbc.tar.gz urubu-7b4ed6608ea338c77e89b06bb20efae15491fcbc.tar.xz |
Add --only-parse option to the parse command
When this option is enabled, the parser performs only parse and doesn't semantic actions.
-rw-r--r-- | cmd/vartan/parse.go | 32 | ||||
-rw-r--r-- | driver/parser.go | 17 |
2 files changed, 32 insertions, 17 deletions
diff --git a/cmd/vartan/parse.go b/cmd/vartan/parse.go index 1311ce6..d5e3d36 100644 --- a/cmd/vartan/parse.go +++ b/cmd/vartan/parse.go @@ -12,8 +12,9 @@ import ( ) var parseFlags = struct { - source *string - cst *bool + source *string + onlyParse *bool + cst *bool }{} func init() { @@ -25,6 +26,7 @@ func init() { RunE: runParse, } parseFlags.source = cmd.Flags().StringP("source", "s", "", "source file path (default stdin)") + parseFlags.onlyParse = cmd.Flags().Bool("only-parse", false, "when this option is enabled, the parser performs only parse and doesn't semantic actions") parseFlags.cst = cmd.Flags().Bool("cst", false, "when this option is enabled, the parser generates a CST") rootCmd.AddCommand(cmd) } @@ -48,6 +50,10 @@ func runParse(cmd *cobra.Command, args []string) (retErr error) { } }() + if *parseFlags.onlyParse && *parseFlags.cst { + return fmt.Errorf("You cannot enable --only-parse and --cst at the same time") + } + cgram, err := readCompiledGrammar(args[0]) if err != nil { return fmt.Errorf("Cannot read a compiled grammar: %w", err) @@ -66,9 +72,10 @@ func runParse(cmd *cobra.Command, args []string) (retErr error) { } var opts []driver.ParserOption - if *parseFlags.cst { + switch { + case *parseFlags.cst: opts = append(opts, driver.MakeCST()) - } else { + case !*parseFlags.onlyParse: opts = append(opts, driver.MakeAST()) } p, err = driver.NewParser(cgram, src, opts...) @@ -82,14 +89,17 @@ func runParse(cmd *cobra.Command, args []string) (retErr error) { return err } - var tree *driver.Node - if *parseFlags.cst { - tree = p.CST() - } else { - tree = p.AST() - } fmt.Printf("Accepted\n") - driver.PrintTree(os.Stdout, tree) + + if !*parseFlags.onlyParse { + var tree *driver.Node + if *parseFlags.cst { + tree = p.CST() + } else { + tree = p.AST() + } + driver.PrintTree(os.Stdout, tree) + } return nil } diff --git a/driver/parser.go b/driver/parser.go index cdcaf14..a96f89a 100644 --- a/driver/parser.go +++ b/driver/parser.go @@ -81,6 +81,7 @@ type Parser struct { ast *Node makeAST bool makeCST bool + needSemAct bool } func NewParser(gram *spec.CompiledGrammar, src io.Reader, opts ...ParserOption) (*Parser, error) { @@ -93,7 +94,6 @@ func NewParser(gram *spec.CompiledGrammar, src io.Reader, opts ...ParserOption) gram: gram, lex: lex, stateStack: []int{}, - semStack: []*semanticFrame{}, } for _, opt := range opts { @@ -103,6 +103,8 @@ func NewParser(gram *spec.CompiledGrammar, src io.Reader, opts ...ParserOption) } } + p.needSemAct = p.makeAST || p.makeCST + return p, nil } @@ -130,7 +132,7 @@ func (p *Parser) Parse() error { } // semantic action - { + if p.needSemAct { var ast *Node var cst *Node if p.makeAST { @@ -154,14 +156,17 @@ func (p *Parser) Parse() error { case act > 0: // Reduce accepted := p.reduce(act) if accepted { - top := p.semStack[len(p.semStack)-1] - p.cst = top.cst - p.ast = top.ast + if p.needSemAct { + top := p.semStack[len(p.semStack)-1] + p.cst = top.cst + p.ast = top.ast + } + return nil } // semantic action - { + if p.needSemAct { prodNum := act lhs := p.gram.ParsingTable.LHSSymbols[prodNum] |