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