|
|
/* This file is part of libeval, a simple math expression evaluator
Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.*/
%token_type { numEval::TokenType }%extra_argument { NUMERIC_EVALUATOR* pEval }
%nonassoc VAR ASSIGN SEMCOL.%left PLUS MINUS.%right UNIT.%left DIVIDE MULT.
%include {#include <assert.h>#include <libeval/numeric_evaluator.h>}
%syntax_error { pEval->parseError("Syntax error");}
%parse_accept { pEval->parseOk();}
main ::= in.
/* Allow multiple statements in input string: x=1; y=2 */in ::= stmt.in ::= in stmt.
/* A statement can be empty, an expr or an expr followed by ';' */stmt ::= ENDS.stmt ::= expr(A) ENDS. { pEval->parseSetResult(A.valid ? A.dValue : NAN); }stmt ::= expr SEMCOL. { pEval->parseSetResult(NAN); }
expr(A) ::= VALUE(B). { A.dValue = B.dValue; A.valid=true; }expr(A) ::= expr(B) UNIT(C). { A.dValue = B.dValue * C.dValue; A.valid=B.valid; }expr(A) ::= MINUS expr(B). { A.dValue = -B.dValue; A.valid=B.valid; }expr(A) ::= PLUS expr(B). { A.dValue = B.dValue; A.valid=B.valid; }expr(A) ::= VAR(B). { A.dValue = pEval->GetVar(B.text); A.valid=true; }expr(A) ::= VAR(B) ASSIGN expr(C). { pEval->SetVar(B.text, C.dValue); A.dValue = C.dValue; A.valid=false; }expr(A) ::= expr(B) PLUS expr(C). { A.dValue = B.dValue + C.dValue; A.valid=C.valid; }expr(A) ::= expr(B) MINUS expr(C). { A.dValue = B.dValue - C.dValue; A.valid=C.valid; }expr(A) ::= expr(B) MULT expr(C). { A.dValue = B.dValue * C.dValue; A.valid=C.valid; }expr(A) ::= expr(B) DIVIDE expr(C). { if( C.dValue != 0.0 ) A.dValue = B.dValue / C.dValue; else pEval->parseError( "Divide by zero" );
A.valid = C.valid; }expr(A) ::= PARENL expr(B) PARENR. { A.dValue = B.dValue; A.valid = B.valid; }
|