public T Reduce <T>(T aggregator, ReduceAction <T> action) { T result = aggregator; foreach (WikiPageSection section in Subsections) { result = action(section, result); } return(result); }
private void DoReduce(Token token, ReduceAction action) { int reduceLength = action.Rule.Rhs.Length; State currentState; // Do not reduce if the rule is single nonterminal and TrimReductions is on bool skipReduce = ((TrimReductions) && (reduceLength == 1) && (action.Rule.Rhs[0] is SymbolNonterminal)); if (skipReduce) { stateStack.Pop(); currentState = stateStack.Peek(); } else { Token[] tokens = new Token[reduceLength]; for (int i = 0; i < reduceLength; i++) { stateStack.Pop(); tokens[reduceLength - i - 1] = tokenStack.Pop(); } NonterminalToken nttoken; if (reduceLength == 0) { nttoken = new NonterminalToken(action.Rule, tokens, token.Location); } else { nttoken = new NonterminalToken(action.Rule, tokens, tokens[reduceLength - 1].Location); } tokenStack.Push(nttoken); currentState = stateStack.Peek(); if (OnReduce != null) { ReduceEventArgs args = new ReduceEventArgs(action.Rule, nttoken, currentState); OnReduce(this, args); DoReleaseTokens(args.Token); continueParsing = args.Continue; } } Action gotoAction = currentState.Actions.Get(action.Rule.Lhs); if (gotoAction is GotoAction) { DoGoto(token, (GotoAction)gotoAction); } else { throw new ParserException("Invalid action table in state"); } }
private void DoReduce(Token token, ReduceAction action) { int reduceLength = action.Rule.Rhs.Length; State currentState; bool skipReduce = ((TrimReductions) && (reduceLength == 1) && (action.Rule.Rhs[0] is SymbolNonterminal)); if (skipReduce) { stateStack.Pop(); currentState = stateStack.Peek(); } else { Token[] tokens = new Token[reduceLength]; for (int i = 0; i < reduceLength; i++) { stateStack.Pop(); tokens[reduceLength - i - 1] = tokenStack.Pop(); } NonterminalToken nttoken = new NonterminalToken(action.Rule, tokens); tokenStack.Push(nttoken); currentState = stateStack.Peek(); if (OnReduce != null) { ReduceEventArgs args = new ReduceEventArgs(action.Rule, nttoken, currentState); OnReduce(this, args); DoReleaseTokens(args.Token); continueParsing = args.Continue; } } lalr.Action gotoAction = currentState.Actions.Get(action.Rule.Lhs); if (gotoAction is GotoAction) { DoGoto(token, (GotoAction)gotoAction); } else { throw new ParserException("Tabla de acciones inválida en el estado"); } }
public PureProduction(string name, int elemCount, ReduceAction action) { Name = name; ElemCount = elemCount; Action = action; }
private void SetAction(ParserState state, ProductionEntry key, ParserAction newAction) { if (key is NonTerminal nt) { Console.WriteLine(); } if (state.Action.ContainsKey(key.ID)) { var oldAction = state.Action[key.ID]; if (oldAction.ToString() == newAction.ToString()) { return; } if (!(oldAction is AcceptAction) && !(newAction is AcceptAction)) { if (oldAction.Name != newAction.Name) { //Shift/Reduce Conflict ShiftAction shiftAction = (oldAction.Name == "shift" ? oldAction : newAction) as ShiftAction; ReduceAction reduceAction = (oldAction.Name == "shift" ? newAction : oldAction) as ReduceAction; var prod = reduceAction.Production; var term = key as Terminal; //Resolve based on precedence and associativity if (prod.Precendece > term.Precedence || (prod.Precendece == term.Precedence && prod.Associatvity == OperatorAssociativity.Left)) { state.Action[key.ID] = reduceAction; } else { state.Action[key.ID] = shiftAction; } return; } else if (newAction is ReduceAction) { //Reduce/Reduce conflict var newProd = (newAction as ReduceAction).Production; var oldProd = (oldAction as ReduceAction).Production; bool newFirst = false; if (newProd.Lhs != oldProd.Lhs) { //Find the NonTerminal to appear first newFirst = newProd.Lhs.ID < oldProd.Lhs.ID; } else { //Find the production to appear first foreach (var p in newProd.Lhs.Productions) { if (p != newProd && p != oldProd) { continue; } if (p == newProd) { newFirst = true; } break; } } //Resolve based on first appearance if (newFirst) { state.Action[key.ID] = newAction; } return; } else { throw new Exception($"Conflict in state {state} on entry {key}. Cannot resolve shift/shift conflict."); } } } state.Action[key.ID] = newAction; }