Ejemplo n.º 1
0
 void CompSync(Node p)
 {
     while (p != null && !visited[p.n]) {
     visited[p.n] = true;
     if (p.typ == Node.sync) {
         BitArray s = Expected(p.next, curSy);
         s[eofSy.n] = true;
         allSyncSets.Or(s);
         p.set = s;
     } else if (p.typ == Node.alt) {
         CompSync(p.sub); CompSync(p.down);
     } else if (p.typ == Node.opt || p.typ == Node.iter)
         CompSync(p.sub);
     p = p.next;
     }
 }
Ejemplo n.º 2
0
 void GenCond(BitArray s, Node p)
 {
     if (p.typ == Node.rslv) CopySourcePart(p.pos, 0);
     else {
     int n = Sets.Elements(s);
     if (n == 0) gen.Write("false"); // should never happen
     else if (n <= maxTerm)
         foreach (Symbol sym in tab.terminals) {
             if (s[sym.n]) {
                 gen.Write("la.kind == {0}", sym.n);
                 --n;
                 if (n > 0) gen.Write(" || ");
             }
         }
     else
         gen.Write("StartOf({0})", NewCondSet(s));
     /*
     if (p.typ == Node.alt) {
         // for { ... | IF ... | ... } or [ ... | IF ... | ... ]
         // check resolvers in addition to terminal start symbols of alternatives
         Node q = p;
         while (q != null) {
             if (q.sub.typ == Node.rslv) {
                 gen.Write(" || ");
                 CopySourcePart(q.sub.pos, 0);
             }
             q = q.down;
         }
     }
     */
     }
 }
Ejemplo n.º 3
0
 public void SetContextTrans(Node p)
 {
     // set transition code in the graph rooted at p
     while (p != null) {
       if (p.typ == Node.opt || p.typ == Node.iter) {
     SetContextTrans(p.sub);
       } else if (p.typ == Node.alt) {
     SetContextTrans(p.sub); SetContextTrans(p.down);
       }
       if (p.up) break;
       p = p.next;
     }
 }
Ejemplo n.º 4
0
 void CheckRes(Node p, bool rslvAllowed)
 {
     while (p != null) {
     switch (p.typ) {
         case Node.alt:
             BitArray expected = new BitArray(terminals.Count);
             for (Node q = p; q != null; q = q.down)
                 expected.Or(Expected0(q.sub, curSy));
             BitArray soFar = new BitArray(terminals.Count);
             for (Node q = p; q != null; q = q.down) {
                 if (q.sub.typ == Node.rslv) {
                   BitArray fs = Expected(q.sub.next, curSy);
                     if (Sets.Intersect(fs, soFar))
                         ResErr(q.sub, "Warning: Resolver will never be evaluated. " +
                         "Place it at previous conflicting alternative.");
                     if (!Sets.Intersect(fs, expected))
                         ResErr(q.sub, "Warning: Misplaced resolver: no LL(1) conflict.");
                 } else soFar.Or(Expected(q.sub, curSy));
                 CheckRes(q.sub, true);
             }
             break;
         case Node.iter: case Node.opt:
             if (p.sub.typ == Node.rslv) {
                 BitArray fs = First(p.sub.next);
                 BitArray fsNext = Expected(p.next, curSy);
                 if (!Sets.Intersect(fs, fsNext))
                     ResErr(p.sub, "Warning: Misplaced resolver: no LL(1) conflict.");
             }
             CheckRes(p.sub, true);
             break;
         case Node.rslv:
             if (!rslvAllowed)
                 ResErr(p, "Warning: Misplaced resolver: no alternative.");
             break;
     }
     if (p.up) break;
     p = p.next;
     rslvAllowed = false;
     }
 }
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
 public Graph(Node left, Node right)
 {
     l = left; r = right;
 }
Ejemplo n.º 7
0
 //-------------- check if every nts can be reached  -----------------
 void MarkReachedNts(Node p)
 {
     while (p != null) {
     if (p.typ == Node.nt && !visited[p.sym.n]) { // new nt reached
         visited[p.sym.n] = true;
         MarkReachedNts(p.sym.graph);
     } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
         MarkReachedNts(p.sub);
         if (p.typ == Node.alt) MarkReachedNts(p.down);
     }
     if (p.up) break;
     p = p.next;
     }
 }
Ejemplo n.º 8
0
 public BitArray First(Node p)
 {
     BitArray fs = First0(p, new BitArray(nodes.Count));
     if (ddt[3]) {
     trace.WriteLine();
     if (p != null) trace.WriteLine("First: node = {0}", p.n);
     else trace.WriteLine("First: node = null");
     PrintSet(fs, 0);
     }
     return fs;
 }
Ejemplo n.º 9
0
 //--------- check if every nts can be derived to terminals  ------------
 bool IsTerm(Node p, BitArray mark)
 {
     // true if graph can be derived to terminals
     while (p != null) {
     if (p.typ == Node.nt && !mark[p.sym.n]) return false;
     if (p.typ == Node.alt && !IsTerm(p.sub, mark)
     && (p.down == null || !IsTerm(p.down, mark))) return false;
     if (p.up) break;
     p = p.next;
     }
     return true;
 }
Ejemplo n.º 10
0
 Node LeadingAny(Node p)
 {
     if (p == null) return null;
     Node a = null;
     if (p.typ == Node.any) a = p;
     else if (p.typ == Node.alt) {
     a = LeadingAny(p.sub);
     if (a == null) a = LeadingAny(p.down);
     }
     else if (p.typ == Node.opt || p.typ == Node.iter) a = LeadingAny(p.sub);
     else if (DelNode(p) && !p.up) a = LeadingAny(p.next);
     return a;
 }
Ejemplo n.º 11
0
 void GetSingles(Node p, ArrayList singles)
 {
     if (p == null) return;  // end of graph
     if (p.typ == Node.nt) {
     if (p.up || DelGraph(p.next)) singles.Add(p.sym);
     } else if (p.typ == Node.alt || p.typ == Node.iter || p.typ == Node.opt) {
     if (p.up || DelGraph(p.next)) {
         GetSingles(p.sub, singles);
         if (p.typ == Node.alt) GetSingles(p.down, singles);
     }
     }
     if (!p.up && DelNode(p)) GetSingles(p.next, singles);
 }
Ejemplo n.º 12
0
 //---------------------------------------------------------------------
 //  Symbol set computations
 //---------------------------------------------------------------------
 /* Computes the first set for the graph rooted at p */
 BitArray First0(Node p, BitArray mark)
 {
     BitArray fs = new BitArray(terminals.Count);
     while (p != null && !mark[p.n]) {
     mark[p.n] = true;
     switch (p.typ) {
         case Node.nt: {
             if (p.sym.firstReady) fs.Or(p.sym.first);
             else fs.Or(First0(p.sym.graph, mark));
             break;
         }
         case Node.t: case Node.wt: {
             fs[p.sym.n] = true; break;
         }
         case Node.any: {
             fs.Or(p.set); break;
         }
         case Node.alt: {
             fs.Or(First0(p.sub, mark));
             fs.Or(First0(p.down, mark));
             break;
         }
         case Node.iter: case Node.opt: {
             fs.Or(First0(p.sub, mark));
             break;
         }
     }
     if (!DelNode(p)) break;
     p = p.next;
     }
     return fs;
 }
Ejemplo n.º 13
0
 // use a switch if more than 5 alternatives and none starts with a resolver
 bool UseSwitch(Node p)
 {
     BitArray s1, s2;
     if (p.typ != Node.alt) return false;
     int nAlts = 0;
     s1 = new BitArray(tab.terminals.Count);
     while (p != null) {
     s2 = tab.Expected0(p.sub, curSy);
     // must not optimize with switch statement, if there are ll1 warnings
     if (Overlaps(s1, s2)) { return false; }
     s1.Or(s2);
     ++nAlts;
     // must not optimize with switch-statement, if alt uses a resolver expression
     if (p.sub.typ == Node.rslv) return false;
     p = p.down;
     }
     return nAlts > 5;
 }
Ejemplo n.º 14
0
 public BitArray Expected(Node p, Symbol curSy)
 {
     BitArray s = First(p);
     if (DelGraph(p)) s.Or(curSy.follow);
     return s;
 }
Ejemplo n.º 15
0
 int Num(Node p)
 {
     if (p == null) return 0; else return p.n;
 }
Ejemplo n.º 16
0
 // 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);
 }
Ejemplo n.º 17
0
 //----------------- graph printing ----------------------
 int Ptr(Node p, bool up)
 {
     if (p == null) return 0;
     else if (up) return -p.n;
     else return p.n;
 }
Ejemplo n.º 18
0
        public Node r; // right end of graph = list of nodes to be linked to successor graph

        #endregion Fields

        #region Constructors

        public Graph()
        {
            l = null; r = null;
        }
Ejemplo n.º 19
0
 //------------- check if resolvers are legal  --------------------
 void ResErr(Node p, string msg)
 {
     errors.Warning(p.line, p.pos.col, msg);
 }
Ejemplo n.º 20
0
 public Node NewNode(int typ, Node sub)
 {
     Node node = NewNode(typ, null, 0);
     node.sub = sub;
     return node;
 }
Ejemplo n.º 21
0
 public bool DelAlt(Node p)
 {
     return p == null || DelNode(p) && (p.up || DelAlt(p.next));
 }
Ejemplo n.º 22
0
 public Graph(Node p)
 {
     l = p; r = p;
 }
Ejemplo n.º 23
0
 //------------ graph deletability check -----------------
 public bool DelGraph(Node p)
 {
     return p == null || DelNode(p) && DelGraph(p.next);
 }
Ejemplo n.º 24
0
 void CheckAlts(Node p)
 {
     BitArray s1, s2;
     while (p != null) {
     if (p.typ == Node.alt) {
         Node q = p;
         s1 = new BitArray(terminals.Count);
         while (q != null) { // for all alternatives
             s2 = Expected0(q.sub, curSy);
             CheckOverlap(s1, s2, 1);
             s1.Or(s2);
             CheckAlts(q.sub);
             q = q.down;
         }
     } else if (p.typ == Node.opt || p.typ == Node.iter) {
         if (DelSubGraph(p.sub)) LL1Error(4, null); // e.g. [[...]]
         else {
             s1 = Expected0(p.sub, curSy);
             s2 = Expected(p.next, curSy);
             CheckOverlap(s1, s2, 2);
         }
         CheckAlts(p.sub);
     } else if (p.typ == Node.any) {
         if (Sets.Elements(p.set) == 0) LL1Error(3, null);
         // e.g. {ANY} ANY or [ANY] ANY
     }
     if (p.up) break;
     p = p.next;
     }
 }
Ejemplo n.º 25
0
 public bool DelNode(Node p)
 {
     if (p.typ == Node.nt) return p.sym.deletable;
     else if (p.typ == Node.alt) return DelAlt(p.sub) || p.down != null && DelAlt(p.down);
     else return p.typ == Node.iter || p.typ == Node.opt || p.typ == Node.sem
     || p.typ == Node.eps || p.typ == Node.rslv || p.typ == Node.sync;
 }
Ejemplo n.º 26
0
 void CompFollow(Node p)
 {
     while (p != null && !visited[p.n]) {
     visited[p.n] = true;
     if (p.typ == Node.nt) {
         BitArray s = First(p.next);
         p.sym.follow.Or(s);
         if (DelGraph(p.next))
             p.sym.nts[curSy.n] = true;
     } else if (p.typ == Node.opt || p.typ == Node.iter) {
         CompFollow(p.sub);
     } else if (p.typ == Node.alt) {
         CompFollow(p.sub); CompFollow(p.down);
     }
     p = p.next;
     }
 }
Ejemplo n.º 27
0
 public bool DelSubGraph(Node p)
 {
     return p == null || DelNode(p) && (p.up || DelSubGraph(p.next));
 }
Ejemplo n.º 28
0
 void FindAS(Node p)
 {
     // find ANY sets
     Node a;
     while (p != null) {
     if (p.typ == Node.opt || p.typ == Node.iter) {
         FindAS(p.sub);
         a = LeadingAny(p.sub);
         if (a != null) 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);
             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;
         }
     }
     if (p.up) break;
     p = p.next;
     }
 }
Ejemplo n.º 29
0
 void GenCode(Node p, int indent, BitArray isChecked)
 {
     Node p2;
     BitArray s1, s2;
     while (p != null) {
     switch (p.typ) {
         case Node.nt: {
             Indent(indent);
             gen.Write(p.sym.name + "(");
             CopySourcePart(p.pos, 0);
             gen.WriteLine(");");
             break;
         }
         case Node.t: {
             Indent(indent);
             if (isChecked[p.sym.n]) gen.WriteLine("Get();");
             else gen.WriteLine("Expect({0});", p.sym.n);
             break;
         }
         case Node.wt: {
             Indent(indent);
             s1 = tab.Expected(p.next, curSy);
             s1.Or(tab.allSyncSets);
             gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1));
             break;
         }
         case Node.any: {
             Indent(indent);
             gen.WriteLine("Get();");
             break;
         }
         case Node.eps: break; // nothing
         case Node.rslv: break; // nothing
         case Node.sem: {
             CopySourcePart(p.pos, indent);
             break;
         }
         case Node.sync: {
             Indent(indent);
             GenErrorMsg(syncErr, curSy);
             s1 = (BitArray)p.set.Clone();
             gen.Write("while (!("); GenCond(s1, p); gen.Write(")) {");
             gen.Write("SynErr({0}); Get();", errorNr); gen.WriteLine("}");
             break;
         }
         case Node.alt: {
             s1 = tab.First(p);
             bool equal = Sets.Equals(s1, isChecked);
             bool useSwitch = UseSwitch(p);
             if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); }
             p2 = p;
             while (p2 != null) {
                 s1 = tab.Expected(p2.sub, curSy);
                 Indent(indent);
                 if (useSwitch) {
                     PutCaseLabels(s1); gen.WriteLine("{");
                 } else if (p2 == p) {
                     gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {");
                 } else if (p2.down == null && equal) { gen.WriteLine("} else {");
                 } else {
                     gen.Write("} else if (");  GenCond(s1, p2.sub); gen.WriteLine(") {");
                 }
                 s1.Or(isChecked);
                 //if (p2.sub.typ == Node.rslv) GenCode(p2.sub.next, indent + 1, s1);
                 //else GenCode(p2.sub, indent + 1, s1);
                 GenCode(p2.sub, indent + 1, s1);
                 if (useSwitch) {
                     Indent(indent); gen.WriteLine("\tbreak;");
                     Indent(indent); gen.WriteLine("}");
                 }
                 p2 = p2.down;
             }
             Indent(indent);
             if (equal) {
                 gen.WriteLine("}");
             } else {
                 GenErrorMsg(altErr, curSy);
                 if (useSwitch) {
                     gen.WriteLine("default: SynErr({0}); break;", errorNr);
                     Indent(indent); gen.WriteLine("}");
                 } else {
                     gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr);
                 }
             }
             break;
         }
         case Node.iter: {
             Indent(indent);
             p2 = p.sub;
             gen.Write("while (");
             if (p2.typ == Node.wt) {
                 s1 = tab.Expected(p2.next, curSy);
                 s2 = tab.Expected(p.next, curSy);
                 gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2));
                 s1 = new BitArray(tab.terminals.Count);  // for inner structure
                 if (p2.up || p2.next == null) p2 = null; else p2 = p2.next;
             } else {
                 s1 = tab.First(p2);
                 GenCond(s1, p2);
             }
             gen.WriteLine(") {");
             GenCode(p2, indent + 1, s1);
             Indent(indent); gen.WriteLine("}");
             break;
         }
         case Node.opt:
             //if (p.sub.typ == Node.rslv) s1 = tab.First(p.sub.next);
             //else s1 = tab.First(p.sub);
             s1 = tab.First(p.sub);
             Indent(indent);
             gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {");
             //if (p.sub.typ == Node.rslv) GenCode(p.sub.next, indent + 1, s1);
             //else GenCode(p.sub, indent + 1, s1);
             GenCode(p.sub, indent + 1, s1);
             Indent(indent); gen.WriteLine("}");
             break;
     }
     if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync)
         isChecked.SetAll(false);  // = new BitArray(tab.terminals.Count);
     if (p.up) break;
     p = p.next;
     }
 }