help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Please help!....Strange Error


From: Gregory L Montgomery
Subject: Please help!....Strange Error
Date: Sat, 12 Apr 2003 22:27:21 -0700

Hi
        I'm constructing an interpreter which is an extention of a simple 
calculator. My goal is to enable my interpreter to have scope, and to be able 
to have function calls. At the present time I have run into a strange problem 
(previous versions worked well no problem.) I can enter a simple command at 
my interpreters prompt like a=1\n and everything is OK ONLY FOR THAT FIRST 
LINE. Everything entered after this receives an error. To track down what was 
happening I #define YYDEBUG 1, and set "int yydebug = 1;" in the output from 
bison. The command which I used to generate my parser files was

bison -d -y --debug -v cofact.y

As you might have guessed the name of my bison source file is cofact.y. When 
I traced the subsequent states I found that my the parser would start at 
state 0 (everythings OK so far). I found that the parser would enter state 
110 after completing the computation on the first line of input, and it would 
always end up in state 110 after each subsequent line entered. This was with 
the same result. A brief output follows to illustrate what I'm talking about.

>Entering state 21
>Next token is 281 (NEWLINE)
>Shifting token 281 (NEWLINE), Entering state 54
>Reducing via rule 1 (line 109), if_exp NEWLINE  -> exp_line
>a==Byte : 1

The output above is from the first line entered. Now I enter a second line of 
input "b=2" - this output is listed below....

>state stack now 0
>Entering state 110
>Reading a token:  *>b=2
>Next token is 282 (VARIABLE)
>line 2, column 1: parse error
>Error: state stack now 0
>Shifting error token, Entering state 1
>Next token is 282 (VARIABLE)
>Discarding token 282 (VARIABLE).
>Error: state stack now 0
>Shifting error token, Entering state 1
>Reading a token: Next token is 61 ('=')
>Discarding token 61 ('=').
>Error: state stack now 0
>Shifting error token, Entering state 1
>Reading a token: Next token is 257 (INTEGER_LITERAL)
>Discarding token 257 (INTEGER_LITERAL).
>Error: state stack now 0
>Shifting error token, Entering state 1
>Reading a token: Next token is 281 (NEWLINE)
>Shifting token 281 (NEWLINE), Entering state 38
>Reducing via rule 7 (line 152), error NEWLINE  -> exp_line
>line 3, column 0: $1
>Error
>state stack now 0
>Entering state 110
>Reading a token:  *>

I thought that I had described an LALR language, but I have somehow messed 
things up. Yet everything appears OK to me.

Please can anyone help? I have listed my cofact.y file below.

Thank you
Gregory L Montgomery
address@hidden

%{
#include <iostream.h>
#include <stdlib.h>
#include "/home/glm/CurrentWork/common/Lib/defs.h"
#include "/home/glm/CurrentWork/common/Lib/Conversions.h"
#include "/home/glm/CurrentWork/common/Lib/Generic.h"
#include "/home/glm/CurrentWork/common/Lib/Container.h"
#include "/home/glm/CurrentWork/common/Lib/Tree.h"
#include "/home/glm/CurrentWork/common/Lib/Numeric.h"
#include "Executer.h"

  //#define YYDEBUG 1

  void         yyerror(char*);
  int          yywrap();
  int          a_value;
  long long    a_long_value;
  long double  a_real_value;
  Tree       * ParseTree;
  Tree       * Tr;
  ExecObj      E;
  Generic    * G;
  int          yylex();
%}

%union 
{
        int           y_int;
        char        * y_string;
        long long     y_long_long;
        long double   y_long_double;
        Tree        * y_tree;
        Numeric     * y_real;
        Numeric     * y_Integer;
        Numeric     * y_Rational;
};


%token INTEGER_LITERAL 
       REAL_LITERAL
       RATIONAL_LITERAL
       MULT_ASSIGN
       DIV_ASSIGN
       MOD_ASSIGN
       ADD_ASSIGN
       SUB_ASSIGN
       PORTS
       WHILE_DO
       PUSH
       INC
       DEC
       MUL
       DIV
       COMBINATION
       SHIFT_RIGHT
       SHIFT_LEFT
       DOUBLE_SHIFT
       LOG
       SQRT
       OUT
       IN
       POP
       NEWLINE 
       VARIABLE



%token BAD

%type <y_long_long>   INTEGER_LITERAL
%type <y_Rational>    RATIONAL_LITERAL
%type <y_long_double> REAL_LITERAL
               
%type <y_string> VARIABLE
%type <y_tree> iliteral,rliteral,variable
%type <y_tree> if_exp,var_exp,exp,add_exp
%type <y_tree> mult_exp,combination,or_exp
%type <y_tree> xor_exp,and_exp,shift_exp
%type <y_tree> neg_exp,function,factor,exp
%type <y_tree> rationalliteral,exp_line

%start exp_line

%%

/* 
 *  Adding the type between the '$' and '$' or '1' helps the reader     *
 *  to understand the type that is being used and thus                  *
 *  the associated operations                                           *
 */


exp_line : if_exp NEWLINE
           { 
             $$ = $1;
             ParseTree = $1;
             if(ParseTree) E.PushStatement(ParseTree);
             if(ParseTree->NodeType() == VARIABLE_NODE)
             {
               Tr = new Tree(EVALUATE_OpCode,ParseTree);
               G = E.driver(Tr);
             }
             else
               G = E.driver(ParseTree);
             if(G) cout << *G;
             printf(" \n *>");  
           }
         | '{' NEWLINE
            {
              E.CatchSt(1);
              E.PushScope();
              printf(" *>");
              //$$ = 0;
            }
         | '}' NEWLINE
            {
              E.CatchSt(0);
              E.PopScope();
              printf(" *>");
              //$$ = 0;
            }
         | PORTS NEWLINE
           {
             //DumpPorts(); 
           }
         | NEWLINE 
           {
             printf("NewLine*>");      /* for blank line */
             //$$ = 0; // Make sure that $1 is NULL when it gets to exp_list
           }
         | '!' NEWLINE 
            {
              E.DumpEnv(); /* this is for debuging : dump the linked list of 
variable */
              //$$ = 0; /* and there associated bindings */
              printf(" *>");
            }
| error NEWLINE 
         { 
     printf("line %d, column %d: $1\n", YYlineno(), YYcolumnno());
     printf("Error\n *>");
     //$$ = 0; // Make sure that $1 is NULL when it gets to exp_list
   } /* for parse error */
         ;

if_exp : exp 
       { 
         $$ = $1; 
         //printf("if_exp->$1: %d\n",$<y_int>1);
       }
       | var_exp '?' if_exp ':' if_exp
          {
            //$<y_tree>$ = make_op2_node(P_IF,$<y_tree>1,
            //              make_op2_node(P_CON,$<y_tree>3,$<y_tree>5));
            //   $$ = new Tree(P_IF,$<y_tree>1, new 
Tree(P_CON,$<y_tree>3,$<y_tree>5));
            $$ = $1; 
          }
       | var_exp '#' if_exp
          {
            //$<y_tree>$ = make_op2_node(P_ITER,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(ITER_OpCode,$1,$3);
          }
       | WHILE_DO var_exp ',' var_exp ')'
          {
            //$<y_tree>$ = make_op2_node(P_WHILE,$<y_tree>2,$<y_tree>4);
            $$ = new Tree(WHILE_OpCode,$2,$4);
          } 
       ;

exp     : var_exp 
          { 
            $$ = $1; 
            //printf("exp->$1: %d\n",$<y_int>1);
          }
        | PUSH var_exp
          {
             $$ = new Tree(PUSH_OpCode,$2);
          }
        ;

var_exp : add_exp  
           { 
             $$ = $1; 
             //printf("var_exp->$1: %d\n",$<y_int>1);
           }
        | variable '=' var_exp
           {
             $$ = new Tree(ASSIGN_OpCode,$1,$3);
           } 
        | variable MULT_ASSIGN add_exp
           {
             $$ = new Tree(MUL_ASSIGN_OpCode,$1,$3);
           } 
        | variable DIV_ASSIGN add_exp
           {
             $$ = new Tree(DIV_ASSIGN_OpCode,$1,$3);
           } 
        | variable MOD_ASSIGN add_exp
           {
             $$ = new Tree(MOD_ASSIGN_OpCode,$1,$3);
           } 
        | variable ADD_ASSIGN add_exp
           {
             $$ = new Tree(ADD_ASSIGN_OpCode,$1,$3);
           } 
        | variable SUB_ASSIGN add_exp
           {
             $$ = new Tree(SUB_ASSIGN_OpCode,$1,$3);
           } 
         ; 

add_exp : mult_exp 
          { 
            $$ = $1; 
            //printf("add_exp->$1: %d\n",$<y_int>1);
          }
        | add_exp '+'  mult_exp  
          { 
            //$<y_tree>$ = make_op2_node(P_ADD,$<y_tree>1,$<y_tree>3);
             $$ = new Tree(ADD_OpCode,$1,$3);
          }
        | add_exp '-'  mult_exp  
          { 
            //$<y_tree>$ = make_op2_node(P_SUB,$<y_tree>1,$<y_tree>3);
             $$ = new Tree(SUB_OpCode,$1,$3);
          }
        | add_exp INC
         {
           //$<y_tree>$ = make_op1_node(P_INC,$<y_tree>1);
           $$ = new Tree(INC_OpCode,$1);
         }
        | add_exp DEC
         {
           //$<y_tree>$ = make_op1_node(P_DEC,$<y_tree>1);
           $$ = new Tree(DEC_OpCode,$1);
         }
        ;

mult_exp : combination 
          { 
            $$ = $1;
            //printf("mult_exp->$1: %d\n",$<y_int>1);
          }
        | mult_exp '*' or_exp 
          { 
            //$<y_tree>$ = make_op2_node(P_MULT,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(MULT_OpCode,$1,$3);
          }
        | mult_exp '/' or_exp 
          {
            //$<y_tree>$ = make_op2_node(P_DIVI,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(DIVI_OpCode,$1,$3);
          }
        | mult_exp MUL
          {
            //$<y_tree>$ = make_op1_node(P_MUL,$<y_tree>1);
            $$ = new Tree();
          }
        | mult_exp DIV
          {
            //$<y_tree>$ = make_op1_node(P_DIV,$<y_tree>1);
            $$ = new Tree(DIV_OpCode,$1);
          }
        ;

combination : or_exp 
          { 
            $$ = $1; 
            //printf("combination->$1: %d\n",$<y_int>1);
          }
        | COMBINATION mult_exp ',' mult_exp ')' 
          {
            //$<y_tree>$ = make_op2_node(P_CMBO,$<y_tree>2,$<y_tree>4);
            $$ = new Tree(CMBO_OpCode,$2,$4);
          }
          ;

or_exp  : xor_exp 
          { 
            $$ = $1;  
            //printf("or_exp->$1: %d\n",$<y_int>1);
          } 
        | or_exp '|' xor_exp 
          {
            //$<y_tree>$ = make_op2_node(P_OR,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(OR_OpCode,$1,$3);
          }
        ;

xor_exp : and_exp 
          { 
            $$ = $1;  
            //printf("xor_exp->$1: %d\n",$1);
          } 
        | xor_exp '^' and_exp 
          {
            //$<y_tree>$ = make_op2_node(P_XOR,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(BIT_XOR_OpCode,$1,$3);
          }
        ;

and_exp : shift_exp 
          { 
            $$ = $1;  
            //printf("and_exp->$1: %d\n",$<y_int>1);
          } 
        | and_exp '&' shift_exp 
          {
            //$<y_tree>$ = make_op2_node(P_AND,$<y_tree>1,$<y_tree>3);
            $$ = new Tree(AND_OpCode,$<y_tree>1,$<y_tree>3);
          }
        ;

shift_exp : neg_exp 
            { 
              $$ = $1;  
              //printf("shift_exp->$1: %d\n",$<y_int>1);
            } 
          | shift_exp SHIFT_RIGHT  neg_exp  
            { 
              //$<y_tree>$ = make_op2_node(P_SHIFT_RIGHT,$<y_tree>1,$<y_tree>3);
              $$ = new Tree(SHIFT_RIGHT_OpCode,$1,$3);
            }
          | shift_exp SHIFT_LEFT   neg_exp  
            { 
              //$<y_tree>$ = make_op2_node(P_SHIFT_LEFT,$<y_tree>1,$<y_tree>3);
              $$ = new Tree(SHIFT_LEFT_OpCode,$1,$3);
            }
          | shift_exp DOUBLE_SHIFT neg_exp 
            {   
              //$<y_tree>$ = make_op2_node(P_EQ_SHIFT,$<y_tree>1,$<y_tree>3);
              $$ = new Tree(EQ_SHIFT_OpCode,$1,$3);
            }
          ;


neg_exp : function 
          { 
            $$ = $1;  
            //printf("reg_exp->$1: %d\n",$<y_int>1);
          } 
        | '~' factor 
          { 
            //$<y_tree>$ = make_op1_node(P_NEGATE, $<y_tree>2);
            $$ = new Tree(NEGATE_OpCode, $2);
          }
        ;

function : factor 
           { 
             $$ = $1; 
             //printf("function->$1: %d\n",$<y_int>1);
           }
         | LOG exp ')' 
           {
             //$<y_tree>$ = make_op1_node(P_LOG,$<y_tree>2);
             $$ = new Tree(LOG_OpCode,$2);
           }
         | SQRT exp ')' 
           {
             //$<y_tree>$ = make_op1_node(P_SQRT,$<y_tree>2);
             $$ = new Tree(SQRT_OpCode,$2);
           }
         | OUT exp ',' exp ')'
           {
             //$<y_tree>$ = make_op2_node(P_OUT,$<y_tree>2,$<y_tree>4);
             $$ = new Tree(OUT_OpCode,$2,$4);
           }
         | IN exp ')'
           {
             // $<y_tree>$ = make_op1_node(P_IN,$<y_tree>2);
             $$ = new Tree(IN_OpCode,$2);
           }
         ;

factor  : iliteral      
          { 
            $$ = $1; 
            //printf("factor->$1: %d\n",$<y_int>1);
          }
        | rliteral      
          { 
            $$ = $1;
          }
        | rationalliteral 
          { 
            $$ = $1; 
          }
        | '(' if_exp ')'  
          { 
            $$ = $2; 
          }
        | POP          
          {
            //$<y_tree>$ = make_op1_node(P_POP, NULL);   
            $$ = new  Tree(POP_OpCode, NULL);
          }
        | variable 
          {
            $$ = $1; 
          }
        ;

iliteral : INTEGER_LITERAL 
           {
             Numeric * i = new Numeric($1);
             i->Reduce(); // Put things in lowest terms
             $$ = new Tree(i);
             delete i;
             //printf("integer literal->$1: %d\n",$<y_int>1);
           }
         ;

rliteral : REAL_LITERAL 
            {
              Numeric * r = new Numeric($1);
              r->Reduce(); // Put things in lowest terms
              $$ = new Tree(r);
              delete r;
              //printf("real literal->$1: %d\n",$<y_int>1);
            }
         ;

rationalliteral : RATIONAL_LITERAL
                  {
                    $$ = new Tree($1);
                    delete $1;
                    //printf("rationalliteral->$1: %d\n",$<y_int>1);
                  }
                ;

variable : VARIABLE 
           { 
             String * w = new String($1);
             $$ = new Tree(w);
             //printf("variable->$1: %s\n",$1);
             delete w;
           }
         ;

%%

int YYlineno(void);
int YYcolumnno(void);

void yyerror(char* s)
{
  fprintf(stderr, "line %d, column %d: %s\n", YYlineno(), YYcolumnno(), s);
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]