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 ************************/