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:
  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