14 using System.Collections.Generic;
16 using System.Diagnostics;
24 namespace Irony.
Parsing.Construction {
26 internal class ParserStateData {
27 public readonly ParserState State;
28 public readonly LRItemSet AllItems =
new LRItemSet();
29 public readonly LRItemSet ShiftItems =
new LRItemSet();
30 public readonly LRItemSet ReduceItems =
new LRItemSet();
31 public readonly LRItemSet InitialItems =
new LRItemSet();
32 public readonly BnfTermSet ShiftTerms =
new BnfTermSet();
33 public readonly TerminalSet ShiftTerminals =
new TerminalSet();
34 public readonly TerminalSet Conflicts =
new TerminalSet();
35 public readonly TerminalSet ResolvedConflicts =
new TerminalSet();
36 public readonly
bool IsInadequate;
37 public LR0ItemSet AllCores =
new LR0ItemSet();
40 public ParserStateData(ParserState state, LR0ItemSet kernelCores) {
42 foreach (var core
in kernelCores)
44 IsInadequate = ReduceItems.Count > 1 || ReduceItems.Count == 1 && ShiftItems.Count > 0;
47 public void AddItem(LR0Item core) {
49 if(!AllCores.Add(core))
return ;
51 var item =
new LRItem(State, core);
53 if (item.Core.IsFinal)
54 ReduceItems.Add(item);
57 if (item.Core.IsInitial)
58 InitialItems.Add(item);
59 if (core.IsFinal)
return;
61 if (!ShiftTerms.Add(core.Current))
return;
62 if (core.Current is Terminal)
63 ShiftTerminals.Add(core.Current as Terminal);
66 if (currNt == null)
return;
67 foreach(var prod
in currNt.Productions)
68 AddItem(prod.LR0Items[0]);
71 public TransitionTable Transitions {
73 if(_transitions == null)
74 _transitions =
new TransitionTable();
77 } TransitionTable _transitions;
80 public ParserStateSet ReadStateSet {
82 if(_readStateSet == null) {
83 _readStateSet =
new ParserStateSet();
84 foreach(var shiftTerm
in State.BuilderData.ShiftTerms)
85 if (shiftTerm.FlagIsSet(
TermFlags.IsNullable)) {
86 var targetState = State.Actions[shiftTerm].NewState;
87 _readStateSet.Add(targetState);
88 _readStateSet.UnionWith(targetState.BuilderData.ReadStateSet);
93 } ParserStateSet _readStateSet;
96 public TerminalSet GetShiftReduceConflicts() {
97 var result =
new TerminalSet();
98 result.UnionWith(Conflicts);
99 result.IntersectWith(ShiftTerminals);
102 public TerminalSet GetReduceReduceConflicts() {
103 var result =
new TerminalSet();
104 result.UnionWith(Conflicts);
105 result.ExceptWith(ShiftTerminals);
112 internal class Transition {
113 public readonly ParserState FromState;
114 public readonly ParserState ToState;
115 public readonly NonTerminal OverNonTerminal;
116 public readonly LRItemSet Items;
117 public readonly TransitionSet Includes =
new TransitionSet();
118 public readonly TransitionSet IncludedBy =
new TransitionSet();
121 public Transition(ParserState fromState, NonTerminal overNonTerminal) {
122 FromState = fromState;
123 OverNonTerminal = overNonTerminal;
124 ToState = FromState.Actions[overNonTerminal].NewState;
125 _hashCode = unchecked(FromState.GetHashCode() - overNonTerminal.GetHashCode());
126 FromState.BuilderData.Transitions.Add(overNonTerminal,
this);
127 Items = FromState.BuilderData.ShiftItems.SelectByCurrent(overNonTerminal);
128 foreach(var item
in Items) {
129 item.Transition =
this;
134 public void Include(Transition other) {
135 if (other ==
this)
return;
136 if (!IncludeTransition(other))
return;
138 foreach(var child
in other.Includes) {
139 IncludeTransition(child);
142 private bool IncludeTransition(Transition other) {
143 if (!Includes.Add(other))
return false;
144 other.IncludedBy.Add(
this);
146 foreach(var incBy
in IncludedBy)
147 incBy.IncludeTransition(other);
151 public override string ToString() {
152 return FromState.Name +
" -> (over " + OverNonTerminal.Name +
") -> " + ToState.Name;
154 public override int GetHashCode() {
159 internal class TransitionSet : HashSet<Transition> { }
160 internal class TransitionList :
List<Transition> { }
161 internal class TransitionTable :
Dictionary<NonTerminal, Transition> { }
163 internal class LRItem {
164 public readonly ParserState State;
165 public readonly LR0Item Core;
167 public LRItem ShiftedItem;
168 public Transition Transition;
172 public TransitionSet Lookbacks =
new TransitionSet();
173 public TerminalSet Lookaheads =
new TerminalSet();
175 public LRItem(ParserState state, LR0Item core) {
178 _hashCode = unchecked(state.GetHashCode() + core.GetHashCode());
180 public override string ToString() {
181 return Core.ToString();
183 public override int GetHashCode() {
189 internal class LRItemList :
List<LRItem> {}
191 internal class LRItemSet : HashSet<LRItem> {
193 public LRItem FindByCore(LR0Item core) {
194 foreach (LRItem item
in this)
195 if (item.Core == core)
return item;
198 public LRItemSet SelectByCurrent(BnfTerm current) {
199 var result =
new LRItemSet();
200 foreach (var item
in this)
201 if (item.Core.Current == current)
206 public LR0ItemSet GetShiftedCores() {
207 var result =
new LR0ItemSet();
208 foreach (var item
in this)
209 if (item.Core.ShiftedItem != null)
210 result.Add(item.Core.ShiftedItem);
213 public LRItemSet SelectByLookahead(Terminal lookahead) {
214 var result =
new LRItemSet();
215 foreach (var item
in this)
216 if (item.Lookaheads.Contains(lookahead))
232 internal readonly
int ID;
238 Current = (Position < Production.RValues.Count) ?
Production.
RValues[Position] : null;
240 Hints.AddRange(hints);
241 _hashCode = ID.ToString().GetHashCode();
246 if (Position >=
Production.LR0Items.Count - 1)
249 return Production.LR0Items[Position + 1];
252 public bool IsKernel {
253 get {
return Position > 0; }
255 public bool IsInitial {
256 get {
return Position == 0; }
258 public bool IsFinal {
259 get {
return Position == Production.RValues.Count; }
262 return Production.ProductionToString(
Production, Position);
270 internal class LR0ItemList :
List<LR0Item> { }
271 internal class LR0ItemSet : HashSet<LR0Item> { }
readonly Production Production
readonly BnfTermList RValues
override string ToString()
LR0Item(int id, Production production, int position, GrammarHintList hints)
override int GetHashCode()