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; }
public bool Equals(GrammarRule g) { if ((System.Object)g == null) { return false; } if (!RuleSymbol.Equals(g.RuleSymbol)) return false; if (Expression.Count != g.Expression.Count) return false; bool result = true; foreach (var item in g.Expression) { result = result && Expression.Contains(item); } return result; }
static void Main(string[] args) { List<GrammarRule> originalGrammar = new List<GrammarRule>(); List<GrammarRule> Grammar = new List<GrammarRule>(); //GrammarRule Rule1 = new GrammarRule("S", new Symbol[] { new Symbol("leftPar", "("), new Symbol("L"), new Symbol("rightPar", ")") }); //GrammarRule Rule2 = new GrammarRule("S", new Symbol[] { new Symbol("X", "X") }); //GrammarRule Rule3 = new GrammarRule("L", new Symbol[] { new Symbol("S") }); //GrammarRule Rule4 = new GrammarRule("L", new Symbol[] { new Symbol("L"), new Symbol("comma", ","), new Symbol("S") }); //GrammarRule Rule1 = new GrammarRule("S", new Symbol[] { new Symbol("A") }); //GrammarRule Rule2 = new GrammarRule("A", new Symbol[] { new Symbol("a", "a"), new Symbol("A"), new Symbol("d", "d") }); //GrammarRule Rule3 = new GrammarRule("A", new Symbol[] { new Symbol("B"), new Symbol("C") }); //GrammarRule Rule4 = new GrammarRule("B", new Symbol[] { new Symbol("b", "b"), new Symbol("B"), new Symbol("c", "c") }); //GrammarRule Rule5 = new GrammarRule("B", new Symbol[] { Lr0GenerationHelper.Lr0GenerationHelper.getEpsylonSymbol() }); //GrammarRule Rule6 = new GrammarRule("C", new Symbol[] { new Symbol("a", "a"), new Symbol("c", "c"), new Symbol("C") }); //GrammarRule Rule7 = new GrammarRule("C", new Symbol[] { new Symbol("a", "a"), new Symbol("d", "d") }); //GrammarRule Rule1 = new GrammarRule("E", new Symbol[] { new Symbol("T"), new Symbol("Ex") }); //GrammarRule Rule2 = new GrammarRule("Ex", new Symbol[] { new Symbol("+", "+"), new Symbol("T"), new Symbol("Ex") }); //GrammarRule Rule3 = new GrammarRule("Ex", new Symbol[] { Lr0GenerationHelper.Lr0GenerationHelper.getEpsylonSymbol() }); //GrammarRule Rule4 = new GrammarRule("T", new Symbol[] { new Symbol("F"), new Symbol("Tx") }); //GrammarRule Rule5 = new GrammarRule("Tx", new Symbol[] { new Symbol("*", "*"), new Symbol("F"), new Symbol("Tx") }); //GrammarRule Rule6 = new GrammarRule("Tx", new Symbol[] { Lr0GenerationHelper.Lr0GenerationHelper.getEpsylonSymbol() }); //GrammarRule Rule7 = new GrammarRule("F", new Symbol[] { new Symbol("(", "("), new Symbol("E"), new Symbol(")", ")") }); //GrammarRule Rule8 = new GrammarRule("F", new Symbol[] { new Symbol("id", "id") }); GrammarRule Rule0 = new GrammarRule("S", new Symbol[] { new Symbol("E"), Lr0GenerationHelper.getEndSymbol() }); GrammarRule Rule1 = new GrammarRule("E", new Symbol[] { new Symbol("T"), new Symbol("plus", "+"), new Symbol("E") }); GrammarRule Rule2 = new GrammarRule("E", new Symbol[] { new Symbol("T") }); GrammarRule Rule3 = new GrammarRule("T", new Symbol[] { new Symbol("X", "x") }); originalGrammar.Add(Rule0); originalGrammar.Add(Rule1); originalGrammar.Add(Rule2); originalGrammar.Add(Rule3); //originalGrammar.Add(Rule4); //originalGrammar.Add(Rule5); //originalGrammar.Add(Rule6); //originalGrammar.Add(Rule7); //originalGrammar.Add(Rule8); Grammar = Lr0GenerationHelper.AugmentGrammar(originalGrammar); HashSet<input> nonTerminals = new HashSet<input>(); HashSet<Symbol> terminals = new HashSet<Symbol>(); foreach (GrammarRule rule in Grammar) { nonTerminals.Add(rule.RuleSymbol.id); } foreach (GrammarRule rule in Grammar) { foreach (Symbol sym in rule.Expression) { if (sym.isTerminal) { terminals.Add(sym); } } } HashSet<Tuple<dfaState, Symbol, Int32>> reduceStates = new HashSet<Tuple<dfaState, Symbol, Int32>>(); HashSet<input> tokens = new HashSet<input>(); DFA theAutomaton = BuildLr0(Grammar, out reduceStates, out tokens); ParsingTable theParsingTable = GetParsingTable(theAutomaton, tokens, nonTerminals, reduceStates, Grammar); HashSet<Symbol> theInputs = new HashSet<Symbol>(); foreach (GrammarRule rule in Grammar) { foreach (Symbol sym in rule.Expression) { if (sym.isTerminal) { theInputs.Add(sym); } } } foreach (GrammarRule rule in Grammar) { foreach (Symbol sym in rule.Expression) { if (!sym.isTerminal) { theInputs.Add(sym); } } } HashSet<dfaState> theStates = new HashSet<dfaState>(); foreach (KeyValuePair<dfaState, input> key in theParsingTable.transitionTable.Keys) { theStates.Add(key.Key); } #if (DEBUG) foreach (GrammarRule rule in originalGrammar) { Console.WriteLine(rule); } foreach (Symbol item in theInputs) { Console.Write("| " + item.stringRepresentation + "|"); } Console.WriteLine(); foreach (dfaState state in theStates) { foreach (Symbol key in theInputs) { Action tmpAction; if (theParsingTable.transitionTable.TryGetValue(new KeyValuePair<dfaState, input>(state, key.id), out tmpAction)) Console.Write("|" + tmpAction + "|"); else Console.Write("| |"); } Console.WriteLine(); } Console.WriteLine(); HashSet<Symbol> AFirst = First(new Symbol("E"), Grammar); foreach (Symbol sym in AFirst) { Console.Write(sym + ","); } Console.WriteLine(); AFirst = First(new Symbol("Ex"), Grammar); foreach (Symbol sym in AFirst) { Console.Write(sym + ","); } Console.WriteLine(); AFirst = First(new Symbol("T"), Grammar); foreach (Symbol sym in AFirst) { Console.Write(sym + ","); } Console.WriteLine(); AFirst = First(new Symbol("Tx"), Grammar); foreach (Symbol sym in AFirst) { Console.Write(sym + ","); } Console.WriteLine(); AFirst = First(new Symbol("F"), Grammar); foreach (Symbol sym in AFirst) { Console.Write(sym + ","); } Console.WriteLine(); Console.ReadLine(); //------------------- Console.WriteLine(); HashSet<Symbol> AFollow = Follow(new Symbol("E"), Grammar); foreach (Symbol sym in AFollow) { Console.Write(sym + ","); } Console.WriteLine(); AFollow = Follow(new Symbol("Ex"), Grammar); foreach (Symbol sym in AFollow) { Console.Write(sym + ","); } Console.WriteLine(); AFollow = Follow(new Symbol("T"), Grammar); foreach (Symbol sym in AFollow) { Console.Write(sym + ","); } Console.WriteLine(); AFollow = Follow(new Symbol("Tx"), Grammar); foreach (Symbol sym in AFollow) { Console.Write(sym + ","); } Console.WriteLine(); AFollow = Follow(new Symbol("F"), Grammar); foreach (Symbol sym in AFollow) { Console.Write(sym + ","); } Console.WriteLine(); Console.ReadLine(); List<input> theInput = new List<input>(new input[] { "X", "plus", "X", "plus", "X"}); Console.WriteLine(parse(theInput, theParsingTable, Grammar)); Console.ReadLine(); using (System.IO.StreamWriter writer = new System.IO.StreamWriter("grafo.dot")) { writer.Write("digraph G {"); printGraph(theAutomaton, writer); writer.Write("rankdir=LR; }"); } #endif }