Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- #include <cmath>
- #include <FlexLexer.h>
- #include <Scanner.hpp>
- #include "parser.hpp"
- static
- int yylex(yy::parser::semantic_type* yylval, yy::parser::location_type* yylloc, Scanner& scanner)
- {
- return scanner.yylex(yylval, yylloc);
- }
- %}
- %error-verbose
- %skeleton "lalr1.cc"
- %token-table
- %locations
- %parse-param {Scanner& scanner}
- %parse-param {Variables& vars}
- %parse-param {double& result}
- %parse-param {std::string& error_message}
- %lex-param {Scanner& scanner}
- %code requires {
- #include <map>
- #include <string>
- typedef std::map<std::string, double> Variables;
- class Scanner;
- }
- %define api.value.type variant
- %define parse.assert
- %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"
- %token END 0 "end of file"
- %token<std::string> IDENTIFIER "identifier"
- %token<double> NUMBER "number"
- %type<double> expr
- %printer { yyoutput << $$; } <*>
- %left '+' '-'
- %left '*' '/' '%'
- %left SIGN
- %left '^'
- %%
- root: expr { result = $1; }
- expr:
- NUMBER { $$ = $1; } |
- IDENTIFIER
- {
- const Variables::const_iterator it = vars.find($1);
- if (it == vars.end()) {
- std::ostringstream err;
- err << "undefined identifier '" << $1 << "'";
- throw syntax_error(@1, err.str());
- }
- const double val = it == vars.end() ? 0.0 : it->second;
- $$ = val;
- } |
- '(' expr ')' { $$ = $2; } |
- expr '+' expr { $$ = $1 + $3; } |
- expr '-' expr { $$ = $1 - $3; } |
- expr '*' expr { $$ = $1 * $3; } |
- expr '/' expr { $$ = $1 / $3; } |
- expr '%' expr { $$ = std::fmod($1, $3); } |
- expr '^' expr { $$ = std::pow($1, $3); } |
- '+' expr %prec SIGN { $$ = $2; } |
- '-' expr %prec SIGN { $$ = -$2; } |
- POW '(' expr ',' expr ')' { $$ = std::pow($3, $5); } |
- ABS '(' expr ')' { $$ = std::abs($3); } |
- EXP '(' expr ')' { $$ = std::exp($3); } |
- SQRT '(' expr ')' { $$ = std::sqrt($3); } |
- COS '(' expr ')' { $$ = std::cos($3); } |
- SIN '(' expr ')' { $$ = std::sin($3); } |
- TAN '(' expr ')' { $$ = std::tan($3); } |
- ACOS '(' expr ')' { $$ = std::acos($3); } |
- ASIN '(' expr ')' { $$ = std::asin($3); } |
- ATAN '(' expr ')' { $$ = std::atan($3); } |
- ATAN2 '(' expr ',' expr ')' { $$ = std::atan2($3, $5); } |
- CEIL '(' expr ')' { $$ = std::ceil($3); } |
- FLOOR '(' expr ')' { $$ = std::floor($3); } |
- MOD '(' expr ',' expr ')' { $$ = std::fmod($3, $5); } |
- LOG '(' expr ')' { $$ = std::log($3); } |
- LOG10 '(' expr ')' { $$ = std::log10($3); }
- %%
- void yy::parser::error(const yy::location& l, const std::string& m)
- {
- std::ostringstream error_stream;
- error_stream << l << ": " << m;
- error_message = error_stream.str();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement