Mercurial > ~dholland > hg > ag > index.cgi
diff tests/agcl/parsifal/eval-e.syn @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/agcl/parsifal/eval-e.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,207 @@ +{ +/* + 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 + event driven + 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 + -1 +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 ************************/