1: /*
   2: **  GRAMMAR.Y -- Equel 6.2 grammar
   3: **
   4: **	Yacc grammar and semantic rules for Quel
   5: **	embedded in C.
   6: **
   7: **	The grammar is organized in the following manner:
   8: **		a) control structure
   9: **		b) quel statments
  10: **		c) equel statements
  11: **		d) declaration and use of C vars
  12: **		e) special objects
  13: **		f) expressions
  14: **		g) keywords
  15: **		h) noise words and punctuation
  16: **	Within a single classification, major objects are ordered
  17: **	alphabetically, and minor objects under the major ones they
  18: **	are in.
  19: **
  20: **	Side Effects:
  21: **		performs the translation of an Equel program into
  22: **		a C program with calls on the Equel run-time
  23: **		support
  24: **
  25: **	NOTE:
  26: **		There are two shift/reduce conflicts associated
  27: **		with the non-terminals "[o_]gen_while". It is resolved
  28: **		correctly by yacc.
  29: */
  30: 
  31: 
  32: 
  33: %{
  34:     /* STANDARD SCANNER & PARSER GLOBALS */
  35: 
  36: # include   "constants.h"
  37: # include   <stdio.h>
  38: # include   "globals.h"
  39: # include   <sccs.h>
  40: 
  41: SCCSID(@(#)grammar.y	8.2	3/1/85)
  42: 
  43: 
  44: %}
  45: %union
  46: {
  47:     struct disp_node    *u_dn;
  48: };
  49: 
  50: 
  51:     /* QUEL keywords */
  52: %token  <u_dn>  APPEND      COPY        CREATE      DEFINE
  53: %token  <u_dn>  DELETE      DELIM       DESTROY     HELP
  54: %token  <u_dn>  INDEX       MODIFY      PRINT       INTEGRITY
  55: %token  <u_dn>  RANGE       REPLACE     RETRIEVE    SAVE
  56: %token  <u_dn>  UNIQUE      UNUSE       USE     PERMIT
  57: %token  <u_dn>  VIEW
  58: 
  59:     /* special embedded QUEL commands */
  60: %token  <u_dn>  INGRES      EXIT        PARAM
  61: 
  62:     /* C variable usages */
  63: %token  <u_dn>  TYPE        ALLOC       STRUCT      STRUCT_VAR
  64: 
  65:     /* QUEL noise words */
  66: %token  <u_dn>  ALL     BY      FROM        IN
  67: %token  <u_dn>  INTO        IS      OF      ON
  68: %token  <u_dn>  ONTO        TO      WHERE       UNTIL
  69: %token  <u_dn>  AT
  70: 
  71:     /* constants */
  72: 
  73: %token  <u_dn>  NAME        SCONST      I2CONST     I4CONST
  74: %token  <u_dn>  F8CONST     C_CODE
  75: 
  76:     /* punctuation */
  77: %token  <u_dn>  COMMA       LPAREN      RPAREN      PERIOD
  78: %token  <u_dn>  QUOTE       BGNCMNT     ENDCMNT     LBRACE
  79: %token  <u_dn>  RBRACE      LBRKT       RBRKT       NONREF
  80: %token  <u_dn>  SEMICOL     POINTER     COLON       DOLLAR
  81: %token  <u_dn>  PCT
  82: 
  83:     /* operator classes */
  84: %token  <u_dn>  UOP
  85: %token  <u_dn>  BOP
  86: %token  <u_dn>  UAOP
  87: %token  <u_dn>  BDOP
  88: %token  <u_dn>  EOP
  89: %token  <u_dn>  LBOP        LUOP
  90: %token  <u_dn>  FOP     FBOP
  91: %token  <u_dn>  AOP
  92: 
  93:     /* define ascending precedence for operators */
  94: 
  95: %left   LBOP
  96: %left   LUOP
  97: %left   UAOP
  98: %left   BOP     LBRKT
  99: %left   UOP
 100: %nonassoc       unaryop
 101: 
 102:     /* non-teriminal type info */
 103: %type <u_dn>        endblock
 104: %type <u_dn>        c_variable
 105: %type <u_dn>        cvarx
 106: %type <u_dn>        struct_var
 107: %type <u_dn>        ptr
 108: %type <u_dn>        selector_part
 109: %type <u_dn>        str_var_key
 110: %type <u_dn>        id
 111: 
 112: 
 113: 
 114: %%
 115: %{
 116:     struct cvar *cvarp;
 117: %}
 118: 
 119: /*
 120:  * Program Control Structure
 121:  */
 122: 
 123: program:    program statement =
 124:         {
 125:             /* for each "statement", free the symbol space
 126: 			 * used by that query (lookahed space must not
 127: 			 * be freed), and catch up on output lines
 128: 			 */
 129:             symspfree();
 130:             equate_lines();
 131:         }
 132:     |   ;
 133: ;
 134: statement:  startquel quel_statement =
 135:         {
 136:             w_sync();
 137:             /* the purpose of the actions for startquel
 138: 			 * and this action is to make each query
 139: 			 * a single compound C statement (if (x) "{query}")
 140: 			 */
 141:             w_op("}");
 142:         }
 143:     |   startquel equel_statement =
 144:         {
 145:             end_quote();
 146:             w_op("}");
 147:         }
 148:     |   c_code
 149:     |   declaration
 150:     |   error
 151: ;
 152: startquel:  =
 153:             w_op("{");
 154: ;
 155: /*
 156:  * C_CODE is a token returned by the lexical analyzer
 157:  * when it recognizes that the following line is not
 158:  * equel code. On the NEXT call to the lexical analyzer,
 159:  * the code will be copied from the source to the output file.
 160:  */
 161: c_code:     C_CODE
 162:     |   beginblock =
 163:             Block_level += 1;
 164:     |   endblock =
 165:         {
 166:             if (Block_level == 0)
 167:                 yyserror("extra '}'", $1);
 168:             else if ((Block_level -= 1) == 0)
 169:             {
 170:                 freecvar(&C_locals);
 171:                 freecvar(&F_locals);
 172:             }
 173:         }
 174: ;
 175: 
 176:     /* the %prec is to resolve conflicts with the { after a
 177: 	 * "tupret".
 178: 	 */
 179: beginblock: LBRACE  %prec LBOP =
 180:             w_op($1->d_elm);
 181: ;
 182: endblock:   RBRACE =
 183:             w_op($1->d_elm);
 184: ;
 185: quel_statement: append
 186:     |   copy
 187:     |   create
 188:     |   delete
 189:     |   delim
 190:     |   destroy
 191:     |   help
 192:     |   index
 193:     |   integrity
 194:     |   modify
 195:     |   permit
 196:     |   print
 197:     |   range
 198:     |   replace
 199:     |   retrieve
 200:     |   save
 201:     |   unuse
 202:     |   use
 203:     |   view
 204: ;
 205: 
 206:     /* commands particular to Equel */
 207: 
 208: equel_statement:append_p
 209:         {
 210:             w_sync();
 211:         }
 212:     |   copy_p
 213:     |   create_p
 214:         {
 215:             w_sync();
 216:         }
 217:     |   exit
 218:     |   ingres
 219:     |   replace_p
 220:         {
 221:             w_sync();
 222:         }
 223:     |   retrieve_p
 224:     |   tupret
 225:     |   view_p
 226: ;
 227: /*
 228:  * QUEL statements
 229:  */
 230: 
 231: append:     append_key apclause tlclause qualclause
 232: ;
 233: apclause:   apkword id
 234: ;
 235: 
 236: copy:       copy_key id lparen ctl rparen cp_kword filename
 237:     |   copy_key id lparen rparen cp_kword filename
 238: ;
 239: filename:   sconst
 240:     |   id
 241: ;
 242: 
 243: create:     create_key id lparen ctl rparen
 244: ;
 245: 
 246: delete:     delete_key delclause qualclause
 247: ;
 248: delclause:  delnoise id
 249: ;
 250: 
 251: delim:      define_key delim_key id lparen id comma sconst rparen
 252: ;
 253: 
 254: destroy:    destroy_key idlist
 255:     |   destroy_key integ_permit id int_list_all
 256:     |   destroy_key delim_key id
 257: ;
 258: integ_permit:   integ_key
 259:     |   permit_key
 260: ;
 261: int_list_all:   int_list
 262:     |   all
 263: ;
 264: 
 265: help:       help_key
 266:     |   help_key all
 267:     |   help_key hlist
 268:     |   help_key delim_key
 269:     |   help_key delim_key hlist
 270:     |   help_key int_perm_view idlist
 271: ;
 272: hlist:      hparam
 273:     |   hlist comma hparam
 274: ;
 275: hparam:     id
 276:     |   sconst
 277: ;
 278: int_perm_view:  integ_permit
 279:     |   view_key
 280: ;
 281: 
 282: index:      index_key id is id lparen idlist rparen
 283: ;
 284: 
 285: integrity:  define_key integ_key integnoise id isnoise qual
 286: ;
 287: 
 288: modify:     modify_key id to id on modkeylist density
 289:     |   modify_key id to id
 290: ;
 291: modkeylist: modkey
 292:     |   modkeylist comma modkey
 293: ;
 294: modkey:     id
 295:     |   id colon id
 296: ;
 297: density:    where modfill
 298:     |   ;
 299: ;
 300: modfill:    id is mod_var
 301:     |   modfill comma id is mod_var
 302: ;
 303:     /* mod_var can be an integer constant or var, or a string var
 304: 	 * or a quel name
 305: 	 */
 306: mod_var:    I2CONST =
 307:             w_con(I2CONST, $1->d_elm);
 308:     |   c_variable =
 309:         {
 310:             if ($1)
 311:             {
 312:                 if (!Cvarp)
 313:                     w_key($1->d_elm);
 314:                 else if (Fieldp && Fieldp->c_type == opINT
 315:                     || Cvarp->c_type == opINT)
 316:                         w_var(Cv_display, opINT);
 317:                 else if (Fieldp && Fieldp->c_type == opSTRING
 318:                     || Cvarp->c_type == opSTRING)
 319:                         w_var(Cv_display, opIDSTRING);
 320:                 else
 321:                     yyserror("in MODIFY, qual var must be in or string",
 322:                     $1);
 323:             }
 324:             else
 325:                 yyserror("bad modify qualification", 0);
 326:             free_display(Cv_display);
 327:             Cvarp = Fieldp = 0;
 328:         }
 329: ;
 330: 
 331: permit:     def_perm permit_list on_of_to id perm_tl
 332:             perm_who perm_term perm_time perm_day qualclause
 333: ;
 334: def_perm:   define_key permit_key
 335: ;
 336: permit_list:    permlistelm
 337:     |   permit_list comma permlistelm
 338: ;
 339: permlistelm:    RETRIEVE =
 340:             w_key($1->d_elm);
 341:     |   APPEND =
 342:             w_key($1->d_elm);
 343:     |   DELETE =
 344:             w_key($1->d_elm);
 345:     |   REPLACE =
 346:             w_key($1->d_elm);
 347:     |   all
 348: ;
 349: on_of_to:   on
 350:     |   of
 351:     |   to
 352: ;
 353: perm_tl:    lparen idlist rparen
 354:     |   ;
 355: ;
 356: perm_who:   to id
 357:     |   to all
 358:     |   ;
 359: ;
 360: perm_term:  at id
 361:     |   at all
 362:     |   ;
 363: ;
 364: perm_time:  from integer colon integer to
 365:             integer colon integer
 366:     |   ;
 367: ;
 368: perm_day:   on id to id
 369:     |   ;
 370: ;
 371: 
 372: print:      print_key idlist
 373: ;
 374: 
 375: range:      range_of id is id
 376: ;
 377: 
 378: replace:    replace_key repclause tlclause qualclause
 379: ;
 380: repclause:  repkword id
 381: ;
 382: 
 383: retrieve:   retrieve_key resclause tlclause qualclause
 384: ;
 385: resclause:  retkword id
 386: ;
 387: 
 388: save:       save_key id until date
 389: ;
 390: date:       id integer integer
 391: ;
 392: 
 393: unuse:      unuse_key id
 394: ;
 395: 
 396: use:        use_key id
 397: ;
 398: 
 399: view:       define_key view_key id tlclause qualclause
 400: ;
 401: 
 402: /*
 403:  * Statements Particular to Equel
 404:  */
 405: 
 406: append_p:   append_p_key apclause param_tl qualclause
 407: ;
 408: 
 409: copy_p:     copy_p_key id param_tl fr_in_id filename
 410: ;
 411: fr_in_id:   cp_kword
 412:     |   c_variable =
 413:         {
 414:             if ($1 && Cvarp)
 415:             {
 416:                 if (Fieldp && Fieldp->c_type != opSTRING
 417:                    || !Fieldp && Cvarp->c_type != opSTRING)
 418:                     yyserror("string var expected for from/into in COPY",
 419:                     $1);
 420:                 else
 421:                     w_var(Cv_display, opIDSTRING);
 422:             }
 423:             else
 424:                 yyserror("into/from expected in COPY", $1);
 425:             free_display(Cv_display);
 426:             Fieldp = Cvarp = 0;
 427:         }
 428: ;
 429: 
 430: create_p:   create_p_key id param_tl
 431: ;
 432: 
 433: exit:       EXIT =
 434:         {
 435:             Opflag = mdEXIT;
 436:             w_new("IIexit();");
 437:         }
 438: ;
 439: 
 440: ingres:     ingres_key param_list =
 441:             w_op(");");
 442: ;
 443: param_list: param =
 444:             w_op("0");
 445:     |   param param_list
 446: ;
 447: param:      id  =
 448:             w_op(",");
 449:     |   SCONST =
 450:         {
 451:             w_string($1->d_elm, 0);
 452:             w_op(",");
 453:         }
 454: ;
 455: 
 456: replace_p:  replace_p_key repclause param_tl qualclause
 457: ;
 458: 
 459: retrieve_p: retrieve_p_key resclause param_tl qualclause
 460: ;
 461: 
 462: tupret:     tupret_keyw xc_code =
 463:             w_flush();
 464:     |   tupret_p o_xc_code =
 465:             w_flush();
 466: ;
 467: tupret_keyw:    retrieve_key unique c_tlclause qualclause   =
 468:         {
 469:             w_new("IIsetup();");
 470:         }
 471: ;
 472: unique:     UNIQUE =
 473:         {
 474:             Opflag = mdTUPRET;
 475:             w_key($1->d_elm);
 476:         }
 477:     |   =
 478:             Opflag = mdTUPRET;
 479: ;
 480: c_tlclause: lparen  c_tlist rparen
 481: ;
 482: c_tlist:    c_tlelm
 483:     |   c_tlelm comma c_tlist
 484: ;
 485: c_tlelm:    reduc cvar is_key afcn
 486: ;
 487: reduc:      =
 488:             Opflag = mdCTLELM;
 489: ;
 490: xc_code:    LBRACE gen_while c_code RBRACE %prec LBRACE =
 491:             w_op("}");
 492:     |   gen_while %prec LBOP =
 493:             w_op("}");
 494: ;
 495: gen_while:  =
 496:         {
 497:             w_new("while(IIn_get(");
 498:             w_file();
 499:             w_op(")){");
 500:             w_ret();
 501:             free_ret();
 502:             w_op("if(IIerrtest())continue;");
 503:             equate_lines();
 504:         }
 505: ;
 506: o_xc_code:  LBRACE  o_gen_while c_code RBRACE %prec LBRACE =
 507:             w_op("}");
 508:     |   o_gen_while %prec LBOP =
 509:             w_op("}");
 510: ;
 511: o_gen_while:    =
 512:         {
 513:             w_new("while(IIgettup(");
 514:             w_file();
 515:             w_op(")){");
 516:             equate_lines();
 517:         }
 518: ;
 519: tupret_p:   tupret_p_key unique param_tl qualclause =
 520:         {
 521:             w_new("IIsetup();");
 522:         }
 523: ;
 524: 
 525: view_p:     PARAM define_key view_key id param_tl qualclause
 526: ;
 527: 
 528: /*
 529:  * Declarations and use of C variables
 530:  */
 531: 
 532: declaration:    decl_specifer declarator_list SEMICOL   =
 533:         {
 534:             w_op($3->d_elm);
 535:             Type_spec = 0;
 536:         }
 537:     |   decl_specifer SEMICOL =
 538:         {
 539:             w_op($2->d_elm);
 540:             Type_spec = 0;
 541:         }
 542: ;
 543: decl_specifer:  type_specifier
 544:     |   sc_specifier
 545:     |   type_specifier sc_specifier
 546:     |   sc_specifier type_specifier
 547:     |   struct_dec =
 548:         {
 549:             Struct_flag = 0;
 550:             Type_spec = opSTRUCT;
 551:         }
 552:     |   sc_specifier struct_dec =
 553:         {
 554:             Struct_flag = 0;
 555:             Type_spec = opSTRUCT;
 556:         }
 557: ;
 558: sc_specifier:   ALLOC   =
 559:         {
 560:             Opflag = mdDECL;
 561:             w_key($1->d_elm);
 562:             /* in case the default "int" should be assumed,
 563: 			 * the Type_spec is set up for it, if a previous
 564: 			 * type hasn't been given
 565: 			 */
 566:             if (!Type_spec)
 567:                 Type_spec = opINT;
 568:         }
 569: ;
 570: type_specifier: TYPE    =
 571:         {
 572:             Opflag = mdDECL;
 573:             w_key($1->d_elm);
 574:             Type_spec = Opcode;
 575:         }
 576: ;
 577: struct_dec: struct_name field_declaration
 578:     |   struct_name
 579:     |   struct_key field_declaration
 580: ;
 581: struct_name:    struct_key NAME =
 582:             w_key($2->d_elm);
 583: ;
 584: field_declaration:  lbrace field_seq RBRACE =
 585:         {
 586:             w_op($3->d_elm);
 587:             Type_spec = 0;
 588:         }
 589: ;
 590: field_seq:  field_seq field
 591:     |   ;
 592: ;
 593: field:      type_specifier declarator_list SEMICOL =
 594:         {
 595:             w_op($3->d_elm);
 596:             Type_spec = 0;
 597:         }
 598:     |   C_CODE
 599: ;
 600: declarator_list:    cvar_dec
 601:     |   declarator_list comma cvar_dec
 602: ;
 603: cvar_dec:   cvarx =
 604:         {
 605:             if (Type_spec == opSTRING)
 606:                 Indir_level -= 1;
 607:             if (Struct_flag)
 608:                 decl_field($1->d_elm, Type_spec,
 609:                     Indir_level, Block_level);
 610:             else
 611:                 decl_cvar($1->d_elm, Type_spec,
 612:                     Indir_level, Block_level);
 613:             free_display(Cv_display);
 614:             Indir_level = Field_indir = 0;
 615:             Fieldp = Cvarp = 0;
 616:         }
 617: ;
 618: c_variable: cvarx =
 619:         {
 620:             $$ = $1;
 621:             if (Cvarp && Cvarp->c_indir != Indir_level)
 622:             {
 623:                 yyserror("bad indirection on a C variable", $1);
 624:                 $$ = 0;
 625:             }
 626:             Indir_level = Field_indir = 0;
 627:         }
 628:     |   NONREF NAME =
 629:         {
 630:             enter_display(Cv_display, salloc($1->d_elm));
 631:             Cvarp = Fieldp = 0;
 632:             $$ = $2;
 633:         }
 634:     |   NONREF STRUCT_VAR =
 635:         {
 636:             enter_display(Cv_display, salloc($1->d_elm));
 637:             Cvarp = Fieldp = 0;
 638:             $$ = $2;
 639:         }
 640:     |   struct_var =
 641:         {
 642:             if (!Fieldp)
 643:             {
 644:                 yyserror("undeclared field", $1);
 645:                 $$ = $<u_dn>0;
 646:             }
 647:             else if (Fieldp->c_indir != Field_indir)
 648:             {
 649:                 yyserror("bad indirection on a structure's field",
 650:                 $1);
 651:                 $$ = 0;
 652:             }
 653:             if (Cvarp->c_indir != Indir_level)
 654:             {
 655:                 yysemerr("bad indirection a structure variable",
 656:                 Cvarp->c_indir);
 657:                 $$ = 0;
 658:             }
 659:             Indir_level = Field_indir = 0;
 660:         }
 661: ;
 662: struct_var: ptr struct_var  %prec unaryop =
 663:         {
 664:             if ($1->d_elm[1] == '*')
 665:                 Field_indir += 1;
 666:             Field_indir += 1;
 667:             $$ = $2;
 668:         }
 669:     |   struct_var arraysub %prec LBRKT =
 670:             Field_indir += 1;
 671:     |   str_var_key selector_part
 672: ;
 673: str_var_key:    STRUCT_VAR =
 674:         {
 675:             Cvarp = getcvar($1->d_elm);
 676:             enter_display(Cv_display, $1->d_elm);
 677:         }
 678: ;
 679: selector_part:  arraysub selector_part =
 680:         {
 681:             Indir_level += 1;
 682:             $$ = $2;
 683:         }
 684:     |   select_op NAME =
 685:         {
 686:             enter_display(Cv_display, $2->d_elm);
 687:             Fieldp = getfield($2->d_elm);
 688:             $$ = $2;
 689:         }
 690: ;
 691: select_op:  PERIOD =
 692:             enter_display(Cv_display, $1->d_elm);
 693:     |   POINTER =
 694:         {
 695:             enter_display(Cv_display, $1->d_elm);
 696:             Indir_level += 1;
 697:         }
 698: ;
 699: 
 700: /* use of a C variable */
 701: cvar:       c_variable =
 702:         {
 703:             if ($1)
 704:             {
 705:                 if (!Fieldp && ! Cvarp)
 706:                 {
 707:                     if (!Field_indir && !Indir_level
 708:                       && (sequal($1->d_elm, "dba")
 709:                         || sequal($1->d_elm, "usercode")))
 710:                         /* constant operator COP */
 711:                         w_key($1->d_elm);
 712:                     else
 713:                         yyserror("C var expected", $1);
 714:                 }
 715:                 else if (Opflag == mdCTLELM)
 716:                 {
 717:                     w_con(NAME,
 718:                       Fieldp ? Fieldp->c_id: Cvarp->c_id);
 719:                     enter_ret(Cv_display,
 720:                       Fieldp ? Fieldp->c_type: Cvarp->c_type);
 721:                 }
 722:                 else
 723:                     w_var(Cv_display,
 724:                       Fieldp ? Fieldp->c_type: Cvarp->c_type);
 725:             }
 726:             free_display(Cv_display);
 727:             Fieldp = Cvarp = 0;
 728:             Indir_level = Field_indir = 0;
 729:         }
 730: cvarx:      NAME =
 731:         {
 732:             if (Opflag == mdDECL)
 733:                 w_con(NAME, $1->d_elm);
 734:             else
 735:             {
 736:                 Cvarp = getcvar($1->d_elm);
 737:                 enter_display(Cv_display, salloc($1->d_elm));
 738:             }
 739:         }
 740:     |   ptr cvarx %prec unaryop =
 741:         {
 742:             if ($1->d_elm [1] == '*')
 743:                 Indir_level += 1;
 744:             Indir_level += 1;
 745:             $$ = $2;
 746:         }
 747:     |   cvarx arraysub  %prec LBRKT =
 748:         {
 749:             Indir_level += 1;
 750:         }
 751: ;
 752: ptr:        BOP =
 753:         {
 754:             if (!sequal($1->d_elm, "*") && !sequal((struct disp_node *)($1)->d_elm, "**"))
 755:                 yyserror(Opflag == mdDECL ?
 756:                 "invalid operator in declaration":
 757:                 "invalid operator in C variable",
 758:                 $1);
 759:             if (Opflag == mdDECL)
 760:                 w_op($1->d_elm);
 761:             else
 762:                 enter_display(Cv_display, salloc($1->d_elm));
 763:         }
 764: ;
 765: arraysub:   LBRKT =
 766:         {
 767:             if (Opflag == mdDECL)
 768:                 eat_display(0, '[', ']');
 769:             else
 770:                 eat_display(Cv_display, '[', ']');
 771:         }
 772: ;
 773: 
 774: /*
 775:  * Special Objects used throughout grammar
 776:  */
 777: 
 778: id:     c_variable =
 779:         {
 780:             if ($1)
 781:             {
 782:                 if (Cvarp)
 783:                 {
 784:                     if (Fieldp && Fieldp->c_type != opSTRING
 785:                        || !Fieldp && Cvarp->c_type != opSTRING)
 786:                         yyserror("string var expected", $1);
 787:                     else if (Opflag == mdFILENAME)
 788:                         w_var(Cv_display, opSTRING);
 789:                     else if (Opflag == mdINGRES)
 790:                         w_display(Cv_display);
 791:                     else
 792:                         w_var(Cv_display, opIDSTRING);
 793:                 }
 794:                 else if (Opflag == mdINGRES)
 795:                     w_string($1->d_elm, 0);
 796:                 else if (Opflag == mdFILENAME)
 797:                     yyserror("file for a COPY must be a string or string variable",
 798:                     $1);
 799:                 else
 800:                     w_key($1->d_elm);
 801:             }
 802:             free_display(Cv_display);
 803:             Fieldp = Cvarp = 0;
 804:         }
 805: ;
 806: 
 807: idlist:     id
 808:     |   idlist comma id
 809: ;
 810: 
 811: integer:    I2CONST =
 812:             w_con(I2CONST, $1->d_elm);
 813:     |   c_variable =
 814:         {
 815:             if ($1)
 816:             {
 817:                 if (Cvarp)
 818:                     if (Fieldp && Fieldp->c_type == opINT
 819:                        || Cvarp->c_type == opINT)
 820:                         w_var(Cv_display, opINT);
 821:                     else
 822:                         yyserror("integer variable required",
 823:                         $1);
 824:                 else
 825:                     yyserror("integer variable required", $1);
 826:             }
 827:             free_display(Cv_display);
 828:         }
 829: ;
 830: 
 831: int_list:   integer
 832:     |   int_list comma integer
 833: ;
 834: 
 835: param_tl:   LPAREN =
 836:         {
 837:             w_op("(");
 838:             end_quote();
 839:             if (Opflag == mdTUPRET)
 840:                 w_key("IIw_left");
 841:             else
 842:                 w_key("IIw_right");
 843:             eat_display(0, '(', ')');
 844:             w_op(";");
 845:             begin_quote();
 846:             w_op(")");
 847: 
 848:         }
 849: ;
 850: 
 851: qualclause: where qual
 852:     |   where c_variable =
 853:         {
 854:             if (!$2 || !Cvarp)
 855:                 yyserror("C var (string) expected", $2);
 856:             else if (Fieldp && Fieldp->c_type == opSTRING
 857:                 || Cvarp->c_type == opSTRING)
 858:             {
 859:                 end_quote();
 860:                 w_op("IIwrite(");
 861:                 w_display(Cv_display);
 862:                 w_op(");");
 863:             }
 864:             else
 865:                 yyserror("var must be string valued for qualification",
 866:                 $2);
 867:             free_display(Cv_display);
 868:             Cvarp = Fieldp = 0;
 869:         }
 870:     |   ;
 871: ;
 872: qual:       lparen qual rparen
 873:     |   luop qual       %prec LUOP
 874:     |   qual lbop qual      %prec LBOP
 875:     |   clause
 876:     |   ;
 877: ;
 878: clause: afcn rop afcn
 879:     |   afcn rop afcn bdop afcn
 880: ;
 881: ctl:        id is id
 882:     |   ctl comma id is id
 883: ;
 884: 
 885: sconst:     SCONST =
 886:             w_con(SCONST, $1->d_elm);
 887: ;
 888: 
 889: tlclause:   lparen tlist rparen
 890: ;
 891: tlist:      tlelm
 892:     |   tlelm comma tlist
 893: ;
 894: tlelm:      id is_key afcn
 895:     |   attrib
 896: ;
 897: 
 898: /*
 899:  * Expressions
 900:  */
 901: 
 902: afcn:       aggrfcn
 903:     |   aggr
 904:     |   attribfcn
 905:     |   afcn bop afcn   %prec BOP
 906:     |   afcn uaop afcn  %prec UAOP
 907:     |   lparen afcn rparen
 908:     |   uop afcn    %prec unaryop
 909:     |   fop lparen afcn rparen
 910:     |   fbop lparen afcn comma afcn rparen
 911: ;
 912: aggr:       aop lparen afcn qualclause rparen
 913: ;
 914: aggrfcn:    aop lparen afcn by aseq qualclause rparen
 915: ;
 916: attribfcn:  I2CONST =
 917:             w_con(I2CONST, $1->d_elm);
 918:     |   I4CONST =
 919:             w_con(I4CONST, $1->d_elm);
 920:     |   F8CONST =
 921:             w_con(F8CONST, $1->d_elm);
 922:     |   SCONST  =
 923:             w_con(SCONST, $1->d_elm);
 924:     |   cvar
 925:     |   attrib
 926: ;
 927: aseq:       aseq comma afcn
 928:     |   afcn
 929: ;
 930: attrib:     id period id
 931:     |   id period all=
 932:         {
 933:             if (Opflag != mdVIEW && Opflag != mdRETRIEVE
 934:                && Opflag != mdAPPEND)
 935:                 yyserror(
 936:                 "'all' applied to this range variable illegal in this kind of statement",
 937:                 $1);
 938:         }
 939:     |   attrib stringpart
 940: ;
 941: stringpart: leftclose subelm rightclose
 942:     |   leftclose grpelm rightclose
 943: ;
 944: leftclose:  pct
 945:     |   lparen
 946: ;
 947: rightclose: pct
 948:     |   rparen
 949: ;
 950: subelm:     integer nameprt
 951:     |   integer nameprt dollar
 952:     |   dollar
 953:     |   nameprt
 954:     |   nameprt dollar
 955: ;
 956: grpelm:     subelm comma subelm
 957: ;
 958: nameprt:    id
 959:     |   sconst
 960: ;
 961: lbop:       LBOP    =
 962:             w_key($1->d_elm);
 963: ;
 964: luop:       LUOP    =
 965:             w_key($1->d_elm);
 966: ;
 967: bdop:       BDOP    =
 968:             w_op($1->d_elm);
 969: ;
 970: rop:        EOP =
 971:             w_op($1->d_elm);
 972:     |   BDOP    =
 973:             w_op($1->d_elm);
 974:     |   IS  =
 975:             w_op("=");
 976: ;
 977: uop:        UOP =
 978:             w_op($1->d_elm);
 979: ;
 980: fop:        FOP =
 981:             w_key($1->d_elm);
 982: ;
 983: fbop:       FBOP =
 984:             w_key($1->d_elm);
 985: ;
 986: bop:        BOP =
 987:             w_op($1->d_elm);
 988:     |   UOP =
 989:             w_op($1->d_elm);
 990: ;
 991: by:     BY =
 992:             w_key($1->d_elm);
 993: ;
 994: aop:        AOP =
 995:             w_key($1->d_elm);
 996: ;
 997: uaop:       UAOP =
 998:             w_key($1->d_elm);
 999: ;
1000: 
1001: /*
1002:  * Keywords
1003:  */
1004: 
1005: append_p_key:   PARAM APPEND =
1006:         {
1007:             begin_quote();
1008:             w_key($2->d_elm);
1009:             Opflag = mdAPPEND;
1010:         }
1011: ;
1012: append_key: APPEND  =
1013:         {
1014:             Opflag = mdAPPEND;
1015:             begin_quote();
1016:             w_key($1->d_elm);
1017:         }
1018: ;
1019: copy_key:   COPY    =
1020:         {
1021:             Opflag = mdCOPY;
1022:             begin_quote();
1023:             w_key($1->d_elm);
1024:         }
1025: ;
1026: copy_p_key: PARAM COPY =
1027:         {
1028:             Opflag = mdCOPY;
1029:             begin_quote();
1030:             w_key($2->d_elm);
1031:         }
1032: ;
1033: cp_kword:   INTO    =
1034:         {
1035:             w_key($1->d_elm);
1036:             Opflag = mdFILENAME;
1037:         }
1038:     |   FROM    =
1039:         {
1040:             w_key($1->d_elm);
1041:             Opflag = mdFILENAME;
1042:         }
1043: ;
1044: create_key: CREATE  =
1045:         {
1046:             Opflag = mdCREATE;
1047:             begin_quote();
1048:             w_key($1->d_elm);
1049:         }
1050: ;
1051: create_p_key:   PARAM CREATE =
1052:         {
1053:             Opflag = mdCREATE;
1054:             begin_quote();
1055:             w_key($2->d_elm);
1056:         }
1057: ;
1058: define_key: DEFINE =
1059:         {
1060:             Opflag = mdDEFINE;
1061:             begin_quote();
1062:             w_key($1->d_elm);
1063:         }
1064: ;
1065: delete_key: DELETE  =
1066:         {
1067:             Opflag = mdDELETE;
1068:             begin_quote();
1069:             w_key($1->d_elm);
1070:         }
1071: ;
1072: delim_key:  DELIM =
1073:         {
1074:             w_key($1->d_elm);
1075:         }
1076: ;
1077: destroy_key:    DESTROY =
1078:         {
1079:             Opflag = mdDESTROY;
1080:             begin_quote();
1081:             w_key($1->d_elm);
1082:         }
1083: ;
1084: help_key:   HELP =
1085:         {
1086:             Opflag = mdHELP;
1087:             begin_quote();
1088:             w_key($1->d_elm);
1089:         }
1090: ;
1091: index_key:  INDEX ON =
1092:         {
1093:             Opflag = mdINDEX;
1094:             begin_quote();
1095:             w_key($1->d_elm);
1096:             w_key($2->d_elm);
1097:         }
1098: ;
1099: ingres_key: INGRES  =
1100:         {
1101:             Opflag = mdINGRES;
1102:             w_new("IIingres(");
1103:         }
1104: ;
1105: integ_key:  INTEGRITY=
1106:         {
1107:             if (Opflag == mdDEFINE)
1108:                 Opflag = mdINTEGRITY;
1109:             w_key($1->d_elm);
1110:         }
1111: ;
1112: is_key:     IS =
1113:         {
1114:             if (Opflag == mdCTLELM)
1115:                 Opflag = mdTUPRET;
1116:             w_op("=");
1117:         }
1118:     |   BY =
1119:             w_key($1->d_elm);
1120: ;
1121: modify_key: MODIFY  =
1122:         {
1123:             Opflag = mdMODIFY;
1124:             begin_quote();
1125:             w_key($1->d_elm);
1126:         }
1127: ;
1128: permit_key: PERMIT=
1129:         {
1130:             if (Opflag == mdDEFINE)
1131:                 Opflag = mdPROT;
1132:             w_key($1->d_elm);
1133:         }
1134: ;
1135: print_key:  PRINT   =
1136:         {
1137:             Opflag = mdPRINT;
1138:             begin_quote();
1139:             w_key($1->d_elm);
1140:         }
1141: ;
1142: range_of:   RANGE OF =
1143:         {
1144:             Opflag = mdRANGE;
1145:             begin_quote();
1146:             w_key($1->d_elm);
1147:             w_key($2->d_elm);
1148:         }
1149: ;
1150: replace_key:    REPLACE =
1151:         {
1152:             Opflag = mdREPLACE;
1153:             begin_quote();
1154:             w_key($1->d_elm);
1155:         }
1156: ;
1157: replace_p_key:  PARAM REPLACE =
1158:         {
1159:             begin_quote();
1160:             Opflag = mdREPLACE;
1161:             w_key($2->d_elm);
1162:         }
1163: ;
1164: retrieve_key:   RETRIEVE    =
1165:         {
1166:             Opflag = mdRETRIEVE;
1167:             begin_quote();
1168:             w_key($1->d_elm);
1169:         }
1170: ;
1171: retrieve_p_key: PARAM RETRIEVE =
1172:         {
1173:             Opflag = mdRETRIEVE;
1174:             begin_quote();
1175:             w_key($2->d_elm);
1176:         }
1177: ;
1178: save_key:   SAVE    =
1179:         {
1180:             Opflag = mdSAVE;
1181:             begin_quote();
1182:             w_key($1->d_elm);
1183:         }
1184: ;
1185: struct_key:     STRUCT =
1186:         {
1187:             Opflag = mdDECL;
1188:             Struct_flag = 1;
1189:             w_key($1->d_elm);
1190:         }
1191: ;
1192: tupret_p_key:   PARAM RETRIEVE =
1193:         {
1194:             begin_quote();
1195:             w_key($2->d_elm);
1196:             Opflag = mdTUPRET;
1197:         }
1198: ;
1199: unuse_key:  UNUSE =
1200:         {
1201:             begin_quote();
1202:             w_key($1->d_elm);
1203:         }
1204: ;
1205: use_key:    USE =
1206:         {
1207:             begin_quote();
1208:             w_key($1->d_elm);
1209:         }
1210: ;
1211: view_key:   VIEW =
1212:         {
1213:             if (Opflag == mdDEFINE)
1214:                 Opflag = mdVIEW;
1215:             w_key($1->d_elm);
1216:         }
1217: ;
1218: 
1219: /*
1220:  * Noise words and punctuation
1221:  */
1222: 
1223: all:        ALL=
1224:             w_key($1->d_elm);
1225: ;
1226: apkword:    INTO
1227:     |   ONTO
1228:     |   TO
1229:     |   ON
1230:     |   ;
1231: ;
1232: at:     AT =
1233:             w_key($1->d_elm);
1234: ;
1235: colon:      COLON =
1236:             w_op($1->d_elm);
1237: ;
1238: comma:      COMMA   =
1239:             w_op($1->d_elm);
1240: ;
1241: delnoise:   IN
1242:     |   ON
1243:     |   FROM
1244:     |   ;
1245: ;
1246: dollar:     DOLLAR =
1247:             w_key($1->d_elm);
1248: ;
1249: from:       FROM =
1250:             w_key($1->d_elm);
1251: ;
1252: integnoise: ON
1253:     |   ONTO
1254:     |   IN
1255:     |   OF
1256: ;
1257: is:     IS  =
1258:             w_op("=");
1259: ;
1260: isnoise:    IS
1261:     |   ;
1262: ;
1263: lbrace:     LBRACE =
1264:             w_op($1->d_elm);
1265: ;
1266: lparen:     LPAREN  =
1267:             w_op($1->d_elm);
1268: ;
1269: of:     OF=
1270:             w_key($1->d_elm);
1271: ;
1272: on:     ON =
1273:             w_key($1->d_elm);
1274: ;
1275: pct:        PCT =
1276:             w_op($1->d_elm);
1277: ;
1278: period:     PERIOD =
1279:             w_op($1->d_elm);
1280: ;
1281: repkword:   INTO
1282:     |   IN
1283:     |   ON
1284:     |   ;
1285: ;
1286: rparen:     RPAREN  =
1287:             w_op($1->d_elm);
1288: ;
1289: to:     TO =
1290:             w_key($1->d_elm);
1291: ;
1292: retkword:   INTO
1293:     |   TO
1294:     |   ;
1295: ;
1296: until:      UNTIL   =
1297:             w_key($1->d_elm);
1298: ;
1299: where:      WHERE   =
1300:             w_key($1->d_elm);
1301: ;
1302: %%
1303: 
1304: # include   "tokens.y"
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2969
Valid CSS Valid XHTML 1.0 Strict