|
|
1.1 ! root 1: %{ ! 2: #include "awk.h" ! 3: yywrap() { return(1); } ! 4: #ifndef DEBUG ! 5: # define PUTS(x) ! 6: #endif ! 7: Node *beginloc = 0, *endloc = 0; ! 8: int infunc = 0; /* = 1 if in arglist or body of func */ ! 9: uchar *curfname = 0; ! 10: Node *arglist = 0; /* list of args for current function */ ! 11: uchar *strnode(); ! 12: %} ! 13: ! 14: %union { ! 15: Node *p; ! 16: Cell *cp; ! 17: int i; ! 18: uchar *s; ! 19: } ! 20: ! 21: %token <i> FIRSTTOKEN /* must be first */ ! 22: %token <i> FATAL ! 23: %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND ! 24: %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']' ! 25: %token <i> ARRAY ! 26: %token <i> MATCH NOTMATCH MATCHOP ! 27: %token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS ! 28: %token <i> AND BOR APPEND EQ GE GT LE LT NE IN ! 29: %token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC ! 30: %token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT ! 31: %token <i> ADD MINUS MULT DIVIDE MOD ! 32: %token <i> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ ! 33: %token <i> PRINT PRINTF SPRINTF ! 34: %token <p> ELSE INTEST CONDEXPR ! 35: %token <i> POSTINCR PREINCR POSTDECR PREDECR ! 36: %token <cp> VAR IVAR VARNF CALL NUMBER STRING FIELD ! 37: %token <s> REGEXPR ! 38: ! 39: %type <p> pas pattern ppattern plist pplist patlist prarg term ! 40: %type <p> pa_pat pa_stat pa_stats reg_expr ! 41: %type <p> simple_stmt opt_simple_stmt stmt stmtlist ! 42: %type <p> var varname funcname varlist ! 43: %type <p> for if while ! 44: %type <i> pst opt_pst lbrace rparen comma nl opt_nl and bor ! 45: %type <i> subop print ! 46: ! 47: %right ASGNOP ! 48: %right '?' ! 49: %right ':' ! 50: %left BOR ! 51: %left AND ! 52: %left GETLINE ! 53: %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|' ! 54: %left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FIELD FUNC ! 55: %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER ! 56: %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR ! 57: %left REGEXPR VAR VARNF IVAR WHILE '(' ! 58: %left CAT ! 59: %left '+' '-' ! 60: %left '*' '/' '%' ! 61: %left NOT UMINUS ! 62: %right POWER ! 63: %right DECR INCR ! 64: %left INDIRECT ! 65: %token LASTTOKEN /* must be last */ ! 66: ! 67: %% ! 68: ! 69: program: ! 70: pas { if (errorflag==0) ! 71: winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); } ! 72: | error { yyclearin; bracecheck(); yyerror("bailing out"); } ! 73: ; ! 74: ! 75: and: ! 76: AND | and NL ! 77: ; ! 78: ! 79: bor: ! 80: BOR | bor NL ! 81: ; ! 82: ! 83: comma: ! 84: ',' | comma NL ! 85: ; ! 86: ! 87: do: ! 88: DO | do NL ! 89: ; ! 90: ! 91: else: ! 92: ELSE | else NL ! 93: ; ! 94: ! 95: for: ! 96: FOR '(' opt_simple_stmt ';' pattern ';' opt_simple_stmt rparen stmt ! 97: { $$ = stat4(FOR, $3, op2(NE,$5,nullnode), $7, $9); } ! 98: | FOR '(' opt_simple_stmt ';' ';' opt_simple_stmt rparen stmt ! 99: { $$ = stat4(FOR, $3, NIL, $6, $8); } ! 100: | FOR '(' varname IN varname rparen stmt ! 101: { $$ = stat3(IN, $3, makearr($5), $7); } ! 102: ; ! 103: ! 104: funcname: ! 105: VAR { setfname($1); } ! 106: | CALL { setfname($1); } ! 107: ; ! 108: ! 109: if: ! 110: IF '(' pattern rparen { $$ = op2(NE,$3,nullnode); } ! 111: ; ! 112: ! 113: lbrace: ! 114: '{' | lbrace NL ! 115: ; ! 116: ! 117: nl: ! 118: NL | nl NL ! 119: ; ! 120: ! 121: opt_nl: ! 122: /* empty */ { $$ = 0; } ! 123: | nl ! 124: ; ! 125: ! 126: opt_pst: ! 127: /* empty */ { $$ = 0; } ! 128: | pst ! 129: ; ! 130: ! 131: ! 132: opt_simple_stmt: ! 133: /* empty */ { $$ = 0; } ! 134: | simple_stmt ! 135: ; ! 136: ! 137: pas: ! 138: opt_pst { $$ = 0; } ! 139: | opt_pst pa_stats opt_pst { $$ = $2; } ! 140: ; ! 141: ! 142: pa_pat: ! 143: pattern { $$ = op2(NE, $1, nullnode); } ! 144: ; ! 145: ! 146: pa_stat: ! 147: pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); } ! 148: | pa_pat lbrace stmtlist '}' { $$ = stat2(PASTAT, $1, $3); } ! 149: | pa_pat ',' pa_pat { $$ = pa2stat($1, $3, stat2(PRINT, rectonode(), NIL)); } ! 150: | pa_pat ',' pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $3, $5); } ! 151: | lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); } ! 152: | XBEGIN lbrace stmtlist '}' ! 153: { beginloc = linkum(beginloc, $3); $$ = 0; } ! 154: | XEND lbrace stmtlist '}' ! 155: { endloc = linkum(endloc, $3); $$ = 0; } ! 156: | FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}' ! 157: { infunc--; curfname=0; defn($2, $4, $8); $$ = 0; } ! 158: ; ! 159: ! 160: pa_stats: ! 161: pa_stat ! 162: | pa_stats pst pa_stat { $$ = linkum($1, $3); } ! 163: ; ! 164: ! 165: patlist: ! 166: pattern ! 167: | patlist comma pattern { $$ = linkum($1, $3); } ! 168: ; ! 169: ! 170: ppattern: ! 171: var ASGNOP ppattern { $$ = op2($2, $1, $3); } ! 172: | ppattern '?' ppattern ':' ppattern %prec '?' ! 173: { $$ = op3(CONDEXPR, op2(NE,$1,nullnode), $3, $5); } ! 174: | ppattern bor ppattern %prec BOR ! 175: { $$ = op2(BOR, op2(NE,$1,nullnode), op2(NE,$3,nullnode)); } ! 176: | ppattern and ppattern %prec AND ! 177: { $$ = op2(AND, op2(NE,$1,nullnode), op2(NE,$3,nullnode)); } ! 178: | NOT ppattern ! 179: { $$ = op1(NOT, op2(NE,$2,nullnode)); } ! 180: | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, makedfa($3, 0)); } ! 181: | ppattern MATCHOP ppattern ! 182: { if (constnode($3)) ! 183: $$ = op3($2, NIL, $1, makedfa(strnode($3), 0)); ! 184: else ! 185: $$ = op3($2, (Node *)1, $1, $3); } ! 186: | ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } ! 187: | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } ! 188: | ppattern term %prec CAT { $$ = op2(CAT, $1, $2); } ! 189: | reg_expr ! 190: { $$ = op3(MATCH, NIL, rectonode(), makedfa($1, 0)); } ! 191: | term ! 192: ; ! 193: ! 194: pattern: ! 195: var ASGNOP pattern { $$ = op2($2, $1, $3); } ! 196: | pattern '?' pattern ':' pattern %prec '?' ! 197: { $$ = op3(CONDEXPR, op2(NE,$1,nullnode), $3, $5); } ! 198: | pattern bor pattern %prec BOR ! 199: { $$ = op2(BOR, op2(NE,$1,nullnode), op2(NE,$3,nullnode)); } ! 200: | pattern and pattern %prec AND ! 201: { $$ = op2(AND, op2(NE,$1,nullnode), op2(NE,$3,nullnode)); } ! 202: | NOT pattern ! 203: { $$ = op1(NOT, op2(NE,$2,valtonode(lookup("$zero&null",symtab),CCON))); } ! 204: | pattern EQ pattern { $$ = op2($2, $1, $3); } ! 205: | pattern GE pattern { $$ = op2($2, $1, $3); } ! 206: | pattern GT pattern { $$ = op2($2, $1, $3); } ! 207: | pattern LE pattern { $$ = op2($2, $1, $3); } ! 208: | pattern LT pattern { $$ = op2($2, $1, $3); } ! 209: | pattern NE pattern { $$ = op2($2, $1, $3); } ! 210: | pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, makedfa($3, 0)); } ! 211: | pattern MATCHOP pattern ! 212: { if (constnode($3)) ! 213: $$ = op3($2, NIL, $1, makedfa(strnode($3), 0)); ! 214: else ! 215: $$ = op3($2, (Node *)1, $1, $3); } ! 216: | pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } ! 217: | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } ! 218: | pattern '|' GETLINE var { $$ = op3(GETLINE, $4, (Node*)$2, $1); } ! 219: | pattern '|' GETLINE { $$ = op3(GETLINE, (Node*)0, (Node*)$2, $1); } ! 220: | pattern term %prec CAT { $$ = op2(CAT, $1, $2); } ! 221: | reg_expr ! 222: { $$ = op3(MATCH, NIL, rectonode(), makedfa($1, 0)); } ! 223: | term ! 224: ; ! 225: ! 226: plist: ! 227: pattern comma pattern { $$ = linkum($1, $3); } ! 228: | plist comma pattern { $$ = linkum($1, $3); } ! 229: ; ! 230: ! 231: pplist: ! 232: ppattern ! 233: | pplist comma ppattern { $$ = linkum($1, $3); } ! 234: ! 235: prarg: ! 236: /* empty */ { $$ = rectonode(); } ! 237: | pplist ! 238: | '(' plist ')' { $$ = $2; } ! 239: ; ! 240: ! 241: print: ! 242: PRINT | PRINTF ! 243: ; ! 244: ! 245: pst: ! 246: NL | ';' | pst NL | pst ';' ! 247: ; ! 248: ! 249: rbrace: ! 250: '}' | rbrace NL ! 251: ; ! 252: ! 253: reg_expr: ! 254: '/' {startreg();} REGEXPR '/' { $$ = (Node *) $3; } ! 255: ; ! 256: ! 257: rparen: ! 258: ')' | rparen NL ! 259: ; ! 260: ! 261: simple_stmt: ! 262: print prarg '|' term { $$ = stat3($1, $2, (Node *) $3, $4); } ! 263: | print prarg APPEND term { $$ = stat3($1, $2, (Node *) $3, $4); } ! 264: | print prarg GT term { $$ = stat3($1, $2, (Node *) $3, $4); } ! 265: | print prarg { $$ = stat3($1, $2, NIL, NIL); } ! 266: | DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); } ! 267: | pattern { $$ = exptostat($1); } ! 268: | error { yyclearin; yyerror("illegal statement"); } ! 269: ; ! 270: ! 271: st: ! 272: nl | ';' opt_nl ! 273: ; ! 274: ! 275: stmt: ! 276: BREAK st { $$ = stat1(BREAK, NIL); } ! 277: | CLOSE pattern st { $$ = stat1(CLOSE, $2); } ! 278: | CONTINUE st { $$ = stat1(CONTINUE, NIL); } ! 279: | do stmt WHILE '(' pattern ')' st ! 280: { $$ = stat2(DO, $2, op2(NE,$5,nullnode)); } ! 281: | EXIT pattern st { $$ = stat1(EXIT, $2); } ! 282: | EXIT st { $$ = stat1(EXIT, NIL); } ! 283: | for ! 284: | if stmt else stmt { $$ = stat3(IF, $1, $2, $4); } ! 285: | if stmt { $$ = stat3(IF, $1, $2, NIL); } ! 286: | lbrace stmtlist rbrace { $$ = $2; } ! 287: | NEXT st { if (infunc) ! 288: yyerror("next is illegal inside a function"); ! 289: $$ = stat1(NEXT, NIL); } ! 290: | RETURN pattern st { $$ = stat1(RETURN, $2); } ! 291: | RETURN st { $$ = stat1(RETURN, NIL); } ! 292: | simple_stmt st ! 293: | while stmt { $$ = stat2(WHILE, $1, $2); } ! 294: | ';' opt_nl { $$ = 0; } ! 295: ; ! 296: ! 297: stmtlist: ! 298: stmt ! 299: | stmtlist stmt { $$ = linkum($1, $2); } ! 300: ; ! 301: ! 302: subop: ! 303: SUB | GSUB ! 304: ; ! 305: ! 306: term: ! 307: term '+' term { $$ = op2(ADD, $1, $3); } ! 308: | term '-' term { $$ = op2(MINUS, $1, $3); } ! 309: | term '*' term { $$ = op2(MULT, $1, $3); } ! 310: | term '/' term { $$ = op2(DIVIDE, $1, $3); } ! 311: | term '%' term { $$ = op2(MOD, $1, $3); } ! 312: | term POWER term { $$ = op2(POWER, $1, $3); } ! 313: | '-' term %prec UMINUS { $$ = op1(UMINUS, $2); } ! 314: | '+' term %prec UMINUS { $$ = $2; } ! 315: | BLTIN '(' ')' { $$ = op2(BLTIN, (Node *) $1, rectonode()); } ! 316: | BLTIN '(' patlist ')' { $$ = op2(BLTIN, (Node *) $1, $3); } ! 317: | BLTIN { $$ = op2(BLTIN, (Node *) $1, rectonode()); } ! 318: | CALL '(' ')' { $$ = op2(CALL, valtonode($1,CVAR), NIL); } ! 319: | CALL '(' patlist ')' { $$ = op2(CALL, valtonode($1,CVAR), $3); } ! 320: | DECR var { $$ = op1(PREDECR, $2); } ! 321: | INCR var { $$ = op1(PREINCR, $2); } ! 322: | var DECR { $$ = op1(POSTDECR, $1); } ! 323: | var INCR { $$ = op1(POSTINCR, $1); } ! 324: | GETLINE var LT term { $$ = op3(GETLINE, $2, (Node *)$3, $4); } ! 325: | GETLINE LT term { $$ = op3(GETLINE, NIL, (Node *)$2, $3); } ! 326: | GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); } ! 327: | GETLINE { $$ = op3(GETLINE, NIL, NIL, NIL); } ! 328: | INDEX '(' pattern comma pattern ')' ! 329: { $$ = op2(INDEX, $3, $5); } ! 330: | INDEX '(' pattern comma reg_expr ')' ! 331: { yyerror("index() doesn't permit regular expressions"); ! 332: $$ = op2(INDEX, $3, $5); } ! 333: | '(' pattern ')' { $$ = $2; } ! 334: | MATCHFCN '(' pattern comma reg_expr ')' ! 335: { $$ = op3(MATCHFCN, NIL, $3, makedfa($5, 1)); } ! 336: | MATCHFCN '(' pattern comma pattern ')' ! 337: { if (constnode($5)) ! 338: $$ = op3(MATCHFCN, NIL, $3, makedfa(strnode($5), 1)); ! 339: else ! 340: $$ = op3(MATCHFCN, (Node *)1, $3, $5); } ! 341: | NUMBER { $$ = valtonode($1, CCON); } ! 342: | SPLIT '(' pattern comma varname comma pattern ')' /* string */ ! 343: { $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); } ! 344: | SPLIT '(' pattern comma varname comma reg_expr ')' /* const /regexp/ */ ! 345: { $$ = op4(SPLIT, $3, makearr($5), makedfa($7, 1), (Node *)REGEXPR); } ! 346: | SPLIT '(' pattern comma varname ')' ! 347: { $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); } /* default */ ! 348: | SPRINTF '(' patlist ')' { $$ = op1($1, $3); } ! 349: | STRING { $$ = valtonode($1, CCON); } ! 350: | subop '(' reg_expr comma pattern ')' ! 351: { $$ = op4($1, NIL, makedfa($3, 1), $5, rectonode()); } ! 352: | subop '(' pattern comma pattern ')' ! 353: { if (constnode($3)) ! 354: $$ = op4($1, NIL, makedfa(strnode($3), 1), $5, rectonode()); ! 355: else ! 356: $$ = op4($1, (Node *)1, $3, $5, rectonode()); } ! 357: | subop '(' reg_expr comma pattern comma pattern ')' ! 358: { $$ = op4($1, NIL, makedfa($3, 1), $5, $7); } ! 359: | subop '(' pattern comma pattern comma pattern ')' ! 360: { if (constnode($3)) ! 361: $$ = op4($1, NIL, makedfa(strnode($3), 1), $5, $7); ! 362: else ! 363: $$ = op4($1, (Node *)1, $3, $5, $7); } ! 364: | SUBSTR '(' pattern comma pattern comma pattern ')' ! 365: { $$ = op3(SUBSTR, $3, $5, $7); } ! 366: | SUBSTR '(' pattern comma pattern ')' ! 367: { $$ = op3(SUBSTR, $3, $5, NIL); } ! 368: | var ! 369: ; ! 370: ! 371: var: ! 372: varname ! 373: | varname '[' patlist ']' { $$ = op2(ARRAY, makearr($1), $3); } ! 374: | FIELD { $$ = valtonode($1, CFLD); } ! 375: | IVAR { $$ = op1(INDIRECT, valtonode($1, CVAR)); } ! 376: | INDIRECT term { $$ = op1(INDIRECT, $2); } ! 377: ; ! 378: ! 379: varlist: ! 380: /* nothing */ { arglist = $$ = 0; } ! 381: | VAR { arglist = $$ = valtonode($1,CVAR); } ! 382: | varlist comma VAR { arglist = $$ = linkum($1,valtonode($3,CVAR)); } ! 383: ; ! 384: ! 385: varname: ! 386: VAR { $$ = valtonode($1, CVAR); } ! 387: | ARG { $$ = op1(ARG, (Node *) $1); } ! 388: | VARNF { $$ = op1(VARNF, (Node *) $1); } ! 389: ; ! 390: ! 391: ! 392: while: ! 393: WHILE '(' pattern rparen { $$ = op2(NE,$3,nullnode); } ! 394: ; ! 395: ! 396: %% ! 397: ! 398: setfname(p) ! 399: Cell *p; ! 400: { ! 401: if (isarr(p)) ! 402: yyerror("%s is an array, not a function", p->nval); ! 403: else if (isfunc(p)) ! 404: yyerror("you can't define function %s more than once", p->nval); ! 405: curfname = p->nval; ! 406: } ! 407: ! 408: constnode(p) ! 409: Node *p; ! 410: { ! 411: return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON; ! 412: } ! 413: ! 414: uchar *strnode(p) ! 415: Node *p; ! 416: { ! 417: return ((Cell *)(p->narg[0]))->sval; ! 418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.