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

📄 vpreproc.cpp

📁 Verilog Parser in Perl
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    return (VP_TEXT);	}	if (m_lineCmt!="") {	    // We have some `line directive to return to the user.  Do it.	    static string rtncmt;  // Keep the c string till next call	    rtncmt = m_lineCmt;	    if (m_lineCmtNl) {		if (!m_rawAtBol) rtncmt = "\n"+rtncmt;		m_lineCmtNl = false;	    }	    yytext=(char*)rtncmt.c_str(); yyleng=rtncmt.length();	    m_lineCmt = "";	    if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');	    if (m_state!=ps_DEFVALUE) return (VP_TEXT);	    else {		VPreprocLex::s_currentLexp->appendDefValue(yytext,yyleng);		goto next_tok;	    }	}	if (isEof()) return (VP_EOF);	// Snarf next token from the file	m_filelinep = m_lexp->m_curFilelinep;  // Remember token start location	VPreprocLex::s_currentLexp = m_lexp;   // Tell parser where to get/put data	int tok = yylex();	if (debug()) {	    string buf = string (yytext, yyleng);	    string::size_type pos;	    while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }	    while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }	    fprintf (stderr, "%d: RAW %s s%d dr%d:  %-10s: %s\n",		     m_filelinep->lineno(), m_off?"of":"on", m_state, (int)m_defRefs.size(),		     tokenName(tok), buf.c_str());	}	// On EOF, try to pop to upper level includes, as needed.	if (tok==VP_EOF) {	    eof();	    goto next_tok;  // Parse parent, or find the EOF.	}	if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');	return tok;    }}// Sorry, we're not using bison/yacc. It doesn't handle returning white space// in the middle of parsing other tokens.int VPreprocImp::getToken() {    // Return the next user-visible token in the input stream.    // Includes and such are handled here, and are never seen by the caller.    while (1) {      next_tok:	if (isEof()) return VP_EOF;	int tok = getRawToken();	// Always emit white space and comments between tokens.	if (tok==VP_WHITE) return (tok);	if (tok==VP_COMMENT) {	    if (!m_off && m_lexp->m_keepComments) {		if (m_lexp->m_keepComments == KEEPCMT_SUB		    || m_lexp->m_keepComments == KEEPCMT_EXP) {		    string rtn; rtn.assign(yytext,yyleng);		    m_preprocp->comment(rtn);		} else {		    return (tok);		}	    }	    // We're off or processed the comment specially.  If there are newlines	    // in it, we also return the newlines as TEXT so that the linenumber	    // count is maintained for downstream tools	    for (int len=0; len<yyleng; len++) { if (yytext[len]=='\n') m_lineAdd++; }	    goto next_tok;	}	if (tok==VP_LINE) {	    addLineComment(0);	    goto next_tok;	}	// Deal with some special parser states	switch (m_state) {	case ps_TOP: {	    break;	}	case ps_DEFNAME: {	    if (tok==VP_SYMBOL) {		m_state = ps_TOP;		m_lastSym.assign(yytext,yyleng);		if (m_stateFor==VP_IFDEF		    || m_stateFor==VP_IFNDEF) {		    bool enable = m_preprocp->defExists(m_lastSym);		    if (debug()) cout<<"Ifdef "<<m_lastSym<<(enable?" ON":" OFF")<<endl;		    if (m_stateFor==VP_IFNDEF) enable = !enable;		    m_ifdefStack.push(VPreIfEntry(enable,false));		    if (!enable) parsingOff();		}		else if (m_stateFor==VP_ELSIF) {		    if (m_ifdefStack.empty()) {			error("`elsif with no matching `if\n");		    } else {			// Handle `else portion			VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();			if (!lastIf.on()) parsingOn();			// Handle `if portion			bool enable = !lastIf.everOn() && m_preprocp->defExists(m_lastSym);			if (debug()) cout<<"Elsif "<<m_lastSym<<(enable?" ON":" OFF")<<endl;			m_ifdefStack.push(VPreIfEntry(enable, lastIf.everOn()));			if (!enable) parsingOff();		    }		}		else if (m_stateFor==VP_UNDEF) {		    if (!m_off) {			if (debug()) cout<<"Undef "<<m_lastSym<<endl;			m_preprocp->undef(m_lastSym);		    }		}		else if (m_stateFor==VP_DEFINE) {		    // m_lastSym already set.		    m_state = ps_DEFVALUE;		    m_lexp->pushStateDefValue();		}		else fatalSrc("Bad case\n");		goto next_tok;	    }	    else {		error((string)"Expecting define name. Found: "+tokenName(tok)+"\n");		goto next_tok;	    }	}	case ps_DEFVALUE: {	    static string newlines;	    newlines = "\n";  // Always start with trailing return	    if (tok == VP_DEFVALUE) {		// Remove returns		for (unsigned i=0; i<m_lexp->m_defValue.length(); i++) {		    if (m_lexp->m_defValue[i] == '\n') {			m_lexp->m_defValue[i] = ' ';			newlines += "\n";		    }		}		if (!m_off) {		    string params;		    if (m_lexp->m_defValue=="" || isspace(m_lexp->m_defValue[0])) {			// Define without parameters		    } else if (m_lexp->m_defValue[0] == '(') {			string::size_type paren = m_lexp->m_defValue.find(")");			if (paren == string::npos) {			    error((string)"Missing ) to end define arguments.\n");			} else {			    params = m_lexp->m_defValue.substr(0, paren+1);			    m_lexp->m_defValue.replace(0, paren+1, "");			}		    } else {			error((string)"Missing space or paren to start define value.\n");		    }		    // Remove leading whitespace		    unsigned leadspace = 0;		    while (m_lexp->m_defValue.length() > leadspace			   && isspace(m_lexp->m_defValue[leadspace])) leadspace++;		    if (leadspace) m_lexp->m_defValue.erase(0,leadspace);		    // Remove trailing whitespace		    unsigned trailspace = 0;		    while (m_lexp->m_defValue.length() > trailspace			   && isspace(m_lexp->m_defValue[m_lexp->m_defValue.length()-1-trailspace])) trailspace++;		    if (trailspace) m_lexp->m_defValue.erase(m_lexp->m_defValue.length()-trailspace,trailspace);		    // Define it		    if (debug()) cout<<"Define "<<m_lastSym<<" = '"<<m_lexp->m_defValue<<"'"<<endl;		    m_preprocp->define(m_lastSym, m_lexp->m_defValue, params);		}	    } else {		fatalSrc("Bad define text\n");	    }	    m_state = ps_TOP;	    // DEFVALUE is terminated by a return, but lex can't return both tokens.	    // Thus, we emit a return here.	    yytext=(char*)(newlines.c_str()); yyleng=newlines.length();	    return(VP_WHITE);	}	case ps_DEFPAREN: {	    if (tok==VP_TEXT && yyleng==1 && yytext[0]=='(') {		m_state = ps_DEFARG;		goto next_tok;	    } else {		m_state = ps_TOP;		if (m_defRefs.empty()) error("InternalError: Shouldn't be in DEFPAREN w/o active defref");		VPreDefRef* refp = &(m_defRefs.top());		error((string)"Expecting ( to begin argument list for define reference `"+refp->name()+"\n");		goto next_tok;	    }	}	case ps_DEFARG: {	    if (m_defRefs.empty()) error("InternalError: Shouldn't be in DEFARG w/o active defref");	    VPreDefRef* refp = &(m_defRefs.top());	    refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue="";	    if (tok==VP_DEFARG && yyleng==1 && yytext[0]==',') {		refp->args().push_back(refp->nextarg());		m_state = ps_DEFARG;		m_lexp->pushStateDefArg(1);		refp->nextarg("");		goto next_tok;	    } else if (tok==VP_DEFARG && yyleng==1 && yytext[0]==')') {		refp->args().push_back(refp->nextarg());		string out = defineSubst(refp);		// Substitute in and prepare for next action		// Similar code in non-parenthesized define (Search for END_OF_DEFARG)		m_defRefs.pop();		m_lexp->unputString(out.c_str());		if (m_defRefs.empty()) {		    m_state = ps_TOP;		    m_lexp->m_parenLevel = 0;		}		else {  // Finished a defref inside a upper defref		    refp = &(m_defRefs.top());  // We popped, so new top		    m_lexp->m_parenLevel = refp->parenLevel();		    m_state = ps_DEFARG;		}		goto next_tok;	    } else if (tok==VP_DEFREF) {		// Expand it, then state will come back here		// Value of building argument is data before the lower defref		// we'll append it when we push the argument.		break;	    } else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE) {		string rtn; rtn.assign(yytext,yyleng);		refp->nextarg(refp->nextarg()+rtn);		goto next_tok;	    } else {		error((string)"Expecting ) or , to end argument list for define reference. Found: "+tokenName(tok));		m_state = ps_TOP;		goto next_tok;	    }	}	case ps_INCNAME: {	    if (tok==VP_STRING) {		m_state = ps_TOP;		m_lastSym.assign(yytext,yyleng);		if (debug()) cout<<"Include "<<m_lastSym<<endl;		// Drop leading and trailing quotes.		m_lastSym.erase(0,1);		m_lastSym.erase(m_lastSym.length()-1,1);		m_preprocp->include(m_lastSym);		goto next_tok;	    }	    else if (tok==VP_TEXT && yyleng==1 && yytext[0]=='<') {		// include <filename>		m_state = ps_INCNAME;  // Still		m_lexp->pushStateIncFilename();		goto next_tok;	    }	    else if (tok==VP_DEFREF) {		// Expand it, then state will come back here		break;	    }	    else {		m_state = ps_TOP;		error((string)"Expecting include filename. Found: "+tokenName(tok)+"\n");		goto next_tok;	    }	}	case ps_ERRORNAME: {	    if (tok==VP_STRING) {		m_state = ps_TOP;		if (!m_off) {		    m_lastSym.assign(yytext,yyleng);		    error(m_lastSym);		}		goto next_tok;	    }	    else {		m_state = ps_TOP;		error((string)"Expecting `error string. Found: "+tokenName(tok)+"\n");		goto next_tok;	    }	}	default: fatalSrc("Bad case\n");	}	// Default is to do top level expansion of some tokens	switch (tok) {	case VP_INCLUDE:	    if (!m_off) {		m_state = ps_INCNAME;  m_stateFor = tok;	    }	    goto next_tok;	case VP_UNDEF:	case VP_DEFINE:	case VP_IFDEF:	case VP_IFNDEF:	case VP_ELSIF:	    m_state = ps_DEFNAME;  m_stateFor = tok;	    goto next_tok;	case VP_ELSE:	    if (m_ifdefStack.empty()) {		error("`else with no matching `if\n");	    } else {		VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();		bool enable = !lastIf.everOn();		if (debug()) cout<<"Else "<<(enable?" ON":" OFF")<<endl;		m_ifdefStack.push(VPreIfEntry(enable, lastIf.everOn()));		if (!lastIf.on()) parsingOn();		if (!enable) parsingOff();	    }	    goto next_tok;	case VP_ENDIF:	    if (debug()) cout<<"Endif "<<endl;	    if (m_ifdefStack.empty()) {		error("`endif with no matching `if\n");	    } else {		VPreIfEntry lastIf = m_ifdefStack.top(); m_ifdefStack.pop();		if (!lastIf.on()) parsingOn();		// parsingOn() really only enables parsing if		// all ifdef's above this want it on	    }	    goto next_tok;	case VP_DEFREF: {	    if (!m_off) {		string name; name.append(yytext+1,yyleng-1);		if (debug()) cout<<"DefRef "<<name<<endl;		if (m_defDepth++ > VPreproc::DEFINE_RECURSION_LEVEL_MAX) {		    error("Recursive `define substitution: `"+name);		    goto next_tok;		}		//		string params = m_preprocp->defParams(name);		if (params=="") {   // Not found, return original string as-is		    m_defDepth = 0;		    if (debug()) cout<<"Defref `"<<name<<" => not_defined"<<endl;		    return (VP_TEXT);		}		else if (params=="0") {  // Found, as simple substitution		    string out = m_preprocp->defValue(name);		    if (debug()) cout<<"Defref `"<<name<<" => '"<<out<<"'"<<endl;		    // Similar code in parenthesized define (Search for END_OF_DEFARG)		    if (m_defRefs.empty()) {			// Just output the substitution			m_lexp->unputString(out.c_str());		    } else {			// Inside another define.  Can't subst now, or			// `define a x,y			// foo(`a,`b)  would break because a contains comma			VPreDefRef* refp = &(m_defRefs.top());			refp->nextarg(refp->nextarg()+m_lexp->m_defValue+out); m_lexp->m_defValue="";		    }		    goto next_tok;		}		else {  // Found, with parameters		    if (debug()) cout<<"Defref `"<<name<<" => parametrized"<<endl;		    m_defRefs.push(VPreDefRef(name, params, m_lexp->m_parenLevel));		    m_state = ps_DEFPAREN;  m_stateFor = tok;		    m_lexp->pushStateDefArg(0);		    goto next_tok;		}		fatalSrc("Bad case\n");	    }	    else goto next_tok;	}	case VP_ERROR: {	    m_state = ps_ERRORNAME;  m_stateFor = tok;	    goto next_tok;	}	case VP_EOF:	    if (!m_ifdefStack.empty()) {		error("`ifdef not terminated at EOF\n");	    }	    return tok;	case VP_SYMBOL:	case VP_STRING:	case VP_TEXT: {	    m_defDepth = 0;	    if (!m_off) return tok;	    else goto next_tok;	}	case VP_WHITE:		// Handled at top of loop	case VP_COMMENT:	// Handled at top of loop	case VP_DEFVALUE:	// Handled by m_state=ps_DEFVALUE;	default:	    fatalSrc("Internal error: Unexpected token.\n");	    break;	}	return tok;    }}string VPreprocImp::getline() {    // Get a single line from the parse stream.  Buffer unreturned text until the newline.    if (isEof()) return "";    while (1) {	char* rtnp;	bool gotEof = false;	while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) {	    int tok = getToken();	    if (debug()) {		string buf = string (yytext, yyleng);		string::size_type pos;		while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }		while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }		fprintf (stderr,"%d: GETFETC:  %-10s: %s\n",			 m_filelinep->lineno(), tokenName(tok), buf.c_str());	    }	    if (tok==VP_EOF) {		// Add a final newline, if the user forgot the final \n.		// Note tok==VP_EOF isn't always seen by us, as isEof() may be set earlier		if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') {		    m_lineChars.append("\n");		}		gotEof = true;	    }	    else {		m_lineChars.append(yytext,0,yyleng);	    }	}	// Make new string with data up to the newline.	int len = rtnp-m_lineChars.c_str()+1;	string theLine(m_lineChars, 0, len);	m_lineChars = m_lineChars.erase(0,len);	// Remove returned characters	if (!m_preprocp->keepWhitespace() && !gotEof) {	    const char* cp=theLine.c_str();	    for (; *cp && (isspace(*cp) || *cp=='\n'); cp++) {}	    if (!*cp) continue;	}	if (debug()) fprintf (stderr,"%d: GETLINE:  %s\n", m_filelinep->lineno(), theLine.c_str());	return theLine;    }}

⌨️ 快捷键说明

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