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");
		}
	}
}
예제 #2
0
// 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);
	}
}
예제 #3
0
// 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;
		}
	}

}