void _Create() { ptokens tks = new ptokens(erh); m_outname = "syntax"; tks.m_sgen = this; m_lexer = tks; m_symbols.erh = erh; m_symbols.ClassInit(this); m_outname = "syntax"; m_outFile.WriteLine("using System;using Tools;"); Production special = new Production(this,m_symbols.Special); m_lexer.yytext = "error"; CSymbol e = (new CSymbol(this)).Resolve(); e.m_symtype = CSymbol.SymType.nonterminal; e.m_defined=true; // 1: INPUT // top-down parsing of script m_lexer.Start(m_inFile); m_tok = (TOKEN)m_lexer.Next(); //Console.WriteLine("Token <{0}> {1}",m_tok.yytext,m_tok.GetType().Name); while (m_tok!=null) ParseProduction(); // that's the end of the script if (!m_parserseen) Error(30,0,"no parser directive detected - possibly incorrect text encoding?"); m_outFile.WriteLine(m_actions); // output the action function m_outFile.WriteLine("} return null; }"); special.AddToRhs(m_symbols.m_startSymbol); special.AddToRhs(m_symbols.EOFSymbol); // 2: PROCESSING Console.WriteLine("First"); DoFirst(); Console.WriteLine("Follow"); DoFollow(); Console.WriteLine("Parse Table"); ParseState start = new ParseState(this,null); m_symbols.m_states[0] = start; start.MaybeAdd(new ProdItem(special,0)); start.Closure(); start.AddEntries(); Transition tfinal = (Transition)start.m_transitions[m_symbols.m_startSymbol.yytext]; ParserShift pe = tfinal.m_next; m_symbols.m_accept = pe.m_next; if (m_symbols.m_accept==null) m_symbols.erh.Error(new CSToolsFatalException(43,0,0,"","No accept state. ParserGenerator cannot continue.")); // 2A: Reduce States for the LR(0) parser foreach (ParseState ps in m_symbols.m_states.Values) ps.ReduceStates(); /* if (m_showParser) { foreach (ParseState ps in m_symbols.m_states.Values) { ps.Print0(); if (ps==m_symbols.m_accept) Console.WriteLine(" EOF accept"); } } */ // 3: Compute Look-ahead sets if (m_lalrParser) { m_symbols.Transitions(new Builder(Transition.BuildDR)); /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.DR),"DR"); */ m_symbols.Transitions(new Builder(Transition.BuildReads)); new Digraph(this, new Relation(Transition.reads), new Func(Transition.DR), new Func(Transition.Read), new AddToFunc(Transition.AddToRead)).Compute(); // detect cycles in Read TBD /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.Read),"Read"); */ m_symbols.Transitions(new Builder(Transition.BuildIncludes)); m_symbols.Transitions(new Builder(Transition.BuildLookback)); new Digraph(this, new Relation(Transition.includes), new Func(Transition.Read), new Func(Transition.Follow), new AddToFunc(Transition.AddToFollow)).Compute(); // detect cycles for which Read is non empty TBD /* if (m_showParser) m_symbols.PrintTransitions(new Func(Transition.Follow),"Follow"); */ m_symbols.Transitions(new Builder(Transition.BuildLA)); } // 5: OUTPUT // output the run-time ParsingInfo table Console.WriteLine("Building parse table"); m_symbols.Transitions(new Builder(Transition.BuildParseTable)); foreach (CSymbol v in m_symbols.symbols.Values) { if (v.m_symtype!=CSymbol.SymType.nodesymbol) continue; ParsingInfo pi = new ParsingInfo(v.yytext); CSymbol r = v; while (r.m_symtype==CSymbol.SymType.nodesymbol) r = r.m_refSymbol; if (m_symbols.symbolInfo[v.yytext]!=null) m_symbols.erh.Error(new CSToolsException(45,"Bad %node/%symbol hierarchy")); pi.m_parsetable = m_symbols.GetSymbolInfo(r.yytext).m_parsetable; m_symbols.symbolInfo[v.yytext] = pi; } Console.WriteLine("Writing the output file"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public yy"+m_outname+"():base() { arr = new int[] { "); m_symbols.Emit(m_outFile); // output the class factories CSymbol s; Console.WriteLine("Class factories"); IDictionaryEnumerator de = m_symbols.symbols.GetEnumerator(); for (int pos = 0; pos<m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s==null) // might happen because of error recovery || (s.m_symtype!=CSymbol.SymType.nonterminal && s.m_symtype!=CSymbol.SymType.nodesymbol)) continue; //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine("new Sfactory(this,\"{0}\",new SCreator({0}_factory));",str); } m_outFile.WriteLine("}"); de.Reset(); for (int pos = 0; pos<m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s==null) // might happen because of error recovery || (s.m_symtype!=CSymbol.SymType.nonterminal && s.m_symtype!=CSymbol.SymType.nodesymbol)) continue; //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public static object "+str+"_factory(Parser yyp) { return new "+str+"(yyp); }"); } m_outFile.WriteLine("}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public class "+m_outname+": Parser {"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"():base(new yy"+m_outname+"(),new "+m_lexerClass+"()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"(Symbols syms):base(syms,new "+m_lexerClass+"()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public "+m_outname+"(Symbols syms,ErrorHandler erh):base(syms,new "+m_lexerClass+"(erh)) {}"); m_outFile.WriteLine(m_actvars); m_outFile.WriteLine(" }"); if (m_namespace) m_outFile.WriteLine("}"); Console.WriteLine("Done"); if (m_showParser) { foreach (ParseState ps in m_symbols.m_states.Values) { ps.Print(); if (ps==m_symbols.m_accept) Console.WriteLine(" EOF accept"); } } }
void _Create() { ptokens tks = new ptokens(erh); m_outname = "syntax"; tks.m_sgen = this; m_lexer = tks; m_symbols.erh = erh; m_symbols.ClassInit(this); m_outname = "syntax"; m_outFile.WriteLine("using System;using Tools;"); Production special = new Production(this, m_symbols.Special); m_lexer.yytext = "error"; CSymbol e = (new CSymbol(this)).Resolve(); e.m_symtype = CSymbol.SymType.nonterminal; e.m_defined = true; // 1: INPUT // top-down parsing of script m_lexer.Start(m_inFile); m_tok = (TOKEN)m_lexer.Next(); //Console.WriteLine("Token <{0}> {1}",m_tok.yytext,m_tok.GetType().Name); while (m_tok != null) { ParseProduction(); } // that's the end of the script if (!m_parserseen) { Error(30, 0, "no parser directive detected - possibly incorrect text encoding?"); } m_outFile.WriteLine(m_actions); // output the action function m_outFile.WriteLine("} return null; }"); special.AddToRhs(m_symbols.m_startSymbol); special.AddToRhs(m_symbols.EOFSymbol); // 2: PROCESSING Console.WriteLine("First"); DoFirst(); Console.WriteLine("Follow"); DoFollow(); Console.WriteLine("Parse Table"); ParseState start = new ParseState(this, null); m_symbols.m_states[0] = start; start.MaybeAdd(new ProdItem(special, 0)); start.Closure(); start.AddEntries(); Transition tfinal = (Transition)start.m_transitions[m_symbols.m_startSymbol.yytext]; ParserShift pe = tfinal.m_next; m_symbols.m_accept = pe.m_next; if (m_symbols.m_accept == null) { m_symbols.erh.Error(new CSToolsFatalException(43, 0, 0, "", "No accept state. ParserGenerator cannot continue.")); } // 2A: Reduce States for the LR(0) parser foreach (ParseState ps in m_symbols.m_states.Values) { ps.ReduceStates(); } /* if (m_showParser) * { * foreach (ParseState ps in m_symbols.m_states.Values) * { * ps.Print0(); * if (ps==m_symbols.m_accept) * Console.WriteLine(" EOF accept"); * } * } */ // 3: Compute Look-ahead sets if (m_lalrParser) { m_symbols.Transitions(new Builder(Transition.BuildDR)); /* if (m_showParser) * m_symbols.PrintTransitions(new Func(Transition.DR),"DR"); */ m_symbols.Transitions(new Builder(Transition.BuildReads)); new Digraph(this, new Relation(Transition.reads), new Func(Transition.DR), new Func(Transition.Read), new AddToFunc(Transition.AddToRead)).Compute(); // detect cycles in Read TBD /* if (m_showParser) * m_symbols.PrintTransitions(new Func(Transition.Read),"Read"); */ m_symbols.Transitions(new Builder(Transition.BuildIncludes)); m_symbols.Transitions(new Builder(Transition.BuildLookback)); new Digraph(this, new Relation(Transition.includes), new Func(Transition.Read), new Func(Transition.Follow), new AddToFunc(Transition.AddToFollow)).Compute(); // detect cycles for which Read is non empty TBD /* if (m_showParser) * m_symbols.PrintTransitions(new Func(Transition.Follow),"Follow"); */ m_symbols.Transitions(new Builder(Transition.BuildLA)); } // 5: OUTPUT // output the run-time ParsingInfo table Console.WriteLine("Building parse table"); m_symbols.Transitions(new Builder(Transition.BuildParseTable)); foreach (CSymbol v in m_symbols.symbols.Values) { if (v.m_symtype != CSymbol.SymType.nodesymbol) { continue; } ParsingInfo pi = new ParsingInfo(v.yytext); CSymbol r = v; while (r.m_symtype == CSymbol.SymType.nodesymbol) { r = r.m_refSymbol; } if (m_symbols.symbolInfo[v.yytext] != null) { m_symbols.erh.Error(new CSToolsException(45, "Bad %node/%symbol hierarchy")); } pi.m_parsetable = m_symbols.GetSymbolInfo(r.yytext).m_parsetable; m_symbols.symbolInfo[v.yytext] = pi; } Console.WriteLine("Writing the output file"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public yy" + m_outname + "():base() { arr = new int[] { "); m_symbols.Emit(m_outFile); // output the class factories CSymbol s; Console.WriteLine("Class factories"); IDictionaryEnumerator de = m_symbols.symbols.GetEnumerator(); for (int pos = 0; pos < m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s == null) || // might happen because of error recovery (s.m_symtype != CSymbol.SymType.nonterminal && s.m_symtype != CSymbol.SymType.nodesymbol)) { continue; } //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine("new Sfactory(this,\"{0}\",new SCreator({0}_factory));", str); } m_outFile.WriteLine("}"); de.Reset(); for (int pos = 0; pos < m_symbols.symbols.Count; pos++) { de.MoveNext(); string str = (string)de.Key; s = (CSymbol)de.Value; if ((s == null) || // might happen because of error recovery (s.m_symtype != CSymbol.SymType.nonterminal && s.m_symtype != CSymbol.SymType.nodesymbol)) { continue; } //Console.WriteLine("{0} {1}",s.yytext,s.m_symtype); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public static object " + str + "_factory(Parser yyp) { return new " + str + "(yyp); }"); } m_outFile.WriteLine("}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public class " + m_outname + ": Parser {"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public " + m_outname + "():base(new yy" + m_outname + "(),new " + m_lexerClass + "()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public " + m_outname + "(Symbols syms):base(syms,new " + m_lexerClass + "()) {}"); m_outFile.WriteLine(@"/// <summary/>"); m_outFile.WriteLine("public " + m_outname + "(Symbols syms,ErrorHandler erh):base(syms,new " + m_lexerClass + "(erh)) {}"); m_outFile.WriteLine(m_actvars); m_outFile.WriteLine(" }"); if (m_namespace) { m_outFile.WriteLine("}"); } Console.WriteLine("Done"); if (m_showParser) { foreach (ParseState ps in m_symbols.m_states.Values) { ps.Print(); if (ps == m_symbols.m_accept) { Console.WriteLine(" EOF accept"); } } } }