void FindAS(Node p, Symbol nonTerminal) { // find ANY sets Node a; while (p != null) { if (p.typ == Node.opt || p.typ == Node.iter) { FindAS(p.sub, nonTerminal); a = LeadingAny(p.sub); if (a != null) { if (p.next == null) Sets.Subtract(a.set, nonTerminal.follow); else Sets.Subtract(a.set, First(p.next)); } } else if (p.typ == Node.alt) { BitArray s1 = new BitArray(terminals.Count); Node q = p; while (q != null) { FindAS(q.sub, nonTerminal); a = LeadingAny(q.sub); if (a != null) Sets.Subtract(a.set, First(q.down).Or(s1)); else s1.Or(First(q.sub)); q = q.down; } } // Remove alternative terminals before ANY, in the following // examples a and b must be removed from the ANY set: // [a] ANY, or {a|b} ANY, or [a][b] ANY, or (a|) ANY, or // A = [a]. A ANY if (DelNode(p)) { a = LeadingAny(p.next); if (a != null) { Node q = (p.typ == Node.nt) ? p.sym.graph : p.sub; Sets.Subtract(a.set, First(q)); } } if (p.up) break; p = p.next; } }
void AttrDecl(Symbol sym) { if (la.kind == 29) { Get(); sym.isAuto = true; sym.attrPos = new Position(t.pos, t.pos + 6, t.col, t.line); } else if (la.kind == 30) { Get(); int beg = la.pos; int col = la.col; while (StartOf(11)) { if (StartOf(12)) { Get(); } else { Get(); SemErr("bad string in attributes"); } } Expect(31); if (t.pos > beg) sym.attrPos = new Position(beg, t.pos, col, t.line); } else if (la.kind == 32) { Get(); int beg = la.pos; int col = la.col; while (StartOf(13)) { if (StartOf(14)) { Get(); } else { Get(); SemErr("bad string in attributes"); } } Expect(33); if (t.pos > beg) sym.attrPos = new Position(beg, t.pos, col, t.line); } else SynErr(55); }
void GenErrorMsg(int errTyp, Symbol sym) { errorNr++; err.Write("\t\t\tcase " + errorNr + ": s = \""); switch (errTyp) { case tErr: if (sym.name[0] == '"') err.Write(tab.Escape(sym.name) + " expected"); else err.Write(sym.name + " expected"); break; case altErr: err.Write("invalid " + sym.name); break; case syncErr: err.Write("this symbol not expected in " + sym.name); break; } err.WriteLine("\"; break;"); }
public void ConvertToStates(Node p, Symbol sym) { curSy = sym; if (Tab.DelGraph(p)) { parser.SemErr("token might be empty"); return; } NumberNodes(p, firstState, true); FindTrans(p, true, new BitArray(tab.nodes.Count)); if (p.typ == Node.iter) { Step(firstState, p, new BitArray(tab.nodes.Count)); } }
// match string against current automaton; store it either as a fixedToken or as a litToken public void MatchLiteral(string s, Symbol sym) { s = tab.Unescape(s.Substring(1, s.Length-2)); int i, len = s.Length; State state = firstState; Action a = null; for (i = 0; i < len; i++) { // try to match s against existing DFA a = FindAction(state, s[i]); if (a == null) break; state = a.target.state; } // if s was not totally consumed or leads to a non-final state => make new DFA from it if (i != len || state.endOf == null) { state = firstState; i = 0; a = null; dirtyDFA = true; } for (; i < len; i++) { // make new DFA for s[i..len-1], ML: i is either 0 or len State to = NewState(); NewTransition(state, to, Node.chr, s[i], Node.normalTrans); state = to; } Symbol matchedSym = state.endOf; if (state.endOf == null) { state.endOf = sym; } else if (matchedSym.tokenKind == Symbol.fixedToken || (a != null && a.tc == Node.contextTrans)) { // s matched a token with a fixed definition or a token with an appendix that will be cut off parser.SemErr("tokens " + sym.name + " and " + matchedSym.name + " cannot be distinguished"); } else { // matchedSym == classToken || classLitToken matchedSym.tokenKind = Symbol.classLitToken; sym.tokenKind = Symbol.litToken; } }
// does not look behind resolvers; only called during LL(1) test and in CheckRes public BitArray Expected0(Node p, Symbol curSy) { if (p.typ == Node.rslv) return new BitArray(terminals.Count); else return Expected(p, curSy); }
public CNode (Symbol l, Symbol r) { left = l; right = r; }
void AttrDecl( #line 293 "Coco.atg" //SOURCE beg=12799,len=10,col=10 Symbol sym #line default //END SOURCE ) { if (la.kind == 25) { Get(); #line 294 "Coco.atg" //SOURCE beg=12850,len=36,col=36 int beg = la.pos; int col = la.col; #line default //END SOURCE while (StartOf(9)) { if (StartOf(10)) { Get(); } else { Get(); #line 296 "Coco.atg" //SOURCE beg=12934,len=36,col=36 SemErr("bad string in attributes"); #line default //END SOURCE } } Expect(26); #line 298 "Coco.atg" //SOURCE beg=13014,len=142,col=36 if (t.pos > beg) sym.attrPos = new Position(beg, t.pos - beg, col, GetVirtualFile(), GetVirtualLine()); #line default //END SOURCE } else if (la.kind == 27) { Get(); #line 300 "Coco.atg" //SOURCE beg=13195,len=36,col=36 int beg = la.pos; int col = la.col; #line default //END SOURCE while (StartOf(11)) { if (StartOf(12)) { Get(); } else { Get(); #line 302 "Coco.atg" //SOURCE beg=13279,len=36,col=36 SemErr("bad string in attributes"); #line default //END SOURCE } } Expect(28); #line 304 "Coco.atg" //SOURCE beg=13359,len=142,col=36 if (t.pos > beg) sym.attrPos = new Position(beg, t.pos - beg, col, GetVirtualFile(), GetVirtualLine()); #line default //END SOURCE } else SynErr(48); }
public void CheckLL1() { foreach (Symbol sym in nonterminals) { curSy = sym; CheckAlts(curSy.graph); } }
void GenProductions() { foreach (Symbol sym in tab.nonterminals) { curSy = sym; gen.Write("\tvoid {0}(", sym.name); if (sym.isAuto) gen.Write("Role role"); else CopySourcePart(sym.attrPos, 0); gen.WriteLine(") {"); if (sym.isAuto) gen.WriteLine("\t\tvar result = new {0}(); NodeStart(result);", sym.name); CopySourcePart(sym.semPos, 2); GenCode(sym.graph, 2, new BitArray(tab.terminals.Count)); if (sym.isAuto) gen.WriteLine("\t\tNodeEnd(result, role);"); gen.WriteLine("\t}"); gen.WriteLine(); } }
void AttrDecl(Symbol sym) { if (la.kind == 24) { Get(); int beg = la.pos; int col = la.col; while (StartOf(9)) { if (StartOf(10)) { Get(); } else { Get(); SemErr("bad string in attributes"); } } Expect(25); if (t.pos > beg) sym.attrPos = new Position(beg, t.pos, col); } else if (la.kind == 26) { Get(); int beg = la.pos; int col = la.col; while (StartOf(11)) { if (StartOf(12)) { Get(); } else { Get(); SemErr("bad string in attributes"); } } Expect(27); if (t.pos > beg) sym.attrPos = new Position(beg, t.pos, col); } else SynErr(45); }
public void ConvertToStates(Node p, Symbol sym) { curGraph = p; curSy = sym; if (tab.DelGraph(curGraph)) parser.SemErr("token might be empty"); NumberNodes(curGraph, firstState); FindTrans(curGraph, true, new BitArray(tab.nodes.Count)); }
BitArray visited; //!< mark list for graph traversals #endregion Fields #region Constructors public Tab(Parser parser) { this.parser = parser; errors = parser.errors; buffer = parser.scanner.buffer; eofSy = NewSym(Node.t, "EOF", 0); dummyNode = NewNode(Node.eps); ignored = new CharSet(); literals = new Hashtable(); }
public int val; //!< chr: ordinal character value #endregion Fields #region Constructors public Node(int typ, Symbol sym, int line, int col) { this.typ = typ; this.sym = sym; this.line = line; this.col = col; }
void CompFollowSets() { foreach (Symbol sym in nonterminals) { sym.follow = new BitArray(terminals.Count); sym.nts = new BitArray(nonterminals.Count); } gramSy.follow[eofSy.n] = true; visited = new BitArray(nodes.Count); foreach (Symbol sym in nonterminals) { // get direct successors of nonterminals curSy = sym; CompFollow(sym.graph); } foreach (Symbol sym in nonterminals) { // add indirect successors to followers visited = new BitArray(nonterminals.Count); curSy = sym; Complete(sym); } }
public void CheckResolvers() { foreach (Symbol sym in nonterminals) { curSy = sym; CheckRes(curSy.graph, false); } }
public BitArray Expected(Node p, Symbol curSy) { BitArray s = First(p); if (DelGraph(p)) s.Or(curSy.follow); return s; }
public State state; // DFA state corresponding to this node // (only used in DFA.ConvertToStates) public Node(int typ, Symbol sym, int line) { this.typ = typ; this.sym = sym; this.line = line; }
void CompSyncSets() { allSyncSets = new BitArray(terminals.Count); allSyncSets[eofSy.n] = true; visited = new BitArray(nodes.Count); foreach (Symbol sym in nonterminals) { curSy = sym; CompSync(curSy.graph); } }
public Tab(Parser parser) { this.parser = parser; trace = parser.trace; errors = parser.errors; eofSy = NewSym(Node.t, "EOF", 0); dummyNode = NewNode(Node.eps, null, 0); literals = new Hashtable(); }
//--------------- check for LL(1) errors ---------------------- void LL1Error(int cond, Symbol sym) { string s = " LL1 warning in " + curSy.name + ": "; if (sym != null) s += sym.name + " is "; switch (cond) { case 1: s += "start of several alternatives"; break; case 2: s += "start & successor of deletable structure"; break; case 3: s += "an ANY node that matches no symbol"; break; case 4: s += "contents of [...] or {...} must not be deletable"; break; } errors.Warning(s); }
public Symbol NewSym(int typ, string name, int line) { if (name.Length == 2 && name[0] == '"') { parser.SemErr("empty token not allowed"); name = "???"; } Symbol sym = new Symbol(typ, name, line); switch (typ) { case Node.t: sym.n = terminals.Count; terminals.Add(sym); break; case Node.pr: pragmas.Add(sym); break; case Node.nt: sym.n = nonterminals.Count; nonterminals.Add(sym); break; } return sym; }
public void GetTargetStates(Action a, out BitArray targets, out Symbol endOf, out bool ctx) { // compute the set of target states targets = new BitArray(maxStates); endOf = null; ctx = false; for (Target t = a.target; t != null; t = t.next) { int stateNr = t.state.nr; if (stateNr <= lastSimState) targets[stateNr] = true; else targets.Or(MeltedSet(stateNr)); if (t.state.endOf != null) if (endOf == null || endOf == t.state.endOf) endOf = t.state.endOf; else errors.SemErr("Tokens " + endOf.name + " and " + t.state.endOf.name + " cannot be distinguished"); if (t.state.ctx) { ctx = true; // The following check seems to be unnecessary. It reported an error // if a symbol + context was the prefix of another symbol, e.g. // s1 = "a" "b" "c". // s2 = "a" CONTEXT("b"). // But this is ok. // if (t.state.endOf != null) { // Console.WriteLine("Ambiguous context clause"); // errors.count++; // } } } }
void PrintSym(Symbol sym) { trace.Write("{0,3} {1,-14} {2}", sym.n, Name(sym.name), nTyp[sym.typ]); if (sym.attrPos==null) trace.Write(" false "); else trace.Write(" true "); if (sym.typ == Node.nt) { trace.Write("{0,5}", Num(sym.graph)); if (sym.deletable) trace.Write(" true "); else trace.Write(" false "); } else trace.Write(" "); trace.WriteLine("{0,5} {1}", sym.line, tKind[sym.tokenKind]); }
string SymName(Symbol sym) { if (Char.IsLetter(sym.name[0])) { // real name value is stored in Tab.literals foreach (DictionaryEntry e in tab.literals) if ((Symbol)e.Value == sym) return (string)e.Key; } return sym.name; }
public Node NewNode(int typ, Symbol sym, int line) { Node node = new Node(typ, sym, line); node.n = nodes.Count; nodes.Add(node); return node; }
void ConflictSymbol(out Symbol sym) { string name; int kind; Sym(out name, out kind); sym = tab.FindSym(name); if (sym == null && kind == isLiteral) sym = tab.literals[name] as Symbol; bool undef = (sym == null); if (undef) { sym = ForwardDeclare(name, kind); } }
void Complete(Symbol sym) { if (!visited[sym.n]) { visited[sym.n] = true; foreach (Symbol s in nonterminals) { if (sym.nts[s.n]) { Complete(s); sym.follow.Or(s.follow); if (sym == curSy) sym.nts[s.n] = false; } } } }
void GenProductions() { foreach (Symbol sym in tab.nonterminals) { curSy = sym; gen.Write("\tvoid {0}(", sym.name); CopySourcePart(sym.attrPos, 0); gen.WriteLine(") {"); CopySourcePart(sym.semPos, 2); GenCode(sym.graph, 2, new BitArray(tab.terminals.Count)); gen.WriteLine("\t}"); gen.WriteLine(); } }
static void PrintSym(Symbol sym) { Trace.Write("{0,3} {1,-14} {2}", sym.n, Node.Name(sym.name), Node.nTyp[sym.typ]); if (sym.attrPos==null) Trace.Write(" false "); else Trace.Write(" true "); if (sym.typ == Node.nt) { Trace.Write("{0,5}", Num(sym.graph)); if (sym.deletable) Trace.Write(" true "); else Trace.Write(" false "); } else Trace.Write(" "); Trace.WriteLine("{0,5}", sym.line); }