/// <summary> /// Creates a new state contianing the given value with a reference to the given graph. /// </summary> /// <param name="value"></param> /// <param name="graph"></param> public StateNode(T value, StateGraph <TKey, T> graph) { fromTransitions = new Dictionary <TKey, StateNode <TKey, T> >(); toTransitions = new List <StateNode <TKey, T> >(); Value = value; Graph = graph; }
/// <summary> /// Creates a new parse table from the given graph. /// </summary> /// <param name="graph"></param> public ParseTable(StateGraph <GrammarElement <T>, LRItem <T>[]> graph, NonTerminal <T> startingElement) { ActionTable = new Table <int, Terminal <T>, List <ParserAction <T> > >(); GotoTable = new Table <int, NonTerminal <T>, int?>(); //int state = 0; //build the parse table from the root of the graph buildParseTable(graph, startingElement); //, state, startingElement, ref state); }
/// <summary> /// Builds the parse table from the given graph and starting element. /// </summary> /// <param name="graph"></param> /// <param name="startingElement"></param> private void buildParseTable(StateGraph <GrammarElement <T>, LRItem <T>[]> graph, NonTerminal <T> startingElement) { if (graph == null) { throw new ArgumentNullException("graph"); } if (startingElement == null) { throw new ArgumentNullException("startingElement"); } //clear the tables ActionTable.Clear(); GotoTable.Clear(); //get the breadth-first traversal of the graph List <StateNode <GrammarElement <T>, LRItem <T>[]> > t = graph.GetBreadthFirstTraversal().ToList(); //add the transitions for each node in the traversal for (var i = 0; i < t.Count; i++) { //for each transition in the node, add either a shift action or goto action foreach (KeyValuePair <GrammarElement <T>, StateNode <GrammarElement <T>, LRItem <T>[]> > transition in t[i].FromTransitions) { if (transition.Key is Terminal <T> ) { //add a shift from this state to the next state addAction((Terminal <T>)transition.Key, i, new ShiftAction <T>(this, t.IndexOf(transition.Value))); } else { addGoto((NonTerminal <T>)transition.Key, i, t.IndexOf(transition.Value)); } } //for each of the items in the state that are at the end of a production, //add either a reduce action or accept action foreach (LRItem <T> item in t[i].Value.Where(a => a.IsAtEndOfProduction())) { //if we would reduce to the starting element, then accept if (item.LeftHandSide.Equals(startingElement)) { addAction(item.LookaheadElement, i, new AcceptAction <T>(this, item)); } //otherwise, add a reduce action else { addAction(item.LookaheadElement, i, new ReduceAction <T>(this, item)); } } } }
/// <summary> /// Creates a new Parse Table from the given State Graph. /// </summary> /// <param name="graph"></param> public ParseTable(StateGraph <GrammarElement <T>, LRItem <T>[]> graph) { if (graph.Root != null && graph.Root.Value.Length > 0) { ActionTable = new Table <int, Terminal <T>, List <ParserAction <T> > >(); GotoTable = new Table <int, NonTerminal <T>, int?>(); buildParseTable(graph, graph.Root.Value.First().LeftHandSide); } else { throw new ArgumentException("The given graph must have at least one item in the root node.", "graph"); } }