lines : /* empty */
     | lines line
     ;

  line: dexp >\n>
       { printf("%15.8f\n",$1); }
     | vexp >\n>
       { printf("(%15.8f,%15.8f)\n",
         $1.lo, $1.hi); }
     | DREG >=> dexp >\n>
       { dreg[$1]= $3; }
     | VREG >=> vexp >\n>
       { vreg[$1]= $3; }
     | error >\n>
       { yyerrok; }
    ;

  dexp: CONST
    | DREG
       { $$= dreg[$1]; }
    | dexp >+> dexp
       { $$= $1+$3;}
    | dexp >-> dexp
       { $$= $1-$3;}
    | dexp >*> dexp
       { $$= $1*$3;}
    | dexp >/> dexp
       { $$= $1/$3;}
    | >-> dexp%prec UMINUS
       { $$= -$2; }
    | >(> dexp >)>
       { $$= $2; }
    ;

  vexp: dexp
       { $$.hi= $$.lo= $1; }
    | >(> dexp >,> dexp >)>
       {
        $$.lo= $2;
        $$.hi= $4;
        if ($$.lo > $$.hi) {
        printf("interval out of order\n");
        YYERROR;
         }
       }
    | VREG
       { $$= vreg[$1]; }
    | vexp >+> vexp
       { $$.hi= $1.hi+$3.hi;
        $$.lo= $1.lo+$3.lo; }
    | dexp >+> vexp
       { $$.hi= $1+$3.hi;
        $$.lo= $1+$3.lo; }
    | vexp >-> vexp
       { $$.hi= $1.hi-$3.lo;
        $$.lo= $1.lo-$3.hi; }
    | dexp >-> vexp
       { $$.hi= $1-$3.lo;
        $$.lo= $1-$3.hi; }
    | vexp >*> vexp
       { $$= vmul($1.lo, $1.hi, $3); }
    | dexp >*> vexp
       { $$= vmul($1, $1, $3); }
    | vexp >/> vexp
       { if( dckeck($3) ) YYERROR;
        $$= vdiv($1.lo, $1.hi, $3); }
    | dexp >/> vexp
       { if( dckeck($3) ) YYERROR;
        $$= vdiv($1, $1, $3); }
    | >-> vexp%prec UMINUS
       { $$.hi= -$2.lo;
        $$.lo= -$2.hi; }
    | >(> vexp >)>
       { $$ = $2; }
    ;

  %%