⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 nRF24E1 sample sensor node code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <string>using std::string;#include "token.h"extern CToken* yylex();extern FILE* yyin;string g_header;bool g_lineinfo;bool g_debug;std::map<string,string> g_macros;class ETEOF{};class ETUnmatch{public:    ETUnmatch(int _exp, CToken* _enc) : exp(_exp), enc(_enc) { }    string to_string (int c)    {        char buff[10];        if(c<MIN_TOKEN)            sprintf(buff,"'%c'",c);        else            sprintf(buff,"%d",c);        return string(buff);    }    int exp;    CToken* enc;};class Parser{public:    int parse(const char*);private:    int NextToken(bool if_throw=true) ;    CToken* MatchAny();    CToken* Match(int t);    CToken* MatchPair(int,int);    CToken* MatchPair(int,int,string&);    CToken* parse_template();    CToken* parse_component();    CToken* parse_connect();      CToken* parse_varid();	CToken* parse_compid();	CToken* parse_typename();    CToken* parse_port(string &, bool&);    CToken* parse_funct_body();        CToken* parse_arglist(string&, string&);        std::vector<CToken*> m_tokens;    std::vector<CToken*> m_program;    std::vector<CToken*>::iterator m_iter;    CToken* m_template;    ComponentClass* m_current_component;    ComponentTable* m_component_table;        FILE* m_outfile;    void WriteProgram();	string m_hfilename;};int Parser::NextToken(bool if_throw){	if(m_iter==m_tokens.end())	{   	    if(if_throw)            throw ETEOF();        else            return 0;    }    else        return (*m_iter)->type;}CToken* Parser::MatchAny(){    CPort* port;    CToken* t = *m_iter;    m_iter++;    if(m_iter!=m_tokens.end()&&(*m_iter)->type==VARID)	{	    if(m_current_component!=NULL)	    {	        for(unsigned int i=0;i<m_current_component->tmpl_args.size();i++)	        {	            if( (*m_iter)->GetID() == m_current_component->tmpl_args[i])	            {	                (*m_iter)->type=ARGID;	                //printf("line: %d, argid: %s\n",(*m_iter)->lineno,(*m_iter)->text.c_str());	                break;	            }	        }	    }		if(t->type!=SCOPE&&t->type!='.'&&t->type!=DOTSTAR&&t->type!=ARROWSTAR&&t->type!=ARROW)		{			if(ComponentClass::Lookup((*m_iter)->GetID())!=NULL)			{			    //printf("convert '%s' to COMPID\n",(*m_iter)->GetID().c_str());				(*m_iter)->type=COMPID;		    }			if(m_current_component!=NULL && (port=m_current_component->LookupPort((*m_iter)->GetID()))!=NULL )			{			    //printf("convert '%s' to PORTID\n",(*m_iter)->GetID().c_str());				(*m_iter)->type=PORTID;		    }		}       }    return t;};CToken* Parser::Match(int t) {     if(t!=NextToken())         throw ETUnmatch(t,*m_iter);    else        return MatchAny();}CToken* Parser::MatchPair(int left, int right){    CToken *s, *t;	s=t=Match(left);    int level=0;    while(level!=0||NextToken()!=right)    {        if(NextToken()==right)level--;        if(NextToken()==left)level++;        t->sibling=MatchAny();		t=t->sibling;    }    t->sibling=MatchAny();    t=t->sibling;    return s;}CToken* Parser::MatchPair(int left, int right, string& text){    CToken *s, *t;	s=t=Match(left);	text = t->text;    int level=0;    while(level!=0||NextToken()!=right)    {        if(NextToken()==right)level--;        if(NextToken()==left)level++;        t->sibling=MatchAny();		t=t->sibling;		text += t->text;    }    t->sibling=MatchAny();    t=t->sibling;	text += t->text;    return s;}int Parser::parse(const char* filename){    yyin= fopen(filename,"r");    if(yyin==NULL)    {        printf("error: cannot open file '%s'\n", filename);        return 2;    }    CTranslation::New();    CTranslation::Current()->filename=filename;    CToken::New(CTranslation::Current());    // read all tokens into m_tokens    while( (yylex()) != NULL )    {        m_tokens.push_back(CToken::Current());    }    /*for(unsigned int i=0;i<m_tokens.size();i++)    {        m_tokens[i]->Dump();     }*/    fclose(yyin);    g_header =  "#include <assert.h> \n #include<vector> \n"                "template <class T> class compcxx_array { public: \n"                "virtual ~compcxx_array() { for (typename std::vector<T*>::iterator i=m_elements.begin();i!=m_elements.end();i++) delete (*i); } \n"
                "void SetSize(unsigned int n) { for(unsigned int i=0;i<n;i++)m_elements.push_back(new T); } \n"
                "T& operator [] (unsigned int i) { assert(i<m_elements.size()); return(*m_elements[i]); } \n"
                "unsigned int size() { return m_elements.size();} \n"
                "private: std::vector<T*> m_elements; }; \n"
                "class compcxx_component; \n"
                "template <class T> class compcxx_functor {public: \n"                "void Connect(compcxx_component&_c, T _f){ c.push_back(&_c); f.push_back(_f); } \n"
                "protected: std::vector<compcxx_component*>c; std::vector<T> f; }; \n"
                "class compcxx_component { public: \n";    string ofilename = filename;    m_hfilename=ofilename;    unsigned int pos = ofilename.rfind('.');    ofilename.erase(pos+1);    m_hfilename.erase(pos);    m_hfilename = string("compcxx_") + m_hfilename + ".h";    ofilename+="cxx";    //printf("output file name:%s\n",ofilename.c_str());    m_outfile=fopen(ofilename.c_str(),"w");    if(m_outfile==NULL)    {        printf("cannot open output file '%s'\n",ofilename.c_str());        return 1;    }        // starting parsing here    m_iter=m_tokens.begin();    int type;    bool line_info=true;    CToken* token;         parsing:    m_current_component = NULL;    m_component_table = NULL;        try     {        while( (type=NextToken(false))!=0)        {    	    assert(m_current_component==NULL);    	    assert(m_component_table==NULL);            switch(type)            {            case TEMPLATE:                token=parse_template();                break;            case COMPONENT:                token=parse_component();                break;            case CONNECT:                token=MatchAny();                CTranslation::Error(token,4, "connect statements must appear within a function\n");			    break;        	            case INPORT:            case OUTPORT:                token=MatchAny();                CTranslation::Error(token,5, "port must be declared within a component\n");                break;            case COMPID:        	    token= parse_compid() ;        	    break;            case VARID:        	    token = parse_varid();        	    break;        	case TYPENAME:        		token = parse_typename();        		break;            default:                token=MatchAny();            }            if(token!=NULL)            {                if(line_info==true)                {                    token->line_info=true;                    line_info=false;                }                m_program.push_back(token);                            }            else                line_info=true;        }    }    catch( ETUnmatch& e )    {        CTranslation::Error(e.enc, 3, "syntax error -- expected: %s, encountered: %s\n",             e.to_string(e.exp).c_str(), e.to_string(e.enc->type).c_str());        line_info=true;        goto parsing;    }    catch( ETEOF & )    {        CTranslation::Error(NULL, 2, "unexpected end-of-file\n");    }        if(CTranslation::ErrorCount())    {        printf("%d error(s).\n",CTranslation::ErrorCount());    }        WriteProgram();    fclose(m_outfile);        m_outfile=fopen(m_hfilename.c_str(),"w+");    if(m_outfile==NULL)    {        printf("cannot open %s\n",m_hfilename.c_str());        return 1;    }    fprintf(m_outfile,"%s};\n",g_header.c_str());    fclose(m_outfile);    return CTranslation::ErrorCount();}CToken* Parser::parse_template(){    CToken* t =  Match(TEMPLATE);    t->AppendChild( MatchPair('<','>') );    if(NextToken()==TEMPLATE)    {        t->AppendChild(Match(TEMPLATE));        t->AppendChild(MatchPair('<','>'));    }    return t;}CToken* Parser::parse_component(){    int token;    string port_name, comp_name;    string return_type, full_list, arg_list;    bool array;        CToken* comp = Match(COMPONENT);    CToken* comp_decl = CToken::New(comp,component_declaration);    CToken* tmpl = NULL;    CToken* p = NULL;        if(!m_program.empty()&&m_program.back()->type==TEMPLATE)    {    	tmpl = m_program.back();    	m_program.pop_back();    	comp_decl->AppendChild(tmpl);    	comp->lineno=tmpl->lineno;    	tmpl->text = string("/*") + tmpl->text;    	assert(tmpl->last_child!=NULL);    	tmpl->last_child->text += "*/";    }  	comp->line_info=true;    comp_decl->AppendChild(comp);    CToken* t = Match(VARID);    t->type=MAINID;    comp_decl->AppendChild(t);    comp_name = t->GetID();        m_current_component = ComponentClass::Lookup(comp_name);    if(m_current_component!=NULL)    {    	CTranslation::Error(t,6,"component '%s' has already been defined\n",comp_name.c_str());    	comp_name+='_';    }   	m_current_component = ComponentClass::New(comp,comp_name);   	if(g_debug)printf("component %s\n",comp_name.c_str());   	if(tmpl!=NULL)m_current_component->AnalyzeTemplate(tmpl);   	   	m_component_table = m_current_component;    if(NextToken()==';')    {        CTranslation::Error(t,7,"foward component declaration not necessary\n");        comp_decl->AppendChild(MatchAny());        return comp;    }        if(NextToken()==':')    {        CToken* t = Match(':');        t->text += "public " COMPCXX "component, ";        comp_decl->AppendChild(t);    }    else    {        CToken* t = CToken::New(comp,UNKNOWN);        t->text = ": public " COMPCXX "component ";        comp_decl->AppendChild(t);    }        while(NextToken()!='{')        comp_decl->AppendChild(MatchAny());    comp_decl->AppendChild(Match('{'));        while( (token=NextToken())!='}')    {        switch(token)        {    	case COMPONENT:        	CTranslation::Error(*m_iter,8,"nested component not permitted\n");        	while(NextToken()!=';')                MatchAny();	        MatchAny();            break;    	case INPORT:        	t = parse_port( port_name, array);        	comp_decl->AppendChild(t);        	break;    	case OUTPORT:        	t = parse_port( port_name, array);        	p = CToken::New(t, outport_declaration);        	p->text = port_name;        	p->AppendChild(t);        	comp_decl->AppendChild(p);            if(m_current_component!=NULL&&m_current_component->composite&&array)            {              	CTranslation::Error(t,19,"a composite component cannot have outport arrays\n");            }        	break;    	case CONNECT:            MatchAny();            CTranslation::Error(NULL,4, "connect statements must appear within a function\n");            break;    	case COMPID:        	comp_decl->AppendChild(parse_compid());            break;       	case VARID:        	comp_decl->AppendChild(parse_varid());            break;        case CLASS:			while(NextToken()!=';'&&NextToken()!='{')				comp_decl->AppendChild(MatchAny());			if(NextToken()=='{')	        	comp_decl->AppendChild(MatchPair('{','}'));	       	else	       		comp_decl->AppendChild(Match(';'));			break;        	       	default:            comp_decl->AppendChild(MatchAny());        }    };        CToken* tend = Match('}');   	if(g_debug)printf("end component\n");    comp_decl->AppendChild(CToken::New(tend,end_of_component_declaration));    comp_decl->AppendChild(tend);    if(NextToken()==';')        comp_decl->AppendChild(Match(';'));    m_current_component->AddToken(comp_decl);    m_current_component=NULL;    m_component_table=NULL;	return NULL;  }CToken*  Parser::parse_port(string& port_name, bool& array)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -