home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / parser / grammar.y < prev    next >
Encoding:
Text File  |  1992-09-18  |  22.2 KB  |  1,321 lines

  1.  
  2. /*
  3. **  GRAMMAR.Y
  4. **
  5. **    This file contains a grammar for ingres parsing.  It is setup
  6. **    for the (7-31-78) version of yacc.
  7. **
  8. **    Use:
  9. **        to use for non-distributed ingres:
  10. **            grep -v "DDD" > grammar.y
  11. **
  12. **    Trace Flags:
  13. **        Grammar.y ~~ 38, 39
  14. */
  15.  
  16. %{
  17. /* SCANNER/PARSER GLOBALS & TABLES */
  18. # include    <ingres.h>
  19. # include    <aux.h>
  20. # include    <tree.h>
  21. # include    <symbol.h>
  22. # include    <pv.h>
  23. # include    "parser.h"
  24. # include    <sccs.h>
  25. # include     <errors.h>
  26.  
  27. SCCSID(@(#)grammar.y    8.6    5/30/88)
  28.  
  29. # ifdef        xPTR1
  30. # define    YYDEBUG    1
  31. # endif
  32.  
  33. int                i;
  34. struct atstash            *aptr;
  35. char                permbuf[3];
  36. /* space for two names, their null bytes and the seperator */
  37. char                modbuf[(2 * (MAXNAME + 1)) + 1];
  38. static char            hqmbuf[2];
  39.  
  40. extern DESC            Reldesc;
  41. extern int            Opflag;
  42. extern QTREE            *Lastree;
  43. extern QTREE            *Tidnode;
  44. extern int            Err_current;
  45. extern int            Rsdmno;
  46. extern int            Resrng;
  47. extern int            Qrymod;
  48. extern int            Permcomd;
  49. extern char            *Trname;
  50. extern int            Qlflag;
  51. extern struct atstash         Faketid;
  52. extern char            *Tuple;
  53. extern TID            tid;
  54.  
  55. # ifdef    DISTRIB
  56. extern struct atstash        Fakesid;
  57. # endif
  58.  
  59. extern char            *Indexname;
  60.  
  61. extern QTREE            *tree();
  62. extern QTREE            *tlprepend();
  63. extern QTREE            *addresdom();
  64. extern QTREE            *xdot();
  65. extern QTREE            *norml();
  66. extern struct atstash        *attlookup();
  67. extern int            rngent();
  68. extern int            rnglook();
  69. extern PARRNG            Parrng[];
  70. extern STRKEEPER        *substring(),*endvals();
  71. %}
  72.  
  73. /* NEW BEGIN-END THINGS */
  74. %start        program
  75.  
  76. /* UNION YYSTYPE DEFINED */
  77. %union
  78. {
  79.     int                type_type;    /* OPERATOR TYPES ETC. */
  80.     QTREE                *tree_type;
  81.     int                rng_type;
  82.     char                char_type;
  83.     int                int_type;
  84.     short                *I2_type;
  85.     long                *I4_type;
  86.     float                *F4_type;
  87.     double                *F8_type;
  88.     char                *string_type;
  89.     STRKEEPER            *substr_type;
  90. }
  91.  
  92. /* COMMANDS */
  93. %token        APPEND    COPY    CREATE    DELETE    DESTROY    HELP    INDEX    MODIFY
  94. %token        PRINT    RANGE    REPLACE    RETRIEVE    SAVE        
  95. %token        DEFINE    PERMIT    VIEW    INTEGRITY
  96. %token        DELIM    USE    UNUSE
  97. /*DDD*/%token    DISTRIBUTE
  98.  
  99. /* 'NOISE' WORDS */
  100. %token        ALL    BY    FROM    IN    INTO    UNIQUE    AT
  101. %token        IS    OF    ON    ONTO    TO    UNTIL    WHERE
  102. /*DDD*/%token    DISTRD
  103.  
  104. /* CONSTANTS */
  105. %token        NAME    SCONST    I2CONST    I4CONST F4CONST    F8CONST
  106.  
  107. /* PUNCTUATION */
  108. %token        COMMA    LPAREN    PERIOD    RPAREN    COLON    BGNCMNT    ENDCMNT
  109. %token        LBRAC    RBRAC    DOLLAR    PCT
  110.  
  111. /* UNARY ARITHMETIC OPERATORS */
  112. %token        UAOP
  113.  
  114. /* BINARY ARITHMETIC OPERATORS */
  115. %token        BAOP    BAOPH
  116.  
  117. /* BOUNDS OPERATORS */
  118. %token        BDOP
  119.  
  120. /* EQUALITY OPERATORS */
  121. %token        EOP
  122.  
  123. /* LOGICAL OPERATORS */
  124. %token        LBOP    LUOP
  125.  
  126. /* FUNCTIONAL OPERATORS */
  127. %token        FOP    FBOP
  128.  
  129. /* AGGREGATE OPERATORS */
  130. %token        AGOP
  131.  
  132. /* TYPES FOR INGRES TOKENS */
  133. %type    <type_type>    IS
  134. %type    <string_type>    NAME    SCONST
  135. %type    <I2_type>    I2CONST
  136. %type    <I4_type>    I4CONST
  137. %type    <F4_type>    F4CONST
  138. %type    <F8_type>    F8CONST
  139. %type    <type_type>    UAOP
  140. %type    <type_type>    BAOP    BAOPH
  141. %type    <type_type>    BDOP
  142. %type    <type_type>    EOP
  143. %type    <type_type>    LBOP    LUOP
  144. %type    <type_type>    FOP    FBOP
  145. %type    <type_type>    AGOP
  146. %type   <I4_type>    LPAREN    RPAREN    LBRAC    RBRAC  PCT
  147.  
  148. /* TYPES FOR INGRES NON-TERMINALS */
  149. %type    <tree_type>    permtarg    permtlist    permtlelm
  150. /*DDD*/%type    <tree_type>    distribute    distcrits    dcriterion
  151. %type    <tree_type>    tlclause    tlist    tlelm
  152. %type    <tree_type>    qualclause    qual    clause    afcn    aggrfcn
  153. %type    <type_type>    relop
  154. %type    <tree_type>    domseq    targdom    attrib
  155. %type    <rng_type>    var
  156. %type    <tree_type>    attribfcn
  157. %type    <type_type>    uop
  158. %type    <string_type>    alias
  159. %type   <substr_type>   subelm    stringpart    grpelm    nameprt
  160. %type    <I4_type>    leftclose    rightclose
  161.  
  162. /* DEFINE ASCENDING PRECEDENCE FOR OPERATORS */
  163. %left        LBOP
  164. %left        LUOP
  165. %left        UAOP
  166. %left        BAOP
  167. %left        BAOPH
  168. %nonassoc    unaryop
  169.  
  170. %%
  171. program:    program stmnt =
  172.         {
  173. #            ifdef    xPTR1
  174.             tTfp(38, 0, "*** [program stmnt] parsed.\n");
  175. #            endif
  176.  
  177.             if (endquelst(Opflag) < 0)
  178.                 return (-1);
  179.         }
  180.     |    stmnt =
  181.         {
  182. #            ifdef    xPTR1
  183.             tTfp(38, 1, "*** [stmnt] parsed.\n");
  184. #            endif
  185.  
  186.             if (endquelst(Opflag) < 0)
  187.                 return (-1);
  188.         }
  189.     |
  190.         {
  191. #            ifdef    xPTR1
  192.             tTfp(38, 2, "*** [(NULL)] parsed.\n");
  193. #            endif
  194.         }
  195. ;
  196. stmnt:        append
  197.     |    copy
  198.     |    create
  199.     |    delete     
  200.     |    destroy
  201. /*DDD*/    |    distribute
  202.     |    help
  203.     |    index    
  204.     |    integrity
  205.     |    modify
  206.     |    permit
  207.     |    print
  208.     |    range
  209.     |    replace    
  210.     |    retrieve 
  211.     |    save
  212.     |    view
  213.     |    use
  214.     |    unuse
  215.     |    delim    
  216.     |    error
  217.         {
  218. #            ifdef    xPTR1
  219.             tTfp(38, 0, "*** [error] parsed.\n");
  220. #            endif
  221.         }
  222.  
  223. ;
  224. range:        rngstmnt OF NAME IS NAME =
  225.         {
  226.             if ((i = openr(&Reldesc, OR_RELTID, $5)) < 0)
  227.                 syserr("relname: error in openr '%d'", i);
  228.             if (i > 0)
  229.             {
  230.                 /* invalid relation name */
  231.                 par_error(RNGEXIST, WARN, $5, 0);
  232.                 YYERROR;
  233.             }
  234.             else
  235.                 rngent(R_EXTERNAL, $3, &Reldesc);
  236.         }
  237. ;
  238. rngstmnt:    RANGE =
  239.         {
  240.             Opflag = mdRANGE;
  241.         }
  242. ;
  243. append:        apstmnt apto relation tlclause qualclause =
  244.         {
  245.             /* make root node */
  246.             Lastree = tree($4, $5, ROOT, sizeof(struct rootnode), 1);
  247.         }
  248. ;
  249. apstmnt:    APPEND =
  250.         {
  251.             Opflag = mdAPP;
  252.         }
  253. ;
  254. apto:        INTO
  255.     |    ONTO
  256.     |    TO
  257.     |    ON
  258.     |    ;
  259. ;
  260. delete:        delstmnt delwd relation qualclause =
  261.         {
  262.             /* make root node for delete, with a TIDNODE at leftmost */
  263.             Lastree = tree(tree(NULL, Tidnode, RESDOM, sizeof(struct resdomnode), NULL), $4, ROOT, sizeof(struct rootnode), 1);
  264.         }
  265. ;
  266. delstmnt:    DELETE =
  267.         {
  268.             Opflag = mdDEL;
  269.         }
  270. ;
  271. delwd:        IN
  272.     |    ON
  273.     |    FROM
  274.     |    ;
  275. ;
  276. replace:    repstmnt repkwd relation tlclause qualclause =
  277.         {
  278.             /* make root node for replace */
  279.             Lastree = tree($4, $5, ROOT, sizeof(struct rootnode), 1);
  280.         }
  281. ;
  282. repstmnt:    REPLACE =
  283.         {
  284.             Opflag = mdREPL;
  285.         }
  286. ;
  287. repkwd:        INTO
  288.     |    IN
  289.     |    ON
  290.     |    ;
  291. ;
  292. retrieve:    retstmnt retclause tlclause qualclause =
  293.         {
  294.             /* make root node for retrieve */
  295.             Lastree = tree($3, $4, ROOT, sizeof(struct rootnode), 1);
  296.         }
  297. ;
  298. retstmnt:    RETRIEVE =
  299.         {
  300.             Opflag = mdRETR;
  301.         }
  302. ;
  303. retclause:    retkwd relation =
  304.         {
  305.             /* set up pipe block and save relname for create */
  306. #            ifdef    xPTR2
  307.             tTfp(38, 4, "retclause: Rsdmno %d", Rsdmno);
  308. #            endif
  309.             Rsdmno = 0;
  310.             setp(PV_STR, "0");    /* relstat = nil */
  311.             setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
  312.         }
  313.     |    =
  314.         {
  315.             /* no result relation, output to terminal */
  316.             Rsdmno = 0;
  317.             Resrng = -1;
  318.         }
  319.     |    UNIQUE =
  320.         {
  321.             Opflag = mdRET_UNI;
  322.             Rsdmno = 0;
  323.             Resrng = -1;
  324.         }
  325. ;
  326. retkwd:        INTO
  327.     |    TO
  328.     |    ;
  329. ;
  330.  
  331. delim:        DEFINE DELIM NAME LPAREN NAME COMMA SCONST RPAREN = 
  332.         {
  333.             Opflag = mdSTOP;
  334.             if ((i = openr(&Reldesc, OR_WRITE, "rdelim")) < 0)
  335.                 syserr("relname: error in openr '%d'", i);
  336.             if (i > 0)
  337.             {
  338.                 /* invalid relation name */
  339.                 par_error(RNGEXIST, WARN, "rdelim", 0);
  340.                 YYERROR;
  341.             }
  342.             else
  343.             {
  344.                 if (( i = make_tuples(&Reldesc, $3, $5, $7)) < 0)
  345.                 {
  346.                     closer(&Reldesc);
  347.                     par_error(BADBNF, WARN, "rdelim", 0);
  348.                 }
  349.             }
  350.             closer(&Reldesc);
  351.         }
  352. ;
  353. use:        USE NAME =
  354.         {
  355.             Opflag = mdSTOP;
  356.             if ((i = openr(&Reldesc, OR_WRITE, "rdelim")) < 0)
  357.                 syserr("relname: error in openr '%d'", i);
  358.             if (i > 0)
  359.             {
  360.                 /* invalid relation name */
  361.                 par_error(RNGEXIST, WARN, "rdelim", 0);
  362.                 YYERROR;
  363.             }
  364.             else
  365.             {
  366.                 if ((i = make_list(&Reldesc, $2)) < 0)
  367.                 {
  368.                     closer(&Reldesc);
  369.                     par_error(DELEXIST, WARN, 0);
  370.                 }
  371.             }
  372.             closer(&Reldesc);
  373.         }
  374. ;
  375. unuse:        UNUSE NAME =
  376.         {
  377.             Opflag = mdSTOP;
  378.             if ( i = shrink_list($2) < 0)
  379.             {
  380.                 par_error(NOGRP,WARN,0);
  381.             }
  382.         }
  383. ;
  384.  
  385. view:        viewclause tlclause qualclause =
  386.         {
  387.             Lastree = tree($2, $3, ROOT, sizeof(struct rootnode), 1);
  388.         }
  389. ;
  390. viewclause:    viewstmnt relation =
  391.         {
  392.             Rsdmno = 0;
  393.             setp(PV_STR, "0040");    /* relstat = S_VIEW */
  394.             setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
  395.         }
  396. ;
  397. viewstmnt:    DEFINE VIEW =
  398.         {
  399.             Opflag = mdVIEW;
  400.             if (!Qrymod)
  401.             {
  402.                 /* no qrymod in database */
  403.                 par_error(NOQRYMOD, WARN, 0);
  404.             }
  405.         }
  406. ;
  407. permit:        permstmnt permlist permrel permtarg permwho permplace permtd qualclause =
  408.         {
  409.             Lastree = tree($4, $8, ROOT, sizeof(struct rootnode), 1);
  410.         }
  411. ;
  412. permstmnt:    DEFINE PERMIT =
  413.         {
  414.             Opflag = mdPROT;
  415.             if (!Qrymod)
  416.             {
  417.                 /* no qrymod in database */
  418.                 par_error(NOQRYMOD, WARN, 0);
  419.             }
  420.         }
  421. ;
  422. permlist:    permxlist
  423.     |    permlist COMMA permxlist
  424. ;
  425. permxlist:    ALL =
  426.         {
  427.             permcom(-1);    /* means 'all' commands */
  428.         }
  429.     |    RETRIEVE =
  430.         {
  431.             permcom(mdRETR);
  432.         }
  433.     |    DELETE =
  434.         {
  435.             permcom(mdDEL);
  436.         }
  437.     |    APPEND =
  438.         {
  439.             permcom(mdAPP);
  440.         }
  441.     |    REPLACE =
  442.         {
  443.             permcom(mdREPL);
  444.         }
  445. ;
  446. permrel:    permword relation =
  447.         {
  448.             /* put command vector into list now since this always happens */
  449.             setp(PV_INT, Permcomd);
  450.             Permcomd = 0;        /* reset command map */
  451.             setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
  452.             bmove(Parrng[Resrng].vardesc.reldum.relowner, permbuf, 2);
  453.             permbuf[2] = 0;
  454.             setp(PV_STR, permbuf);
  455.         }
  456. ;
  457. permword:    ON
  458.     |    OF
  459.     |    TO
  460. ;
  461. permtarg:    LPAREN permtlist RPAREN =
  462.         {
  463.             $$ = $2;
  464.         }
  465.     |    =
  466.         {
  467.             $$ = NULL;
  468.         }
  469. ;
  470. permtlist:    permtlelm
  471.     |    permtlist COMMA permtlelm =
  472.         {
  473.             /*
  474.             ** attach bulk of permit tl to leftmost node of new elem
  475.             */
  476.             if (!Err_current)
  477.                 $$ = tlprepend($1, $3);
  478.         }
  479. ;
  480. permtlelm:    NAME =
  481.         {
  482.             /* Resrng is set by the "relation" production */
  483.             if (!Err_current)
  484.             {
  485.                 Trname = $1;
  486.                 aptr = attlookup(Resrng, Trname);
  487.                 $$ = tree(NULL, NULL, VAR, sizeof(struct varnode), Resrng, aptr);
  488.                 $$ = addresdom(NULL, $$);
  489.             }
  490.         }
  491. ;
  492. permwho:    TO NAME =
  493.         {
  494.             setp(PV_STR, $2);
  495.         }
  496.     |    TO ALL =
  497.         {
  498.             setp(PV_STR, "all");
  499.         }
  500. ;
  501. permplace:    AT NAME =
  502.         {
  503.             setp(PV_STR, $2);
  504.         }
  505.     |    AT ALL =
  506.         {
  507.             setp(PV_STR, "all");
  508.         }
  509.     |    =
  510.         {
  511.             setp(PV_STR, "all");        /* default is all */
  512.         }
  513. ;
  514. permtd:        permtime permday
  515.     |    permdeftime permday
  516.     |    permtime permdefday
  517.     |    permdeftime permdefday
  518. ;
  519. permdeftime:    =
  520.         {
  521.             setp(PV_INT, 0);
  522.             setp(PV_INT, 1440);
  523.         }
  524. ;
  525. permdefday:    =
  526.         {
  527.             setp(PV_STR, "sun");
  528.             setp(PV_STR, "sat");
  529.         }
  530. ;
  531. permtime:    FROM I2CONST COLON I2CONST TO I2CONST COLON I2CONST =
  532.         {
  533.             setp(PV_INT, timeofday($2, $4));
  534.             setp(PV_INT, timeofday($6, $8));
  535.         }
  536. ;
  537. permday:    ON NAME TO NAME =
  538.         {
  539.             setp(PV_STR, $2);
  540.             setp(PV_STR, $4);
  541.         }
  542. ;
  543. integrity:    integstmnt integnoise relation integis qual =
  544.         {
  545.             Lastree = tree(NULL, norml($5), ROOT, sizeof(struct rootnode), 1);
  546.             Qlflag--;    /* turn off here */
  547.         }
  548. ;
  549. integstmnt:    DEFINE INTEGRITY =
  550.         {
  551.             Opflag = mdINTEG;
  552.             Qlflag++;    /* OK to turn on here because integrity doesn't have a targ list */
  553.             if (!Qrymod)
  554.             {
  555.                 /* no qrymod in database */
  556.                 par_error(NOQRYMOD, WARN, 0);
  557.             }
  558.         }
  559. ;
  560. integnoise:    ON
  561.     |    ONTO
  562.     |    IN
  563.     |    OF
  564.     |    /* null */
  565. ;
  566. integis:    IS
  567.     |    /* null*/
  568. ;
  569. /*DDD*/distribute:    diststmnt relation AT distcrits =
  570. /*DDD*/        {
  571. /*DDD*/            if (!Err_current)
  572. /*DDD*/            {
  573. /*DDD*/                $$ = tree(NULL, NULL, QLEND, 0);
  574. /*DDD*/                Lastree = tree($4, $$, ROOT, sizeof(struct rootnode), 1);
  575. /*DDD*/            }
  576. /*DDD*/        }
  577. /*DDD*/;
  578. /*DDD*/diststmnt:    DISTRIBUTE =
  579. /*DDD*/                Opflag = mdDISTRIB;
  580. /*DDD*/;
  581. /*DDD*/distcrits:    dcriterion =
  582. /*DDD*/        {
  583. /*DDD*/            $$ = $1;
  584. /*DDD*/        }
  585. /*DDD*/    |    distcrits dcriterion =
  586. /*DDD*/        {
  587. /*DDD*/            $$ = tlprepend($1, $2);
  588. /*DDD*/        }
  589. /*DDD*/;
  590. /*DDD*/dcriterion:    NAME where qual =
  591. /*DDD*/        {
  592. /*DDD*/            Qlflag--;
  593. /*DDD*/            syserr("Warning this node may be the wrong size\n");
  594. /*DDD*/            if (!Err_current)
  595. /*DDD*/                $$ = tree(NULL, norml($3), SITE, 2, $1);
  596. /*DDD*/        }
  597. /*DDD*/;
  598. relation:    NAME =
  599.         {
  600. #            ifdef    xPTR2
  601.             tTfp(38, 3, "res rel name/var: '%s'\n", $1);
  602. #            endif
  603.             switch (Opflag)
  604.             {
  605.               case mdRETR:
  606.               case mdVIEW:
  607.                 /* result better not be a rel name */
  608.                 if ((i = openr(&Reldesc, OR_RELTID, $1)) < 0)
  609.                     syserr("relation: err openr '%d'", i);
  610.                 if (i == 0)
  611.                 {
  612.                     /* reln exists */
  613.                     if (bequal(Reldesc.reldum.relowner, Usercode, UCODE_SZ))
  614.                     {
  615.                         /* same owner, can't duplicate name */
  616.                         par_error(RESEXIST, WARN, $1, 0);
  617.                         YYERROR;
  618.                     }
  619.                     else if (!Err_current)
  620.                     {
  621.                         /* owned by dba -- purge range table */
  622.                         rngdel($1);
  623.                     }
  624.                 }
  625.                 if (!Err_current)
  626.                 {
  627.                     bmove(Usercode, Reldesc.reldum.relowner, UCODE_SZ);
  628.                     pmove($1, Reldesc.reldum.relid, MAXNAME, ' ');
  629.                     Resrng = rngent(R_INTERNAL, "", &Reldesc);
  630.                 }
  631.                 break;
  632.  
  633.               case mdAPP:
  634.                 /* result is a rel name */
  635.                 if (!Err_current)
  636.                 {
  637.                     Resrng = rnglook($1, LOOKREL);
  638.                     if (Resrng < 0)
  639.                     {
  640.                         if ((i = openr(&Reldesc, OR_RELTID, $1)) < 0)
  641.                             syserr("relation: err openr '%d'", i);
  642.                         if (i)
  643.                         {
  644.                             /* invalid relation name */
  645.                             par_error(RESAPPEX, WARN, $1, 0);
  646.                             YYERROR;
  647.                         }
  648.                         Resrng = rngent(R_INTERNAL, "", &Reldesc);
  649.                     }
  650.                     else
  651.                         ctlmod_decl(Resrng);
  652.                     checkupd(Resrng);
  653.                 }
  654.                 break;
  655.  
  656.               case mdPROT:
  657.               case mdINTEG:
  658. #              ifdef    DISTRIB
  659.               case mdDISTRIB:
  660. #              endif
  661.                 /* the result is a tuple variable */
  662.                 Resrng = rnglook($1, LOOKVAR);
  663.                 if (Resrng < 0)
  664.                 {
  665.                     /* variable not declared */
  666.                     par_error(NOVBLE, WARN, $1, 0);
  667.                     YYERROR;
  668.                 }
  669.                 else
  670.                     ctlmod_decl(Resrng);
  671.                 break;
  672.  
  673.               case mdREPL:
  674.               case mdDEL:
  675.                 /* the result is a tuple variable */
  676.                 Resrng = rnglook($1, LOOKVAR);
  677.                 if (Resrng < 0)
  678.                     /* variable not declared */
  679.                 {
  680.                     par_error(NOVBLE, WARN, $1, 0);
  681.                     YYERROR;
  682.                 }
  683.                 else
  684.                     ctlmod_decl(Resrng);
  685.  
  686.                 checkupd(Resrng);
  687.                 Tidnode = tree(NULL, NULL, VAR, sizeof(struct varnode), Resrng, &Faketid);
  688.                 break;
  689.               default:
  690.                 ;
  691.             }
  692.         }
  693. ;
  694. tlclause:    LPAREN tlist RPAREN =
  695.         {
  696.             $$ = $2;
  697.  
  698.             /*
  699.             ** replace must have tid node as left branch
  700.             **    (so does delete but it doesn't have a targ list)
  701.             */
  702.             if (Opflag == mdREPL && !Err_current)
  703.             {
  704.                 $$ = tlprepend(tree(NULL, Tidnode, RESDOM, sizeof(struct resdomnode), 0), $$);
  705.             }
  706.         }
  707. ;
  708. tlist:        tlelm
  709.     |    tlist COMMA tlelm =
  710.         {
  711.             /*
  712.             ** attach bulk of targ list to leftmost node
  713.             ** of new element
  714.             */
  715.             if (!Err_current)
  716.                 $$ = tlprepend($1, $3);
  717.         }
  718. ;
  719. tlelm:        NAME is afcn =
  720.         {
  721.             Trname = $1;
  722.             /* make a new resdom entry for targ list */
  723.             if (!Err_current)
  724.                 $$ = addresdom(NULL, $3);
  725.         }
  726.     |    attrib =
  727.         {
  728.         /* makes a new resdom entry for targ list */
  729.             if (!Err_current)
  730.                 $$ = addresdom(NULL, $1);
  731.         }
  732.     |    var PERIOD ALL =
  733.         {
  734.             if (Opflag == mdREPL)
  735.             {
  736.                 /* ALL not defined for REPLACE */
  737.                 par_error(REPALL, WARN,
  738.                     trim_relname(Qt.qt_rangev[$1].rngvdesc->relvname), 0);
  739.                 YYERROR;
  740.             }
  741.             /* makes set of new resdom entries for targ list */
  742.             else if (!Err_current)
  743.                 $$ = xdot($1);
  744.         }
  745. ;
  746. is:        IS
  747.     |    BY
  748. ;
  749. qualclause:    where qual =
  750.         {
  751.             $$ = norml($2);
  752.             Qlflag--;
  753.             if (Opflag == mdREPL)
  754.                 qualindex();
  755.         }
  756.     |    =
  757.         {
  758.             /* null qualification */
  759.             if (Opflag == mdREPL)
  760.                 qualindex();
  761.             $$ = norml(NULL);
  762.         }
  763. ;
  764. where:        WHERE =
  765.         {
  766.             Qlflag++;
  767.         }
  768. ;
  769. qual:        LPAREN qual RPAREN =
  770.         {
  771.             $$ = $2;
  772.         }
  773.     |    LUOP qual =
  774.         {
  775.             $$ = tree(NULL, $2, UOP, 2, $1);
  776.         }
  777.     |    qual LBOP qual =
  778.         {
  779.             $$ = tree($1, $3, $2, sizeof (struct rootnode) -2, 0);
  780.         }
  781.     |    clause
  782. ;
  783. clause:        afcn relop afcn =
  784.         {
  785.             $$ = tree($1, $3, BOP, 2, $2);
  786.         }
  787. ;
  788. relop:        EOP
  789.     |    IS
  790.     |    BDOP
  791. ;
  792. afcn:        aggrfcn
  793.     |    attribfcn
  794.     |    afcn BAOPH afcn =
  795.         {
  796.             $$ = tree($1, $3, BOP, 2, $2);
  797.         }
  798.     |    afcn BAOP afcn =
  799.         {
  800.             $$ = tree($1, $3, BOP, 2, $2);
  801.         }
  802.     |    afcn UAOP afcn =
  803.         {
  804.             $$ = tree($1, $3, BOP, 2, $2);
  805.         }
  806.     |    LPAREN afcn RPAREN =
  807.         {
  808.             $$ = $2;
  809.         }
  810.     |    uop afcn    %prec unaryop    =
  811.         {
  812.             $$ = tree(NULL, $2, UOP, 2, $1);
  813.         }
  814.     |    FOP LPAREN afcn RPAREN =
  815.         {
  816.             $$ = tree($3, NULL, UOP, 2, $1);
  817.         }
  818.     |    FBOP LPAREN afcn COMMA afcn RPAREN =
  819.         {
  820.             $$ = tree($3, $5, BOP, 2, $1);
  821.         }
  822. ;
  823. aggrfcn:    AGOP LPAREN afcn BY domseq qualclause RPAREN =
  824.         {
  825. #            ifdef    xPTR2
  826.             tTfp(39, 0, "agg func\n");
  827. #            endif
  828.             windup($5);
  829.             $$ = tree(tree($5, tree(NULL, $3, AOP, 6, $1), BYHEAD, sizeof(struct resdomnode), 0), $6, AGHEAD, sizeof(struct rootnode), 0);
  830.             tlprepend(tree(NULL, NULL, TREE, 0), $$);
  831.         }
  832.     |    AGOP LPAREN afcn qualclause RPAREN =
  833.         {
  834.             $$ = tree(tree(NULL, $3, AOP, 6, $1), $4,  AGHEAD, sizeof(struct rootnode), 0);
  835.         }
  836. ;
  837. domseq:        targdom
  838.     |    domseq COMMA targdom =
  839.         {
  840.             $$ = tlprepend($1, $3);
  841.         }
  842. ;
  843. targdom:    afcn =
  844.         {
  845.             $$ = tree(NULL, $1, RESDOM, sizeof(struct resdomnode), Rsdmno);
  846.         }
  847. ;
  848. nameprt:    NAME =
  849.         {
  850.             $$ = substring($1,1);
  851.         }
  852.     |    SCONST =
  853.         {
  854.             $$ = substring($1,0);
  855.         }
  856. ;
  857. subelm:        DOLLAR =
  858.         { 
  859.             $$ = substring(NULL,0);
  860.         }
  861.     |    nameprt DOLLAR =
  862.         {
  863.             $1->flag[0] |= 2;
  864.             $$ = $1;
  865.         }
  866.     |    nameprt =
  867.         {
  868.             $$ = $1;
  869.         }
  870.     |    I2CONST subelm =
  871.         {
  872.             setnumber($2,$1);
  873.             $$ = $2;
  874.         }
  875. ;
  876. grpelm:        subelm COMMA subelm =
  877.         {
  878.             groupstrings($1,$3);
  879.             $$ = $1;
  880.         }    
  881. ;
  882. leftclose:    PCT =
  883.         {
  884.             $$ = $1;
  885.         }
  886.     |    LPAREN =
  887.         {
  888.             $$ = $1;
  889.         }
  890. ;
  891. rightclose:    PCT =
  892.         {
  893.             $$ = $1;
  894.         }
  895.     |    RPAREN =
  896.         {
  897.             $$ = $1;
  898.         }
  899. ;
  900. stringpart:    leftclose subelm rightclose =
  901.         {
  902.             $$ = endvals($2,$1,$3);
  903.         }
  904.     |    leftclose grpelm rightclose =
  905.         {
  906.             $$ = endvals($2,$1,$3);
  907.         }
  908. ;
  909. attrib:        var PERIOD NAME =
  910.         {
  911. #            ifdef    xPTR2
  912.             tTfp(39, 1, "attrib %12s.%12s found\n",
  913.             Qt.qt_rangev[$1].rngvdesc->relvname, $3);
  914. #            endif
  915.  
  916.             /* remember attribute name */
  917.             Trname = $3;
  918.  
  919.             /* look up attribute */
  920.             aptr = attlookup($1, Trname);
  921.             $$ = tree(NULL, NULL, VAR, sizeof(struct varnode), $1, aptr);
  922.         }
  923.     |       attrib stringpart =
  924.         {
  925.             $1->sym.value.sym_var.varstr = $2;
  926.             $$ = $1;
  927.         }
  928. ;
  929. var:        NAME =
  930.         {
  931.             $$ = rnglook($1, LOOKVAR);
  932.             if ($$ < 0)
  933.             {
  934.                 /* variable not declared */
  935.                 par_error(NOVBLE, WARN, $1, 0);
  936.                 YYERROR;
  937.             }
  938.             else
  939.                 ctlmod_decl($$);
  940.         }
  941. ;
  942. attribfcn:    I2CONST =
  943.         {
  944.             $$ = tree(NULL, NULL, INT, 2, $1);
  945.         }
  946.     |    I4CONST =
  947.         {
  948.             $$ = tree(NULL, NULL, INT, 4, $1);
  949.         }
  950.     |    F4CONST =
  951.         {
  952.             $$ = tree(NULL, NULL, FLOAT, 4, $1);
  953.         }
  954.     |    F8CONST =
  955.         {
  956.             $$ = tree(NULL, NULL, FLOAT, 8, $1);
  957.         }
  958.     |    SCONST =
  959.         {
  960.             patmat($1);
  961.             $$ = tree(NULL, NULL, CHAR, length($1), $1);
  962.         }
  963.     |    NAME =
  964.         {
  965.             $$ = tree(NULL, NULL, COP, 2, $1);
  966.         }
  967.     |    attrib
  968. ;
  969. uop:        UAOP    %prec unaryop    =
  970.         {
  971.             if ($1 == opADD)
  972.                 $$ = opPLUS;
  973.             else
  974.                 if ($1 == opSUB)
  975.                     $$ = opMINUS;
  976.         }
  977. ;
  978. copy:        copstmnt alias LPAREN coparam RPAREN keywd SCONST =
  979.         {
  980. #            ifdef    xPTR2
  981.             tTfp(39, 3, "copy %12s,%12s\n", $2, $7);
  982. #            endif
  983.  
  984.             setp(PV_STR, $7);
  985.         }
  986. ;
  987. copstmnt:    COPY =
  988.         {
  989.             Opflag = mdCOPY;
  990.         }
  991. ;
  992. coparam:    cospecs
  993.     |    ;
  994. ;
  995. cospecs:    alias is coent
  996.     |    cospecs COMMA alias is coent
  997. ;
  998. coent:        alias
  999.     |    SCONST =
  1000.         {
  1001.             setp(PV_STR, $1);
  1002.         }
  1003. ;
  1004. alias:        NAME =
  1005.         {
  1006.             if (!Err_current)
  1007.             {
  1008.                 setp(PV_STR, $1);
  1009.                 if (Opflag == mdDESTROY || Opflag == mdCREATE
  1010. #                    ifdef    DISTRIB
  1011.                     || Opflag == mdDCREATE
  1012. #                    endif
  1013.                                 )
  1014.                     rngdel($1);
  1015.             }
  1016.         }
  1017. ;
  1018. specs:        alias is alias
  1019.     |    specs COMMA alias is alias
  1020. ;
  1021. keywd:        INTO =
  1022.         {
  1023.             setp(PV_STR, "\0");
  1024.             setp(PV_STR, "i");
  1025.         }
  1026.     |    FROM =
  1027.         {
  1028.             setp(PV_STR, "\0");
  1029.             setp(PV_STR, "f");
  1030.         }
  1031. ;
  1032. create:        crestmnt alias LPAREN specs RPAREN
  1033. ;
  1034. crestmnt:    CREATE =
  1035.         {
  1036.             Opflag = mdCREATE;
  1037.  
  1038.             /* set up parameters for regular create */
  1039.             setp(PV_STR, "0");        /* relstat = nil */
  1040.         }
  1041. /*DDD*/    |    CREATE DISTRD =
  1042. /*DDD*/        {
  1043. /*DDD*/            Opflag = mdDCREATE;
  1044. /*DDD*/
  1045. /*DDD*/            /* setup parameters for distributed create */
  1046. /*DDD*/            setp(PV_STR, "U");
  1047. /*DDD*/            setp(PV_STR, "");
  1048. /*DDD*/            setp(PV_STR, "01000");    /* relstat = S_DISTRIBUTED */
  1049. /*DDD*/        }
  1050. ;
  1051. destroy:    destmnt keys
  1052.     |    destqm destlist
  1053.     |    destmnt DELIM NAME =
  1054.         {
  1055.             Opflag = mdSTOP;
  1056.             if ((i = openr(&Reldesc, OR_WRITE, "rdelim")) < 0)
  1057.                 syserr("relname: error in openr '%d'", i);
  1058.             if (i > 0)
  1059.             {
  1060.                 /* invalid relation name */
  1061.                 par_error(RNGEXIST, WARN, "rdelim", 0);
  1062.                 YYERROR;
  1063.             }
  1064.             else
  1065.             {
  1066.                 if ( i = destroy_delim(&Reldesc, $3) < 0)
  1067.                 {
  1068.                     closer(&Reldesc);
  1069.                     par_error(DELEXIST, WARN, "rdelim",0);
  1070.                 }
  1071.             }
  1072.             closer(&Reldesc);
  1073.         }
  1074. ;
  1075. destmnt:    DESTROY =
  1076.         {
  1077.             Opflag = mdDESTROY;
  1078.         }
  1079. ;
  1080. destqm:        destmnt INTEGRITY NAME =
  1081.         {
  1082.             Opflag = mdREMQM;
  1083.             if (!Qrymod)
  1084.                 /* no qrymod in database */
  1085.                 par_error(NOQRYMOD, WARN, 0);
  1086.             setp(PV_STR, "6");
  1087.             setp(PV_STR, $3);
  1088.         }
  1089.     |    destmnt PERMIT NAME =
  1090.         {
  1091.             Opflag = mdREMQM;
  1092.             if (!Qrymod)
  1093.                 /* no qrymod in database */
  1094.                 par_error(NOQRYMOD, WARN, 0);
  1095.             setp(PV_STR, "5");
  1096.             setp(PV_STR, $3);
  1097.         }
  1098. ;
  1099. destlist:    I2CONST =
  1100.         {
  1101.             i = iocv(*($1));
  1102.             setp(PV_STR, i);
  1103.         }
  1104.     |    destlist COMMA I2CONST =
  1105.         {
  1106.             i = iocv(*($3));
  1107.             setp(PV_STR, i);
  1108.         }
  1109.     |    ALL
  1110. ;
  1111. help:        helstmnt hlist
  1112.     |    helstmnt =
  1113.         {
  1114.             setp(PV_INT, RELIST);    /* all relns */
  1115.         }
  1116.     |    helqmstmnt hqmlist
  1117.     |    heldelstmnt =
  1118.         {
  1119.             setp(PV_INT, ALLDELLIST);    /* all delims */
  1120.         }
  1121.     |    heldelstmnt dlist
  1122. ;
  1123. helstmnt:    HELP =
  1124.         {
  1125.             Opflag = mdHELP;
  1126.         }
  1127. ;
  1128. heldelstmnt:    HELP DELIM =
  1129.         {
  1130.             Opflag = mdHELP;
  1131.         }
  1132. ;
  1133. helqmstmnt:    HELP VIEW =
  1134.         {
  1135.             Opflag = mdDISPLAY;
  1136.             if (!Qrymod)
  1137.                 /* no qrymod in database */
  1138.                 par_error(NOQRYMOD, WARN, 0);
  1139.             smove("4", hqmbuf);
  1140.         }
  1141.     |    HELP PERMIT =
  1142.         {
  1143.             Opflag = mdDISPLAY;
  1144.             if (!Qrymod)
  1145.                 /* no qrymod in database */
  1146.                 par_error(NOQRYMOD, WARN, 0);
  1147.             smove("5", hqmbuf);
  1148.         }
  1149.     |    HELP INTEGRITY =
  1150.         {
  1151.             Opflag = mdDISPLAY;
  1152.             if (!Qrymod)
  1153.                 /* no qrymod in database */
  1154.                 par_error(NOQRYMOD, WARN, 0);
  1155.             smove("6", hqmbuf);
  1156.         }
  1157.  
  1158. ;
  1159. hlist:        hparam
  1160.     |    hlist COMMA hparam
  1161.     |    ALL =
  1162.         {
  1163.             setp(PV_INT, ALLRELINFO);
  1164.         }
  1165. ;
  1166. dlist:        dparam
  1167.     |    dlist COMMA dparam
  1168. ;
  1169. dparam:    NAME =
  1170.         {
  1171.             /* relation */
  1172.             setp(PV_INT, DELLIST);
  1173.             setp(PV_STR, $1);
  1174.         }
  1175. ;
  1176. hparam:        NAME =
  1177.         {
  1178.             /* relation */
  1179.             setp(PV_INT, RELINFO);
  1180.             setp(PV_STR, $1);
  1181.         }
  1182.     |    SCONST =
  1183.         {
  1184.             /* manual page */
  1185.             setp(PV_INT, MANSEC);
  1186.             setp(PV_STR, $1);
  1187.         }
  1188. ;
  1189. hqmlist:    NAME =
  1190.         {
  1191.             setp(PV_STR, hqmbuf);
  1192.             setp(PV_STR, $1);
  1193.         }
  1194.     |    hqmlist COMMA NAME =
  1195.         {
  1196.             setp(PV_STR, hqmbuf);
  1197.             setp(PV_STR, $3);
  1198.         }
  1199. ;
  1200. index:        instmnt LPAREN keys RPAREN =
  1201.         {
  1202.             if (Rsdmno > MAXKEYS)
  1203.                 /* too many attributes in key */
  1204.                 par_error(INDEXTRA, WARN, 0);
  1205.         }
  1206. ;
  1207. instmnt:    indexq ON NAME IS NAME =
  1208.         {
  1209.             /* init INDEX command */
  1210.             Rsdmno = 0;
  1211.             setp(PV_STR, $3);
  1212.             setp(PV_STR, $5);
  1213.             Indexname = $5;
  1214.         }
  1215. ;
  1216. indexq:        INDEX =
  1217.         {
  1218.             Opflag = mdINDEX;
  1219.         }
  1220. ;
  1221. modify:        modstmnt alias TO modstorage modkeys modqual
  1222. ;
  1223. modstmnt:    MODIFY =
  1224.         {
  1225.             Opflag = mdMODIFY;
  1226.             Rsdmno = 0;
  1227.         }
  1228. ;
  1229. modstorage:    NAME =
  1230.         {
  1231.             setp(PV_STR, $1);
  1232.         }
  1233. modkeys:    modstkey modrptkey
  1234.     |    ;
  1235. ;
  1236. modstkey:    ON =
  1237.         {
  1238.             setp(PV_STR, "name");
  1239.         }
  1240. ;
  1241. modrptkey:    modbasekey
  1242.     |    modrptkey COMMA modbasekey
  1243. ;
  1244. modbasekey:    NAME =
  1245.         {
  1246.             setp(PV_STR, $1);
  1247.         }
  1248.     |    NAME COLON NAME =
  1249.         {
  1250.             concat($1, ztack(":", $3), modbuf);
  1251.             setp(PV_STR, modbuf);
  1252.         }
  1253. ;
  1254. modqual:    modcond modfill
  1255.     |    ;
  1256. ;
  1257. modcond:    WHERE =
  1258.         {
  1259.             setp(PV_STR, "\0");
  1260.         }
  1261. ;
  1262. modfill:    modfillnum
  1263.     |    modfill COMMA modfillnum
  1264. ;
  1265. modfillnum:    NAME IS I2CONST =
  1266.         {
  1267.             setp(PV_STR, $1);
  1268.             i = iocv(*($3));
  1269.             setp(PV_STR, i);
  1270.         }
  1271.     |    NAME IS NAME =
  1272.         {
  1273.             setp(PV_STR, $1);
  1274.             setp(PV_STR, $3);
  1275.         }
  1276. ;
  1277. keys:        alias =
  1278.         {
  1279.             Rsdmno++;
  1280.         }
  1281.     |    keys COMMA alias =
  1282.         {
  1283.             Rsdmno++;
  1284.         }
  1285. ;
  1286. print:        prinstmnt keys
  1287. ;
  1288. prinstmnt:    PRINT =
  1289.         {
  1290.             Opflag = mdPRINT;
  1291.         }
  1292. ;
  1293. save:        savstmnt alias UNTIL date
  1294.     |    savstmnt alias
  1295. ;
  1296. savstmnt:    SAVE =
  1297.         {
  1298.             Opflag = mdSAVE;
  1299.         }
  1300. ;
  1301. date:        month day_year day_year
  1302. ;
  1303. month:        alias
  1304.     |    day_year
  1305. ;
  1306. day_year:    I2CONST =
  1307.         {
  1308.             i = iocv(*($1));
  1309.  
  1310. #            ifdef    xPTR3
  1311.             tTfp(39, 4, "day_year: %s\n", i);
  1312. #            endif
  1313.  
  1314.             setp(PV_STR, i);
  1315.         }
  1316. ;
  1317. %%
  1318. # include    "scanner.h"
  1319. # include    "tables.y"
  1320. # include    "yyerror.y"
  1321.