comparison tests/agcl/oldagsrc/bciastp.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 BCIAST.SYN
4
5 Compiler for Byte Code Interpreter (using parse tree)
6 Copyright (c) 1997 Parsifal Software, All Rights Reserved.
7
8 The expression syntax is borrowed from C but with the
9 addition of the FORTRAN exponentiation operator (**).
10
11 The cast, increment, and decrement operators are not
12 implemented, nor are operations that are defined only
13 for integers:
14 Bitwise logical operators: &, |, ^, ~, &=, |=, ^=
15 Remainder operators: %, %=
16 Shift operators: <<, >>, >>=, <<=
17
18 The supported operations are:
19 Assignment operators: =, +=, -=, *=, /=
20 Conditional expressions: ? :
21 Logical operators: !, &&, ||
22 Comparison operators: ==, !=, <, <=, >, >=
23 Binary arithmetic operators: +, -, *, /
24 Exponentiation: **
25 Unary arithmetic operators: +, -
26 Parentheses
27 Built-in functions LOG, EXP
28
29 All arithmetic is double precision floating point.
30
31 Statements may include expression statements, blocks, if/else statements
32 or while statements, following the rules of C.
33
34 The statement syntax has been written to avoid the conventional
35 if/else ambiguity.
36
37 There are no declarations. All variables are presumed to be double.
38
39 Input strings may contain any number of statements. White space may be
40 used freely, including both C and C++ style comments.
41
42 vmParse makes the following external calls:
43 void pushChar(int character);
44 Push the specified character onto a character stack.
45
46 int locateVariable(int nameLength);
47 Pop the last nameLength characters from the character stack
48 and, treating them as the name of a variable, return an
49 index into the variable array.
50
51 Overrides for macros defined by AnaGram, such as SYNTAX_ERROR
52 are included in VMDEFS.H
53
54 VMPT.SYN is compiled with the AnaGram parser generator
55 yielding VMPT.H and VMPT.CPP.
56
57 To build VMPT, compile and link VMPT.CPP, VMDEMO.CPP and PTREE.CPP
58 with your C++ compiler.
59
60 For information about AnaGram, visit http://www.parsifalsoft.com.
61 */
62
63 #include "bciast.h"
64 #include "agstk.h" // Defines AgStack<Object>
65 #include "agstr.h" // Defines AgString et al
66 #include <math.h> // for pow()
67 #include "ptree.h"
68
69 //typedef AgStack<Statement *> StatementList;
70
71 }
72 // -- CONFIGURATION SECTION ----------------------------
73 [
74 disregard white space
75 lexeme {real, name}
76 pointer input
77 parser name = astParse
78 parser file name = "#.cpp"
79 reentrant parser
80
81 wrapper {AgStack<Statement *>, AgString}
82
83 // Put the following in the parser control block for use during parsing
84 extend pcb {
85 // Maps symbol names to variables
86 // AgSharedStringDictionary symbolDictionary;
87 AbstractSyntaxTree *ast;
88
89 // Temporary space to accumulate identifiers while parsing
90 AgString charStack;
91 }
92 ]
93
94 /*
95 * Mark input string with $ to indicate it is the "grammar token",
96 * that is, the whole of the input we're intending to parse.
97 */
98 (Program *) input string $
99 -> statements:s, eof = PCB.ast->makeProgram(s);
100
101 /*
102 * Zero or more statements. Generate a list of pointers to
103 * statement descriptors.
104 */
105 (AgStack<Statement *>) statements
106 -> =AgStack<Statement *>();
107 -> statements:s, statement:x =s.push(x);
108
109 /*
110 * A single statement.
111 *
112 * Here, an "open" statement is a statement that can legally be
113 * followed by an "else" keyword. A "closed" statement is one that
114 * cannot.
115 *
116 * This resolves the common if-then-else ambiguity. See ifelse.html for
117 * a discussion of the ambiguity and this technique for resolving it.
118 */
119 (Statement *) statement
120 -> closed statement
121 -> open statement
122
123 /*
124 Any statement than can accept a dengling else clause
125 is an open statement
126 */
127
128 (Statement *) open statement
129 -> "if", '(', expression:x, ')',
130 statement:s = PCB.ast->makeIfStatement(x, s);
131 -> "if", '(', expression:x, ')',
132 closed statement:s1,
133 "else",
134 open statement:s2 = PCB.ast->makeIfElseStatement(x,s1,s2);
135 -> "while", '(', expression:x, ')',
136 open statement:s = PCB.ast->makeWhileStatement(x,s);
137 -> "for", '(',
138 expression:init, ';',
139 expression:cond, ';',
140 expression:inc, ')', open statement:s = PCB.ast->makeForStatement(init, cond, inc, s);
141
142 (Statement *) closed statement
143 -> "if", '(', expression:x, ')', closed statement:s1,
144 "else", closed statement:s2 = PCB.ast->makeIfElseStatement(x,s1,s2);
145 -> "while", '(', expression:x, ')',
146 closed statement:s = PCB.ast->makeWhileStatement(x,s);
147 -> "for", '(',
148 expression:init, ';',
149 expression:cond, ';',
150 expression:inc, ')', closed statement:s = PCB.ast->makeForStatement(init, cond, inc, s);
151 -> simple statement:x = x;
152
153 /*
154 * Statements that do not end with other statements. These all behave the
155 * same way with respect to the closed statement/open statement construct
156 * above, and are therefore factored out to PCB.ast->make it clearer.
157 *
158 * The bare expression appendss a pop instruction so that the resulting
159 * byte code will discard the expression's value. (This is not an
160 * optimizing compiler.)
161 */
162 (Statement *) simple statement
163 -> "do", statement:s,
164 "while", '(', expression:x, ')', ';' = PCB.ast->makeDoStatement(s,x);
165 -> expression:x, ';' = PCB.ast->makeExpressionStatement(x);
166 -> ';' = PCB.ast->makeStatement();
167 -> '{', statements:s, '}' = PCB.ast->makeStatementBlock(s);
168
169 // General expression. As in C, comma expression has the lowest precedence.
170 (Expression *) expression
171 -> assignment expression
172 -> expression:x, ',', assignment expression:y = PCB.ast->makeCommaExpression(x,y);
173
174 /*
175 * Next precedence: assignments. Again, as in C, except we don't
176 * support quite all the operators.
177 */
178 (Expression *) assignment expression
179 -> conditional expression
180 -> name:k, '=', assignment expression:x =PCB.ast->makeSimpleAssignment(k, x);
181 -> name:k, "+=", assignment expression:x =PCB.ast->makeAddMemory(k, x);
182 -> name:k, "-=", assignment expression:x =PCB.ast->makeSubMemory(k, x);
183 -> name:k, "*=", assignment expression:x =PCB.ast->makeMulMemory(k, x);
184 -> name:k, "/=", assignment expression:x =PCB.ast->makeDivMemory(k, x);
185
186 // Conditional expression (ternary operator)
187 (Expression *) conditional expression
188 -> logical or expression
189 -> logical or expression:c, '?',
190 expression:x, ':', conditional expression:y =PCB.ast->makeConditionalExpression(c,x,y);
191
192 // Logical expressions with short-cut evaluation, as in C.
193 (Expression *) logical or expression
194 -> logical and expression
195 -> logical or expression:x, "||",
196 logical and expression:y =PCB.ast->makeLogicalOrExpression(x, y);
197
198 (Expression *) logical and expression
199 -> equality expression
200 -> logical and expression:x, "&&",
201 equality expression:y =PCB.ast->makeLogicalAndExpression(x,y);
202
203 // Arithmetic expressions, in operator precedence order.
204 (Expression *) equality expression
205 -> relational expression
206 -> equality expression:x, "==", relational expression:y =PCB.ast->makeEqExpression(x,y);
207 -> equality expression:x, "!=", relational expression:y =PCB.ast->makeNeExpression(x,y);
208
209 (Expression *) relational expression
210 -> additive expression
211 -> relational expression:x, '<', additive expression:y =PCB.ast->makeLtExpression(x,y);
212 -> relational expression:x, "<=", additive expression:y =PCB.ast->makeLeExpression(x,y);
213 -> relational expression:x, '>', additive expression:y =PCB.ast->makeGtExpression(x,y);
214 -> relational expression:x, ">=", additive expression:y =PCB.ast->makeGeExpression(x,y);
215
216 (Expression *) additive expression
217 -> multiplicative expression
218 -> additive expression:x, '+',
219 multiplicative expression:y =PCB.ast->makeAddExpression(x,y);
220 -> additive expression:x, '-',
221 multiplicative expression:y =PCB.ast->makeSubExpression(x,y);
222
223 (Expression *) multiplicative expression
224 -> unary expression
225 -> multiplicative expression:x, '*', unary expression:y =PCB.ast->makeMulExpression(x,y);
226 -> multiplicative expression:x, '/', unary expression:y =PCB.ast->makeDivExpression(x,y);
227
228 (Expression *) unary expression
229 -> factor
230 -> '-', unary expression:x =PCB.ast->makeNegExpression(x);
231 -> '+', unary expression:x =x;
232 -> '!', unary expression:x =PCB.ast->makeNotExpression(x);
233
234 /*
235 * Syntactically, we can use ** for exponentiation because we don't have
236 * pointers. (In C, ** could be confused with pointer indirection.)
237 * Note that the precedence of ** is inserted between unary +/- and unary !.
238 */
239 (Expression *) factor
240 -> primary
241 -> primary:x, "**", unary expression:y =PCB.ast->makePowExpression(x,y);
242
243 /*
244 * Primary expression - bottom level of expression syntax.
245 * Variable references, constants, the builtin functions.
246 * Also, another expression in parentheses. (This is how you make
247 * parentheses work the way they're supposed to.)
248 */
249 (Expression *) primary
250 -> real:x =PCB.ast->makeConstant(x);
251 -> name:k =PCB.ast->makeVariable(k);
252 -> "log", '(', expression:x, ')' =PCB.ast->makeLogExpression(x);
253 -> "exp", '(', expression:x, ')' =PCB.ast->makeExpExpression(x);
254 -> "sqrt", '(', assignment expression:x, ')' =PCB.ast->makeSqrtExpression(x);
255 -> '(', expression:x, ')' =x;
256
257 // -- LEXICAL UNITS ------------------------------------------------
258 digit = '0-9'
259 eof = 0
260 letter = 'a-z' + 'A-Z' + '_'
261
262 (void) white space
263 -> ' ' + '\t' + '\f' + '\v' + '\r' + '\n'
264 -> "/*", ~eof?..., "*/" // C style comment
265 -> "//", ~(eof+'\n')?..., '\n' // C++ style comment
266
267 (double) real
268 -> simple real:x =x;
269 -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e);
270 -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e);
271
272 (double) simple real
273 -> integer part:i, '.', fraction part:f = i+f;
274 -> integer part:i, '.'? = i;
275 -> '.', fraction part:f = f;
276
277 (double) integer part
278 -> digit:d = d-'0';
279 -> integer part:x, digit:d = 10*x + d-'0';
280
281 (double) fraction part
282 -> digit:d =(d-'0')/10.;
283 -> digit:d, fraction part:f =(d-'0' + f)/10.;
284
285 (int) exponent
286 -> digit:d = d-'0';
287 -> exponent:x, digit:d = 10*x + d-'0';
288
289 (AgString) name
290 -> letter: c =AgString().concat(c);
291 -> name:s, letter+digit: c =s.concat(c);
292
293 { // begin embedded C
294
295 void ag_delete_wrappers(astParse_pcb_struct *);
296
297 void parseStatements(AbstractSyntaxTree *tree, char *text) {
298 astParse_pcb_struct pcb;
299 pcb.ast = tree;
300 pcb.pointer = (unsigned char *) text;
301 astParse(&pcb);
302 if (pcb.exit_flag == AG_SUCCESS_CODE) tree->setRoot(astParse_value(&pcb));
303 else ag_delete_wrappers(&pcb);
304 }
305 } // end of embedded C
306 /********************* End of bciast.syn ************************/