|
|
1.1 root 1: /* Grammar for Icon Version 5.10. */
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 /* >= */
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: int cstack[50]; /* context stack expression lists */
138: int stacktop = 0; /* stack top */
139: nodeptr cswitch();
140: %}
141:
142: program : decls EOFX {gout(globfile);} ;
143:
144: decls : ;
145: | decls decl ;
146:
147: decl : record {
148: if (!nocode)
149: rout(globfile, Str0($1));
150: nocode = 0;
151: loc_init();
152: } ;
153: | proc {
154: if (!nocode)
155: codegen($1);
156: nocode = 0;
157: treeinit();
158: loc_init();
159: } ;
160: | global ;
161: | LINK lnklist ;
162:
163: lnklist : lnkfile ;
164: | lnklist COMMA lnkfile;
165:
166: lnkfile : IDENT {addlfile(Str0($1));} ;
167: | STRINGLIT {addlfile(Str0($1));} ;
168:
169: global : GLOBAL {idflag = F_Global;} idlist ;
170:
171: record : RECORD {idflag = F_Argument;} IDENT LPAREN arglist RPAREN {
172: install(Str0($3),F_Record|F_Global,(int)$5);
173: $$ = $3;
174: } ;
175:
176: proc : prochead SEMICOL locals initial procbody END {
177: $$ = (nodeptr)ProcNode($1,$4,$5,$6);
178: } ;
179:
180: prochead: PROCEDURE {idflag = F_Argument;} IDENT LPAREN arglist RPAREN {
181: $$ = $3;
182: install(Str0($3),F_Proc|F_Global,(int)$5);
183: } ;
184:
185: arglist : {$$ = (int)0;} ;
186: | idlist {$$ = (nodeptr)$1;} ;
187:
188:
189: idlist : IDENT {
190: install(Str0($1),idflag,0);
191: $$ = (nodeptr)1;
192: } ;
193: | idlist COMMA IDENT {
194: install(Str0($3),idflag,0);
195: $$ = (nodeptr)((int)$1 + 1);
196: } ;
197:
198: locals : ;
199: | locals retention idlist SEMICOL ;
200:
201: retention: LOCAL {idflag = F_Dynamic;} ;
202: | STATIC {idflag = F_Static;} ;
203: | DYNAMIC {idflag = F_Dynamic;} ;
204:
205: initial : {$$ = EmptyNode;} ;
206: | INITIAL expr SEMICOL {$$ = $2;} ;
207:
208: procbody: {$$ = EmptyNode;} ;
209: | nexpr SEMICOL procbody {$$ = SListNode($2, $1, $3);} ;
210:
211: nexpr : {$$ = EmptyNode;} ;
212: | expr ;
213:
214: expr : expr1a ;
215: | expr CONJUNC expr1a {$$ = ConjNode($2,$1,$3);} ;
216:
217: expr1a : expr1 ;
218: | expr1a QMARK expr1 {$$ = ScanNode($2,$1,$3);} ;
219:
220: expr1 : expr2 ;
221: | expr2 op1 expr1 {binop: $$ = BinopNode($2,$1,$3);} ;
222: | expr2 op1a expr1 {$$ = AugopNode($2,$1,$3);} ;
223: | expr2 SCANASGN expr1 {$$ = ScanNode($2,$1,$3);} ;
224: | expr2 AUGAND expr1 {$$ = ConjNode($2,$1,$3);} ;
225: | expr2 AUGACT expr1 {$$ = ActivNode($2,$3,$1);} ;
226:
227: op1 : SWAP ;
228: | ASSIGN ;
229: | REVSWAP ;
230: | REVASSIGN ;
231:
232: op1a : CONCATASGN ;
233: | LCONCATASGN ;
234: | DIFFASGN ;
235: | UNIONASGN ;
236: | PLUSASGN ;
237: | MINUSASGN ;
238: | STARASGN ;
239: | INTERASGN ;
240: | SLASHASGN ;
241: | MODASGN ;
242: | CARETASGN ;
243: | AUGEQ ;
244: | AUGEQV ;
245: | AUGGE ;
246: | AUGGT ;
247: | AUGLE ;
248: | AUGLT ;
249: | AUGNE ;
250: | AUGNEQV ;
251: | AUGSEQ ;
252: | AUGSGE ;
253: | AUGSGT ;
254: | AUGSLE ;
255: | AUGSLT ;
256: | AUGSNE ;
257:
258: expr2 : expr3 ;
259: | expr2 TO expr3 {$$ = ToNode($2,$1,$3);} ;
260: | expr2 TO expr3 BY expr3 {$$ = ToByNode($2,$1,$3,$5);} ;
261:
262: expr3 : expr4 ;
263: | expr4 BAR expr3 {$$ = AltNode($2,$1,$3);} ;
264:
265: expr4 : expr5 ;
266: | expr4 op4 expr5 {goto binop;} ;
267:
268: op4 : LEXEQ ;
269: | LEXGE ;
270: | LEXGT ;
271: | LEXLE ;
272: | LEXLT ;
273: | LEXNE ;
274: | NUMEQ ;
275: | NUMGE ;
276: | NUMGT ;
277: | NUMLE ;
278: | NUMLT ;
279: | NUMNE ;
280: | EQUIV ;
281: | NOTEQUIV ;
282:
283: expr5 : expr6 ;
284: | expr5 op5 expr6 {goto binop;} ;
285:
286: op5 : CONCAT ;
287: | LCONCAT ;
288:
289: expr6 : expr7 ;
290: | expr6 op6 expr7 {goto binop;} ;
291:
292: op6 : PLUS ;
293: | DIFF ;
294: | UNION ;
295: | MINUS ;
296:
297: expr7 : expr8 ;
298: | expr7 op7 expr8 {goto binop;} ;
299:
300: op7 : STAR ;
301: | INTER ;
302: | SLASH ;
303: | MOD ;
304:
305: expr8 : expr9 ;
306: | expr9 CARET expr8 {goto binop;} ;
307:
308: expr9 : expr10 ;
309: | expr9 BACKSLASH expr10 {$$ = LimitNode($1,$3);} ;
310: | expr9 AT expr10 {$$ = ActivNode($2, $3, $1);};
311:
312: expr10 : expr11 ;
313: | AT expr10 {$$ = ActivNode($1, $2, EmptyNode);} ;
314: | NOT expr10 {$$ = NotNode($2);} ;
315: | BAR expr10 {$$ = BarNode($2);} ;
316: | CONCAT expr10 {$$ = BarNode($2);} ;
317: | LCONCAT expr10 {$$ = BarNode($2);} ;
318: | op10 expr10 {$$ = UnopNode($1,$2);} ;
319:
320: op10 : DOT ;
321: | BANG ;
322: | DIFF ;
323: | PLUS ;
324: | STAR ;
325: | SLASH ;
326: | CARET ;
327: | INTER ;
328: | TILDE ;
329: | MINUS ;
330: | NUMEQ ;
331: | NUMNE ;
332: | LEXEQ ;
333: | LEXNE ;
334: | EQUIV ;
335: | UNION ;
336: | QMARK ;
337: | NOTEQUIV ;
338: | BACKSLASH ;
339:
340: expr11 : literal ;
341: | section ;
342: | return ;
343: | if ;
344: | case ;
345: | while ;
346: | until ;
347: | every ;
348: | repeat ;
349: | CREATE expr {$$ = CreateNode($1,$2);} ;
350: | IDENT {Val0($1) = putloc(Str0($1),0);} ;
351: | NEXT {$$ = NextNode($1);} ;
352: | BREAK nexpr {$$ = BreakNode($1,$2);} ;
353: | LPAREN {
354: pushcs(0);
355: } exprlist {
356: popcs();
357: } RPAREN {
358: if (($3)->n_type == N_Elist)
359: $$ = InvokNode($1,EmptyNode,$3);
360: else
361: $$ = $3; } ;
362: | LBRACE compound RBRACE {$$ = $2;} ;
363: | LBRACK {
364: pushcs(0);
365: } exprlist {
366: popcs();
367: } RBRACK {
368: $$ = ListNode($1,$3);} ;
369: | expr11 LBRACK nexpr RBRACK {$$ = BinopNode($2,$1,$3);} ;
370: | expr11 LBRACE RBRACE {$$ = InvokNode($2,$1,ListNode($2,EmptyNode));} ;
371: | expr11 LBRACE {
372: pushcs(1);
373: } exprlist {
374: popcs();
375: } RBRACE {
376: $$ = InvokNode($2,$1,ListNode($2,$4));
377: } ;
378: | expr11 LPAREN {
379: pushcs(0);
380: } exprlist {
381: popcs();
382: } RPAREN {
383: $$ = InvokNode($2,$1,$4);
384: } ;
385: | expr11 DOT IDENT {$$ = FieldNode($2,$1,$3);} ;
386: | CONJUNC FAIL {$$ = KeyNode($1, K_FAIL);} ;
387: | CONJUNC IDENT {
388: if ((i = klocate(Str0($2))) == NULL)
389: err("invalid keyword",Str0($2));
390: $$ = KeyNode($1, i);
391: } ;
392:
393: while : WHILE expr {$$ = LoopNode($1,$2,EmptyNode);} ;
394: | WHILE expr DO expr {$$ = LoopNode($1,$2,$4);} ;
395:
396: until : UNTIL expr {$$ = LoopNode($1,$2,EmptyNode);} ;
397: | UNTIL expr DO expr {$$ = LoopNode($1,$2,$4);} ;
398:
399: every : EVERY expr {$$ = LoopNode($1,$2,EmptyNode);} ;
400: | EVERY expr DO expr {$$ = LoopNode($1,$2,$4);} ;
401:
402: repeat : REPEAT expr {$$ = LoopNode($1,$2,EmptyNode);} ;
403:
404: return : FAIL {$$ = RetNode($1,EmptyNode);} ;
405: | RETURN nexpr {$$ = RetNode($1,$2);} ;
406: | SUSPEND nexpr {$$ = SuspNode($1,$2);} ;
407:
408: if : IF expr THEN expr {$$ = IfNode($1,$2,$4,EmptyNode);} ;
409: | IF expr THEN expr ELSE expr {$$ = IfNode($1,$2,$4,$6);} ;
410:
411: case : CASE expr OF LBRACE caselist RBRACE {$$ = CaseNode($1,$2,$5);} ;
412:
413: caselist: cclause ;
414: | caselist SEMICOL cclause {$$ = ClistNode($2,$1,$3);} ;
415:
416: cclause : DEFAULT COLON expr {$$ = CclsNode($2,$1,$3);} ;
417: | expr COLON expr {$$ = CclsNode($2,$1,$3);} ;
418:
419: exprlist: nexpr {
420: $$ = cswitch($1,$1);
421: } ;
422: | exprlist COMMA nexpr {
423: $$ = ElistNode($2,$1,cswitch($3,$2));
424: } ;
425:
426: literal : INTLIT {Val0($1) = putlit(Str0($1),F_IntLit,0);} ;
427: | REALLIT {Val0($1) = putlit(Str0($1),F_RealLit,0);} ;
428: | STRINGLIT {Val0($1) = putlit(Str0($1),F_StrLit,Val1($1));} ;
429: | CSETLIT {Val0($1) = putlit(Str0($1),F_CsetLit,Val1($1));} ;
430:
431: section : expr11 LBRACK expr sectop expr RBRACK {$$ = (nodeptr)SectNode($4,$1,$3,$5);} ;
432:
433: sectop : COLON ;
434: | PCOLON ;
435: | MCOLON ;
436:
437: compound: nexpr ;
438: | nexpr SEMICOL compound {$$ = SListNode($2, $1, $3);} ;
439:
440: program : error decls EOFX ;
441: proc : prochead error procbody END ;
442: expr : error ;
443: %%
444:
445: pushcs(val)
446: int val;
447: {
448: stacktop = stacktop + 1;
449: cstack[stacktop] = val;
450: }
451:
452: popcs()
453: {
454: stacktop = stacktop - 1;
455: }
456:
457: nodeptr cswitch(x,y)
458: nodeptr x, y;
459: {
460: if (cstack[stacktop]) return(CreateNode(y,x));
461: else return(x);
462: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.