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"