internal SemanticAction(Production production, int pos, LexSpan span) { this.production = production; this.pos = pos; this.codeSpan = span; commands = span.ToString(); }
private void AddNonKernel(Production production) { ProductionItem item = new ProductionItem(production, 0); if (!allItems.Contains(item)) { allItems.Add(item); AddClosure(item); } }
internal static void Calculate(Production p) { // // Precedence of a production is that of its rightmost terminal // unless explicitly labelled with %prec // if (p.prec == null) { Terminal last = p.RightmostTerminal(); if (last != null) p.prec = last.prec; } }
internal static void Calculate(Production p) { // Precedence of a production is that of its rightmost terminal // unless explicitly labelled with %prec if (p.prec == null) for (int i = p.rhs.Count - 1; i >= 0; i--) if (p.rhs[i] is Terminal) { p.prec = ((Terminal)p.rhs[i]).prec; break; } }
private static AutomatonState PathTo(AutomatonState q, Production prod, int prefix) { // q -> prod.rhs[0] ... prod.rhs[prefix] -> ??? for (int i = 0; i < prefix; i++) { Symbol s = prod.rhs[i]; if (q.Goto.ContainsKey(s)) q = q.Goto[s]; else return null; } return q; }
internal AutomatonState(Production production) { num = TotalStates++; AddKernel(production, 0); }
private void AddKernel(Production production, int pos) { ProductionItem item = new ProductionItem(production, pos); kernelItems.Add(item); allItems.Add(item); }
internal ProductionItem(Production production, int pos) { this.production = production; this.pos = pos; }
private static void GenerateShiftReduceMachineRule( Production production ) { Console.Write( " rules[{0}] = new Rule({1}, new int[]{{", production.num, production.lhs.num ); bool first = true; foreach (Symbol sym in production.rhs) { if (!first) Console.Write( "," ); else first = false; Console.Write( "{0}", sym.num ); } Console.WriteLine( "});" ); }
internal void AddProduction(Production production) { productions.Add(production); production.num = productions.Count; }
internal void BuildParseTable() { foreach (AutomatonState state in states) { // // Add shift actions ... // This makes shift the default action for all // terminal transitions. This is modified as required, // later in this foreach state loop. // foreach (Terminal t in state.terminalTransitions) { state.parseTable[t] = new Shift(state.Goto[t]); } // Add reduce actions ... foreach (ProductionItem item in state.allItems) { if (item.isReduction()) { // Accept on everything if (item.production == grammar.rootProduction) { foreach (Terminal t in grammar.terminals.Values) { state.parseTable[t] = new Reduce(item); } } foreach (Terminal t in item.LA) { // possible conflict with existing action if (state.parseTable.ContainsKey(t)) { Reduce reduceAction; ParserAction other = state.parseTable[t]; Production iProd = item.production; if ((reduceAction = other as Reduce) != null) { Production oProd = reduceAction.item.production; // Choose in favour of production listed first in the grammar if (oProd.num > iProd.num) { state.parseTable[t] = new Reduce(item); } string p1 = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", oProd.num, oProd.ToString()); string p2 = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", iProd.num, iProd.ToString()); int chsn = (oProd.num > iProd.num ? iProd.num : oProd.num); grammar.conflicts.Add(new ReduceReduceConflict(t, p1, p2, chsn, state)); if (GPCG.Verbose) { Console.Error.WriteLine( "Reduce/Reduce conflict in state {0} on symbol {1}", state.num, t.ToString()); Console.Error.WriteLine(p1); Console.Error.WriteLine(p2); } else { Console.Error.WriteLine("Reduce/Reduce conflict, state {0}: {1} vs {2} on {3}", state.num, iProd.num, oProd.num, t); } } else { if (iProd.prec != null && t.prec != null) { if (iProd.prec.prec > t.prec.prec) { // // Production iProd has precedence over t, so Reduce. // state.parseTable[t] = new Reduce(item); // No shift/Reduce warning. } else if (iProd.prec.prec == t.prec.prec) { // // Precedence is equal, so use associativity to decide. // if (t.prec.type == PrecType.left) { // // For %left tokens reduce the left subexpression. // state.parseTable[t] = new Reduce(item); } else if (t.prec.type == PrecType.nonassoc) // && iProd.RightmostTerminal() == t) { // What is the correct semantics here? // If %nonassoc x y, is E x E y E an error? // The YACC spec seems to imply, but not explictly state, // that x,y are non-associative AS A GROUP // rather than just individually non-associative. // // For %nonassoc tokens disallow the shift action, and force // lookahead just in case this state has an LR0 Reduce action. // { state.parseTable.Remove(t); state.ForceLookahead = true; } // else t.prec.type == PrecType.right, so Shift. } // else iProd.prec.prec < t.proc.prec, so Shift anyway. } else // Need to issue a Shift/Reduce warning message. { AutomatonState next = ((Shift)other).next; string p1 = String.Format(CultureInfo.InvariantCulture, " Shift \"{0}\":\tState-{1} -> State-{2}", t, state.num, next.num); string p2 = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", iProd.num, iProd.ToString()); grammar.conflicts.Add(new ShiftReduceConflict(t, p1, p2, state, next)); if (GPCG.Verbose) { Console.Error.WriteLine("Shift/Reduce conflict"); Console.Error.WriteLine(p1); Console.Error.WriteLine(p2); } else { Console.Error.WriteLine("Shift/Reduce conflict, state {0} on {1}", state.num, t); } } } } else { state.parseTable[t] = new Reduce(item); } } } } } }