%{ #include #include #include #include #include using namespace std; using namespace Latan; %} %pure-parser %name-prefix="_Math_" %locations %defines %error-verbose %parse-param { Latan::MathParserState* state } %initial-action {yylloc.last_column = 0;} %lex-param { void* scanner } %union { double val_double; char val_char; char val_str[MAXIDLENGTH]; Latan::MathNode* val_nodept; } %token ERR %token FLOAT %token ID %left '+' '-' %left '*' '/' %left '^' %nonassoc UMINUS %type expr %{ int _Math_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner); void _Math_error(YYLTYPE* locp, MathParserState* state, const char* err) { stringstream buf; buf << *state->stream_name << ":" << locp->first_line << ":"\ << locp->first_column << ": " << err; LATAN_ERROR(Parsing,buf.str()); } #define scanner state->scanner %} %% program: /* empty string */ | expr {*state->data = $1;} ; expr: FLOAT {$$ = new MathNode($FLOAT,NodeType::Constant);} | ID {$$ = new MathNode($ID,NodeType::Variable);} | '-' expr %prec UMINUS {$$ = new MathNode("-",NodeType::Operator,1,$2);} | expr '+' expr {$$ = new MathNode("+",NodeType::Operator,2,$1,$3);} | expr '-' expr {$$ = new MathNode("-",NodeType::Operator,2,$1,$3);} | expr '*' expr {$$ = new MathNode("*",NodeType::Operator,2,$1,$3);} | expr '/' expr {$$ = new MathNode("/",NodeType::Operator,2,$1,$3);} | expr '^' expr {$$ = new MathNode("^",NodeType::Operator,2,$1,$3);} | '(' expr ')' {$$ = $2;} ;