/// <summary> /// Gera a tabela da análise ascendente a partir do afd /// </summary> private void GenerateTable() { GrammarState initialState = GrammarState.ConvertFrom(Afd.InitialState); _table.AddEntry(Terminal.Initial, initialState, null, EntryType.ACCEPTED); GenerateTableEntries(initialState); //A partir daqui, todos os estados finais devem estar listados foreach (GrammarState state in FinalStatesList) { GrammarState usedState = GrammarState.ConvertFrom(Afd.GetState(state.StateValue)); Symbol stateSymbol = state.GetStateSymbol(); if (stateSymbol.Value.Equals(NonTerminal.AscendentSymbolString)) { _table.AddEntry(Terminal.Initial, state, null, EntryType.ACCEPTED); } else { NonTerminal nonTerminal = (NonTerminal)stateSymbol; List <Terminal> follows = nonTerminal.Follows; foreach (Terminal follow in follows) { _table.AddEntry(follow, GenerateReduction(state), null, EntryType.REDUCTION); } } } }
/// <summary> /// Gera a entrada das tabelas /// </summary> /// <param name="state"></param> private List <TableEntry> GenerateTableEntries(GrammarState state) { GrammarState stateC = new GrammarState(state.StateValue); if (!state.Equals(GrammarState.ConvertFrom(Afd.InitialState))) { state = GrammarState.ConvertFrom(Afd.GetState(state.StateValue)); } List <TableEntry> entries = new List <TableEntry>(); Symbol stateSymbol = state.GetStateSymbol(); //Verifica se o estado é final para adicioná-lo à lista if (state.VerifyFinal()) { //Aparentemente, essa verificação não está correta if (!FinalStatesList.Contains(state)) { state.IsFinal = true; FinalStatesList.Add(state); } } //Varre todas as transições do estado foreach (StateTransiction <string, Symbol> transiction in state.Transictions) { Symbol symbol = transiction.Transiction; GrammarState grammarNextState = GrammarState.ConvertFrom(transiction.NextState); if (symbol is NonTerminal) { TableEntry entry = new TableEntry(symbol, state, grammarNextState, EntryType.GOTO); if (_table.AddEntry(entry)) { GenerateTableEntries(grammarNextState); entries.Add(entry); } } else { //Manda gerar as próximas entradas na tabela, mas não adiciona a entrada if (grammarNextState != null) { TableEntry entry = new TableEntry(symbol, state, grammarNextState, EntryType.SHIFT); if (_table.AddEntry(entry)) { GenerateTableEntries(grammarNextState); entries.Add(entry); } } else { TableEntry entry = new TableEntry(symbol, state, null, EntryType.REDUCTION); if (_table.AddEntry(entry)) { entries.Add(entry); } } } } return(entries); }