void eD() { char simbolo = palavra[posicaoPalavra]; if (!ehFinalPalavra(simbolo)) { if (ehOperador(simbolo)) { posicaoPalavra++; eA(); } else { if (!pilhaEstaVazia(pilha_estados)) { ptr_estado estado_desempilhado = desempilha(pilha_estados, &posicao_pilha); estado_desempilhado(); } else { if (verificaAceitacao(pilha_estados, simbolo)) { printf("\nACEITO!\n"); } else { printf("\nNÃO ACEITO!\n"); } } } } else { if (verificaAceitacao(pilha_estados, simbolo)) { printf("\nACEITO!\n"); } else { printf("\nNÃO ACEITO!\n"); } } }
// Função recursiva auxiliar a leEntrada void recLeEntrada (no **N) { char entrada[MAX]; scanf ("%s", entrada); *N = novoNo (entrada); // é operador, então lê seus operandos if (ehOperador (entrada)) { recLeEntrada (&(*N)->esquerdo); recLeEntrada (&(*N)->direito); } }
// Função recursiva auxiliar a imprimeInfixa void recImprimeInfixa (no *N) { if (N != NULL) { // se é operador, escreve os parênteses e espaços certos if (ehOperador (N->valor)) { printf ("("); recImprimeInfixa (N->esquerdo); printf (" %s ", N->valor); recImprimeInfixa (N->direito); printf (")"); } else { printf ("%s", N->valor); } } }
bool Sintatico::OperaSintatico() { bool retorno = true; int tokenOri = 0; if ((int)this->pilhaSintatico.size() <= 0) retorno = false; else { //le o proximo token da fita int token = this->listaTokens.back()->getEstado(); if (Sintatico::debug) cout << "FITA: " << Token::ImprimeToken(token, "ID") << " POS: " << this->listaTokens.back()->getPosicao() << " Linha: " << this->listaTokens.back()->getLinha()+1 << endl; this->listaTokens.pop_back(); //cout << "Leu: " << Token::ImprimeToken(token, "ID") << endl; if (token == ERRO) { retorno = false; } else if (token == INICIO && (int)this->pilhaSintatico.size() == 1) retorno = true; else { //consome o topo da pilha int topoPilha = this->pilhaSintatico.back(); this->pilhaSintatico.pop_back(); if (Sintatico::debug) cout << "PILHA: " << Token::ImprimeToken(topoPilha, "ID") << endl; if (Sintatico::debug) cout << "Tamanho Pilha: " << this->pilhaSintatico.size() << endl << endl; //trata o token antes de testar tokenOri = token; token = ehBooleano(token); token = ehOperador(token); //cout << "Leu Depois: " << Token::ImprimeToken(token, "ID") << endl; //testa o token //chamada recursiva no final do switch case //retorno = (retorno ? this->OperaSintatico(token) : retorno); switch(token) { case IDENTIFICADOR: if (topoPilha == INICIO || topoPilha == LCHAVES) { this->pilhaSintatico.push_back(topoPilha); this->pilhaSintatico.push_back(token); } else if (topoPilha == LPARENTS || topoPilha == OUT || topoPilha == ATRIBUICAO) { this->pilhaSintatico.push_back(BOOLVAR); } else if (topoPilha == IN || topoPilha == VIRGULA) { this->pilhaSintatico.push_back(ENTRADA); } else if (topoPilha == OPERADOR) { //this->pilhaSintatico.push_back(topoPilha); this->pilhaSintatico.push_back(BOOLVAR); } else if (topoPilha == CONDICIONAL) { this->pilhaSintatico.push_back(token); } else { retorno = false; } break; case BOOLEANO: if (topoPilha == ATRIBUICAO || topoPilha == OPERADOR || topoPilha == LPARENTS || topoPilha == OUT) { this->pilhaSintatico.push_back(BOOLVAR); } else retorno = false; break; case OUT: case IN: //IN e OUT possuem a mesma caracteristica quando sao lidos da fita, apenas se colocam na pilha if (topoPilha == INICIO || topoPilha == LCHAVES) { this->pilhaSintatico.push_back(topoPilha); this->pilhaSintatico.push_back(token); retorno = true; } else if (topoPilha == CONDICIONAL ) { this->pilhaSintatico.push_back(token); } else { retorno = false; } break; case IF: if (topoPilha == INICIO || topoPilha == LCHAVES) { this->pilhaSintatico.push_back(topoPilha); this->pilhaSintatico.push_back(token); } else if (topoPilha == CONDICIONAL) { this->pilhaSintatico.push_back(token); } else { retorno = false; } break; case ELSE: if (topoPilha == CONDICIONAL) { this->pilhaSintatico.push_back(CONDICIONAL); } else { retorno = false; } break; case ATRIBUICAO: if (topoPilha == IDENTIFICADOR) this->pilhaSintatico.push_back(token); else retorno = false; break; case OPERADOR: if (topoPilha == BOOLVAR || topoPilha == BOOLCOND) this->pilhaSintatico.push_back(OPERADOR); else retorno = false; break; case LPARENTS: if (topoPilha == IF) { this->pilhaSintatico.push_back(CONDICIONAL); this->pilhaSintatico.push_back(token); } else if (topoPilha == OUT) { this->pilhaSintatico.push_back(token); } else if (topoPilha == OPERADOR || topoPilha == ATRIBUICAO) { this->pilhaSintatico.push_back(token); } else if (topoPilha == LPARENTS) { this->pilhaSintatico.push_back(BOOLCOND); this->pilhaSintatico.push_back(token); } else retorno = false; break; case RPARENTS: if (topoPilha == BOOLVAR) { this->pilhaSintatico.push_back(BOOLCOND); retorno = true; } else if (topoPilha == BOOLCOND || topoPilha == ENTRADA || topoPilha == PARENTSIN) { //consome BOOLCOND retorno = true; } else retorno = false; break; case NOT: if (topoPilha == BOOLVAR || topoPilha == BOOLCOND) { this->pilhaSintatico.push_back(topoPilha); retorno = true; } else retorno = false; break; case LCHAVES: //soh pode fazer se todos itens dentro do if (topoPilha == CONDICIONAL) { this->pilhaSintatico.push_back(CONDICIONAL); this->pilhaSintatico.push_back(token); } else if (topoPilha == BOOLCOND) { this->pilhaSintatico.push_back(token); } else { retorno = false; } break; case RCHAVES: //teste se é uma RCHAVES e apenas consome o topo da pilha, finalizando um comando if (topoPilha == LCHAVES) { retorno = true; } else retorno = false; break; case VIRGULA: if (topoPilha == ENTRADA) { this->pilhaSintatico.push_back(token); } else retorno = false; break; case PONTOVIRGULA: if (topoPilha == BOOLVAR || topoPilha == ENTRADA || topoPilha == BOOLCOND || topoPilha == PARENTSIN) retorno = true; else retorno = false; break; default: retorno = false; } //cout << "topoPilha: " << Token::ImprimeToken(topoPilha, "ID") << endl; //cout << "back: " << Token::ImprimeToken(this->pilhaSintatico.back(), "ID") << endl; retorno = (retorno ? this->OperaSintatico() : retorno); if (retorno == false) { } } } return retorno; }
/** * Construtor principal, atraves de uma palavra cria uma lista de tokens **/ Lexico::Lexico(string palavra) { string s; s.clear(); //estado inicial int estado = VAZIO; bool tokenizer = false; string erro; for (int i=0; i < palavra.length(); ++i) { switch(estado) { case VAZIO: if (ehLetra(palavra[i])) { //estado inicial eh uma letra, passa pro estado letra s += palavra[i]; estado = LETRA; tokenizer = false; } else if (ehBooleano(palavra[i])) { //estado inicial eh um booleano, true ou false if (palavra[i] == '0') estado = FALSE; if (palavra[i] == '1') estado = TRUE; tokenizer = true; } else if (ehOperador(palavra[i])) { //estado inicial eh um operador tokenizer = true; if (palavra[i] == '^') // estado AND estado = AND; if (palavra[i] == 'V') // estado OR estado = OR; if (palavra[i] == '\'') // estado NOT estado = NOT; if (palavra[i] == '-') { // estado SE estado = OPERADORSE; tokenizer = false; } if (palavra[i] == '<') { // estado intermediario SESOMENTESE estado = OPERADOR; tokenizer = false; } if (palavra[i] == ':') { // estado ATRIBUICAO estado = ATRIBUICAO; tokenizer = false; } } else if (palavra[i] == '\"'){ //estado inicial eh aspas, passa para o estado booleano estado = BOOLEANO; tokenizer = false; } else if (ehSeparador(palavra[i])) { //estado = SEPARADOR; //break; } else if (ehBloco(palavra[i])) { //estado inicial eh um bloco, passa para o estado de acordo com o caracter if (palavra[i] == '}') estado = RCHAVES; else if (palavra[i] == '{') estado = LCHAVES; else if (palavra[i] == '(') estado = LPARENTS; else if (palavra[i] == ')') estado = RPARENTS; tokenizer = true; } else if (palavra[i] == ';') { //estado eh um ponto e virgula estado = PONTOVIRGULA; tokenizer = true; } else if (palavra[i] == ',') { //estado eh uma virgula estado = VIRGULA; tokenizer = true; } else { //estado inicial nao identificado estado = ERRO; erro = "ID "; erro += palavra[i]; tokenizer = true; } break; case LETRA: if (ehLetra(palavra[i])) { //continua como letra, concatena e segue o baile s += palavra[i]; } else if (ehNumero(palavra[i])) { s += palavra[i]; estado = IDENTIFICADOR; } else { //qualquer coisa diferente de letra muda o estado tokenizer = true; } break; case BOOLEANO: if (ehLetra(palavra[i])) { //acrescenta na string s += palavra[i]; break; } else if (palavra[i] == '\"') { //final das aspas verifica se a palavra eh reconhecida ou nao na linguagem if (s == "verdadeiro" || s == "true" || s == "v" ) { estado = TRUE; //palavra booleana reconhecida } else if (s == "falso" || s == "false" || s == "f" ) { estado = FALSE; //palavra booleana reconhecida } else { estado = ERRO; erro = "BOOLEANO_ASPAS"; } } else { estado = ERRO; erro = "BOOLEANO "; erro += palavra[i]; } tokenizer = true; break; case OPERADOR: // < if (palavra[i] == '-') estado = OPERADORSSS; else { estado = ERRO; erro = "OPERADOR"; tokenizer = true; } break; case OPERADORSE: if(!palavra[i] == '>') { estado = ERRO; erro = "OPERADORSE"; } tokenizer = true; break; case OPERADORSSS: if(!palavra[i] == '>') { estado = ERRO; erro = "OPERADORSSS"; } tokenizer = true; break; case ATRIBUICAO: if (!palavra[i] == '=') { estado == ERRO; erro = "ATRIBUICAO"; } tokenizer = true; break; default: estado = OUTRO; tokenizer = true; break; } if (tokenizer) { //cria um token novo a ser inserido na lista Token * novoToken = new Token(); if (estado == LETRA) { estado = (ehReservado(s) ? PalavraReservada(s) : IDENTIFICADOR ); if (estado == IDENTIFICADOR) novoToken->setId(s); i--; } else if (estado == ERRO) { novoToken->setId(erro); } novoToken->setEstado(estado); novoToken->setPosicao(i); //insere na lista listaTokens.push_back(novoToken); //retorna a iteracao 1 passo, para o estado inicial vazio //reseta o estado s.clear(); estado = VAZIO; tokenizer = false; } } }