home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pi0 / pas.y < prev    next >
Text File  |  1980-02-17  |  15KB  |  899 lines

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