public void CreateSpecialProduction(NonTerminal root) { this.rootProduction = new Production(this.LookupNonTerminal("$accept")); this.AddProduction(this.rootProduction); this.rootProduction.rhs.Add(root); this.rootProduction.rhs.Add(this.LookupTerminal(GrammarToken.Symbol, "EOF")); }
public SemanticAction(Production production, int startLine, int pos, string commands) { this.production = production; this.pos = pos; this.startLine = startLine; this.commands = commands; }
private void AddNonKernal(Production production) { ProductionItem item = new ProductionItem(production, 0); if (!this.all_items.Contains(item)) { this.all_items.Add(item); this.AddClosure(item); } }
public 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; } }
public static void Calculate(Production p) { 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; return; } } } }
public State(Production production) { this.num = State.TotalStates++; this.AddKernal(production, 0); }
public ProductionItem(Production production, int pos) { this.production = production; this.pos = pos; }
public void CreateSpecialProduction(NonTerminal root) { rootProduction = new Production(LookupNonTerminal("$accept")); AddProduction(rootProduction); rootProduction.rhs.Add(root); rootProduction.rhs.Add(LookupTerminal(GrammarToken.Symbol, "END_OF_FILE")); }
private void GenerateRule(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("});"); }
private void AddKernal(Production production, int pos) { ProductionItem item = new ProductionItem(production, pos); kernal_items.Add(item); all_items.Add(item); }
public void AddProduction(Production production) { this.productions.Add(production); production.num = this.productions.Count; }
public State(Production production) { num = TotalStates++; AddKernal(production, 0); }
private State PathTo(State q, Production prod, int prefix) { for (int i = 0; i < prefix; i++) { Symbol key = prod.rhs[i]; if (!q.Goto.ContainsKey(key)) { return null; } q = q.Goto[key]; } return q; }
public void AddProduction(Production production) { productions.Add(production); production.num = productions.Count; }
private void GenerateRule(Production production) { this.output.Write(" new Rule(" + production.lhs.num + ", new int[]{"); bool flag = true; foreach (Symbol current in production.rhs) { if (!flag) { this.output.Write(","); } else { flag = false; } this.output.Write("{0}", current.num); } this.output.WriteLine("}),"); }
private State PathTo(State 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; }
private void ParseRhs(NonTerminal lhs) { Production production = new Production(lhs); int pos = 0; while (token == GrammarToken.Symbol || token == GrammarToken.Literal || token == GrammarToken.Action || token == GrammarToken.Prec) { switch (token) { case GrammarToken.Literal: { production.rhs.Add(grammar.LookupTerminal(token, scanner.yylval)); Advance(); pos++; break; } case GrammarToken.Symbol: { if (grammar.terminals.ContainsKey(scanner.yylval)) production.rhs.Add(grammar.terminals[scanner.yylval]); else production.rhs.Add(grammar.LookupNonTerminal(scanner.yylval)); Advance(); pos++; break; } case GrammarToken.Prec: { Advance(); if (token == GrammarToken.Symbol) { production.prec = grammar.LookupTerminal(token, scanner.yylval).prec; Advance(); } else scanner.ReportError("Expected symbol after %prec"); break; } case GrammarToken.Action: { SemanticAction semanticAction = new SemanticAction(production, pos, scanner.yylval); Advance(); if (token == GrammarToken.Divider || token == GrammarToken.SemiColon || token == GrammarToken.Prec) // reduce action production.semanticAction = semanticAction; else { NonTerminal node = grammar.LookupNonTerminal("@" + (++grammar.NumActions).ToString()); Production nullProduction = new Production(node); nullProduction.semanticAction = semanticAction; grammar.AddProduction(nullProduction); production.rhs.Add(node); } pos++; break; } } } grammar.AddProduction(production); Precedence.Calculate(production); }
private void ParseRhs(NonTerminal lhs) { Production production = new Production(lhs); int num = 0; while (this.token == GrammarToken.Symbol || this.token == GrammarToken.Literal || this.token == GrammarToken.Action || this.token == GrammarToken.Prec) { GrammarToken grammarToken = this.token; switch (grammarToken) { case GrammarToken.Symbol: if (this.grammar.terminals.ContainsKey(this.scanner.yylval)) { production.rhs.Add(this.grammar.terminals[this.scanner.yylval]); } else { production.rhs.Add(this.grammar.LookupNonTerminal(this.scanner.yylval)); } this.Advance(); num++; break; case GrammarToken.Literal: production.rhs.Add(this.grammar.LookupTerminal(this.token, this.scanner.yylval)); this.Advance(); num++; break; case GrammarToken.Action: { SemanticAction semanticAction = new SemanticAction(production, this.tokenStartLine, num, this.scanner.yylval); this.Advance(); if (this.token == GrammarToken.Divider || this.token == GrammarToken.SemiColon || this.token == GrammarToken.Prec) { production.semanticAction = semanticAction; } else { Grammar arg_1BA_0 = this.grammar; string arg_1B5_0 = "@"; int num2 = ++this.grammar.NumActions; NonTerminal nonTerminal = arg_1BA_0.LookupNonTerminal(arg_1B5_0 + num2.ToString()); Production production2 = new Production(nonTerminal); production2.semanticAction = semanticAction; this.grammar.AddProduction(production2); production.rhs.Add(nonTerminal); } num++; break; } default: if (grammarToken == GrammarToken.Prec) { this.Advance(); if (this.token == GrammarToken.Symbol) { production.prec = this.grammar.LookupTerminal(this.token, this.scanner.yylval).prec; this.Advance(); } else { this.scanner.ReportError("Expected symbol after %prec", new object[0]); } } break; } } this.grammar.AddProduction(production); Precedence.Calculate(production); }
private void GenerateActionMethod(List <Production> productions) { // TODO: parameterize; it seems that 0 is optimal though const int GroupSizeLog = 0; int groupSize = 1 << GroupSizeLog; int mask = groupSize - 1; int groupCount = (productions.Count >> GroupSizeLog) + ((productions.Count & mask) != 0 ? 1 : 0); Console.WriteLine(" protected override void DoAction(int action)"); Console.WriteLine(" {"); List <int> nonEmptyProductionCounts = new List <int>(); for (int g = 0; g < groupCount; g++) { int nonEmptyCount = 0; for (int i = 0; i < groupSize; i++) { int index = (g << GroupSizeLog) + i; if (index >= productions.Count) { break; } if (productions[index].semanticAction != null) { nonEmptyCount++; } } nonEmptyProductionCounts.Add(nonEmptyCount); } Debug.Assert(nonEmptyProductionCounts.Count == groupCount); if (groupCount > 1) { if (groupSize > 1) { Console.WriteLine(" int mod = action & 0x{0:X};", mask); Console.WriteLine(" switch (action >> {0})", GroupSizeLog); } else { Console.WriteLine(" switch (action)", GroupSizeLog); } Console.WriteLine(" {"); for (int g = 0; g < groupCount; g++) { if (nonEmptyProductionCounts[g] > 0) { Console.WriteLine(" case {0}: _{0}({1}); return;", g, groupSize > 1 ? "mod" : ""); } } Console.WriteLine(" }"); } else { Console.WriteLine(" _0(action);"); } Console.WriteLine(" }"); Console.WriteLine(); for (int g = 0; g < groupCount; g++) { if (nonEmptyProductionCounts[g] > 0) { Console.WriteLine(" private void _{0}({1})", g, groupSize > 1 ? "int mod" : ""); Console.WriteLine(" {"); if (groupSize > 1) { Console.WriteLine(" switch (mod)"); Console.WriteLine(" {"); } for (int i = 0; i < groupSize; i++) { int index = (g << GroupSizeLog) + i; if (index >= productions.Count) { break; } Production production = productions[index]; Debug.Assert(index == production.num - 1); if (production.semanticAction != null) { if (groupSize > 1) { Console.WriteLine(" case {0}:", i); } Console.WriteLine(" // " + production.ToString()); production.semanticAction.GenerateCode(this); if (groupSize > 1) { Console.WriteLine(" return;"); } } } if (groupSize > 1) { Console.WriteLine(" default: return;"); Console.WriteLine(" }"); } Console.WriteLine(" }"); Console.WriteLine(); } } }