예제 #1
0
        public new static object Serialise(object o, Serialiser s)
        {
            if (s == null)
            {
                return((object)new ParserShift());
            }
            ParserShift parserShift = (ParserShift)o;

            if (s.Encode)
            {
                ParserEntry.Serialise((object)parserShift, s);
                s.Serialise((object)parserShift.m_next);
                return((object)null);
            }
            ParserEntry.Serialise((object)parserShift, s);
            parserShift.m_next = (ParseState)s.Deserialise();
            return((object)parserShift);
        }
예제 #2
0
    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");
                }
            }
        }
    }