Trabalho de Paradigmas de Programação
09 outubro, 2006
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();}
-
}
-
}
-
}
-
}





