コード例 #1
0
        /// <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);
                    }
                }
            }
        }
コード例 #2
0
ファイル: TableEntry.cs プロジェクト: YvensFaos/TinyBASIC_IDE
 public TableEntry(Symbol horizontal, GrammarState vertical, GrammarState nextState, EntryType type)
 {
     _horizontal = horizontal;
     _vertical   = vertical;
     _nextState  = nextState;
     _type       = type;
 }
コード例 #3
0
        /// <summary>
        /// Retorna todas as entradas na tabela que contém aquele estado na vertical da tabela
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public List <TableEntry> TableEntriesFor(GrammarState state)
        {
            List <TableEntry> listEntry = new List <TableEntry>();

            foreach (string entryString in _tableEntryHash.Keys)
            {
                TableEntry entry = _tableEntryHash[entryString];

                if (entry.Vertical.Equals(state))
                {
                    listEntry.Add(entry);
                }
            }

            return(listEntry);
        }
コード例 #4
0
        /// <summary>
        /// Converte um afnde para uma imagem representando o gráfico
        /// </summary>
        public static bool AFNDEtoPNG(string path)
        {
            GrammarNonDeterministicAutomata afnde = new GrammarNonDeterministicAutomata();
            Graph graph = new Graph("");

            for (int i = 0; i < afnde.StateList.Count; i++)
            {
                GrammarState state = GrammarState.ConvertFrom(afnde.StateList[i]);
                graph.AddNode(state.StateValue);
                for (int j = 0; j < state.Transictions.Count; j++)
                {
                    graph.AddEdge(state.StateValue, state.Transictions[j].Transiction.Value, state.Transictions[j].NextState.StateValue);
                }
            }

            return(GenerateGraphImage(graph, path));
        }
コード例 #5
0
 //Gera o número associado à redução
 public GrammarState GenerateReduction(GrammarState state)
 {
     for (int i = 0; i < _productions.Count; i++)
     {
         NonTerminal nonterminal = (NonTerminal)state.GetStateSymbol();
         if (state.ReductionNumber == 0)
         {
             if (nonterminal.FirstContainsEmpty())
             {
                 int reduction = _productions[i].Split(' ').Length - 1;
                 state.ReductionNumber = reduction;
             }
             else if (_productions[i].Equals(state.StateValue.Remove(state.StateValue.LastIndexOf('.') - 1)))
             {
                 int reduction = _productions[i].Split(' ').Length;
                 state.ReductionNumber = reduction;
             }
         }
     }
     return(state);
 }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        private bool AscendentAnalizer(ref string feedback)
        {
            GrammarDeterministicAutomata afd = new GrammarDeterministicAutomata();

            AscendentDealer dealer = new AscendentDealer(afd);

            //Pilha do estado
            SimpleStack <GrammarState> stateStack = new SimpleStack <GrammarState>();

            GrammarState ascendentState = GrammarState.ConvertFrom(afd.InitialState);

            stateStack.Push(ascendentState);

            Token token      = null;
            bool  nextToken  = true;
            bool  errorFound = false;

            while (!errorFound)
            {
                GrammarState state  = null;
                Symbol       symbol = null;

                #region Leitura e análise do token
                if (nextToken)
                {
                    token = Lexic.NextToken();
                    if (token != null)
                    {
                        if (token.Type == TokenType.LINE_BREAK)
                        {
                            line++;
                            //Eu anulo o token para ele mais à frente preencherem o símbolo com $
                            token = null;
                        }
                    }

                    nextToken = false;
                }

                if (token != null)
                {
                    if (token.Type == TokenType.VARIABLE)
                    {
                        symbol = Symbol.GetSymbol("var");
                    }
                    else if (token.Type == TokenType.VALUE)
                    {
                        symbol = Symbol.GetSymbol("num");
                    }
                    else if (token.Type == TokenType.STRING)
                    {
                        symbol = Symbol.GetSymbol("string");
                    }
                    else
                    {
                        symbol = Symbol.GetSymbol(token.Value);
                    }
                }
                else
                {
                    //Se chegou ao fim da linha lida, começa a ler $
                    symbol = Terminal.Initial;
                }
                #endregion

                state = stateStack.Top();

                TableEntry entry = dealer.Table.GetEntry(symbol, state);
                if (entry != null)
                {
                    switch (entry.Type)
                    {
                    case EntryType.SHIFT:
                    {
                        GrammarState nextState = entry.NextState;
                        stateStack.Push(nextState);
                        nextToken = true;
                        break;
                    }

                    case EntryType.REDUCTION:
                    {
                        GrammarState grammarState = stateStack.Top();
                        int          reduction    = dealer.GenerateReduction(grammarState).ReductionNumber;

                        Symbol newSymbol = grammarState.GetStateSymbol();

                        for (int i = 0; i < reduction; i++)
                        {
                            stateStack.Pop();
                        }

                        GrammarState newStateTop = stateStack.Top();
                        entry = dealer.Table.GetEntry(newSymbol, newStateTop);

                        if (entry.Type.Equals(EntryType.GOTO))
                        {
                            goto case EntryType.GOTO;
                        }

                        //Falta empilhar aqui
                        break;
                    }

                    case EntryType.GOTO:
                    {
                        stateStack.Push(entry.NextState);
                        break;
                    }

                    case EntryType.ACCEPTED:
                    {
                        //Fim de arquivo
                        if (Lexic.ListToken.Count == Lexic.Position)
                        {
                            return(true);
                        }
                        else
                        {
                            //Ler próxima linha, esvaziando a pilha
                            nextToken = true;
                            while (!stateStack.IsEmpty())
                            {
                                stateStack.Pop();
                            }
                            stateStack.Push(ascendentState);
                        }
                        break;
                    }

                    default:
                    {
                        feedback  += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                        errorFound = true;
                        break;
                    }
                    }
                }
                else
                {
                    if (state.IsFinal)
                    {
                        //GrammarState grammarState = stateStack.Top();
                        int reduction = dealer.GenerateReduction(state).ReductionNumber;

                        Symbol newSymbol = state.GetStateSymbol();

                        for (int i = 0; i < reduction; i++)
                        {
                            stateStack.Pop();
                        }

                        GrammarState newStateTop = stateStack.Top();
                        entry = dealer.Table.GetEntry(newSymbol, newStateTop);

                        if (entry.Type.Equals(EntryType.GOTO))
                        {
                            stateStack.Push(entry.NextState);
                        }
                    }
                    else
                    {
                        String expectedState = null;
                        if (state.StateValue.Contains('.'))
                        {
                            expectedState = state.StateValue.Split('.')[1].Split(' ')[1].Trim();
                        }

                        if (expectedState == null)
                        {
                            feedback  += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                            errorFound = true;
                            break;
                        }
                        else
                        {
                            feedback  += INCOMPLETE_TENSE_MISS + expectedState + ", linha " + line + "\r\n";
                            errorFound = true;
                            break;
                        }
                    }
                }

                #region código antigo

                /*
                 * //Para debug
                 * List<TableEntry> list = dealer.Table.TableEntriesFor(state);
                 * List<TableEntry> list2 = dealer.Table.TableEntriesIn(symbol);
                 * TableEntry entry = dealer.Table.GetEntry(symbol, state);
                 *
                 * if (entry != null)
                 * {
                 *  switch (entry.Type)
                 *  {
                 *      case EntryType.SHIFT:
                 *          {
                 *              GrammarState nextState = entry.NextState;
                 *              stateStack.Push(nextState);
                 *
                 *              if (nextState.IsFinal)
                 *              {
                 *                  goto case EntryType.REDUCTION;
                 *              }
                 *              else
                 *              {
                 *                  nextToken = true;
                 *              }
                 *              break;
                 *          }
                 *      case EntryType.REDUCTION:
                 *          {
                 #region código abandonado
                 *              //for (int i = 0; i < entry.Vertical.ReductionNumber; i++)
                 *              //{
                 *              //    stateStack.Pop();
                 *              //}
                 #endregion
                 *
                 *              //Desempilhar (reductionNumber) estados da pilha
                 *
                 *              //Topo: itemprint:string . -> reduction = 1
                 *              int reduction = dealer.GenerateReduction(stateStack.Top()).ReductionNumber;
                 *
                 *              for (int i = 0; i < reduction; i++)
                 *              {
                 *                  stateStack.Pop();
                 *              }
                 *
                 *              //entry.NextState: itemprint: string .
                 *              //nextSymbol = itemprint
                 *              Symbol nextSymbol = null;
                 *              if (entry.NextState != null)
                 *              {
                 *                  nextSymbol = entry.NextState.GetStateSymbol();
                 *              }
                 *              else
                 *              {
                 *                  nextSymbol = entry.Vertical.GetStateSymbol();
                 *              }
                 *
                 *              //Topo: instrução:PRINT . listaprint
                 *              GrammarState topState = stateStack.Top();
                 *
                 *              //Voltar para o não-terminal à esquerda da produção
                 *              if (topState == null)
                 *              {
                 *                  entry = dealer.Table.GetEntry(nextSymbol, ascendentState);
                 *              }
                 *              else
                 *              {
                 *                  //Deve ter uma transição de PRINT. listaprint em itemprint
                 *                  entry = dealer.Table.GetEntry(nextSymbol, topState);
                 *              }
                 *
                 *              if (entry != null)
                 *              {
                 *                  if (entry.Type == EntryType.GOTO)
                 *                  {
                 *                      nextToken = true;
                 *                      goto case EntryType.GOTO;
                 *                  }
                 *                  else
                 *                  {
                 *                      errorFound = true;
                 *                  }
                 *              }
                 *              else
                 *              {
                 *                  feedback += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                 *                  errorFound = true;
                 *              }
                 *
                 *              break;
                 *
                 *          }
                 *      case EntryType.GOTO:
                 *          {
                 *              stateStack.Push(entry.NextState);
                 *              break;
                 *          }
                 *      case EntryType.ACCEPTED:
                 *          {
                 *              //Fim de arquivo
                 *              if (Lexic.ListToken.Count == Lexic.Position)
                 *              {
                 *                  return true;
                 *              }
                 *              else
                 *              {
                 *                  //Ler próxima linha, esvaziando a pilha
                 *                  nextToken = true;
                 *                  while (!stateStack.IsEmpty())
                 *                  {
                 *                      stateStack.Pop();
                 *                  }
                 *                  stateStack.Push(ascendentState);
                 *              }
                 *              break;
                 *          }
                 *      default:
                 *          {
                 *              feedback += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                 *              errorFound = true;
                 *              break;
                 *          }
                 *  }
                 * }
                 *  //Caso a entry seja nula
                 * else
                 * {
                 *  if (state != null)
                 *  {
                 *      if (state.IsFinal)
                 *      {
                 *          //feedback += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                 *
                 *          //Topo: listaprint:itemprint. separador listaprint
                 *          GrammarState stackTop = stateStack.Top();
                 *
                 *          //Realiza redução daquele estado
                 *          int reduction = dealer.GenerateReduction(stackTop).ReductionNumber;
                 *          for (int i = 0; i < reduction; i++)
                 *          {
                 *              stateStack.Pop();
                 *          }
                 *
                 *          //nextSymbol = listaprint
                 *          Symbol nextSymbol = stackTop.GetStateSymbol();
                 *
                 *          //Topo: instrução:PRINT . listaprint
                 *          stackTop = stateStack.Top();
                 *
                 *          //Deve ter uma transição de listaprint. em instrução
                 *
                 *          //List<TableEntry> debugList = dealer.Table.TableEntriesFor(topState);
                 *          entry = dealer.Table.GetEntry(nextSymbol, stackTop);
                 *
                 *          if (entry != null)
                 *          {
                 *              GrammarState nextState = entry.NextState;
                 *              //Verificar aqui para quando pular e quando não pular o token
                 *              stateStack.Push(nextState);
                 *
                 *              //if (nextState.VerifyFinal())
                 *              //{
                 *              //    nextToken = true;
                 *              //}
                 *
                 *              TableEntry entry2 = dealer.Table.GetEntry(symbol, nextState);
                 *
                 *              if (entry2 == null || entry2.NextState == null)
                 *              {
                 *                  nextToken = true;
                 *              }
                 *          }
                 *          else
                 *          {
                 *              feedback += PARAMETER_INVALID + token.Value + ", linha " + line + "\r\n";
                 *              errorFound = true;
                 *          }
                 *      }
                 *      else if (token != null)
                 *      {
                 *          errorFound = true;
                 *          feedback += INSTRUCTION_INVALID + token.Value + ", linha " + line + "\r\n";
                 *      }
                 *      else
                 *      {
                 *          errorFound = true;
                 *      }
                 *  }
                 *  else
                 *  {
                 *      errorFound = true;
                 *  }
                 * }
                 */
                #endregion
            }
            return(!errorFound);
        }
コード例 #8
0
        /// <summary>
        /// Análise sintática aceitando qualquer gramática. Não pode necessitar de análise léxica para identificar tokens.
        /// </summary>
        /// <param name="feedback"></param>
        /// <returns></returns>
        private bool AscendentAnalizerNonLexic(ref string feedback)
        {
            GrammarDeterministicAutomata afd = new GrammarDeterministicAutomata();

            AscendentDealer dealer = new AscendentDealer(afd);

            //Pilha dos símbolos
            SimpleStack <Symbol> symbolStack = new SimpleStack <Symbol>();

            symbolStack.Push(Terminal.Initial);
            //Pilha do estado
            SimpleStack <GrammarState> stateStack = new SimpleStack <GrammarState>();

            GrammarState ascendentState = GrammarState.ConvertFrom(afd.InitialState);

            stateStack.Push(ascendentState);

            string[] file = Lexic.File;

            bool success    = false;
            bool errorFound = false;

            GrammarState state;
            Symbol       symbol;

            foreach (string line in file)
            {
                int           indexToken = 0;
                List <string> tokens     = new List <string>(line.Split(' '));
                tokens.Add("$");

                string token = "";
                state  = null;
                symbol = null;

                while (!errorFound || !success)
                {
                    token  = tokens[indexToken++];
                    symbol = Symbol.GetSymbol(token);

                    state = stateStack.Top();

                    //Para debug
                    List <TableEntry> list1 = dealer.Table.TableEntriesFor(state);
                    List <TableEntry> list2 = dealer.Table.TableEntriesIn(symbol);

                    TableEntry entry = dealer.Table.GetEntry(symbol, state);

                    if (entry != null)
                    {
                        switch (entry.Type)
                        {
                        case EntryType.SHIFT:
                        {
                            GrammarState nextState = entry.NextState;

                            symbolStack.Push(entry.Horizontal);
                            stateStack.Push(nextState);
                            if (nextState.IsFinal)
                            {
                                goto case EntryType.REDUCTION;
                            }
                            break;
                        }

                        case EntryType.REDUCTION:
                        {
                            GrammarState nextState = entry.NextState;

                            int reduction = dealer.GenerateReduction(nextState).ReductionNumber;
                            for (int i = 0; i < reduction; i++)
                            {
                                symbolStack.Pop();
                                stateStack.Pop();
                            }

                            Symbol trans = nextState.GetStateSymbol();
                            entry = dealer.Table.GetEntry(trans, stateStack.Top());

                            nextState = entry.NextState;

                            symbolStack.Push(entry.Horizontal);
                            stateStack.Push(nextState);
                            break;
                        }

                        default:
                            break;
                        }
                    }
                }
            }

            return(!errorFound);
        }
コード例 #9
0
 public SymbolPair(Symbol horizontal, GrammarState vertical)
 {
     _vertical   = vertical;
     _horizontal = horizontal;
 }
コード例 #10
0
        /// <summary>
        /// Retorna a entrada para o par passado. Returna nulo caso a entrada não exista.
        /// </summary>
        /// <param name="horizontal"></param>
        /// <param name="vertical"></param>
        /// <returns></returns>
        public TableEntry GetEntry(Symbol horizontal, GrammarState vertical)
        {
            SymbolPair pair = new SymbolPair(horizontal, vertical);

            return(GetEntry(pair));
        }
コード例 #11
0
        /// <summary>
        /// Retorna verdadeiro ou false se tiver a entrada com os símbolos passados
        /// </summary>
        /// <param name="horizontal"></param>
        /// <param name="vertical"></param>
        /// <returns></returns>
        public bool HasEntry(Symbol horizontal, GrammarState vertical)
        {
            SymbolPair pair = new SymbolPair(horizontal, vertical);

            return(HasEntry(pair));
        }
コード例 #12
0
 /// <summary>
 /// Adiciona uma entrada na tabela
 /// </summary>
 /// <param name="horizontal"></param>
 /// <param name="vertical"></param>
 /// <param name="nextState"></param>
 /// <param name="type"></param>
 /// <returns>Verdadeiro caso essa entrada seja nova na tabela</returns>
 public bool AddEntry(Symbol horizontal, GrammarState vertical, GrammarState nextState, EntryType type)
 {
     return(AddEntry(new TableEntry(horizontal, vertical, nextState, type)));
 }