/* ML 2002-09-07 Generates the class "Tokens" * * which maps the token number to meaningfully named integer constants, * * as specified in the NAMES section. */ static void GenTokens() { if (Symbol.tokenNames != null && Symbol.tokenNames.Count > 0) { gen.WriteLine("public class Tokens {"); foreach (DictionaryEntry entry in Symbol.tokenNames) { string token = entry.Key as string; string name = entry.Value as string; if (IsCSharpKW(name)) { Parser.SemErr(name + " is a C# keyword." + "Use another name for the token " + token); continue; } Symbol sym = Symbol.Find(token); if (sym != null && (sym.typ == Node.t || sym.typ == Node.wt)) { gen.WriteLine("\tpublic const int {0} = {1};", name, sym.n); } } gen.WriteLine("}"); } }
static void Factor(out Graph g) { string name; int kind; Position pos; bool weak = false; g = null; switch (la.kind) { case 1: case 3: case 5: case 27: { if (la.kind == 27) { Get(); weak = true; } Sym(out name, out kind); Symbol sym = Symbol.Find(name); bool undef = sym == null; if (undef) { if (kind == id) { sym = new Symbol(Node.nt, name, 0); // forward nt } else if (genScanner) { sym = new Symbol(Node.t, name, t.line); DFA.MatchLiteral(sym); } else // undefined string in production { SemErr("undefined string in production"); sym = Tab.eofSy; // dummy } } int typ = sym.typ; if (typ != Node.t && typ != Node.nt && typ != Node.rslv) /* ML */ { SemErr("this symbol kind is not allowed in a production"); } if (weak) { if (typ == Node.t) { typ = Node.wt; } else { SemErr("only terminals may be weak"); } } Node p = new Node(typ, sym, t.line); g = new Graph(p); if (la.kind == 24) { Attribs(p); if (kind != id) { SemErr("a literal must not have attributes"); } } if (undef) { sym.attrPos = p.pos; // dummy } else if ((p.pos == null) != (sym.attrPos == null)) { SemErr("attribute mismatch between declaration and use of this symbol"); } break; } case 28: { Get(); Expression(out g); Expect(29); break; } case 30: { Get(); Expression(out g); Expect(31); Graph.MakeOption(g); break; } case 32: { Get(); Expression(out g); Expect(33); Graph.MakeIteration(g); break; } case 38: { SemText(out pos); Node p = new Node(Node.sem, null, 0); p.pos = pos; g = new Graph(p); break; } case 23: { Get(); Node p = new Node(Node.any, null, 0); // p.set is set in Tab.SetupAnys g = new Graph(p); break; } case 34: { Get(); Node p = new Node(Node.sync, null, 0); g = new Graph(p); break; } default: SynErr(53); break; } }
static void TokenDecl(int typ) { string name; int kind; Symbol sym; Graph g; Sym(out name, out kind); sym = Symbol.Find(name); if (sym != null) { SemErr("name declared twice"); } else { sym = new Symbol(typ, name, t.line); sym.tokenKind = Symbol.classToken; } while (!(StartOf(13))) { SynErr(46); Get(); } if (la.kind == 8) { Get(); TokenExpr(out g); Expect(9); if (kind != id) { SemErr("a literal must not be declared with a structure"); } Graph.Finish(g); DFA.ConvertToStates(g.l, sym); } else if (la.kind == 9) { Get(); if (typ != Node.rslv) { SemErr("resolver is only allowed in RESOLVERS section"); } } else if (StartOf(14)) { if (kind == id) { genScanner = false; } else { DFA.MatchLiteral(sym); } } else { SynErr(47); } if (la.kind == 38) { SemText(out sym.semPos); if (typ == Node.t) { SemErr("semantic action not allowed here"); } } else if (StartOf(15)) { if (typ == Node.rslv) { SemErr("resolvers must have a semantic action"); } } else { SynErr(48); } }
static void Coco() { Symbol sym; Graph g; string gramName; if (la.kind == 40) { UsingDecl(out ParserGen.usingPos); } Expect(6); int gramLine = t.line; genScanner = true; bool ok = true; Tab.ignored = null; Expect(1); gramName = t.val; int beg = la.pos; while (StartOf(1)) { Get(); } Tab.semDeclPos = new Position(beg, la.pos - beg, 0); while (StartOf(2)) { Declaration(); } while (!(la.kind == 0 || la.kind == 7)) { SynErr(43); Get(); } Expect(7); if (genScanner) { DFA.MakeDeterministic(); } Graph.DeleteNodes(); while (la.kind == 1) { Get(); sym = Symbol.Find(t.val); bool undef = sym == null; if (undef) { sym = new Symbol(Node.nt, t.val, t.line); } else { if (sym.typ == Node.nt) { if (sym.graph != null) { SemErr("name declared twice"); } } else { SemErr("this symbol kind not allowed on left side of production"); } sym.line = t.line; } bool noAttrs = sym.attrPos == null; sym.attrPos = null; if (la.kind == 24) { AttrDecl(sym); } if (!undef) { if (noAttrs != (sym.attrPos == null)) { SemErr("attribute mismatch between declaration and use of this symbol"); } } if (la.kind == 38) { SemText(out sym.semPos); } ExpectWeak(8, 3); Expression(out g); sym.graph = g.l; Graph.Finish(g); ExpectWeak(9, 4); } Expect(10); Expect(1); if (gramName != t.val) { SemErr("name does not match grammar name"); } Tab.gramSy = Symbol.Find(gramName); if (Tab.gramSy == null) { SemErr("missing production for grammar name"); } else { sym = Tab.gramSy; if (sym.attrPos != null) { SemErr("grammar symbol must not have attributes"); } } Tab.noSym = new Symbol(Node.t, "???", 0); // noSym gets highest number Tab.SetupAnys(); Tab.RenumberPragmas(); if (Tab.ddt[2]) { Node.PrintNodes(); } if (Errors.count == 0) { Console.WriteLine("checking"); Tab.CompSymbolSets(); ok = ok && Tab.GrammarOk(); if (Tab.ddt[7]) { Tab.XRef(); } if (ok) { Console.Write("parser"); ParserGen.WriteParser(); if (genScanner) { Console.Write(" + scanner"); DFA.WriteScanner(); if (Tab.ddt[0]) { DFA.PrintStates(); } } Console.WriteLine(" generated"); if (Tab.ddt[8]) { ParserGen.WriteStatistics(); } } } if (Tab.ddt[6]) { Tab.PrintSymbolTable(); } Expect(9); }