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