public void TestAutomataAFD() { Automata <int, char> testAutomata = GenerateTestAutomataAFN(); List <char> transictionList = new List <char>(new char[] { 'a', 'b', 'e' }); testAutomata = Automata <int, char> .AFNtoAFD(testAutomata, transictionList, 'e'); State <int, char> state0 = testAutomata.InitialState; Assert.AreEqual(0, state0.StateValue, "Valor do estado 0 diferente de 0, valor = " + state0.StateValue); State <int, char> stateAux = state0.Transictions[0].NextState; Assert.AreEqual(2, stateAux.StateValue, "Valor do estado 2 diferente de 2, valor = " + stateAux.StateValue); Assert.AreEqual(2, stateAux.Transictions.Count, "Valor do estado 2 diferente de 2, valor = " + stateAux.StateValue); stateAux = stateAux.Transictions[0].NextState; Assert.AreEqual(3, stateAux.StateValue, "Valor do estado 3 diferente de 3, valor = " + stateAux.StateValue); Assert.AreEqual(1, stateAux.Transictions.Count, "Valor do estado 1 diferente de 1, valor = " + stateAux.StateValue); stateAux = stateAux.Transictions[0].NextState; Assert.AreEqual(4, stateAux.StateValue, "Valor do estado 4 diferente de 4, valor = " + stateAux.StateValue); Assert.IsTrue(stateAux.IsFinal, "Estado 4 não é final!"); GrammarDeterministicAutomata automata = new GrammarDeterministicAutomata(); Assert.IsNotNull(automata, "Automato determinístico retornou nulo"); //TODO mais testes }
public AscendentDealer(GrammarDeterministicAutomata afd) { _afd = afd; //Para a geração dos firsts e follows _nonRecursiveDealer = new NonRecursiveDealer(); _finalStatesList = new List <GrammarState>(); _table = new SyntaxTable(); _productions = new List <String>(); //Numera todas as produções NumerateProductions(); //Método que gera a tabela GenerateTable(); }
/// <summary> /// Converte um afd para uma imagem representando o gráfico /// </summary> public static bool AFDtoPNG(string path) { GrammarDeterministicAutomata afd = new GrammarDeterministicAutomata(); Graph graph = new Graph(""); for (int i = 0; i < afd.StateList.Count; i++) { GrammarState state = GrammarState.ConvertFrom(afd.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)); }
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); }
/// <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); }