afe513ca2470dfc8434ba0f02709adfd767c7497
[p5sagit/p5-mst-13.2.git] / x2p / a2p.y
1 %{
2 /* $Header: a2p.y,v 3.0 89/10/18 15:34:29 lwall Locked $
3  *
4  *    Copyright (c) 1989, Larry Wall
5  *
6  *    You may distribute under the terms of the GNU General Public License
7  *    as specified in the README file that comes with the perl 3.0 kit.
8  *
9  * $Log:        a2p.y,v $
10  * Revision 3.0  89/10/18  15:34:29  lwall
11  * 3.0 baseline
12  * 
13  */
14
15 #include "INTERN.h"
16 #include "a2p.h"
17
18 int root;
19 int begins = Nullop;
20 int ends = Nullop;
21
22 %}
23 %token BEGIN END
24 %token REGEX
25 %token SEMINEW NEWLINE COMMENT
26 %token FUN1 FUNN GRGR
27 %token PRINT PRINTF SPRINTF SPLIT
28 %token IF ELSE WHILE FOR IN
29 %token EXIT NEXT BREAK CONTINUE RET
30 %token GETLINE DO SUB GSUB MATCH
31 %token FUNCTION USERFUN DELETE
32
33 %right ASGNOP
34 %right '?' ':'
35 %left OROR
36 %left ANDAND
37 %left IN
38 %left NUMBER VAR SUBSTR INDEX
39 %left MATCHOP
40 %left RELOP '<' '>'
41 %left OR
42 %left STRING
43 %left '+' '-'
44 %left '*' '/' '%'
45 %right UMINUS
46 %left NOT
47 %right '^'
48 %left INCR DECR
49 %left FIELD VFIELD
50
51 %%
52
53 program : junk hunks
54                 { root = oper4(OPROG,$1,begins,$2,ends); }
55         ;
56
57 begin   : BEGIN '{' maybe states '}' junk
58                 { begins = oper4(OJUNK,begins,$3,$4,$6); in_begin = FALSE;
59                     $$ = Nullop; }
60         ;
61
62 end     : END '{' maybe states '}'
63                 { ends = oper3(OJUNK,ends,$3,$4); $$ = Nullop; }
64         | end NEWLINE
65                 { $$ = $1; }
66         ;
67
68 hunks   : hunks hunk junk
69                 { $$ = oper3(OHUNKS,$1,$2,$3); }
70         | /* NULL */
71                 { $$ = Nullop; }
72         ;
73
74 hunk    : patpat
75                 { $$ = oper1(OHUNK,$1); need_entire = TRUE; }
76         | patpat '{' maybe states '}'
77                 { $$ = oper2(OHUNK,$1,oper2(OJUNK,$3,$4)); }
78         | FUNCTION USERFUN '(' arg_list ')' maybe '{' maybe states '}'
79                 { fixfargs($2,$4,0); $$ = oper5(OUSERDEF,$2,$4,$6,$8,$9); }
80         | '{' maybe states '}'
81                 { $$ = oper2(OHUNK,Nullop,oper2(OJUNK,$2,$3)); }
82         | begin
83         | end
84         ;
85
86 arg_list: expr_list
87                 { $$ = rememberargs($$); }
88         ;
89
90 patpat  : pat
91                 { $$ = oper1(OPAT,$1); }
92         | pat ',' pat
93                 { $$ = oper2(ORANGE,$1,$3); }
94         ;
95
96 pat     : match
97         | rel
98         | compound_pat
99         ;
100
101 compound_pat
102         : '(' compound_pat ')'
103                 { $$ = oper1(OPPAREN,$2); }
104         | pat ANDAND maybe pat
105                 { $$ = oper3(OPANDAND,$1,$3,$4); }
106         | pat OROR maybe pat
107                 { $$ = oper3(OPOROR,$1,$3,$4); }
108         | NOT pat
109                 { $$ = oper1(OPNOT,$2); }
110         ;
111
112 cond    : expr
113         | match
114         | rel
115         | compound_cond
116         ;
117
118 compound_cond
119         : '(' compound_cond ')'
120                 { $$ = oper1(OCPAREN,$2); }
121         | cond ANDAND maybe cond
122                 { $$ = oper3(OCANDAND,$1,$3,$4); }
123         | cond OROR maybe cond
124                 { $$ = oper3(OCOROR,$1,$3,$4); }
125         | NOT cond
126                 { $$ = oper1(OCNOT,$2); }
127         ;
128
129 rel     : expr RELOP expr
130                 { $$ = oper3(ORELOP,$2,$1,$3); }
131         | expr '>' expr
132                 { $$ = oper3(ORELOP,string(">",1),$1,$3); }
133         | expr '<' expr
134                 { $$ = oper3(ORELOP,string("<",1),$1,$3); }
135         | '(' rel ')'
136                 { $$ = oper1(ORPAREN,$2); }
137         ;
138
139 match   : expr MATCHOP expr
140                 { $$ = oper3(OMATCHOP,$2,$1,$3); }
141         | expr MATCHOP REGEX
142                 { $$ = oper3(OMATCHOP,$2,$1,oper1(OREGEX,$3)); }
143         | REGEX         %prec MATCHOP
144                 { $$ = oper1(OREGEX,$1); }
145         | '(' match ')'
146                 { $$ = oper1(OMPAREN,$2); }
147         ;
148
149 expr    : term
150                 { $$ = $1; }
151         | expr term
152                 { $$ = oper2(OCONCAT,$1,$2); }
153         | variable ASGNOP expr
154                 { $$ = oper3(OASSIGN,$2,$1,$3);
155                         if ((ops[$1].ival & 255) == OFLD)
156                             lval_field = TRUE;
157                         if ((ops[$1].ival & 255) == OVFLD)
158                             lval_field = TRUE;
159                 }
160         ;
161
162 term    : variable
163                 { $$ = $1; }
164         | NUMBER
165                 { $$ = oper1(ONUM,$1); }
166         | STRING
167                 { $$ = oper1(OSTR,$1); }
168         | term '+' term
169                 { $$ = oper2(OADD,$1,$3); }
170         | term '-' term
171                 { $$ = oper2(OSUBTRACT,$1,$3); }
172         | term '*' term
173                 { $$ = oper2(OMULT,$1,$3); }
174         | term '/' term
175                 { $$ = oper2(ODIV,$1,$3); }
176         | term '%' term
177                 { $$ = oper2(OMOD,$1,$3); }
178         | term '^' term
179                 { $$ = oper2(OPOW,$1,$3); }
180         | term IN VAR
181                 { $$ = oper2(ODEFINED,aryrefarg($3),$1); }
182         | term '?' term ':' term
183                 { $$ = oper2(OCOND,$1,$3,$5); }
184         | variable INCR
185                 { $$ = oper1(OPOSTINCR,$1); }
186         | variable DECR
187                 { $$ = oper1(OPOSTDECR,$1); }
188         | INCR variable
189                 { $$ = oper1(OPREINCR,$2); }
190         | DECR variable
191                 { $$ = oper1(OPREDECR,$2); }
192         | '-' term %prec UMINUS
193                 { $$ = oper1(OUMINUS,$2); }
194         | '+' term %prec UMINUS
195                 { $$ = oper1(OUPLUS,$2); }
196         | '(' expr ')'
197                 { $$ = oper1(OPAREN,$2); }
198         | GETLINE
199                 { $$ = oper0(OGETLINE); }
200         | GETLINE VAR
201                 { $$ = oper1(OGETLINE,$2); }
202         | GETLINE '<' expr
203                 { $$ = oper3(OGETLINE,Nullop,string("<",1),$3);
204                     if (ops[$3].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
205         | GETLINE VAR '<' expr
206                 { $$ = oper3(OGETLINE,$2,string("<",1),$4);
207                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
208         | term 'p' GETLINE
209                 { $$ = oper3(OGETLINE,Nullop,string("|",1),$1);
210                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
211         | term 'p' GETLINE VAR
212                 { $$ = oper3(OGETLINE,$4,string("|",1),$1);
213                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
214         | FUN1
215                 { $$ = oper0($1); need_entire = do_chop = TRUE; }
216         | FUN1 '(' ')'
217                 { $$ = oper1($1,Nullop); need_entire = do_chop = TRUE; }
218         | FUN1 '(' expr ')'
219                 { $$ = oper1($1,$3); }
220         | FUNN '(' expr_list ')'
221                 { $$ = oper1($1,$3); }
222         | USERFUN '(' expr_list ')'
223                 { $$ = oper2(OUSERFUN,$1,$3); }
224         | SPRINTF expr_list
225                 { $$ = oper1(OSPRINTF,$2); }
226         | SUBSTR '(' expr ',' expr ',' expr ')'
227                 { $$ = oper3(OSUBSTR,$3,$5,$7); }
228         | SUBSTR '(' expr ',' expr ')'
229                 { $$ = oper2(OSUBSTR,$3,$5); }
230         | SPLIT '(' expr ',' VAR ',' expr ')'
231                 { $$ = oper3(OSPLIT,$3,aryrefarg(numary($5)),$7); }
232         | SPLIT '(' expr ',' VAR ')'
233                 { $$ = oper2(OSPLIT,$3,aryrefarg(numary($5))); }
234         | INDEX '(' expr ',' expr ')'
235                 { $$ = oper2(OINDEX,$3,$5); }
236         | MATCH '(' expr ',' REGEX ')'
237                 { $$ = oper2(OMATCH,$3,oper1(OREGEX,$5)); }
238         | MATCH '(' expr ',' expr ')'
239                 { $$ = oper2(OMATCH,$3,$5); }
240         | SUB '(' expr ',' expr ')'
241                 { $$ = oper2(OSUB,$3,$5); }
242         | SUB '(' REGEX ',' expr ')'
243                 { $$ = oper2(OSUB,oper1(OREGEX,$3),$5); }
244         | GSUB '(' expr ',' expr ')'
245                 { $$ = oper2(OGSUB,$3,$5); }
246         | GSUB '(' REGEX ',' expr ')'
247                 { $$ = oper2(OGSUB,oper1(OREGEX,$3),$5); }
248         | SUB '(' expr ',' expr ',' expr ')'
249                 { $$ = oper3(OSUB,$3,$5,$7); }
250         | SUB '(' REGEX ',' expr ',' expr ')'
251                 { $$ = oper3(OSUB,oper1(OREGEX,$3),$5,$7); }
252         | GSUB '(' expr ',' expr ',' expr ')'
253                 { $$ = oper3(OGSUB,$3,$5,$7); }
254         | GSUB '(' REGEX ',' expr ',' expr ')'
255                 { $$ = oper3(OGSUB,oper1(OREGEX,$3),$5,$7); }
256         ;
257
258 variable: VAR
259                 { $$ = oper1(OVAR,$1); }
260         | VAR '[' expr_list ']'
261                 { $$ = oper2(OVAR,aryrefarg($1),$3); }
262         | FIELD
263                 { $$ = oper1(OFLD,$1); }
264         | VFIELD term
265                 { $$ = oper1(OVFLD,$2); }
266         ;
267
268 expr_list
269         : expr
270         | clist
271         | /* NULL */
272                 { $$ = Nullop; }
273         ;
274
275 clist   : expr ',' maybe expr
276                 { $$ = oper3(OCOMMA,$1,$3,$4); }
277         | clist ',' maybe expr
278                 { $$ = oper3(OCOMMA,$1,$3,$4); }
279         | '(' clist ')'         /* these parens are invisible */
280                 { $$ = $2; }
281         ;
282
283 junk    : junk hunksep
284                 { $$ = oper2(OJUNK,$1,$2); }
285         | /* NULL */
286                 { $$ = Nullop; }
287         ;
288
289 hunksep : ';'
290                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
291         | SEMINEW
292                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
293         | NEWLINE
294                 { $$ = oper0(ONEWLINE); }
295         | COMMENT
296                 { $$ = oper1(OCOMMENT,$1); }
297         ;
298
299 maybe   : maybe nlstuff
300                 { $$ = oper2(OJUNK,$1,$2); }
301         | /* NULL */
302                 { $$ = Nullop; }
303         ;
304
305 nlstuff : NEWLINE
306                 { $$ = oper0(ONEWLINE); }
307         | COMMENT
308                 { $$ = oper1(OCOMMENT,$1); }
309         ;
310
311 separator
312         : ';' maybe
313                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),$2); }
314         | SEMINEW maybe
315                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
316         | NEWLINE maybe
317                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
318         | COMMENT maybe
319                 { $$ = oper2(OJUNK,oper1(OSCOMMENT,$1),$2); }
320         ;
321
322 states  : states statement
323                 { $$ = oper2(OSTATES,$1,$2); }
324         | /* NULL */
325                 { $$ = Nullop; }
326         ;
327
328 statement
329         : simple separator maybe
330                 { $$ = oper2(OJUNK,oper2(OSTATE,$1,$2),$3); }
331         | ';' maybe
332                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSEMICOLON),$2)); }
333         | SEMINEW maybe
334                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSNEWLINE),$2)); }
335         | compound
336         ;
337
338 simpnull: simple
339         | /* NULL */
340                 { $$ = Nullop; }
341         ;
342
343 simple
344         : expr
345         | PRINT expr_list redir expr
346                 { $$ = oper3(OPRINT,$2,$3,$4);
347                     do_opens = TRUE;
348                     saw_ORS = saw_OFS = TRUE;
349                     if (!$2) need_entire = TRUE;
350                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
351         | PRINT expr_list
352                 { $$ = oper1(OPRINT,$2);
353                     if (!$2) need_entire = TRUE;
354                     saw_ORS = saw_OFS = TRUE;
355                 }
356         | PRINTF expr_list redir expr
357                 { $$ = oper3(OPRINTF,$2,$3,$4);
358                     do_opens = TRUE;
359                     if (!$2) need_entire = TRUE;
360                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
361         | PRINTF expr_list
362                 { $$ = oper1(OPRINTF,$2);
363                     if (!$2) need_entire = TRUE;
364                 }
365         | BREAK
366                 { $$ = oper0(OBREAK); }
367         | NEXT
368                 { $$ = oper0(ONEXT); }
369         | EXIT
370                 { $$ = oper0(OEXIT); }
371         | EXIT expr
372                 { $$ = oper1(OEXIT,$2); }
373         | CONTINUE
374                 { $$ = oper0(OCONTINUE); }
375         | RET
376                 { $$ = oper0(ORETURN); }
377         | RET expr
378                 { $$ = oper1(ORETURN,$2); }
379         | DELETE VAR '[' expr ']'
380                 { $$ = oper2(ODELETE,aryrefarg($2),$4); }
381         ;
382
383 redir   : '>'   %prec FIELD
384                 { $$ = oper1(OREDIR,$1); }
385         | GRGR
386                 { $$ = oper1(OREDIR,string(">>",2)); }
387         | '|'
388                 { $$ = oper1(OREDIR,string("|",1)); }
389         ;
390
391 compound
392         : IF '(' cond ')' maybe statement
393                 { $$ = oper2(OIF,$3,bl($6,$5)); }
394         | IF '(' cond ')' maybe statement ELSE maybe statement
395                 { $$ = oper3(OIF,$3,bl($6,$5),bl($9,$8)); }
396         | WHILE '(' cond ')' maybe statement
397                 { $$ = oper2(OWHILE,$3,bl($6,$5)); }
398         | DO maybe statement WHILE '(' cond ')'
399                 { $$ = oper2(ODO,bl($3,$2),$6); }
400         | FOR '(' simpnull ';' cond ';' simpnull ')' maybe statement
401                 { $$ = oper4(OFOR,$3,$5,$7,bl($10,$9)); }
402         | FOR '(' simpnull ';'  ';' simpnull ')' maybe statement
403                 { $$ = oper4(OFOR,$3,string("",0),$6,bl($9,$8)); }
404         | FOR '(' expr ')' maybe statement
405                 { $$ = oper2(OFORIN,$3,bl($6,$5)); }
406         | '{' maybe states '}' maybe
407                 { $$ = oper3(OBLOCK,oper2(OJUNK,$2,$3),Nullop,$5); }
408         ;
409
410 %%
411 #include "a2py.c"