Exemplo n.º 1
0
        /// <summary>
        ///     Loads parse tables from the specified BinaryReader. Only EGT (version 5.0) is supported.
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public bool LoadCompiledGrammar(BinaryReader reader)
        {
            var egt = new EGTReader();

            try
            {
                egt.Open(reader);

                Restart();
                while (!egt.EndOfFile())
                {
                    egt.GetNextRecord();
                    var recordType = (EGTRecord)egt.RetrieveByte();

                    if (recordType == EGTRecord.Property)
                    {
                        //Index, Name, ValueExpression
                        int index = egt.RetrieveInt16();
                        egt.RetrieveString();
                        //Just discard
                        _grammar.SetValue(index, egt.RetrieveString());
                    }
                    else if (recordType == EGTRecord.TableCounts)
                    {
                        //Symbol, CharacterSet, Rule, DFA, LALR
                        _symbolTable     = new SymbolList(egt.RetrieveInt16());
                        _charSetTable    = new CharacterSetList(egt.RetrieveInt16());
                        _productionTable = new ProductionList(egt.RetrieveInt16());
                        _dfa             = new FAStateList(egt.RetrieveInt16());
                        _lrStates        = new LRStateList(egt.RetrieveInt16());
                        _groupTable      = new GroupList(egt.RetrieveInt16());
                    }
                    else if (recordType == EGTRecord.InitialStates)
                    {
                        //DFA, LALR
                        _dfa.InitialState      = (short)egt.RetrieveInt16();
                        _lrStates.InitialState = (short)egt.RetrieveInt16();
                    }
                    else if (recordType == EGTRecord.Symbol)
                    {
                        //#, Name, Kind

                        int    index = egt.RetrieveInt16();
                        string name  = egt.RetrieveString();
                        var    type  = (SymbolType)egt.RetrieveInt16();

                        _symbolTable[index] = new Symbol(name, type, (short)index);
                    }
                    else if (recordType == EGTRecord.Group)
                    {
                        //#, Name, Container#, Start#, End#, Tokenized, Open Ended, Reserved, Count, (Nested Group #...)
                        var group = new Group();

                        int index = egt.RetrieveInt16();
                        group.Name      = egt.RetrieveString();
                        group.Container = SymbolTable[egt.RetrieveInt16()];
                        group.Start     = SymbolTable[egt.RetrieveInt16()];
                        group.End       = SymbolTable[egt.RetrieveInt16()];

                        group.Advance = (Group.AdvanceMode)egt.RetrieveInt16();
                        group.Ending  = (Group.EndingMode)egt.RetrieveInt16();
                        egt.RetrieveEntry();
                        //Reserved
                        int count = egt.RetrieveInt16();
                        for (int n = 0; n < count; n++)
                        {
                            group.Nesting.Add(egt.RetrieveInt16());
                        }


                        //=== Link back
                        group.Container.Group = group;
                        group.Start.Group     = group;
                        group.End.Group       = group;

                        _groupTable[index] = group;
                    }
                    else if (recordType == EGTRecord.CharRanges)
                    {
                        //#, Total Sets, RESERVED, (Start#, End#  ...)

                        int index = egt.RetrieveInt16();
                        egt.RetrieveInt16();
                        egt.RetrieveInt16();
                        egt.RetrieveEntry();

                        _charSetTable[index] = new CharacterSet();
                        while (!egt.RecordComplete())
                        {
                            _charSetTable[index].Add(new CharacterRange((ushort)egt.RetrieveInt16(), (ushort)egt.RetrieveInt16()));
                        }
                    }
                    else if (recordType == EGTRecord.Production)
                    {
                        //#, ID#, Reserved, (Symbol#,  ...)

                        int index     = egt.RetrieveInt16();
                        int headIndex = egt.RetrieveInt16();
                        egt.RetrieveEntry();

                        _productionTable[index] = new Production(_symbolTable[headIndex], (short)index);

                        while (!(egt.RecordComplete()))
                        {
                            int symbolIndex = egt.RetrieveInt16();
                            _productionTable[index].Handle.Add(_symbolTable[symbolIndex]);
                        }
                    }
                    else if (recordType == EGTRecord.DfaState)
                    {
                        //#, Accept?, Accept#, Reserved (CharSet#, Target#, Reserved)...

                        int  index       = egt.RetrieveInt16();
                        bool accept      = egt.RetrieveBoolean();
                        int  acceptIndex = egt.RetrieveInt16();
                        egt.RetrieveEntry();

                        if (accept)
                        {
                            _dfa[index] = new FAState(_symbolTable[acceptIndex]);
                        }
                        else
                        {
                            _dfa[index] = new FAState();
                        }

                        //(Edge chars, Target#, Reserved)...
                        while (!egt.RecordComplete())
                        {
                            int setIndex = egt.RetrieveInt16();
                            int target   = egt.RetrieveInt16();
                            egt.RetrieveEntry();

                            _dfa[index].Edges.Add(new FAEdge(_charSetTable[setIndex], target));
                        }
                    }
                    else if (recordType == EGTRecord.LrState)
                    {
                        //#, Reserved (Symbol#, Action, Target#, Reserved)...

                        int index = egt.RetrieveInt16();
                        egt.RetrieveEntry();

                        _lrStates[index] = new LRState();

                        //(Symbol#, Action, Target#, Reserved)...
                        while (!(egt.RecordComplete()))
                        {
                            int symbolIndex = egt.RetrieveInt16();
                            int action      = egt.RetrieveInt16();
                            int target      = egt.RetrieveInt16();
                            egt.RetrieveEntry();

                            _lrStates[index].Add(new LRAction(_symbolTable[symbolIndex], (LRActionType)action, (short)target));
                        }
                    }
                    else
                    {
                        throw new EngineException("File Error. A record of type '" + recordType + "' was read. This is not a valid code.");
                    }
                }
            }
            catch (EngineException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new EngineException("Error while loading tables.", ex);
            }

            _areTablesLoaded = true;
            return(true);
        }
Exemplo n.º 2
0
 internal Production(Symbol head, short tableIndex)
 {
     _head       = head;
     _handle     = new SymbolList();
     _tableIndex = tableIndex;
 }