This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Protection against trailing spaces in embed.fnc
[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
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                 { $$ = oper3(OASSIGN,$2,$1,$3);
141                         if ((ops[$1].ival & 255) == OFLD)
142                             lval_field = TRUE;
143                         if ((ops[$1].ival & 255) == OVFLD)
144                             lval_field = TRUE;
145                 }
146         ;
147
148 sprintf : SPRINTF_NEW
149         | SPRINTF_OLD ;
150
151 term    : variable
152                 { $$ = $1; }
153         | NUMBER
154                 { $$ = oper1(ONUM,$1); }
155         | STRING
156                 { $$ = oper1(OSTR,$1); }
157         | term '+' term
158                 { $$ = oper2(OADD,$1,$3); }
159         | term '-' term
160                 { $$ = oper2(OSUBTRACT,$1,$3); }
161         | term '*' term
162                 { $$ = oper2(OMULT,$1,$3); }
163         | term '/' term
164                 { $$ = oper2(ODIV,$1,$3); }
165         | term '%' term
166                 { $$ = oper2(OMOD,$1,$3); }
167         | term '^' term
168                 { $$ = oper2(OPOW,$1,$3); }
169         | term IN VAR
170                 { $$ = oper2(ODEFINED,aryrefarg($3),$1); }
171         | variable INCR
172                 { $$ = oper1(OPOSTINCR,$1); }
173         | variable DECR
174                 { $$ = oper1(OPOSTDECR,$1); }
175         | INCR variable
176                 { $$ = oper1(OPREINCR,$2); }
177         | DECR variable
178                 { $$ = oper1(OPREDECR,$2); }
179         | '-' term %prec UMINUS
180                 { $$ = oper1(OUMINUS,$2); }
181         | '+' term %prec UMINUS
182                 { $$ = oper1(OUPLUS,$2); }
183         | '(' cond ')'
184                 { $$ = oper1(OPAREN,$2); }
185         | GETLINE
186                 { $$ = oper0(OGETLINE); }
187         | GETLINE variable
188                 { $$ = oper1(OGETLINE,$2); }
189         | GETLINE '<' expr
190                 { $$ = oper3(OGETLINE,Nullop,string("<",1),$3);
191                     if (ops[$3].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
192         | GETLINE variable '<' expr
193                 { $$ = oper3(OGETLINE,$2,string("<",1),$4);
194                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
195         | term 'p' GETLINE
196                 { $$ = oper3(OGETLINE,Nullop,string("|",1),$1);
197                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
198         | term 'p' GETLINE variable
199                 { $$ = oper3(OGETLINE,$4,string("|",1),$1);
200                     if (ops[$1].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
201         | FUN1
202                 { $$ = oper0($1); need_entire = do_chop = TRUE; }
203         | FUN1 '(' ')'
204                 { $$ = oper1($1,Nullop); need_entire = do_chop = TRUE; }
205         | FUN1 '(' expr ')'
206                 { $$ = oper1($1,$3); }
207         | FUNN '(' expr_list ')'
208                 { $$ = oper1($1,$3); }
209         | USERFUN '(' expr_list ')'
210                 { $$ = oper2(OUSERFUN,$1,$3); }
211         | SPRINTF_NEW '(' expr_list ')'
212                 { $$ = oper1(OSPRINTF,$3); }
213         | sprintf expr_list
214                 { $$ = oper1(OSPRINTF,$2); }
215         | SUBSTR '(' expr ',' expr ',' expr ')'
216                 { $$ = oper3(OSUBSTR,$3,$5,$7); }
217         | SUBSTR '(' expr ',' expr ')'
218                 { $$ = oper2(OSUBSTR,$3,$5); }
219         | SPLIT '(' expr ',' VAR ',' expr ')'
220                 { $$ = oper3(OSPLIT,$3,aryrefarg(numary($5)),$7); }
221         | SPLIT '(' expr ',' VAR ',' REGEX ')'
222                 { $$ = oper3(OSPLIT,$3,aryrefarg(numary($5)),oper1(OREGEX,$7));}
223         | SPLIT '(' expr ',' VAR ')'
224                 { $$ = oper2(OSPLIT,$3,aryrefarg(numary($5))); }
225         | INDEX '(' expr ',' expr ')'
226                 { $$ = oper2(OINDEX,$3,$5); }
227         | MATCH '(' expr ',' REGEX ')'
228                 { $$ = oper2(OMATCH,$3,oper1(OREGEX,$5)); }
229         | MATCH '(' expr ',' expr ')'
230                 { $$ = oper2(OMATCH,$3,$5); }
231         | SUB '(' expr ',' expr ')'
232                 { $$ = oper2(OSUB,$3,$5); }
233         | SUB '(' REGEX ',' expr ')'
234                 { $$ = oper2(OSUB,oper1(OREGEX,$3),$5); }
235         | GSUB '(' expr ',' expr ')'
236                 { $$ = oper2(OGSUB,$3,$5); }
237         | GSUB '(' REGEX ',' expr ')'
238                 { $$ = oper2(OGSUB,oper1(OREGEX,$3),$5); }
239         | SUB '(' expr ',' expr ',' expr ')'
240                 { $$ = oper3(OSUB,$3,$5,$7); }
241         | SUB '(' REGEX ',' expr ',' expr ')'
242                 { $$ = oper3(OSUB,oper1(OREGEX,$3),$5,$7); }
243         | GSUB '(' expr ',' expr ',' expr ')'
244                 { $$ = oper3(OGSUB,$3,$5,$7); }
245         | GSUB '(' REGEX ',' expr ',' expr ')'
246                 { $$ = oper3(OGSUB,oper1(OREGEX,$3),$5,$7); }
247         ;
248
249 variable: VAR
250                 { $$ = oper1(OVAR,$1); }
251         | VAR '[' expr_list ']'
252                 { $$ = oper2(OVAR,aryrefarg($1),$3); }
253         | FIELD
254                 { $$ = oper1(OFLD,$1); }
255         | VFIELD term
256                 { $$ = oper1(OVFLD,$2); }
257         ;
258
259 expr_list
260         : expr
261         | clist
262         | /* NULL */
263                 { $$ = Nullop; }
264         ;
265
266 clist   : expr ',' maybe expr
267                 { $$ = oper3(OCOMMA,$1,$3,$4); }
268         | clist ',' maybe expr
269                 { $$ = oper3(OCOMMA,$1,$3,$4); }
270         | '(' clist ')'         /* these parens are invisible */
271                 { $$ = $2; }
272         ;
273
274 junk    : junk hunksep
275                 { $$ = oper2(OJUNK,$1,$2); }
276         | /* NULL */
277                 { $$ = Nullop; }
278         ;
279
280 hunksep : ';'
281                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
282         | SEMINEW
283                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),oper0(ONEWLINE)); }
284         | NEWLINE
285                 { $$ = oper0(ONEWLINE); }
286         | COMMENT
287                 { $$ = oper1(OCOMMENT,$1); }
288         ;
289
290 maybe   : maybe nlstuff
291                 { $$ = oper2(OJUNK,$1,$2); }
292         | /* NULL */
293                 { $$ = Nullop; }
294         ;
295
296 nlstuff : NEWLINE
297                 { $$ = oper0(ONEWLINE); }
298         | COMMENT
299                 { $$ = oper1(OCOMMENT,$1); }
300         ;
301
302 separator
303         : ';' maybe
304                 { $$ = oper2(OJUNK,oper0(OSEMICOLON),$2); }
305         | SEMINEW maybe
306                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
307         | NEWLINE maybe
308                 { $$ = oper2(OJUNK,oper0(OSNEWLINE),$2); }
309         | COMMENT maybe
310                 { $$ = oper2(OJUNK,oper1(OSCOMMENT,$1),$2); }
311         ;
312
313 states  : states statement
314                 { $$ = oper2(OSTATES,$1,$2); }
315         | /* NULL */
316                 { $$ = Nullop; }
317         ;
318
319 statement
320         : simple separator maybe
321                 { $$ = oper2(OJUNK,oper2(OSTATE,$1,$2),$3); }
322         | ';' maybe
323                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSEMICOLON),$2)); }
324         | SEMINEW maybe
325                 { $$ = oper2(OSTATE,Nullop,oper2(OJUNK,oper0(OSNEWLINE),$2)); }
326         | compound
327         ;
328
329 simpnull: simple
330         | /* NULL */
331                 { $$ = Nullop; }
332         ;
333
334 simple
335         : expr
336         | PRINT expr_list redir expr
337                 { $$ = oper3(OPRINT,$2,$3,$4);
338                     do_opens = TRUE;
339                     saw_ORS = saw_OFS = TRUE;
340                     if (!$2) need_entire = TRUE;
341                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
342         | PRINT expr_list
343                 { $$ = oper1(OPRINT,$2);
344                     if (!$2) need_entire = TRUE;
345                     saw_ORS = saw_OFS = TRUE;
346                 }
347         | PRINTF expr_list redir expr
348                 { $$ = oper3(OPRINTF,$2,$3,$4);
349                     do_opens = TRUE;
350                     if (!$2) need_entire = TRUE;
351                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
352         | PRINTF expr_list
353                 { $$ = oper1(OPRINTF,$2);
354                     if (!$2) need_entire = TRUE;
355                 }
356         | BREAK
357                 { $$ = oper0(OBREAK); }
358         | NEXT
359                 { $$ = oper0(ONEXT); }
360         | EXIT
361                 { $$ = oper0(OEXIT); }
362         | EXIT expr
363                 { $$ = oper1(OEXIT,$2); }
364         | CONTINUE
365                 { $$ = oper0(OCONTINUE); }
366         | RET
367                 { $$ = oper0(ORETURN); }
368         | RET expr
369                 { $$ = oper1(ORETURN,$2); }
370         | DELETE VAR '[' expr_list ']'
371                 { $$ = oper2(ODELETE,aryrefarg($2),$4); }
372         ;
373
374 redir   : '>'   %prec FIELD
375                 { $$ = oper1(OREDIR,string(">",1)); }
376         | GRGR
377                 { $$ = oper1(OREDIR,string(">>",2)); }
378         | '|'
379                 { $$ = oper1(OREDIR,string("|",1)); }
380         ;
381
382 compound
383         : IF '(' cond ')' maybe statement
384                 { $$ = oper2(OIF,$3,bl($6,$5)); }
385         | IF '(' cond ')' maybe statement ELSE maybe statement
386                 { $$ = oper3(OIF,$3,bl($6,$5),bl($9,$8)); }
387         | WHILE '(' cond ')' maybe statement
388                 { $$ = oper2(OWHILE,$3,bl($6,$5)); }
389         | DO maybe statement WHILE '(' cond ')'
390                 { $$ = oper2(ODO,bl($3,$2),$6); }
391         | FOR '(' simpnull ';' cond ';' simpnull ')' maybe statement
392                 { $$ = oper4(OFOR,$3,$5,$7,bl($10,$9)); }
393         | FOR '(' simpnull ';'  ';' simpnull ')' maybe statement
394                 { $$ = oper4(OFOR,$3,string("",0),$6,bl($9,$8)); }
395         | FOR '(' expr ')' maybe statement
396                 { $$ = oper2(OFORIN,$3,bl($6,$5)); }
397         | '{' maybe states '}' maybe
398                 { $$ = oper3(OBLOCK,oper2(OJUNK,$2,$3),Nullop,$5); }
399         ;
400
401 %%
402
403 int yyparse (void);
404
405 #include "a2py.c"