aboutsummaryrefslogtreecommitdiff
path: root/grammar/parsing_table.go
diff options
context:
space:
mode:
Diffstat (limited to 'grammar/parsing_table.go')
-rw-r--r--grammar/parsing_table.go29
1 files changed, 27 insertions, 2 deletions
diff --git a/grammar/parsing_table.go b/grammar/parsing_table.go
index 903f95a..aee5963 100644
--- a/grammar/parsing_table.go
+++ b/grammar/parsing_table.go
@@ -136,6 +136,7 @@ type lrTableBuilder struct {
nonTermCount int
symTab *symbolTable
sym2AnonPat map[symbol]string
+ precAndAssoc *precAndAssoc
conflicts []conflict
}
@@ -222,6 +223,12 @@ func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym
nextState: nextState,
prodNum: p,
})
+
+ if b.resolveConflict(sym.num(), p) == ActionTypeShift {
+ tab.writeAction(state.Int(), sym.num().Int(), newShiftActionEntry(nextState))
+ }
+
+ return
}
}
@@ -230,7 +237,7 @@ func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym
// writeReduceAction writes a reduce action to the parsing table. When a shift/reduce conflict occurred,
// we prioritize the shift action, and when a reduce/reduce conflict we prioritize the action that reduces
-// teh production with higher priority. Productions defined earlier in the grammar file have a higher priority.
+// the production with higher priority. Productions defined earlier in the grammar file have a higher priority.
func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sym symbol, prod productionNum) {
act := tab.readAction(state.Int(), sym.num().Int())
if !act.isEmpty() {
@@ -261,7 +268,9 @@ func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sy
prodNum: prod,
})
- tab.writeAction(state.Int(), sym.num().Int(), newShiftActionEntry(s))
+ if b.resolveConflict(sym.num(), prod) == ActionTypeReduce {
+ tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(prod))
+ }
}
return
@@ -270,6 +279,22 @@ func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sy
tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(prod))
}
+func (b *lrTableBuilder) resolveConflict(sym symbolNum, prod productionNum) ActionType {
+ symPrec := b.precAndAssoc.terminalPrecedence(sym)
+ prodPrec := b.precAndAssoc.productionPredence(prod)
+ if symPrec < prodPrec {
+ return ActionTypeShift
+ }
+ if symPrec == prodPrec {
+ assoc := b.precAndAssoc.productionAssociativity(prod)
+ if assoc != assocTypeLeft {
+ return ActionTypeShift
+ }
+ }
+
+ return ActionTypeReduce
+}
+
func (b *lrTableBuilder) writeDescription(w io.Writer, tab *ParsingTable) {
conflicts := map[stateNum][]conflict{}
for _, con := range b.conflicts {