protected override void SetupExtraParserElements() { terminates = new Dictionary <AdvanceableProduction, AdvanceableRule>(); memo = new Dictionary <AdvanceableRule, Dictionary <string, LookaheadRule> >(); singles = new Dictionary <string, Dictionary <string, Dictionary <AdvanceableProduction, LookaheadRule> > >(); baseToken = new Token <string>(TerminateSymbol, TerminateSymbol, TerminateSymbol.Length); stateStack = new Stack <object>(); initial = new LookaheadRule(TerminateSymbol, TargetGrammar[0]); cPrime = new List <List <LookaheadRule> >(); advProds = new Dictionary <Production, AdvanceableProduction>(); skipList = new Dictionary <string, AdvanceableRule>(); firstCache = new Dictionary <string, IEnumerable <string> >(); advancementDict = new Dictionary <AdvanceableProduction, AdvanceableProduction>(); initialListing = new Dictionary <Rule, AdvanceableRule>(); // actionTable = new LR1ParsingTable(); // gotoTable = new LR1GotoTable(); PopulateAdvProds(); PopulateInitialListings(); PopulateSkipList(); PopulateFirstCache(); PopulateNextCache(); PopulateMemoCache(); PopulateSinglesCache(); }
public EnhancedLR1Parser(EnhancedGrammar g, string terminateSymbol, EnhancedParsingTable table, SemanticRule r) : base(g, terminateSymbol, r, true, false) { this.table = table; baseToken = new Token <string>(TerminateSymbol, TerminateSymbol, TerminateSymbol.Length); stateStack = new Stack <object>(); initial = new LookaheadRule(TerminateSymbol, TargetGrammar[0]); }
public LR1Parser(Cortex.Grammar.Grammar g, string terminateSymbol, LR1ParsingTable table, LR1GotoTable gotoTable, SemanticRule r) : base(g, terminateSymbol, r, true, false) { this.actionTable = table; this.gotoTable = gotoTable; this.onAccept = r; baseToken = new Token <string>(TerminateSymbol, TerminateSymbol, TerminateSymbol.Length); stateStack = new Stack <object>(); initial = new LookaheadRule(TerminateSymbol, TargetGrammar[0]); }
protected virtual void PopulateFirstCache() { LookaheadRule temp = new LookaheadRule(); foreach (var v in skipList) { temp.Repurpose(v.Key); temp.Repurpose(v.Value); First(temp, 0); } }
protected virtual void PopulateMemoCache() { foreach (var v in initialListing) { var dict = new Dictionary <string, LookaheadRule>(); dict[TerminateSymbol] = new LookaheadRule(TerminateSymbol, v.Value); foreach (var q in TargetGrammar.TerminalSymbols) { dict[q] = new LookaheadRule(q, v.Value); } memo[v.Value] = dict; } }
protected virtual void PopulateSinglesCache() { var symbs = TargetGrammar.TerminalSymbols.Concat(new string[] { TerminateSymbol }).ToArray(); for (int i = 0; i < TargetGrammar.Count; i++) { var v = TargetGrammar[i]; singles[v.Name] = new Dictionary <string, Dictionary <AdvanceableProduction, LookaheadRule> >(); var ii = initialListing[v]; for (int j = 0; j < ii.Count; j++) { var p = ii[j]; for (int k = 0; k < symbs.Length; k++) //foreach(var symb in TargetGrammar.TerminalSymbols.Concat(new string[] { TerminateSymbol } )) { var symb = symbs[k]; if (!singles[v.Name].ContainsKey(symb)) { singles[v.Name][symb] = new Dictionary <AdvanceableProduction, LookaheadRule>(); } var iter = p; while (iter.HasNext) { var tmp = advancementDict[iter]; LookaheadRule lr = new LookaheadRule(); lr.Repurpose(v.Name); lr.LookaheadSymbol = symb; lr.Add(tmp); singles[v.Name][symb][iter] = lr; iter = tmp; } LookaheadRule lr2 = new LookaheadRule(); lr2.Repurpose(v.Name); lr2.LookaheadSymbol = symb; lr2.Add(iter); singles[v.Name][symb][iter] = lr2; } } } }
public abstract IEnumerable <string> First(LookaheadRule rule, int lookahead);
public override IEnumerable <string> First(LookaheadRule rule, int lookahead) { HashSet <string> s = new HashSet <string>(); LookaheadRule lr = null; //LookaheadRule lr = new LookaheadRule(); for (int i = 0; i < rule.Count; i++) { var v = rule[i]; if (v.Count == 0) //empty rule { s.Add("<empty>"); continue; } for (int j = lookahead; j < v.Count; j++) { var q = v[j]; //this is some ugly f*****g code. //my better idea is to store a dictionary that //ties a ruleIndex to a list of valid productions //------- //More succintly it lists the values that do not //start with the current rule symbol. It is a far smaller //list and doesn't chew through tons of space. In fact it //doesn't have to be a int but a string to make things more //convienient since we are referring to a rule //------ //Plus it is also precomputed at Parser creation time because it is not //going to change. if (TargetGrammar.Exists(q)) { if (firstCache.ContainsKey(q)) { s.UnionWith(firstCache[q]); break; } else { if (lr == null) { lr = new LookaheadRule(); } if (q.Equals(rule.Name)) //prevent an infinite loop { lr.Repurpose(rule.LookaheadSymbol, skipList[rule.Name]); } else { lr.Repurpose(rule.LookaheadSymbol, TargetGrammar[q]); } IEnumerable <string> result = First(lr, 0); s.UnionWith(result); if (!firstCache.ContainsKey(q)) { firstCache.Add(q, result); } if (result.Contains("<empty>")) { continue; } else { break; } } } else //assume non-terminal { s.Add(q); break; } } } return(s); }