1 /* awk.g.y 4.1 82/05/07 */ 2 3 %token FIRSTTOKEN /*must be first*/ 4 %token FINAL FATAL 5 %token LT LE GT GE EQ NE 6 %token MATCH NOTMATCH 7 %token APPEND 8 %token ADD MINUS MULT DIVIDE MOD UMINUS 9 %token ASSIGN ADDEQ SUBEQ MULTEQ DIVEQ MODEQ 10 %token JUMP 11 %token XBEGIN XEND 12 %token NL 13 %token PRINT PRINTF SPRINTF SPLIT 14 %token IF ELSE WHILE FOR IN NEXT EXIT BREAK CONTINUE 15 %token PROGRAM PASTAT PASTAT2 16 17 %right ASGNOP 18 %left BOR 19 %left AND 20 %left NOT 21 %left NUMBER VAR ARRAY FNCN SUBSTR LSUBSTR INDEX 22 %left GETLINE 23 %nonassoc RELOP MATCHOP 24 %left OR 25 %left STRING DOT CCL NCCL CHAR 26 %left '(' '^' '$' 27 %left CAT 28 %left '+' '-' 29 %left '*' '/' '%' 30 %left STAR PLUS QUEST 31 %left POSTINCR PREINCR POSTDECR PREDECR INCR DECR 32 %left FIELD INDIRECT 33 %token LASTTOKEN /* has to be last */ 34 35 %{ 36 #include "awk.def" 37 #ifndef DEBUG 38 # define PUTS(x) 39 #endif 40 %} 41 %% 42 43 program: 44 begin pa_stats end { if (errorflag==0) winner = (node *)stat3(PROGRAM, $1, $2, $3); } 45 | error { yyclearin; yyerror("bailing out"); } 46 ; 47 48 begin: 49 XBEGIN '{' stat_list '}' { PUTS("XBEGIN list"); $$ = $3; } 50 | begin NL 51 | { PUTS("empty XBEGIN"); $$ = (hack)nullstat; } 52 ; 53 54 end: 55 XEND '{' stat_list '}' { PUTS("XEND list"); $$ = $3; } 56 | end NL 57 | { PUTS("empty END"); $$ = (hack)nullstat; } 58 ; 59 60 compound_conditional: 61 conditional BOR conditional { PUTS("cond||cond"); $$ = op2(BOR, $1, $3); } 62 | conditional AND conditional { PUTS("cond&&cond"); $$ = op2(AND, $1, $3); } 63 | NOT conditional { PUTS("!cond"); $$ = op1(NOT, $2); } 64 | '(' compound_conditional ')' { $$ = $2; } 65 ; 66 67 compound_pattern: 68 pattern BOR pattern { PUTS("pat||pat"); $$ = op2(BOR, $1, $3); } 69 | pattern AND pattern { PUTS("pat&&pat"); $$ = op2(AND, $1, $3); } 70 | NOT pattern { PUTS("!pat"); $$ = op1(NOT, $2); } 71 | '(' compound_pattern ')' { $$ = $2; } 72 ; 73 74 conditional: 75 expr { PUTS("expr"); $$ = op2(NE, $1, valtonode(lookup("$zero&null", symtab, 0), CCON)); } 76 | rel_expr { PUTS("relexpr"); } 77 | lex_expr { PUTS("lexexpr"); } 78 | compound_conditional { PUTS("compcond"); } 79 ; 80 81 else: 82 ELSE optNL { PUTS("else"); } 83 ; 84 85 field: 86 FIELD { PUTS("field"); $$ = valtonode($1, CFLD); } 87 | INDIRECT term { PUTS("ind field"); $$ = op1(INDIRECT, $2); } 88 ; 89 90 if: 91 IF '(' conditional ')' optNL { PUTS("if(cond)"); $$ = $3; } 92 ; 93 94 lex_expr: 95 expr MATCHOP regular_expr { PUTS("expr~re"); $$ = op2($2, $1, makedfa($3)); } 96 | '(' lex_expr ')' { PUTS("(lex_expr)"); $$ = $2; } 97 ; 98 99 var: 100 NUMBER {PUTS("number"); $$ = valtonode($1, CCON); } 101 | STRING { PUTS("string"); $$ = valtonode($1, CCON); } 102 | VAR { PUTS("var"); $$ = valtonode($1, CVAR); } 103 | VAR '[' expr ']' { PUTS("array[]"); $$ = op2(ARRAY, $1, $3); } 104 | field 105 ; 106 term: 107 var 108 | GETLINE { PUTS("getline"); $$ = op1(GETLINE, 0); } 109 | FNCN { PUTS("func"); 110 $$ = op2(FNCN, $1, valtonode(lookup("$record", symtab, 0), CFLD)); 111 } 112 | FNCN '(' ')' { PUTS("func()"); 113 $$ = op2(FNCN, $1, valtonode(lookup("$record", symtab, 0), CFLD)); 114 } 115 | FNCN '(' expr ')' { PUTS("func(expr)"); $$ = op2(FNCN, $1, $3); } 116 | SPRINTF print_list { PUTS("sprintf"); $$ = op1($1, $2); } 117 | SUBSTR '(' expr ',' expr ',' expr ')' 118 { PUTS("substr(e,e,e)"); $$ = op3(SUBSTR, $3, $5, $7); } 119 | SUBSTR '(' expr ',' expr ')' 120 { PUTS("substr(e,e,e)"); $$ = op3(SUBSTR, $3, $5, nullstat); } 121 | SPLIT '(' expr ',' VAR ',' expr ')' 122 { PUTS("split(e,e,e)"); $$ = op3(SPLIT, $3, $5, $7); } 123 | SPLIT '(' expr ',' VAR ')' 124 { PUTS("split(e,e,e)"); $$ = op3(SPLIT, $3, $5, nullstat); } 125 | INDEX '(' expr ',' expr ')' 126 { PUTS("index(e,e)"); $$ = op2(INDEX, $3, $5); } 127 | '(' expr ')' {PUTS("(expr)"); $$ = $2; } 128 | term '+' term { PUTS("t+t"); $$ = op2(ADD, $1, $3); } 129 | term '-' term { PUTS("t-t"); $$ = op2(MINUS, $1, $3); } 130 | term '*' term { PUTS("t*t"); $$ = op2(MULT, $1, $3); } 131 | term '/' term { PUTS("t/t"); $$ = op2(DIVIDE, $1, $3); } 132 | term '%' term { PUTS("t%t"); $$ = op2(MOD, $1, $3); } 133 | '-' term %prec QUEST { PUTS("-term"); $$ = op1(UMINUS, $2); } 134 | '+' term %prec QUEST { PUTS("+term"); $$ = $2; } 135 | INCR var { PUTS("++var"); $$ = op1(PREINCR, $2); } 136 | DECR var { PUTS("--var"); $$ = op1(PREDECR, $2); } 137 | var INCR { PUTS("var++"); $$= op1(POSTINCR, $1); } 138 | var DECR { PUTS("var--"); $$= op1(POSTDECR, $1); } 139 ; 140 141 expr: 142 term { PUTS("term"); } 143 | expr term { PUTS("expr term"); $$ = op2(CAT, $1, $2); } 144 | var ASGNOP expr { PUTS("var=expr"); $$ = stat2($2, $1, $3); } 145 ; 146 147 optNL: 148 NL 149 | 150 ; 151 152 pa_stat: 153 pattern { PUTS("pattern"); $$ = stat2(PASTAT, $1, genprint()); } 154 | pattern '{' stat_list '}' { PUTS("pattern {...}"); $$ = stat2(PASTAT, $1, $3); } 155 | pattern ',' pattern { PUTS("srch,srch"); $$ = pa2stat($1, $3, genprint()); } 156 | pattern ',' pattern '{' stat_list '}' 157 { PUTS("srch, srch {...}"); $$ = pa2stat($1, $3, $5); } 158 | '{' stat_list '}' { PUTS("null pattern {...}"); $$ = stat2(PASTAT, nullstat, $2); } 159 ; 160 161 pa_stats: 162 pa_stats pa_stat st { PUTS("pa_stats pa_stat"); $$ = linkum($1, $2); } 163 | { PUTS("null pa_stat"); $$ = (hack)nullstat; } 164 | pa_stats pa_stat {PUTS("pa_stats pa_stat"); $$ = linkum($1, $2); } 165 ; 166 167 pattern: 168 regular_expr { PUTS("regex"); 169 $$ = op2(MATCH, valtonode(lookup("$record", symtab, 0), CFLD), makedfa($1)); 170 } 171 | rel_expr { PUTS("relexpr"); } 172 | lex_expr { PUTS("lexexpr"); } 173 | compound_pattern { PUTS("comp pat"); } 174 ; 175 176 print_list: 177 expr { PUTS("expr"); } 178 | pe_list { PUTS("pe_list"); } 179 | { PUTS("null print_list"); $$ = valtonode(lookup("$record", symtab, 0), CFLD); } 180 ; 181 182 pe_list: 183 expr ',' expr {$$ = linkum($1, $3); } 184 | pe_list ',' expr {$$ = linkum($1, $3); } 185 | '(' pe_list ')' {$$ = $2; } 186 ; 187 188 redir: 189 RELOP 190 | '|' 191 ; 192 193 regular_expr: 194 '/' { startreg(); } 195 r '/' 196 { PUTS("/r/"); $$ = $3; } 197 ; 198 199 r: 200 CHAR { PUTS("regex CHAR"); $$ = op2(CHAR, (node *) 0, $1); } 201 | DOT { PUTS("regex DOT"); $$ = op2(DOT, (node *) 0, (node *) 0); } 202 | CCL { PUTS("regex CCL"); $$ = op2(CCL, (node *) 0, cclenter($1)); } 203 | NCCL { PUTS("regex NCCL"); $$ = op2(NCCL, (node *) 0, cclenter($1)); } 204 | '^' { PUTS("regex ^"); $$ = op2(CHAR, (node *) 0, HAT); } 205 | '$' { PUTS("regex $"); $$ = op2(CHAR, (node *) 0 ,(node *) 0); } 206 | r OR r { PUTS("regex OR"); $$ = op2(OR, $1, $3); } 207 | r r %prec CAT 208 { PUTS("regex CAT"); $$ = op2(CAT, $1, $2); } 209 | r STAR { PUTS("regex STAR"); $$ = op2(STAR, $1, (node *) 0); } 210 | r PLUS { PUTS("regex PLUS"); $$ = op2(PLUS, $1, (node *) 0); } 211 | r QUEST { PUTS("regex QUEST"); $$ = op2(QUEST, $1, (node *) 0); } 212 | '(' r ')' { PUTS("(regex)"); $$ = $2; } 213 ; 214 215 rel_expr: 216 expr RELOP expr 217 { PUTS("expr relop expr"); $$ = op2($2, $1, $3); } 218 | '(' rel_expr ')' 219 { PUTS("(relexpr)"); $$ = $2; } 220 ; 221 222 st: 223 NL 224 | ';' 225 ; 226 227 simple_stat: 228 PRINT print_list redir expr 229 { PUTS("print>stat"); $$ = stat3($1, $2, $3, $4); } 230 | PRINT print_list 231 { PUTS("print list"); $$ = stat3($1, $2, nullstat, nullstat); } 232 | PRINTF print_list redir expr 233 { PUTS("printf>stat"); $$ = stat3($1, $2, $3, $4); } 234 | PRINTF print_list 235 { PUTS("printf list"); $$ = stat3($1, $2, nullstat, nullstat); } 236 | expr { PUTS("expr"); $$ = exptostat($1); } 237 | { PUTS("null simple statement"); $$ = (hack)nullstat; } 238 | error { yyclearin; yyerror("illegal statement"); } 239 ; 240 241 statement: 242 simple_stat st { PUTS("simple stat"); } 243 | if statement { PUTS("if stat"); $$ = stat3(IF, $1, $2, nullstat); } 244 | if statement else statement 245 { PUTS("if-else stat"); $$ = stat3(IF, $1, $2, $4); } 246 | while statement { PUTS("while stat"); $$ = stat2(WHILE, $1, $2); } 247 | for { PUTS("for stat"); } 248 | NEXT st { PUTS("next"); $$ = stat1(NEXT, 0); } 249 | EXIT st { PUTS("exit"); $$ = stat1(EXIT, 0); } 250 | EXIT expr st { PUTS("exit"); $$ = stat1(EXIT, $2); } 251 | BREAK st { PUTS("break"); $$ = stat1(BREAK, 0); } 252 | CONTINUE st { PUTS("continue"); $$ = stat1(CONTINUE, 0); } 253 | '{' stat_list '}' { PUTS("{statlist}"); $$ = $2; } 254 ; 255 256 stat_list: 257 stat_list statement { PUTS("stat_list stat"); $$ = linkum($1, $2); } 258 | { PUTS("null stat list"); $$ = (hack)nullstat; } 259 ; 260 261 while: 262 WHILE '(' conditional ')' optNL { PUTS("while(cond)"); $$ = $3; } 263 ; 264 265 for: 266 FOR '(' simple_stat ';' conditional ';' simple_stat ')' optNL statement 267 { PUTS("for(e;e;e)"); $$ = stat4(FOR, $3, $5, $7, $10); } 268 | FOR '(' simple_stat ';' ';' simple_stat ')' optNL statement 269 { PUTS("for(e;e;e)"); $$ = stat4(FOR, $3, nullstat, $6, $9); } 270 | FOR '(' VAR IN VAR ')' optNL statement 271 { PUTS("for(v in v)"); $$ = stat3(IN, $3, $5, $8); } 272 ; 273 274 %% 275