private Production CreateProduction(NonTerminal lvalue, BnfTermList operands) { Production prod = new Production(lvalue); //create RValues list skipping Empty terminal and collecting grammar hints foreach (BnfTerm operand in operands) { if (operand == Grammar.Empty) { continue; } //Collect hints as we go - they will be added to the next non-hint element GrammarHint hint = operand as GrammarHint; if (hint != null) { hint.Position = prod.RValues.Count; prod.Hints.Add(hint); continue; } //Check if it is a Terminal or Error element Terminal t = operand as Terminal; if (t != null) { prod.Flags |= ProductionFlags.HasTerminals; if (t.Category == TokenCategory.Error) { prod.Flags |= ProductionFlags.IsError; } } //Add the operand info and LR0 Item _itemID++; LR0Item item = new LR0Item(prod, prod.RValues.Count, _itemID); prod.LR0Items.Add(item); prod.RValues.Add(operand); }//foreach operand //set the flags if (lvalue == Data.AugmentedRoot) { prod.Flags |= ProductionFlags.IsInitial; } if (prod.RValues.Count == 0) { prod.Flags |= ProductionFlags.IsEmpty; } //Add final LRItem _itemID++; prod.LR0Items.Add(new LR0Item(prod, prod.RValues.Count, _itemID)); return(prod); }
} //method //Checks Reduce productions of an action for a ReduceThis hint. If found, the production is moved to the beginning of the list. private bool CheckReduceHint(ActionRecord action) { foreach (Production prod in action.ReduceProductions) { GrammarHint reduceHint = GetHint(prod, prod.RValues.Count, HintType.ReduceThis); if (reduceHint != null) { action.ReduceProductions.Remove(prod); action.ReduceProductions.Insert(0, prod); action.ActionType = ParserActionType.Reduce; action.ConflictResolved = true; return(true); } //if } //foreach prod return(false); } //method
//Checks shift items for PreferShift grammar hint. Hints are associated with a particular position // inside production, which is in fact an LR0 item. The LR0 item is available thru shiftItem.Core property. // If PreferShift hint found, moves the hint-owning shiftItem to the beginning of the list and returns true. private bool CheckShiftHint(ActionRecord action) { foreach (LRItem shiftItem in action.ShiftItems) { GrammarHint shiftHint = GetHint(shiftItem.Core.Production, shiftItem.Core.Position, HintType.PreferShift); if (shiftHint != null) { action.ActionType = ParserActionType.Shift; action.ShiftItems.Remove(shiftItem); action.ShiftItems.Insert(0, shiftItem); action.ConflictResolved = true; return(true); } //if } //foreach shiftItem return(false); } //method
private Production CreateProduction(NonTerminal lvalue, BnfTermList operands) { Production prod = new Production(lvalue); GrammarHintList hints = null; //create RValues list skipping Empty terminal and collecting grammar hints foreach (BnfTerm operand in operands) { if (operand == _grammar.Empty) { continue; } //Collect hints as we go - they will be added to the next non-hint element GrammarHint hint = operand as GrammarHint; if (hint != null) { if (hints == null) { hints = new GrammarHintList(); } hints.Add(hint); continue; } //Add the operand and create LR0 Item prod.RValues.Add(operand); prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count - 1, hints)); hints = null; }//foreach operand //set the flags if (prod.RValues.Count == 0) { prod.Flags |= ProductionFlags.IsEmpty; } //Add final LRItem ComputeProductionFlags(prod); prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints)); return(prod); }
protected GrammarHint ImplyPrecedenceHere(int precedence, Associativity associativity) { var hint = new GrammarHint(HintType.Precedence, null); hint.Precedence = precedence; hint.Associativity = associativity; return hint; }