aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/parser.go3
-rw-r--r--driver/parser_test.go44
2 files changed, 47 insertions, 0 deletions
diff --git a/driver/parser.go b/driver/parser.go
index 7b6df7b..fa89fcf 100644
--- a/driver/parser.go
+++ b/driver/parser.go
@@ -121,8 +121,11 @@ func (p *Parser) Parse() error {
}
// semantic action
+
prodNum := act
lhs := p.gram.ParsingTable.LHSSymbols[prodNum]
+
+ // When an alternative is empty, `n` will be 0, and `handle` will be empty slice.
n := p.gram.ParsingTable.AlternativeSymbolCounts[prodNum]
handle := p.semStack[len(p.semStack)-n:]
diff --git a/driver/parser_test.go b/driver/parser_test.go
index 8713893..3dec508 100644
--- a/driver/parser_test.go
+++ b/driver/parser_test.go
@@ -104,6 +104,50 @@ id: "[A-Za-z_][0-9A-Za-z_]*";
),
),
},
+ // The driver can reduce productions that have the empty alternative and can generate a CST (and AST) node.
+ {
+ specSrc: `
+s
+ : foo bar
+ ;
+foo
+ :
+ ;
+bar
+ : bar_text
+ |
+ ;
+bar_text: "bar";
+`,
+ src: ``,
+ cst: nonTermNode("s",
+ termNode("foo", ""),
+ termNode("bar", ""),
+ ),
+ },
+ // The driver can reduce productions that have the empty alternative and can generate a CST (and AST) node.
+ {
+ specSrc: `
+s
+ : foo bar
+ ;
+foo
+ :
+ ;
+bar
+ : bar_text
+ |
+ ;
+bar_text: "bar";
+`,
+ src: `bar`,
+ cst: nonTermNode("s",
+ termNode("foo", ""),
+ nonTermNode("bar",
+ termNode("bar_text", "bar"),
+ ),
+ ),
+ },
{
specSrc: `
mode_tran_seq