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.go95
1 files changed, 48 insertions, 47 deletions
diff --git a/grammar/parsing_table.go b/grammar/parsing_table.go
index 93033a3..53f692e 100644
--- a/grammar/parsing_table.go
+++ b/grammar/parsing_table.go
@@ -4,6 +4,7 @@ import (
"fmt"
"sort"
+ "github.com/nihei9/vartan/grammar/symbol"
spec "github.com/nihei9/vartan/spec/grammar"
)
@@ -82,7 +83,7 @@ type conflict interface {
type shiftReduceConflict struct {
state stateNum
- sym symbol
+ sym symbol.Symbol
nextState stateNum
prodNum productionNum
resolvedBy conflictResolutionMethod
@@ -93,7 +94,7 @@ func (c *shiftReduceConflict) conflict() {
type reduceReduceConflict struct {
state stateNum
- sym symbol
+ sym symbol.Symbol
prodNum1 productionNum
prodNum2 productionNum
resolvedBy conflictResolutionMethod
@@ -123,12 +124,12 @@ type ParsingTable struct {
InitialState stateNum
}
-func (t *ParsingTable) getAction(state stateNum, sym symbolNum) (ActionType, stateNum, productionNum) {
+func (t *ParsingTable) getAction(state stateNum, sym symbol.SymbolNum) (ActionType, stateNum, productionNum) {
pos := state.Int()*t.terminalCount + sym.Int()
return t.actionTable[pos].describe()
}
-func (t *ParsingTable) getGoTo(state stateNum, sym symbolNum) (GoToType, stateNum) {
+func (t *ParsingTable) getGoTo(state stateNum, sym symbol.SymbolNum) (GoToType, stateNum) {
pos := state.Int()*t.nonTerminalCount + sym.Int()
return t.goToTable[pos].describe()
}
@@ -141,8 +142,8 @@ func (t *ParsingTable) writeAction(row int, col int, act actionEntry) {
t.actionTable[row*t.terminalCount+col] = act
}
-func (t *ParsingTable) writeGoTo(state stateNum, sym symbol, nextState stateNum) {
- pos := state.Int()*t.nonTerminalCount + sym.num().Int()
+func (t *ParsingTable) writeGoTo(state stateNum, sym symbol.Symbol, nextState stateNum) {
+ pos := state.Int()*t.nonTerminalCount + sym.Num().Int()
t.goToTable[pos] = newGoToEntry(nextState)
}
@@ -151,7 +152,7 @@ type lrTableBuilder struct {
prods *productionSet
termCount int
nonTermCount int
- symTab *symbolTableReader
+ symTab *symbol.SymbolTableReader
precAndAssoc *precAndAssoc
conflicts []conflict
@@ -179,7 +180,7 @@ func (b *lrTableBuilder) build() (*ParsingTable, error) {
for sym, kID := range state.next {
nextState := b.automaton.states[kID]
- if sym.isTerminal() {
+ if sym.IsTerminal() {
b.writeShiftAction(ptab, state.num, sym, nextState.num)
} else {
ptab.writeGoTo(state.num, sym, nextState.num)
@@ -226,12 +227,12 @@ func (b *lrTableBuilder) build() (*ParsingTable, error) {
// writeShiftAction writes a shift action to the parsing table. When a shift/reduce conflict occurred,
// we prioritize the shift action.
-func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym symbol, nextState stateNum) {
- act := tab.readAction(state.Int(), sym.num().Int())
+func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym symbol.Symbol, nextState stateNum) {
+ act := tab.readAction(state.Int(), sym.Num().Int())
if !act.isEmpty() {
ty, _, p := act.describe()
if ty == ActionTypeReduce {
- act, method := b.resolveSRConflict(sym.num(), p)
+ act, method := b.resolveSRConflict(sym.Num(), p)
b.conflicts = append(b.conflicts, &shiftReduceConflict{
state: state,
sym: sym,
@@ -240,19 +241,19 @@ func (b *lrTableBuilder) writeShiftAction(tab *ParsingTable, state stateNum, sym
resolvedBy: method,
})
if act == ActionTypeShift {
- tab.writeAction(state.Int(), sym.num().Int(), newShiftActionEntry(nextState))
+ tab.writeAction(state.Int(), sym.Num().Int(), newShiftActionEntry(nextState))
}
return
}
}
- tab.writeAction(state.Int(), sym.num().Int(), newShiftActionEntry(nextState))
+ tab.writeAction(state.Int(), sym.Num().Int(), newShiftActionEntry(nextState))
}
// 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
// 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())
+func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sym symbol.Symbol, prod productionNum) {
+ act := tab.readAction(state.Int(), sym.Num().Int())
if !act.isEmpty() {
ty, s, p := act.describe()
switch ty {
@@ -269,12 +270,12 @@ func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sy
resolvedBy: ResolvedByProdOrder,
})
if p < prod {
- tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(p))
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(p))
} else {
- tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(prod))
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
}
case ActionTypeShift:
- act, method := b.resolveSRConflict(sym.num(), prod)
+ act, method := b.resolveSRConflict(sym.Num(), prod)
b.conflicts = append(b.conflicts, &shiftReduceConflict{
state: state,
sym: sym,
@@ -283,15 +284,15 @@ func (b *lrTableBuilder) writeReduceAction(tab *ParsingTable, state stateNum, sy
resolvedBy: method,
})
if act == ActionTypeReduce {
- tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(prod))
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
}
}
return
}
- tab.writeAction(state.Int(), sym.num().Int(), newReduceActionEntry(prod))
+ tab.writeAction(state.Int(), sym.Num().Int(), newReduceActionEntry(prod))
}
-func (b *lrTableBuilder) resolveSRConflict(sym symbolNum, prod productionNum) (ActionType, conflictResolutionMethod) {
+func (b *lrTableBuilder) resolveSRConflict(sym symbol.SymbolNum, prod productionNum) (ActionType, conflictResolutionMethod) {
symPrec := b.precAndAssoc.terminalPrecedence(sym)
prodPrec := b.precAndAssoc.productionPredence(prod)
if symPrec == 0 || prodPrec == 0 {
@@ -313,26 +314,26 @@ func (b *lrTableBuilder) resolveSRConflict(sym symbolNum, prod productionNum) (A
func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Report, error) {
var terms []*spec.Terminal
{
- termSyms := b.symTab.terminalSymbols()
+ termSyms := b.symTab.TerminalSymbols()
terms = make([]*spec.Terminal, len(termSyms)+1)
for _, sym := range termSyms {
- name, ok := b.symTab.toText(sym)
+ name, ok := b.symTab.ToText(sym)
if !ok {
return nil, fmt.Errorf("failed to generate terminals: symbol not found: %v", sym)
}
term := &spec.Terminal{
- Number: sym.num().Int(),
+ Number: sym.Num().Int(),
Name: name,
}
- prec := b.precAndAssoc.terminalPrecedence(sym.num())
+ prec := b.precAndAssoc.terminalPrecedence(sym.Num())
if prec != precNil {
term.Precedence = prec
}
- assoc := b.precAndAssoc.terminalAssociativity(sym.num())
+ assoc := b.precAndAssoc.terminalAssociativity(sym.Num())
switch assoc {
case assocTypeLeft:
term.Associativity = "l"
@@ -340,22 +341,22 @@ func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Repo
term.Associativity = "r"
}
- terms[sym.num()] = term
+ terms[sym.Num()] = term
}
}
var nonTerms []*spec.NonTerminal
{
- nonTermSyms := b.symTab.nonTerminalSymbols()
+ nonTermSyms := b.symTab.NonTerminalSymbols()
nonTerms = make([]*spec.NonTerminal, len(nonTermSyms)+1)
for _, sym := range nonTermSyms {
- name, ok := b.symTab.toText(sym)
+ name, ok := b.symTab.ToText(sym)
if !ok {
return nil, fmt.Errorf("failed to generate non-terminals: symbol not found: %v", sym)
}
- nonTerms[sym.num()] = &spec.NonTerminal{
- Number: sym.num().Int(),
+ nonTerms[sym.Num()] = &spec.NonTerminal{
+ Number: sym.Num().Int(),
Name: name,
}
}
@@ -368,16 +369,16 @@ func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Repo
for _, p := range ps {
rhs := make([]int, len(p.rhs))
for i, e := range p.rhs {
- if e.isTerminal() {
- rhs[i] = e.num().Int()
+ if e.IsTerminal() {
+ rhs[i] = e.Num().Int()
} else {
- rhs[i] = e.num().Int() * -1
+ rhs[i] = e.Num().Int() * -1
}
}
prod := &spec.Production{
Number: p.num.Int(),
- LHS: p.lhs.num().Int(),
+ LHS: p.lhs.Num().Int(),
RHS: rhs,
}
@@ -441,33 +442,33 @@ func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Repo
var goTo []*spec.Transition
{
TERMINALS_LOOP:
- for _, t := range b.symTab.terminalSymbols() {
- act, next, prod := tab.getAction(s.num, t.num())
+ for _, t := range b.symTab.TerminalSymbols() {
+ act, next, prod := tab.getAction(s.num, t.Num())
switch act {
case ActionTypeShift:
shift = append(shift, &spec.Transition{
- Symbol: t.num().Int(),
+ Symbol: t.Num().Int(),
State: next.Int(),
})
case ActionTypeReduce:
for _, r := range reduce {
if r.Production == prod.Int() {
- r.LookAhead = append(r.LookAhead, t.num().Int())
+ r.LookAhead = append(r.LookAhead, t.Num().Int())
continue TERMINALS_LOOP
}
}
reduce = append(reduce, &spec.Reduce{
- LookAhead: []int{t.num().Int()},
+ LookAhead: []int{t.Num().Int()},
Production: prod.Int(),
})
}
}
- for _, n := range b.symTab.nonTerminalSymbols() {
- ty, next := tab.getGoTo(s.num, n.num())
+ for _, n := range b.symTab.NonTerminalSymbols() {
+ ty, next := tab.getGoTo(s.num, n.Num())
if ty == GoToTypeRegistered {
goTo = append(goTo, &spec.Transition{
- Symbol: n.num().Int(),
+ Symbol: n.Num().Int(),
State: next.Int(),
})
}
@@ -489,13 +490,13 @@ func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Repo
{
for _, c := range srConflicts[s.num] {
conflict := &spec.SRConflict{
- Symbol: c.sym.num().Int(),
+ Symbol: c.sym.Num().Int(),
State: c.nextState.Int(),
Production: c.prodNum.Int(),
ResolvedBy: c.resolvedBy.Int(),
}
- ty, s, p := tab.getAction(s.num, c.sym.num())
+ ty, s, p := tab.getAction(s.num, c.sym.Num())
switch ty {
case ActionTypeShift:
n := s.Int()
@@ -514,13 +515,13 @@ func (b *lrTableBuilder) genReport(tab *ParsingTable, gram *Grammar) (*spec.Repo
for _, c := range rrConflicts[s.num] {
conflict := &spec.RRConflict{
- Symbol: c.sym.num().Int(),
+ Symbol: c.sym.Num().Int(),
Production1: c.prodNum1.Int(),
Production2: c.prodNum2.Int(),
ResolvedBy: c.resolvedBy.Int(),
}
- _, _, p := tab.getAction(s.num, c.sym.num())
+ _, _, p := tab.getAction(s.num, c.sym.Num())
conflict.AdoptedProduction = p.Int()
rr = append(rr, conflict)