// match a Dfa against lexer's input bool Match(ref TOKEN tok,Dfa dfa) { char ch=PeekChar(); int op=m_pch, mark=0; Dfa next; if (m_debug) { Console.Write("state {0} with ",dfa.m_state); if (char.IsLetterOrDigit(ch)||char.IsPunctuation(ch)) Console.WriteLine(ch); else Console.WriteLine("#"+(int)ch); } if (dfa.m_actions!=null) { mark = Mark(); } if (// ch==0 || (next=((Dfa)dfa.m_map[m_tokens.Filter(ch)]))==null) { if (m_debug) Console.Write("{0} no arc",dfa.m_state); if (dfa.m_actions!=null) { if (m_debug) Console.WriteLine(" terminal"); return TryActions(dfa,ref tok); // fails on REJECT } if (m_debug) Console.WriteLine(" fails"); return false; } Advance(); if (!Match(ref tok, next)) { // rest of string fails if (m_debug) Console.WriteLine("back to {0} with {1}",dfa.m_state,ch); if (dfa.m_actions!=null) { // this is still okay at a terminal if (m_debug) Console.WriteLine("{0} succeeds",dfa.m_state); Restore(mark); return TryActions(dfa,ref tok); } if (m_debug) Console.WriteLine("{0} fails",dfa.m_state); return false; } if (dfa.m_reswds>=0) { ((ResWds)m_tokens.reswds[dfa.m_reswds]).Check(this,ref tok); } if (m_debug) { Console.Write("{0} matched ",dfa.m_state); if (m_pch<=m_buf.Length) Console.WriteLine(m_buf.Substring(op,m_pch-op)); else Console.WriteLine(m_buf.Substring(op)); } return true; }
bool TryActions(Dfa dfa,ref TOKEN tok) { int len = m_pch-m_startMatch; if (len==0) return false; if (m_startMatch+len<=m_buf.Length) yytext = m_buf.Substring(m_startMatch,len); else // can happen with {EOF} rules yytext = m_buf.Substring(m_startMatch); // actions is a list of old-style actions for this DFA in order of priority // there is a list because of the chance that any of them may REJECT Dfa.Action a = dfa.m_actions; bool reject = true; while (reject && a!=null) { int action = a.a_act; reject = false; a = a.a_next; if (a==null && dfa.m_tokClass!="") { // last one might not be an old-style action if (m_debug) Console.WriteLine("creating a "+dfa.m_tokClass); tok=(TOKEN)Tfactory.create(dfa.m_tokClass,this); } else { tok = m_tokens.OldAction(this,ref yytext,action,ref reject); if (m_debug && !reject) Console.WriteLine("Old action "+action); } } return !reject; }
public CSToolsFatalException(int n, TOKEN t, string s) : base(n, t.yylx, t.pos, t.yytext, s) { }
/// <exclude/> public CSToolsStopException(int n,TOKEN t,string s) : base(n,t,s) { }
public override void ParserDirective() { m_parserseen = true; m_lexer.yy_begin("parser"); m_tok = m_lexer.Next(); // collect token file name from %parser directive m_lexer.yy_begin("YYINITIAL"); string tokfile = m_tok.yytext; if (!tokfile.EndsWith(".cs")) tokfile += ".cs"; GetDefs(tokfile); int ch; m_outname = "syntax"; do // look to see if the parser class name is given { ch = m_lexer.GetChar(); } while (ch==' '||ch=='\t'); if (ch!='\n') { string clsname = new string((char)ch,1); while (ch!=' ' && ch!='\t' && ch!='\n' && ch!=0) { ch = m_lexer.GetChar(); clsname += new string((char)ch,1); } if (clsname!="") m_outname = clsname; } while (ch!='\n' && ch!=0) // ignore anything else on the line { ch = m_lexer.GetChar(); } m_actions = "/// <summary/>\n" + "public class yy"+m_outname+": Symbols {\n" + "/// <summary/>\n" + "/// <param name='yyq'></param>\n" + "/// <param name='yysym'></param>\n" + "/// <param name='yyact'></param>\n" + " public override object Action(Parser yyq,SYMBOL yysym, int yyact) {\n" + " switch(yyact) {\n" + " case -1: break; //// keep compiler happy"; }
public override void SetStartSymbol() { m_tok = m_lexer.Next(); // recursive call of lexer.Next should be okay m_symbols.m_startSymbol = ((CSymbol)m_tok).Resolve(); m_symbols.m_startSymbol.m_symtype = CSymbol.SymType.nonterminal; }
public CSToolsStopException(int n, TOKEN t, string s) : base(n, t, s) { }
public PrecReference(Lexer lx,TOKEN t) : base(lx) { precref = ((CSymbol)t).Resolve(); new SymbolType(((ptokens)lx).m_sgen,t.yytext,true); }
public bool MoveNext() { t = lxr.Next(); return(t != null); }
public CSToolsException(int n, TOKEN t, string s) : this(n, t.yylx, t.pos, t.yytext, s) { sym = t; }
public _Enumerator(Lexer x) { lxr = x; t = null; }
// match a Dfa against lexer's input bool Match(ref TOKEN tok, Dfa dfa, int depth = 0) { char ch = PeekChar(); int op = m_pch, mark = 0; Dfa next; if (m_debug) { Console.Write("state {0} with ", dfa.m_state); if (char.IsLetterOrDigit(ch) || char.IsPunctuation(ch)) { Console.WriteLine(ch); } else { Console.WriteLine("#" + (int)ch); } } if (dfa.m_actions != null) { mark = Mark(); } if (// ch==0 || (next = ((Dfa)dfa.m_map[m_tokens.Filter(ch)])) == null) { if (m_debug) { Console.Write("{0} no arc", dfa.m_state); } if (dfa.m_actions != null) { if (m_debug) { Console.WriteLine(" terminal"); } return(TryActions(dfa, ref tok)); // fails on REJECT } if (m_debug) { Console.WriteLine(" fails"); } return(false); } Advance(); if (depth > 16) { } if (!Match(ref tok, next, depth + 1)) { // rest of string fails if (m_debug) { Console.WriteLine("back to {0} with {1}", dfa.m_state, ch); } if (dfa.m_actions != null) { // this is still okay at a terminal if (m_debug) { Console.WriteLine("{0} succeeds", dfa.m_state); } Restore(mark); return(TryActions(dfa, ref tok)); } if (m_debug) { Console.WriteLine("{0} fails", dfa.m_state); } return(false); } if (dfa.m_reswds >= 0) { ((ResWds)m_tokens.reswds[dfa.m_reswds]).Check(this, ref tok); } if (m_debug) { Console.Write("{0} matched ", dfa.m_state); if (m_pch <= m_buf.Length) { Console.WriteLine(m_buf.Substring(op, m_pch - op)); } else { Console.WriteLine(m_buf.Substring(op)); } } return(true); }
public CSToolsFatalException(int n,TOKEN t,string s) : base(n,t.yylx,t.pos,t.yytext,s) {}
/// <exclude/> public _Enumerator(Lexer x) { lxr = x; t = null; }
public int EmitClassDefin(string b, ref int p, int max, CsReader inf, string defbas, out string bas, out string name, bool lx) { bool defconseen = false; name = ""; bas = defbas; if (lx) { NonWhite(b, ref p, max); } White(b, ref p, max); for (; p < max && b[p] != '{' && b[p] != ':' && b[p] != ';' && b[p] != ' ' && b[p] != '\t' && b[p] != '\n'; p++) { name += b[p]; } White(b, ref p, max); if (b[p] == ':') { p++; White(b, ref p, max); for (bas = ""; p < max && b[p] != ' ' && b[p] != '{' && b[p] != '\t' && b[p] != ';' && b[p] != '\n'; p++) { bas += b[p]; } } int num = new TokClassDef(this, name, bas).m_yynum; m_outFile.WriteLine("//%+{0}+{1}", name, num); m_outFile.Write("public partial class "); m_outFile.Write(name); m_outFile.Write(" : " + bas); m_outFile.WriteLine("{"); do { if (p >= max) { b += inf.ReadLine(); max = b.Length; } White(b, ref p, max); } while (p >= max); if (b[p] != ';') { cs0syntax syms = new cs0syntax(new yycs0syntax(), erh); cs0tokens tks = (cs0tokens)syms.m_lexer; tks.Out = m_outname; // syms.m_debug = true; syms.Cls = name; syms.Out = m_outname; if (lx) { syms.Ctx = "Lexer yyl"; syms.Par = "yym"; } else { syms.Ctx = "Parser yyp"; syms.Par = "yyq"; } string str = ToBraceIfFound(ref b, ref p, ref max, inf); TOKEN s = null; try // 4.7c { s = (TOKEN)syms.Parse(str); } catch (Exception) {} if (s == null) { Error(48, p, "Bad class definition for " + name); return(-1); } s.yytext = s.yytext.Replace("yyq", "((" + m_outname + ")yyp)"); s.yytext = s.yytext.Replace("yym", "((" + m_outname + ")yyl)"); string[] ss = s.yytext.Split('\n'); for (int j = 0; j < ss.Length; j++) { m_outFile.WriteLine(ss[j]); } defconseen = syms.defconseen; } if (lx || !m_partial) { m_outFile.WriteLine("public override string yyname { get { return \"" + name + "\"; }}"); m_outFile.WriteLine("public override int yynum { get { return " + num + "; }}"); } else { m_outFile.WriteLine("public override string yyname_" + m_outname + " { get { return \"" + name + "\"; }}"); m_outFile.WriteLine("public override int yynum_" + m_outname + " { get { return " + num + "; }}"); } if (!defconseen) { if (lx) { m_outFile.Write("public " + name + "(Lexer yyl):base(yyl){}"); } else if (!lx && !m_partial) { m_outFile.Write("public " + name + "(Parser yyp):base(yyp){}"); } } m_outFile.WriteLine("}"); return(num); }
/// <exclude/> public void Check(Lexer yyl,ref TOKEN tok) { string str = tok.yytext; if (m_upper) str = str.ToUpper(); object o = m_wds[str]; if (o==null) return; tok = (TOKEN)Tfactory.create((string)o,yyl); }
public CSToolsException(int n, TOKEN t, string s) : this(n, t.yylx, t.pos, t.yytext, s) { this.sym = (SYMBOL)t; }
public TOKEN m_tok; // current input token as returned by Parser.Next public void Advance() { m_tok = (TOKEN)m_lexer.Next(); }
/// <exclude/> public bool MoveNext() { t = lxr.Next(); return t!=null; }
public override void SetNamespace() { m_tok = m_lexer.Next(); m_namespace = true; m_outFile.WriteLine("namespace "+m_tok.yytext+" {"); }
/// <exclude/> public CSToolsException(int n,TOKEN t,string s) : this(n,t.yylx,t.pos,t.yytext,s) { sym=t; }
// parsing routines internal void ParseProduction() { TOKEN tok = m_tok; CSymbol lhs = null; try { lhs = ((CSymbol)m_tok).Resolve(); } catch(Exception e) { erh.Error(new CSToolsFatalException(45,tok,string.Format("Syntax error in Parser script - possibly extra semicolon?",e.Message))); } m_tok = lhs; if (m_tok.IsTerminal()) Error(39,m_tok.pos,string.Format("Illegal left hand side <{0}> for production",m_tok.yytext)); if (m_symbols.m_startSymbol==null) m_symbols.m_startSymbol = lhs; if (lhs.m_symtype==CSymbol.SymType.unknown) lhs.m_symtype = CSymbol.SymType.nonterminal; if ((!lhs.m_defined) && lhs.m_prods.Count==0) { // lhs not defined in %symbol statement and not previously a lhs // so declare it as a new symbol m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public class "+lhs.yytext+" : SYMBOL {"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine(@"/// <param name='yyq'></param>"); m_outFile.WriteLine(" public "+lhs.yytext+"(Parser yyq):base(yyq) { }"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine(" public override string yyname() { return \""+lhs.yytext+"\"; }}"); } if (!Find(lhs)) new SymbolType(this,lhs.yytext); m_prod = new Production(this,lhs); m_lexer.yy_begin("rhs"); Advance(); if (!m_tok.Matches(":")) Error(40,m_tok.pos,String.Format("Colon expected for production {0}",lhs.yytext)); Advance(); RhSide(m_prod); while(m_tok!=null && m_tok.Matches("|")) { Advance(); m_prod = new Production(this,lhs); RhSide(m_prod); } if (m_tok==null || !m_tok.Matches(";")) Error(41,m_lexer.m_pch,"Semicolon expected"); Advance(); m_prod = null; m_lexer.yy_begin("YYINITIAL"); }
public int EmitClassDefin( string b, ref int p, int max, CsReader inf, string defbas, out string bas, out string name, bool lx) { bool flag = false; name = ""; bas = defbas; if (lx) { this.NonWhite(b, ref p, max); } this.White(b, ref p, max); while (p < max && b[p] != '{' && (b[p] != ':' && b[p] != ';') && (b[p] != ' ' && b[p] != '\t' && b[p] != '\n')) { name += (string)(object)b[p]; ++p; } this.White(b, ref p, max); if (b[p] == ':') { ++p; this.White(b, ref p, max); bas = ""; while (p < max && b[p] != ' ' && (b[p] != '{' && b[p] != '\t') && (b[p] != ';' && b[p] != '\n')) { bas += (string)(object)b[p]; ++p; } } int yynum = new TokClassDef(this, name, bas).m_yynum; this.m_outFile.WriteLine("//%+{0}+{1}", (object)name, (object)yynum); this.m_outFile.Write("public class "); this.m_outFile.Write(name); this.m_outFile.Write(" : " + bas); this.m_outFile.WriteLine("{"); do { if (p >= max) { b += inf.ReadLine(); max = b.Length; } this.White(b, ref p, max); }while (p >= max); if (b[p] != ';') { cs0syntax cs0syntax = new cs0syntax((YyParser) new yycs0syntax(), this.erh); ((cs0tokens)cs0syntax.m_lexer).Out = this.m_outname; cs0syntax.Cls = name; cs0syntax.Out = this.m_outname; if (lx) { cs0syntax.Ctx = "Lexer yyl"; cs0syntax.Par = "yym"; } else { cs0syntax.Ctx = "Parser yyp"; cs0syntax.Par = "yyq"; } string braceIfFound = this.ToBraceIfFound(ref b, ref p, ref max, inf); TOKEN token = (TOKEN)null; try { token = (TOKEN)cs0syntax.Parse(braceIfFound); } catch (Exception ex) { } if (token == null) { this.Error(48, p, "Bad class definition for " + name); return(-1); } token.yytext = token.yytext.Replace("yyq", "((" + this.m_outname + ")yyp)"); token.yytext = token.yytext.Replace("yym", "((" + this.m_outname + ")yyl)"); string yytext = token.yytext; char[] chArray = new char[1] { '\n' }; foreach (string str in yytext.Split(chArray)) { this.m_outFile.WriteLine(str); } flag = cs0syntax.defconseen; } this.m_outFile.WriteLine("public override string yyname { get { return \"" + name + "\"; }}"); this.m_outFile.WriteLine("public override int yynum { get { return " + (object)yynum + "; }}"); if (!flag) { if (lx) { this.m_outFile.Write("public " + name + "(Lexer yyl):base(yyl){}"); } else { this.m_outFile.Write("public " + name + "(Parser yyp):base(yyp){}"); } } this.m_outFile.WriteLine("}"); return(yynum); }