private void ExecuteReduceAction(ActionRecord action) { ParserState oldState = _currentState; int popCnt = action.PopCount; //Get new node's child nodes - these are nodes being popped from the stack AstNodeList childNodes = new AstNodeList(); for (int i = 0; i < action.PopCount; i++) { AstNode child = Stack[Stack.Count - popCnt + i].Node; if (child.Term.IsSet(TermOptions.IsPunctuation)) { continue; } //Transient nodes - don't add them but add their childrent directly to grandparent if (child.Term.IsSet(TermOptions.IsTransient)) { foreach (AstNode grandChild in child.ChildNodes) { childNodes.Add(grandChild); } continue; } //Add normal child childNodes.Add(child); } //recover state, location and pop the stack SourceSpan newNodeSpan; if (popCnt == 0) { newNodeSpan = new SourceSpan(_currentToken.Location, 0); } else { SourceLocation firstPopLoc = Stack[Stack.Count - popCnt].Node.Location; int lastPopEndPos = Stack[Stack.Count - 1].Node.Span.EndPos; newNodeSpan = new SourceSpan(firstPopLoc, lastPopEndPos - firstPopLoc.Position); _currentState = Stack[Stack.Count - popCnt].State; Stack.Pop(popCnt); } //Create new node AstNode node = CreateNode(action, newNodeSpan, childNodes); action.NonTerminal.OnNodeCreated(node); // Push node/current state into the stack Stack.Push(node, _currentState); //switch to new state ActionRecord gotoAction; if (_currentState.Actions.TryGetValue(action.NonTerminal.Key, out gotoAction)) { _currentState = gotoAction.NewState; } else { //should never happen throw new CompilerException(string.Format("Cannot find transition for input {0}; state: {1}, popped state: {2}", action.NonTerminal, oldState, _currentState)); } }//method
public ParserActionEventArgs(ParserState state, Token input, ActionRecord action) { State = state; Input = input; Action = action; }
private void ExecuteShiftAction(ActionRecord action) { Stack.Push(_currentToken, _currentState); _currentState = action.NewState; NextToken(); }