|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 6324 (0x18b4) Types: TextFile Notes: UNIX file Names: »awk.y«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/awk/awk.y«
/* * AWK grammar * yacc -prods 120 -terms 80 -nterms 40 -states 200 awk.y * to make it fit on the PDP-11 (non separated I/D). * Do not be surprised at the 48 S/R * conflicts that this grammar gets * from yacc. Worry if you get more * though. This is mostly due to * the combination of implicit string * concatenation mixed with embedded assignments. * In addition, 12 of these come from regular * expressions. * (NOTE: unary minus cannot be done because * it is totally ambiguous with string concatentation. * and output redirection is disambiguated by disallowing * the relation '>' in `print' and `printf' statements.) */ %{ #include "awk.h" %} %union { int u_char; char *u_charp; NODE *u_node; int (*u_func)(); } %token IF_ WHILE_ FOR_ ELSE_ BREAK_ CONTINUE_ NEXT_ EXIT_ %token IN_ %token PRINT_ PRINTF_ %token BEGIN_ END_ %token FAPPEND_ FOUT_ %token <u_node> ID_ STRING_ NUMBER_ FUNCTION_ %type <u_node> linelist line pattern regexp re %type <u_node> stat stlist compound assignment %type <u_node> variable terminal constant exp e %type <u_node> output elist error %type <u_char> reclosure assignop %left SCON_ %right ASADD_ ASSUB_ ASMUL_ ASDIV_ ASMOD_ '=' %left OROR_ %left ANDAND_ %left '~' NMATCH_ %nonassoc EQ_ NE_ %nonassoc GE_ LE_ '>' '<' %left '+' '-' %left '*' '/' '%' %nonassoc '!' INC_ DEC_ %nonassoc '$' /* * Special tokens for * regular expressions * and expression precedences. */ %token REEOL_ REBOL_ REANY_ %token <u_charp> RECLASS_ %token <u_char> RECHAR_ %left REOR_ %left RECON_ %nonassoc RECLOS_ RENECL_ REZOCL_ %% code: linelist { codep = $1; } ; linelist: line linelist { $$ = node(ALIST, $1, $2); } | line ; line: compound '\n' { $$ = node(AROOT, NULL, $1); } | pattern '\n' { $$ = node(AROOT, $1, NULL); } | pattern compound '\n' { $$ = node(AROOT, $1, $2); } ; pattern: BEGIN_ { $$ = node(ABEGIN); } | END_ { $$ = node(AEND); } | e | e ',' e { $$ = node(ARANGE, $1, $3); } ; regexp: '/' { lexre=1; } re '/' { lexre = 0; $$ = $3; } | error '\n' { yyerrok; yyerror("Badly formed regular expression"); } regexp { $$ = $4; } ; re: re re %prec RECON_ { register NODE *np; for (np = $1; np->n_O3!=NULL; np = np->n_O3) ; np->n_O3 = $2; $$ = $1; } | '(' re ')' { $$ = $2; } | re REOR_ re { $$ = node(AROR, $1, $3, NULL); } | re reclosure { $$ = node($2, $1, NULL, NULL); } | RECLASS_ { $$ = node(yflag?ARDCLASS:ARCLASS, NULL, NULL, NULL); $$->n_o1.n_charp = $1; } | REANY_ { $$ = node(ARANY, NULL, NULL, NULL); } | REBOL_ { $$ = node(ARBOL, NULL, NULL, NULL); } | REEOL_ { $$ = node(AREOL, NULL, NULL, NULL); } | RECHAR_ { $$ = cnode(yflag?ARDCHAR:ARCHAR, $1); } ; reclosure: RECLOS_ { $$ = ARCLOS; } | REZOCL_ { $$ = ARZOCL; } | RENECL_ { $$ = ARNECL; } ; compound: '{' stlist '}' { $$ = $2; } ; stat: IF_ '(' e specparen stat { $$ = node(AIF, $3, $5, NULL); } | IF_ '(' e specparen stat ELSE_ {nlskip = 1;} stat { $$ = node(AIF, $3, $5, $8); } | WHILE_ '(' e specparen stat { $$ = node(AWHILE, $3, $5); } | FOR_ '(' variable IN_ variable specparen stat { $$ = node(AFORIN, $3, $5, $7); } | FOR_ '(' e ';' e ';' e specparen stat { $$ = node(AFOR, $3, $5, $7, $9); } | BREAK_ ';' { $$ = node(ABREAK); } | CONTINUE_ ';' { $$ = node(ACONTIN); } | compound | e ';' | PRINT_ {outflag++;} elist output { $$ = node(APRINT, $3, $4); } | PRINT_ {outflag++;} output { $$ = node(APRINT, &xfield0, $3); } | PRINTF_ {outflag++;} elist output { $$ = node(APRINTF, $3, $4); } | NEXT_ ';' { $$ = node(ANEXT); } | EXIT_ ';' { $$ = node(AEXIT); } | ';' { $$ = NULL; } ; stlist: stat | stat stlist { if ($1!=NULL && $2!=NULL) $$ = node(ALIST, $1, $2); else if ($1 != NULL) $$ = $1; else $$ = $2; } ; specparen: ')' { nlskip = 1; } ; assignment: variable '=' exp { $$ = node(AASGN, $1, $3); } | variable assignop exp { $$ = node(AASGN, $1, node($2, $1, $3)); } | INC_ variable { $$ = node(AASGN, $2, node(AADD, $2, &xone)); } | variable INC_ { $$ = node(AINCA, $1); } | DEC_ variable { $$ = node(AASGN, $2, node(ASUB, $2, &xone)); } | variable DEC_ { $$ = node(ADECA, $1); } ; assignop: ASADD_ { $$ = AADD; } | ASSUB_ { $$ = ASUB; } | ASMUL_ { $$ = AMUL; } | ASDIV_ { $$ = ADIV; } | ASMOD_ { $$ = AMOD; } ; variable: '$' '(' e ')' { $$ = node(AFIELD, $3); } | '$' terminal { $$ = node(AFIELD, $2); } | ID_ '[' exp ']' { $$ = node(AARRAY, $1, $3); } | ID_ ; constant: STRING_ | NUMBER_ ; terminal: variable | constant ; exp: e | exp e %prec SCON_ { $$ = node(ACONC, $1, $2); } ; e: '(' e ')' { $$ = $2; } | e ANDAND_ e { $$ = node(AANDAND, $1, $3); } | e OROR_ e { $$ = node(AOROR, $1, $3); } | '!' e { $$ = node(ANOT, $2); } | terminal | assignment | e '+' e { $$ = node(AADD, $1, $3); } | e '-' e { $$ = node(ASUB, $1, $3); } | e '*' e { $$ = node(AMUL, $1, $3); } | e '/' e { $$ = node(ADIV, $1, $3); } | e '%' e { $$ = node(AMOD, $1, $3); } | e '>' e { $$ = node(AGT, $1, $3); } | e '<' e { $$ = node(ALT, $1, $3); } | e EQ_ e { $$ = node(AEQ, $1, $3); } | e NE_ e { $$ = node(ANE, $1, $3); } | e GE_ e { $$ = node(AGE, $1,$3); } | e LE_ e { $$ = node(ALE, $1, $3); } | e '~' regexp { $$ = node(AREMAT, $1, $3); } | e NMATCH_ regexp { $$ = node(ARENMAT, $1, $3); } | regexp { if (brlevel) awkerr("Regular expression illegal in action"); $$ = node(ARE, $1); } | FUNCTION_ '(' elist ')' { $$ = node(AFUNC, $1, $3); } | FUNCTION_ { $$ = node(AFUNC, $1, NULL); } ; output: FAPPEND_ terminal ';' { $$ = node(AFAPP, $2); } | FOUT_ terminal %prec '$' ';' { $$ = node(AFOUT, $2); } | '|' terminal ';' { $$ = node(AFPIPE, $2); } | ';' { $$ = NULL; } ; elist: exp { $$ = $1; } | exp ',' elist { $$ = node(ALIST, $1, $3); } ;