1 module gamma.parsgen.lalr1.SimpleLR1ConflictResolver; 2 3 import gamma.grammar.Alternative; 4 import gamma.grammar.Grammar; 5 import gamma.grammar.Nonterminal; 6 import gamma.grammar.Terminal; 7 import gamma.parsgen.lalr1.LR1ConflictResolver; 8 9 /** 10 * A standard LR(1) conflict resolver. 11 * 12 * @author SöKa 13 */ 14 public class SimpleLR1ConflictResolver : LR1ConflictResolver 15 { 16 int srConflicts = 0; 17 18 int rrConflicts = 0; 19 20 int haltConflicts = 0; 21 22 private Grammar grammar; 23 24 this(Grammar grammar) 25 { 26 this.grammar = grammar; 27 } 28 29 public Object resolveShiftReduceConflict(Terminal terminal, Alternative alternative, size_t state) 30 { 31 import std.format : format; 32 33 ++srConflicts; 34 alternative.position 35 .markError(format!"shift/reduce conflict at state %s for look-ahead %s"(state, terminal)); 36 return terminal; 37 } 38 39 public Object resolveReduceReduceConflict(Alternative alternative1, Alternative alternative2, 40 Terminal terminal, size_t state) 41 { 42 import std.format : format; 43 44 ++rrConflicts; 45 alternative1.position 46 .markError(format!"reduce/reduce conflict with '%s' for look-ahead %s"(alternative2, 47 (terminal !is null) ? terminal.toString : "(null)")); 48 49 const n1 = (cast(Nonterminal) alternative1.lhs.symbol).index; 50 const n2 = (cast(Nonterminal) alternative2.lhs.symbol).index; 51 52 if (n1 < n2) 53 return alternative1; 54 else if (n1 > n2) 55 return alternative2; 56 else 57 foreach (alternative; this.grammar.ruleOf(this.grammar.nonterminal(n1)).alternatives) 58 { 59 if (alternative == alternative1) 60 return alternative1; 61 else if (alternative == alternative2) 62 return alternative2; 63 } 64 return null; 65 } 66 67 public void noteHaltConflictOn(Alternative alternative, size_t state) 68 { 69 ++haltConflicts; 70 alternative.position 71 .markError("reduce/halt conflict"); 72 } 73 74 75 public int getHaltConflicts() const 76 { 77 return this.haltConflicts; 78 } 79 80 81 public int getRrConflicts() const 82 { 83 return this.rrConflicts; 84 } 85 86 87 public int getSrConflicts() const 88 { 89 return this.srConflicts; 90 } 91 }