//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); }
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> /// 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); }
/// <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); }