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