public int Add(LRStateBuild Item) { LRState item = Item; Item = (LRStateBuild)item; return(base.Add(item)); }
internal SymbolList GetExpectedSymbols(short CurrentLALR) { LRState state = m_LRStates[CurrentLALR]; List <Symbol> expectedSymbols = new List <Symbol>(); state.ForEach(action => { switch (action.Symbol.Type) { case SymbolType.Content: case SymbolType.End: case SymbolType.GroupStart: case SymbolType.GroupEnd: expectedSymbols.Add(action.Symbol); break; } }); return(new SymbolList(expectedSymbols)); }
internal EGT(BinaryReader Reader) { EGTReader EGT = new EGTReader(Reader); EGTRecord RecType = default(EGTRecord); try { while (!EGT.EndOfFile()) { EGT.GetNextRecord(); RecType = (EGTRecord)EGT.RetrieveByte(); switch (RecType) { case EGTRecord.Property: { //Index, Name, Value int Index = 0; string Name = null; Index = EGT.RetrieveInt16(); Name = EGT.RetrieveString(); //Just discard m_Grammar.SetValue(Index, EGT.RetrieveString()); } break; case EGTRecord.TableCounts: //Symbol, CharacterSet, Rule, DFA, LALR m_SymbolTable = new SymbolList(EGT.RetrieveInt16()); m_CharSetTable = new CharacterSetList(EGT.RetrieveInt16()); m_ProductionTable = new ProductionList(EGT.RetrieveInt16()); m_DFA = new FAStateList(EGT.RetrieveInt16()); m_LRStates = new LRStateList(EGT.RetrieveInt16()); m_GroupTable = new GroupList(EGT.RetrieveInt16()); break; case EGTRecord.InitialStates: //DFA, LALR m_DFA.InitialState = EGT.RetrieveInt16(); m_LRStates.InitialState = EGT.RetrieveInt16(); break; case EGTRecord.Symbol: { //#, Name, Kind short Index = 0; string Name = null; SymbolType Type = default(SymbolType); Index = EGT.RetrieveInt16(); Name = EGT.RetrieveString(); Type = (SymbolType)EGT.RetrieveInt16(); m_SymbolTable[Index] = new Symbol(Name, Type, Index); } break; case EGTRecord.Group: //#, Name, Container#, Start#, End#, Tokenized, Open Ended, Reserved, Count, (Nested Group #...) { Group G = new Group(); G.TableIndex = EGT.RetrieveInt16(); //# G.Name = EGT.RetrieveString(); G.Container = m_SymbolTable[EGT.RetrieveInt16()]; G.Start = m_SymbolTable[EGT.RetrieveInt16()]; G.End = m_SymbolTable[EGT.RetrieveInt16()]; G.Advance = (Group.AdvanceMode)EGT.RetrieveInt16(); G.Ending = (Group.EndingMode)EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved int Count = EGT.RetrieveInt16(); for (int n = 1; n <= Count; n++) { G.Nesting.Add(EGT.RetrieveInt16()); } //=== Link back m_GroupStart.Add(G.Start, G); m_GroupTable[G.TableIndex] = G; } break; case EGTRecord.CharRanges: //#, Total Sets, RESERVED, (Start#, End# ...) { int Index = 0; int Total = 0; Index = EGT.RetrieveInt16(); EGT.RetrieveInt16(); //Codepage Total = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_CharSetTable[Index] = new CharacterSet(); while (!(EGT.RecordComplete())) { m_CharSetTable[Index].Add(new CharacterRange(EGT.RetrieveUInt16(), EGT.RetrieveUInt16())); } } break; case EGTRecord.Production: //#, ID#, Reserved, (Symbol#, ...) { short Index = 0; int HeadIndex = 0; int SymIndex = 0; Index = EGT.RetrieveInt16(); HeadIndex = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved List <Symbol> symbols = new List <Symbol>(); while (!(EGT.RecordComplete())) { SymIndex = EGT.RetrieveInt16(); //m_ProductionTable[Index].Handle().Add(m_SymbolTable[SymIndex]); symbols.Add(m_SymbolTable[SymIndex]); } SymbolList symbolList = new SymbolList(symbols); m_ProductionTable[Index] = new Production(m_SymbolTable[HeadIndex], Index, symbolList); } break; case EGTRecord.DFAState: //#, Accept?, Accept#, Reserved (CharSet#, Target#, Reserved)... { int Index = 0; bool Accept = false; int AcceptIndex = 0; int SetIndex = 0; short Target = 0; Index = EGT.RetrieveInt16(); Accept = EGT.RetrieveBoolean(); AcceptIndex = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved if (Accept) { m_DFA[Index] = new FAState(m_SymbolTable[AcceptIndex]); } else { m_DFA[Index] = new FAState(); } //(Edge chars, Target#, Reserved)... while (!(EGT.RecordComplete())) { SetIndex = EGT.RetrieveInt16(); //Char table index Target = EGT.RetrieveInt16(); //Target EGT.RetrieveEntry(); //Reserved m_DFA[Index].Edges.Add(new FAEdge(m_CharSetTable[SetIndex], Target)); } } break; case EGTRecord.LRState: //#, Reserved (Symbol#, Action, Target#, Reserved)... { int Index = 0; int SymIndex = 0; LRActionType Action = 0; short Target = 0; Index = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_LRStates[Index] = new LRState(); //(Symbol#, Action, Target#, Reserved)... while (!EGT.RecordComplete()) { SymIndex = EGT.RetrieveInt16(); Action = (LRActionType)EGT.RetrieveInt16(); Target = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_LRStates[Index].Add(new LRAction(m_SymbolTable[SymIndex], Action, Target)); } } break; default: //RecordIDComment throw new ParserException("File Error. A record of type '" + (char)RecType + "' was read. This is not a valid code."); } } } catch (Exception ex) { throw new ParserException(ex.Message, ex, "LoadTables"); } }
internal LRAction FindLRAction(short CurrentLALR, Symbol symbolToFind) { LRState state = m_LRStates[CurrentLALR]; return(state.Find(action => action.Symbol.Equals(symbolToFind))); }
internal EGT(BinaryReader Reader) { EGTReader EGT = new EGTReader(Reader); EGTRecord RecType = default(EGTRecord); try { while (!EGT.EndOfFile()) { EGT.GetNextRecord(); RecType = (EGTRecord)EGT.RetrieveByte(); switch (RecType) { case EGTRecord.Property: { //Index, Name, Value int Index = 0; string Name = null; Index = EGT.RetrieveInt16(); Name = EGT.RetrieveString(); //Just discard m_Grammar.SetValue(Index, EGT.RetrieveString()); } break; case EGTRecord.TableCounts: //Symbol, CharacterSet, Rule, DFA, LALR m_SymbolTable = new SymbolList(EGT.RetrieveInt16()); m_CharSetTable = new CharacterSetList(EGT.RetrieveInt16()); m_ProductionTable = new ProductionList(EGT.RetrieveInt16()); m_DFA = new FAStateList(EGT.RetrieveInt16()); m_LRStates = new LRStateList(EGT.RetrieveInt16()); m_GroupTable = new GroupList(EGT.RetrieveInt16()); break; case EGTRecord.InitialStates: //DFA, LALR m_DFA.InitialState = EGT.RetrieveInt16(); m_LRStates.InitialState = EGT.RetrieveInt16(); break; case EGTRecord.Symbol: { //#, Name, Kind short Index = 0; string Name = null; SymbolType Type = default(SymbolType); Index = EGT.RetrieveInt16(); Name = EGT.RetrieveString(); Type = (SymbolType)EGT.RetrieveInt16(); m_SymbolTable[Index] = new Symbol(Name, Type, Index); } break; case EGTRecord.Group: //#, Name, Container#, Start#, End#, Tokenized, Open Ended, Reserved, Count, (Nested Group #...) { Group G = new Group(); G.TableIndex = EGT.RetrieveInt16(); //# G.Name = EGT.RetrieveString(); G.Container = m_SymbolTable[EGT.RetrieveInt16()]; G.Start = m_SymbolTable[EGT.RetrieveInt16()]; G.End = m_SymbolTable[EGT.RetrieveInt16()]; G.Advance = (Group.AdvanceMode)EGT.RetrieveInt16(); G.Ending = (Group.EndingMode)EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved int Count = EGT.RetrieveInt16(); for (int n = 1; n <= Count; n++) { G.Nesting.Add(EGT.RetrieveInt16()); } //=== Link back m_GroupStart.Add(G.Start, G); m_GroupTable[G.TableIndex] = G; } break; case EGTRecord.CharRanges: //#, Total Sets, RESERVED, (Start#, End# ...) { int Index = 0; int Total = 0; Index = EGT.RetrieveInt16(); EGT.RetrieveInt16(); //Codepage Total = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_CharSetTable[Index] = new CharacterSet(); while (!(EGT.RecordComplete())) { m_CharSetTable[Index].Add(new CharacterRange(EGT.RetrieveUInt16(), EGT.RetrieveUInt16())); } } break; case EGTRecord.Production: //#, ID#, Reserved, (Symbol#, ...) { short Index = 0; int HeadIndex = 0; int SymIndex = 0; Index = EGT.RetrieveInt16(); HeadIndex = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved List<Symbol> symbols = new List<Symbol>(); while (!(EGT.RecordComplete())) { SymIndex = EGT.RetrieveInt16(); //m_ProductionTable[Index].Handle().Add(m_SymbolTable[SymIndex]); symbols.Add(m_SymbolTable[SymIndex]); } SymbolList symbolList = new SymbolList(symbols); m_ProductionTable[Index] = new Production(m_SymbolTable[HeadIndex], Index, symbolList); } break; case EGTRecord.DFAState: //#, Accept?, Accept#, Reserved (CharSet#, Target#, Reserved)... { int Index = 0; bool Accept = false; int AcceptIndex = 0; int SetIndex = 0; short Target = 0; Index = EGT.RetrieveInt16(); Accept = EGT.RetrieveBoolean(); AcceptIndex = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved if (Accept) { m_DFA[Index] = new FAState(m_SymbolTable[AcceptIndex]); } else { m_DFA[Index] = new FAState(); } //(Edge chars, Target#, Reserved)... while (!(EGT.RecordComplete())) { SetIndex = EGT.RetrieveInt16(); //Char table index Target = EGT.RetrieveInt16(); //Target EGT.RetrieveEntry(); //Reserved m_DFA[Index].Edges.Add(new FAEdge(m_CharSetTable[SetIndex], Target)); } } break; case EGTRecord.LRState: //#, Reserved (Symbol#, Action, Target#, Reserved)... { int Index = 0; int SymIndex = 0; LRActionType Action = 0; short Target = 0; Index = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_LRStates[Index] = new LRState(); //(Symbol#, Action, Target#, Reserved)... while (!EGT.RecordComplete()) { SymIndex = EGT.RetrieveInt16(); Action = (LRActionType)EGT.RetrieveInt16(); Target = EGT.RetrieveInt16(); EGT.RetrieveEntry(); //Reserved m_LRStates[Index].Add(new LRAction(m_SymbolTable[SymIndex], Action, Target)); } } break; default: //RecordIDComment throw new ParserException("File Error. A record of type '" + (char)RecType + "' was read. This is not a valid code."); } } } catch (Exception ex) { throw new ParserException(ex.Message, ex, "LoadTables"); } }
public void GenerateTable(List <LRState> LRstates) { var states = LRstates.ToList(); var groupedStates = new List <LRState>(); var statesNumbers = new List <int>(); var nextStateNumber = 0; foreach (var variable in states) { if (!statesNumbers.Exists(w => w.Equals(variable.Number))) { var similarStates = new List <LRState>(); similarStates.Add(variable); if (variable.Number == 6) { } foreach (var state in LRstates.ToList().Where(e => e.Number != variable.Number)) { bool equalFlag = true; if (state.Productions.Count() == variable.Productions.Count()) { for (int i = 0; i < variable.Productions.Count; i++) { if (variable.Productions[i].Production.Equals(state.Productions[i].Production) && variable.Productions[i].Marked.Index == state.Productions[i].Marked.Index) { } else { equalFlag = false; } } } else { equalFlag = false; } if (equalFlag) { similarStates.Add(state); } } LRState newState = similarStates.ToList().First(); foreach (var oldState in similarStates) { foreach (var s in states.Where(w => w.Productions.Exists(q => q.Action == ActionType.State && q.ActionNumber == oldState.Number))) { foreach (var p in s.Productions.Where(q => q.Action == ActionType.State && q.ActionNumber == oldState.Number)) { p.ActionNumber = nextStateNumber; } } } foreach (var oldState in similarStates.Where(y => y.Number != newState.Number)) { statesNumbers.Add(oldState.Number); //Atualizar o Follow Local var localFollowSize = oldState.Productions.Count; for (int j = 0; j < localFollowSize; j++) { foreach (var lf in oldState.Productions[j].LocalFolow) { if (!newState.Productions[j].LocalFolow.Exists(r => r.Value == lf.Value)) { newState.Productions[j].LocalFolow.Add(lf); } } } } newState.Number = nextStateNumber; statesNumbers.Add(newState.Number); nextStateNumber++; groupedStates.Add(newState); } } Generated = true; CreateTableMatches(groupedStates); }
public void GenerateTable(DataGridView gridView) { int NextStateNumber = 0; //Número do próximo estado List <LRState> states = new List <LRState>(); //Estados var productions = _syntactic.GetSingleProductions(); //Pega todas as produções var firstProduction = productions.First(); //Inicio com o primeiro estado (0) var firstState = new LRState(); firstState.Number = NextStateNumber; NextStateNumber++; //Adiciona a primeira produção (Slinha) var firstStateProduction = new LRStateProduction(); firstStateProduction.LocalFolow.Add(new Symbol() { Type = SymbolType.EndOfFile, Value = "$" }); firstStateProduction.Production = firstProduction; firstState.Productions.Add(firstStateProduction); states.Add(firstState); while (states.Exists(e => e.Done == false)) { var actualState = states.First(w => w.Done == false); while (actualState.Productions.Exists(u => u.Checked == false)) { var p = actualState.Productions.First(i => i.Checked == false); if (!p.Checked) { Closure(p, ref actualState, productions); } } if (!actualState.Productions.Exists(g => g.Checked == false)) { actualState.Done = true; //TERMINOU O FECHO, CRIA OS PRÓXIMOS ESTADOS } var grouped = actualState.Productions.Where(e => e.Action == ActionType.State).GroupBy(item => item.Marked.Symbol.Value); foreach (var item in grouped) { bool similarTransitionFound = false; //VERIFICA SE JÁ EXISTE ALGUMA TRANSIÇÃO SIMILAR // item = transições para o mesmo estado, agrupadas foreach (var VARIABLE in states.Where(e => !e.Equals(actualState))) { var stateGroupedProductions = VARIABLE.Productions.GroupBy(x => new { x.ActionNumber }); foreach (var gp in stateGroupedProductions) { if (gp.ToList().Count == item.ToList().Count() && gp.All(a => a.Action == ActionType.State)) { bool flag = true; //SÃO DO MESMO TAMANHO, POSSO VERIFICAR SE SÃO IGUAIS for (int i = 0; i < gp.ToList().Count; i++) { if (!(gp.ToList()[i].Production.Equals(item.ToList()[i].Production)) || !(gp.ToList()[i].Marked.Index == item.ToList()[i].Marked.Index)) { flag = false; } else { if (gp.ToList()[i].LocalFolow.ToList().Count == item.ToList()[i].LocalFolow.Count()) { //SÃO DO MESMO TAMANHO, POSSO VERIFICAR SE SÃO IGUAIS for (int j = 0; j < gp.ToList()[i].LocalFolow.Count; j++) { if (!(gp.ToList()[i].LocalFolow[j].Value.Equals(item.ToList()[i].LocalFolow[j].Value))) { flag = false; } } } else { flag = false; } } } if (flag) { similarTransitionFound = true; foreach (var va in item) { va.ActionNumber = gp.First().ActionNumber; } break; } } } if (similarTransitionFound) { break; } } if (!similarTransitionFound) { var newState = new LRState(); newState.Number = NextStateNumber; foreach (var VARIABLE in item) { var nextStateNewProduction = new LRStateProduction() { Production = VARIABLE.Production, Marked = new MarkedSymbol() { Index = VARIABLE.Marked.Index, Symbol = new Symbol() { Type = VARIABLE.Marked.Symbol.Type, Value = VARIABLE.Marked.Symbol.Value } }, Checked = false }; nextStateNewProduction.LocalFolow.AddRange(VARIABLE.LocalFolow); newState.Productions.Add(nextStateNewProduction); } foreach (var pro in newState.Productions) { pro.Checked = false; } states.Add(newState); foreach (var VARIABLE in item) { actualState.Productions.Find(w => w.Equals(VARIABLE)).ActionNumber = NextStateNumber; } NextStateNumber++; } } } CreateTableMatches(states); Generated = true; this.LRstates.AddRange(states.ToList()); }
public void Closure(LRStateProduction p, ref LRState actualState, List <SingleProduction> productions) { //VERIFICO SE PRECISO ANDAR COM O FECHO E INCREMENTO O INDEX p.Marked.Index++; if (p.Marked.Index < p.Production.Produced.Count) { p.Marked.Symbol = p.Production.Produced.ElementAt(p.Marked.Index); } //Verifica se existe um simbolo nesse index. Caso não, é uma redução if ((p.Marked.Index >= p.Production.Produced.Count) || ((p.Marked.Symbol.Type == SymbolType.Empty) && (p.Marked.Index + 1 == p.Production.Produced.Count))) { p.Action = ActionType.Reduction; p.ActionNumber = p.Production.Number; } else { p.Marked.Symbol = p.Production.Produced.ElementAt(p.Marked.Index); p.Action = ActionType.State; //ANDEI COM O FECHO, VERIFICO SE É UM NÃO TERMINAL var s = p.Marked.Symbol; if (s.Type == SymbolType.NonTerminal) { //PEGO AS PRODUÇÕES DESSE NÃO TERMINAL var nonTerminalProductions = productions.Where(t => t.Producer.Value == s.Value); //DECIDO QUAL VAI SER O FOLLOW var localFollow = new List <Symbol>(); if (p.Marked.Index + 1 < p.Production.Produced.Count) { //Pego o first desse simbolo var nextSymbol = p.Production.Produced.ElementAt(p.Marked.Index + 1); if (nextSymbol.Type == SymbolType.Terminal) { localFollow.Add(new Symbol() { Type = nextSymbol.Type, Value = nextSymbol.Value }); } if (nextSymbol.Type == SymbolType.NonTerminal) { localFollow.AddRange(_semantic.GetFirstList() .Find(e => e.NonTerminal.Value == nextSymbol.Value).Terminals); } } else { //Follow local é igual ao follow atual localFollow.AddRange(p.LocalFolow); } //Já tenho o Follow local, verifico se preciso atualizar o follow de alguém if (actualState.ClosureSymbols.Exists(i => i.Value == s.Value)) { var actualStateNumber = actualState.Number; var pendingUpdateProductions = actualState.Productions.Where(r => r.Production.Producer.Value == s.Value && r.GeneratorStateNumber == actualStateNumber); foreach (var lrp in pendingUpdateProductions) { foreach (var followSymbol in localFollow) { if (!lrp.LocalFolow.Exists(e => e.Value == followSymbol.Value)) { lrp.LocalFolow.Add(followSymbol); } } } } else { //CRIEI UM NOVO LRStateProduction para o estado, que é igual à production desse não terminal foreach (var VARIABLE in nonTerminalProductions) { LRStateProduction sp = new LRStateProduction(); sp.Production = VARIABLE; sp.LocalFolow.AddRange(localFollow); sp.GeneratorStateNumber = actualState.Number; actualState.Productions.Add(sp); } //SALVA QUE JÁ GEROU O FECHO DESSE NÃO TERMINAL actualState.ClosureSymbols.Add(s); } } } p.Checked = true; //MARCO QUE TERMINEI O FECHO DESSE }
public List <LRStateProduction> IsThereASimilarTransition(List <LRStateProduction> productions, LRState s, LRState actualState) { bool flag = false; var grouped = s.Productions.Where(e => e.Action == ActionType.State && e.ActionNumber != actualState.Number).GroupBy(item => item.ActionNumber); foreach (var item in grouped) { flag = true; if (item.ToList().Count == productions.Count) { for (int i = 0; i < productions.Count; i++) { if (!productions[i].Production.Equals(item.ToList()[i].Production)) { flag = false; } } } else { flag = false; } if (flag) { return(item.ToList()); } } return(null); }