home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / pas.y < prev    next >
Encoding:
Text File  |  1991-04-16  |  21.2 KB  |  988 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)pas.y    5.5 (Berkeley) 4/16/91
  34.  */
  35.  
  36. /*
  37.  * Yacc grammar for UNIX Pascal
  38.  *
  39.  * This grammar is processed by the commands in the shell script
  40.  * "gram" to yield parse tables and semantic routines in the file
  41.  * "y.tab.c" and a header defining the lexical tokens in "yy.h".
  42.  *
  43.  * In order for the syntactic error recovery possible with this
  44.  * grammar to work, the grammar must be processed by a yacc which
  45.  * has been modified to fully enumerate possibilities in states
  46.  * which involve the symbol "error".
  47.  * The parser used for Pascal also uses a different encoding of
  48.  * the test entries in the action table which speeds the parse.
  49.  * A version of yacc which will work for Pascal is included on
  50.  * the distribution table as "eyacc".
  51.  *
  52.  * The "gram" script also makes the following changes to the "y.tab.c"
  53.  * file:
  54.  *
  55.  *    1) Causes yyval to be declared int *.
  56.  *
  57.  *    2) Loads the variable yypv into a register as yyYpv so that
  58.  *       the arguments $1, ... are available as yyYpv[1] etc.
  59.  *       This produces much smaller code in the semantic actions.
  60.  *
  61.  *    3) Deletes the unused array yysterm.
  62.  *
  63.  *    4) Moves the declarations up to the flag line containing
  64.  *       '##' to the file yy.h so that the routines which use
  65.  *       these "magic numbers" don't have to all be compiled at
  66.  *       the same time.
  67.  *
  68.  *    5) Creates the semantic restriction checking routine yyEactr
  69.  *       by processing action lines containing `@@'.
  70.  *
  71.  * This compiler uses a different version of the yacc parser, a
  72.  * different yyerror which is called yerror, and requires more
  73.  * lookahead sets than normally provided by yacc.
  74.  *
  75.  * Source for the yacc used with this grammar is included on
  76.  * distribution tapes.
  77.  */
  78.  
  79. /*
  80.  * TERMINAL DECLARATIONS
  81.  *
  82.  * Some of the terminal declarations are out of the most natural
  83.  * alphabetic order because the error recovery
  84.  * will guess the first of equal cost non-terminals.
  85.  * This makes, e.g. YTO preferable to YDOWNTO.
  86.  */
  87.  
  88. %term
  89.     YAND        YARRAY        YBEGIN        YCASE
  90.     YCONST        YDIV        YDO        YDOTDOT
  91.     YTO        YELSE        YEND        YFILE
  92.     YFOR        YFORWARD    YPROCEDURE    YGOTO
  93.     YID        YIF        YIN        YINT
  94.     YLABEL        YMOD        YNOT        YNUMB
  95.     YOF        YOR        YPACKED        YNIL
  96.     YFUNCTION    YPROG        YRECORD        YREPEAT
  97.     YSET        YSTRING        YTHEN        YDOWNTO
  98.     YTYPE        YUNTIL        YVAR        YWHILE
  99.     YWITH        YBINT        YOCT        YHEX
  100.     YCASELAB    YILLCH        YEXTERN        YLAST
  101.  
  102. /*
  103.  * PRECEDENCE DECLARATIONS
  104.  *
  105.  * Highest precedence is the unary logical NOT.
  106.  * Next are the multiplying operators, signified by '*'.
  107.  * Lower still are the binary adding operators, signified by '+'.
  108.  * Finally, at lowest precedence and non-associative are the relationals.
  109.  */
  110.  
  111. %binary    '<'    '='    '>'    YIN
  112. %left    '+'    '-'    YOR    '|'
  113. %left    UNARYSIGN
  114. %left    '*'    '/'    YDIV    YMOD    YAND    '&'
  115. %left    YNOT
  116.  
  117. %{
  118. /*
  119.  * GLOBALS FOR ACTIONS
  120.  */
  121.  
  122. /* Copyright (c) 1979 Regents of the University of California */
  123.  
  124. /* static    char sccsid[] = "@(#)pas.y 5.5 4/16/91"; */
  125.  
  126. /*
  127.  * The following line marks the end of the yacc
  128.  * Constant definitions which are removed from
  129.  * y.tab.c and placed in the file y.tab.h.
  130.  */
  131. ##
  132. /* Copyright (c) 1979 Regents of the University of California */
  133.  
  134. static    char sccsid[] = "@(#)pas.y 5.5 4/16/91";
  135.  
  136. #include "whoami.h"
  137. #include "0.h"
  138. #include "tree_ty.h"        /* must be included for yy.h */
  139. #include "yy.h"
  140. #include "tree.h"
  141.  
  142. #ifdef PI
  143. #define    lineof(l)    l
  144. #define    line2of(l)    l
  145. #endif
  146.  
  147. %}
  148.  
  149. %%
  150.  
  151. /*
  152.  * PRODUCTIONS
  153.  */
  154.  
  155. goal:
  156.     prog_hedr decls block '.'
  157.         = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
  158.         |
  159.     decls
  160.         = segend();
  161.         ;
  162.     
  163.  
  164. prog_hedr:
  165.     YPROG YID '(' id_list ')' ';' 
  166.         = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, fixlist($4.tr_entry), TR_NIL)));
  167.         |
  168.     YPROG YID ';'
  169.         = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry),  $2.tr_entry, TR_NIL, TR_NIL)));
  170.         |
  171.     YPROG error
  172.         = {
  173.             yyPerror("Malformed program statement", PPROG);
  174.             /*
  175.              * Should make a program statement
  176.              * with "input" and "output" here.
  177.              */
  178.             $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), TR_NIL, TR_NIL, TR_NIL)));
  179.           }
  180.         ;
  181. block:
  182.     YBEGIN stat_list YEND
  183.         = {
  184.             $$.tr_entry = tree3(T_BSTL, lineof($1.i_entry), fixlist($2.tr_entry));
  185.             if ($3.i_entry < 0)
  186.                 brerror($1.i_entry, "begin");
  187.           }
  188.         ;
  189.  
  190.  
  191. /*
  192.  * DECLARATION PART
  193.  */
  194. decls:
  195.     decls decl
  196.         = trfree();
  197.         |
  198.     decls error
  199.         = {
  200.             constend(), typeend(), varend(), trfree();
  201.             yyPerror("Malformed declaration", PDECL);
  202.           }
  203.         |
  204.     /* lambda */
  205.         = trfree();
  206.         ;
  207.  
  208. decl:
  209.     labels
  210.         |
  211.     const_decl
  212.         = constend();
  213.         |
  214.     type_decl
  215.         = typeend();
  216.         |
  217.     var_decl
  218.         = varend();
  219.         |
  220.     proc_decl
  221.         ;
  222.  
  223. /*
  224.  * LABEL PART
  225.  */
  226.  
  227. labels:
  228.     YLABEL label_decl ';'
  229.         = label(fixlist($2.tr_entry), lineof($1.i_entry));
  230.         ;
  231. label_decl:
  232.     YINT
  233.         = $$.tr_entry = newlist($1.i_entry == NIL ? TR_NIL :
  234.                     (struct tnode *) *hash($1.cptr, 1));
  235.         |
  236.     label_decl ',' YINT
  237.         = $$.tr_entry = addlist($1.tr_entry, $3.i_entry == NIL ?
  238.                 TR_NIL : (struct tnode *) *hash($3.cptr, 1));
  239.         ;
  240.  
  241. /*
  242.  * CONST PART
  243.  */
  244.  
  245. const_decl:
  246.     YCONST YID '=' const ';'
  247.         = constbeg($1.i_entry, lineof($1.i_entry)),
  248.           constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
  249.         |
  250.     const_decl YID '=' const ';'
  251.         = constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
  252.         |
  253.     YCONST error
  254.         = {
  255.             constbeg($1.i_entry);
  256. Cerror:
  257.             yyPerror("Malformed const declaration", PDECL);
  258.           }
  259.         |
  260.     const_decl error
  261.         = goto Cerror;
  262.         ;
  263.  
  264. /*
  265.  * TYPE PART
  266.  */
  267.  
  268. type_decl:
  269.     YTYPE YID '=' type ';'
  270.         = typebeg($1.i_entry, line2of($2.i_entry)), type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
  271.         |
  272.     type_decl YID '=' type ';'
  273.         = type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
  274.         |
  275.     YTYPE error
  276.         = {
  277.             typebeg($1.i_entry, line2of($1.i_entry));
  278. Terror:
  279.             yyPerror("Malformed type declaration", PDECL);
  280.           }
  281.         |
  282.     type_decl error
  283.         = goto Terror;
  284.         ;
  285.  
  286. /*
  287.  * VAR PART
  288.  */
  289.  
  290. var_decl:
  291.     YVAR id_list ':' type ';'
  292.         = varbeg($1.i_entry, line2of($3.i_entry)), var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
  293.         |
  294.     var_decl id_list ':' type ';'
  295.         = var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
  296.         |
  297.     YVAR error 
  298.         = {
  299.             varbeg($1.i_entry, line2of($1.i_entry));
  300. Verror:
  301.             yyPerror("Malformed var declaration", PDECL);
  302.           }
  303.         |
  304.     var_decl error
  305.         = goto Verror;
  306.         ;
  307.  
  308. /*
  309.  * PROCEDURE AND FUNCTION DECLARATION PART
  310.  */
  311.  
  312. proc_decl:
  313.     phead YFORWARD ';'
  314.         = funcfwd($1.nl_entry);
  315.         |
  316.     phead YEXTERN ';'
  317.         = (void) funcext($1.nl_entry);
  318.         |
  319.     pheadres decls block ';'
  320.         = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
  321.         |
  322.     phead error
  323.         ;
  324. pheadres:
  325.     phead
  326.         = (void) funcbody($1.nl_entry);
  327.         ;
  328. phead:
  329.     porf YID params ftype ';'
  330.         = $$.nl_entry = funchdr(tree5($1.i_entry, lineof($5.i_entry),
  331.                 $2.tr_entry, $3.tr_entry, $4.tr_entry));
  332.         ;
  333. porf:
  334.     YPROCEDURE
  335.         = $$.i_entry = T_PDEC;
  336.         |
  337.     YFUNCTION
  338.         = $$.i_entry = T_FDEC;
  339.         ;
  340. params:
  341.     '(' param_list ')'
  342.         = $$.tr_entry = fixlist($2.tr_entry);
  343.         |
  344.     /* lambda */
  345.         = $$.tr_entry = TR_NIL;
  346.         ;
  347.  
  348. /*
  349.  * PARAMETERS
  350.  */
  351.  
  352. param:
  353.     id_list ':' type
  354.         = $$.tr_entry = tree3(T_PVAL, (int) fixlist($1.tr_entry), $3.tr_entry);
  355.         |
  356.     YVAR id_list ':' type
  357.         = $$.tr_entry = tree3(T_PVAR, (int) fixlist($2.tr_entry), $4.tr_entry);
  358.         |
  359.     YFUNCTION id_list params ftype
  360.         = $$.tr_entry = tree5(T_PFUNC, (int) fixlist($2.tr_entry),
  361.                 $4.tr_entry, $3.tr_entry, 
  362.                 (struct tnode *) lineof($1.i_entry));
  363.         |
  364.     YPROCEDURE id_list params ftype
  365.         = $$.tr_entry = tree5(T_PPROC, (int) fixlist($2.tr_entry),
  366.                 $4.tr_entry, $3.tr_entry, 
  367.                 (struct tnode *) lineof($1.i_entry));
  368.         ;
  369. ftype:
  370.     ':' type
  371.         = $$ = $2;
  372.         |
  373.     /* lambda */
  374.         = $$.tr_entry = TR_NIL;
  375.         ;
  376. param_list:
  377.     param
  378.         = $$.tr_entry = newlist($1.tr_entry);
  379.         |
  380.     param_list ';' param
  381.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  382.         ;
  383.  
  384. /*
  385.  * CONSTANTS
  386.  */
  387.  
  388. const:
  389.     YSTRING
  390.         = $$.tr_entry = tree2(T_CSTRNG, $1.i_entry);
  391.         |
  392.     number
  393.         |
  394.     '+' number
  395.         = $$.tr_entry = tree2(T_PLUSC, $2.i_entry);
  396.         |
  397.     '-' number
  398.         = $$.tr_entry = tree2(T_MINUSC, $2.i_entry);
  399.         ;
  400. number:
  401.     const_id
  402.         = $$.tr_entry = tree2(T_ID, $1.i_entry);
  403.         |
  404.     YINT
  405.         = $$.tr_entry = tree2(T_CINT, $1.i_entry);
  406.         |
  407.     YBINT
  408.         = $$.tr_entry = tree2(T_CBINT, $1.i_entry);
  409.         |
  410.     YNUMB
  411.         = $$.tr_entry = tree2(T_CFINT, $1.i_entry);
  412.         ;
  413. const_list:
  414.     const
  415.         = $$.tr_entry = newlist($1.tr_entry);
  416.         |
  417.     const_list ',' const
  418.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  419.         ;
  420.  
  421. /*
  422.  * TYPES
  423.  */
  424.  
  425. type:
  426.     simple_type
  427.         |
  428.     '^' YID
  429.         = $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID,
  430.                                 $2.i_entry));
  431.         |
  432.     struct_type
  433.         |
  434.     YPACKED struct_type
  435.         = $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry);
  436.         ;
  437. simple_type:
  438.     type_id
  439.         |
  440.     '(' id_list ')'
  441.         = $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry));
  442.         |
  443.     const YDOTDOT const
  444.         = $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry,
  445.                 $3.tr_entry);
  446.         ;
  447. struct_type:
  448.     YARRAY '[' simple_type_list ']' YOF type
  449.         = $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry),
  450.                     fixlist($3.tr_entry), $6.tr_entry);
  451.         |
  452.     YFILE YOF type
  453.         = $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry);
  454.         |
  455.     YSET YOF simple_type
  456.         = $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry);
  457.         |
  458.     YRECORD field_list YEND
  459.         = {
  460.             $$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry);
  461.             if ($3.i_entry < 0)
  462.                 brerror($1.i_entry, "record");
  463.           }
  464.         ;
  465. simple_type_list:
  466.     simple_type
  467.         = $$.tr_entry = newlist($1.tr_entry);
  468.         |
  469.     simple_type_list ',' simple_type
  470.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  471.         ;
  472.  
  473. /*
  474.  * RECORD TYPE
  475.  */
  476. field_list:
  477.     fixed_part variant_part
  478.         = $$.tr_entry = tree4(T_FLDLST, lineof(NIL), 
  479.                 fixlist($1.tr_entry), $2.tr_entry);
  480.         ;
  481. fixed_part:
  482.     field
  483.         = $$.tr_entry = newlist($1.tr_entry);
  484.         |
  485.     fixed_part ';' field
  486.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  487.         |
  488.     fixed_part error
  489.         = yyPerror("Malformed record declaration", PDECL);
  490.         ;
  491. field:
  492.     /* lambda */
  493.         = $$.tr_entry = TR_NIL;
  494.         |
  495.     id_list ':' type
  496.         = $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry),
  497.                 fixlist($1.tr_entry), $3.tr_entry);
  498.         ;
  499.  
  500. variant_part:
  501.     /* lambda */
  502.         = $$.tr_entry = TR_NIL;
  503.         |
  504.     YCASE type_id YOF variant_list
  505.         = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL, 
  506.                 $2.tr_entry, fixlist($4.tr_entry));
  507.         |
  508.     YCASE YID ':' type_id YOF variant_list
  509.         = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry),
  510.                 $2.tr_entry, $4.tr_entry,
  511.                     fixlist($6.tr_entry));
  512.         ;
  513. variant_list:
  514.     variant
  515.         = $$.tr_entry = newlist($1.tr_entry);
  516.         |
  517.     variant_list ';' variant
  518.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  519.         |
  520.     variant_list error
  521.         = yyPerror("Malformed record declaration", PDECL);
  522.         ;
  523. variant:
  524.     /* lambda */
  525.         = $$.tr_entry = TR_NIL;
  526.         |
  527.     const_list ':' '(' field_list ')'
  528.         = $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry),
  529.                 $4.tr_entry);
  530.         ;
  531.  
  532. /*
  533.  * STATEMENT LIST
  534.  */
  535.  
  536. stat_list:
  537.     stat
  538.         = $$.tr_entry = newlist($1.tr_entry);
  539.         |
  540.     stat_lsth stat
  541.         = {
  542.             if ((p = $1.tr_entry) != TR_NIL && (q = p->list_node.list)->tag == T_IFX) {
  543.                 q->tag = T_IFEL;
  544.                 q->if_node.else_stmnt = $2.tr_entry;
  545.             } else
  546.                 $$.tr_entry= addlist($1.tr_entry, $2.tr_entry);
  547.           }
  548.         ;
  549.  
  550. stat_lsth:
  551.     stat_list ';'
  552.         = if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) {
  553.             if (yychar < 0)
  554.                 yychar = yylex();
  555.             if (yyshifts >= 2 && yychar == YELSE) {
  556.                 recovered();
  557.                 copy((char *) (&Y), (char *) (&OY), sizeof Y);
  558.                 yerror("Deleted ';' before keyword else");
  559.                 yychar = yylex();
  560.                 p->tag = T_IFX;
  561.             }
  562.           }
  563.         ;
  564.  
  565. /*
  566.  * CASE STATEMENT LIST
  567.  */
  568.  
  569. cstat_list:
  570.     cstat
  571.         = $$.tr_entry = newlist($1.tr_entry);
  572.         |
  573.     cstat_list ';' cstat
  574.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  575.         |
  576.     error
  577.         = {
  578.             $$.tr_entry = TR_NIL;
  579. Kerror:
  580.             yyPerror("Malformed statement in case", PSTAT);
  581.           }
  582.         |
  583.     cstat_list error
  584.         = goto Kerror;
  585.         ;
  586.  
  587. cstat:
  588.     const_list ':' stat
  589.         = $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry),
  590.                 fixlist($1.tr_entry), $3.tr_entry);
  591.         |
  592.     YCASELAB stat
  593.         = $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL,
  594.                     $2.tr_entry);
  595.         |
  596.     /* lambda */
  597.         = $$.tr_entry = TR_NIL;
  598.         ;
  599.  
  600. /*
  601.  * STATEMENT
  602.  */
  603.  
  604. stat:
  605.     /* lambda */
  606.         = $$.tr_entry = TR_NIL;
  607.         |
  608.     YINT ':' stat
  609.         = $$.tr_entry = tree4(T_LABEL, lineof($2.i_entry),
  610.                 $1.tr_entry == TR_NIL ? TR_NIL :
  611.                         (struct tnode *) *hash($1.cptr, 1), $3.tr_entry);
  612.         |
  613.     proc_id
  614.         = $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry,
  615.                         TR_NIL);
  616.         |
  617.     proc_id '(' wexpr_list ')'
  618.         = $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry,
  619.                     fixlist($3.tr_entry));
  620.         |
  621.     YID error
  622.         = goto NSerror;
  623.         |
  624.     assign
  625.         |
  626.     YBEGIN stat_list YEND
  627.         = {
  628.             $$.tr_entry = tree3(T_BLOCK, lineof($1.i_entry),
  629.                         fixlist($2.tr_entry));
  630.             if ($3.i_entry < 0)
  631.                 brerror($1.i_entry, "begin");
  632.           }
  633.         |
  634.     YCASE expr YOF cstat_list YEND
  635.         = {
  636.             $$.tr_entry = tree4(T_CASE, lineof($1.i_entry),
  637.                     $2.tr_entry, fixlist($4.tr_entry));
  638.             if ($5.i_entry < 0)
  639.                 brerror($1.i_entry, "case");
  640.           }
  641.         |
  642.     YWITH var_list YDO stat
  643.         = $$.tr_entry = tree4(T_WITH, lineof($1.i_entry),
  644.                 fixlist($2.tr_entry), $4.tr_entry);
  645.         |
  646.     YWHILE expr YDO stat
  647.         = $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry,
  648.                     $4.tr_entry);
  649.         |
  650.     YREPEAT stat_list YUNTIL expr
  651.         = $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry),
  652.                 fixlist($2.tr_entry), $4.tr_entry);
  653.         |
  654.     YFOR assign YTO expr YDO stat
  655.         = $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry,
  656.                 $4.tr_entry, $6.tr_entry);
  657.         |
  658.     YFOR assign YDOWNTO expr YDO stat
  659.         = $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry,
  660.                 $4.tr_entry, $6.tr_entry);
  661.         |
  662.     YGOTO YINT
  663.         = $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry),
  664.                 (struct tnode *) *hash($2.cptr, 1));
  665.         |
  666.     YIF expr YTHEN stat
  667.         = $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry,
  668.                 $4.tr_entry, TR_NIL);
  669.         |
  670.     YIF expr YTHEN stat YELSE stat
  671.         = $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry,
  672.                     $4.tr_entry, $6.tr_entry);
  673.         |
  674.     error
  675.         = {
  676. NSerror:
  677.             $$.tr_entry = TR_NIL;
  678.             yyPerror("Malformed statement", PSTAT);
  679.           }
  680.         ;
  681. assign:
  682.     variable ':' '=' expr
  683.         = $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry,
  684.                     $4.tr_entry);
  685.         ;
  686.  
  687. /*
  688.  * EXPRESSION
  689.  */
  690.  
  691. expr:
  692.     error
  693.         = {
  694. NEerror:
  695.             $$.tr_entry = TR_NIL;
  696.             yyPerror("Missing/malformed expression", PEXPR);
  697.           }
  698.         |
  699.     expr relop expr            %prec '<'
  700.         = $$.tr_entry = tree4($2.i_entry,
  701.             $1.tr_entry->expr_node.const_tag == SAWCON ?
  702.             $3.tr_entry->expr_node.const_tag :
  703.             $1.tr_entry->expr_node.const_tag,
  704.             $1.tr_entry, $3.tr_entry);
  705.         |
  706.     '+' expr            %prec UNARYSIGN
  707.         = $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag,
  708.                 $2.tr_entry);
  709.         |
  710.     '-' expr            %prec UNARYSIGN
  711.         = $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag,
  712.                 $2.tr_entry);
  713.         |
  714.     expr addop expr            %prec '+'
  715.         = $$.tr_entry = tree4($2.i_entry,
  716.             $1.tr_entry->expr_node.const_tag == SAWCON ?
  717.             $3.tr_entry->expr_node.const_tag :
  718.             $1.tr_entry->expr_node.const_tag, $1.tr_entry,
  719.             $3.tr_entry);
  720.         |
  721.     expr divop expr            %prec '*'
  722.         = $$.tr_entry = tree4($2.i_entry,
  723.             $1.tr_entry->expr_node.const_tag == SAWCON ?
  724.             $3.tr_entry->expr_node.const_tag :
  725.             $1.tr_entry->expr_node.const_tag, $1.tr_entry,
  726.             $3.tr_entry);
  727.         |
  728.     YNIL
  729.         = $$.tr_entry = tree2(T_NIL, NOCON);
  730.         |
  731.     YSTRING
  732.         = $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry);
  733.         |
  734.     YINT
  735.         = $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry);
  736.         |
  737.     YBINT
  738.         = $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry);
  739.         |
  740.     YNUMB
  741.         = $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry);
  742.         |
  743.     variable
  744.         |
  745.     YID error
  746.         = goto NEerror;
  747.         |
  748.     func_id '(' wexpr_list ')'
  749.         = $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry,
  750.             fixlist($3.tr_entry));
  751.         |
  752.     '(' expr ')'
  753.         = $$.tr_entry = $2.tr_entry;
  754.         |
  755.     negop expr            %prec YNOT
  756.         = $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry);
  757.         |
  758.     '[' element_list ']'
  759.         = $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry));
  760.         |
  761.     '[' ']'
  762.         = $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL);
  763.         ;
  764.  
  765. element_list:
  766.     element
  767.         = $$.tr_entry = newlist($1.tr_entry);
  768.         |
  769.     element_list ',' element
  770.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  771.         ;
  772. element:
  773.     expr
  774.         |
  775.     expr YDOTDOT expr
  776.         = $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry);
  777.         ;
  778.  
  779. /*
  780.  * QUALIFIED VARIABLES
  781.  */
  782.  
  783. variable:
  784.     YID
  785.         = {
  786.             @@ return (identis(var, VAR));
  787.             $$.tr_entry = setupvar($1.cptr, TR_NIL);
  788.           }
  789.         |
  790.     qual_var
  791.         = $1.tr_entry->var_node.qual = 
  792.                     fixlist($1.tr_entry->var_node.qual);
  793.         ;
  794. qual_var:
  795.     array_id '[' expr_list ']'
  796.         = $$.tr_entry = setupvar($1.cptr, tree2(T_ARY, 
  797.                 (int) fixlist($3.tr_entry)));
  798.         |
  799.     qual_var '[' expr_list ']'
  800.         = $1.tr_entry->var_node.qual =
  801.                 addlist($1.tr_entry->var_node.qual,
  802.                 tree2(T_ARY, (int) fixlist($3.tr_entry)));
  803.         |
  804.     record_id '.' field_id
  805.         = $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry,
  806.                             TR_NIL));
  807.         |
  808.     qual_var '.' field_id
  809.         = $1.tr_entry->var_node.qual =
  810.             addlist($1.tr_entry->var_node.qual,
  811.             setupfield($3.tr_entry, TR_NIL));
  812.         |
  813.     ptr_id '^'
  814.         = $$.tr_entry = setupvar($1.cptr, tree1(T_PTR));
  815.         |
  816.     qual_var '^'
  817.         = $1.tr_entry->var_node.qual = 
  818.             addlist($1.tr_entry->var_node.qual, tree1(T_PTR));
  819.         ;
  820.  
  821. /*
  822.  * Expression with write widths
  823.  */
  824. wexpr:
  825.     expr
  826.         |
  827.     expr ':' expr
  828.         = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL);
  829.         |
  830.     expr ':' expr ':' expr
  831.         = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
  832.                         $5.tr_entry);
  833.         |
  834.     expr octhex
  835.         = $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry);
  836.         |
  837.     expr ':' expr octhex
  838.         = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
  839.                     $4.tr_entry);
  840.         ;
  841. octhex:
  842.     YOCT
  843.         = $$.i_entry = OCT;
  844.         |
  845.     YHEX
  846.         = $$.i_entry = HEX;
  847.         ;
  848.  
  849. expr_list:
  850.     expr
  851.         = $$.tr_entry = newlist($1.tr_entry);
  852.         |
  853.     expr_list ',' expr
  854.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  855.         ;
  856.  
  857. wexpr_list:
  858.     wexpr
  859.         = $$.tr_entry = newlist($1.tr_entry);
  860.         |
  861.     wexpr_list ',' wexpr
  862.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  863.         ;
  864.  
  865. /*
  866.  * OPERATORS
  867.  */
  868.  
  869. relop:
  870.     '='    = $$.i_entry = T_EQ;
  871.         |
  872.     '<'    = $$.i_entry = T_LT;
  873.         |
  874.     '>'    = $$.i_entry = T_GT;
  875.         |
  876.     '<' '>'    = $$.i_entry = T_NE;
  877.         |
  878.     '<' '='    = $$.i_entry = T_LE;
  879.         |
  880.     '>' '='    = $$.i_entry = T_GE;
  881.         |
  882.     YIN    = $$.i_entry = T_IN;
  883.         ;
  884. addop:
  885.     '+'    = $$.i_entry = T_ADD;
  886.         |
  887.     '-'    = $$.i_entry = T_SUB;
  888.         |
  889.     YOR    = $$.i_entry = T_OR;
  890.         |
  891.     '|'    = $$.i_entry = T_OR;
  892.         ;
  893. divop:
  894.     '*'    = $$.i_entry = T_MULT;
  895.         |
  896.     '/'    = $$.i_entry = T_DIVD;
  897.         |
  898.     YDIV    = $$.i_entry = T_DIV;
  899.         |
  900.     YMOD    = $$.i_entry = T_MOD;
  901.         |
  902.     YAND    = $$.i_entry = T_AND;
  903.         |
  904.     '&'    = $$.i_entry = T_AND;
  905.         ;
  906.  
  907. negop:
  908.     YNOT
  909.         |
  910.     '~'
  911.         ;
  912.  
  913. /*
  914.  * LISTS
  915.  */
  916.  
  917. var_list:
  918.     variable
  919.         = $$.tr_entry = newlist($1.tr_entry);
  920.         |
  921.     var_list ',' variable
  922.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  923.         ;
  924.  
  925. id_list:
  926.     YID
  927.         = $$.tr_entry = newlist($1.tr_entry);
  928.         |
  929.     id_list ',' YID
  930.         = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
  931.         ;
  932.  
  933. /*
  934.  * Identifier productions with semantic restrictions
  935.  *
  936.  * For these productions, the characters @@ signify
  937.  * that the associated C statement is to provide
  938.  * the semantic restriction for this reduction.
  939.  * These lines are made into a procedure yyEactr, similar to
  940.  * yyactr, which determines whether the corresponding reduction
  941.  * is permitted, or whether an error is to be signaled.
  942.  * A zero return from yyEactr is considered an error.
  943.  * YyEactr is called with an argument "var" giving the string
  944.  * name of the variable in question, essentially $1, although
  945.  * $1 will not work because yyEactr is called from loccor in
  946.  * the recovery routines.
  947.  */
  948.  
  949. const_id:
  950.     YID
  951.         = @@ return (identis(var, CONST));
  952.         ;
  953. type_id:
  954.     YID
  955.         = {
  956.             @@ return (identis(var, TYPE));
  957.             $$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry);
  958.           }
  959.         ;
  960. var_id:
  961.     YID
  962.         = @@ return (identis(var, VAR));
  963.         ;
  964. array_id:
  965.     YID
  966.         = @@ return (identis(var, ARRAY));
  967.         ;
  968. ptr_id:
  969.     YID
  970.         = @@ return (identis(var, PTRFILE));
  971.         ;
  972. record_id:
  973.     YID
  974.         = @@ return (identis(var, RECORD));
  975.         ;
  976. field_id:
  977.     YID
  978.         = @@ return (identis(var, FIELD));
  979.         ;
  980. proc_id:
  981.     YID
  982.         = @@ return (identis(var, PROC));
  983.         ;
  984. func_id:
  985.     YID
  986.         = @@ return (identis(var, FUNC));
  987.         ;
  988.