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