protected override void MakeGotoTable() { List <LookaheadRule> g = new List <LookaheadRule>(); int state = 0; for (int j = 0; j < cPrime.Count; j++) { var Ii = cPrime[j]; for (int k = 0; k < Ii.Count; k++) { var rule = Ii[k]; for (int z = 0; z < rule.Count; z++) { var prod = rule[z]; var curr = prod.Current; if (curr == null) { continue; } if (TargetGrammar.Exists(curr)) { g.AddRange(ComputeGoto(Ii, curr)); AddToGotoTable((int)GetIndex(g), curr, state); g.Clear(); } } } state++; } }
public override object Parse(IEnumerable <Token <string> > tokens, string input) { var _input = tokens.Concat(new [] { baseToken }); stateStack.Clear(); stateStack.Push(baseToken); stateStack.Push((uint)0); Queue <Token <string> > _i = new Queue <Token <string> >(_input); var a = _i.Dequeue(); uint s = 0; var result = table[a.TokenType][(int)s]; while (true) { //object __input = stateStack.Peek(); //Console.WriteLine("typeof input is {0}", __input.GetType()); s = (uint)stateStack.Peek(); result = table[a.TokenType][(int)s]; IEnumerable <uint> encoding = enc.Decode(result); TableCellAction action = (TableCellAction)encoding.ElementAt(0); uint targetRule = encoding.ElementAt(1); uint targetProduction = encoding.ElementAt(2); switch (action) { case TableCellAction.Shift: stateStack.Push(a); stateStack.Push(targetProduction); a = _i.Dequeue(); break; case TableCellAction.Reduce: var rule = TargetGrammar.LookupRule(Encode(targetRule, targetProduction)); var firstRule = rule[0]; int count = firstRule.Count; //not the rule's length but the rule's first production's length object[] elements = new object[count]; for (int i = 0; i < count; i++) { stateStack.Pop(); //targetState elements[i] = stateStack.Pop(); } var element = (uint)stateStack.Peek(); //we just do the goto anyway var next = enc.Decode(table[rule.Name][(int)element]); var quantity = firstRule.Rule(elements.Reverse().ToArray()); stateStack.Push(quantity); stateStack.Push(next.ElementAt(2)); break; case TableCellAction.Accept: if (!SupressMessages) { Console.WriteLine("State Stack Contents before accept"); foreach (var v in stateStack) { Console.WriteLine(v); } } stateStack.Pop(); return(onAccept(new object[] { stateStack.Pop() })); case TableCellAction.Error: Console.WriteLine("Error Occurred at position {0}, {1}", a.Start, a.Value); Console.WriteLine("{0}", input.Substring(0, a.Start + 1)); return(false); } } }
protected override void MakeTable() { List <LookaheadRule> Ij = new List <LookaheadRule>(); int state = 0; for (int k = 0; k < cPrime.Count; k++) { var Ii = cPrime[k]; for (int q = 0; q < Ii.Count; q++) { var rule = Ii[q]; for (int b = 0; b < rule.Count; b++) { var prod = rule[b]; if (!prod.HasNext) { if (prod.Target.Equals(initial[0].Target)) { MakeTable_SetAcceptState(state, TerminateSymbol); } else { Encoding rev = TargetGrammar.ReverseLookup(rule.Name, prod); TableCellAction action = MakeTable_ExtractAction(state, rule.LookaheadSymbol); switch (action) { case TableCellAction.Accept: if (!SupressMessages && MakeTable_Reduce_Condition(rev, state, rule.LookaheadSymbol)) { Console.WriteLine("WTF Mate, attempt to overwrite accept state"); } break; case TableCellAction.Reduce: if (!SupressMessages && MakeTable_Reduce_Condition(rev, state, rule.LookaheadSymbol)) { Console.WriteLine("Reduce/Reduce Conflict detected with rule {0}", rule.Name); } break; case TableCellAction.Shift: if (!SupressMessages && MakeTable_Reduce_Condition(rev, state, rule.LookaheadSymbol)) { Console.WriteLine("Shift/Reduce Conflict detected with rule {0}", rule.Name); } break; case TableCellAction.Goto: throw new Exception("This is an error! You shouldn't have gotten here!!!!"); case TableCellAction.Error: default: MakeTable_SetReduceState(state, rule.LookaheadSymbol, rev); break; } } } else { var a = prod.Current; if (TargetGrammar.IsTerminalSymbol(a)) { Ij.AddRange(ComputeGoto(Ii, a)); int targetState = GetIndex(Ij); Ij.Clear(); var action = MakeTable_ExtractAction(state, a); //var original = _st[a]; switch (action) { case TableCellAction.Shift: if (!SupressMessages && MakeTable_Shift_Condition(targetState, state, a)) { Console.WriteLine("Shift/Shift Conflict detected with rule {0}", rule.Name); } break; case TableCellAction.Reduce: if (!SupressMessages && MakeTable_Shift_Condition(targetState, state, a)) { Console.WriteLine("Reduce/Shift Conflict detected with rule {0}", rule.Name); } break; case TableCellAction.Accept: if (!SupressMessages && MakeTable_Shift_Condition(targetState, state, a)) { Console.WriteLine("WTF Mate, attempt to overwrite accept state"); } break; case TableCellAction.Goto: throw new Exception("This is an error! You shouldn't have gotten here!!!!"); case TableCellAction.Error: default: MakeTable_SetShiftState(state, a, targetState); // _st[a] = new LR1ParsingTableCell( // LR1ParsingTableEntryAction.Shift, targetState); break; } } } } } state++; } #if DEBUG Console.WriteLine("Make Table Took {0}", DateTime.Now - start); #endif }
internal override void MarkReachableDefs() { TargetGrammar.MarkReacheableDefine(this.name); }
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); }
public override IEnumerable <LookaheadRule> Closure( IEnumerable <LookaheadRule> rules, string terminateSymbol) { //Closure is more refined. //If [A → α • B β, a] belongs to the set of items, //and B → γ is a production of the grammar, //then we add the item [B → • γ, b] for all b in FIRST(β a). HashSet <LookaheadRule> rr = new HashSet <LookaheadRule>(rules); int size = currentRules.Count; do { size = rr.Count; //get rid of the foreach (var rule in rr) { var a = rule.LookaheadSymbol; var container = singles[rule.Name][rule.LookaheadSymbol]; for (int j = 0; j < rule.Count; j++) { var p = rule[j]; string symbol = p.Current; if (!p.HasNext) { nullTerminators.Add(terminates[p]); } else { if (TargetGrammar.Exists(symbol)) { AdvanceableProduction betaProd = advancementDict[p]; //create beta var target = initialListing[TargetGrammar[symbol]]; //grab the B-Production var actualTarget = memo[target]; if (!betaProd.HasNext && a.Equals(terminateSymbol)) { currentRules.Add(actualTarget[terminateSymbol]); } else { if (betaProd.HasNext) { var next = container[p]; var ff = First(next, betaProd.Position); foreach (var v in ff) { currentRules.Add(actualTarget[v]); } } currentRules.Add(actualTarget[a]); } } } } } rr.UnionWith(currentRules); currentRules.Clear(); }while(rr.Count != size); for (int n = 0; n < nullTerminators.Count; n++) { var v = nullTerminators[n]; string name = v.Name; foreach (var s in rr) { if (s.Name.Equals(name)) { foreach (var qq in v) { if (!s.Contains(qq)) { s.Add(qq); } } } } } if (nullTerminators.Count > 0) { nullTerminators.Clear(); } if (currentRules.Count > 0) { currentRules.Clear(); } return(rr); }
protected object CoreParse(IEnumerable <Token <string> > tokens, string input, bool printErrorMessages, bool invokeRules) { var _input = tokens.Concat(new [] { baseToken }); stateStack.Clear(); stateStack.Push(baseToken); stateStack.Push(0); Queue <Token <string> > _i = new Queue <Token <string> >(_input); var a = _i.Dequeue(); int s = 0; var result = actionTable[s, a.TokenType]; while (true) { s = (int)stateStack.Peek(); result = actionTable[s, a.TokenType]; switch (result.Action) { case TableCellAction.Shift: stateStack.Push(a); stateStack.Push(result.TargetState); a = _i.Dequeue(); break; case TableCellAction.Reduce: var rule = TargetGrammar.LookupRule(result.TargetState); var firstRule = rule[0]; int count = firstRule.Count; //not the rule's length but the rule's first production's length object[] elements = new object[count]; for (int i = 0; i < count; i++) { stateStack.Pop(); //targetState elements[i] = stateStack.Pop(); } var element = (int)stateStack.Peek(); var next = gotoTable[element, rule.Name]; if (invokeRules) { var quantity = firstRule.Rule(elements.Reverse().ToArray()); stateStack.Push(quantity); } else { stateStack.Push(new object()); } stateStack.Push(next); break; case TableCellAction.Accept: if (!SupressMessages) { Console.WriteLine("State Stack Contents before accept"); foreach (var v in stateStack) { Console.WriteLine(v); } } stateStack.Pop(); if (invokeRules) { return(onAccept(new object[] { stateStack.Pop() })); } else { return(true); } case TableCellAction.Error: if (printErrorMessages) { Console.WriteLine("Error Occurred at position {0}, {1}", a.Start, a.Value); Console.WriteLine("{0}", input.Substring(0, a.Start + 1)); } return(false); } } }