aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyo Nihei <nihei.dev@gmail.com>2021-09-07 00:31:06 +0900
committerRyo Nihei <nihei.dev@gmail.com>2021-09-07 02:17:41 +0900
commit72da4b04e42baf3743ecf54b207f446a570d55e2 (patch)
treea4e126afcb0fa39b20075af3849ba1105c6c9a84
parentChange semantic action APIs (diff)
downloadurubu-72da4b04e42baf3743ecf54b207f446a570d55e2.tar.gz
urubu-72da4b04e42baf3743ecf54b207f446a570d55e2.tar.xz
Add the semantic action API 'TrapAndShiftError' instead of 'TrapError' and 'ShiftError'
-rw-r--r--driver/parser.go5
-rw-r--r--driver/semantic_action.go57
-rw-r--r--driver/semantic_action_test.go25
3 files changed, 35 insertions, 52 deletions
diff --git a/driver/parser.go b/driver/parser.go
index af257e2..522362e 100644
--- a/driver/parser.go
+++ b/driver/parser.go
@@ -158,9 +158,6 @@ ACTION_LOOP:
return nil
}
- if p.semAct != nil {
- p.semAct.TrapError(count)
- }
p.onError = true
p.shiftCount = 0
@@ -173,7 +170,7 @@ ACTION_LOOP:
p.shift(act * -1)
if p.semAct != nil {
- p.semAct.ShiftError()
+ p.semAct.TrapAndShiftError(count)
}
}
}
diff --git a/driver/semantic_action.go b/driver/semantic_action.go
index 421a722..5bec385 100644
--- a/driver/semantic_action.go
+++ b/driver/semantic_action.go
@@ -13,11 +13,6 @@ type SemanticActionSet interface {
// the symbol. When the driver recovered from an error state by shifting the token, `recovered` is true.
Shift(tok *mldriver.Token, recovered bool)
- // Shift runs when the driver shifts a symbol onto the state stack. `tok` is a token corresponding to
- // the symbol. This function doesn't take a token as an argument because a token corresponding to
- // the error symbol doesn't exist.
- ShiftError()
-
// Reduce runs when the driver reduces an RHS of a production to its LHS. `prodNum` is a number of
// the production. When the driver recovered from an error state by reducing the production,
// `recovered` is true.
@@ -26,9 +21,11 @@ type SemanticActionSet interface {
// Accept runs when the driver accepts an input.
Accept()
- // TrapError runs when the driver traps a syntax error. `n` is the number of frames that the driver discards
- // from the state stack.
- TrapError(n int)
+ // TrapAndShiftError runs when the driver traps a syntax error and shifts a error symbol onto the state stack.
+ // `n` is the number of frames that the driver discards from the state stack.
+ // Unlike `Shift` function, this function doesn't take a token as an argument because a token corresponding to
+ // the error symbol doesn't exist.
+ TrapAndShiftError(n int)
// MissError runs when the driver fails to trap a syntax error.
MissError()
@@ -125,28 +122,6 @@ func (a *SyntaxTreeActionSet) Shift(tok *mldriver.Token, recovered bool) {
})
}
-func (a *SyntaxTreeActionSet) ShiftError() {
- errSym := a.gram.ParsingTable.ErrorSymbol
-
- var ast *Node
- var cst *Node
- if a.makeAST {
- ast = &Node{
- KindName: a.gram.ParsingTable.Terminals[errSym],
- }
- }
- if a.makeCST {
- cst = &Node{
- KindName: a.gram.ParsingTable.Terminals[errSym],
- }
- }
-
- a.semStack.push(&semanticFrame{
- cst: cst,
- ast: ast,
- })
-}
-
func (a *SyntaxTreeActionSet) Reduce(prodNum int, recovered bool) {
lhs := a.gram.ParsingTable.LHSSymbols[prodNum]
@@ -229,8 +204,28 @@ func (a *SyntaxTreeActionSet) Accept() {
a.ast = top[0].ast
}
-func (a *SyntaxTreeActionSet) TrapError(n int) {
+func (a *SyntaxTreeActionSet) TrapAndShiftError(n int) {
a.semStack.pop(n)
+
+ errSym := a.gram.ParsingTable.ErrorSymbol
+
+ var ast *Node
+ var cst *Node
+ if a.makeAST {
+ ast = &Node{
+ KindName: a.gram.ParsingTable.Terminals[errSym],
+ }
+ }
+ if a.makeCST {
+ cst = &Node{
+ KindName: a.gram.ParsingTable.Terminals[errSym],
+ }
+ }
+
+ a.semStack.push(&semanticFrame{
+ cst: cst,
+ ast: ast,
+ })
}
func (a *SyntaxTreeActionSet) MissError() {
diff --git a/driver/semantic_action_test.go b/driver/semantic_action_test.go
index 0856b3d..ef92d92 100644
--- a/driver/semantic_action_test.go
+++ b/driver/semantic_action_test.go
@@ -23,10 +23,6 @@ func (a *testSemAct) Shift(tok *mldriver.Token, recovered bool) {
}
}
-func (a *testSemAct) ShiftError() {
- a.actLog = append(a.actLog, "shift/error")
-}
-
func (a *testSemAct) Reduce(prodNum int, recovered bool) {
lhsSym := a.gram.ParsingTable.LHSSymbols[prodNum]
lhsText := a.gram.ParsingTable.NonTerminals[lhsSym]
@@ -41,8 +37,8 @@ func (a *testSemAct) Accept() {
a.actLog = append(a.actLog, "accept")
}
-func (a *testSemAct) TrapError(n int) {
- a.actLog = append(a.actLog, fmt.Sprintf("trap/%v", n))
+func (a *testSemAct) TrapAndShiftError(n int) {
+ a.actLog = append(a.actLog, fmt.Sprintf("trap/%v/shift/error", n))
}
func (a *testSemAct) MissError() {
@@ -110,32 +106,28 @@ char: "[a-z]";
},
},
{
- caption: "when a grammar has `error` symbol, the driver calls `TrapError` and `ShiftError`.",
+ caption: "when a grammar has `error` symbol, the driver calls `TrapAndShiftError`.",
specSrc: specSrcWithErrorProd,
src: `a; b !; c d !; e ! * *; h i j;`,
actLog: []string{
"shift/char",
- "trap/1",
- "shift/error",
+ "trap/1/shift/error",
"shift/semicolon",
"reduce/seq/recovered",
"shift/char",
- "trap/2",
- "shift/error",
+ "trap/2/shift/error",
"shift/semicolon",
"reduce/seq/recovered",
"shift/char",
"shift/char",
- "trap/3",
- "shift/error",
+ "trap/3/shift/error",
"shift/semicolon",
"reduce/seq/recovered",
"shift/char",
- "trap/2",
- "shift/error",
+ "trap/2/shift/error",
"shift/star",
"shift/star",
// When the driver shifts three times, it recovers from an error.
@@ -160,8 +152,7 @@ char: "[a-z]";
src: `a !`,
actLog: []string{
"shift/char",
- "trap/1",
- "shift/error",
+ "trap/1/shift/error",
},
},
{