Fetch Flex from Sourceforge.
[AROS-Contrib.git] / regina / yaccsrc.y
blob19d9d446bc799495c81142ab69be2ec77f1bbd39
1 %{
3 #ifndef lint
4 static char *RCSid = "$Id$";
5 #endif
7 /*
8 * The Regina Rexx Interpreter
9 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details.
21 * You should have received a copy of the GNU Library General Public
22 * License along with this library; if not, write to the Free
23 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <time.h>
27 #include "rexx.h"
29 #if defined(HAVE_MALLOC_H)
30 # include <malloc.h>
31 #endif
33 #if defined(HAVE_ALLOCA_H)
34 # include <alloca.h>
35 #endif
37 #include <ctype.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <assert.h>
43 #if defined(_MSC_VER) || defined(MAC)
44 # define __STDC__ 1 /* Hack to allow const since it is not defined */
45 #endif
47 #define YYSTYPE nodeptr
49 /* locals, they are protected by regina_parser (see lexsrc.l) */
50 static int tmplno, tmpchr ;
51 static nodeptr current, with = NULL ;
52 #if 0 /* see below */
53 static nodeptr *narray=NULL ;
54 static int narptr=0, narmax=0 ;
55 #endif
57 static int gettypeof( nodeptr this ) ;
58 static void checkconst( nodeptr this ) ;
59 static void transform( nodeptr this ) ;
60 static nodeptr create_head( const char *name ) ;
61 static nodeptr makenode( int type, int numb, ... ) ;
62 static void checkdosyntax( cnodeptr this ) ;
63 void newlabel( const tsd_t *TSD, internal_parser_type *ipt, nodeptr this ) ;
67 %token ADDRESS ARG CALL DO TO BY FOR WHILE UNTIL EXIT IF THEN ELSE
68 %token ITERATE INTERPRET LEAVE NOP NUMERIC PARSE EXTERNAL SOURCE VAR
69 %token VALUE WITH PROCEDURE EXPOSE PULL PUSH QUEUE SAY RETURN SELECT
70 %token WHEN DROP OTHERWISE SIGNAL ON OFF ERROR SYNTAX HALT NOVALUE
71 %token TRACE END UPPER ASSIGNMENTVARIABLE STATSEP FOREVER DIGITS FORM
72 %token FUZZ SCIENTIFIC ENGINEERING NOT CONCATENATE MODULUS GTE GT LTE
73 %token LT DIFFERENT EQUALEQUAL NOTEQUALEQUAL OFFSET SPACE EXP XOR
74 %token PLACEHOLDER NOTREADY CONSYMBOL SIMSYMBOL EXFUNCNAME INFUNCNAME
75 %token LABEL DOVARIABLE HEXSTRING STRING VERSION LINEIN WHATEVER NAME
76 %token FAILURE BINSTRING OPTIONS ENVIRONMENT LOSTDIGITS
77 %token GTGT LTLT NOTGTGT NOTLTLT GTGTE LTLTE
78 %token INPUT OUTPUT ERROR NORMAL APPEND REPLACE STREAM STEM LIFO FIFO
80 %start prog
82 %left '|' XOR
83 %left '&'
84 %nonassoc '=' DIFFERENT GTE GT LT LTE EQUALEQUAL NOTEQUALEQUAL GTGT LTLT NOTGTGT NOTLTLT GTGTE LTLTE
85 %left CONCATENATE SPACE CCAT
86 %left '+' '-'
87 %left '*' '/' '%' MODULUS
88 %left EXP
89 %left UMINUS UPLUSS NOT
90 %nonassoc SYNTOP
92 %nonassoc THEN
93 %nonassoc ELSE
95 %right STATSEP
98 #ifdef NDEBUG
99 # define YYDEBUG 0
100 #else
101 # define YYDEBUG 1
102 #endif
107 prog : nseps stats { EndProg( $2 ) ; }
108 | nseps { EndProg( NULL ) ; }
111 stats : ystatement stats { $$->next = $2 ; }
112 | ystatement { $$->next = NULL ; }
115 xstats : statement xstats { $$->next = $2 ; }
116 | statement gruff { $$->next = NULL ; }
119 ystatement : statement { $$ = $1 ; }
120 | lonely_end { exiterror( ERR_UNMATCHED_END, 1 ) ; }
123 lonely_end : gruff end seps
126 nxstats : xstats { $$ = $1 ; }
127 | gruff { $$ = NULL ; }
130 nseps : seps
134 seps : STATSEP seps
135 | STATSEP
138 statement : mstatement { $$=$1; }
139 | ex_when_stat { $$=$1; }
142 mstatement : mttstatement { $$=$1; }
143 | unexp_then { $$=$1; }
146 gruff : { tmpchr=parser_data.tstart; tmplno=parser_data.tline; }
149 mttstatement : gruff mtstatement { $$=$2; }
152 mtstatement : address_stat
153 | expr_stat
154 | arg_stat
155 | call_stat
156 | do_stat
157 | drop_stat
158 | exit_stat
159 | if_stat
160 | unexp_else
161 | ipret_stat
162 | iterate_stat
163 | label_stat
164 | leave_stat
165 | nop_stat
166 | numeric_stat
167 | options_stat
168 | parse_stat
169 | proc_stat
170 | pull_stat
171 | push_stat
172 | queue_stat
173 | return_stat
174 | say_stat
175 | select_stat
176 | signal_stat
177 | trace_stat
178 | upper_stat
179 | assignment
182 call : CALL { $$ = makenode(X_CALL,0) ;
183 $$->lineno = parser_data.tline ;
184 $$->charnr = parser_data.tstart ; } ;
185 do : DO { $$ = makenode(X_DO,0) ;
186 $$->lineno = parser_data.tline ;
187 $$->charnr = parser_data.tstart ; } ;
188 exit : EXIT { $$ = makenode(X_EXIT,0) ;
189 $$->lineno = parser_data.tline ;
190 $$->charnr = parser_data.tstart ; } ;
191 if : IF { $$ = makenode(X_IF,0) ;
192 $$->lineno = parser_data.tline ;
193 $$->charnr = parser_data.tstart ; } ;
194 iterate : ITERATE { $$ = makenode(X_ITERATE,0) ;
195 $$->lineno = parser_data.tline ;
196 $$->charnr = parser_data.tstart ; } ;
197 leave : LEAVE { $$ = makenode(X_LEAVE,0) ;
198 $$->lineno = parser_data.tline ;
199 $$->charnr = parser_data.tstart ; } ;
200 say : SAY { $$ = makenode(X_SAY,0) ;
201 $$->lineno = parser_data.tline ;
202 $$->charnr = parser_data.tstart ; } ;
203 return : RETURN { $$ = makenode(X_RETURN,0) ;
204 $$->lineno = parser_data.tline ;
205 $$->charnr = parser_data.tstart ; } ;
206 address : ADDRESS { $$ = makenode(X_ADDR_N,0) ;
207 $$->lineno = parser_data.tline ;
208 $$->charnr = parser_data.tstart ; } ;
209 arg : ARG { $$ = makenode(X_PARSE_ARG_U,0) ;
210 $$->lineno = parser_data.tline ;
211 $$->charnr = parser_data.tstart ; } ;
212 drop : DROP { $$ = makenode(X_DROP,0) ;
213 $$->lineno = parser_data.tline ;
214 $$->charnr = parser_data.tstart ; } ;
215 interpret : INTERPRET { $$ = makenode(X_IPRET,0) ;
216 $$->lineno = parser_data.tline ;
217 $$->charnr = parser_data.tstart ; } ;
218 label : LABEL { $$ = makenode(X_LABEL,0) ;
219 $$->lineno = parser_data.tline ;
220 $$->charnr = parser_data.tstart ; } ;
221 nop : NOP { $$ = makenode(X_NULL,0) ;
222 $$->lineno = parser_data.tline ;
223 $$->charnr = parser_data.tstart ; }
224 numeric : NUMERIC { $$ = makenode(0,0) ;
225 $$->lineno = parser_data.tline ;
226 $$->charnr = parser_data.tstart ; } ;
227 options : OPTIONS { $$ = makenode(X_OPTIONS,0) ;
228 $$->lineno = parser_data.tline ;
229 $$->charnr = parser_data.tstart ; } ;
230 parse : PARSE { $$ = makenode(0,0) ;
231 $$->lineno = parser_data.tline ;
232 $$->charnr = parser_data.tstart ; } ;
233 proc : PROCEDURE { $$ = makenode(X_PROC,0) ;
234 $$->lineno = parser_data.tline ;
235 $$->charnr = parser_data.tstart ; } ;
236 pull : PULL { $$ = makenode(X_PULL,0) ;
237 $$->lineno = parser_data.tline ;
238 $$->charnr = parser_data.tstart ; } ;
239 push : PUSH { $$ = makenode(X_PUSH,0) ;
240 $$->lineno = parser_data.tline ;
241 $$->charnr = parser_data.tstart ; } ;
242 queue : QUEUE { $$ = makenode(X_QUEUE,0) ;
243 $$->lineno = parser_data.tline ;
244 $$->charnr = parser_data.tstart ; } ;
245 select : SELECT { $$ = makenode(X_SELECT,0) ;
246 $$->lineno = parser_data.tline ;
247 $$->charnr = parser_data.tstart ; } ;
248 signal : SIGNAL { $$ = makenode(X_SIG_LAB,0) ;
249 $$->lineno = parser_data.tline ;
250 $$->charnr = parser_data.tstart ; } ;
251 when : WHEN { $$ = makenode(X_WHEN,0) ;
252 $$->lineno = parser_data.tline ;
253 $$->charnr = parser_data.tstart ; } ;
254 otherwise : OTHERWISE { $$ = makenode(X_OTHERWISE,0) ;
255 $$->lineno = parser_data.tline ;
256 $$->charnr = parser_data.tstart ; } ;
257 trace : TRACE { $$ = makenode(X_TRACE,0) ;
258 $$->lineno = parser_data.tline ;
259 $$->charnr = parser_data.tstart ; } ;
260 upper : UPPER { $$ = makenode(X_UPPER_VAR,0) ;
261 $$->lineno = parser_data.tline ;
262 $$->charnr = parser_data.tstart ; } ;
263 address_stat : address { $$ = current = $1 ; }
264 address_stat2
267 address_stat2: VALUE expr naddr_with { current->type = X_ADDR_V ;
268 current->p[0] = $2 ;
269 current->p[1] = $3 ; }
270 | addr_with { exiterror( ERR_STRING_EXPECTED, 1, __reginatext ) ;}
271 | seps { current->type = X_ADDR_S ; }
272 | error { exiterror( ERR_STRING_EXPECTED, 1, __reginatext ) ;}
273 naddr_with
274 | nvir nexpr naddr_with { current->name = (streng *)$1 ;
275 current->type = X_ADDR_N ;
276 current->p[0] = $2 ;
277 current->p[1] = $3 ; }
278 | '(' expr ')' nspace naddr_with { current->type = X_ADDR_V ;
279 current->p[0] = $2 ;
280 current->p[1] = $5 ;
281 current->u.nonansi = 1 ; }
284 arg_stat : arg templs seps { $$ = $1 ;
285 $$->p[0] = $2 ; }
288 call_stat : call asymbol exprs seps { $$ = $1 ;
289 $$->p[0] = $3 ;
290 $$->name = (streng *) $2 ; }
291 | call string exprs seps { $$ = $1 ;
292 $$->type = X_EX_FUNC ;
293 $$->p[0] = $3 ;
294 $$->name = (streng *) $2 ; }
295 | call function seps { $$ = $1 ;
296 $$->name = $2->name ;
297 $$->p[0] = $2->p[0] ;
298 RejectNode( $2 ); }
299 | call on error { exiterror( ERR_INV_SUBKEYWORD, 1, "ERROR FAILURE HALT NOTREADY", __reginatext ) ;}
300 seps
301 | call off error { exiterror( ERR_INV_SUBKEYWORD, 2, "ERROR FAILURE HALT NOTREADY", __reginatext ) ;}
302 seps
303 | call on c_action error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
304 seps
305 | call on c_action namespec error { exiterror( ERR_STRING_EXPECTED, 3, __reginatext ) ;}
306 seps
307 | call on c_action namespec seps
308 { $$ = $1 ;
309 $$->type = X_CALL_SET ;
310 $$->p[0] = $2 ;
311 $$->name = (streng *)$4 ;
312 $$->p[1] = $3 ; }
313 | call on c_action seps { $$ = $1 ;
314 $$->type = X_CALL_SET ;
315 $$->p[0] = $2 ;
316 $$->name = NULL ;
317 $$->p[1] = $3 ; }
318 | call off c_action error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
319 seps
320 | call off c_action seps { $$ = $1 ;
321 $$->type = X_CALL_SET ;
322 $$->p[0] = $2 ;
323 $$->p[1] = $3 ; }
326 expr_stat : expr seps
327 { $$ = makenode(X_COMMAND,0) ;
328 $$->charnr = tmpchr ;
329 $$->lineno = tmplno;
330 $$->p[0] = $1 ; }
333 end_stat : END { $$ = makenode(X_END,0) ;
334 $$->lineno = parser_data.tline ;
335 $$->charnr = parser_data.tstart ; }
338 end : end_stat simsymb { $$ = $1 ;
339 $$->name = (streng*)($2) ; }
340 | end_stat { $$ = $1 ; }
341 | end_stat simsymb error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
344 do_stat : do repetitor conditional seps nxstats end seps
345 { $$ = $1 ;
346 $$->p[0] = $2 ;
347 $$->p[1] = $3 ;
348 $$->p[2] = $5 ;
349 $$->p[3] = $6 ;
350 if (($$->p[0]==NULL || $$->p[0]->name==NULL)
351 && $$->p[3]->name)
352 exiterror( ERR_UNMATCHED_END, 0 ) ;
353 if (($$->p[0])&&($$->p[0]->name)&&
354 ($$->p[3]->name)&&
355 (($$->p[3]->name->len != $$->p[0]->name->len)||
356 (strncmp($$->p[3]->name->value,
357 $$->p[0]->name->value,
358 $$->p[0]->name->len))))
359 exiterror( ERR_UNMATCHED_END, 0 ) ;
363 repetitor : dovar '=' expr tobyfor tobyfor tobyfor
364 { $$ =makenode(X_REP,4,$3,$4,$5,$6) ;
365 $$->name = (streng *)$1 ;
366 checkdosyntax($$) ; }
367 | dovar '=' expr tobyfor tobyfor
368 { $$ =makenode(X_REP,3,$3,$4,$5) ;
369 $$->name = (streng *)$1 ;
370 checkdosyntax($$) ; }
371 | dovar '=' expr tobyfor { $$ =makenode(X_REP,2,$3,$4) ;
372 $$->name = (streng *)$1 ;
373 checkdosyntax($$) ; }
374 | dovar '=' expr { $$ =makenode(X_REP,1,$3) ;
375 $$->name = (streng *)$1 ;
376 checkdosyntax($$) ; }
377 | FOREVER { $$ = makenode(X_REP_FOREVER,0) ; }
378 | FOREVER error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
379 seps
380 | expr { $1 = makenode(X_DO_EXPR,1,$1) ;
381 $$ = makenode(X_REP,2,NULL,$1) ; }
382 | { $$ = NULL ; }
385 nvir : CONSYMBOL { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
386 | SIMSYMBOL { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
387 | STRING { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
390 naddr_with : { SymbolDetect |= SD_ADDRWITH ;
391 $$ = with = makenode(X_ADDR_WITH,0) ;
392 $$->lineno = parser_data.tline ;
393 $$->charnr = parser_data.tstart ; }
394 addr_with { with = NULL ;
395 SymbolDetect &= ~SD_ADDRWITH ; }
396 | seps { $$ = NULL ; }
399 addr_with : WITH connection seps { $$ = $2 ; /* pro forma */ }
400 | WITH connection error seps { exiterror( ERR_INV_SUBKEYWORD, 5, __reginatext ) ; }
401 | WITH nspace seps { exiterror( ERR_INV_SUBKEYWORD, 5, __reginatext ) ; }
404 connection : inputstmts
405 | outputstmts
406 | errorstmts
407 | error { exiterror( ERR_INV_SUBKEYWORD, 5, __reginatext ) ; }
410 inputstmts : inputstmt
411 adeo
414 outputstmts : outputstmt
415 adei
418 errorstmts : errorstmt
419 adio
422 adeo : outputstmt nspace
423 | outputstmt errorstmt nspace
424 | errorstmt nspace
425 | errorstmt outputstmt nspace
426 | nspace
429 adei : inputstmt nspace
430 | inputstmt errorstmt nspace
431 | errorstmt nspace
432 | errorstmt inputstmt nspace
433 | nspace
436 adio : inputstmt nspace
437 | inputstmt outputstmt nspace
438 | outputstmt nspace
439 | outputstmt inputstmt nspace
440 | nspace
443 inputstmt : nspace INPUT nspace resourcei { with->p[0] = $4; }
444 | nspace INPUT error { exiterror( ERR_INV_SUBKEYWORD, 6, __reginatext ) ; }
447 outputstmt : nspace OUTPUT nspace resourceo { with->p[1] = $4; }
448 | nspace OUTPUT error { exiterror( ERR_INV_SUBKEYWORD, 7, __reginatext ) ; }
451 errorstmt : nspace ERROR nspace resourceo { with->p[2] = $4; }
452 | nspace ERROR error { exiterror( ERR_INV_SUBKEYWORD, 14, __reginatext ) ; }
455 resourcei : resources { $$ = $1 ; }
456 | NORMAL { $$ = makenode(X_ADDR_WITH, 0) ;
457 $$->lineno = parser_data.tline ;
458 $$->charnr = parser_data.tstart ; }
461 resourceo : resources { $$ = $1 ; }
462 | APPEND resources { $$ = $2 ;
463 $$->u.of.append = 1 ; }
464 | APPEND error { exiterror( ERR_INV_SUBKEYWORD, 8, __reginatext ) ; }
465 | REPLACE resources { $$ = $2 ; }
466 | REPLACE error { exiterror( ERR_INV_SUBKEYWORD, 9, __reginatext ) ; }
467 | NORMAL { $$ = makenode(X_ADDR_WITH, 0) ;
468 $$->lineno = parser_data.tline ;
469 $$->charnr = parser_data.tstart ; }
472 resources : STREAM nnvir { /* ANSI extension: nsimsymb is
473 * used by the standard, but I think
474 * there are no reasons why using
475 * it here as a must. FGC
477 $$ = makenode(X_ADDR_WITH, 0) ;
478 $$->name = (streng *) $2 ;
479 $$->lineno = parser_data.tline ;
480 $$->charnr = parser_data.tstart ;
481 $$->u.of.awt = isSTREAM;
482 SymbolDetect |= SD_ADDRWITH ; }
483 | STREAM error { exiterror( ERR_INVALID_OPTION, 1, __reginatext ) ; }
484 | STEM nsimsymb {
485 streng *tmp=(streng *)$2;
486 if ( tmp->value[(tmp->len)-1] != '.' )
487 exiterror( ERR_INVALID_OPTION, 3, __reginatext );
488 $$ = makenode(X_ADDR_WITH, 0, 0) ;
489 $$->name = (streng *) $2 ;
490 $$->lineno = parser_data.tline ;
491 $$->charnr = parser_data.tstart ;
492 $$->u.of.awt = isSTEM;
493 SymbolDetect |= SD_ADDRWITH ; }
494 | STEM error { exiterror( ERR_INVALID_OPTION, 2, __reginatext ) ; }
495 | LIFO nnvir {
496 $$ = makenode(X_ADDR_WITH, 0) ;
497 $$->name = (streng *) $2 ;
498 $$->lineno = parser_data.tline ;
499 $$->charnr = parser_data.tstart ;
500 $$->u.of.awt = isLIFO;
501 SymbolDetect |= SD_ADDRWITH ; }
502 | LIFO error { exiterror( ERR_INVALID_OPTION, 100, __reginatext ) ; }
503 | FIFO nnvir {
504 $$ = makenode(X_ADDR_WITH, 0) ;
505 $$->name = (streng *) $2 ;
506 $$->lineno = parser_data.tline ;
507 $$->charnr = parser_data.tstart ;
508 $$->u.of.awt = isFIFO;
509 SymbolDetect |= SD_ADDRWITH ; }
510 | FIFO error { exiterror( ERR_INVALID_OPTION, 101, __reginatext ) ; }
513 nsimsymb : { SymbolDetect &= ~SD_ADDRWITH ; }
514 nspace xsimsymb { $$ = $3 ; }
517 nnvir : { SymbolDetect &= ~SD_ADDRWITH ; }
518 nspace nvir { $$ = $3 ; }
521 nspace : SPACE
525 dovar : DOVARIABLE { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
528 tobyfor : TO expr { $$ = makenode(X_DO_TO,1,$2) ; }
529 | FOR expr { $$ = makenode(X_DO_FOR,1,$2) ; }
530 | BY expr { $$ = makenode(X_DO_BY,1,$2) ; }
533 conditional : WHILE expr { $$ = makenode(X_WHILE,1,$2) ; }
534 | UNTIL expr { $$ = makenode(X_UNTIL,1,$2) ; }
535 | { $$ = NULL ; }
538 drop_stat : drop anyvars error { exiterror( ERR_SYMBOL_EXPECTED, 1, __reginatext ) ;}
539 | drop anyvars seps { $$ = $1 ;
540 $$->p[0] = $2 ; }
543 upper_stat : upper anyvars error { exiterror( ERR_SYMBOL_EXPECTED, 1, __reginatext ) ;}
544 | upper anyvars seps { $$ = $1 ;
545 $$->p[0] = $2 ; }
548 exit_stat : exit nexpr seps { $$ = $1 ;
549 $$->p[0] = $2 ; }
552 if_stat : if expr nseps THEN nseps ystatement
553 { $$ = $1 ;
554 $$->p[0] = $2 ;
555 $$->p[1] = $6 ; }
556 | if expr nseps THEN nseps ystatement ELSE nseps ystatement
557 { $$ = $1 ;
558 $$->p[0] = $2 ;
559 $$->p[1] = $6 ;
560 $$->p[2] = $9 ; }
561 | if expr nseps THEN nseps ystatement ELSE nseps error
562 { exiterror( ERR_INCOMPLETE_STRUCT, 4 ) ;}
563 | if expr nseps THEN nseps error
564 { exiterror( ERR_INCOMPLETE_STRUCT, 3 ) ;}
565 | if seps { exiterror( ERR_INCOMPLETE_STRUCT, 0 ) ;}
566 | if expr nseps error { exiterror( ERR_THEN_EXPECTED, 1, parser_data.if_linenr, __reginatext ) ; }
569 unexp_then : gruff THEN { exiterror( ERR_THEN_UNEXPECTED, 1 ) ; }
572 unexp_else : gruff ELSE { exiterror( ERR_THEN_UNEXPECTED, 2 ) ; }
575 ipret_stat : interpret expr seps { $$ = $1 ;
576 $$->p[0] = $2 ; }
580 iterate_stat : iterate simsymb seps { $$ = $1 ;
581 $$->name = (streng *) $2 ; }
582 | iterate simsymb error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
583 seps
584 | iterate seps { $$ = $1 ; }
587 label_stat : labelname nseps { $$ = $1 ;
588 newlabel( (const tsd_t *)parser_data.TSD,
589 &parser_data,
590 $1 ) ; }
593 labelname : label { $$ = $1 ;
594 $$->name = Str_cre_TSD(parser_data.TSD,retvalue) ; }
597 leave_stat : leave simsymb seps { $$ = $1 ;
598 $$->name = (streng *) $2 ; }
599 | leave simsymb error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
600 seps
601 | leave seps { $$ = $1 ; }
604 nop_stat : nop seps { $$ = $1 ; }
605 | nop error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
606 seps
609 numeric_stat : numeric DIGITS expr seps { $$ = $1 ;
610 $$->type = X_NUM_D ;
611 $$->p[0] = $3 ; }
612 | numeric DIGITS seps { $$ = $1; $$->type = X_NUM_DDEF ; }
613 | numeric FORM form_expr error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
614 seps
615 | numeric FORM form_expr seps
616 { $$ = $1 ;
617 $$->type = X_NUM_F ;
618 $$->p[0] = $3 ; }
619 | numeric FORM seps { /* NOTE! This clashes ANSI! */
620 $$ = $1 ; $$->type=X_NUM_FRMDEF ;}
621 | numeric FORM VALUE expr seps { $$ = $1 ; $$->type=X_NUM_V ;
622 $$->p[0] = $4 ; }
623 | numeric FORM error { exiterror( ERR_INV_SUBKEYWORD, 11, "ENGINEERING SCIENTIFIC", __reginatext ) ;}
624 seps
625 | numeric FUZZ seps { $$ = $1; $$->type = X_NUM_FDEF ;}
626 | numeric FUZZ expr seps { $$ = $1 ;
627 $$->type = X_NUM_FUZZ ;
628 $$->p[0] = $3 ; }
629 | numeric error { exiterror( ERR_INV_SUBKEYWORD, 15, "DIGITS FORM FUZZ", __reginatext ) ;}
630 seps
633 form_expr : SCIENTIFIC { $$ = makenode(X_NUM_SCI,0) ; }
634 | ENGINEERING { $$ = makenode(X_NUM_ENG,0) ; }
637 options_stat : options nexpr seps { ($$=$1)->p[0]=$2 ; }
640 parse_stat : parse parse_param template seps
641 { $$ = $1 ;
642 $$->type = X_PARSE ;
643 $$->p[0] = $2 ;
644 $$->p[1] = $3 ; }
645 | parse UPPER parse_param template seps
646 { $$ = $1 ;
647 $$->type = X_PARSE_U ;
648 $$->p[0] = $3 ;
649 $$->p[1] = $4 ; }
650 | parse ARG templs seps { $$ = $1 ;
651 $$->type = X_PARSE_ARG ;
652 $$->p[0] = $3 ; }
653 | parse UPPER ARG templs seps
654 { $$ = $1 ;
655 $$->type = X_PARSE_ARG_U ;
656 $$->p[0] = $4 ; }
657 | parse UPPER error { exiterror( ERR_INV_SUBKEYWORD, 13, "ARG EXTERNAL LINEIN PULL SOURCE UPPER VAR VALUE VERSION", __reginatext ) ;}
658 | parse error { exiterror( ERR_INV_SUBKEYWORD, 12, "ARG EXTERNAL LINEIN PULL SOURCE UPPER VAR VALUE VERSION", __reginatext ) ;}
659 seps
662 templs : template ',' templs { $$ = $1 ; $$->next = $3 ; }
663 | template { $$ = $1 ; }
666 parse_param : LINEIN { $$ = makenode(X_PARSE_EXT,0) ; }
667 | EXTERNAL { $$ = makenode(X_PARSE_EXT,0) ; }
668 | VERSION { $$ = makenode(X_PARSE_VER,0) ; }
669 | PULL { $$ = makenode(X_PARSE_PULL,0) ; }
670 | SOURCE { $$ = makenode(X_PARSE_SRC,0) ; }
671 | VAR simsymb { $$ = makenode(X_PARSE_VAR,0) ;
672 $$->name = (streng *) $2 ; }
673 | VALUE nexpr WITH { $$ = makenode(X_PARSE_VAL,1,$2) ; }
674 | VALUE error seps { exiterror( ERR_INVALID_TEMPLATE, 3 ) ;}
677 proc_stat : proc seps { $$ = $1 ; }
678 | proc error { exiterror( ERR_INV_SUBKEYWORD, 17, __reginatext ) ;}
679 seps
680 | proc EXPOSE error { exiterror( ERR_SYMBOL_EXPECTED, 1, __reginatext ) ;}
681 seps
682 | proc EXPOSE anyvars error { exiterror( ERR_SYMBOL_EXPECTED, 1, __reginatext ) ;}
683 seps
684 | proc EXPOSE anyvars seps { $$ = $1 ;
685 $$->p[0] = $3 ; }
688 pull_stat : pull template seps { $$ = $1 ;
689 $$->p[0] = $2 ; }
692 push_stat : push nexpr seps { $$ = $1 ;
693 $$->p[0] = $2 ; }
696 queue_stat : queue nexpr seps { $$ = $1 ;
697 $$->p[0] = $2 ; }
700 say_stat : say nexpr seps { $$ = $1 ;
701 $$->p[0] = $2 ; }
704 return_stat : return nexpr seps { $$ = $1 ;
705 $$->p[0] = $2 ; }
708 sel_end : END simsymb { exiterror( ERR_UNMATCHED_END, 0 ) ;}
709 | END simsymb error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
710 | END
713 select_stat : select seps when_stats otherwise_stat sel_end seps
714 { $$ = $1 ;
715 $$->p[0] = $3 ;
716 $$->p[1] = $4 ; }
717 | select seps END error { exiterror( ERR_WHEN_EXPECTED, 0 ) ;}
718 | select seps otherwise error
719 { exiterror( ERR_WHEN_EXPECTED, 0 ) ;}
720 | select error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
721 | select seps THEN { exiterror( ERR_THEN_UNEXPECTED, 0 ) ;}
722 | select seps when_stats otherwise error
723 { exiterror( ERR_INCOMPLETE_STRUCT, 0 ) ;}
726 when_stats : when_stat when_stats { $$->next = $2 ; }
727 | when_stat { $$ = $1 ; }
728 | error { exiterror( ERR_WHEN_EXPECTED, 0 ) ;}
731 when_stat : when expr nseps THEN nseps statement
732 { $$ = $1 ;
733 $$->p[0] = $2 ;
734 $$->p[1] = $6 ; }
735 | when expr nseps THEN nseps statement THEN
736 { exiterror( ERR_THEN_UNEXPECTED, 0 ) ;}
737 | when expr seps
738 { exiterror( ERR_THEN_EXPECTED, 2, parser_data.when_linenr, __reginatext ) ; }
739 | when error { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
742 when_or_other: when
743 | otherwise
746 ex_when_stat : gruff when_or_other { exiterror( ERR_WHEN_UNEXPECTED, 0 ) ;}
749 otherwise_stat : otherwise nseps nxstats {
750 $$ = $1 ;
751 $$->p[0] = $3 ; }
752 | { $$ = makenode(X_NO_OTHERWISE,0) ;
753 $$->lineno = parser_data.tline ;
754 $$->charnr = parser_data.tstart ; }
758 signal_stat : signal VALUE expr seps { $$ = $1 ;
759 $$->type = X_SIG_VAL ;
760 $$->p[0] = $3 ; }
761 | signal asymbol error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
762 seps
763 | signal asymbol seps { $$ = $1 ;
764 $$->name = (streng *)$2 ; }
765 | signal on error { exiterror( ERR_INV_SUBKEYWORD, 3, "ERROR FAILURE HALT NOTREADY NOVALUE SYNTAX LOSTDIGITS", __reginatext ) ;}
766 seps
767 | signal off error { exiterror( ERR_INV_SUBKEYWORD, 4, "ERROR FAILURE HALT NOTREADY NOVALUE SYNTAX LOSTDIGITS", __reginatext ) ;}
768 seps
769 | signal on s_action error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
770 seps
771 | signal on s_action namespec error { exiterror( ERR_STRING_EXPECTED, 3, __reginatext ) ;}
772 seps
773 | signal on s_action namespec seps
774 { $$ = $1 ;
775 $$->type = X_SIG_SET ;
776 $$->p[0] = $2 ;
777 $$->name = (streng *)$4 ;
778 $$->p[1] = $3 ; }
779 | signal on s_action seps
780 { $$ = $1 ;
781 $$->type = X_SIG_SET ;
782 $$->p[0] = $2 ;
783 $$->name = (streng *)$4 ;
784 $$->p[1] = $3 ; }
785 | signal off s_action error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
786 seps
787 | signal off s_action seps { $$ = $1 ;
788 $$->type = X_SIG_SET ;
789 $$->p[0] = $2 ;
790 $$->p[1] = $3 ; }
793 namespec : NAME SIMSYMBOL { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue);}
794 | NAME error { exiterror( ERR_STRING_EXPECTED, 3, __reginatext ) ;}
797 asymbol : CONSYMBOL { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
798 | SIMSYMBOL { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
799 | error { exiterror( ERR_STRING_EXPECTED, 0 ) ;}
802 on : ON { $$ = makenode(X_ON,0) ; }
805 off : OFF { $$ = makenode(X_OFF,0) ; }
808 c_action : ERROR { $$ = makenode(X_S_ERROR,0) ; }
809 | HALT { $$ = makenode(X_S_HALT,0) ; }
810 | NOTREADY { $$ = makenode(X_S_NOTREADY,0) ; }
811 | FAILURE { $$ = makenode(X_S_FAILURE,0) ; }
814 s_action : c_action { $$ = $1 ; }
815 | NOVALUE { $$ = makenode(X_S_NOVALUE,0) ; }
816 | SYNTAX { $$ = makenode(X_S_SYNTAX,0) ; }
817 | LOSTDIGITS { $$ = makenode(X_S_LOSTDIGITS,0) ; }
819 trace_stat : trace VALUE expr seps { $$ = $1 ;
820 $$->p[0] = $3 ; }
821 | trace expr seps { $$ = $1 ;
822 $$->p[0] = $2 ; }
823 | trace whatever error { exiterror( ERR_EXTRA_DATA, 1, __reginatext ) ;}
824 seps
825 | trace whatever seps { $$ = $1 ;
826 $$->name = (streng *) $2 ; }
829 whatever : WHATEVER { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
833 assignment : ass_part nexpr seps { $$ = $1 ;
834 $$->p[1] = $2 ;
835 if (($2) && gettypeof($$->p[1])==1)
836 $$->type = X_NASSIGN ; }
839 ass_part : ASSIGNMENTVARIABLE { $$ = makenode(X_ASSIGN,0) ;
840 $$->charnr = parser_data.tstart ;
841 $$->lineno = parser_data.tline ;
842 $$->p[0] = (nodeptr)create_head( (const char *)retvalue ); }
846 expr : '(' expr ')' { $$ = $2 ; }
847 | NOT expr { $$ = makenode(X_LOG_NOT,1,$2) ; }
848 | NOT { exiterror( ERR_INVALID_EXPRESSION, 1, "NOT" ) ;}
849 | expr '+' expr { $$ = makenode(X_PLUSS,2,$1,$3) ; }
850 | expr '=' expr { $$ = makenode(X_EQUAL,2,$1,$3) ;
851 transform( $$ ) ; }
852 | '=' { exiterror( ERR_INVALID_EXPRESSION, 1, "=" ) ;}
853 | expr '-' expr { $$ = makenode(X_MINUS,2,$1,$3) ; }
854 | expr '*' expr { $$ = makenode(X_MULT,2,$1,$3) ; }
855 | '*' { exiterror( ERR_INVALID_EXPRESSION, 1, "*" ) ;}
856 | expr '/' expr { $$ = makenode(X_DEVIDE,2,$1,$3) ; }
857 | '/' { exiterror( ERR_INVALID_EXPRESSION, 1, "/" ) ;}
858 | expr '%' expr { $$ = makenode(X_INTDIV,2,$1,$3) ; }
859 | '%' { exiterror( ERR_INVALID_EXPRESSION, 1, "%" ) ;}
860 | expr '|' expr { $$ = makenode(X_LOG_OR,2,$1,$3) ; }
861 | '|' { exiterror( ERR_INVALID_EXPRESSION, 1, "|" ) ;}
862 | expr '&' expr { $$ = makenode(X_LOG_AND,2,$1,$3) ; }
863 | '&' { exiterror( ERR_INVALID_EXPRESSION, 1, "&" ) ;}
864 | expr XOR expr { $$ = makenode(X_LOG_XOR,2,$1,$3) ; }
865 | XOR { exiterror( ERR_INVALID_EXPRESSION, 1, "&&" ) ;}
866 | expr EXP expr { $$ = makenode(X_EXP,2,$1,$3) ; }
867 | EXP { exiterror( ERR_INVALID_EXPRESSION, 1, "**" ) ;}
868 | expr SPACE expr { $$ = makenode(X_SPACE,2,$1,$3) ; }
869 | SPACE { exiterror( ERR_INVALID_EXPRESSION, 1, " " ) ;}
870 | expr GTE expr { $$ = makenode(X_GTE,2,$1,$3) ;
871 transform( $$ ) ; }
872 | GTE { exiterror( ERR_INVALID_EXPRESSION, 1, ">=" ) ;}
873 | expr LTE expr { $$ = makenode(X_LTE,2,$1,$3) ;
874 transform( $$ ) ; }
875 | GT { exiterror( ERR_INVALID_EXPRESSION, 1, ">" ) ;}
876 | expr GT expr { $$ = makenode(X_GT,2,$1,$3) ;
877 transform( $$ ) ; }
878 | expr MODULUS expr { $$ = makenode(X_MODULUS,2,$1,$3) ; }
879 | MODULUS { exiterror( ERR_INVALID_EXPRESSION, 1, "//" ) ;}
880 | expr LT expr { $$ = makenode(X_LT,2,$1,$3) ;
881 transform( $$ ) ; }
882 | LT { exiterror( ERR_INVALID_EXPRESSION, 1, "<" ) ;}
883 | expr DIFFERENT expr { $$ = makenode(X_DIFF,2,$1,$3) ;
884 transform( $$ ) ; }
885 | DIFFERENT { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
886 | expr EQUALEQUAL expr { $$ = makenode(X_S_EQUAL,2,$1,$3) ; }
887 | EQUALEQUAL { exiterror( ERR_INVALID_EXPRESSION, 1, "==" ) ;}
888 | expr NOTEQUALEQUAL expr { $$ = makenode(X_S_DIFF,2,$1,$3) ; }
889 | NOTEQUALEQUAL { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
890 | expr GTGT expr { $$ = makenode(X_S_GT,2,$1,$3) ; }
891 | GTGT { exiterror( ERR_INVALID_EXPRESSION, 1, ">>" ) ;}
892 | expr LTLT expr { $$ = makenode(X_S_LT,2,$1,$3) ; }
893 | LTLT { exiterror( ERR_INVALID_EXPRESSION, 1, "<<" ) ;}
894 | expr NOTGTGT expr { $$ = makenode(X_S_NGT,2,$1,$3) ; }
895 | NOTGTGT { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
896 | expr NOTLTLT expr { $$ = makenode(X_S_NLT,2,$1,$3) ; }
897 | NOTLTLT { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
898 | expr GTGTE expr { $$ = makenode(X_S_GTE,2,$1,$3) ; }
899 | GTGTE { exiterror( ERR_INVALID_EXPRESSION, 1, ">>=" ) ;}
900 | expr LTLTE expr { $$ = makenode(X_S_LTE,2,$1,$3) ; }
901 | LTLTE { exiterror( ERR_INVALID_EXPRESSION, 1, "<<=" ) ;}
902 | symbtree { $$ = $1 ; }
903 | CONSYMBOL { $$ = makenode(X_STRING,0) ;
904 $$->name = Str_cre_TSD(parser_data.TSD,retvalue) ; }
905 | HEXSTRING { $$ = makenode(X_STRING,0) ;
906 $$->name = Str_make_TSD(parser_data.TSD,retlength) ;
907 memcpy($$->name->value,retvalue,
908 $$->name->len=retlength); }
909 | BINSTRING { $$ = makenode(X_STRING,0) ;
910 $$->name = Str_make_TSD(parser_data.TSD,retlength) ;
911 memcpy($$->name->value,retvalue,
912 $$->name->len=retlength); }
913 | STRING { $$ = makenode(X_STRING,0) ;
914 $$->name = Str_cre_TSD(parser_data.TSD,retvalue) ; }
915 | function { $$ = $1 ; }
916 | '+' expr %prec UPLUSS { $$ = makenode(X_U_PLUSS,1,$2) ; }
917 | '-' expr %prec UMINUS { $$ = makenode(X_U_MINUS,1,$2) ; }
918 | '+' %prec SYNTOP { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
919 | '-' %prec SYNTOP { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
920 | expr CONCATENATE expr { $$ = makenode(X_CONCAT,2,$1,$3) ; }
921 | CONCATENATE { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
922 | expr CCAT expr { $$ = makenode(X_CONCAT,2,$1,$2) ; }
923 | CCAT { exiterror( ERR_INVALID_EXPRESSION, 0 ) ;}
926 symbtree : SIMSYMBOL { $$ = (nodeptr)create_head( (const char *)retvalue ) ; }
930 function : extfunc exprs ')' { $$ = makenode(X_EX_FUNC,1,$2) ;
931 $$->name = (streng *)$1 ; }
932 | intfunc exprs ')' { $$ = makenode(X_IN_FUNC,1,$2) ;
933 $$->name = (streng *)$1 ; }
936 intfunc : INFUNCNAME { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
939 extfunc : EXFUNCNAME { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
942 template : pv solid template { $$ =makenode(X_TPL_SOLID,3,$1,$2,$3);}
943 | pv { $$ =makenode(X_TPL_SOLID,1,$1) ; }
944 | error { exiterror( ERR_INVALID_TEMPLATE, 1, __reginatext ) ;}
945 seps
948 solid : '-' offset { $$ = makenode(X_NEG_OFFS,0) ;
949 $$->name = (streng *) $2 ; }
950 | '+' offset { $$ = makenode(X_POS_OFFS,0) ;
951 $$->name = (streng *) $2 ; }
952 | offset { $$ = makenode(X_ABS_OFFS,0) ;
953 $$->name = (streng *) $1 ; }
954 | '=' offset { $$ = makenode(X_ABS_OFFS,0) ;
955 $$->name = (streng *) $2 ; }
956 | '(' symbtree ')' { $$ = makenode(X_TPL_VAR,0) ;
957 $$->p[0] = $2 ; }
958 | '-' '(' symbtree ')' { $$ = makenode(X_NEG_OFFS,0) ;
959 $$->p[0] = $3 ; }
960 | '+' '(' symbtree ')' { $$ = makenode(X_POS_OFFS,0) ;
961 $$->p[0] = $3 ; }
962 | '=' '(' symbtree ')' { $$ = makenode(X_ABS_OFFS,0) ;
963 $$->p[0] = $3 ; }
964 | string { $$ = makenode(X_TPL_MVE,0) ;
965 $$->name = (streng *) $1 ; }
968 offset : OFFSET { $$ = (nodeptr)Str_cre_TSD(parser_data.TSD,retvalue) ; }
969 | CONSYMBOL { streng *sptr = Str_cre_TSD(parser_data.TSD,retvalue) ;
970 if (myisnumber(sptr))
972 exiterror( ERR_INVALID_INTEGER, 4, sptr->value ) ;
974 else
975 exiterror( ERR_INVALID_TEMPLATE, 0 ) ;}
978 string : STRING { $$ = (nodeptr) Str_cre_TSD(parser_data.TSD,retvalue) ; }
979 | HEXSTRING { streng *sptr = Str_make_TSD(parser_data.TSD,retlength) ;
980 memcpy(sptr->value,retvalue,
981 sptr->len=retlength) ;
982 $$ = (nodeptr) sptr ; }
983 | BINSTRING { streng *sptr = Str_make_TSD(parser_data.TSD,retlength) ;
984 memcpy(sptr->value,retvalue,
985 sptr->len=retlength) ;
986 $$ = (nodeptr) sptr ; }
989 pv : PLACEHOLDER pv { $$ = makenode(X_TPL_POINT,1,$2) ; }
990 | symbtree pv { $$ = makenode(X_TPL_SYMBOL,1,$2) ;
991 $$->p[1] = $1 ; }
992 | { $$ = NULL ; }
995 exprs : nexpr ',' exprs { $$ = makenode(X_EXPRLIST,2,$1,$3) ;
996 checkconst( $$ ) ; }
998 | nexpr { $$ = makenode(X_EXPRLIST,1,$1) ;
999 checkconst( $$ ) ; }
1002 nexpr : expr { $$ = $1 ; }
1003 | { $$ = NULL ; }
1006 anyvars : xsimsymb anyvars { $$ = makenode(X_SIM_SYMBOL,1,$2) ;
1007 $$->name = (streng *) $1 ; }
1008 | xsimsymb { $$ = makenode(X_SIM_SYMBOL,0) ;
1009 $$->name = (streng *) $1 ; }
1010 | '(' xsimsymb ')' anyvars { $$ = makenode(X_IND_SYMBOL,1,$4) ;
1011 $$->name = (streng *) $2 ; }
1012 | '(' xsimsymb ')' { $$ = makenode(X_IND_SYMBOL,0) ;
1013 $$->name = (streng *) $2 ; }
1016 xsimsymb : SIMSYMBOL { $$ = (treenode *) Str_cre_TSD(parser_data.TSD,retvalue);}
1019 simsymb : SIMSYMBOL { $$ = (treenode *) Str_cre_TSD(parser_data.TSD,retvalue);}
1020 | error { exiterror( ERR_SYMBOL_EXPECTED, 1, __reginatext ) ;}
1025 #if 0
1026 static void checkin( nodeptr ptr )
1028 nodeptr *new ;
1029 tsd_t *TSD = parser_data.TSD;
1031 if (!narray)
1033 narray = MallocTSD( sizeof(nodeptr)* 100 ) ;
1034 narmax = 100 ;
1035 narptr = 0 ;
1038 if (narptr==narmax)
1040 new = MallocTSD( sizeof(nodeptr)*narmax*3 ) ;
1041 memcpy( new, narray, sizeof(nodeptr)*narmax ) ;
1042 narmax *= 3 ;
1043 FreeTSD( narray ) ;
1044 narray = new ;
1047 narray[narptr++] = ptr ;
1049 #endif
1051 static nodeptr makenode( int type, int numb, ... )
1053 nodeptr thisleave ;
1054 va_list argptr ;
1055 int i ;
1057 assert(numb <= sizeof(thisleave->p)/sizeof(thisleave->p[0]));
1058 #ifdef REXXDEBUG
1059 printf("makenode: making new node, type: %d\n",type) ;
1060 #endif /* REXXDEBUG */
1062 thisleave = FreshNode( ) ;
1063 /* thisleave is initialized to zero except for nodeindex */
1064 va_start( argptr, numb ) ;
1065 thisleave->type = type ;
1066 thisleave->lineno = -1 ;
1067 thisleave->charnr = -1 ;
1068 for (i=0;i<numb;i++)
1069 thisleave->p[i]=va_arg(argptr, nodeptr) ;
1071 va_end( argptr ) ;
1073 return( thisleave ) ;
1076 static char *getdokeyword( int type )
1078 char *ptr;
1079 switch( type )
1081 case X_DO_TO: ptr="TO";break;
1082 case X_DO_BY: ptr="BY";break;
1083 case X_DO_FOR: ptr="FOR";break;
1084 default: ptr="";break;
1086 return ptr;
1089 static void checkdosyntax( cnodeptr this )
1091 if ((this->p[1]!=NULL)&&(this->p[2]!=NULL))
1093 if ((this->p[1]->type)==(this->p[2]->type))
1095 exiterror( ERR_INVALID_DO_SYNTAX, 1, getdokeyword(this->p[1]->type) ) ;
1098 if ((this->p[2]!=NULL)&&(this->p[3]!=NULL))
1100 if ((this->p[2]->type)==(this->p[3]->type))
1102 exiterror( ERR_INVALID_DO_SYNTAX, 1, getdokeyword(this->p[2]->type) ) ;
1105 if ((this->p[1]!=NULL)&&(this->p[3]!=NULL))
1107 if ((this->p[1]->type)==(this->p[3]->type))
1109 exiterror( ERR_INVALID_DO_SYNTAX, 1, getdokeyword(this->p[1]->type) ) ;
1112 return ;
1116 void newlabel( const tsd_t *TSD, internal_parser_type *ipt, nodeptr this )
1118 labelboxptr new ;
1120 assert( this ) ;
1122 new = MallocTSD(sizeof(labelbox)) ;
1124 new->next = NULL ;
1125 new->entry = this ;
1126 if (ipt->first_label == NULL)
1128 ipt->first_label = new ;
1129 ipt->last_label = new ; /* must be NULL, too */
1131 else
1133 ipt->last_label->next = new ;
1134 ipt->last_label = new ;
1136 ipt->numlabels++;
1139 static nodeptr create_tail( const char *name )
1141 const char *cptr ;
1142 nodeptr node ;
1143 int constant ;
1144 streng *tname ;
1145 tsd_t *TSD = parser_data.TSD;
1147 if (!*name)
1149 node = makenode( X_CTAIL_SYMBOL, 0 ) ;
1150 node->name = Str_make_TSD( parser_data.TSD, 0) ;
1151 return node ;
1154 cptr = name ;
1155 constant = isdigit(*cptr) || *cptr=='.' || (!*cptr) ;
1156 node = makenode( (constant) ? X_CTAIL_SYMBOL : X_VTAIL_SYMBOL, 0 ) ;
1158 for (;*cptr && *cptr!='.'; cptr++) ;
1159 node->name = Str_ncre_TSD( parser_data.TSD, name, cptr-name ) ;
1161 if (*cptr)
1163 node->p[0] = create_tail( ++cptr ) ;
1164 if (constant && node->p[0]->type==X_CTAIL_SYMBOL)
1166 streng *first, *second ;
1167 nodeptr tptr ;
1169 first = node->name ;
1170 second = node->p[0]->name ;
1171 node->name = NULL;
1172 node->p[0]->name = NULL;
1173 tname = Str_makeTSD( first->len + second->len + 1) ;
1174 memcpy( tname->value, first->value, first->len ) ;
1175 tname->value[first->len] = '.' ;
1176 memcpy( tname->value+first->len+1, second->value, second->len) ;
1177 tname->len = first->len + second->len + 1 ;
1179 Free_stringTSD( first ) ;
1180 Free_stringTSD( second ) ;
1181 node->name = tname ;
1182 tptr = node->p[0] ;
1183 node->p[0] = tptr->p[0] ;
1184 RejectNode(tptr);
1188 return node ;
1191 static nodeptr create_head( const char *name )
1193 const char *cptr ;
1194 nodeptr node ;
1196 for (cptr=name; *cptr && *cptr!='.'; cptr++) ;
1197 node = makenode( X_SIM_SYMBOL, 0 ) ;
1198 node->name = Str_ncre_TSD( parser_data.TSD, name, cptr-name+(*cptr=='.')) ;
1200 if (*cptr)
1202 if (*(++cptr))
1203 node->p[0] = create_tail( cptr ) ;
1204 else
1205 node->p[0] = NULL ;
1207 node->type = (node->p[0]) ? X_HEAD_SYMBOL : X_STEM_SYMBOL ;
1210 return node ;
1213 #define IS_UNKNOWN 0
1214 #define IS_A_NUMBER 1
1215 #define IS_NO_NUMBER 2
1216 #define IS_IRREG_NUMBER 10
1218 static int gettypeof( nodeptr this )
1220 tsd_t *TSD = parser_data.TSD;
1222 switch(this->type)
1224 case X_PLUSS:
1225 case X_MINUS:
1226 case X_MULT:
1227 case X_U_PLUSS:
1228 case X_U_MINUS:
1229 case X_DEVIDE:
1230 case X_INTDIV:
1231 case X_MODULUS:
1232 case X_EQUAL:
1233 case X_DIFF:
1234 case X_GTE:
1235 case X_GT:
1236 case X_LTE:
1237 case X_LT:
1238 case X_SEQUAL:
1239 case X_SDIFF:
1240 case X_SGTE:
1241 case X_SGT:
1242 case X_SLTE:
1243 case X_SLT:
1244 case X_NEQUAL:
1245 case X_NDIFF:
1246 case X_NGTE:
1247 case X_NGT:
1248 case X_NLTE:
1249 case X_NLT:
1250 return IS_A_NUMBER ;
1253 case X_SIM_SYMBOL:
1254 return 3 ;
1256 case X_HEAD_SYMBOL:
1257 return 4 ;
1259 case X_STRING:
1260 case X_CON_SYMBOL:
1262 if (this->u.number)
1263 return IS_A_NUMBER ;
1265 this->u.number = is_a_descr( TSD, this->name ) ;
1266 if (this->u.number)
1268 streng *stmp = str_norm( TSD, this->u.number, NULL ) ;
1269 if (Str_cmp(stmp,this->name))
1271 Free_stringTSD( stmp ) ;
1272 return IS_UNKNOWN ;
1274 Free_stringTSD( stmp ) ;
1276 return (this->u.number) ? IS_A_NUMBER : IS_NO_NUMBER ;
1279 return IS_UNKNOWN ;
1284 static void transform( nodeptr this )
1286 int left, rght, type ;
1288 left = gettypeof( this->p[0] ) ;
1289 rght = gettypeof( this->p[1] ) ;
1290 type = this->type ;
1292 if (left==1 && rght==1)
1294 if (type==X_EQUAL)
1295 this->type = X_NEQUAL ;
1296 else if (type==X_DIFF)
1297 this->type = X_NDIFF ;
1298 else if (type==X_GTE)
1299 this->type = X_NGTE ;
1300 else if (type==X_GT)
1301 this->type = X_NGT ;
1302 else if (type==X_LTE)
1303 this->type = X_NLTE ;
1304 else if (type==X_LT)
1305 this->type = X_NLT ;
1307 else if (left==2 || rght==2)
1309 if (type==X_EQUAL)
1310 this->type = X_SEQUAL ;
1311 else if (type==X_DIFF)
1312 this->type = X_SDIFF ;
1313 else if (type==X_GTE)
1314 this->type = X_SGTE ;
1315 else if (type==X_GT)
1316 this->type = X_SGT ;
1317 else if (type==X_LTE)
1318 this->type = X_SLTE ;
1319 else if (type==X_LT)
1320 this->type = X_SLT ;
1322 else
1324 type = this->p[0]->type ;
1325 if (left==1 && (type==X_STRING || type==X_CON_SYMBOL))
1326 this->u.flags.lnum = 1 ;
1327 else if (left==3)
1328 this->u.flags.lsvar = 1 ;
1329 else if (left==4)
1330 this->u.flags.lcvar = 1 ;
1332 type = this->p[1]->type ;
1333 if (rght==1 && (type==X_STRING || type==X_CON_SYMBOL))
1334 this->u.flags.rnum = 1 ;
1335 else if (rght==3)
1336 this->u.flags.rsvar = 1 ;
1337 else if (rght==4)
1338 this->u.flags.rcvar = 1 ;
1343 static int is_const( cnodeptr this )
1345 if (!this)
1346 return 1 ;
1348 switch (this->type)
1350 case X_STRING:
1351 case X_CON_SYMBOL:
1352 return 1 ;
1354 case X_U_PLUSS:
1355 case X_U_MINUS:
1356 return is_const( this->p[0] ) ;
1358 case X_PLUSS:
1359 case X_MINUS:
1360 case X_MULT:
1361 /* case X_DEVIDE: Bug 20000807-41821 */
1362 case X_INTDIV:
1363 case X_MODULUS:
1364 case X_EQUAL:
1365 case X_DIFF:
1366 case X_GTE:
1367 case X_GT:
1368 case X_LTE:
1369 case X_LT:
1370 case X_SEQUAL:
1371 case X_SDIFF:
1372 case X_SGTE:
1373 case X_SGT:
1374 case X_SLTE:
1375 case X_SLT:
1376 case X_NEQUAL:
1377 case X_NDIFF:
1378 case X_NGTE:
1379 case X_NGT:
1380 case X_NLTE:
1381 case X_NLT:
1382 case X_SPACE:
1383 case X_CONCAT:
1384 return is_const( this->p[0] ) && is_const( this->p[1] ) ;
1386 return 0 ;
1390 static void checkconst( nodeptr this )
1392 tsd_t *TSD = parser_data.TSD;
1394 assert( this->type == X_EXPRLIST ) ;
1395 if (is_const(this->p[0]))
1397 if (this->p[0])
1398 this->u.strng = evaluate( TSD, this->p[0], NULL ) ;
1399 else
1400 this->u.strng = NULL ;
1402 this->type = X_CEXPRLIST ;