PageRenderTime 50ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/parser.y

https://github.com/Laski/tl
Happy | 181 lines | 151 code | 30 blank | 0 comment | 0 complexity | 7bb494ad9a329e85dde6895631a48cb5 MD5 | raw file
  1. %{
  2. #include "node.h"
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <string>
  6. NPrograma *programBlock; /* the top level root Nodo of our final AST */
  7. extern int yylex();
  8. extern int yylineno;
  9. extern char* yytext;
  10. extern int yychar;
  11. void yyerror(const char *s) {
  12. std::cout << "ERROR de parseo: Encontré '" << yytext << "' pero esperaba otro símbolo." << std::endl;
  13. std::exit(1);
  14. }
  15. %}
  16. /* Represents the many different ways we can access our data */
  17. %union {
  18. Nodo *nodo;
  19. NPrograma *programa;
  20. NPloteo *plot;
  21. NBloque *block;
  22. NFuncion *func;
  23. NExpresion *expr;
  24. NNumero *num;
  25. NCondicion *cond;
  26. NSentencia *sent;
  27. NIdentificador *ident;
  28. NLlamadaFuncion *llamfunc;
  29. std::vector<NIdentificador*> *varvec;
  30. std::map<std::string,NFuncion*> *funcdicc;
  31. std::vector<NExpresion*> *exprvec;
  32. std::vector<NSentencia*> *sentvec;
  33. std::string *string;
  34. int token;
  35. }
  36. /* Define our terminal symbols (tokens). This should
  37. match our tokens.l lex file. We also define the Nodo type
  38. they represent.
  39. */
  40. %token <string> TIDENTIFICADOR TDOUBLE
  41. %token <token> TIGUALIGUAL TDISTINTO TMENOR TMENORIGUAL TMAYOR TMAYORIGUAL
  42. %token <token> TPARENL TPARENR TLLAVEL TLLAVER TCOMA TPUNTOS
  43. %token <token> TMAS TMENOS TPOT TMUL TDIV
  44. %token <token> TAND TOR TNOT
  45. %token <token> TRETURN TIF TTHEN TELSE TWHILE TFOR TFUNC TPLOT
  46. %token <token> TPI TIGUAL
  47. /* Define the type of node our nonterminal symbols represent.
  48. The types refer to the %union declaration above. Ex: when
  49. we call an ident (defined by union type ident) we are really
  50. calling an (NIdentificador*). It makes the compiler happy.
  51. */
  52. %type <ident> nombre
  53. %type <expr> expresion
  54. %type <num> numero
  55. %type <varvec> argumentos
  56. %type <exprvec> expresiones
  57. %type <sentvec> sentencias
  58. %type <funcdicc> funciones
  59. %type <programa> programa
  60. %type <func> funcion
  61. %type <llamfunc> llamada_funcion
  62. %type <block> bloque
  63. %type <sent> sentencia asignacion ifthenelse return while
  64. %type <cond> condicion
  65. %type <plot> ploteo
  66. /* Operator precedence for mathematical operators */
  67. %left TMAS TMENOS
  68. %left TMUL TDIV
  69. %left NEG
  70. %left TPOT
  71. %start programa
  72. %%
  73. programa : funciones ploteo {DEBUG_OUT("programa -> funciones ploteo"); $$ = new NPrograma(*$1, *$2); programBlock = $$; }
  74. ;
  75. // Acá usamos el diccionario. Por alguna razon no compila si usamos el operator[], por lo que tuve que usar insert y quedo más feo.
  76. funciones : funciones funcion {DEBUG_OUT("funciones -> funciones funcion");
  77. if($1->find($2->id.nombre) != $1->end()){
  78. ERROR_OUT("de parseo: la funcion '" << $2->id.nombre << "' fue declarada más de una vez.");
  79. }else
  80. $1->insert(std::pair<std::string, NFuncion*>($2->id.nombre, $2)); }
  81. | funcion { DEBUG_OUT("funciones -> funcion" ); $$ = new DiccFunciones();
  82. $$->insert(std::pair<std::string, NFuncion*>($1->id.nombre, $1) ); }
  83. ;
  84. funcion : TFUNC nombre TPARENL argumentos TPARENR bloque { DEBUG_OUT("funcion -> nombre argumentos bloque" ); $$ = new NFuncion(*$2, *$4, *$6); }
  85. ;
  86. nombre : TIDENTIFICADOR { DEBUG_OUT("nombre -> '" << *$1 << "'"); $$ = new NIdentificador(*$1); delete $1; }
  87. ;
  88. argumentos : /* lambda */ { DEBUG_OUT("argumentos -> lambda"); $$ = new ListaVariables(); }
  89. | nombre { DEBUG_OUT("argumentos -> nombre"); $$ = new ListaVariables(); $$->push_back($1); }
  90. | argumentos TCOMA nombre { DEBUG_OUT("argumentos -> argumentos nombre"); $1->push_back($3); }
  91. ;
  92. bloque : sentencia { DEBUG_OUT("bloque -> sentencia"); ListaSentencias *aux = new ListaSentencias; aux->push_back($1); $$ = new NBloque(*aux); }
  93. | TLLAVEL sentencias TLLAVER { DEBUG_OUT("bloque -> sentencias"); $$ = new NBloque(*$2); }
  94. | TLLAVEL TLLAVER { DEBUG_OUT("bloque -> vacio"); ListaSentencias *aux = new ListaSentencias; $$ = new NBloque(*aux); }
  95. ;
  96. sentencias : sentencia { DEBUG_OUT("sentencias -> sentencia"); $$ = new ListaSentencias(); $$->push_back($1); }
  97. | sentencias sentencia { DEBUG_OUT("sentencias -> sentencias sentencia"); $1->push_back($2); }
  98. ;
  99. sentencia : asignacion { DEBUG_OUT("sentencia -> asignacion"); $$ = $1; }
  100. | ifthenelse { DEBUG_OUT("sentencia -> ifthenelse"); $$ = $1; }
  101. | while { DEBUG_OUT("sentencia -> while"); $$ = $1; }
  102. | return { DEBUG_OUT("sentencia -> return"); $$ = $1; }
  103. ;
  104. asignacion : nombre TIGUAL expresion { DEBUG_OUT("asignacion -> nombre expresion"); $$ = new NAsignacion(*$1, *$3); }
  105. ;
  106. ifthenelse : TIF condicion TTHEN bloque { DEBUG_OUT("ifthenelse -> IFTHEN condicion bloque"); $$ = new NIfThen(*$2, *$4); }
  107. | TIF condicion TTHEN bloque TELSE bloque { DEBUG_OUT("ifthenelse -> IFTHENELSE condicion bloque bloque"); $$ = new NIfThenElse(*$2, *$4, *$6); }
  108. ;
  109. while : TWHILE condicion bloque{ DEBUG_OUT("while -> condicion bloque"); $$ = new NWhile(*$2, *$3); }
  110. ;
  111. return : TRETURN expresion { DEBUG_OUT("return -> expresion"); $$ = new NReturn(*$2); }
  112. ;
  113. expresiones : /* lambda */ { DEBUG_OUT("expresiones -> lambda"); $$ = new ListaExpresiones(); }
  114. | expresiones TCOMA expresion { DEBUG_OUT("expresiones -> expresiones expresion"); $1->push_back($3); }
  115. | expresion { DEBUG_OUT("expresiones -> expresion"); $$ = new ListaExpresiones(); $$->push_back($1); }
  116. ;
  117. /*http://www-h.eng.cam.ac.uk/help/tpl/languages/flexbison/*/
  118. expresion:
  119. numero { DEBUG_OUT("expresion -> numero"); $$ = $1; }
  120. | nombre { DEBUG_OUT("expresion -> nombre"); $$ = new NIdentificador(*$1); delete $1; }
  121. | llamada_funcion { DEBUG_OUT("expresion -> llamada_funcion"); $$ = $1;}
  122. | expresion TMAS expresion { DEBUG_OUT("expresion -> expresion + expresion"); $$ = new NOperacionAritmetica(MAS, *$1, *$3); }
  123. | expresion TMENOS expresion { DEBUG_OUT("expresion -> expresion - expresion"); $$ = new NOperacionAritmetica(MENOS, *$1, *$3); }
  124. | expresion TMUL expresion { DEBUG_OUT("expresion -> expresion * expresion"); $$ = new NOperacionAritmetica(MUL, *$1, *$3); }
  125. | expresion TDIV expresion { DEBUG_OUT("expresion -> expresion / expresion"); $$ = new NOperacionAritmetica(DIV, *$1, *$3); }
  126. | expresion TPOT expresion { DEBUG_OUT("expresion -> expresion ** expresion"); $$ = new NOperacionAritmetica(POT, *$1, *$3); }
  127. | TMENOS expresion %prec NEG { DEBUG_OUT("expresion -> -expresion"); $$ = new NOperacionAritmetica(MENOS, *(new NDouble(0)), *$2); } // -x es 0-x
  128. | TPARENL expresion TPARENR { DEBUG_OUT("expresion -> (expresion)"); $$ = $2; }
  129. ;
  130. /************************************************************/
  131. numero : TDOUBLE { $$ = new NDouble(atof($1->c_str())); $$->value=atof($1->c_str()); DEBUG_OUT("numero -> TDOUBLE: " << $$->value); delete $1; }
  132. | TPI { DEBUG_OUT("numero -> TPI"); $$ = new NDouble(3.141592); }
  133. ;
  134. llamada_funcion : nombre TPARENL expresiones TPARENR { DEBUG_OUT("llamada_funcion -> nombre expresiones"); $$ = new NLlamadaFuncion(*$1, *$3); delete $3; }
  135. condicion :
  136. TNOT condicion { DEBUG_OUT("condicion -> NOT condicion"); $$ = new NOperacionBooleana(*$2); }
  137. | condicion TAND condicion { DEBUG_OUT("condicion -> condicion AND condicion"); $$ = new NOperacionBooleana(AND, *$1, *$3); }
  138. | condicion TOR condicion { DEBUG_OUT("condicion -> condicion OR condicion"); $$ = new NOperacionBooleana(OR, *$1, *$3); }
  139. | expresion TIGUALIGUAL expresion { DEBUG_OUT("condicion -> expresion == expresion"); $$ = new NComparacion(IGUAL, *$1, *$3); }
  140. | expresion TDISTINTO expresion { DEBUG_OUT("condicion -> expresion != expresion"); $$ = new NComparacion(DISTINTO, *$1, *$3); }
  141. | expresion TMENOR expresion { DEBUG_OUT("condicion -> expresion < expresion"); $$ = new NComparacion(MENOR, *$1, *$3); }
  142. | expresion TMENORIGUAL expresion { DEBUG_OUT("condicion -> expresion <= expresion"); $$ = new NComparacion(MENORIGUAL, *$1, *$3); }
  143. | expresion TMAYOR expresion { DEBUG_OUT("condicion -> expresion > expresion"); $$ = new NComparacion(MAYOR, *$1, *$3); }
  144. | expresion TMAYORIGUAL expresion { DEBUG_OUT("condicion -> expresion >= expresion"); $$ = new NComparacion(MAYORIGUAL, *$1, *$3); }
  145. | expresion { ERROR_OUT("de parseo: Se encontró '" << yytext << "' pero se esperaba un símbolo de comparación."); }
  146. ;
  147. ploteo :
  148. TPLOT TPARENL llamada_funcion TCOMA llamada_funcion TPARENR TFOR nombre TIGUAL expresion TPUNTOS expresion TPUNTOS expresion
  149. { DEBUG_OUT("ploteo -> llamada_funcion llamada_funcion numero numero numero "); $$ = new NPloteo(*$3, *$5, *$8, *$10, *$12, *$14); }
  150. | TPLOT TIDENTIFICADOR { ERROR_OUT("de parseo: Encontré '" << yytext << "', pero esperaba '('."); }
  151. %%