perl 4.0.00: (no release announcement available)
[p5sagit/p5-mst-13.2.git] / x2p / a2p.y
1 %{
2 /* $Header: a2p.y,v 4.0 91/03/20 01:57:21 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 4.0  91/03/20  01:57:21  lwall
11  * 4.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  : cond
91                 { $$ = oper1(OPAT,$1); }
92         | cond ',' cond
93                 { $$ = oper2(ORANGE,$1,$3); }
94         ;
95
96 cond    : expr
97         | match
98         | rel
99         | compound_cond
100         ;
101
102 compound_cond
103         : '(' compound_cond ')'
104                 { $$ = oper1(OCPAREN,$2); }
105         | cond ANDAND maybe cond
106                 { $$ = oper3(OCANDAND,$1,$3,$4); }
107         | cond OROR maybe cond
108                 { $$ = oper3(OCOROR,$1,$3,$4); }
109         | NOT cond
110                 { $$ = oper1(OCNOT,$2); }
111         ;
112
113 rel     : expr RELOP expr
114                 { $$ = oper3(ORELOP,$2,$1,$3); }
115         | expr '>' expr
116                 { $$ = oper3(ORELOP,string(">",1),$1,$3); }
117         | expr '<' expr
118                 { $$ = oper3(ORELOP,string("<",1),$1,$3); }
119         | '(' rel ')'
120                 { $$ = oper1(ORPAREN,$2); }
121         ;
122
123 match   : expr MATCHOP expr
124                 { $$ = oper3(OMATCHOP,$2,$1,$3); }
125         | expr MATCHOP REGEX
126                 { $$ = oper3(OMATCHOP,$2,$1,oper1(OREGEX,$3)); }
127         | REGEX         %prec MATCHOP
128                 { $$ = oper1(OREGEX,$1); }
129         | '(' match ')'
130                 { $$ = oper1(OMPAREN,$2); }
131         ;
132
133 expr    : term
134                 { $$ = $1; }
135         | expr term
136                 { $$ = oper2(OCONCAT,$1,$2); }
137         | variable ASGNOP cond
138                 { $$ = oper3(OASSIGN,$2,$1,$3);
139                         if ((ops[$1].ival & 255) == OFLD)
140                             lval_field = TRUE;
141                         if ((ops[$1].ival & 255) == OVFLD)
142                             lval_field = TRUE;
143                 }
144         ;
145
146 term    : variable
147                 { $$ = $1; }
148         | NUMBER
149                 { $$ = oper1(ONUM,$1); }
150         | STRING
151                 { $$ = oper1(OSTR,$1); }
152         | term '+' term
153                 { $$ = oper2(OADD,$1,$3); }
154         | term '-' term
155                 { $$ = oper2(OSUBTRACT,$1,$3); }
156         | term '*' term
157                 { $$ = oper2(OMULT,$1,$3); }
158         | term '/' term
159                 { $$ = oper2(ODIV,$1,$3); }
160         | term '%' term
161                 { $$ = oper2(OMOD,$1,$3); }
162         | term '^' term
163                 { $$ = oper2(OPOW,$1,$3); }
164         | term IN VAR
165                 { $$ = oper2(ODEFINED,aryrefarg($3),$1); }
166         | term '?' term ':' term
167                 { $$ = oper3(OCOND,$1,$3,$5); }
168         | variable INCR
169                 { $$ = oper1(OPOSTINCR,$1); }
170         | variable DECR
171                 { $$ = oper1(OPOSTDECR,$1); }
172         | INCR variable
173                 { $$ = oper1(OPREINCR,$2); }
174         | DECR variable
175                 { $$ = oper1(OPREDECR,$2); }
176         | '-' term %prec UMINUS
177                 { $$ = oper1(OUMINUS,$2); }
178         | '+' term %prec UMINUS
179                 { $$ = oper1(OUPLUS,$2); }
180         | '(' cond ')'
181                 { $$ = oper1(OPAREN,$2); }
182         | GETLINE
183                 { $$ = oper0(OGETLINE); }
184         | GETLINE VAR
185                 { $$ = oper1(OGETLINE,$2); }
186         | GETLINE '<' expr
187                 { $$ = oper3(OGETLINE,Nullop,string("<",1),$3);
188                     if (ops[$3].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
189         | GETLINE VAR '<' expr
190                 { $$ = oper3(OGETLINE,$2,string("<",1),$4);
191                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
192         | term 'p' GETLINE
193                 { $$ = oper3(OGETLINE,Nullop,string("|",1),$1);
194                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
195         | term 'p' GETLINE VAR
196                 { $$ = oper3(OGETLINE,$4,string("|",1),$1);
197                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
198         | FUN1
199                 { $$ = oper0($1); need_entire = do_chop = TRUE; }
200         | FUN1 '(' ')'
201                 { $$ = oper1($1,Nullop); need_entire = do_chop = TRUE; }
202         | FUN1 '(' expr ')'
203                 { $$ = oper1($1,$3); }
204         | FUNN '(' expr_list ')'
205                 { $$ = oper1($1,$3); }
206         | USERFUN '(' expr_list ')'
207                 { $$ = oper2(OUSERFUN,$1,$3); }
208         | SPRINTF expr_list
209                 { $$ = oper1(OSPRINTF,$2); }
210         | SUBSTR '(' expr ',' expr ',' expr ')'
211                 { $$ = oper3(OSUBSTR,$3,$5,$7); }
212         | SUBSTR '(' expr ',' expr ')'
213                 { $$ = oper2(OSUBSTR,$3,$5); }
214         | SPLIT '(' expr ',' VAR ',' expr ')'
215                 { $$ = oper3(OSPLIT,$3,aryrefarg(numary($5)),$7); }
216         | SPLIT '(' expr ',' VAR ',' REGEX ')'
217                 { $$ = oper3(OSPLIT,$3,aryrefarg(numary($5)),oper1(OREGEX,$7));}
218         | SPLIT '(' expr ',' VAR ')'
219                 { $$ = oper2(OSPLIT,$3,aryrefarg(numary($5))); }
220         | INDEX '(' expr ',' expr ')'
221                 { $$ = oper2(OINDEX,$3,$5); }
222         | MATCH '(' expr ',' REGEX ')'
223                 { $$ = oper2(OMATCH,$3,oper1(OREGEX,$5)); }
224         | MATCH '(' expr ',' expr ')'
225                 { $$ = oper2(OMATCH,$3,$5); }
226         | SUB '(' expr ',' expr ')'
227                 { $$ = oper2(OSUB,$3,$5); }
228         | SUB '(' REGEX ',' expr ')'
229                 { $$ = oper2(OSUB,oper1(OREGEX,$3),$5); }
230         | GSUB '(' expr ',' expr ')'
231                 { $$ = oper2(OGSUB,$3,$5); }
232         | GSUB '(' REGEX ',' expr ')'
233                 { $$ = oper2(OGSUB,oper1(OREGEX,$3),$5); }
234         | SUB '(' expr ',' expr ',' expr ')'
235                 { $$ = oper3(OSUB,$3,$5,$7); }
236         | SUB '(' REGEX ',' expr ',' expr ')'
237                 { $$ = oper3(OSUB,oper1(OREGEX,$3),$5,$7); }
238         | GSUB '(' expr ',' expr ',' expr ')'
239                 { $$ = oper3(OGSUB,$3,$5,$7); }
240         | GSUB '(' REGEX ',' expr ',' expr ')'
241                 { $$ = oper3(OGSUB,oper1(OREGEX,$3),$5,$7); }
242         ;
243
244 variable: VAR
245                 { $$ = oper1(OVAR,$1); }
246         | VAR '[' expr_list ']'
247                 { $$ = oper2(OVAR,aryrefarg($1),$3); }
248         | FIELD
249                 { $$ = oper1(OFLD,$1); }
250         | VFIELD term
251                 { $$ = oper1(OVFLD,$2); }
252         ;
253
254 expr_list
255         : expr
256         | clist
257         | /* NULL */
258                 { $$ = Nullop; }
259         ;
260
261 clist   : expr ',' maybe expr
262                 { $$ = oper3(OCOMMA,$1,$3,$4); }
263         | clist ',' maybe expr
264                 { $$ = oper3(OCOMMA,$1,$3,$4); }
265         | '(' clist ')'         /* these parens are invisible */
266                 { $$ = $2; }
267         ;
268
269 junk    : junk hunksep
270                 { $$ = oper2(OJUNK,$1,$2); }
271         | /* NULL */
272                 { $$ = Nullop; }
273         ;
274
275 hunksep : ';'
276                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
277         | SEMINEW
278                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
279         | NEWLINE
280                 { $$ = oper0(ONEWLINE); }
281         | COMMENT
282                 { $$ = oper1(OCOMMENT,$1); }
283         ;
284
285 maybe   : maybe nlstuff
286                 { $$ = oper2(OJUNK,$1,$2); }
287         | /* NULL */
288                 { $$ = Nullop; }
289         ;
290
291 nlstuff : NEWLINE
292                 { $$ = oper0(ONEWLINE); }
293         | COMMENT
294                 { $$ = oper1(OCOMMENT,$1); }
295         ;
296
297 separator
298         : ';' maybe
299                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),$2); }
300         | SEMINEW maybe
301                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
302         | NEWLINE maybe
303                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
304         | COMMENT maybe
305                 { $$ = oper2(OJUNK,oper1(OSCOMMENT,$1),$2); }
306         ;
307
308 states  : states statement
309                 { $$ = oper2(OSTATES,$1,$2); }
310         | /* NULL */
311                 { $$ = Nullop; }
312         ;
313
314 statement
315         : simple separator maybe
316                 { $$ = oper2(OJUNK,oper2(OSTATE,$1,$2),$3); }
317         | ';' maybe
318                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSEMICOLON),$2)); }
319         | SEMINEW maybe
320                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSNEWLINE),$2)); }
321         | compound
322         ;
323
324 simpnull: simple
325         | /* NULL */
326                 { $$ = Nullop; }
327         ;
328
329 simple
330         : expr
331         | PRINT expr_list redir expr
332                 { $$ = oper3(OPRINT,$2,$3,$4);
333                     do_opens = TRUE;
334                     saw_ORS = saw_OFS = TRUE;
335                     if (!$2) need_entire = TRUE;
336                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
337         | PRINT expr_list
338                 { $$ = oper1(OPRINT,$2);
339                     if (!$2) need_entire = TRUE;
340                     saw_ORS = saw_OFS = TRUE;
341                 }
342         | PRINTF expr_list redir expr
343                 { $$ = oper3(OPRINTF,$2,$3,$4);
344                     do_opens = TRUE;
345                     if (!$2) need_entire = TRUE;
346                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
347         | PRINTF expr_list
348                 { $$ = oper1(OPRINTF,$2);
349                     if (!$2) need_entire = TRUE;
350                 }
351         | BREAK
352                 { $$ = oper0(OBREAK); }
353         | NEXT
354                 { $$ = oper0(ONEXT); }
355         | EXIT
356                 { $$ = oper0(OEXIT); }
357         | EXIT expr
358                 { $$ = oper1(OEXIT,$2); }
359         | CONTINUE
360                 { $$ = oper0(OCONTINUE); }
361         | RET
362                 { $$ = oper0(ORETURN); }
363         | RET expr
364                 { $$ = oper1(ORETURN,$2); }
365         | DELETE VAR '[' expr ']'
366                 { $$ = oper2(ODELETE,aryrefarg($2),$4); }
367         ;
368
369 redir   : '>'   %prec FIELD
370                 { $$ = oper1(OREDIR,string(">",1)); }
371         | GRGR
372                 { $$ = oper1(OREDIR,string(">>",2)); }
373         | '|'
374                 { $$ = oper1(OREDIR,string("|",1)); }
375         ;
376
377 compound
378         : IF '(' cond ')' maybe statement
379                 { $$ = oper2(OIF,$3,bl($6,$5)); }
380         | IF '(' cond ')' maybe statement ELSE maybe statement
381                 { $$ = oper3(OIF,$3,bl($6,$5),bl($9,$8)); }
382         | WHILE '(' cond ')' maybe statement
383                 { $$ = oper2(OWHILE,$3,bl($6,$5)); }
384         | DO maybe statement WHILE '(' cond ')'
385                 { $$ = oper2(ODO,bl($3,$2),$6); }
386         | FOR '(' simpnull ';' cond ';' simpnull ')' maybe statement
387                 { $$ = oper4(OFOR,$3,$5,$7,bl($10,$9)); }
388         | FOR '(' simpnull ';'  ';' simpnull ')' maybe statement
389                 { $$ = oper4(OFOR,$3,string("",0),$6,bl($9,$8)); }
390         | FOR '(' expr ')' maybe statement
391                 { $$ = oper2(OFORIN,$3,bl($6,$5)); }
392         | '{' maybe states '}' maybe
393                 { $$ = oper3(OBLOCK,oper2(OJUNK,$2,$3),Nullop,$5); }
394         ;
395
396 %%
397 #include "a2py.c"