Trabalho de Paradigmas de Programação
09 outubro, 2006 Sem comentários »
Curso de Sistema de Informação
Disciplina Paradigmas de Programação
Fábio José Rodrigues Pinheiro
Escrever um programa (em qualquer linguagem de programação) que contenha um analisador léxico e um analisador sintático para a seguinte gramática:
atribuição → id = expr
id → A | B | C
expr → id + expr
| id * expr
| (expr)
| id
Tal programa deve reconhecer todas as sentenças possíveis geradas por essa gramática.
Exemplos:
A + B
A + C + B
(((A)))
A = B * (A + C)
Agradecimentos a Manoel Teixeira.
CODE:
-
#include
-
#include
-
#include
-
-
using namespace std;
-
-
int analiza(); // Função principal, dá inicio ao analisador sintático
-
const char * str_replace(string o, char * r, string s); // Função para tirar os espaços da sentença
-
void analizador_lexico(); // Analisador Léxico - Função para obter o próximo token
-
void expressao(); // Analisador Sintático
-
void debugador(); // Funçao de Debug
-
-
int pos,p_aberto,token,xerro,debug_on=0; // posição expressão,parênteses abertos,próximo token,mensagem de erro, argumento
-
string sentenca; // sentença capturada pelo teclado
-
enum token {id,op,p_esq,p_dir,igual,fim}; // tokens permitidos
-
-
int main(int argc, char *argv[]) // função principal
-
{
-
cout <<" Escrever um programa (em qualquer linguagem de programa‡Æo) que contenha um \n";
-
cout <<" analisador l‚xico e um analisador sint tico para a seguinte gram tica:\n";
-
cout <<"\n -> = \n"; cout <<" -> A | B | C\n"; cout <<" -> + \n";
-
cout <<" | * \n"; cout <<" | ()\n"; cout <<" | \n";
-
cout <<"\n Ex:\n A + B \n A + C + B\n (((A)))\n A = B * (A + C) ";
-
if (argv[1]) {if (strcmp(argv[1],"debug") == 0) debug_on=1;} // verifica o argumento de debug
-
while (1) { // laço principal
-
pos = 0; p_aberto = 0; xerro = 0; // zera os valores para multiplas consultas
-
if(debug_on) cout <<"\n\n **** MODO DEBUG LIGADO **** \n\n";
-
cout <<"\n\n Digite a senten‡a ou 0 (zero) para sair: \n";
-
getline(cin, sentenca); strupr((char *) sentenca.c_str()); sentenca = str_replace(" ","",sentenca);
-
if (sentenca == "0") break;
-
if (analiza()) { cout <<"\n Senten‡a v lida!\n"; }
-
else { cout <<"\n Senten‡a inv lida!\n"; }
-
cout <<sentenca <<"\n";
-
}
-
return EXIT_SUCCESS;
-
}
-
-
const char * str_replace(string o, char * r, string s){
-
int i;
-
string t;
-
while (s.find(o,0) <string::npos){
-
for (i=0;i
-
t = s[i];
-
if (strcmp (t.c_str(),o.c_str())==0) s.replace(i,1,r);
-
}
-
} return s.c_str();
-
}
-
-
int analiza() {
-
analizador_lexico();
-
if (token == id) { // Caracteriza: atribuição e expr
-
analizador_lexico();
-
if (token == igual) { // Caracteriza: atribuição
-
analizador_lexico();
-
expressao();
-
} else {
-
if (token == op) { // Caracteriza: expressão
-
analizador_lexico();
-
if( token == fim) { cout <<"ERRO 1: Fim inesperado! \n"; return 0;}
-
else expressao();
-
} else { cout <<"ERRO 2: Operador +, * ou = esperado! \n"; return 0;}
-
}
-
} else expressao();
-
switch (xerro) {
-
case 0: return 1; break;
-
case 1: return 0; break;
-
}
-
}
-
-
void debugador() {
-
if(debug_on) cout <<"DEBUG: sentenca[pos]: " <<sentenca[pos] <<" pos: " <<pos <<" token: " <<token <<" p_aberto: " <<p_aberto <<"\n";
-
}
-
-
void analizador_lexico() {
-
debugador();
-
if (pos <sentenca.length()) {
-
switch (sentenca[pos]) {
-
case 'A':
-
case 'B':
-
case 'C':
-
token = id;
-
break;
-
case '+':
-
case '*':
-
token = op;
-
break;
-
case '=':
-
token = igual;
-
break;
-
case ')':
-
token = p_dir;
-
break;
-
case '(':
-
token = p_esq;
-
break;
-
default:
-
token = fim;
-
cout <<"ERRO 3: Caracter nÆo reconhecido " <<sentenca[pos] <<pos << " \n";
-
xerro=1;
-
break;
-
}
-
} else token = fim;
-
pos++;
-
}
-
-
void expressao() {
-
debugador();
-
if (token == id) {
-
analizador_lexico();
-
if (token == op) {
-
analizador_lexico();
-
expressao();
-
} else {
-
if (token == p_dir && p_aberto> 0) { p_aberto--; analizador_lexico(); expressao();}
-
else {
-
if (token == fim) {
-
if (p_aberto> 0) { cout <<"ERRO 4: Fechamento de parˆnteses esperado! \n"; xerro=1; return; }
-
else return;
-
} else { cout <<"ERRO 5: Operador +,* esperado!\n"; xerro=1; return; }
-
}
-
}
-
} else {
-
if (token == p_esq) {p_aberto++; analizador_lexico(); expressao();}
-
else {
-
if (token == p_dir && p_aberto> 0) {
-
p_aberto--; analizador_lexico(); expressao();
-
if (token == fim && p_aberto == 0 ) return;
-
else {cout <<"ERRO 6: Caracter nÆo esperado! \n"; xerro=1; return;}
-
} else {
-
if (token == fim) {
-
if (p_aberto ==0) return;
-
else {cout <<"ERRO 7: Parˆnteses desbalanceados! \n"; xerro=1; return;}
-
} else {analizador_lexico();expressao();}
-
}
-
}
-
}
-
}





