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.
		
		
		
		
		
			
		
			
				
					
					
						
							70 lines
						
					
					
						
							2.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							70 lines
						
					
					
						
							2.8 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( "Divide by zero" ); | |
| 
 | |
|                                               A.valid = C.valid; | |
|                                           } | |
| expr(A) ::= PARENL expr(B) PARENR.        { A.dValue = B.dValue; A.valid = B.valid; } | |
| 
 |