comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 {
2 /*
3 EVALKERN.SYN
4
5 evaluateExpression: A Simple Expression Evaluator
6 Copyright (c) 1996 Parsifal Software, All Rights Reserved.
7 See the file COPYING for license and usage terms.
8
9 EVALKERN.SYN is the kernel of the example, consisting
10 of the expression parser itself. Support functions are
11 defined in EVALWRAP.C. A test program is defined in
12 EVALDEMO.C. Global declarations are contained in
13 EVALDEFS.H.
14
15 The parse function defined in EVALKERN.SYN is called
16 evalKernel. All communication with evalKernel is via
17 the parser control block. The wrapper function,
18 evaluateExpression, defined in EVALWRAP.C, provides
19 a more convenient interface for the function.
20
21 The expression syntax is borrowed from C but with the
22 addition of the FORTRAN exponentiation operator (**).
23
24 The cast, increment, and decrement operators are not
25 implemented, nor are operations that are defined only
26 for integers:
27 Bitwise logical operators: &, |, ^, ~, &=, |=, ^=
28 Remainder operators: %, %=
29 Shift operators: <<, >>, >>=, <<=
30
31 The supported operations are:
32 Assignment operators: =, +=, -=, *=, /=
33 Conditional expressions: ? :
34 Logical operators: !, &&, ||
35 Comparison operators: ==, !=, <, <=, >, >=
36 Binary arithmetic operators: +, -, *, /
37 Exponentiation: **
38 Unary arithmetic operators: +, -
39 Parentheses
40 Function calls
41
42 All arithmetic is double precision floating point.
43
44 Input strings may contain any number of expressions, separated by
45 commas or semicolons. White space may be used freely, including
46 both C and C++ style comments.
47
48 eval makes the following external calls:
49 void pushChar(int character);
50 Push the specified character onto a character stack.
51
52 double *locateVariable(int nameLength);
53 Pop the last nameLength characters from the character stack
54 and, treating them as the name of a variable, return a pointer
55 to the location where the value of the variable is stored.
56
57 void pushArg(double value);
58 Push the specified value onto an argument stack.
59
60 double callFunction(nameLength, int argCount);
61 Pop the last nameLength characters from the character stack
62 and, treating them as the name of a function, identify the
63 function and invoke it with argCount arguments popped from
64 the argument stack.
65
66 double checkZero(double value);
67 Verify that value is not zero.
68
69 Overrides for macros defined by AnaGram, such as SYNTAX_ERROR
70 should are included in EVALDEFS.H
71
72 EVALKERN.SYN is compiled with the AnaGram parser generator
73 yielding EVALKERN.H and EVALKERN.C.
74
75 For information about AnaGram, visit http://www.parsifalsoft.com.
76 */
77
78 #include <math.h>
79 #include "evaldefs.h" // defines external interface
80
81 }
82 // -- CONFIGURATION SECTION ----------------------------
83 [
84 default token type = double
85 disregard white space
86 lexeme {real, name}
87 //pointer input
88 event driven
89 parser name = evalKernel
90 error frame
91 auto resynch
92 ]
93
94 (void) input string $ // specify grammar token
95 -> expressions, eof
96
97 (void) expressions
98 -> expression?
99 -> expressions, ',' + ';', expression?
100
101 expression
102 -> conditional expression
103 -> name:k, '=', expression:x =*locateVariable(k) = x;
104 -> name:k, "+=", expression:x =*locateVariable(k) += x;
105 -> name:k, "-=", expression:x =*locateVariable(k) -= x;
106 -> name:k, "*=", expression:x =*locateVariable(k) *= x;
107 -> name:k, "/=", expression:x =*locateVariable(k) /= x;
108
109 conditional expression
110 -> logical or expression
111 -> logical or expression:c, '?',
112 expression:x, ':', conditional expression:y =c?x:y;
113
114 logical or expression
115 -> logical and expression
116 -> logical or expression:x, "||", logical and expression:y =x||y;
117
118 logical and expression
119 -> equality expression
120 -> logical and expression:x, "&&", equality expression:y =x&&y;
121
122 equality expression
123 -> relational expression
124 -> equality expression:x, "==", relational expression:y =x==y;
125 -> equality expression:x, "!=", relational expression:y =x!=y;
126
127 relational expression
128 -> additive expression
129 -> relational expression:x, '<', additive expression:y =x<y;
130 -> relational expression:x, "<=", additive expression:y =x<=y;
131 -> relational expression:x, '>', additive expression:y =x>y;
132 -> relational expression:x, ">=", additive expression:y =x>=y;
133
134 additive expression
135 -> multiplicative expression
136 -> additive expression:x, '+', multiplicative expression:y =x+y;
137 -> additive expression:x, '-', multiplicative expression:y =x-y;
138
139 multiplicative expression
140 -> factor
141 -> multiplicative expression:x, '*', factor:y =x*y;
142 -> multiplicative expression:x, '/', factor:y =x/checkZero(y);
143
144 factor
145 -> primary
146 -> primary:x, "**", factor:y = pow(x,y);
147
148 primary
149 -> real
150 -> name:k =*locateVariable(k);
151 -> name:k, '(', arguments:n, ')' =callFunction(k,n);
152 -> '(', expression:x, ')' =x;
153 -> '-', primary:x =-x;
154 -> '+', primary:x = x;
155 -> '!', primary:x =!x;
156
157 (int) arguments //value of arguments is number of args
158 -> =0;
159 -> argument list //argument count passes automatically
160
161 (int) argument list //value of argument list is number of args
162 -> expression:x =pushArg(x), 1;
163 -> argument list:k, ',', expression:x =pushArg(x), k+1;
164
165 // -- LEXICAL UNITS ------------------------------------------------
166 digit = '0-9'
167 eof = 0 + -1
168 letter = 'a-z' + 'A-Z' + '_'
169
170 (void) white space
171 -> ' ' + '\t' + '\f' + '\v' + '\r' + '\n'
172 -> "/*", ~eof?..., "*/" // C style comment
173 -> "//", ~(eof+'\n')?..., '\n' // C++ style comment
174
175 real
176 -> simple real
177 -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e);
178 -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e);
179
180 simple real
181 -> integer part:i, '.', fraction part:f = i+f;
182 -> integer part, '.'?
183 -> '.', fraction part:f = f;
184
185 integer part
186 -> digit:d = d-'0';
187 -> integer part:x, digit:d = 10*x + d-'0';
188
189 fraction part
190 -> digit:d =(d-'0')/10.;
191 -> digit:d, fraction part:f =(d-'0' + f)/10.;
192
193 (int) exponent
194 -> digit:d = d-'0';
195 -> exponent:x, digit:d = 10*x + d-'0';
196
197 (int) name //value of name token is length of name string
198 -> letter: c =pushChar(c), 1;
199 -> name:k, letter+digit: c =pushChar(c), k+1;
200
201 {
202 #define SYNTAX_ERROR printf("%s in %s, line %d, column %d\n", \
203 (PCB).error_message, TOKEN_NAMES[(PCB).error_frame_token], (PCB).line, (PCB).column)
204
205 }
206
207 /********************* End of EVALKERN.SYN ************************/