Mercurial > ~dholland > hg > ag > index.cgi
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 ************************/ |