示例#1
0
	/* AW: this replaces the method int Alternatives (Node p) */
	static bool UseSwitch (Node p) {
		if (p.typ != Node.alt) return false;
		int nAlts = 0;
		while (p != null) {
		  ++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;
	}
示例#2
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;
	}
示例#3
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);
             // assert: if isChecked[p.sym.n] is true, then isChecked contains only p.sym.n
             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);
             int acc = Sets.Elements(p.set);
             if (tab.terminals.Count == (acc + 1) || (acc > 0 && Sets.Equals(p.set, isChecked))) {
                 // either this ANY accepts any terminal (the + 1 = end of file), or exactly what's allowed here
                 gen.WriteLine("Get();");
             } else {
                 GenErrorMsg(altErr, curSy);
                 if (acc > 0) {
                     gen.Write("if ("); GenCond(p.set, p); gen.WriteLine(") Get(); else SynErr({0});", errorNr);
                 } else gen.WriteLine("SynErr({0}); // ANY node that matches no symbol", errorNr);
             }
             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(") {");
                 }
                 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:
             s1 = tab.First(p.sub);
             Indent(indent);
             gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {");
             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;
     }
 }
示例#4
0
 State TheState(Node p)
 {
     State state;
     if (p == null) {state = NewState(); state.endOf = curSy; return state;}
     else return p.state;
 }
示例#5
0
 // Assigns a state n.state to every node n. There will be a transition from
 // n.state to n.next.state triggered by n.val. All nodes in an alternative
 // chain are represented by the same state.
 // Numbering scheme:
 //  - any node after a chr, clas, opt, or alt, must get a new number
 //  - if a nested structure starts with an iteration the iter node must get a new number
 //  - if an iteration follows an iteration, it must get a new number
 void NumberNodes(Node p, State state, bool renumIter)
 {
     if (p == null) return;
     if (p.state != null) return; // already visited;
     if (state == null || (p.typ == Node.iter && renumIter)) state = NewState();
     p.state = state;
     if (Tab.DelGraph(p)) state.endOf = curSy;
     switch (p.typ) {
     case Node.clas: case Node.chr: {
         NumberNodes(p.next, null, false);
         break;
     }
     case Node.opt: {
         NumberNodes(p.next, null, false);
         NumberNodes(p.sub, state, true);
         break;
     }
     case Node.iter: {
         NumberNodes(p.next, state, true);
         NumberNodes(p.sub, state, true);
         break;
     }
     case Node.alt: {
         NumberNodes(p.next, null, false);
         NumberNodes(p.sub, state, true);
         NumberNodes(p.down, state, renumIter);
         break;
     }
     }
 }
示例#6
0
 string CommentStr(Node p)
 {
     StringBuilder s = new StringBuilder();
     while (p != null) {
     if (p.typ == Node.chr) {
         s.Append((char)p.val);
     } else if (p.typ == Node.clas) {
         CharSet set = tab.CharClassSet(p.val);
         if (set.Elements() != 1) parser.SemErr("character set contains more than 1 character");
         s.Append((char)set.First());
     } else parser.SemErr("comment delimiters may not be structured");
     p = p.next;
     }
     if (s.Length == 0 || s.Length > 2) {
     parser.SemErr("comment delimiters must be 1 or 2 characters long");
     s = new StringBuilder("?");
     }
     return s.ToString();
 }
示例#7
0
 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));
     }
 }
示例#8
0
文件: Tab.cs 项目: ggrov/tacny
	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);
	}
示例#9
0
文件: Tab.cs 项目: ggrov/tacny
	public static bool DelNode(Node p) {
		if (p.typ == Node.nt) return p.sym.deletable;
		else if (p.typ == Node.alt) return DelSubGraph(p.sub) || p.down != null && DelSubGraph(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;
	}
示例#10
0
文件: Tab.cs 项目: ggrov/tacny
	public static bool DelSubGraph(Node p) {
		return p == null || DelNode(p) && (p.up || DelSubGraph(p.next));
	}
示例#11
0
文件: Tab.cs 项目: ggrov/tacny
	//------------ graph deletability check -----------------

	public static bool DelGraph(Node p) {
		return p == null || DelNode(p) && DelGraph(p.next);
	}
示例#12
0
文件: Tab.cs 项目: ggrov/tacny
 public void SetContextTrans(Node p) { // set transition code in the graph rooted at p
   while (p != null) {
     if (p.typ == Node.chr || p.typ == Node.clas) {
       p.code = Node.contextTrans;
     } else 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;
   }
 }
示例#13
0
文件: Tab.cs 项目: ggrov/tacny
	public void DeleteNodes() {
		nodes = new ArrayList();
		dummyNode = NewNode(Node.eps, null, 0);
	}
示例#14
0
文件: Tab.cs 项目: ggrov/tacny
	public Node NewNode(int typ, Node sub) {
		Node node = NewNode(typ, null, 0);
		node.sub = sub;
		return node;
	}
示例#15
0
文件: Tab.cs 项目: ggrov/tacny
	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;
	}
示例#16
0
文件: Tab.cs 项目: ggrov/tacny
	// 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);
	}
示例#17
0
文件: Tab.cs 项目: ggrov/tacny
	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;
		}
	}
示例#18
0
文件: Tab.cs 项目: ggrov/tacny
	//----------------- graph printing ----------------------
	
	string Ptr(Node p, bool up) {
		string ptr = (p == null) ? "0" : p.n.ToString();
		return (up) ? ("-" + ptr) : ptr;
	}
示例#19
0
文件: Tab.cs 项目: ggrov/tacny
	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 or ( ANY | ANY )
			}
			if (p.up) break;
			p = p.next;
		}
	}
示例#20
0
文件: Tab.cs 项目: ggrov/tacny
	//---------------------------------------------------------------------
	//  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;
	}
示例#21
0
 public void NewComment(Node from, Node to, bool nested)
 {
     Comment c = new Comment(CommentStr(from), CommentStr(to), nested);
     c.next = firstComment; firstComment = c;
 }
示例#22
0
文件: Tab.cs 项目: ggrov/tacny
	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;
	}
示例#23
0
 void FindTrans(Node p, bool start, BitArray marked)
 {
     if (p == null || marked[p.n]) return;
     marked[p.n] = true;
     if (start) Step(p.state, p, new BitArray(tab.nodes.Count)); // start of group of equally numbered nodes
     switch (p.typ) {
     case Node.clas: case Node.chr: {
         FindTrans(p.next, true, marked);
         break;
     }
     case Node.opt: {
         FindTrans(p.next, true, marked); FindTrans(p.sub, false, marked);
         break;
     }
     case Node.iter: {
         FindTrans(p.next, false, marked); FindTrans(p.sub, false, marked);
         break;
     }
     case Node.alt: {
         FindTrans(p.sub, false, marked); FindTrans(p.down, false, marked);
         break;
     }
     }
 }
示例#24
0
文件: Tab.cs 项目: ggrov/tacny
	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;
		}
	}
示例#25
0
 void Step(State from, Node p, BitArray stepped)
 {
     if (p == null) return;
     stepped[p.n] = true;
     switch (p.typ) {
     case Node.clas: case Node.chr: {
         NewTransition(from, TheState(p.next), p.typ, p.val, p.code);
         break;
     }
     case Node.alt: {
         Step(from, p.sub, stepped); Step(from, p.down, stepped);
         break;
     }
     case Node.iter: {
         if (Tab.DelSubGraph(p.sub)) {
             parser.SemErr("contents of {...} must not be deletable");
             return;
         }
         if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped);
         Step(from, p.sub, stepped);
         if (p.state != from) {
             Step(p.state, p, new BitArray(tab.nodes.Count));
         }
         break;
     }
     case Node.opt: {
         if (p.next != null && !stepped[p.next.n]) Step(from, p.next, stepped);
         Step(from, p.sub, stepped);
         break;
     }
     }
 }
示例#26
0
文件: Tab.cs 项目: ggrov/tacny
	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);
		if (a == null && DelNode(p) && !p.up) a = LeadingAny(p.next);
		return a;
	}
示例#27
0
 void Attribs(Node p)
 {
     if (la.kind == 30) {
     Get();
     int beg = la.pos; int col = la.col; int line = la.line;
     while (StartOf(11)) {
         if (StartOf(12)) {
             Get();
         } else {
             Get();
             SemErr("bad string in attributes");
         }
     }
     Expect(31);
     if (t.pos > beg) p.pos = new Position(beg, t.pos, col, line);
     } else if (la.kind == 32) {
     Get();
     int beg = la.pos; int col = la.col; int line = la.line;
     while (StartOf(13)) {
         if (StartOf(14)) {
             Get();
         } else {
             Get();
             SemErr("bad string in attributes");
         }
     }
     Expect(33);
     if (t.pos > beg) p.pos = new Position(beg, t.pos, col, line);
     } else SynErr(60);
 }
示例#28
0
文件: Tab.cs 项目: ggrov/tacny
	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;
				}
			}

			// 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;
		}
	}
示例#29
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"); // happens if an ANY set matches no symbol
     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));
     }
 }
示例#30
0
文件: Tab.cs 项目: ggrov/tacny
	public BitArray Expected(Node p, Symbol curSy) {
		BitArray s = First(p);
		if (DelGraph(p)) s.Or(curSy.follow);
		return s;
	}