public void BuildParseTable() { foreach (State state in states) { // Add shift actions ... foreach (Terminal t in state.terminalTransitions) { state.parseTable[t] = new Shift(state.Goto[t]); } // Add reduce actions ... foreach (ProductionItem item in state.all_items) { if (item.isReduction()) { // Accept on everything if (item.production == grammar.rootProduction) { foreach (Terminal t in grammar.terminals.Values) { state.parseTable[t] = new Reduce(item); } } foreach (Terminal t in item.LA) { // possible conflict with existing action if (state.parseTable.ContainsKey(t)) { ParserAction other = state.parseTable[t]; if (other is Reduce) { Console.Error.WriteLine("Reduce/Reduce conflict, state {0}: {1} vs {2} on {3}", state.num, item.production.num, ((Reduce)other).item.production.num, t); // choose in favour of production listed first in the grammar if (((Reduce)other).item.production.num > item.production.num) { state.parseTable[t] = new Reduce(item); } } else { if (item.production.prec != null && t.prec != null) { if (item.production.prec.prec > t.prec.prec || (item.production.prec.prec == t.prec.prec && item.production.prec.type == PrecType.left)) { // resolve in favour of reduce (without error) state.parseTable[t] = new Reduce(item); } else { // resolve in favour of shift (without error) } } else { Console.Error.WriteLine("Shift/Reduce conflict, state {0} on {1}", state.num, t); } // choose in favour of the shift } } else { state.parseTable[t] = new Reduce(item); } } } } } }
public void BuildParseTable() { foreach (State current in this.states) { foreach (Terminal current2 in current.terminalTransitions) { current.parseTable[current2] = new Shift(current.Goto[current2]); } foreach (ProductionItem current3 in current.all_items) { if (current3.isReduction()) { if (current3.production == this.grammar.rootProduction) { foreach (Terminal current4 in this.grammar.terminals.Values) { current.parseTable[current4] = new Reduce(current3); } } foreach (Terminal current5 in current3.LA) { if (current.parseTable.ContainsKey(current5)) { ParserAction parserAction = current.parseTable[current5]; if (parserAction is Reduce) { Console.Error.WriteLine("Reduce/Reduce conflict, state {0}: {1} vs {2} on {3}", new object[] { current.num, current3.production.num, ((Reduce)parserAction).item.production.num, current5 }); if (((Reduce)parserAction).item.production.num > current3.production.num) { current.parseTable[current5] = new Reduce(current3); } } else { if (current3.production.prec != null && current5.prec != null) { if (current3.production.prec.prec > current5.prec.prec || (current3.production.prec.prec == current5.prec.prec && current3.production.prec.type == PrecType.left)) { current.parseTable[current5] = new Reduce(current3); } } else { Console.Error.WriteLine("Shift/Reduce conflict, state {0} on {1}", current.num, current5); } } } else { current.parseTable[current5] = new Reduce(current3); } } } } } }