home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / vsl-gramma.Y < prev    next >
Text File  |  1998-05-14  |  19KB  |  825 lines

  1. /* $Id: vsl-gramma.Y,v 1.13 1998/05/14 17:01:08 zeller Exp $ -*- C++ -*- */
  2. /* VSL grammar */
  3.  
  4. %{
  5.  
  6. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  7. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  8. // 
  9. // This file is part of DDD.
  10. // 
  11. // DDD is free software; you can redistribute it and/or
  12. // modify it under the terms of the GNU General Public
  13. // License as published by the Free Software Foundation; either
  14. // version 2 of the License, or (at your option) any later version.
  15. // 
  16. // DDD is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19. // See the GNU General Public License for more details.
  20. // 
  21. // You should have received a copy of the GNU General Public
  22. // License along with DDD -- see the file COPYING.
  23. // If not, write to the Free Software Foundation, Inc.,
  24. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. // 
  26. // DDD is the data display debugger.
  27. // For details, see the DDD World-Wide-Web page, 
  28. // `http://www.cs.tu-bs.de/softech/ddd/',
  29. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  30.  
  31.  
  32. // Some declarations and utilities
  33.  
  34. char VSL_yacc_rcsid[] = 
  35.     "$Id: vsl-gramma.Y,v 1.13 1998/05/14 17:01:08 zeller Exp $";
  36.  
  37.  
  38. // Function calls
  39.  
  40. // Return appropriate node for function call
  41. VSLNode *VSLLib::_call(const string& func_name, VSLNode *arg)
  42. {
  43.     // Find definition list
  44.     VSLDefList* def = deflist(func_name);
  45.     if (def == 0)
  46.     {
  47.     VSLLib::parse_error("'" + func_name + "(...)' undefined");
  48.     delete arg;
  49.     arg = 0;
  50.     }
  51.  
  52.     // Return calling node
  53.     if (def && arg)
  54.     return new DefCallNode(def, arg);
  55.  
  56.     return 0;
  57. }
  58.  
  59. VSLNode *VSLLib::call(const string& name)
  60. {
  61.     return _call(name, new EmptyListNode);
  62. }
  63.  
  64. VSLNode *VSLLib::call(const string& name, VSLNode *arg)
  65. {
  66.     if (arg)
  67.     return _call(name, new FixListNode(arg));
  68.  
  69.     return 0;
  70. }
  71.  
  72. VSLNode *VSLLib::call(const string& name, VSLNode *arg1, VSLNode *arg2)
  73. {
  74.     if (arg1 && arg2)
  75.     return _call(name, new FixListNode(arg1, arg2));
  76.  
  77.     return 0;
  78. }
  79.  
  80. VSLNode *VSLLib::call(const string& name, 
  81.               VSLNode *arg1, VSLNode *arg2, VSLNode *arg3)
  82. {
  83.     if (arg1 && arg2 && arg3)
  84.     return _call(name, new FixListNode(arg1, arg2, arg3));
  85.  
  86.     return 0;
  87. }
  88.  
  89. // Some settings
  90. #define YYERROR_VERBOSE
  91.  
  92. #ifdef YYERROR_VERBOSE
  93. #define YYDEBUG 1
  94. #endif
  95. %}
  96.  
  97. /*** Tokens ***/
  98. %token IDENTIFIER        /* [_a-zA-Z][_a-zA-Z0-9]* */
  99. %token STRING            /* \"(\\.|[^\"\n])*\" */
  100. %token INTEGER            /* [0-9]+ */
  101. %token ARROW            /* -> */
  102. %token IF            /* if */
  103. %token THEN            /* then */
  104. %token ELSE            /* else */
  105. %token ELSIF            /* elsif */
  106. %token FI            /* fi */
  107. %token OR            /* or */
  108. %token AND            /* and */
  109. %token NOT            /* not */
  110. %token LET            /* let */
  111. %token IN            /* in */
  112. %token WHERE            /* where */
  113. %token OVERRIDE            /* ^#override */
  114. %token REPLACE            /* ^#replace */
  115. %token EQ            /* = */
  116. %token NE            /* <> */
  117. %token GT            /* > */
  118. %token GE            /* >= */
  119. %token LT            /* < */
  120. %token LE            /* <= */
  121. %token HALIGN            /* & */
  122. %token VALIGN            /* | */
  123. %token UALIGN            /* ^ */
  124. %token TALIGN            /* ~ */
  125. %token APPEND            /* : */
  126. %token CONS            /* :: */
  127. %token THREEDOTS        /* ... */
  128.  
  129. /*** Operator associativity and precedence (raising) ***/
  130. %left OR            /* or */
  131. %left AND            /* and */
  132. %left EQ NE            /* = <> */
  133. %left LE LT GE GT        /* <= < >= > */
  134. %right CONS            /* : */
  135. %left VALIGN            /* | */
  136. %left UALIGN            /* ^ */
  137. %left TALIGN            /* ~ */
  138. %left HALIGN            /* & */
  139. %left '+' '-'            /* + - */
  140. %left '*' '/' '%'        /* * / % */
  141. %right NOT            /* not */
  142.  
  143. %union {
  144.     // Our special yacctoC program makes this a struct -- 
  145.     // thus we use an anonymous union (does not harm in other cases)
  146.     union {
  147.     VSLNode *node;
  148.     string *str;
  149.     int num;
  150.     double fnum;
  151.     struct {
  152.         string *id;
  153.         VSLNode *pattern;
  154.         string *file;
  155.         int line;
  156.     } header;
  157.     struct {
  158.         VSLNode *pattern;
  159.         VSLNode *args;
  160.     } vardef;
  161.     };
  162. }
  163.  
  164. %type <str> identifier function_identifier string_constant
  165. %type <header> function_header local_header global_header
  166. %type <node> function_body box_expression_with_defs box_expression_with_wheres
  167.     box_expression const_expression
  168.     unary_expression binary_expression function_call function_argument
  169.     argument_or_function cond_expression else_expression list_expression 
  170.     box_expression_list multiple_box_expression_list
  171.     in_box_expression box_expression_with_where
  172. %type <num> numeric_constant
  173. %type <vardef> var_definition 
  174.  
  175. %start file
  176.  
  177. %%
  178.  
  179. /*** files ***/
  180.  
  181. file            :    item_list
  182.  
  183. item_list        :    /* empty */
  184.             |    item_list item
  185.  
  186. item            :    function_declaration ';'
  187.             |    function_definition ';'
  188.             |    override_declaration
  189.             |    replace_declaration
  190.             |    ';'
  191.             |    error ';'
  192.  
  193. /*** functions ***/
  194.  
  195. function_declaration    :    function_header
  196.                 {
  197.                     ASSERT($1.pattern == 0 || 
  198.                        $1.pattern->OK());
  199.  
  200.                     if ($1.pattern)
  201.                     {
  202.                     vsllib->add(*$1.id,
  203.                             $1.pattern, 0, False,
  204.                             *$1.file, $1.line);
  205.                     }
  206.                     delete $1.id;
  207.                     delete $1.file;
  208.                 }
  209.  
  210. function_header        :    function_identifier function_argument
  211.                 {
  212.                     ASSERT($1->OK());
  213.                     ASSERT($2 == 0 || $2->OK());
  214.  
  215.                     $$.id      = $1;
  216.                     $$.pattern = $2;
  217.                     $$.file    = new string(vslfilename);
  218.                     $$.line    = vsllinenumber;
  219.                 }
  220.             |    function_identifier
  221.                 {
  222.                     ASSERT($1->OK());
  223.  
  224.                     $$.id      = new string("#" + *$1);
  225.                     $$.pattern = new EmptyListNode;
  226.                     $$.file    = new string(vslfilename);
  227.                     $$.line    = vsllinenumber;
  228.  
  229.                     delete $1;
  230.                 }
  231.  
  232. function_identifier    :    identifier
  233.                 { $$ = $1; }
  234.             |    '(' EQ ')'
  235.                 { $$ = new string("(=)"); }
  236.             |    '(' NE ')'
  237.                 { $$ = new string("(<>)"); }
  238.             |    '(' GT ')'
  239.                 { $$ = new string("(>)"); }
  240.             |    '(' GE ')'
  241.                 { $$ = new string("(>=)"); }
  242.             |    '(' LT ')'
  243.                 { $$ = new string("(<)"); }
  244.             |    '(' LE ')'
  245.                 { $$ = new string("(<=)"); }
  246.             |    '(' HALIGN ')'
  247.                 { $$ = new string("(&)"); }
  248.             |    '(' VALIGN ')'
  249.                 { $$ = new string("(|)"); }
  250.             |    '(' UALIGN ')'
  251.                 { $$ = new string("(^)"); }
  252.             |    '(' TALIGN ')'
  253.                 { $$ = new string("(~)"); }
  254.             |    '(' '+' ')'
  255.                 { $$ = new string("(+)"); }
  256.             |    '(' '-' ')'
  257.                 { $$ = new string("(-)"); }
  258.             |    '(' '*' ')'
  259.                 { $$ = new string("(*)"); }
  260.             |    '(' '/' ')'
  261.                 { $$ = new string("(/)"); }
  262.             |    '(' '%' ')'
  263.                 { $$ = new string("(%)"); }
  264.             |    '(' CONS ')'
  265.                 { $$ = new string("(::)"); }
  266.             |    '(' NOT ')'
  267.                 { $$ = new string("(not)"); }
  268.  
  269. identifier        :    IDENTIFIER
  270.                 { $$ = new string((char *)vsltext); }
  271.  
  272. function_definition    :    local_definition
  273.             |    global_definition
  274.  
  275. local_definition    :     local_header function_body
  276.                 { 
  277.                     ASSERT($1.pattern == 0 || 
  278.                        $1.pattern->OK());
  279.                     ASSERT($2 == 0 || $2->OK());
  280.  
  281.                     if ($1.pattern)
  282.                     {
  283.                     // Define function
  284.                     vsllib->add(*$1.id,
  285.                             $1.pattern, $2, False,
  286.                             *$1.file, $1.line);
  287.                     }
  288.  
  289.                     delete $1.id;
  290.                     delete $1.file;
  291.                 }
  292.  
  293. local_header        :    function_header EQ
  294.                 {
  295.                     ASSERT($1.pattern == 0 || 
  296.                        $1.pattern->OK());
  297.  
  298.                     if ($1.pattern)
  299.                     {
  300.                     // Declare function now
  301.                     // (for recursive calls)
  302.                     vsllib->add(*$1.id,
  303.                             $1.pattern->dup(), 0, 
  304.                             False,
  305.                             vslfilename, 
  306.                             vsllinenumber);
  307.                     }
  308.  
  309.                     $$ = $1;
  310.                 }
  311.  
  312. global_definition    :    global_header function_body
  313.                 { 
  314.                     ASSERT($1.pattern == 0 || 
  315.                        $1.pattern->OK());
  316.                     ASSERT($2 == 0 || $2->OK());
  317.  
  318.                     if ($1.pattern)
  319.                     {
  320.                     // Define function
  321.                     vsllib->add(*$1.id, 
  322.                             $1.pattern, $2, True,
  323.                             *$1.file, $1.line);
  324.                     }
  325.  
  326.                     delete $1.id;
  327.                     delete $1.file;
  328.                 }
  329.  
  330. global_header        :    function_header ARROW
  331.                 {
  332.                   if ($1.pattern)
  333.                   {
  334.                       ASSERT($1.pattern->OK());
  335.  
  336.                       // Declare function now
  337.                       // (for recursive calls)
  338.                       vsllib->add(*$1.id,
  339.                           $1.pattern->dup(), 0, True,
  340.                           vslfilename, vsllinenumber);
  341.                   }
  342.                   $$ = $1;
  343.                 }
  344.  
  345. function_body        :    box_expression_with_defs
  346.                 { $$ = $1; }
  347.  
  348.  
  349.  
  350. /*** expressions ***/
  351.  
  352. /*** LET, WHERE ***/
  353.  
  354. box_expression_with_defs:    box_expression_with_wheres
  355.                 {
  356.                     $$ = $1;
  357.                 }
  358.             |    LET var_definition in_box_expression
  359.                 { 
  360.                     ASSERT($2.pattern == 0 || 
  361.                        $2.pattern->OK());
  362.                     ASSERT($2.args == 0 || 
  363.                        $2.args->OK());
  364.                     ASSERT($3 == 0 || $3->OK());
  365.  
  366.                     $$ = ($2.pattern && $2.args && $3) ?
  367.                     new LetNode($2.pattern, $2.args, $3) :
  368.                     0;
  369.                     ASSERT($$ == 0 || $$->OK());
  370.                 }
  371.  
  372. in_box_expression    :    IN box_expression_with_defs
  373.                 {
  374.                     $$ = $2;
  375.                 }
  376.             |    ',' var_definition in_box_expression
  377.                 { 
  378.                     ASSERT($2.pattern == 0 || 
  379.                        $2.pattern->OK());
  380.                     ASSERT($2.args == 0 || 
  381.                        $2.args->OK());
  382.                     ASSERT($3 == 0 || $3->OK());
  383.  
  384.                     $$ = ($2.pattern && $2.args && $3) ?
  385.                     new LetNode($2.pattern, $2.args, $3) :
  386.                     0;
  387.  
  388.                     ASSERT($$ == 0 || $$->OK());
  389.                 }
  390.  
  391. box_expression_with_wheres:    box_expression
  392.                 { $$ = $1; }
  393.             |    box_expression_with_where
  394.                 { $$ = $1; }
  395.  
  396. box_expression_with_where:    box_expression_with_wheres 
  397.                 WHERE var_definition
  398.                 {
  399.                     ASSERT($1 == 0 || $1->OK());
  400.                     ASSERT($3.pattern == 0 || 
  401.                        $3.pattern->OK());
  402.                     ASSERT($3.args == 0 || 
  403.                        $3.args->OK());
  404.  
  405.                     $$ = ($3.pattern && $3.args && $1) ?
  406.                     new WhereNode($3.pattern, $3.args, $1):
  407.                     0;
  408.                     ASSERT($$ == 0 || $$->OK());
  409.                 }
  410.             |    box_expression_with_where 
  411.                 ',' var_definition
  412.                 {
  413.                     ASSERT($1 == 0 || $1->OK());
  414.                     ASSERT($3.pattern == 0 || 
  415.                        $3.pattern->OK());
  416.                     ASSERT($3.args == 0 || 
  417.                        $3.args->OK());
  418.  
  419.                     $$ = ($3.pattern && $3.args && $1) ?
  420.                     new WhereNode($3.pattern, $3.args, $1):
  421.                     0;
  422.  
  423.                     ASSERT($$ == 0 || $$->OK());
  424.                 }
  425.  
  426. var_definition        :    box_expression EQ box_expression
  427.                 {
  428.                     ASSERT($1 == 0 || $1->OK());
  429.                     ASSERT($3 == 0 || $3->OK());
  430.  
  431.                     $$.pattern = $1;
  432.                     $$.args    = $3;
  433.                 }
  434.  
  435.  
  436. /*** basic expresions ***/
  437.  
  438. box_expression        :    '(' box_expression_with_defs ')'
  439.                 { $$ = $2; }
  440.             |    list_expression
  441.                 { $$ = $1; }
  442.             |    const_expression
  443.                 { $$ = $1; }
  444.             |    binary_expression
  445.                 { $$ = $1; }
  446.             |    unary_expression
  447.                 { $$ = $1; }
  448.             |    cond_expression
  449.                 { $$ = $1; }
  450.             |    function_call
  451.                 { $$ = $1; }
  452.             |    argument_or_function
  453.                 { $$ = $1; }
  454.  
  455. list_expression        :    '[' ']'
  456.                 {
  457.                     $$ = new EmptyListNode;
  458.                     ASSERT($$->OK());
  459.                 }
  460.             |    '[' box_expression_list ']'
  461.                 {
  462.                     $$ = $2;
  463.                     ASSERT($$ == 0 || $$->OK());
  464.                 }
  465.             |    '(' ')'
  466.                 {
  467.                     $$ = new EmptyListNode;
  468.                     ASSERT($$->OK());
  469.                 }
  470.             |    '(' multiple_box_expression_list ')'
  471.                 {
  472.                     $$ = $2;
  473.                     ASSERT($$ == 0 || $$->OK());
  474.                 }
  475.  
  476. box_expression_list    :    box_expression_with_defs
  477.                 { 
  478.                     ASSERT($1 == 0 || $1->OK());
  479.  
  480.                     $$ = ($1) ? new FixListNode($1) : 0;
  481.                     ASSERT($$ == 0 || $$->OK());
  482.                 }
  483.             |    multiple_box_expression_list
  484.                 { 
  485.                     $$ = $1; 
  486.                 }
  487.  
  488. multiple_box_expression_list:    box_expression APPEND box_expression
  489.                 { 
  490.                     ASSERT($1 == 0 || $1->OK());
  491.                     ASSERT($3 == 0 || $3->OK());
  492.  
  493.                     $$ = ($1 && $3) ? new ListNode($1, $3) : 0;
  494.                     ASSERT($$ == 0 || $$->OK());
  495.                 }
  496.             |    box_expression ',' box_expression_list
  497.                 {
  498.                     ASSERT($1 == 0 || $1->OK());
  499.                     ASSERT($3 == 0 || $3->OK());
  500.  
  501.                     $$ = ($1 && $3) ? new ListNode($1, $3) : 0;
  502.                     ASSERT($$ == 0 || $$->OK());
  503.                 }
  504.             |    box_expression THREEDOTS
  505.                 { 
  506.                     $$ = $1; 
  507.                 }
  508.             |    THREEDOTS
  509.                 {
  510.                     $$ = new NameNode("...");
  511.                     ASSERT($$ == 0 || $$->OK());
  512.                 }
  513.  
  514. const_expression    :    string_constant
  515.                 { 
  516.                     ASSERT($1->OK());
  517.  
  518.                     // Bug workaround
  519.                     char *buf = (char *)*$1;
  520.                     string name = buf;
  521.                     $$ = new StringNode(name);
  522.                     delete $1;
  523.  
  524.                     ASSERT($$->OK());
  525.                 }
  526.             |    numeric_constant
  527.                 { 
  528.                     $$ = new NumNode($1);
  529.                     ASSERT($$->OK());
  530.                 }
  531.  
  532. string_constant        :    STRING
  533.                 {
  534.                     $$ = new string(unquote((char *)vsltext));
  535.                     ASSERT($$->OK());
  536.                 }
  537.             |    string_constant STRING
  538.                 { 
  539.                     ASSERT($1->OK());
  540.  
  541.                     $$ = $1;
  542.                     *$$ += unquote((char *)vsltext);
  543.  
  544.                     ASSERT($$->OK());
  545.                 }
  546.  
  547. numeric_constant    :    INTEGER
  548.                 {
  549.                     $$ = atoi((char *)vsltext);
  550.                 }
  551.  
  552. function_call        :    function_identifier function_argument
  553.                 {
  554.                     ASSERT($1->OK());
  555.                     ASSERT($2 == 0 || $2->OK());
  556.  
  557.                     $$ = ($2) ? 
  558.                     vsllib->_call(*$1, $2) : 0;
  559.                     ASSERT($$ == 0 || $$->OK());
  560.                 }
  561.  
  562. unary_expression    :    NOT box_expression
  563.                 {
  564.                     ASSERT($2 == 0 || $2->OK());
  565.                     $$ = vsllib->call("(not)", $2);
  566.                     ASSERT($$ == 0 || $$->OK());
  567.                 }
  568.             |    '+' box_expression
  569.                 {
  570.                     $$ = $2;
  571.                 }
  572.             |    '-' box_expression
  573.                 {
  574.                     // Simulate `-X' by `0-X'
  575.                     ASSERT($2 == 0 || $2->OK());
  576.                     $$ = ($2) ? 
  577.                     vsllib->call("(-)", new NullNode, $2) :
  578.                     0;
  579.                     ASSERT($$ == 0 || $$->OK());
  580.                 }
  581.  
  582. /*** operators ***/
  583.  
  584. binary_expression    :    box_expression EQ box_expression
  585.                 { 
  586.                     ASSERT($1 == 0 || $1->OK());
  587.                     ASSERT($3 == 0 || $3->OK());
  588.                     $$ = vsllib->call("(=)", $1, $3); 
  589.                     ASSERT($$ == 0 || $$->OK());
  590.                 }
  591.             |    box_expression NE box_expression
  592.                 { 
  593.                     ASSERT($1 == 0 || $1->OK());
  594.                     ASSERT($3 == 0 || $3->OK());
  595.                     $$ = vsllib->call("(<>)", $1, $3); 
  596.                     ASSERT($$ == 0 || $$->OK());
  597.                 }
  598.             |    box_expression GT box_expression
  599.                 { 
  600.                     ASSERT($1 == 0 || $1->OK());
  601.                     ASSERT($3 == 0 || $3->OK());
  602.                     $$ = vsllib->call("(>)", $1, $3); 
  603.                     ASSERT($$ == 0 || $$->OK());
  604.                 }
  605.             |    box_expression GE box_expression
  606.                 { 
  607.                     ASSERT($1 == 0 || $1->OK());
  608.                     ASSERT($3 == 0 || $3->OK());
  609.                     $$ = vsllib->call("(>=)", $1, $3); 
  610.                     ASSERT($$ == 0 || $$->OK());
  611.                 }
  612.             |    box_expression LT box_expression
  613.                 { 
  614.                     ASSERT($1 == 0 || $1->OK());
  615.                     ASSERT($3 == 0 || $3->OK());
  616.                     $$ = vsllib->call("(<)", $1, $3); 
  617.                     ASSERT($$ == 0 || $$->OK());
  618.                 }
  619.             |    box_expression LE box_expression
  620.                 { 
  621.                     ASSERT($1 == 0 || $1->OK());
  622.                     ASSERT($3 == 0 || $3->OK());
  623.                     $$ = vsllib->call("(<=)", $1, $3); 
  624.                     ASSERT($$ == 0 || $$->OK());
  625.                 }
  626.             |    box_expression HALIGN box_expression
  627.                 { 
  628.                     ASSERT($1 == 0 || $1->OK());
  629.                     ASSERT($3 == 0 || $3->OK());
  630.                     $$ = vsllib->call("(&)", $1, $3); 
  631.                     ASSERT($$ == 0 || $$->OK());
  632.                 }
  633.             |    box_expression VALIGN box_expression
  634.                 { 
  635.                     ASSERT($1 == 0 || $1->OK());
  636.                     ASSERT($3 == 0 || $3->OK());
  637.                     $$ = vsllib->call("(|)", $1, $3); 
  638.                     ASSERT($$ == 0 || $$->OK());
  639.                 }
  640.             |    box_expression UALIGN box_expression
  641.                 { 
  642.                     ASSERT($1 == 0 || $1->OK());
  643.                     ASSERT($3 == 0 || $3->OK());
  644.                     $$ = vsllib->call("(^)", $1, $3); 
  645.                     ASSERT($$ == 0 || $$->OK());
  646.                 }
  647.             |    box_expression TALIGN box_expression
  648.                 { 
  649.                     ASSERT($1 == 0 || $1->OK());
  650.                     ASSERT($3 == 0 || $3->OK());
  651.                     $$ = vsllib->call("(~)", $1, $3); 
  652.                     ASSERT($$ == 0 || $$->OK());
  653.                 }
  654.             |    box_expression '+' box_expression
  655.                 { 
  656.                     ASSERT($1 == 0 || $1->OK());
  657.                     ASSERT($3 == 0 || $3->OK());
  658.                     $$ = vsllib->call("(+)", $1, $3); 
  659.                     ASSERT($$ == 0 || $$->OK());
  660.                 }
  661.             |    box_expression '-' box_expression
  662.                 { 
  663.                     ASSERT($1 == 0 || $1->OK());
  664.                     ASSERT($3 == 0 || $3->OK());
  665.                     $$ = vsllib->call("(-)", $1, $3); 
  666.                     ASSERT($$ == 0 || $$->OK());
  667.                 }
  668.             |    box_expression '*' box_expression
  669.                 { 
  670.                     ASSERT($1 == 0 || $1->OK());
  671.                     ASSERT($3 == 0 || $3->OK());
  672.                     $$ = vsllib->call("(*)", $1, $3); 
  673.                     ASSERT($$ == 0 || $$->OK());
  674.                 }
  675.             |    box_expression '/' box_expression
  676.                 { 
  677.                     ASSERT($1 == 0 || $1->OK());
  678.                     ASSERT($3 == 0 || $3->OK());
  679.                     $$ = vsllib->call("(/)", $1, $3); 
  680.                     ASSERT($$ == 0 || $$->OK());
  681.                 }
  682.             |    box_expression '%' box_expression
  683.                 { 
  684.                     ASSERT($1 == 0 || $1->OK());
  685.                     ASSERT($3 == 0 || $3->OK());
  686.                     $$ = vsllib->call("(%)", $1, $3); 
  687.                     ASSERT($$ == 0 || $$->OK());
  688.                 }
  689.             |    box_expression CONS box_expression
  690.                 { 
  691.                     ASSERT($1 == 0 || $1->OK());
  692.                     ASSERT($3 == 0 || $3->OK());
  693.                     $$ = vsllib->call("(::)", $1, $3); 
  694.                     ASSERT($$ == 0 || $$->OK());
  695.                 }
  696.             |    box_expression OR box_expression
  697.                 { 
  698.                     ASSERT($1 == 0 || $1->OK());
  699.                     ASSERT($3 == 0 || $3->OK());
  700.                     // If EXPR-1 then true else EXPR-2
  701.                     $$ = ($1 && $3) ? 
  702.                     new TestNode($1, new TrueNode, $3) : 
  703.                     0;
  704.                   ASSERT($$ == 0 || $$->OK());
  705.                 }
  706.             |    box_expression AND box_expression
  707.                 { 
  708.                     ASSERT($1 == 0 || $1->OK());
  709.                     ASSERT($3 == 0 || $3->OK());
  710.                     // If EXPR-1 then EXPR-2 else false
  711.                     $$ = ($1 && $3) ? 
  712.                     new TestNode($1, $3, new FalseNode) : 
  713.                     0;
  714.                     ASSERT($$ == 0 || $$->OK());
  715.                 }
  716.  
  717. cond_expression        :    IF box_expression
  718.                 THEN box_expression_with_defs
  719.                 else_expression
  720.                 FI
  721.                 { 
  722.                     ASSERT($2 == 0 || $2->OK());
  723.                     ASSERT($4 == 0 || $4->OK());
  724.                     ASSERT($5 == 0 || $5->OK());
  725.  
  726.                     $$ = ($2 && $4 && $5) ?
  727.                     new TestNode($2, $4, $5) : 0;
  728.                     ASSERT($$ == 0 || $$->OK());
  729.                 }
  730.  
  731. else_expression        :    ELSIF box_expression
  732.                 THEN box_expression_with_defs
  733.                 else_expression
  734.                 { 
  735.                     ASSERT($2 == 0 || $2->OK());
  736.                     ASSERT($4 == 0 || $4->OK());
  737.                     ASSERT($5 == 0 || $5->OK());
  738.  
  739.                     $$ = ($2 && $4 && $5) ?
  740.                     new TestNode($2, $4, $5) : 0;
  741.                     ASSERT($$ == 0 || $$->OK());
  742.                 }
  743.             |    ELSE box_expression_with_defs
  744.                 {
  745.                     $$ = $2;
  746.                 }
  747.  
  748. function_argument    :    list_expression
  749.                 {
  750.                     $$ = $1;
  751.                 }
  752.             |    '(' box_expression_with_defs ')'
  753.                 { 
  754.                     ASSERT($2 == 0 || $2->OK());
  755.  
  756.                     $$ = ($2) ? new FixListNode($2) : 0; 
  757.                     ASSERT($$ == 0 || $$->OK());
  758.                 }
  759.  
  760. argument_or_function    :    identifier
  761.                 {
  762.                     ASSERT($1->OK());
  763.  
  764.                     if (*$1 == "_")
  765.                     {
  766.                     $$ = new DummyNode;
  767.                     }
  768.                     else
  769.                     {
  770.                     // If function is declared, use it;
  771.                     // otherwise create placeholder var
  772.                     
  773.                     if (vsllib->deflist("#" + *$1))
  774.                         $$ = vsllib->call("#" + *$1);
  775.                     else
  776.                         $$ = new NameNode(*$1);
  777.                     }
  778.  
  779.                     ASSERT($$->OK());
  780.                     delete $1;
  781.                 }
  782.  
  783.  
  784. /*** directives ***/
  785.  
  786. override_declaration    :    OVERRIDE override_list
  787.  
  788. override_list        :    override_identifier
  789.             |    override_list ',' override_identifier
  790.  
  791. override_identifier    :    function_identifier
  792.                 {
  793.                     ASSERT($1->OK());
  794.  
  795.                     string func_name = *$1;
  796.                     if (vsllib->override(func_name)
  797.                     && vsllib->override("#" + func_name))
  798.                     {
  799.                     VSLLib::parse_error("'" + func_name + 
  800.                                 "(...)'"
  801.                                 " undefined");
  802.                     }
  803.                 }
  804.  
  805. replace_declaration    :    REPLACE replace_list
  806.  
  807. replace_list        :    replace_identifier
  808.             |    replace_list ',' replace_identifier
  809.  
  810. replace_identifier    :    function_identifier
  811.                 {
  812.                     ASSERT($1->OK());
  813.  
  814.                     string func_name = *$1;
  815.                     if (vsllib->replace(func_name)
  816.                     && vsllib->replace("#" + func_name))
  817.                     {
  818.                     VSLLib::parse_error("'" + func_name + 
  819.                                 "(...)'"
  820.                                 " undefined");
  821.                     }
  822.                 }
  823.  
  824. %% /* DO NOT REMOVE THIS COMMENT -- MUNCH-YACC DEPENDS ON IT */
  825.