Advertisement
Guest User

Untitled

a guest
Oct 9th, 2013
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.72 KB | None | 0 0
  1. %{
  2. #include <cmath>
  3. #include <FlexLexer.h>
  4. #include <Scanner.hpp>
  5. #include "parser.hpp"
  6.  
  7. static
  8. int yylex(yy::parser::semantic_type* yylval, yy::parser::location_type* yylloc, Scanner& scanner)
  9. {
  10.     return scanner.yylex(yylval, yylloc);
  11. }
  12.  
  13. %}
  14.  
  15. %error-verbose
  16. %skeleton "lalr1.cc"
  17. %token-table
  18. %locations
  19. %parse-param {Scanner& scanner}
  20. %parse-param {Variables& vars}
  21. %parse-param {double& result}
  22. %parse-param {std::string& error_message}
  23. %lex-param {Scanner& scanner}
  24.  
  25. %code requires {
  26. #include <map>
  27. #include <string>
  28. typedef std::map<std::string, double> Variables;
  29. class Scanner;
  30. }
  31.  
  32. %define api.value.type variant
  33. %define parse.assert
  34.  
  35. %token POW "pow" ABS "abs" EXP "exp" SQRT "sqrt" COS "cos" SIN "sin" TAN "tan" ACOS "acos" ASIN "asin" ATAN "atan" ATAN2 "atan2" CEIL "ceil" FLOOR "floor" MOD "mod" LOG "log" LOG10 "log10"
  36. %token END 0 "end of file"
  37. %token<std::string> IDENTIFIER "identifier"
  38. %token<double> NUMBER "number"
  39. %type<double> expr
  40.  
  41. %printer { yyoutput << $$; } <*>
  42.  
  43. %left '+' '-'
  44. %left '*' '/' '%'
  45. %left SIGN
  46. %left '^'
  47.  
  48. %%
  49.  
  50. root: expr { result = $1; }
  51.  
  52. expr:
  53.     NUMBER          { $$ = $1; } |
  54.     IDENTIFIER
  55. {
  56.     const Variables::const_iterator it = vars.find($1);
  57.     if (it == vars.end()) {
  58.         std::ostringstream err;
  59.         err << "undefined identifier '" << $1 << "'";
  60.         throw syntax_error(@1, err.str());
  61.     }
  62.     const double val = it == vars.end() ? 0.0 : it->second;
  63.     $$ = val;
  64. } |
  65.     '(' expr ')'                { $$ = $2; } |
  66.     expr '+' expr               { $$ = $1 + $3; } |
  67.     expr '-' expr               { $$ = $1 - $3; } |
  68.     expr '*' expr               { $$ = $1 * $3; } |
  69.     expr '/' expr               { $$ = $1 / $3; } |
  70.     expr '%' expr               { $$ = std::fmod($1, $3); } |
  71.     expr '^' expr               { $$ = std::pow($1, $3); } |
  72.     '+' expr %prec SIGN         { $$ = $2; } |
  73.     '-' expr %prec SIGN         { $$ = -$2; } |
  74.     POW '(' expr ',' expr ')'   { $$ = std::pow($3, $5); } |
  75.     ABS '(' expr ')'            { $$ = std::abs($3); } |
  76.     EXP '(' expr ')'            { $$ = std::exp($3); } |
  77.     SQRT '(' expr ')'           { $$ = std::sqrt($3); } |
  78.     COS '(' expr ')'            { $$ = std::cos($3); } |
  79.     SIN '(' expr ')'            { $$ = std::sin($3); } |
  80.     TAN '(' expr ')'            { $$ = std::tan($3); } |
  81.     ACOS '(' expr ')'           { $$ = std::acos($3); } |
  82.     ASIN '(' expr ')'           { $$ = std::asin($3); } |
  83.     ATAN '(' expr ')'           { $$ = std::atan($3); } |
  84.     ATAN2 '(' expr ',' expr ')' { $$ = std::atan2($3, $5); } |
  85.     CEIL '(' expr ')'           { $$ = std::ceil($3); } |
  86.     FLOOR '(' expr ')'          { $$ = std::floor($3); } |
  87.     MOD '(' expr ',' expr ')'   { $$ = std::fmod($3, $5); } |
  88.     LOG '(' expr ')'            { $$ = std::log($3); } |
  89.     LOG10 '(' expr ')'          { $$ = std::log10($3); }
  90.  
  91. %%
  92.  
  93. void yy::parser::error(const yy::location& l, const std::string& m)
  94. {
  95.     std::ostringstream error_stream;
  96.     error_stream << l << ": " << m;
  97.     error_message = error_stream.str();
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement