|
|
1.1 root 1: /* Grammar for Icon Version 5.9, including extensions. */
2:
3: /* primitive tokens */
4:
5: %token CSETLIT
6: EOFX
7: IDENT
8: INTLIT
9: REALLIT
10: STRINGLIT
11:
12: /* reserved words */
13:
14: %token BREAK /* break */
15: BY /* by */
16: CASE /* case */
17: CREATE /* create */
18: DEFAULT /* default */
19: DO /* do */
20: DYNAMIC /* dynamic */
21: ELSE /* else */
22: END /* end */
23: EVERY /* every */
24: FAIL /* fail */
25: GLOBAL /* global */
26: IF /* if */
27: INITIAL /* initial */
28: LINK /* link */
29: LOCAL /* link */
30: NEXT /* next */
31: NOT /* not */
32: OF /* of */
33: PROCEDURE /* procedure */
34: RECORD /* record */
35: REPEAT /* repeat */
36: RETURN /* return */
37: STATIC /* static */
38: SUSPEND /* suspend */
39: THEN /* then */
40: TO /* to */
41: UNTIL /* until */
42: WHILE /* while */
43:
44: /* operators */
45:
46: %token ASSIGN /* := */
47: AT /* @ */
48: AUGACT /* @:= */
49: AUGAND /* &:= */
50: AUGEQ /* =:= */
51: AUGEQV /* ===:= */
52: AUGGE /* >=:= */
53: AUGGT /* >:= */
54: AUGLE /* <=:= */
55: AUGLT /* <:= */
56: AUGNE /* ~=:= */
57: AUGNEQV /* ~===:= */
58: AUGSEQ /* ==:= */
59: AUGSGE /* >>=:= */
60: AUGSGT /* >>:= */
61: AUGSLE /* <<=:= */
62: AUGSLT /* <<:= */
63: AUGSNE /* ~==:= */
64: BACKSLASH /* \ */
65: BANG /* ! */
66: BAR /* | */
67: CARET /* ^ */
68: CARETASGN /* ^:= */
69: COLON /* : */
70: COMMA /* , */
71: CONCAT /* || */
72: CONCATASGN /* ||:= */
73: CONJUNC /* & */
74: DIFF /* -- */
75: DIFFASGN /* --:= */
76: DOT /* . */
77: EQUIV /* === */
78: INTER /* ** */
79: INTERASGN /* **:= */
80: LBRACE /* { */
81: LBRACK /* [ */
82: LCONCAT /* ||| */
83: LCONCATASGN /* |||:= */
84: LEXEQ /* == */
85: LEXGE /* >>= */
86: LEXGT /* >> */
87: LEXLE /* <<= */
88: LEXLT /* << */
89: LEXNE /* ~== */
90: LPAREN /* ( */
91: MCOLON /* -: */
92: MINUS /* - */
93: MINUSASGN /* -:= */
94: MOD /* % */
95: MODASGN /* %:= */
96: NOTEQUIV /* ~=== */
97: NUMEQ /* = */
98: NUMGE /* >e */
99: NUMGT /* > */
100: NUMLE /* <= */
101: NUMLT /* > */
102: NUMNE /* ~= */
103: PCOLON /* +: */
104: PLUS /* + */
105: PLUSASGN /* +:= */
106: QMARK /* ? */
107: RBRACE /* } */
108: RBRACK /* ] */
109: REVASSIGN /* <- */
110: REVSWAP /* <-> */
111: RPAREN /* ) */
112: SCANASGN /* ?:= */
113: SEMICOL /* ; */
114: SLASH /* / */
115: SLASHASGN /* /:= */
116: STAR /* * */
117: STARASGN /* *:= */
118: SWAP /* :=: */
119: TILDE /* ~ */
120: UNION /* ++ */
121: UNIONASGN /* ++:= */
122: %{
123: #include "itran.h"
124: #include "sym.h"
125: #include "tree.h"
126: #include "../h/keyword.h"
127: #define YYSTYPE nodeptr
128: #define YYMAXDEPTH 500
129: %}
130:
131: %%
132:
133: %{
134: int argcnt;
135: int idflag;
136: int i;
137: #ifdef XPX
138: int cstack[50]; /* context stack expression lists */
139: int stacktop = 0; /* stack top */
140: nodeptr cswitch();
141: #endif XPX
142: %}
143:
144: program : decls EOFX {gout(globfile);} ;
145:
146: decls : ;
147: | decls decl ;
148:
149: decl : record {
150: if (!nocode)
151: rout(globfile, STR0($1));
152: nocode = 0;
153: loc_init();
154: } ;
155: | proc {
156: if (!nocode)
157: codegen($1);
158: nocode = 0;
159: treeinit();
160: loc_init();
161: } ;
162: | global ;
163: | LINK lnklist ;
164:
165: lnklist : lnkfile ;
166: | lnklist COMMA lnkfile;
167:
168: lnkfile : IDENT {addlfile(STR0($1));} ;
169: | STRINGLIT {addlfile(STR0($1));} ;
170:
171: global : GLOBAL {idflag = F_GLOBAL;} idlist ;
172:
173: record : RECORD {idflag = F_ARGUMENT;} IDENT LPAREN arglist RPAREN {
174: install(STR0($3),F_RECORD|F_GLOBAL,(int)$5);
175: $$ = $3;
176: } ;
177:
178: proc : prochead SEMICOL locals initial procbody END {
179: $$ = (nodeptr)PROCNODE($1,$4,$5,$6);
180: } ;
181:
182: prochead: PROCEDURE {idflag = F_ARGUMENT;} IDENT LPAREN arglist RPAREN {
183: $$ = $3;
184: install(STR0($3),F_PROC|F_GLOBAL,(int)$5);
185: } ;
186:
187: arglist : {$$ = (int)0;} ;
188: | idlist {$$ = (nodeptr)$1;} ;
189:
190:
191: idlist : IDENT {
192: install(STR0($1),idflag,0);
193: $$ = (nodeptr)1;
194: } ;
195: | idlist COMMA IDENT {
196: install(STR0($3),idflag,0);
197: $$ = (nodeptr)((int)$1 + 1);
198: } ;
199:
200: locals : ;
201: | locals retention idlist SEMICOL ;
202:
203: retention: LOCAL {idflag = F_DYNAMIC;} ;
204: | STATIC {idflag = F_STATIC;} ;
205: | DYNAMIC {idflag = F_DYNAMIC;} ;
206:
207: initial : {$$ = EMPTYNODE;} ;
208: | INITIAL expr SEMICOL {$$ = $2;} ;
209:
210: procbody: {$$ = EMPTYNODE;} ;
211: | nexpr SEMICOL procbody {$$ = SLISTNODE($2, $1, $3);} ;
212:
213: nexpr : {$$ = EMPTYNODE;} ;
214: | expr ;
215:
216: expr : expr1a ;
217: | expr CONJUNC expr1a {$$ = CONJNODE($2,$1,$3);} ;
218:
219: expr1a : expr1 ;
220: | expr1a QMARK expr1 {$$ = SCANNODE($2,$1,$3);} ;
221:
222: expr1 : expr2 ;
223: | expr2 op1 expr1 {binop: $$ = BINOPNODE($2,$1,$3);} ;
224: | expr2 op1a expr1 {$$ = AUGOPNODE($2,$1,$3);} ;
225: | expr2 SCANASGN expr1 {$$ = SCANNODE($2,$1,$3);} ;
226: | expr2 AUGAND expr1 {$$ = CONJNODE($2,$1,$3);} ;
227: | expr2 AUGACT expr1 {$$ = ACTIVNODE($2,$3,$1);} ;
228:
229: op1 : SWAP ;
230: | ASSIGN ;
231: | REVSWAP ;
232: | REVASSIGN ;
233:
234: op1a : CONCATASGN ;
235: | LCONCATASGN ;
236: | DIFFASGN ;
237: | UNIONASGN ;
238: | PLUSASGN ;
239: | MINUSASGN ;
240: | STARASGN ;
241: | INTERASGN ;
242: | SLASHASGN ;
243: | MODASGN ;
244: | CARETASGN ;
245: | AUGEQ ;
246: | AUGEQV ;
247: | AUGGE ;
248: | AUGGT ;
249: | AUGLE ;
250: | AUGLT ;
251: | AUGNE ;
252: | AUGNEQV ;
253: | AUGSEQ ;
254: | AUGSGE ;
255: | AUGSGT ;
256: | AUGSLE ;
257: | AUGSLT ;
258: | AUGSNE ;
259:
260: expr2 : expr3 ;
261: | expr2 TO expr3 {$$ = TONODE($2,$1,$3);} ;
262: | expr2 TO expr3 BY expr3 {$$ = TOBYNODE($2,$1,$3,$5);} ;
263:
264: expr3 : expr4 ;
265: | expr4 BAR expr3 {$$ = ALTNODE($2,$1,$3);} ;
266:
267: expr4 : expr5 ;
268: | expr4 op4 expr5 {goto binop;} ;
269:
270: op4 : LEXEQ ;
271: | LEXGE ;
272: | LEXGT ;
273: | LEXLE ;
274: | LEXLT ;
275: | LEXNE ;
276: | NUMEQ ;
277: | NUMGE ;
278: | NUMGT ;
279: | NUMLE ;
280: | NUMLT ;
281: | NUMNE ;
282: | EQUIV ;
283: | NOTEQUIV ;
284:
285: expr5 : expr6 ;
286: | expr5 op5 expr6 {goto binop;} ;
287:
288: op5 : CONCAT ;
289: | LCONCAT ;
290:
291: expr6 : expr7 ;
292: | expr6 op6 expr7 {goto binop;} ;
293:
294: op6 : PLUS ;
295: | DIFF ;
296: | UNION ;
297: | MINUS ;
298:
299: expr7 : expr8 ;
300: | expr7 op7 expr8 {goto binop;} ;
301:
302: op7 : STAR ;
303: | INTER ;
304: | SLASH ;
305: | MOD ;
306:
307: expr8 : expr9 ;
308: | expr9 CARET expr8 {goto binop;} ;
309:
310: expr9 : expr10 ;
311: | expr9 BACKSLASH expr10 {$$ = LIMITNODE($1,$3);} ;
312: | expr9 AT expr10 {$$ = ACTIVNODE($2, $3, $1);};
313:
314: expr10 : expr11 ;
315: | AT expr10 {$$ = ACTIVNODE($1, $2, EMPTYNODE);} ;
316: | NOT expr10 {$$ = NOTNODE($2);} ;
317: | BAR expr10 {$$ = BARNODE($2);} ;
318: | CONCAT expr10 {$$ = BARNODE($2);} ;
319: | LCONCAT expr10 {$$ = BARNODE($2);} ;
320: | op10 expr10 {$$ = UNOPNODE($1,$2);} ;
321:
322: op10 : DOT ;
323: | BANG ;
324: | DIFF ;
325: | PLUS ;
326: | STAR ;
327: | SLASH ;
328: | CARET ;
329: | INTER ;
330: | TILDE ;
331: | MINUS ;
332: | NUMEQ ;
333: | NUMNE ;
334: | LEXEQ ;
335: | LEXNE ;
336: | EQUIV ;
337: | UNION ;
338: | QMARK ;
339: | NOTEQUIV ;
340: | BACKSLASH ;
341:
342: expr11 : literal ;
343: | section ;
344: | return ;
345: | if ;
346: | case ;
347: | while ;
348: | until ;
349: | every ;
350: | repeat ;
351: | CREATE expr {$$ = CREATENODE($1,$2);} ;
352: | IDENT {VAL0($1) = putloc(STR0($1),0);} ;
353: | NEXT {$$ = NEXTNODE($1);} ;
354: | BREAK nexpr {$$ = BREAKNODE($1,$2);} ;
355: | LPAREN {
356: #ifdef XPX
357: pushcs(0);
358: #endif XPX
359: } exprlist {
360: #ifdef XPX
361: popcs();
362: #endif XPX
363: } RPAREN {
364: if (($3)->n_type == N_ELIST)
365: $$ = INVOKNODE($1,EMPTYNODE,$3);
366: else
367: $$ = $3; } ;
368: | LBRACE compound RBRACE {$$ = $2;} ;
369: | LBRACK {
370: #ifdef XPX
371: pushcs(0);
372: #endif XPX
373: } exprlist {
374: #ifdef XPX
375: popcs();
376: #endif XPX
377: } RBRACK {
378: $$ = LISTNODE($1,$3);} ;
379: | expr11 LBRACK nexpr RBRACK {$$ = BINOPNODE($2,$1,$3);} ;
380: | expr11 LBRACE RBRACE {$$ = INVOKNODE($2,$1,LISTNODE($2,EMPTYNODE));} ;
381: | expr11 LBRACE {
382: #ifdef XPX
383: pushcs(1);
384: #endif XPX
385: } exprlist {
386: #ifdef XPX
387: popcs();
388: #else XPX
389: err("missing semicolon or operator", 0);
390: #endif XPX
391: } RBRACE {
392: $$ = INVOKNODE($2,$1,LISTNODE($2,$4));
393: } ;
394: | expr11 LPAREN {
395: #ifdef XPX
396: pushcs(0);
397: #endif XPX
398: } exprlist {
399: #ifdef XPX
400: popcs();
401: #endif XPX
402: } RPAREN {
403: $$ = INVOKNODE($2,$1,$4);
404: } ;
405: | expr11 DOT IDENT {$$ = FIELDNODE($2,$1,$3);} ;
406: | CONJUNC FAIL {$$ = KEYNODE($1, K_FAIL);} ;
407: | CONJUNC IDENT {
408: if ((i = klocate(STR0($2))) == NULL)
409: err("invalid keyword",STR0($2));
410: $$ = KEYNODE($1, i);
411: } ;
412:
413: while : WHILE expr {$$ = LOOPNODE($1,$2,EMPTYNODE);} ;
414: | WHILE expr DO expr {$$ = LOOPNODE($1,$2,$4);} ;
415:
416: until : UNTIL expr {$$ = LOOPNODE($1,$2,EMPTYNODE);} ;
417: | UNTIL expr DO expr {$$ = LOOPNODE($1,$2,$4);} ;
418:
419: every : EVERY expr {$$ = LOOPNODE($1,$2,EMPTYNODE);} ;
420: | EVERY expr DO expr {$$ = LOOPNODE($1,$2,$4);} ;
421:
422: repeat : REPEAT expr {$$ = LOOPNODE($1,$2,EMPTYNODE);} ;
423:
424: return : FAIL {$$ = RETNODE($1,EMPTYNODE);} ;
425: | RETURN nexpr {$$ = RETNODE($1,$2);} ;
426: | SUSPEND nexpr {$$ = SUSPNODE($1,$2);} ;
427:
428: if : IF expr THEN expr {$$ = IFNODE($1,$2,$4,EMPTYNODE);} ;
429: | IF expr THEN expr ELSE expr {$$ = IFNODE($1,$2,$4,$6);} ;
430:
431: case : CASE expr OF LBRACE caselist RBRACE {$$ = CASENODE($1,$2,$5);} ;
432:
433: caselist: cclause ;
434: | caselist SEMICOL cclause {$$ = CLISTNODE($2,$1,$3);} ;
435:
436: cclause : DEFAULT COLON expr {$$ = CCLSNODE($2,$1,$3);} ;
437: | expr COLON expr {$$ = CCLSNODE($2,$1,$3);} ;
438:
439: exprlist: nexpr {
440: #ifdef XPX
441: $$ = cswitch($1,$1);
442: #endif XPX
443: } ;
444: | exprlist COMMA nexpr {
445: #ifdef XPX
446: $$ = ELISTNODE($2,$1,cswitch($3,$2));
447: #else XPX
448: $$ = ELISTNODE($2,$1,$3);
449: #endif XPX
450: } ;
451:
452: literal : INTLIT {VAL0($1) = putlit(STR0($1),F_INTLIT,0);} ;
453: | REALLIT {VAL0($1) = putlit(STR0($1),F_REALLIT,0);} ;
454: | STRINGLIT {VAL0($1) = putlit(STR0($1),F_STRLIT,VAL1($1));} ;
455: | CSETLIT {VAL0($1) = putlit(STR0($1),F_CSETLIT,VAL1($1));} ;
456:
457: section : expr11 LBRACK expr sectop expr RBRACK {$$ = (nodeptr)SECTNODE($4,$1,$3,$5);} ;
458:
459: sectop : COLON ;
460: | PCOLON ;
461: | MCOLON ;
462:
463: compound: nexpr ;
464: | nexpr SEMICOL compound {$$ = SLISTNODE($2, $1, $3);} ;
465:
466: program : error decls EOFX ;
467: proc : prochead error procbody END ;
468: expr : error ;
469: %%
470:
471: #ifdef XPX
472: pushcs(val)
473: int val;
474: {
475: stacktop = stacktop + 1;
476: cstack[stacktop] = val;
477: }
478:
479: popcs()
480: {
481: stacktop = stacktop - 1;
482: }
483:
484: nodeptr cswitch(x,y)
485: nodeptr x, y;
486: {
487: if (cstack[stacktop]) return(CREATENODE(y,x));
488: else return(x);
489: }
490: #endif XPX
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.