comparison tests/agcl/parsifal/eval-p.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 parser name = evalKernel
89 error frame
90 auto resynch
91 ]
92
93 (void) input string $ // specify grammar token
94 -> expressions, eof
95
96 (void) expressions
97 -> expression?
98 -> expressions, ',' + ';', expression?
99
100 expression
101 -> conditional expression
102 -> name:k, '=', expression:x =*locateVariable(k) = x;
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
108 conditional expression
109 -> logical or expression
110 -> logical or expression:c, '?',
111 expression:x, ':', conditional expression:y =c?x:y;
112
113 logical or expression
114 -> logical and expression
115 -> logical or expression:x, "||", logical and expression:y =x||y;
116
117 logical and expression
118 -> equality expression
119 -> logical and expression:x, "&&", equality expression:y =x&&y;
120
121 equality expression
122 -> relational expression
123 -> equality expression:x, "==", relational expression:y =x==y;
124 -> equality expression:x, "!=", relational expression:y =x!=y;
125
126 relational expression
127 -> additive expression
128 -> relational expression:x, '<', additive expression:y =x<y;
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
133 additive expression
134 -> multiplicative expression
135 -> additive expression:x, '+', multiplicative expression:y =x+y;
136 -> additive expression:x, '-', multiplicative expression:y =x-y;
137
138 multiplicative expression
139 -> factor
140 -> multiplicative expression:x, '*', factor:y =x*y;
141 -> multiplicative expression:x, '/', factor:y =x/checkZero(y);
142
143 factor
144 -> primary
145 -> primary:x, "**", factor:y = pow(x,y);
146
147 primary
148 -> real
149 -> name:k =*locateVariable(k);
150 -> name:k, '(', arguments:n, ')' =callFunction(k,n);
151 -> '(', expression:x, ')' =x;
152 -> '-', primary:x =-x;
153 -> '+', primary:x = x;
154 -> '!', primary:x =!x;
155
156 (int) arguments //value of arguments is number of args
157 -> =0;
158 -> argument list //argument count passes automatically
159
160 (int) argument list //value of argument list is number of args
161 -> expression:x =pushArg(x), 1;
162 -> argument list:k, ',', expression:x =pushArg(x), k+1;
163
164 // -- LEXICAL UNITS ------------------------------------------------
165 digit = '0-9'
166 eof = 0
167 letter = 'a-z' + 'A-Z' + '_'
168
169 (void) white space
170 -> ' ' + '\t' + '\f' + '\v' + '\r' + '\n'
171 -> "/*", ~eof?..., "*/" // C style comment
172 -> "//", ~(eof+'\n')?..., '\n' // C++ style comment
173
174 real
175 -> simple real
176 -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e);
177 -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e);
178
179 simple real
180 -> integer part:i, '.', fraction part:f = i+f;
181 -> integer part, '.'?
182 -> '.', fraction part:f = f;
183
184 integer part
185 -> digit:d = d-'0';
186 -> integer part:x, digit:d = 10*x + d-'0';
187
188 fraction part
189 -> digit:d =(d-'0')/10.;
190 -> digit:d, fraction part:f =(d-'0' + f)/10.;
191
192 (int) exponent
193 -> digit:d = d-'0';
194 -> exponent:x, digit:d = 10*x + d-'0';
195
196 (int) name //value of name token is length of name string
197 -> letter: c =pushChar(c), 1;
198 -> name:k, letter+digit: c =pushChar(c), k+1;
199
200 {
201 #define SYNTAX_ERROR printf("%s in %s, line %d, column %d\n", \
202 (PCB).error_message, TOKEN_NAMES[(PCB).error_frame_token], (PCB).line, (PCB).column)
203
204 }
205
206 /********************* End of EVALKERN.SYN ************************/