public static List<GrammarRule> AugmentGrammar(List<GrammarRule> theGrammar) { List<GrammarRule> AugmentedGrammar = new List<GrammarRule>(); GrammarRule FirstRule = theGrammar[0]; if (!FirstRule.Expression[FirstRule.Expression.Count - 1].Equals(getEndSymbol())) { String ExtraRuleName = FirstRule.RuleSymbol.id + "'"; Symbol[] ExtraRuleExpression = new Symbol[] { new Symbol(FirstRule.RuleSymbol.id), getEndSymbol() }; GrammarRule ExtraRule = new GrammarRule(ExtraRuleName, ExtraRuleExpression); AugmentedGrammar.Add(ExtraRule); } foreach (GrammarRule rule in theGrammar) { AugmentedGrammar.Add(rule); } return AugmentedGrammar; }
private static HashSet<Symbol> Follow(Symbol B, List<GrammarRule> theGrammar) { HashSet<Symbol> result = new HashSet<Symbol>(); foreach (GrammarRule rule in theGrammar) { if (rule.Expression.Contains(B)) { for (int i = 0; i < rule.Expression.Count; i++) // iterate through every expression member { if (rule.Expression[i].Equals(B)) // if it's equal to our symbol... { bool isEpsylon = true; for (int j = i + 1; j < rule.Expression.Count; j++) // iterate through reamining members { // check if they are all epsylon isEpsylon = isEpsylon && rule.Expression[j].Equals(Lr0GenerationHelper.getEpsylonSymbol()); } if (!isEpsylon) { // if rest is not epsylon List<Symbol> RemainingSymbols = rule.Expression.GetRange(i + 1, rule.Expression.Count - (i + 1)); HashSet<Symbol> FirstSet = First(RemainingSymbols, theGrammar); FirstSet.Remove(Lr0GenerationHelper.getEpsylonSymbol()); result.UnionWith(FirstSet); } if (i == rule.Expression.Count - 1) // if it's the final production { if (!rule.RuleSymbol.Equals(B)) result.UnionWith(Follow(rule.RuleSymbol, theGrammar)); } else { List<Symbol> RemainingSymbols = rule.Expression.GetRange(i + 1, rule.Expression.Count - (i + 1)); if (First(RemainingSymbols, theGrammar).Contains(Lr0GenerationHelper.getEpsylonSymbol())) { if (!rule.RuleSymbol.Equals(B)) result.UnionWith(Follow(rule.RuleSymbol, theGrammar)); } } } } } } return result; }
private static HashSet<Symbol> First(Symbol X, List<GrammarRule> theGrammar) { HashSet<Symbol> result = new HashSet<Symbol>(); if (X.isTerminal) result.Add(X); //If it's terminal.. just add it else { foreach (GrammarRule rule in theGrammar) { if (X.Equals(rule.RuleSymbol)) // if productions looks like X --> _______ { if (rule.Expression[0].isTerminal) { result.Add(rule.Expression[0]); } else { HashSet<Symbol> YsFirst = First(rule.Expression, theGrammar); result.UnionWith(YsFirst); } } } } return result; }
public static Lr0State Goto(Lr0State theState, Symbol inputSymbol, List<GrammarRule> theGrammar) { List<Item> generatedItems = theState.GetGotoItems(inputSymbol); Lr0State resultState = new Lr0State(generatedItems); return Closure(resultState, theGrammar); }
public List<Item> GetGotoItems(Symbol theSymbol) { List<Item> ResultSet = new List<Item>(); foreach (Item Production in itemSet) { if (!Production.isFinal()) { if (Production.getCurrentSymbol().Equals(theSymbol)) { Item ItemToAdd = new Item(Production.Rule, Production.Position + 1); ResultSet.Add(ItemToAdd); } } } return ResultSet; }
public GrammarRule(string theName, Symbol[] theExpression) { RuleSymbol = new Symbol(theName); Expression = new List<Symbol>(theExpression); }