|
|
1.1 ! root 1: /* ! 2: * AWK grammar ! 3: * yacc -prods 120 -terms 80 -nterms 40 -states 200 awk.y ! 4: * to make it fit on the PDP-11 (non separated I/D). ! 5: * Do not be surprised at the 48 S/R ! 6: * conflicts that this grammar gets ! 7: * from yacc. Worry if you get more ! 8: * though. This is mostly due to ! 9: * the combination of implicit string ! 10: * concatenation mixed with embedded assignments. ! 11: * In addition, 12 of these come from regular ! 12: * expressions. ! 13: * (NOTE: unary minus cannot be done because ! 14: * it is totally ambiguous with string concatentation. ! 15: * and output redirection is disambiguated by disallowing ! 16: * the relation '>' in `print' and `printf' statements.) ! 17: */ ! 18: ! 19: %{ ! 20: #include "awk.h" ! 21: ! 22: %} ! 23: ! 24: %union { ! 25: int u_char; ! 26: CHAR *u_charp; ! 27: NODE *u_node; ! 28: int (*u_func)(); ! 29: } ! 30: ! 31: %token IF_ WHILE_ FOR_ ELSE_ BREAK_ CONTINUE_ NEXT_ EXIT_ ! 32: %token IN_ ! 33: %token PRINT_ PRINTF_ ! 34: %token BEGIN_ END_ ! 35: %token FAPPEND_ FOUT_ ! 36: %token <u_node> ID_ STRING_ NUMBER_ FUNCTION_ ! 37: ! 38: %type <u_node> linelist line pattern regexp re ! 39: %type <u_node> stat stlist compound assignment ! 40: %type <u_node> variable terminal constant exp e ! 41: %type <u_node> output elist altlst error ! 42: %type <u_char> reclosure assignop ! 43: ! 44: %left SCON_ ! 45: %right ASADD_ ASSUB_ ASMUL_ ASDIV_ ASMOD_ '=' ! 46: %left OROR_ ! 47: %left ANDAND_ ! 48: %left '~' NMATCH_ ! 49: %nonassoc EQ_ NE_ ! 50: %nonassoc GE_ LE_ '>' '<' ! 51: %left '+' '-' ! 52: %left '*' '/' '%' ! 53: %nonassoc '!' INC_ DEC_ ! 54: %nonassoc '$' ! 55: %nonassoc '(' '[' ! 56: ! 57: /* ! 58: * Special tokens for ! 59: * regular expressions ! 60: * and expression precedences. ! 61: */ ! 62: %token REEOL_ REBOL_ REANY_ ! 63: %token <u_charp> RECLASS_ ! 64: %token <u_char> RECHAR_ ! 65: ! 66: %left REOR_ ! 67: %left RECON_ ! 68: %nonassoc RECLOS_ RENECL_ REZOCL_ ! 69: ! 70: %% ! 71: code: ! 72: linelist { ! 73: codep = $1; ! 74: } ! 75: ; ! 76: ! 77: linelist: ! 78: line linelist { ! 79: $$ = node(ALIST, $1, $2); ! 80: } ! 81: | line ! 82: ; ! 83: ! 84: line: ! 85: compound '\n' { ! 86: $$ = node(AROOT, NULL, $1); ! 87: } ! 88: | pattern '\n' { ! 89: $$ = node(AROOT, $1, NULL); ! 90: } ! 91: | pattern compound '\n' { ! 92: $$ = node(AROOT, $1, $2); ! 93: } ! 94: ; ! 95: ! 96: pattern: ! 97: BEGIN_ { ! 98: $$ = node(ABEGIN); ! 99: } ! 100: | END_ { ! 101: $$ = node(AEND); ! 102: } ! 103: | e ! 104: | e ',' e { ! 105: $$ = node(ARANGE, $1, $3); ! 106: } ! 107: ; ! 108: ! 109: regexp: ! 110: '/' { lexre=1; } re '/' { ! 111: lexre = 0; ! 112: $$ = $3; ! 113: } ! 114: | error '\n' { ! 115: yyerrok; ! 116: yyerror("Badly formed regular expression"); ! 117: } regexp { ! 118: $$ = $4; ! 119: } ! 120: ; ! 121: ! 122: re: ! 123: re re %prec RECON_ { ! 124: register NODE *np; ! 125: ! 126: for (np = $1; np->n_O3!=NULL; np = np->n_O3) ! 127: ; ! 128: np->n_O3 = $2; ! 129: $$ = $1; ! 130: } ! 131: | '(' re ')' { ! 132: $$ = $2; ! 133: } ! 134: | re REOR_ re { ! 135: $$ = node(AROR, $1, $3, NULL); ! 136: } ! 137: | re reclosure { ! 138: $$ = node($2, $1, NULL, NULL); ! 139: } ! 140: | RECLASS_ { ! 141: $$ = node(yflag?ARDCLASS:ARCLASS, NULL, NULL, NULL); ! 142: $$->n_o1.n_charp = $1; ! 143: } ! 144: | REANY_ { ! 145: $$ = node(ARANY, NULL, NULL, NULL); ! 146: } ! 147: | REBOL_ { ! 148: $$ = node(ARBOL, NULL, NULL, NULL); ! 149: } ! 150: | REEOL_ { ! 151: $$ = node(AREOL, NULL, NULL, NULL); ! 152: } ! 153: | RECHAR_ { ! 154: $$ = cnode(yflag?ARDCHAR:ARCHAR, $1); ! 155: } ! 156: ; ! 157: ! 158: reclosure: ! 159: RECLOS_ { ! 160: $$ = ARCLOS; ! 161: } ! 162: | REZOCL_ { ! 163: $$ = ARZOCL; ! 164: } ! 165: | RENECL_ { ! 166: $$ = ARNECL; ! 167: } ! 168: ; ! 169: ! 170: compound: ! 171: '{' stlist '}' { ! 172: $$ = $2; ! 173: } ! 174: ; ! 175: ! 176: stat: ! 177: IF_ '(' e specparen stat { ! 178: $$ = node(AIF, $3, $5, NULL); ! 179: } ! 180: | IF_ '(' e specparen stat ELSE_ {nlskip = 1;} stat { ! 181: $$ = node(AIF, $3, $5, $8); ! 182: } ! 183: | WHILE_ '(' e specparen stat { ! 184: $$ = node(AWHILE, $3, $5); ! 185: } ! 186: | FOR_ '(' variable IN_ variable specparen stat { ! 187: $$ = node(AFORIN, $3, $5, $7); ! 188: } ! 189: | FOR_ '(' e ';' e ';' e specparen stat { ! 190: $$ = node(AFOR, $3, $5, $7, $9); ! 191: } ! 192: | FOR_ '(' ';' e ';' e specparen stat { ! 193: $$ = node(AFOR, NULL, $4, $6, $8); ! 194: } ! 195: | BREAK_ ';' { ! 196: $$ = node(ABREAK); ! 197: } ! 198: | CONTINUE_ ';' { ! 199: $$ = node(ACONTIN); ! 200: } ! 201: | compound ! 202: | e ';' ! 203: | PRINT_ {outflag++;} altlst output { ! 204: $$ = node(APRINT, $3, $4); ! 205: } ! 206: | PRINT_ {outflag++;} output { ! 207: $$ = node(APRINT, &xfield0, $3); ! 208: } ! 209: | PRINTF_ {outflag++;} altlst output { ! 210: $$ = node(APRINTF, $3, $4); ! 211: } ! 212: | NEXT_ ';' { ! 213: $$ = node(ANEXT); ! 214: } ! 215: | EXIT_ ';' { ! 216: $$ = node(AEXIT); ! 217: } ! 218: | ';' { ! 219: $$ = NULL; ! 220: } ! 221: ; ! 222: ! 223: stlist: ! 224: stat ! 225: | stat stlist { ! 226: if ($1!=NULL && $2!=NULL) ! 227: $$ = node(ALIST, $1, $2); ! 228: else if ($1 != NULL) ! 229: $$ = $1; ! 230: else ! 231: $$ = $2; ! 232: } ! 233: ; ! 234: ! 235: specparen: ! 236: ')' { ! 237: nlskip = 1; ! 238: } ! 239: ; ! 240: ! 241: assignment: ! 242: variable '=' exp { ! 243: $$ = node(AASGN, $1, $3); ! 244: } ! 245: | variable assignop exp { ! 246: $$ = node(AASGN, $1, node($2, $1, $3)); ! 247: } ! 248: | INC_ variable { ! 249: $$ = node(AASGN, $2, node(AADD, $2, &xone)); ! 250: } ! 251: | variable INC_ { ! 252: $$ = node(AINCA, $1); ! 253: } ! 254: | DEC_ variable { ! 255: $$ = node(AASGN, $2, node(ASUB, $2, &xone)); ! 256: } ! 257: | variable DEC_ { ! 258: $$ = node(ADECA, $1); ! 259: } ! 260: ; ! 261: ! 262: assignop: ! 263: ASADD_ { ! 264: $$ = AADD; ! 265: } ! 266: | ASSUB_ { ! 267: $$ = ASUB; ! 268: } ! 269: | ASMUL_ { ! 270: $$ = AMUL; ! 271: } ! 272: | ASDIV_ { ! 273: $$ = ADIV; ! 274: } ! 275: | ASMOD_ { ! 276: $$ = AMOD; ! 277: } ! 278: ; ! 279: ! 280: variable: ! 281: '$' '(' e ')' { ! 282: $$ = node(AFIELD, $3); ! 283: } ! 284: | '$' terminal { ! 285: $$ = node(AFIELD, $2); ! 286: } ! 287: | ID_ '[' exp ']' { ! 288: $$ = node(AARRAY, $1, $3); ! 289: } ! 290: | ID_ ! 291: ; ! 292: ! 293: constant: ! 294: STRING_ ! 295: | NUMBER_ ! 296: ; ! 297: ! 298: terminal: ! 299: variable ! 300: | constant ! 301: ; ! 302: ! 303: exp: ! 304: e ! 305: | exp e %prec SCON_ { ! 306: $$ = node(ACONC, $1, $2); ! 307: } ! 308: ; ! 309: ! 310: e: ! 311: '(' exp ')' { ! 312: $$ = $2; ! 313: } ! 314: | e ANDAND_ e { ! 315: $$ = node(AANDAND, $1, $3); ! 316: } ! 317: | e OROR_ e { ! 318: $$ = node(AOROR, $1, $3); ! 319: } ! 320: | '!' e { ! 321: $$ = node(ANOT, $2); ! 322: } ! 323: | '-' e %prec '!' { ! 324: $$ = node(ANEG, $2); ! 325: } ! 326: | terminal ! 327: | assignment ! 328: | e '+' e { ! 329: $$ = node(AADD, $1, $3); ! 330: } ! 331: | e '-' e { ! 332: $$ = node(ASUB, $1, $3); ! 333: } ! 334: | e '*' e { ! 335: $$ = node(AMUL, $1, $3); ! 336: } ! 337: | e '/' e { ! 338: $$ = node(ADIV, $1, $3); ! 339: } ! 340: | e '%' e { ! 341: $$ = node(AMOD, $1, $3); ! 342: } ! 343: | e '>' e { ! 344: $$ = node(AGT, $1, $3); ! 345: } ! 346: | e '<' e { ! 347: $$ = node(ALT, $1, $3); ! 348: } ! 349: | e EQ_ e { ! 350: $$ = node(AEQ, $1, $3); ! 351: } ! 352: | e NE_ e { ! 353: $$ = node(ANE, $1, $3); ! 354: } ! 355: | e GE_ e { ! 356: $$ = node(AGE, $1,$3); ! 357: } ! 358: | e LE_ e { ! 359: $$ = node(ALE, $1, $3); ! 360: } ! 361: | e '~' regexp { ! 362: $$ = node(AREMAT, $1, $3); ! 363: } ! 364: | e NMATCH_ regexp { ! 365: $$ = node(ARENMAT, $1, $3); ! 366: } ! 367: | regexp { ! 368: if (brlevel) ! 369: awkerr("Regular expression illegal in action"); ! 370: $$ = node(ARE, $1); ! 371: } ! 372: | FUNCTION_ '(' elist ')' { ! 373: $$ = node(AFUNC, $1, $3); ! 374: } ! 375: | FUNCTION_ { ! 376: $$ = node(AFUNC, $1, NULL); ! 377: } ! 378: ; ! 379: ! 380: output: ! 381: FAPPEND_ terminal ';' { ! 382: $$ = node(AFAPP, $2); ! 383: } ! 384: | FOUT_ terminal %prec '$' ';' { ! 385: $$ = node(AFOUT, $2); ! 386: } ! 387: | '|' terminal ';' { ! 388: $$ = node(AFPIPE, $2); ! 389: } ! 390: | ';' { ! 391: $$ = NULL; ! 392: } ! 393: ; ! 394: ! 395: altlst : '(' elist ')' { ! 396: $$ = $2; ! 397: } ! 398: | elist { ! 399: $$ = $1; ! 400: } ! 401: ; ! 402: ! 403: elist: ! 404: exp { ! 405: $$ = $1; ! 406: } ! 407: | exp ',' elist { ! 408: $$ = node(ALIST, $1, $3); ! 409: } ! 410: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.