diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-09-07 00:31:06 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-09-07 02:17:41 +0900 |
commit | 72da4b04e42baf3743ecf54b207f446a570d55e2 (patch) | |
tree | a4e126afcb0fa39b20075af3849ba1105c6c9a84 | |
parent | Change semantic action APIs (diff) | |
download | urubu-72da4b04e42baf3743ecf54b207f446a570d55e2.tar.gz urubu-72da4b04e42baf3743ecf54b207f446a570d55e2.tar.xz |
Add the semantic action API 'TrapAndShiftError' instead of 'TrapError' and 'ShiftError'
-rw-r--r-- | driver/parser.go | 5 | ||||
-rw-r--r-- | driver/semantic_action.go | 57 | ||||
-rw-r--r-- | driver/semantic_action_test.go | 25 |
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", }, }, { |