/// <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); }
internal Production(Symbol head, short tableIndex) { _head = head; _handle = new SymbolList(); _tableIndex = tableIndex; }