%{ #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->streamName << ":" << 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, MathNode::Type::Constant);} | ID {$$ = new MathNode($ID,MathNode::Type::Variable);} | '-' expr %prec UMINUS {$$ = new MathNode("-", MathNode::Type::Operator, 1,$2);} | expr '+' expr {$$ = new MathNode("+", MathNode::Type::Operator, 2, $1, $3);} | expr '-' expr {$$ = new MathNode("-", MathNode::Type::Operator, 2, $1, $3);} | expr '*' expr {$$ = new MathNode("*", MathNode::Type::Operator, 2, $1, $3);} | expr '/' expr {$$ = new MathNode("/", MathNode::Type::Operator, 2, $1, $3);} | expr '^' expr {$$ = new MathNode("^", MathNode::Type::Operator, 2, $1, $3);} | '(' expr ')' {$$ = $2;} ;