在野牛解析器规则中没有接收对象

时间:2016-11-18 14:44:51

标签: c++ parsing bison yacc

在我的野牛解析器中,一个规则是创建一个非终端(一个对象)并将其传递给其他人,但另一个规则是不正确地接受该对象,特别是它无法访问其中一个属性但其他属性可访问。(在我附加的解析器文件变量 - > Id规则是复制对象指针后面的表达式 - >变量ASSIGNOP logic_expression规则不能访问变量的getName())

解析器文件

%{
#include <iostream>

#include<string>
#include"1305117_SymbolTable.h"
//#define YYSTYPE SymbolInfo      /* yyparse() stack type */
extern FILE* yyin;
int yydebug;
extern SymbolTable *st;
ofstream tokenout;
double globaltemp=0;
void yyerror(const char *s){
    printf("%s\n",s);
}

int yylex(void);


%}

%token NEWLINE NUMBER PLUS MINUS SLASH ASTERISK LPAREN RPAREN ADDOP MULOP ASSIGNOP RELOP LOGICOP NOT SEMICOLON COMMA LCURL RCURL LTHIRD RTHIRD INCOP DECOP IF ELSE FOR WHILE CHAR RETURN VOID MAIN PRINTLN DO SWITCH DEFAULT BREAK CASE CONTINUE

%union{ SymbolInfo * si;float fval;int ival;char *cval; store *sr;}

%token <fval> FLOAT;
%token <ival> INT; 
%type <sr> factor simple_expression term unary_expression rel_expression logic_expression expression expression_statement ;
%token <ival>CONST_INT;
%token <fval>CONST_FLOAT;
%token <cval>CONST_CHAR;
%token <si> ID ;
%type <si> variable;



%error-verbose  
%%
Program : INT MAIN LPAREN RPAREN compound_statement
  ;


compound_statement : LCURL var_declaration statements RCURL {printf("Now in comp_state \n");}
       | LCURL statements RCURL{printf("compound_statement\n");}
       | LCURL RCURL
       ;


var_declaration : type_specifier declaration_list SEMICOLON {printf("Now in var_dec \n");}
    |  var_declaration type_specifier declaration_list SEMICOLON
    ;

type_specifier  : INT 
    | FLOAT
    | CHAR
    ;

declaration_list : declaration_list COMMA ID 
     | declaration_list COMMA ID LTHIRD CONST_INT RTHIRD
     | ID {printf("Now in dec_list rule id first \n");}
     | ID LTHIRD CONST_INT RTHIRD 
     ;

statements : statement {printf("Now in Statemnts statement  first\n");}
     | statements statement {printf("Now in Statemnts statements  first\n");}
     ;


statement  : expression_statement {printf("Now in statement expstate first\n");}
     | compound_statement 
     | FOR LPAREN expression_statement expression_statement expression RPAREN statement 
     | IF LPAREN expression RPAREN statement
     | IF LPAREN expression RPAREN statement ELSE statement
     | WHILE LPAREN expression RPAREN statement 
     | PRINTLN LPAREN ID RPAREN SEMICOLON 
     | RETURN expression SEMICOLON 
     ;

expression_statement  : SEMICOLON     
      | expression SEMICOLON {$$=new store();
                              $$->setdvalue($1->getdvalue());
                              printf("Now in exp_state rule exp_sem last exp value  %lf\n",$1->getdvalue());
                              st->print_not_empty(tokenout);
                              } 
      ;

variable : ID    { printf(" Now in variable rule Id first id name  %s\n",$1->getName().c_str());
                   //$$ = new SymbolInfo();
                   $$=$1;
                   printf("Now in variable rule Id last id name and value %s %lf\n",$$->getName().c_str(),$$->getValue());
                 } 
   | ID LTHIRD expression RTHIRD 
   ;

expression : logic_expression {$$=new store();
                              $$->setdvalue($1->getdvalue());
                              printf("Now in exp rule logic_exp logic value  %lf\n",$1->getdvalue());
                              } 
     | variable ASSIGNOP logic_expression { printf ("Now in exp rule variable first\n");
                                            $$->setdvalue(1);
                                            printf("Now in exp rule variable middle exp value  %lf\n",$3->getdvalue());

                                           $1->setValue($3->getdvalue());
                                           printf("Now in exp rule variable middle var value  %lf\n",$1->getValue());
                                           printf("Now in exp rule variable last var name %s %lf",$1->getName().c_str(),$1->getValue());

                                          }  

     ;

logic_expression : rel_expression  {$$=new store();
                                    $$->setdvalue($1->getdvalue());
                                    printf("Now in logic_exp rule rel_exp last  %lf\n",$1->  getdvalue());
                                    } 
     | rel_expression LOGICOP rel_expression  
     ;

rel_expression  : simple_expression  {
                                       $$=new store();
                                      $$->setdvalue($1->getdvalue());
                                      printf("Now in rel_exp rule simp_exp last   %lf\n",$1->getdvalue());
                                      }
    | simple_expression RELOP simple_expression {printf("Now in rel_exp rule simp_exp_relop last\n");}
    ;

simple_expression : term {$$=new store();
                          $$->setdvalue($1->getdvalue());
                          printf("Now in simp_exp rule term last %lf\n",$1->getdvalue());
                          }
      | simple_expression ADDOP term {$$=new store();
                                      $$->setdvalue($1->getdvalue()+$3->getdvalue());
                                      printf("Now in simp_exp rule Addop last  %lf\n",$1->getdvalue());
                                      }
      ;

term :  unary_expression  {
                           $$=new store();
                           $$->setdvalue($1->getdvalue());
                           printf("Now in term rule u_ex last  %lf\n",$1->getdvalue());
                           }
     |  term MULOP unary_expression{printf("Now in term rule term_mulop first\n");
                                    $$=new store();
                                    $$->setdvalue(($1->getdvalue())*($3->getdvalue()));
                                    printf("Now in term rule term_mulop last  %lf\n",$1->getdvalue());
                                  }
     ;

unary_expression : ADDOP unary_expression  
     | NOT unary_expression {if($2->getdvalue()==0)
                                {
                                  $$=new store();
                                  $$->setdvalue($2->getdvalue()+1);
                                }
                                else
                                {
                                  $$=new store();
                                  $$->setdvalue(0);
                                }
                            }
     | factor {printf("Now in u_ex rule factor first  %lf\n",$1->getdvalue());
               $$=new store();
               $$->setdvalue($1->getdvalue());
               printf("Now in u_ex rule factor last %lf\n",$1->getdvalue());
               }
     ;

factor  : variable   {    printf("Now in factor rule variable first \n");
                           $$=new store();
                           $$->setdvalue($1->getValue());
                           printf("Now in factor rule variable last  %lf\n",$1->getValue());
                      }
  | LPAREN expression RPAREN 
  | CONST_INT {//printf("Now in factor rule const_int first %d \n",$1);
                 $$=new store();
                 $$->setdvalue($1);
                 printf("Now in factor rule const_int last %lf\n",$$->getdvalue());}
  | CONST_FLOAT{$$=new store();$$->setdvalue($1);}
  | CONST_CHAR {$$=new store();$$->setcvalue($1);}
  | factor INCOP 
  | factor DECOP
  ;
%%

int main(int argc,char *argv[])
{

  yydebug=1;
 tokenout.open("1305117_token.txt");
if(argc!=2){
    printf("Please provide input file name and try again\n");
    return 0;
  }

  FILE *fin=fopen(argv[1],"r");
  if(fin==NULL){
    printf("Cannot open specified file\n");
    return 0;
  }



  yyin=fin;
  yyparse();
  st->print_not_empty(tokenout);
  tokenout.close();
  fclose(fin);

    exit(0);
}

标头文件

 #include<cstdio>
#include<string>
#include<iostream>
#include<sstream>
#include <fstream>
#include <cstdlib>
#define NULL_VALUE 0
using namespace std;

class  store{


public:
    store()
    {
        this->dvalue=0;
        this->ivalue=0;
        this->cvalue=0;
        //printf("created\n");
    }
    void setdvalue(double v)
    {
        store::dvalue=v;
    }

    double getdvalue()
    {
        return dvalue;
    }
    int getivalue()
    {
        return ivalue;
    }
    char* getcvalue()
    {
        return cvalue;
    }
    void setivalue(int v)
    {
        store::ivalue=v;
    }
    void setcvalue(char* v)
    {
        store::cvalue=v;
    }

    string code;
    double  dvalue;
    int ivalue;
    char * cvalue;

};

class SymbolInfo
{
public:
    SymbolInfo()// Used as size  is taken later
    {

    }
    SymbolInfo(string  type,string name)
    {
        this->name=name;
        this->type=type;

        this->next= NULL_VALUE;
        this->value=0;

    }

    string getType()
    {
        return type;
    }
    string getName()
    {
        //cout<<"from header "<<name<<endl;
        return name;
    }

    SymbolInfo *getNext() const {
        return next;
    }

    void setNext(SymbolInfo *next) {
        SymbolInfo::next = next;
    }
    void setValue(double value) {
        SymbolInfo::value = value;
    }
    double getValue()
    {
        return value;
    }
    void setCode(string code) {
        SymbolInfo::code = code;
    }
    string getCode()
    {
        return code;
    }

private:
    string type;
    string name;
    SymbolInfo *next;
    double value;
    string code;
};
class position
{
private:
    int i;
    int j;
    string type;
public:
    position(int i, int j) : i(i), j(j) {}

    int getI() const {
        return i;
    }

    void setI(int i) {
        position::i = i;
    }
    void setType(string t)
    {
        type=t;
    }
    string getType()
    {
        return type;
    }


    int getJ() const {
        return j;
    }

    void setJ(int j) {
        position::j = j;
    }
};
class SymbolTable
{
private:

    SymbolInfo **table;
    int maxSize;

    int hash(string  st1) {
        unsigned long hash = 127;
        int c;
        const char*st=st1.c_str();
        while (c = *st++)
        {
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
        }
        return (hash%maxSize);
    }
public:
    SymbolTable(int maxSize)// will have   maxSize number of row
    {
        this->maxSize=maxSize;

        table= new SymbolInfo*[maxSize];
        for(int i=0;i<maxSize;i++)
        {
            *(table+i)=NULL_VALUE;
        }
    }
    SymbolTable()// Used as size  is taken later
    {

    }
     ~SymbolTable()
    {
        SymbolInfo *temp,*temp1;
        for(int i=0;i<maxSize;i++)
        {
           temp=table[i];
            for(;temp!=NULL_VALUE;)
            {
               temp1=temp;
               temp=temp->getNext();
               delete(temp1);
            }
        }
        //cout<<"destructed"<<endl;
    }
    void setSize(int maxSize)
    {
        SymbolTable::maxSize = maxSize;
        this->maxSize=maxSize;

        table= new SymbolInfo*[maxSize];
        for(int i=0;i<maxSize;i++)
        {
            *(table+i)=NULL_VALUE;//necessary to find the end
        }
    }
    position  insert(SymbolInfo* input)
    {
        position pos_temp=(position)lookUp(input->getName());
        if(pos_temp.getI()==-1)// checking is there another entry like this
        {
            int pos = hash(input->getName());//getting hash position
            if (table[pos] == NULL_VALUE) {//is it the first entry of that row
                table[pos] = (input);
                position cur(pos, 0);
                return cur;

            } else {
                SymbolInfo *temp = table[pos];
                int i = 1;
                for (; temp->getNext() != NULL_VALUE; i++) {
                    temp = temp->getNext();
                }
                temp->setNext(input);
                position cur(pos, i);
                return cur;
            }
        }
        else
        {
            //pos_temp.setI(-1);//it's a duplicate entry
            //pos_temp.setJ(-1);
            return  pos_temp;
        }
    }
    position  insert(string info,string Value)
    {
        SymbolInfo *input=new SymbolInfo(info,Value);
        position pos_temp=(position)lookUp(input->getName());
        if(pos_temp.getI()==-1)// checking is there another entry like this
        {
            int pos = hash(input->getName());//getting hash position
            if (table[pos] == NULL_VALUE) {//is it the first entry of that row
                table[pos] = (input);
                position cur(pos, 0);
                return cur;

            } else {
                SymbolInfo *temp = table[pos];
                int i = 1;
                for (; temp->getNext() != NULL_VALUE; i++) {
                    temp = temp->getNext();
                }
                temp->setNext(input);
                position cur(pos, i);
                return cur;
            }
        }
        else
        {
            //pos_temp.setI(-1);//it's a duplicate entry
            //pos_temp.setJ(-1);
            return  pos_temp;
        }
    }
    position lookUp(string st)
    {
        int pos=hash(st);
        //printf("from look up it is %s pos %d\n",st.c_str(),pos);
        SymbolInfo* temp=table[pos];
        console_print();
        string temp_name;
        int i=0;
        for(;(temp!= NULL_VALUE);i++)
        {  //printf("First not null\n");

            temp_name=temp->getName();
            cout<<temp_name<<endl;
            if(temp_name.compare(st.c_str())==0)
            {
                position cur(pos,i);
                //cur.setType(temp->getType());
                printf("from header look ret %d\n",pos);
                return cur;
                //printf("returned\n");
            }
            else
            {
                //printf("here else\n");
                temp = temp->getNext();

            }
        }
        position cur(-1,-1);// as it is a duplicate entry
        printf("hfrom header ret null\n");
        return cur;
    }

    SymbolInfo* getSymbol(position cur)
    {


        SymbolInfo* now,*prev;// two pointer needed as it is a singly linked list
        now=prev=table[cur.getI()];
        for(int j=0;j!=cur.getJ();j++)
        {
            prev=now;
            now=now->getNext();
        }


        return  now;
    }

    void print(ofstream &fout)
    {
        for(int i=0;i<maxSize;i++)
        {
            fout<<i<<" -> ";
            if(table[i]!= NULL_VALUE)
            {
                SymbolInfo *temp = table[i];

                for (;temp!= NULL_VALUE;)
                {
                    //fout<<"<"<<temp->getValue()<<","<<temp->getName().c_str()<<"> ";
                    temp=temp->getNext();
                }
            }
            fout<<endl;
        }
        return;
    }
    void print_not_empty(ofstream &fout)
    {
        fout.seekp(fout.tellp());
        fout<<endl;
        for(int i=0;i<maxSize;i++)
        {

            if(table[i]!= NULL_VALUE)
            {
                fout<<i<<" -> ";
                SymbolInfo *temp = table[i];

                for (;temp!= NULL_VALUE;)
                {
                    fout<<"<"<<temp->getValue()<<","<<temp->getType().c_str()<<"> ";
                    temp=temp->getNext();
                }
                fout<<endl;
            }


        }
        fout<<endl;
        return;
    }
    void console_print()
    {

        cout<<endl;
        for(int i=0;i<maxSize;i++)
        {

            if(table[i]!= NULL_VALUE)
            {
                cout<<i<<" -> ";
                SymbolInfo *temp = table[i];

                for (;temp!= NULL_VALUE;)
                {
                    cout<<"<"<<temp->getValue()<<","<<temp->getType().c_str()<<" ,"<<temp->getName().c_str()<<"> ";
                    temp=temp->getNext();
                }
                cout<<endl;
            }


        }
        cout<<endl;
        return;
    }
    position Delete(string  st)
    {
        position cur=lookUp(st);
        if(cur.getI()==-1)// Checking the value is it exists
        {
            return cur;
        }
        SymbolInfo* now,*prev;// two pointer needed as it is a singly linked list
        now=prev=table[cur.getI()];
        for(int j=0;j!=cur.getJ();j++)
        {
            prev=now;
            now=now->getNext();
        }
        if(cur.getJ()==0)
        {
            table[cur.getI()]=now->getNext();
        }
        prev->setNext(now->getNext());
        delete(now);
        return  cur;
    }
};
/*void func()
{
    ifstream myfile ("input.txt");
    SymbolTable st;
    bool first=true;
    string command,info,value;
    if (myfile.is_open())
    {
        while ( myfile.eof()==false )
        {
                if(first)
                {
                    int s;
                    myfile>>s;
                    st.setSize(s);
                    first=false;
                }
                myfile>>command;
                if(command.compare("I")==0)
                {
                    myfile>>value>>info;
                    SymbolInfo *si=new SymbolInfo(info,value);
                    position pos=(position)(st.insert(si));
                    if(pos.getI()!=-1)
                    {
                        cout<<"<"<<value<<","<<info<<">  "<<"Inserted at position "<<(pos).getI()<<" , "<<pos.getJ()<<endl;
                    }
                    else
                    {
                         cout<<"<"<<value<<","<<info<<">   "<<"Already exist"<<endl;
                    }
                }
                else if(command.compare("P")==0)
                {
                    st.print();
                }
                else if(command.compare("D")==0)
                {
                    myfile>>value;
                    position pos=(position)st.Delete(value);
                    if(pos.getI()==-1)
                    {
                        cout<<value<<" Not Found"<<endl;
                    }
                    else
                    {
                        cout<<"Deleted from "<<(pos).getI()<<"  "<<pos.getJ()<<endl;
                    }
                }
                else if(command.compare("L")==0)
                {
                    myfile>>value;
                    position pos=(position)st.lookUp(value);
                    if(pos.getI()==-1)
                    {
                        cout<<value<<" Not Found"<<endl;
                    }
                    else
                    {
                        cout<<"<"<<value<<","<<pos.getType()<<" Found at "<<(pos).getI()<<"  "<<pos.getJ()<<endl;
                    }
                }
            }
        }
        myfile.close();
    }*/

0 个答案:

没有答案