You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							69 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							69 lines
						
					
					
						
							2.5 KiB
						
					
					
				
								/*
							 | 
						|
								    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("Div by zero");
							 | 
						|
								   A.valid=C.valid; 
							 | 
						|
								}
							 | 
						|
								expr(A) ::= PARENL expr(B) PARENR.        { A.dValue = B.dValue; A.valid=B.valid; }
							 | 
						|
								
							 |