static string Str(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) { BitArray set = CharClass.Set(p.val); if (Sets.Elements(set) != 1) { Parser.SemErr("character set contains more than 1 character"); } s.Append((char)Sets.First(set)); } 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()); }
//---------- String handling static char Hex2Char(string s) { int val = 0; for (int i = 0; i < s.Length; i++) { char ch = s[i]; if ('0' <= ch && ch <= '9') { val = 16 * val + (ch - '0'); } else if ('a' <= ch && ch <= 'f') { val = 16 * val + (10 + ch - 'a'); } else if ('A' <= ch && ch <= 'Z') { val = 16 * val + (10 + ch - 'A'); } else { Parser.SemErr("bad escape sequence in string or character"); } } return((char)val); }
/* 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("}"); } }
public static string Unescape(string s) { /* replaces escape sequences in s by their Unicode values. */ StringBuilder buf = new StringBuilder(); int i = 0; while (i < s.Length) { if (s[i] == '\\') { switch (s[i + 1]) { case '\\': buf.Append('\\'); i += 2; break; case '\'': buf.Append('\''); i += 2; break; case '\"': buf.Append('\"'); i += 2; break; case 'r': buf.Append('\r'); i += 2; break; case 'n': buf.Append('\n'); i += 2; break; case 't': buf.Append('\t'); i += 2; break; case '0': buf.Append('\0'); i += 2; break; case 'a': buf.Append('\a'); i += 2; break; case 'b': buf.Append('\b'); i += 2; break; case 'f': buf.Append('\f'); i += 2; break; case 'v': buf.Append('\v'); i += 2; break; case 'u': case 'x': if (i + 6 <= s.Length) { buf.Append(Hex2Char(s.Substring(i + 2, 4))); i += 6; break; } else { Parser.SemErr("bad escape sequence in string or character"); i = s.Length; break; } default: Parser.SemErr("bad escape sequence in string or character"); i += 2; break; } } else { buf.Append(s[i]); i++; } } return(buf.ToString()); }
public static void ConvertToStates(Node p, Symbol sym) { curGraph = p; curSy = sym; if (Node.DelGraph(curGraph)) { Parser.SemErr("token might be empty"); } NumberNodes(curGraph, firstState); FindTrans(curGraph, true, new BitArray(Node.nodes.Count)); }
static void NewTransition(State from, State to, int typ, int sym, int tc) { if (to == firstState) { Parser.SemErr("token must not start with an iteration"); } Target t = new Target(to); Action a = new Action(typ, sym, tc); a.target = t; from.AddAction(a); }
public Symbol(int typ, string name, int line) { if (name.Length == 2 && name[0] == '"') { Parser.SemErr("empty token not allowed"); name = "???"; } if (name.IndexOf(' ') >= 0) Parser.SemErr("tokens must not contain blanks"); this.typ = typ; this.name = name; this.line = line; switch (typ) { case Node.t: n = terminals.Count; terminals.Add(this); break; case Node.pr: pragmas.Add(this); break; case Node.nt: n = nonterminals.Count; nonterminals.Add(this); break; } }
public static Graph StrToGraph(string str) { string s = DFA.Unescape(str.Substring(1, str.Length-2)); if (s.IndexOf('\0') >= 0) Parser.SemErr("\\0 not allowed here. Used as eof character"); if (s.Length == 0) Parser.SemErr("empty token not allowed"); Graph g = new Graph(); g.r = dummyNode; for (int i = 0; i < s.Length; i++) { Node p = new Node(Node.chr, (int)s[i], 0); g.r.next = p; g.r = p; } g.l = dummyNode.next; dummyNode.next = null; return g; }
public static void MatchLiteral(Symbol sym) // store string either as token or as literal { string name = Unescape(sym.name.Substring(1, sym.name.Length - 2)); if (name.IndexOf('\0') >= 0) { Parser.SemErr("\\0 not allowed here. Used as eof character"); } Symbol matchedSym = MatchedDFA(name, sym); if (matchedSym == null) { sym.tokenKind = Symbol.classToken; } else { matchedSym.tokenKind = Symbol.classLitToken; sym.tokenKind = Symbol.litToken; } }
void NewTransition(State from, State to, int typ, int sym, int tc) { if (to == firstState) { parser.SemErr("token must not start with an iteration"); } Target t = new Target(to); Action a = new Action(typ, sym, tc); a.target = t; from.AddAction(a); if (typ == Node.clas) { curSy.tokenKind = Symbol.classToken; } }
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; } } }