a "replacement" for awk and sed
[perl.git] / x2p / a2p.y
1 %{
2 /* $Header: a2p.y,v 1.0 87/12/18 13:07:05 root Exp $
3  *
4  * $Log:        a2p.y,v $
5  * Revision 1.0  87/12/18  13:07:05  root
6  * Initial revision
7  * 
8  */
9
10 #include "INTERN.h"
11 #include "a2p.h"
12
13 int root;
14
15 %}
16 %token BEGIN END
17 %token REGEX
18 %token SEMINEW NEWLINE COMMENT
19 %token FUN1 GRGR
20 %token PRINT PRINTF SPRINTF SPLIT
21 %token IF ELSE WHILE FOR IN
22 %token EXIT NEXT BREAK CONTINUE
23
24 %right ASGNOP
25 %left OROR
26 %left ANDAND
27 %left NOT
28 %left NUMBER VAR SUBSTR INDEX
29 %left GETLINE
30 %nonassoc RELOP MATCHOP
31 %left OR
32 %left STRING
33 %left '+' '-'
34 %left '*' '/' '%'
35 %right UMINUS
36 %left INCR DECR
37 %left FIELD VFIELD
38
39 %%
40
41 program : junk begin hunks end
42                 { root = oper4(OPROG,$1,$2,$3,$4); }
43         ;
44
45 begin   : BEGIN '{' states '}' junk
46                 { $$ = oper2(OJUNK,$3,$5); in_begin = FALSE; }
47         | /* NULL */
48                 { $$ = Nullop; }
49         ;
50
51 end     : END '{' states '}'
52                 { $$ = $3; }
53         | end NEWLINE
54                 { $$ = $1; }
55         | /* NULL */
56                 { $$ = Nullop; }
57         ;
58
59 hunks   : hunks hunk junk
60                 { $$ = oper3(OHUNKS,$1,$2,$3); }
61         | /* NULL */
62                 { $$ = Nullop; }
63         ;
64
65 hunk    : patpat
66                 { $$ = oper1(OHUNK,$1); need_entire = TRUE; }
67         | patpat '{' states '}'
68                 { $$ = oper2(OHUNK,$1,$3); }
69         | '{' states '}'
70                 { $$ = oper2(OHUNK,Nullop,$2); }
71         ;
72
73 patpat  : pat
74                 { $$ = oper1(OPAT,$1); }
75         | pat ',' pat
76                 { $$ = oper2(ORANGE,$1,$3); }
77         ;
78
79 pat     : REGEX
80                 { $$ = oper1(OREGEX,$1); }
81         | match
82         | rel
83         | compound_pat
84         ;
85
86 compound_pat
87         : '(' compound_pat ')'
88                 { $$ = oper1(OPPAREN,$2); }
89         | pat ANDAND pat
90                 { $$ = oper2(OPANDAND,$1,$3); }
91         | pat OROR pat
92                 { $$ = oper2(OPOROR,$1,$3); }
93         | NOT pat
94                 { $$ = oper1(OPNOT,$2); }
95         ;
96
97 cond    : expr
98         | match
99         | rel
100         | compound_cond
101         ;
102
103 compound_cond
104         : '(' compound_cond ')'
105                 { $$ = oper1(OCPAREN,$2); }
106         | cond ANDAND cond
107                 { $$ = oper2(OCANDAND,$1,$3); }
108         | cond OROR cond
109                 { $$ = oper2(OCOROR,$1,$3); }
110         | NOT cond
111                 { $$ = oper1(OCNOT,$2); }
112         ;
113
114 rel     : expr RELOP expr
115                 { $$ = oper3(ORELOP,$2,$1,$3); }
116         | '(' rel ')'
117                 { $$ = oper1(ORPAREN,$2); }
118         ;
119
120 match   : expr MATCHOP REGEX
121                 { $$ = oper3(OMATCHOP,$2,$1,$3); }
122         | '(' match ')'
123                 { $$ = oper1(OMPAREN,$2); }
124         ;
125
126 expr    : term
127                 { $$ = $1; }
128         | expr term
129                 { $$ = oper2(OCONCAT,$1,$2); }
130         | variable ASGNOP expr
131                 { $$ = oper3(OASSIGN,$2,$1,$3);
132                         if ((ops[$1].ival & 255) == OFLD)
133                             lval_field = TRUE;
134                         if ((ops[$1].ival & 255) == OVFLD)
135                             lval_field = TRUE;
136                 }
137         ;
138
139 term    : variable
140                 { $$ = $1; }
141         | term '+' term
142                 { $$ = oper2(OADD,$1,$3); }
143         | term '-' term
144                 { $$ = oper2(OSUB,$1,$3); }
145         | term '*' term
146                 { $$ = oper2(OMULT,$1,$3); }
147         | term '/' term
148                 { $$ = oper2(ODIV,$1,$3); }
149         | term '%' term
150                 { $$ = oper2(OMOD,$1,$3); }
151         | variable INCR
152                 { $$ = oper1(OPOSTINCR,$1); }
153         | variable DECR
154                 { $$ = oper1(OPOSTDECR,$1); }
155         | INCR variable
156                 { $$ = oper1(OPREINCR,$2); }
157         | DECR variable
158                 { $$ = oper1(OPREDECR,$2); }
159         | '-' term %prec UMINUS
160                 { $$ = oper1(OUMINUS,$2); }
161         | '+' term %prec UMINUS
162                 { $$ = oper1(OUPLUS,$2); }
163         | '(' expr ')'
164                 { $$ = oper1(OPAREN,$2); }
165         | GETLINE
166                 { $$ = oper0(OGETLINE); }
167         | FUN1
168                 { $$ = oper0($1); need_entire = do_chop = TRUE; }
169         | FUN1 '(' ')'
170                 { $$ = oper1($1,Nullop); need_entire = do_chop = TRUE; }
171         | FUN1 '(' expr ')'
172                 { $$ = oper1($1,$3); }
173         | SPRINTF print_list
174                 { $$ = oper1(OSPRINTF,$2); }
175         | SUBSTR '(' expr ',' expr ',' expr ')'
176                 { $$ = oper3(OSUBSTR,$3,$5,$7); }
177         | SUBSTR '(' expr ',' expr ')'
178                 { $$ = oper2(OSUBSTR,$3,$5); }
179         | SPLIT '(' expr ',' VAR ',' expr ')'
180                 { $$ = oper3(OSPLIT,$3,numary($5),$7); }
181         | SPLIT '(' expr ',' VAR ')'
182                 { $$ = oper2(OSPLIT,$3,numary($5)); }
183         | INDEX '(' expr ',' expr ')'
184                 { $$ = oper2(OINDEX,$3,$5); }
185         ;
186
187 variable: NUMBER
188                 { $$ = oper1(ONUM,$1); }
189         | STRING
190                 { $$ = oper1(OSTR,$1); }
191         | VAR
192                 { $$ = oper1(OVAR,$1); }
193         | VAR '[' expr ']'
194                 { $$ = oper2(OVAR,$1,$3); }
195         | FIELD
196                 { $$ = oper1(OFLD,$1); }
197         | VFIELD term
198                 { $$ = oper1(OVFLD,$2); }
199         ;
200
201 maybe   : NEWLINE
202                 { $$ = oper0(ONEWLINE); }
203         | /* NULL */
204                 { $$ = Nullop; }
205         | COMMENT
206                 { $$ = oper1(OCOMMENT,$1); }
207         ;
208
209 print_list
210         : expr
211         | clist
212         | /* NULL */
213                 { $$ = Nullop; }
214         ;
215
216 clist   : expr ',' expr
217                 { $$ = oper2(OCOMMA,$1,$3); }
218         | clist ',' expr
219                 { $$ = oper2(OCOMMA,$1,$3); }
220         | '(' clist ')'         /* these parens are invisible */
221                 { $$ = $2; }
222         ;
223
224 junk    : junk hunksep
225                 { $$ = oper2(OJUNK,$1,$2); }
226         | /* NULL */
227                 { $$ = Nullop; }
228         ;
229
230 hunksep : ';'
231                 { $$ = oper0(OSEMICOLON); }
232         | SEMINEW
233                 { $$ = oper0(OSEMICOLON); }
234         | NEWLINE
235                 { $$ = oper0(ONEWLINE); }
236         | COMMENT
237                 { $$ = oper1(OCOMMENT,$1); }
238         ;
239
240 separator
241         : ';'
242                 { $$ = oper0(OSEMICOLON); }
243         | SEMINEW
244                 { $$ = oper0(OSNEWLINE); }
245         | NEWLINE
246                 { $$ = oper0(OSNEWLINE); }
247         | COMMENT
248                 { $$ = oper1(OSCOMMENT,$1); }
249         ;
250
251 states  : states statement
252                 { $$ = oper2(OSTATES,$1,$2); }
253         | /* NULL */
254                 { $$ = Nullop; }
255         ;
256
257 statement
258         : simple separator
259                 { $$ = oper2(OSTATE,$1,$2); }
260         | compound
261         ;
262
263 simple
264         : expr
265         | PRINT print_list redir expr
266                 { $$ = oper3(OPRINT,$2,$3,$4);
267                     do_opens = TRUE;
268                     saw_ORS = saw_OFS = TRUE;
269                     if (!$2) need_entire = TRUE;
270                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
271         | PRINT print_list
272                 { $$ = oper1(OPRINT,$2);
273                     if (!$2) need_entire = TRUE;
274                     saw_ORS = saw_OFS = TRUE;
275                 }
276         | PRINTF print_list redir expr
277                 { $$ = oper3(OPRINTF,$2,$3,$4);
278                     do_opens = TRUE;
279                     if (!$2) need_entire = TRUE;
280                     if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
281         | PRINTF print_list
282                 { $$ = oper1(OPRINTF,$2);
283                     if (!$2) need_entire = TRUE;
284                 }
285         | BREAK
286                 { $$ = oper0(OBREAK); }
287         | NEXT
288                 { $$ = oper0(ONEXT); }
289         | EXIT
290                 { $$ = oper0(OEXIT); }
291         | EXIT expr
292                 { $$ = oper1(OEXIT,$2); }
293         | CONTINUE
294                 { $$ = oper0(OCONTINUE); }
295         | /* NULL */
296                 { $$ = Nullop; }
297         ;
298
299 redir   : RELOP
300                 { $$ = oper1(OREDIR,string(">",1)); }
301         | GRGR
302                 { $$ = oper1(OREDIR,string(">>",2)); }
303         | '|'
304                 { $$ = oper1(OREDIR,string("|",1)); }
305         ;
306
307 compound
308         : IF '(' cond ')' maybe statement
309                 { $$ = oper2(OIF,$3,bl($6,$5)); }
310         | IF '(' cond ')' maybe statement ELSE maybe statement
311                 { $$ = oper3(OIF,$3,bl($6,$5),bl($9,$8)); }
312         | WHILE '(' cond ')' maybe statement
313                 { $$ = oper2(OWHILE,$3,bl($6,$5)); }
314         | FOR '(' simple ';' cond ';' simple ')' maybe statement
315                 { $$ = oper4(OFOR,$3,$5,$7,bl($10,$9)); }
316         | FOR '(' simple ';'  ';' simple ')' maybe statement
317                 { $$ = oper4(OFOR,$3,string("",0),$6,bl($9,$8)); }
318         | FOR '(' VAR IN VAR ')' maybe statement
319                 { $$ = oper3(OFORIN,$3,$5,bl($8,$7)); }
320         | '{' states '}'
321                 { $$ = oper1(OBLOCK,$2); }
322         ;
323
324 %%
325 #include "a2py.c"