Mercurial > ~dholland > hg > ag > index.cgi
comparison tests/agcl/contrib/yabasic.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 /* | |
4 YABASIC --- a tiny integrated Basic Compiler/Interpreter | |
5 | |
6 BISON - part | |
7 | |
8 this Program is subject to the GNU General Public License; | |
9 see the file yabasic.c for details. | |
10 */ | |
11 | |
12 | |
13 //#undef WINDOWS | |
14 #include "yabasic.h" /* definitions of yabasic */ | |
15 #include <malloc.h> | |
16 | |
17 #if HAVE_ALLOCA_H | |
18 #include <alloca.h> | |
19 #endif | |
20 | |
21 void __yy_bcopy(char *,char *,int); /* prototype missing */ | |
22 | |
23 int yylineno=1; | |
24 int yylex(void); | |
25 | |
26 char *popString(int); | |
27 void pushChar(int); | |
28 | |
29 } | |
30 | |
31 [ | |
32 ~case sensitive | |
33 disregard white space | |
34 lexeme {digit string, name, STRING, STRSYM, number} | |
35 distinguish lexemes | |
36 parser name = parseBasic | |
37 line numbers | |
38 escape backslashes | |
39 ] | |
40 | |
41 white space = ' ' + '\t' | |
42 | |
43 //(double *) step_part | |
44 | |
45 | |
46 SEP | |
47 -> ["REM", ~(eof + white space + '\n')?...], '\n' ={ | |
48 yylineno++; | |
49 if (interactive) PCB.exit_flag = AG_SUCCESS_CODE; | |
50 return; | |
51 } | |
52 | |
53 (double) number | |
54 -> simple real | |
55 -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e); | |
56 -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e); | |
57 | |
58 (double) simple real | |
59 -> integer part:i, '.', fraction part:f = i+f; | |
60 -> integer part, '.'? | |
61 -> '.', fraction part:f = f; | |
62 | |
63 (double) integer part | |
64 -> digit:d = d-'0'; | |
65 -> integer part:x, digit:d = 10*x + d-'0'; | |
66 | |
67 (double) fraction part | |
68 -> digit:d =(d-'0')/10.; | |
69 -> digit:d, fraction part:f =(d-'0' + f)/10.; | |
70 | |
71 (int) exponent | |
72 -> digit:d = d-'0'; | |
73 -> exponent:x, digit:d = 10*x + d-'0'; | |
74 | |
75 (int) name //value of name token is length of name string | |
76 -> letter: c =pushChar(c), 1; | |
77 -> name:k, letter+digit: c =pushChar(c), k+1; | |
78 | |
79 | |
80 (char *) SYMBOL | |
81 -> name:k =strdup(popString(k)); | |
82 | |
83 (char *) STRSYM | |
84 -> name:k, '$' =pushChar('$'), strdup(popString(k+1)); | |
85 | |
86 (char *) DIGITS | |
87 -> digit string:k =strdup(popString(k)); | |
88 | |
89 (int) digit string | |
90 -> digit:d =pushChar(d), 1; | |
91 -> digit string:k, digit:d =pushChar(d), k+1; | |
92 | |
93 (char *) STRING | |
94 -> '"', string text:k, '"' =strdup(popString(k)); | |
95 -> '"', string text:k, '\n' =strdup(popString(k)); | |
96 | |
97 (int) string text | |
98 -> =0; | |
99 -> string text:k, ~(eof + '"' + '\n'):c =pushChar(c), k+1; | |
100 -> string text:k, "\\\"" =pushChar('"'), k+1; | |
101 | |
102 /* | |
103 [ | |
104 left {"OR"} | |
105 left {"AND"} | |
106 left {"NOT"} | |
107 left {'-', '+'} | |
108 left {'*', '/'} | |
109 left {'^'} | |
110 nonassoc {UMINUS} | |
111 ] | |
112 */ | |
113 | |
114 letter = 'a-z' + 'A-Z' | |
115 digit = '0-9' | |
116 eof = 0 + -1 | |
117 | |
118 | |
119 program $ | |
120 -> statement list, eof =end_of_file = TRUE; | |
121 | |
122 statement list | |
123 -> | |
124 /* | |
125 -> statement_list, !{ | |
126 if (errorlevel<=ERROR) {YYABORT;}}, | |
127 SEP, !{ | |
128 yylineno+=$3;}, | |
129 statement | |
130 */ | |
131 -> statement list, SEP, statement | |
132 -> statement list, SEP, label, statement | |
133 | |
134 label | |
135 -> "LABEL", SYMBOL:s =create_label(s); | |
136 -> DIGITS:s =create_label(s); | |
137 | |
138 | |
139 statement /* empty */ | |
140 -> | |
141 -> string_assignment | |
142 -> assignment | |
143 -> for_loop | |
144 -> if_clause | |
145 -> "GOTO", symbol_or_lineno:s ={create_goto(s);} | |
146 -> "GOSUB", symbol_or_lineno:s ={create_gosub(s);} | |
147 -> "ON", "INTERRUPT", "BREAK" ={create_exception(TRUE);} | |
148 -> "ON", "INTERRUPT", "CONTINUE" ={create_exception(FALSE);} | |
149 -> "ON", expression, "GOTO", !{create_skipper();}, goto_list ={create_nop();} | |
150 -> "ON", expression, "GOSUB", !{create_skipper();}, gosub_list ={create_nop();} | |
151 // -> LABEL, symbol_or_lineno ={create_label($2);} | |
152 -> "OPEN", hashed_number:n, ',', string expression, ',', string expression ={create_myopen(n,'+');} | |
153 -> "OPEN", hashed_number:n, ',', string expression ={create_myopen(n,'-');} | |
154 -> "CLOSE", hashed_number:n ={create_myclose(n);} | |
155 -> "PRINT", printintro, printlist, !{ | |
156 create_revert(FALSE);}, | |
157 semicolon | |
158 -> "INPUT", inputintro, inputlist =lastinput->args=0; | |
159 -> "READ", readlist | |
160 -> "DATA", datalist | |
161 -> "RESTORE" =create_restore(""); | |
162 -> "RESTORE", symbol_or_lineno:s =create_restore(s); | |
163 -> "RETURN" ={create_return();} | |
164 -> "DIM", dimlist | |
165 -> "OPEN", "WINDOW", expression, ',', expression =create_openwin(FALSE); | |
166 -> "OPEN", "WINDOW", expression, ',', expression, ',', string expression ={create_openwin(TRUE);} | |
167 -> "DOT", mapping =create_dot(); | |
168 -> "LINE", mapping, "TO", mapping =create_line('l'); | |
169 -> "CIRCLE", mapping, ',', expression =create_circle(); | |
170 -> "TEXT", string expression, ',', mapping =create_text(TRUE); | |
171 -> "TEXT", mapping, ',', string expression =create_text(FALSE); | |
172 -> "MAP", expression, ',', expression, ',', expression, ',', expression, "TO", expression, ',', expression, ',', expression, ',', expression =create_makemap(); | |
173 -> "ARROW", mapping, "TO", mapping =create_line('a'); | |
174 -> "XTICK", mapping, ',', string expression =create_tick(1); | |
175 -> "YTICK", mapping, ',', string expression =create_tick(3); | |
176 -> "XTICK", mapping =create_tick(0); | |
177 -> "YTICK", mapping =create_tick(2); | |
178 -> "CLOSE", "WINDOW" =create_closewin(); | |
179 -> "CLEAR", "WINDOW" =create_clearwin(); | |
180 -> "CLEAR", "SCREEN" =create_clearscreen(); | |
181 -> "OPEN", "PRINTER" =create_openprinter(0); | |
182 -> "OPEN", "PRINTER", string expression =create_openprinter(1); | |
183 -> "CLOSE", "PRINTER" =create_closeprinter(); | |
184 -> "WAIT", expression =create_mywait(); | |
185 -> "BELL" =create_bell(); | |
186 -> "INKEY" ={create_function(MYINKEY); create_popstrsym(NULL);} | |
187 -> "SYSTEM2", '(', string expression, ')' ={create_function(MYSYSTEM2); | |
188 create_popdblsym(NULL);} | |
189 -> "POKE", string expression, ',', string expression ={create_poke('s');} | |
190 -> "POKE", string expression, ',', expression ={create_poke('d');} | |
191 -> "END" ={create_myend();} | |
192 | |
193 string_assignment | |
194 -> STRSYM:s, '=', string expression ={create_popstrsym(s);} | |
195 -> "MID", '(', STRSYM:s, !{ | |
196 create_pushstrptr(s);}, | |
197 ',', expression, ',', expression, ')', '=', string expression ={create_changestring(MYMID);} | |
198 -> "LEFT", '(', STRSYM:s, !{ | |
199 create_pushstrptr(s);}, | |
200 ',', expression, ')', '=', string expression ={create_changestring(MYLEFT);} | |
201 -> "RIGHT", '(', STRSYM:s, !{ | |
202 create_pushstrptr(s);}, | |
203 ',', expression, ')', '=', string expression ={create_changestring(MYRIGHT);} | |
204 -> STRSYM:s, '(', !{ | |
205 pushcounter();}, | |
206 indexlist, ')', '=', string expression ={create_doarray(s,ASSIGNSTRINGARRAY);} | |
207 -> "MID", '(', STRSYM:s, '(', !{ | |
208 pushcounter();}, | |
209 indexlist, ')', !{ | |
210 create_doarray(s,GETSTRINGPOINTER);}, | |
211 ',', expression, ',', expression, ')', '=', string expression ={create_changestring(MYMID);} | |
212 -> "LEFT", '(', STRSYM:s, '(', !{ | |
213 pushcounter();}, | |
214 indexlist, ')', !{ | |
215 create_doarray(s,GETSTRINGPOINTER);}, | |
216 ',', expression, ')', '=', string expression ={create_changestring(MYLEFT);} | |
217 -> "RIGHT", '(', STRSYM:s, '(', !{ | |
218 pushcounter();}, | |
219 indexlist, ')', !{ | |
220 create_doarray(s,GETSTRINGPOINTER);}, | |
221 ',', expression, ')', '=', string expression ={create_changestring(MYRIGHT);} | |
222 | |
223 string expression | |
224 -> primary string expression | |
225 -> string expression, '+', primary string expression ={create_concat();} | |
226 | |
227 primary string expression | |
228 -> STRSYM:s ={create_pushstrsym(s);} | |
229 -> string_function | |
230 -> STRING:s ={if (s==NULL) {error(ERROR,"String not terminated");create_pushstr("");} else {create_pushstr(s);}} | |
231 -> STRSYM:s, '(', !{ | |
232 pushcounter();}, | |
233 indexlist, ')' ={create_doarray(s,CALLSTRINGARRAY);} | |
234 -> '(', string expression, ')' | |
235 | |
236 string_function | |
237 -> "LEFT", '(', string expression, ',', expression, ')' ={create_function(MYLEFT);} | |
238 -> "RIGHT", '(', string expression, ',', expression, ')' ={create_function(MYRIGHT);} | |
239 -> "MID", '(', string expression, ',', expression, ',', expression, ')' ={create_function(MYMID);} | |
240 -> "STR", '(', expression, ')' ={create_function(MYSTR);} | |
241 -> "STR", '(', expression, ',', string expression, ')' ={create_function(MYSTR2);} | |
242 -> "INKEY" ={create_function(MYINKEY);} | |
243 -> "CHR", '(', expression, ')' ={create_function(MYCHR);} | |
244 -> "UPPER", '(', string expression, ')' ={create_function(MYUPPER);} | |
245 -> "LOWER", '(', string expression, ')' ={create_function(MYLOWER);} | |
246 -> "LTRIM", '(', string expression, ')' ={create_function(MYLTRIM);} | |
247 -> "RTRIM", '(', string expression, ')' ={create_function(MYRTRIM);} | |
248 -> "TRIM", '(', string expression, ')' ={create_function(MYTRIM);} | |
249 -> "SYSTEM", '(', string expression, ')' ={create_function(MYSYSTEM);} | |
250 -> "DATE" ={create_function(MYDATE);} | |
251 -> "TIME" ={create_function(MYTIME);} | |
252 -> "PEEK2", '(', string expression, ')' ={create_function(MYPEEK2);} | |
253 | |
254 assignment | |
255 -> SYMBOL:s, '=', expression ={create_popdblsym(s);} | |
256 -> SYMBOL:s, '(', !{ | |
257 pushcounter();}, | |
258 indexlist, ')', '=', expression ={create_doarray(s,ASSIGNARRAY);} | |
259 | |
260 primary expression | |
261 -> number:n =create_pushdbl(n); | |
262 -> function | |
263 -> SYMBOL:s =create_pushdblsym(s); | |
264 -> SYMBOL:s, '(', !pushcounter();, | |
265 indexlist, ')' ={create_doarray(s,CALLARRAY);} | |
266 -> '(', expression, ')' | |
267 -> '-', primary expression /* 1ef4:fa2arec <֠ */ ={create_negate();} | |
268 | |
269 exponential expression | |
270 -> primary expression | |
271 -> exponential expression, '^', primary expression ={create_dblbin('^');} | |
272 | |
273 multiplicative expression | |
274 -> exponential expression | |
275 -> multiplicative expression, '*', exponential expression ={create_dblbin('*');} | |
276 -> multiplicative expression, '/', exponential expression ={create_dblbin('/');} | |
277 | |
278 expression | |
279 -> multiplicative expression | |
280 -> expression, '+', multiplicative expression ={create_dblbin('+');} | |
281 -> expression, '-', multiplicative expression ={create_dblbin('-');} | |
282 | |
283 /* | |
284 -> expression, '+', expression ={create_dblbin('+');} | |
285 -> expression, '-', expression ={create_dblbin('-');} | |
286 -> expression, '*', expression ={create_dblbin('*');} | |
287 -> expression, '/', expression ={create_dblbin('/');} | |
288 -> expression, '^', expression ={create_dblbin('^');} | |
289 -> '-', expression /* 1ef4:fa2arec <֠ * / ={create_negate();} | |
290 */ | |
291 | |
292 mapping | |
293 -> expression, ',', expression | |
294 -> "MAP", '(', expression, ',', expression, ')' ={create_map();} | |
295 | |
296 function | |
297 -> "SIN", '(', expression, ')' ={create_function(MYSIN);} | |
298 -> "ASIN", '(', expression, ')' ={create_function(MYASIN);} | |
299 -> "COS", '(', expression, ')' ={create_function(MYCOS);} | |
300 -> "ACOS", '(', expression, ')' ={create_function(MYACOS);} | |
301 -> "TAN", '(', expression, ')' ={create_function(MYTAN);} | |
302 -> "ATAN", '(', expression, ')' ={create_function(MYATAN);} | |
303 -> "ATAN", '(', expression, ',', expression, ')' ={create_function(MYATAN2);} | |
304 -> "EXP", '(', expression, ')' ={create_function(MYEXP);} | |
305 -> "LOG", '(', expression, ')' ={create_function(MYLOG);} | |
306 -> "SQRT", '(', expression, ')' ={create_function(MYSQRT);} | |
307 -> "INT", '(', expression, ')' ={create_function(MYINT);} | |
308 -> "FRAC", '(', expression, ')' ={create_function(MYFRAC);} | |
309 -> "MOD", '(', expression, ',', expression, ')' ={create_function(MYMOD);} | |
310 -> "RAN", '(', expression, ')' ={create_function(MYRAN);} | |
311 -> "RAN", '(', ')' ={create_function(MYRAN2);} | |
312 -> "MIN", '(', expression, ',', expression, ')' ={create_function(MYMIN);} | |
313 -> "MAX", '(', expression, ',', expression, ')' ={create_function(MYMAX);} | |
314 -> "XMAP", '(', expression, ')' ={create_function(MYXMAP);} | |
315 -> "YMAP", '(', expression, ')' ={create_function(MYYMAP);} | |
316 -> "LEN", '(', string expression, ')' ={create_function(MYLEN);} | |
317 -> "VAL", '(', string expression, ')' ={create_function(MYVAL);} | |
318 -> "ASC", '(', string expression, ')' ={create_function(MYASC);} | |
319 -> "INSTR", '(', string expression, ',', string expression, ')' ={create_function(MYINSTR);} | |
320 -> "SYSTEM2", '(', string expression, ')' ={create_function(MYSYSTEM2);} | |
321 -> "PEEK", '(', string expression, ')' ={create_function(MYPEEK);} | |
322 | |
323 (double) const | |
324 -> number:n =n; | |
325 -> '+', number:n =n; | |
326 -> '-', number:n =-n; | |
327 | |
328 /* | |
329 number | |
330 -> FNUM ={$$=$1;} | |
331 -> DIGITS ={$$=atoi($1);} | |
332 */ | |
333 | |
334 (int) intnum | |
335 -> DIGITS:d =atoi(d); | |
336 | |
337 (char *) symbol_or_lineno | |
338 -> DIGITS:s =s; | |
339 -> SYMBOL:s =s; | |
340 | |
341 dimlist | |
342 -> SYMBOL:s, '(', !{ | |
343 pushcounter();}, | |
344 indexlist, ')' ={create_dim(s,'d');} | |
345 -> dimlist, ',', SYMBOL:s, '(', !{ | |
346 pushcounter();}, | |
347 indexlist, ')' ={create_dim(s,'d');} | |
348 -> STRSYM:s, '(', !{ | |
349 pushcounter();}, | |
350 indexlist, ')' ={create_dim(s,'s');} | |
351 -> dimlist, ',', STRSYM:s, '(', !{ | |
352 pushcounter();}, | |
353 indexlist, ')' ={create_dim(s,'s');} | |
354 | |
355 indexlist | |
356 -> expression ={inccounter();} | |
357 -> indexlist, ',', expression ={inccounter();} | |
358 | |
359 for_loop | |
360 -> "FOR", SYMBOL:s, '=', expression, !{ | |
361 pushname(s);create_popdblsym(s);pushgoto(); | |
362 create_pushdblsym(s);}, | |
363 "TO", expression, step_part:p, !{ | |
364 | |
365 create_dblrelop((p>0)?'{':'}'); | |
366 create_decide(); | |
367 pushlabel();}, | |
368 /* | |
369 SEP, !{ | |
370 yylineno+=$10;}, | |
371 */ SEP, | |
372 statement list, !{ | |
373 create_pushdbl(p); | |
374 create_pushdblsym(s); | |
375 create_dblbin('+'); | |
376 create_popdblsym(s); | |
377 swap();popgoto();poplabel();}, | |
378 next_or_eofile, next_symbol ={/* cookie*/} | |
379 | |
380 next_or_eofile | |
381 -> "NEXT" | |
382 -> eof ={end_of_file=TRUE; | |
383 error(ERROR,"'next'-statement is missing"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;} | |
384 | |
385 (double) step_part | |
386 -> /* can be omitted */ =1.0; | |
387 -> "STEP", const:v =v; | |
388 | |
389 next_symbol | |
390 -> /* can be omitted */ ={pop();} | |
391 -> SYMBOL:s ={if (strcmp(pop()->pointer,s)) | |
392 {error(ERROR,"'for' and 'next' do not match"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;} | |
393 } | |
394 | |
395 if_clause | |
396 -> "IF", condition, !{ | |
397 create_decide();pushlabel();}, | |
398 "THEN", statement list, !{ | |
399 pushlabel();swap();poplabel();}, | |
400 else_part, !{ | |
401 poplabel();}, | |
402 endif_or_eof | |
403 | |
404 endif_or_eof | |
405 -> "ENDIF" | |
406 -> eof ={end_of_file=TRUE; | |
407 error(ERROR,"'endif'-statement is missing"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;} | |
408 /* | |
409 condition | |
410 -> '(', condition, ')' | |
411 -> condition, "OR", condition ={create_boole('|');} | |
412 -> "NOT", condition ={create_boole('!');} | |
413 */ | |
414 | |
415 condition | |
416 -> and condition | |
417 -> condition, "OR", and condition ={create_boole('|');} | |
418 | |
419 | |
420 and condition | |
421 -> primary condition | |
422 -> and condition, "AND", primary condition ={create_boole('&');} | |
423 | |
424 primary condition | |
425 -> comparison | |
426 -> '(', condition, ')' | |
427 -> "NOT", primary condition | |
428 | |
429 comparison | |
430 -> string expression, '=', string expression ={create_strrelop('=');} | |
431 -> string expression, "<>", string expression ={create_strrelop('!');} | |
432 -> string expression, '<', string expression ={create_strrelop('<');} | |
433 -> string expression, "<=", string expression ={create_strrelop('{');} | |
434 -> string expression, '>', string expression ={create_strrelop('>');} | |
435 -> string expression, ">=", string expression ={create_strrelop('}');} | |
436 -> expression, '=', expression ={create_dblrelop('=');} | |
437 -> expression, "<>", expression ={create_dblrelop('!');} | |
438 -> expression, '<', expression ={create_dblrelop('<');} | |
439 -> expression, "<=", expression ={create_dblrelop('{');} | |
440 -> expression, '>', expression ={create_dblrelop('>');} | |
441 -> expression, ">=", expression ={create_dblrelop('}');} | |
442 //-> MYEOF, '(', hashed_number, ')' ={create_testeof($3);} | |
443 | |
444 else_part /* can be omitted */ | |
445 -> | |
446 -> "ELSE", statement list | |
447 | |
448 inputlist | |
449 -> input | |
450 -> input, ',', inputlist | |
451 | |
452 input | |
453 -> SYMBOL:s ={create_myread('d');create_popdblsym(s);} | |
454 -> SYMBOL:s, '(', !{ | |
455 pushcounter();}, | |
456 indexlist, ')' ={create_myread('d');create_doarray(s,ASSIGNARRAY);} | |
457 -> STRSYM:s ={create_myread('s');create_popstrsym(s);} | |
458 -> STRSYM:s, '(', !{ | |
459 pushcounter();}, | |
460 indexlist, ')' ={create_myread('s');create_doarray(s,ASSIGNSTRINGARRAY);} | |
461 | |
462 readlist | |
463 -> readitem | |
464 -> readlist, ',', readitem | |
465 | |
466 readitem | |
467 -> SYMBOL:s ={create_readdata('d');create_popdblsym(s);} | |
468 -> SYMBOL:s, '(', !{ | |
469 pushcounter();}, | |
470 indexlist, ')' ={create_readdata('d');create_doarray(s,ASSIGNARRAY);} | |
471 -> STRSYM:s ={create_readdata('s');create_popstrsym(s);} | |
472 -> STRSYM:s, '(', !{ | |
473 pushcounter();}, | |
474 indexlist, ')' ={create_readdata('s');create_doarray(s,ASSIGNSTRINGARRAY);} | |
475 | |
476 datalist | |
477 -> STRING:s ={create_strdata(s);} | |
478 -> const:v ={create_dbldata(v);} | |
479 -> datalist, ',', STRING:s ={create_strdata(s);} | |
480 -> datalist, ',', const:v ={create_dbldata(v);} | |
481 | |
482 printlist /* possible empty */ | |
483 -> | |
484 -> expression ={create_print('d');} | |
485 -> printlist, ',', expression ={create_print('d');} | |
486 -> string expression ={create_print('s');} | |
487 -> printlist, ',', string expression ={create_print('s');} | |
488 | |
489 inputintro | |
490 -> ={create_myswitch(0);create_readline(NULL);} | |
491 -> stream | |
492 -> position ={create_myswitch(0);create_readline(NULL);} | |
493 -> !{ | |
494 create_myswitch(0);}, | |
495 prompt | |
496 -> position, !{ | |
497 create_myswitch(0);}, | |
498 prompt | |
499 | |
500 printintro | |
501 -> /* can be empty */ ={create_myswitch(0);} | |
502 -> stream | |
503 -> "REVERSE" ={create_revert(TRUE);create_myswitch(0);} | |
504 -> position ={create_myswitch(0);} | |
505 -> "REVERSE", position ={create_revert(TRUE);create_myswitch(0);} | |
506 | |
507 prompt | |
508 -> STRING:s ={create_readline(s);} | |
509 | |
510 position | |
511 -> "AT", '(', expression, ',', expression, ')' ={create_mymove();} | |
512 | |
513 stream | |
514 -> '#', intnum:n ={create_myswitch(n);} | |
515 | |
516 (int) hashed_number | |
517 -> '#', intnum:n =n; | |
518 -> intnum:n /* need not contain hash */ =n; | |
519 | |
520 semicolon /* can be left out */ | |
521 -> ={create_print('n');} | |
522 -> ';' | |
523 | |
524 goto_list | |
525 -> symbol_or_lineno:s ={create_goto(s);create_findnop();} | |
526 -> goto_list, ',', symbol_or_lineno:s ={create_goto(s);create_findnop();} | |
527 | |
528 gosub_list | |
529 -> symbol_or_lineno:s ={create_gosub(s);create_findnop();} | |
530 -> gosub_list, ',', symbol_or_lineno:s ={create_gosub(s);create_findnop();} | |
531 | |
532 { | |
533 #define CHAR_STACK_LENGTH 500 | |
534 | |
535 static char charStack[CHAR_STACK_LENGTH+1]; | |
536 static char *charStackTop = charStack; | |
537 | |
538 /* Define an error record */ | |
539 typedef struct { | |
540 char *message; /* identifies error */ | |
541 int line; /* location of error */ | |
542 int column; | |
543 } ErrorRecord; | |
544 | |
545 ErrorRecord errorRecord; /* define an error record */ | |
546 | |
547 void diagnoseError(char *msg) { | |
548 if (parseBasic_pcb.exit_flag == AG_RUNNING_CODE) | |
549 parseBasic_pcb.exit_flag = AG_SEMANTIC_ERROR_CODE; /* stop parse */ | |
550 errorRecord.message = msg; | |
551 errorRecord.line = parseBasic_pcb.line; | |
552 errorRecord.column = parseBasic_pcb.column; | |
553 } | |
554 | |
555 void pushChar(int c) { /* append char to name string */ | |
556 if (charStackTop < charStack+CHAR_STACK_LENGTH) { | |
557 *charStackTop++ = (char) c; | |
558 return; | |
559 } | |
560 /* buffer overflow, kill parse and issue diagnostic */ | |
561 diagnoseError("Character Stack Overflow"); | |
562 } | |
563 | |
564 static char *popString(int nChars) { /* get string */ | |
565 *charStackTop = 0; | |
566 return charStackTop -= nChars; | |
567 } | |
568 | |
569 FILE *parserInputFile; | |
570 void switch_to_my_file(FILE *inputfile) /* switches lex input to given file */ | |
571 { | |
572 parserInputFile = inputfile; | |
573 return; | |
574 } | |
575 | |
576 #define GET_INPUT ((PCB).input_code = fgetc(parserInputFile)) | |
577 | |
578 int yyparse() { | |
579 parseBasic(); | |
580 return !(PCB.exit_flag == AG_SUCCESS_CODE); | |
581 } | |
582 | |
583 | |
584 } |