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