Mercurial > ~dholland > hg > ag > index.cgi
view tests/agcl/parsifal/eval-p.syn @ 24:a4899cdfc2d6 default tip
Obfuscate the regexps to strip off the IBM compiler's copyright banners.
I don't want bots scanning github to think they're real copyright
notices because that could cause real problems.
author | David A. Holland |
---|---|
date | Mon, 13 Jun 2022 00:40:23 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
{ /* EVALKERN.SYN evaluateExpression: A Simple Expression Evaluator Copyright (c) 1996 Parsifal Software, All Rights Reserved. See the file COPYING for license and usage terms. EVALKERN.SYN is the kernel of the example, consisting of the expression parser itself. Support functions are defined in EVALWRAP.C. A test program is defined in EVALDEMO.C. Global declarations are contained in EVALDEFS.H. The parse function defined in EVALKERN.SYN is called evalKernel. All communication with evalKernel is via the parser control block. The wrapper function, evaluateExpression, defined in EVALWRAP.C, provides a more convenient interface for the function. The expression syntax is borrowed from C but with the addition of the FORTRAN exponentiation operator (**). The cast, increment, and decrement operators are not implemented, nor are operations that are defined only for integers: Bitwise logical operators: &, |, ^, ~, &=, |=, ^= Remainder operators: %, %= Shift operators: <<, >>, >>=, <<= The supported operations are: Assignment operators: =, +=, -=, *=, /= Conditional expressions: ? : Logical operators: !, &&, || Comparison operators: ==, !=, <, <=, >, >= Binary arithmetic operators: +, -, *, / Exponentiation: ** Unary arithmetic operators: +, - Parentheses Function calls All arithmetic is double precision floating point. Input strings may contain any number of expressions, separated by commas or semicolons. White space may be used freely, including both C and C++ style comments. eval makes the following external calls: void pushChar(int character); Push the specified character onto a character stack. double *locateVariable(int nameLength); Pop the last nameLength characters from the character stack and, treating them as the name of a variable, return a pointer to the location where the value of the variable is stored. void pushArg(double value); Push the specified value onto an argument stack. double callFunction(nameLength, int argCount); Pop the last nameLength characters from the character stack and, treating them as the name of a function, identify the function and invoke it with argCount arguments popped from the argument stack. double checkZero(double value); Verify that value is not zero. Overrides for macros defined by AnaGram, such as SYNTAX_ERROR should are included in EVALDEFS.H EVALKERN.SYN is compiled with the AnaGram parser generator yielding EVALKERN.H and EVALKERN.C. For information about AnaGram, visit http://www.parsifalsoft.com. */ #include <math.h> #include "evaldefs.h" // defines external interface } // -- CONFIGURATION SECTION ---------------------------- [ default token type = double disregard white space lexeme {real, name} pointer input parser name = evalKernel error frame auto resynch ] (void) input string $ // specify grammar token -> expressions, eof (void) expressions -> expression? -> expressions, ',' + ';', expression? expression -> conditional expression -> name:k, '=', expression:x =*locateVariable(k) = x; -> name:k, "+=", expression:x =*locateVariable(k) += x; -> name:k, "-=", expression:x =*locateVariable(k) -= x; -> name:k, "*=", expression:x =*locateVariable(k) *= x; -> name:k, "/=", expression:x =*locateVariable(k) /= x; conditional expression -> logical or expression -> logical or expression:c, '?', expression:x, ':', conditional expression:y =c?x:y; logical or expression -> logical and expression -> logical or expression:x, "||", logical and expression:y =x||y; logical and expression -> equality expression -> logical and expression:x, "&&", equality expression:y =x&&y; equality expression -> relational expression -> equality expression:x, "==", relational expression:y =x==y; -> equality expression:x, "!=", relational expression:y =x!=y; relational expression -> additive expression -> relational expression:x, '<', additive expression:y =x<y; -> relational expression:x, "<=", additive expression:y =x<=y; -> relational expression:x, '>', additive expression:y =x>y; -> relational expression:x, ">=", additive expression:y =x>=y; additive expression -> multiplicative expression -> additive expression:x, '+', multiplicative expression:y =x+y; -> additive expression:x, '-', multiplicative expression:y =x-y; multiplicative expression -> factor -> multiplicative expression:x, '*', factor:y =x*y; -> multiplicative expression:x, '/', factor:y =x/checkZero(y); factor -> primary -> primary:x, "**", factor:y = pow(x,y); primary -> real -> name:k =*locateVariable(k); -> name:k, '(', arguments:n, ')' =callFunction(k,n); -> '(', expression:x, ')' =x; -> '-', primary:x =-x; -> '+', primary:x = x; -> '!', primary:x =!x; (int) arguments //value of arguments is number of args -> =0; -> argument list //argument count passes automatically (int) argument list //value of argument list is number of args -> expression:x =pushArg(x), 1; -> argument list:k, ',', expression:x =pushArg(x), k+1; // -- LEXICAL UNITS ------------------------------------------------ digit = '0-9' eof = 0 letter = 'a-z' + 'A-Z' + '_' (void) white space -> ' ' + '\t' + '\f' + '\v' + '\r' + '\n' -> "/*", ~eof?..., "*/" // C style comment -> "//", ~(eof+'\n')?..., '\n' // C++ style comment real -> simple real -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e); -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e); simple real -> integer part:i, '.', fraction part:f = i+f; -> integer part, '.'? -> '.', fraction part:f = f; integer part -> digit:d = d-'0'; -> integer part:x, digit:d = 10*x + d-'0'; fraction part -> digit:d =(d-'0')/10.; -> digit:d, fraction part:f =(d-'0' + f)/10.; (int) exponent -> digit:d = d-'0'; -> exponent:x, digit:d = 10*x + d-'0'; (int) name //value of name token is length of name string -> letter: c =pushChar(c), 1; -> name:k, letter+digit: c =pushChar(c), k+1; { #define SYNTAX_ERROR printf("%s in %s, line %d, column %d\n", \ (PCB).error_message, TOKEN_NAMES[(PCB).error_frame_token], (PCB).line, (PCB).column) } /********************* End of EVALKERN.SYN ************************/