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"
|
---|