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:
  1. #include
  2. #include
  3. #include
  4.  
  5. using namespace std;
  6.  
  7. int analiza(); // Função principal, dá inicio ao analisador sintático
  8. const char * str_replace(string o, char * r, string s); // Função para tirar os espaços da sentença
  9. void analizador_lexico(); // Analisador Léxico - Função para obter o próximo token
  10. void expressao(); // Analisador Sintático
  11. void debugador(); // Funçao de Debug
  12.  
  13. int pos,p_aberto,token,xerro,debug_on=0; // posição expressão,parênteses abertos,próximo token,mensagem de erro, argumento
  14. string sentenca; // sentença capturada pelo teclado
  15. enum token {id,op,p_esq,p_dir,igual,fim}; // tokens permitidos
  16.  
  17. int main(int argc, char *argv[]) // função principal
  18. {
  19. cout <<" Escrever um programa (em qualquer linguagem de programa‡Æo) que contenha um \n";
  20. cout <<" analisador l‚xico e um analisador sint tico para a seguinte gram tica:\n";
  21. cout <<"\n  ->  = \n"; cout <<"  -> A | B | C\n"; cout <<"  ->  + \n";
  22. cout <<"        |  *  \n"; cout <<"          | ()\n"; cout <<"        |  \n";
  23. cout <<"\n Ex:\n  A + B \n  A + C + B\n  (((A)))\n  A = B * (A + C) ";
  24. if (argv[1]) {if (strcmp(argv[1],"debug") == 0) debug_on=1;} // verifica o argumento de debug
  25. while (1) {    // laço principal
  26. pos = 0; p_aberto = 0; xerro = 0; // zera os valores para multiplas consultas
  27. if(debug_on) cout <<"\n\n **** MODO DEBUG LIGADO **** \n\n";
  28. cout <<"\n\n Digite a senten‡a ou 0 (zero) para sair: \n";
  29. getline(cin, sentenca); strupr((char *) sentenca.c_str()); sentenca = str_replace(" ","",sentenca);
  30. if (sentenca == "0") break;
  31. if (analiza()) { cout <<"\n Senten‡a v lida!\n"; }
  32. else { cout <<"\n Senten‡a inv lida!\n"; }
  33. cout <<sentenca <<"\n";
  34. }
  35. return EXIT_SUCCESS;
  36. }
  37.  
  38. const char * str_replace(string o, char * r, string s){
  39. int i;
  40. string t;
  41. while (s.find(o,0) <string::npos){
  42. for (i=0;i
  43. t = s[i];
  44. if (strcmp (t.c_str(),o.c_str())==0) s.replace(i,1,r);
  45. }
  46. } return s.c_str();
  47. }
  48.  
  49. int analiza() {
  50. analizador_lexico();
  51. if (token == id) { // Caracteriza: atribuição e expr
  52. analizador_lexico();
  53. if (token == igual) { // Caracteriza: atribuição
  54. analizador_lexico();
  55. expressao();
  56. } else {
  57. if (token == op) { // Caracteriza: expressão
  58. analizador_lexico();
  59. if( token == fim) { cout <<"ERRO 1: Fim inesperado! \n"; return 0;}
  60. else expressao();
  61. } else { cout <<"ERRO 2: Operador +, * ou = esperado! \n"; return 0;}
  62. }
  63. } else expressao();
  64. switch (xerro) {
  65. case 0: return 1;  break;
  66. case 1: return 0; break;
  67. }
  68. }
  69.  
  70. void debugador() {
  71. if(debug_on) cout <<"DEBUG: sentenca[pos]: " <<sentenca[pos] <<" pos: " <<pos <<" token: " <<token <<" p_aberto: " <<p_aberto <<"\n";
  72. }
  73.  
  74. void analizador_lexico() {
  75. debugador();
  76. if (pos <sentenca.length()) {
  77. switch (sentenca[pos]) {
  78. case 'A':
  79. case 'B':
  80. case 'C':
  81. token = id;
  82. break;
  83. case '+':
  84. case '*':
  85. token = op;
  86. break;
  87. case '=':
  88. token = igual;
  89. break;
  90. case ')':
  91. token = p_dir;
  92. break;
  93. case '(':
  94. token = p_esq;
  95. break;
  96. default:
  97. token = fim;
  98. cout <<"ERRO 3: Caracter nÆo reconhecido " <<sentenca[pos] <<pos << \n";
  99. xerro=1;
  100. break;
  101. }
  102. } else token = fim;
  103. pos++;
  104. }
  105.  
  106. void expressao() {
  107. debugador();
  108. if (token == id) {
  109. analizador_lexico();
  110. if (token == op) {
  111. analizador_lexico();
  112. expressao();
  113. } else {
  114. if (token == p_dir && p_aberto> 0) { p_aberto--; analizador_lexico(); expressao();}
  115. else {
  116. if (token == fim) {
  117. if (p_aberto> 0) { cout <<"ERRO 4: Fechamento de parˆnteses esperado! \n"; xerro=1; return; }
  118. else return;
  119. } else { cout <<"ERRO 5: Operador +,* esperado!\n"; xerro=1; return; }
  120. }
  121. }
  122. } else {
  123. if (token == p_esq) {p_aberto++; analizador_lexico(); expressao();}
  124. else {
  125. if (token == p_dir && p_aberto> 0) {
  126. p_aberto--; analizador_lexico(); expressao();
  127. if (token == fim && p_aberto == 0 ) return;
  128. else {cout <<"ERRO 6: Caracter nÆo esperado! \n"; xerro=1; return;}
  129. } else {
  130. if (token == fim) {
  131. if (p_aberto ==0) return;
  132. else {cout <<"ERRO 7: Parˆnteses desbalanceados! \n"; xerro=1; return;}
  133. } else {analizador_lexico();expressao();}
  134. }
  135. }
  136. }
  137. }

Post a Comment