aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyo Nihei <nihei.dev@gmail.com>2021-08-05 20:01:51 +0900
committerRyo Nihei <nihei.dev@gmail.com>2021-08-05 20:56:01 +0900
commit7b4ed6608ea338c77e89b06bb20efae15491fcbc (patch)
treef4d3d2f5e5e49f56d86aa9b0f0ba77832d2f8217
parentAvoid the growth of slices when constructing trees (diff)
downloadurubu-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.go32
-rw-r--r--driver/parser.go17
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]