1 %{ 2 /*- 3 * Copyright (c) 1982, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)grammar.y 8.1 (Berkeley) 06/06/93"; 11 #endif /* not lint */ 12 13 /* 14 * yacc grammar for debugger commands 15 */ 16 17 #include "defs.h" 18 #include "command.h" 19 #include "sym.h" 20 #include "symtab.h" 21 #include "tree.h" 22 #include "process.h" 23 #include "source.h" 24 25 %} 26 27 %term ALIAS ASSIGN CALL CHFILE 28 %term CONT DUMP EDIT 29 %term GRIPE HELP LIST NEXT 30 %term QUIT REMAKE PRINT 31 %term RUN SH SOURCE 32 %term STATUS STEP 33 %term STOP STOPI TRACE TRACEI 34 %term DELETE 35 %term WHATIS WHICH WHERE 36 %term XI XD 37 38 %term AT IN IF 39 %term FILENAME 40 %term INT REAL NAME STRING 41 %term DIV MOD 42 %term AND OR NOT 43 44 %binary '<' '=' '>' IN 45 %left '+' '-' OR '|' 46 %left UNARYSIGN 47 %left '*' '/' DIV MOD AND '&' 48 %left NOT 49 50 %union { 51 SYM *y_sym; 52 NODE *y_node; 53 int y_int; 54 OP y_op; 55 long y_long; 56 double y_real; 57 char *y_string; 58 BOOLEAN y_bool; 59 }; 60 61 %type <y_int> trace TRACE TRACEI stop STOP STOPI 62 %type <y_long> INT 63 %type <y_real> REAL 64 %type <y_op> addop mulop relop 65 %type <y_string> STRING FILENAME SH opt_filename 66 %type <y_sym> NAME 67 %type <y_node> command rcommand what where opt_arglist opt_cond 68 %type <y_node> exp_list exp boolean_exp term constant 69 %type <y_node> line_list line_number address_list 70 %% 71 input: 72 input command_nl 73 { 74 prompt(); 75 } 76 | /* empty */ 77 ; 78 command_nl: 79 command_line '\n' 80 | '\n' 81 ; 82 83 /* 84 * There are two kinds of commands, those that can be redirected 85 * and those that can't. 86 */ 87 88 command_line: 89 command 90 { 91 eval($1); 92 } 93 | rcommand 94 { 95 eval($1); 96 } 97 | rcommand '>' FILENAME 98 { 99 setout($3); 100 eval($1); 101 unsetout(); 102 } 103 | SH 104 { 105 shell($1); 106 } 107 | run args 108 { 109 run(); 110 } 111 ; 112 run: 113 RUN 114 { 115 arginit(); 116 } 117 ; 118 args: 119 arg args 120 | /* empty */ 121 ; 122 arg: 123 FILENAME 124 { 125 newarg($1); 126 } 127 | '<' FILENAME 128 { 129 inarg($2); 130 } 131 | '>' FILENAME 132 { 133 outarg($2); 134 } 135 ; 136 command: 137 ASSIGN term exp 138 { 139 $$ = build(O_ASSIGN, $2, $3); 140 } 141 | CHFILE opt_filename 142 { 143 $$ = build(O_CHFILE, $2); 144 } 145 | CONT 146 { 147 $$ = build(O_CONT); 148 } 149 | LIST line_list 150 { 151 $$ = build(O_LIST, $2); 152 } 153 | LIST NAME 154 { 155 $$ = build(O_LIST, build(O_NAME, $2)); 156 } 157 | NEXT 158 { 159 $$ = build(O_NEXT); 160 } 161 | PRINT exp_list 162 { 163 $$ = build(O_PRINT, $2); 164 } 165 | QUIT 166 { 167 quit(0); 168 } 169 | STEP 170 { 171 $$ = build(O_STEP); 172 } 173 | stop where opt_cond 174 { 175 $$ = build($1, NIL, $2, $3); 176 } 177 | stop what opt_cond 178 { 179 $$ = build($1, $2, NIL, $3); 180 } 181 | stop IF boolean_exp 182 { 183 $$ = build($1, NIL, NIL, $3); 184 } 185 | trace what where opt_cond 186 { 187 $$ = build($1, $2, $3, $4); 188 } 189 | trace where opt_cond 190 { 191 $$ = build($1, NIL, $2, $3); 192 } 193 | trace what opt_cond 194 { 195 $$ = build($1, $2, NIL, $3); 196 } 197 | trace opt_cond 198 { 199 $$ = build($1, NIL, NIL, $2); 200 } 201 | DELETE INT 202 { 203 $$ = build(O_DELETE, $2); 204 } 205 | WHATIS term 206 { 207 $$ = build(O_WHATIS, $2); 208 } 209 | WHICH NAME 210 { 211 $$ = build(O_WHICH, $2); 212 } 213 | WHERE 214 { 215 $$ = build(O_WHERE); 216 } 217 | XI address_list 218 { 219 $$ = build(O_XI, $2); 220 } 221 | XD address_list 222 { 223 $$ = build(O_XD, $2); 224 } 225 ; 226 rcommand: 227 ALIAS FILENAME opt_filename 228 { 229 $$ = build(O_ALIAS, $2, $3); 230 } 231 | ALIAS 232 { 233 $$ = build(O_ALIAS, NIL, NIL); 234 } 235 | CALL term opt_arglist 236 { 237 $$ = build(O_CALL, $2, $3); 238 } 239 | EDIT opt_filename 240 { 241 $$ = build(O_EDIT, $2); 242 } 243 | DUMP 244 { 245 $$ = build(O_DUMP); 246 } 247 | GRIPE 248 { 249 $$ = build(O_GRIPE); 250 } 251 | HELP 252 { 253 $$ = build(O_HELP); 254 } 255 | REMAKE 256 { 257 $$ = build(O_REMAKE); 258 } 259 | SOURCE FILENAME 260 { 261 $$ = build(O_SOURCE, $2); 262 } 263 | STATUS 264 { 265 $$ = build(O_STATUS); 266 } 267 ; 268 trace: 269 TRACE 270 { 271 $$ = O_TRACE; 272 } 273 | TRACEI 274 { 275 $$ = O_TRACEI; 276 } 277 ; 278 stop: 279 STOP 280 { 281 $$ = O_STOP; 282 } 283 | STOPI 284 { 285 $$ = O_STOPI; 286 } 287 ; 288 what: 289 exp 290 | FILENAME line_number 291 { 292 $$ = build(O_QLINE, $1, $2); 293 } 294 ; 295 where: 296 IN term 297 { 298 $$ = $2; 299 } 300 | AT line_number 301 { 302 $$ = build(O_QLINE, cursource, $2); 303 } 304 | AT FILENAME line_number 305 { 306 $$ = build(O_QLINE, $2, $3); 307 } 308 ; 309 opt_filename: 310 /* empty */ 311 { 312 $$ = NIL; 313 } 314 | FILENAME 315 ; 316 opt_arglist: 317 /* empty */ 318 { 319 $$ = NIL; 320 } 321 | '(' exp_list ')' 322 { 323 $$ = $2; 324 } 325 ; 326 line_list: 327 /* empty */ 328 { 329 NODE *first, *last; 330 331 first = build(O_LCON, (long) 1); 332 last = build(O_LCON, (long) lastlinenum); 333 $$ = build(O_COMMA, first, last); 334 } 335 | line_number 336 { 337 $$ = build(O_COMMA, $1, $1); 338 } 339 | line_number ',' line_number 340 { 341 $$ = build(O_COMMA, $1, $3); 342 } 343 ; 344 line_number: 345 INT 346 { 347 $$ = build(O_LCON, $1); 348 } 349 | '$' 350 { 351 $$ = build(O_LCON, (long) lastlinenum); 352 } 353 ; 354 address_list: 355 exp 356 { 357 $$ = build(O_COMMA, $1, $1); 358 } 359 | exp ',' exp 360 { 361 $$ = build(O_COMMA, $1, $3); 362 } 363 ; 364 opt_cond: 365 /* empty */ 366 { 367 $$ = NIL; 368 } 369 | IF boolean_exp 370 { 371 $$ = $2; 372 } 373 ; 374 exp_list: 375 exp 376 { 377 $$ = build(O_COMMA, $1, NIL); 378 } 379 | exp ',' exp_list 380 { 381 $$ = build(O_COMMA, $1, $3); 382 } 383 ; 384 exp: 385 term 386 { 387 $$ = build(O_RVAL, $1); 388 } 389 | term '(' exp_list ')' 390 { 391 $$ = build(O_CALL, $1, $3); 392 } 393 | constant 394 | '+' exp %prec UNARYSIGN 395 { 396 $$ = $2; 397 } 398 | '-' exp %prec UNARYSIGN 399 { 400 $$ = build(O_NEG, $2); 401 } 402 | exp addop exp %prec '+' 403 { 404 $$ = build($2, $1, $3); 405 } 406 | exp mulop exp %prec '*' 407 { 408 $$ = build($2, $1, $3); 409 } 410 | exp relop exp %prec '<' 411 { 412 $$ = build($2, $1, $3); 413 } 414 | '(' exp ')' 415 { 416 $$ = $2; 417 } 418 ; 419 boolean_exp: 420 exp 421 { 422 chkboolean($$ = $1); 423 } 424 ; 425 term: 426 NAME 427 { 428 $$ = build(O_NAME, $1); 429 } 430 | AT 431 { 432 SYM *s; 433 434 s = st_lookup(symtab, "at"); 435 if (s == NIL) { 436 error("\"at\" is not defined"); 437 } 438 $$ = build(O_NAME, s); 439 } 440 | term '[' exp_list ']' 441 { 442 $$ = subscript($1, $3); 443 } 444 | term '.' NAME 445 { 446 $$ = dot($1, $3); 447 } 448 | term '^' 449 { 450 $$ = build(O_INDIR, $1); 451 } 452 ; 453 constant: 454 INT 455 { 456 $$ = build(O_LCON, $1); 457 } 458 | REAL 459 { 460 $$ = build(O_FCON, $1); 461 } 462 | STRING 463 { 464 $$ = build(O_SCON, $1); 465 } 466 ; 467 addop: 468 '+' 469 { 470 $$ = O_ADD; 471 } 472 | '-' 473 { 474 $$ = O_SUB; 475 } 476 | OR 477 { 478 $$ = O_OR; 479 } 480 | '|' 481 { 482 $$ = O_OR; 483 } 484 ; 485 mulop: 486 '*' 487 { 488 $$ = O_MUL; 489 } 490 | '/' 491 { 492 $$ = O_DIVF; 493 } 494 | DIV 495 { 496 $$ = O_DIV; 497 } 498 | MOD 499 { 500 $$ = O_MOD; 501 } 502 | AND 503 { 504 $$ = O_AND; 505 } 506 | '&' 507 { 508 $$ = O_AND; 509 } 510 ; 511 relop: 512 '<' 513 { 514 $$ = O_LT; 515 } 516 | '<' '=' 517 { 518 $$ = O_LE; 519 } 520 | '>' 521 { 522 $$ = O_GT; 523 } 524 | '>' '=' 525 { 526 $$ = O_GE; 527 } 528 | '=' 529 { 530 $$ = O_EQ; 531 } 532 | '<' '>' 533 { 534 $$ = O_NE; 535 } 536 ; 537 %% 538 539 /* 540 * parser error handling 541 */ 542 543 yyerror(s) 544 char *s; 545 { 546 if (strcmp(s, "syntax error") == 0) { 547 error("bad command syntax"); 548 } else { 549 error(s); 550 } 551 } 552 553 /* 554 * In recovering from an error we gobble input up to a newline. 555 */ 556 557 gobble() 558 { 559 register int t; 560 561 if (!nlflag) { 562 while ((t = yylex()) != '\n' && t != 0); 563 } 564 } 565