示例#1
0
//
// SourceTokenizerC::doCommand_ifndef
//
void SourceTokenizerC::doCommand_ifndef(SourceTokenC *)
{
   SourceTokenC::Reference name = getRaw(); doAssert(name, SourceTokenC::TT_NAM);
   doAssert(peekRaw(), SourceTokenC::TT_ENDL);

   addSkip(hasDefine(name->data) || hasMacro(name->data));
}
示例#2
0
//
// SourceTokenizerC::expand
//
// Expands a token.
//
void SourceTokenizerC::expand(MacroVec &out, std::set<std::string> &used,
   SourcePosition const &pos, SourceTokenC::Reference tok, SourceStream *in,
   MacroArgs const *altArgs, MacroParm const *altParm)
{
   // Check for function-like macro expansion.
   // That is, a function-like macro name followed by an open parenthesis.
   // And of course, that name must not have been expanded yet.
   if(tok->type == SourceTokenC::TT_PAREN_O &&
      !out.empty() && out.back()->type == SourceTokenC::TT_NAM &&
      hasMacro(out.back()->data) && !used.count(out.back()->data))
   {
      tok = out.back(); out.pop_back();
      MacroData const &mdata = macros[tok->data];
      MacroArgs margs;
      readArgs(margs, in, mdata, pos, altArgs, altParm);

      used.insert(tok->data);
      expand(out, used, pos, mdata, margs);
      used.erase(tok->data);

      return;
   }

   // Check for object-like macro expansion.
   // Like above, but it only needs one token to trigger.
   if(tok->type == SourceTokenC::TT_NAM && hasDefine(tok->data) && !used.count(tok->data))
   {
      used.insert(tok->data);
      expand(out, used, pos, defines[tok->data]);
      used.erase(tok->data);

      return;
   }

   // Then check for __FILE__ specifically.
   if(tok->type == SourceTokenC::TT_NAM && tok->data == "__FILE__")
   {
      out.push_back(SourceTokenC::create(pos, pos.filename, SourceTokenC::TT_STR));

      return;
   }

   // And __LINE__.
   if(tok->type == SourceTokenC::TT_NAM && tok->data == "__LINE__")
   {
      std::ostringstream oss; oss << pos.line;
      out.push_back(SourceTokenC::create(pos, oss.str(), SourceTokenC::TT_INT));

      return;
   }

   // If it actually isn't any of those things, then consider the token expanded.
   out.push_back(tok);
}
示例#3
0
//
// SourceTokenizerC::getExpand
//
SourceTokenC::Reference SourceTokenizerC::getExpand()
{
   SourceTokenC::Reference tok = getRaw();

   if (canExpand && tok->type == SourceTokenC::TT_NAM)
   {
      if (hasMacro(tok->data))
      {
         SourceTokenC::Reference tmpTok = getExpand();

         // Macro invocation!
         if (tmpTok->type == SourceTokenC::TT_PAREN_O)
         {
            expandMacro(tok); return getExpand();
         }

         unget(tmpTok);
      }

      if (hasDefine(tok->data))
      {
         expandDefine(tok); return getExpand();
      }

      if (tok->data == "__FILE__")
         return SourceTokenC::create(tok->pos, tok->pos.filename,
                                     SourceTokenC::TT_STR);

      if (tok->data == "__LINE__")
      {
         std::ostringstream oss; oss << tok->pos.line;
         return SourceTokenC::create(tok->pos, oss.str(), SourceTokenC::TT_INT);
      }
   }

   return tok;
}
示例#4
0
void Driver::setupLexer( Lexer * lexer ) {
  // stl
  lexer->addSkipWord( "__STL_BEGIN_NAMESPACE" );
  lexer->addSkipWord( "__STL_END_NAMESPACE" );
  lexer->addSkipWord( "__STL_BEGIN_RELOPS_NAMESPACE" );
  lexer->addSkipWord( "__STL_END_RELOPS_NAMESPACE" );
  lexer->addSkipWord( "__STL_TEMPLATE_NULL" );
  lexer->addSkipWord( "__STL_TRY" );
  lexer->addSkipWord( "__STL_UNWIND" );
  lexer->addSkipWord( "__STL_NOTHROW" );
  lexer->addSkipWord( "__STL_NULL_TMPL_ARGS" );
  lexer->addSkipWord( "__STL_UNWIND", SkipWordAndArguments );
  lexer->addSkipWord( "__GC_CONST" );
  lexer->addSkipWord( "__HASH_ALLOC_INIT", SkipWordAndArguments );
  lexer->addSkipWord( "__STL_DEFAULT_ALLOCATOR", SkipWordAndArguments, "T" );
  lexer->addSkipWord( "__STL_MUTEX_INITIALIZER" );
  lexer->addSkipWord( "__STL_NULL_TMPL_ARGS" );

  // antlr
  lexer->addSkipWord( "ANTLR_BEGIN_NAMESPACE", SkipWordAndArguments );
  lexer->addSkipWord( "ANTLR_USE_NAMESPACE", SkipWordAndArguments );
  lexer->addSkipWord( "ANTLR_USING_NAMESPACE", SkipWordAndArguments );
  lexer->addSkipWord( "ANTLR_END_NAMESPACE" );
  lexer->addSkipWord( "ANTLR_C_USING", SkipWordAndArguments );
  lexer->addSkipWord( "ANTLR_API" );

  // gnu
  lexer->addSkipWord( "__extension__", SkipWordAndArguments );
  lexer->addSkipWord( "__attribute__", SkipWordAndArguments );
  lexer->addSkipWord( "__BEGIN_DECLS" );
  lexer->addSkipWord( "__END_DECLS" );
  lexer->addSkipWord( "__THROW" );
  lexer->addSkipWord( "__restrict" );
  lexer->addSkipWord( "__restrict__" );
  lexer->addSkipWord( "__attribute_pure__" );
  lexer->addSkipWord( "__attribute_malloc__" );
  lexer->addSkipWord( "__attribute_format_strfmon__" );
  lexer->addSkipWord( "__asm__", SkipWordAndArguments );
  lexer->addSkipWord( "__devinit" );
  lexer->addSkipWord( "__devinit__" );
  lexer->addSkipWord( "__init" );
  lexer->addSkipWord( "__init__" );
  lexer->addSkipWord( "__signed" );
  lexer->addSkipWord( "__signed__" );
  lexer->addSkipWord( "__unsigned" );
  lexer->addSkipWord( "__unsigned__" );
  lexer->addSkipWord( "asmlinkage" );
  lexer->addSkipWord( "____cacheline_aligned" );
  lexer->addSkipWord( "__glibcpp_class_requires", SkipWordAndArguments );
  lexer->addSkipWord( "__glibcpp_class2_requires", SkipWordAndArguments );
  lexer->addSkipWord( "__glibcpp_class4_requires", SkipWordAndArguments );
  lexer->addSkipWord( "__glibcpp_function_requires", SkipWordAndArguments );
  lexer->addSkipWord( "restrict" );

  lexer->addSkipWord( "__BEGIN_NAMESPACE_STD" );
  lexer->addSkipWord( "__END_NAMESPACE_STD" );
  lexer->addSkipWord( "__BEGIN_NAMESPACE_C99" );
  lexer->addSkipWord( "__END_NAMESPACE_C99" );
  lexer->addSkipWord( "__USING_NAMESPACE_STD", SkipWordAndArguments );

  // kde
  lexer->addSkipWord( "K_SYCOCATYPE", SkipWordAndArguments );
  lexer->addSkipWord( "EXPORT_DOCKCLASS" );
  lexer->addSkipWord( "K_EXPORT_COMPONENT_FACTORY", SkipWordAndArguments );
  lexer->addSkipWord( "K_SYCOCAFACTORY", SkipWordAndArguments );
  lexer->addSkipWord( "KDE_DEPRECATED" );

  // qt
  lexer->addSkipWord( "Q_OBJECT" );
  lexer->addSkipWord( "Q_OVERRIDE", SkipWordAndArguments );
  lexer->addSkipWord( "Q_ENUMS", SkipWordAndArguments );
  lexer->addSkipWord( "Q_PROPERTY", SkipWordAndArguments );
  lexer->addSkipWord( "Q_CLASSINFO", SkipWordAndArguments );
  lexer->addSkipWord( "Q_SETS", SkipWordAndArguments );
  lexer->addSkipWord( "Q_UNUSED", SkipWordAndArguments );
  lexer->addSkipWord( "Q_CREATE_INSTANCE", SkipWordAndArguments );
  lexer->addSkipWord( "Q_DUMMY_COMPARISON_OPERATOR", SkipWordAndArguments );
  lexer->addSkipWord( "ACTIVATE_SIGNAL_WITH_PARAM", SkipWordAndArguments );
  lexer->addSkipWord( "Q_INLINE_TEMPLATES" );
  lexer->addSkipWord( "Q_TEMPLATE_EXTERN" );
  lexer->addSkipWord( "Q_TYPENAME" );
  lexer->addSkipWord( "Q_REFCOUNT" );
  lexer->addSkipWord( "Q_EXPLICIT" );
  lexer->addSkipWord( "QMAC_PASCAL" );
  lexer->addSkipWord( "QT_STATIC_CONST" );
  lexer->addSkipWord( "QT_STATIC_CONST_IMPL" );
  lexer->addSkipWord( "QT_WIN_PAINTER_MEMBERS" );
  lexer->addSkipWord( "QT_NC_MSGBOX" );
  lexer->addSkipWord( "Q_VARIANT_AS", SkipWordAndArguments );
  lexer->addSkipWord( "CALLBACK_CALL_TYPE" );

  // qt4 [erbsland]
  lexer->addSkipWord( "Q_DECLARE_FLAGS", SkipWordAndArguments );
  lexer->addSkipWord( "Q_DECLARE_OPERATORS_FOR_FLAGS", SkipWordAndArguments );

  // flex
  lexer->addSkipWord( "yyconst" );
  lexer->addSkipWord( "YY_RULE_SETUP" );
  lexer->addSkipWord( "YY_BREAK" );
  lexer->addSkipWord( "YY_RESTORE_YY_MORE_OFFSET" );

  // gtk
  lexer->addSkipWord( "G_BEGIN_DECLS" );
  lexer->addSkipWord( "G_END_DECLS" );
  lexer->addSkipWord( "G_GNUC_CONST" );
  lexer->addSkipWord( "G_CONST_RETURN" );
  lexer->addSkipWord( "GTKMAIN_C_VAR" );
  lexer->addSkipWord( "GTKVAR" );
  lexer->addSkipWord( "GDKVAR" );
  lexer->addSkipWord( "G_GNUC_PRINTF", SkipWordAndArguments );

  // windows
  lexer->addSkipWord( "WINAPI" );
  lexer->addSkipWord( "__stdcall" );
  lexer->addSkipWord( "__cdecl" );
  lexer->addSkipWord( "_cdecl" );
  lexer->addSkipWord( "CALLBACK" );

  // gcc extensions
  if( !hasMacro( "__asm__" ) ) addMacro( Macro( "__asm__", "asm" ) );
  if( !hasMacro( "__inline" ) ) addMacro( Macro( "__inline", "inline" ) );
  if( !hasMacro( "__inline__" ) ) addMacro( Macro( "__inline__", "inline" ) );
  if( !hasMacro( "__const" ) ) addMacro( Macro( "__const", "const" ) );
  if( !hasMacro( "__const__" ) ) addMacro( Macro( "__const__", "const" ) );
  if( !hasMacro( "__volatile__" ) ) addMacro( Macro( "__volatile__", "volatile" ) );
  if( !hasMacro( "__complex__" ) ) addMacro( Macro( "__complex__", "" ) );
}
示例#5
0
int MacroExtender::macroExtend() {
	bool canWrite = false;
	int numLine;
	int macroBound = 0;
	int macroLastStart = 0,macroLastEnd = 0;
	bool textSegment = false;
	bool dataSegment = false;
	bool isMacroBody = false;
	smatch auxMatch;
	string curLine;
	vector<string> currentCode;
	vector<string> macroParams;
	vector<string> macroLines;
	fileIn.append(".pre");
	fileOut.append(".mcr");
	ifstream inputFile(fileIn,ios::in);
		
	if (!inputFile) {
		cerr	<< "Fatal Error: Could not open file " << fileIn << endl; 
		return -1;
	}
	cout << "Opened " << fileIn << " for macro-extending..." << endl;
	ofstream outputFile(fileOut,ios::out);
	if (!outputFile) {
		cerr	<< "Fatal Error: Could not create file " << fileOut << endl; 
		return -1;
	}

	while (getline(inputFile,curLine)) {
		// prepareLine(curLine);
		if (curLine.find("SECTION ")!=string::npos && regex_search(curLine,auxMatch,regex("\\bSECTION "))) {
			if (regex_search(curLine,auxMatch,regex("\\bTEXT$"))) {
				textSegment = true;
			}
			else {
				textSegment = false;
			}
			if (regex_search(curLine,auxMatch,regex("\\bDATA$"))) {
				dataSegment = true;
			}
			else {
				dataSegment = false;
			}
		}
		else if (curLine.find(" MACRO ")!=string::npos || regex_search(curLine,auxMatch,regex(" MACRO$")) || regex_search(curLine,auxMatch,regex("\\bMACRO "))) {
			macroBound++;
			macroLastStart = numLine;
			if (textSegment || dataSegment) {
				addError(numLine,string("Semantical Error: MACRO definitions must go before all"));
			}
		}
		else if (regex_search(curLine,auxMatch,regex("\\bMACRO "))) {
			macroBound++;
			macroLastStart = numLine;
			if (textSegment || dataSegment) {
				addError(numLine,string("Semantical Error: MACRO definitions must go before all"));
			}
		}
		else if (regex_search(curLine,auxMatch,regex("\\bENDMACRO$"))) {
			macroBound--;
			macroLastEnd = numLine;
			if (textSegment || dataSegment) {
				addError(numLine,string("Semantical Error: ENDMACRO must go before all"));
			}
		}
		currentCode.push_back(curLine);
		currentCode.shrink_to_fit();
		numLine++;
	}
	//cout << "Macro Bound: " << macroBound << endl;
	if (macroBound>0) {
		addError(macroLastStart,string("Semantical Error: Caught at least one MACRO without a corresponding ENDMACRO"));
	}
	else if (macroBound<0) {
		addError(macroLastEnd,string("Semantical Error: Caught at least one ENDMACRO without a corresponding MACRO"));
	}

	vector<string>::iterator codeIterator;
	for (numLine=1,codeIterator=currentCode.begin();codeIterator!=currentCode.end();codeIterator++,numLine++) {
		curLine = *codeIterator;
		canWrite = true;
		//cout << "@" << hasMacro(curLine) << endl; 
		if (curLine.find("SECTION ")!=string::npos && regex_search(curLine,auxMatch,regex("\\bSECTION "))) {
			if (regex_search(curLine,auxMatch,regex("\\bTEXT$"))) {
				textSegment = true;
			}
			else {
				textSegment = false;
			}
			outputFile << curLine << "\n";
		}
		else if (curLine.find(" MACRO ")!=string::npos || regex_search(curLine,auxMatch,regex(" MACRO$")) || regex_search(curLine,auxMatch,regex("\\bMACRO "))) {
			macroParams.clear();
			macroLines.clear();
			if (regex_search(curLine,auxMatch,regex("\\bMACRO ")) && curLine.find("MACRO ")==0) {
				addError(numLine,string("Syntactical Error: MACRO must have a definition label"));
			}
			else if (!regex_search(curLine,auxMatch,regex(labelReg))) {
				addError(numLine,string("Syntactical Error: MACRO must have a definition label"));
			}
			else if (macroBound<=0 || (macroBound>0 && numLine!=macroLastStart)) {
				int macroDefLine = numLine;
				int numParameters; 
				string macroLabel = curLine.substr(0,curLine.find_last_of(':'));
				if (directiveTable.isDirective(macroLabel) || opcodeTable.isInstruction(macroLabel)) {
					addError(numLine,string("Semantical Error: Invalid use of keyword"));
				}
				if (macroLabel.find(':')!=string::npos) {
					addError(numLine,string("Syntactical Error: Too many definitions for MACRO constructor"));
				}
				if (curLine.find(" MACRO ") == string::npos) {
					numParameters = 0;
				}
				else {
					string auxParameters = curLine.substr(curLine.find(" MACRO ")+7);
					splitTokenize(auxParameters,macroParams,",");
					if (hasDuplicates(macroParams)) {
						addError(numLine,"Semantical Errors: Duplicate parameter detected");
					}
					for (const string &macroRef : macroParams) {
						if (!regex_match(macroRef,regex("\\&[\\w]"))) {
							addError(numLine,"Syntactical Error: Invalid parameter(s) for MACRO statement");
							break;
						}
					}
					numParameters = macroParams.size();
					if (numParameters > MACRO_MAX_PARAMS) {
						string pError = "Semantical Error: Too many parameters for MACRO definition (max at ";
						pError.append(to_string(MACRO_MAX_PARAMS));
						pError.append(" )");
						pError.shrink_to_fit();
						addError(numLine,pError);
					}
					//cout << macroParams << endl;
				}
				if (MNT.find(macroLabel) != MNT.end()) {
					addError(numLine,"Semantical Error: Macro redefinition detected");
				}
				MNT.emplace(macroLabel,make_pair(macroDefLine,numParameters));
				isMacroBody = true;
				codeIterator++;
				while (isMacroBody && codeIterator != currentCode.end()) {
					curLine = *codeIterator;
					if (curLine.find(" EXTERN") != string::npos && regex_search(curLine,auxMatch,regex(" EXTERN$"))) {
						addError(numLine,"Semantical Error: EXTERN directive inside a macro body is forbidden");
					}
					if (curLine.find(" BEGIN") != string::npos && regex_search(curLine,auxMatch,regex(" BEGIN$"))) {
						addError(numLine,"Semantical Error: BEGIN directive inside a macro body is forbidden");
					}
					if (regex_search(curLine,auxMatch,regex("^\\bEND[\\b]?$"))) {
						addError(numLine,"Semantical Error: END directive inside a macro body is forbidden");
					}
					if (curLine.find("PUBLIC ") != string::npos && regex_search(curLine,auxMatch,regex("^PUBLIC "))) {
						addError(numLine,"Semantical Error: PUBLIC directive inside a macro body is forbidden");
					}
					if (curLine.find(':') != string::npos) {
						addError(numLine,"Semantical Error: MACRO does not support labels inside");
						continue;
					}
					if (regex_search(curLine,auxMatch,regex("\\bENDMACRO$"))) {
						isMacroBody = false;
						break;
					}
					if (curLine.find("SECTION ")!=string::npos && regex_search(curLine,auxMatch,regex("^SECTION "))) {
						addError(numLine,"Semantical Error: SECTION directive inside a macro body is forbidden");
					}
					else {
						for (unsigned i=0;i<macroParams.size();i++) {
							string paramRegex = macroParams[i];
							string paramSub = string("#") + to_string(i+1);
							curLine = regex_replace(curLine,regex(paramRegex),paramSub);
						}
						if(regex_search(curLine,auxMatch,regex("\\&[\\w]"))) {
							addError(numLine,"Semantical Error: MACRO has less parameters than it uses");
						}
						macroLines.push_back(curLine);
					}
					codeIterator++;
					numLine++;
				}
				numLine++;
				MDT.emplace(macroLabel,macroLines);
			}
		}
		//else if (regex_search(curLine,auxMatch,regex("\\bENDMACRO\\b"))) {
		//	canWrite = false;
		//}
		else if (hasMacro(curLine)!=";") {
			string macroFound = hasMacro(curLine);
			//cout << "Found Macro \"" << macroFound << "\"at line " << numLine << endl;
			map<string,std::pair<int,int> >::iterator MNTCell = MNT.find(macroFound);
			map<string,vector<string> >::iterator MDTCell = MDT.find(macroFound);
			std::pair<int,int> MNTDefs = MNTCell->second;
			vector<string> auxiliarLines = MDTCell->second;
			vector<string> paramsToSub;
			try	{
				string finalLine = curLine.substr(curLine.find(macroFound)+macroFound.length()+1);
				if (curLine.find(':') != string::npos) {
					string curLabel = curLine.substr(0,curLine.find(':')+1);
					outputFile << curLabel << " ";
				}
				splitTokenize(finalLine,paramsToSub,",");
				if (paramsToSub.size() != static_cast<unsigned>(MNTDefs.second)) {
					addError(numLine,"Syntactical Error: Wrong number of parameters for current MACRO");
				}
				else {
					for (const string &subLines : auxiliarLines) {
						string auxSubLine = subLines;
						for (int j=0;j<MNTDefs.second;j++) {
							string MDTParamRegex = string("#") + to_string(j+1);
							auxSubLine = regex_replace(auxSubLine,regex(MDTParamRegex),paramsToSub[j]);
						}
						outputFile << auxSubLine << "\n";	
					}
				}
			}
			catch (std::out_of_range &e) {
				//cout << "Macro without params: " << e.what() << endl;
				if (curLine.find(':') != string::npos) {
					string curLabel = curLine.substr(0,curLine.find(':')+1);
					outputFile << curLabel << " ";
				}
				for (const string &subLines : auxiliarLines) {
					outputFile << subLines << "\n";	
				}
			}
		}
		else {
			if (!canWrite) {
				canWrite = true;
			}
			else {
				if (curLine.size()) {
					outputFile << curLine << "\n";
				}
			}
		}
	}
	//cout << "MNT: " << endl;
	//cout << MNT << endl;
	//cout << "MDT: " << endl;
	//cout << MDT << endl;
	if (this->errorList.size()) {
		printErrors();
		outputFile.close();
		remove(fileOut.c_str());
	}
	return this->errorList.size();
}