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