protected virtual void OnReduction(Reduction reduction) { if (Reduction != null) { Reduction(reduction); } }
private bool DoReduction(Stack <Token> tokenStack, LookAheadBuffer lookAheadBuffer, ref ushort lalrState, LRAction parseAction) { Token head = null; //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token Production prod = egtDataManager.GetProduction(parseAction.Value); bool reductionSkipped = false; //Skip reduction? if ((TrimReductions && prod.ConsistsOfOneNonTerminal()) || (SkipEmptyProductions && prod.Handle.Count == 0)) { head = tokenStack.Pop(); head.Symbol = prod.Head; reductionSkipped = true; } //Build a Reduction else { Reduction reduction = new Reduction(prod.Handle.Count, prod); //If a production has no handles, it has no location. //Set a would-be location instead. if (prod.Handle.Count == 0) { reduction.StartPosition = reduction.EndPosition = lookAheadBuffer.Position; } else { for (int i = prod.Handle.Count - 1; i >= 0; i--) { reduction[i] = tokenStack.Pop(); } } head = reduction; } //If n is -1 here, then we have an Internal Table Error!!! LRAction action = egtDataManager.GetLRActionList(tokenStack.Peek().State)[prod.Head]; if (action == null) { OnInternalError(); return(false); } lalrState = action.Value; head.State = lalrState; tokenStack.Push(head); if (!reductionSkipped) { OnReduction((Reduction)tokenStack.Peek()); } return(true); }
// This function analyzes a token and either: // 1. Makes a SINGLE reduction and pushes a complete Reduction object on the m_Stack // 2. Accepts the token and shifts // 3. Errors and places the expected symbol indexes in the Tokens list // The Token is assumed to be valid and WILL be checked // If an action is performed that requires controlt to be returned to the user, the function returns true. // The Message parameter is then set to the type of action. private ParseResult ParseLALR(ref Token token) { LRAction parseAction = lrStates[currentLALR][token.Parent]; ParseResult parseResult = 0; if (parseAction != null) { haveReduction = false; switch (parseAction.Type) { case LRActionType.Shift: currentLALR = parseAction.Value; token.State = (short)currentLALR; stack.Push(token); parseResult = ParseResult.Shift; break; case LRActionType.Reduce: Production production = ProductionTable[parseAction.Value]; Token head; // The current rule only consists of a single nonterminal and can be trimmed from the // parse tree. Usually we create a new Reduction, assign it to the Data property // of Head and push it on the m_Stack. However, in this case, the Data property of the // Head will be assigned the Data property of the reduced token (i.e. the only one // on the m_Stack). // In this case, to save code, the value popped of the m_Stack is changed into the head. if (TrimReductions && production.ContainsOneNonTerminal()) { head = stack.Pop(); head.Parent = production.Head; parseResult = ParseResult.ReduceEliminated; } else { haveReduction = true; Reduction newReduction = new Reduction(production.Handle.Count()) { Parent = production }; short n = (short)(production.Handle.Count() - 1); while (n >= 0) { newReduction[n] = stack.Pop(); n--; } head = new Token(production.Head, newReduction); parseResult = ParseResult.ReduceNormal; } short index = stack.Peek().State; short n2 = lrStates[index].IndexOf(production.Head); if (n2 != -1) { currentLALR = lrStates[index][n2].Value; head.State = (short)currentLALR; stack.Push(head); break; } parseResult = ParseResult.InternalError; break; case LRActionType.Accept: haveReduction = true; parseResult = ParseResult.Accept; break; } } else { ExpectedSymbols.Clear(); foreach (LRAction LRAction in lrStates[currentLALR]) { switch (LRAction.Symbol.Type) { case SymbolType.Content: case SymbolType.End: case SymbolType.GroupStart: case SymbolType.GroupEnd: ExpectedSymbols.Add(LRAction.Symbol); break; } } parseResult = ParseResult.SyntaxError; } return(parseResult); }
private bool DoReduction(Stack<Token> tokenStack, LookAheadBuffer lookAheadBuffer, ref ushort lalrState, LRAction parseAction) { Token head = null; //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token Production prod = egtDataManager.GetProduction(parseAction.Value); bool reductionSkipped = false; //Skip reduction? if ((TrimReductions && prod.ConsistsOfOneNonTerminal()) || (SkipEmptyProductions && prod.Handle.Count == 0)) { head = tokenStack.Pop(); head.Symbol = prod.Head; reductionSkipped = true; } //Build a Reduction else { Reduction reduction = new Reduction(prod.Handle.Count, prod); //If a production has no handles, it has no location. //Set a would-be location instead. if (prod.Handle.Count == 0) { reduction.StartPosition = reduction.EndPosition = lookAheadBuffer.Position; } else { for (int i = prod.Handle.Count - 1; i >= 0; i--) { reduction[i] = tokenStack.Pop(); } } head = reduction; } //If n is -1 here, then we have an Internal Table Error!!! LRAction action = egtDataManager.GetLRActionList(tokenStack.Peek().State)[prod.Head]; if (action == null) { OnInternalError(); return false; } lalrState = action.Value; head.State = lalrState; tokenStack.Push(head); if (!reductionSkipped) { OnReduction((Reduction)tokenStack.Peek()); } return true; }