int DirectiveParser::parseExpressionIfdef(Token *token) { assert((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF)); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); return 0; } MacroSet::const_iterator iter = mMacroSet->find(token->text); int expression = iter != mMacroSet->end() ? 1 : 0; // Warn if there are tokens after #ifdef expression. mTokenizer->lex(token); if (!isEOD(token)) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } return expression; }
int DirectiveParser::parseExpressionIf(Token *token) { assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; ExpressionParser::ErrorSettings errorSettings; errorSettings.integerLiteralsMustFit32BitSignedRange = false; errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; bool valid = true; expressionParser.parse(token, &expression, false, errorSettings, &valid); // Check if there are tokens after #if expression. if (!isEOD(token)) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } return expression; }
void DirectiveParser::parseUndef(Token *token) { assert(getDirective(token) == DIRECTIVE_UNDEF); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } MacroSet::iterator iter = mMacroSet->find(token->text); if (iter != mMacroSet->end()) { if (iter->second.predefined) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, token->location, token->text); } else { mMacroSet->erase(iter); } } mTokenizer->lex(token); }
// Parses pragma of form: #pragma name[(value)]. void DirectiveParser::parsePragma(Token *token) { assert(getDirective(token) == DIRECTIVE_PRAGMA); enum State { PRAGMA_NAME, LEFT_PAREN, PRAGMA_VALUE, RIGHT_PAREN }; bool valid = true; std::string name, value; int state = PRAGMA_NAME; mTokenizer->lex(token); bool stdgl = token->text == "STDGL"; if (stdgl) { mTokenizer->lex(token); } while ((token->type != '\n') && (token->type != Token::LAST)) { switch(state++) { case PRAGMA_NAME: name = token->text; valid = valid && (token->type == Token::IDENTIFIER); break; case LEFT_PAREN: valid = valid && (token->type == '('); break; case PRAGMA_VALUE: value = token->text; valid = valid && (token->type == Token::IDENTIFIER); break; case RIGHT_PAREN: valid = valid && (token->type == ')'); break; default: valid = false; break; } mTokenizer->lex(token); } valid = valid && ((state == PRAGMA_NAME) || // Empty pragma. (state == LEFT_PAREN) || // Without value. (state == RIGHT_PAREN + 1)); // With value. if (!valid) { mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name); } else if (state > PRAGMA_NAME) // Do not notify for empty pragma. { mDirectiveHandler->handlePragma(token->location, name, value, stdgl); } }
/*delimite les fonctions du programme et crée la liste des fonctions */ void Program::comput_function(){ Function *func; Line *element_debut=NULL; Line* current = _head; Directive *d=NULL; string direct; while(current != NULL){ if(current->isDirective()){ d = getDirective(current); direct=d->get_content(); if(direct.size() !=0){ if( direct.compare(0, 4, ".ent")==0){ element_debut=current; } if( direct.compare(0, 4, ".end")==0){ func = new Function(); func->set_head(element_debut); func->set_end(current); element_debut=NULL; //func -> display(); _myfunc.push_back(func); } } } if(current->get_next()==NULL) break; else current = current->get_next(); } if (is_empty()) cout<<"The program is empty"<<endl; }
void DirectiveParser::parseError(Token *token) { assert(getDirective(token) == DIRECTIVE_ERROR); std::ostringstream stream; mTokenizer->lex(token); while ((token->type != '\n') && (token->type != Token::LAST)) { stream << *token; mTokenizer->lex(token); } mDirectiveHandler->handleError(token->location, stream.str()); }
int DirectiveParser::parseExpressionIf(Token *token) { assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; macroExpander.lex(token); expressionParser.parse(token, &expression); // Warn if there are tokens after #if expression. if (!isEOD(token)) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } return expression; }
void GetMkBlock( ss_block *ss_new, char *start, int line ) { line = line; if( start[0] == '\0' ) { if( firstNonWS == start ) { // line is empty - // do not flag following line as having anything to do // with an unterminated macro flags.inMacro = false; } getBeyondText( ss_new ); return; } // Preprocessor directives must start at beginning of line if( (start[0] == '!') && (firstChar == start) ) { getPreproc( ss_new, start ); return; } if( flags.inMacro ) { getMacro( ss_new, start, 0 ); return; } if( isspace( start[0] ) ) { getWhiteSpace( ss_new, start ); return; } switch( start[0] ) { case '$': getMacro( ss_new, start, 1 ); return; case '#': getComment( ss_new, start ); return; case '.': getDirective( ss_new, start ); return; } if( isalpha( start[0] ) ) { getText( ss_new, start ); } else { getSymbol( ss_new ); } }
void DirectiveParser::parseConditionalIf(Token *token) { ConditionalBlock block; block.type = token->text; block.location = token->location; if (skipping()) { // This conditional block is inside another conditional group // which is skipped. As a consequence this whole block is skipped. // Be careful not to parse the conditional expression that might // emit a diagnostic. skipUntilEOD(mTokenizer, token); block.skipBlock = true; } else { DirectiveType directive = getDirective(token); int expression = 0; switch (directive) { case DIRECTIVE_IF: expression = parseExpressionIf(token); break; case DIRECTIVE_IFDEF: expression = parseExpressionIfdef(token); break; case DIRECTIVE_IFNDEF: expression = parseExpressionIfdef(token) == 0 ? 1 : 0; break; default: assert(false); break; } block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; } mConditionalStack.push_back(block); }
void DirectiveParser::parseElse(Token *token) { assert(getDirective(token) == DIRECTIVE_ELSE); if (mConditionalStack.empty()) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } ConditionalBlock &block = mConditionalStack.back(); if (block.skipBlock) { // No diagnostics. Just skip the whole line. skipUntilEOD(mTokenizer, token); return; } if (block.foundElseGroup) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } block.foundElseGroup = true; block.skipGroup = block.foundValidGroup; block.foundValidGroup = true; // Warn if there are extra tokens after #else. mTokenizer->lex(token); if (!isEOD(token)) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } }
void DirectiveParser::parseElif(Token *token) { assert(getDirective(token) == DIRECTIVE_ELIF); if (mConditionalStack.empty()) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } ConditionalBlock &block = mConditionalStack.back(); if (block.skipBlock) { // No diagnostics. Just skip the whole line. skipUntilEOD(mTokenizer, token); return; } if (block.foundElseGroup) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } if (block.foundValidGroup) { // Do not parse the expression. // Also be careful not to emit a diagnostic. block.skipGroup = true; skipUntilEOD(mTokenizer, token); return; } int expression = parseExpressionIf(token); block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; }
void DirectiveParser::parseEndif(Token *token) { assert(getDirective(token) == DIRECTIVE_ENDIF); if (mConditionalStack.empty()) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } mConditionalStack.pop_back(); // Warn if there are tokens after #endif. mTokenizer->lex(token); if (!isEOD(token)) { mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } }
int main(int argc, char **argv) { string directive; // input directive string strArg; // string argument double dblArg; // double argument int intArg; // integer argument KMdata* dataPts = NULL; // the data points KMalg alg; // which algorithm to use initGlobals(); // initialize global values getCmdArgs(argc, argv); kmOut->precision(4); // output precision *kmOut << "------------------------------------------------------------\n" << "kmltest: " << KMlongName << "\n" << " Version: " << KMversion << " " << KMversionCmt << "\n" << " Copyright: " << KMcopyright << ".\n" << " Latest Revision: " << KMlatestRev << ".\n" << "------------------------------------------------------------\n\n"; //-------------------------------------------------------------------- // Main input loop //-------------------------------------------------------------------- // read input directive while (getDirective(*kmIn, directive)) { //---------------------------------------------------------------- // Read options //---------------------------------------------------------------- if (directive == "quit") { kmExit(); } else if (directive == "dim") { *kmIn >> dim; new_clust = true; // force new clusters } else if (directive == "data_size") {
//Verifies all instructions and data on list and translate to binary int verifyAndTranslate() { struct command *com, *aux; char result[32]; int currentAddress = 0; com = (struct command*)malloc(sizeof(struct command)); com = first; while(com != NULL){ //Directive if(getDirective(com->line) == 3){ //printf("\n\nDado: (%s)",com->line); strcpy(com->line, checkData(com->line)); if(strcmp(com->line, "0") == 0){ printf("\n-> ERROR(6): INVALID VALUE - Line %d", com->lineNumber); return 0; } if(strcmp(com->line, "1") == 0){ printf("\n-> ERROR(7): VALUE OVERFLOW - Line %d", com->lineNumber); return 0; } //printf("\n%s (%d bits)\n",com->line, strlen(com->line)); } //Instruction else{ //printf("\n\nInstrucao: (%s)",com->line); strcpy(com->line, checkInstruction(com->line, currentAddress)); if(strcmp(com->line, "1") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(8): INVALID REGISTER - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "2") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(9): INVALID LABEL - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "3") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(10): INVALID CONSTANT - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "4") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(11): INVALID MNEMONIC - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "5") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(12): MISSING PARAMETERS - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "6") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(13): CONSTANT OVERFLOW - Line %d", com->lineNumber); return 0; } else if(strcmp(com->line, "7") == 0){ printf("\nPROGRAM NOT ASSEMBLED"); printf("\n-> ERROR(14): ONLY UNSIGNED CONSTANT - Line %d", com->lineNumber); return 0; } //printf("\n%s (%d bits)\n",com->line, strlen(com->line)); } com = com->next; currentAddress++; } return 1; }
void DirectiveParser::parseIfndef(Token *token) { assert(getDirective(token) == DIRECTIVE_IFNDEF); parseConditionalIf(token); }
void DirectiveParser::parseLine(Token *token) { assert(getDirective(token) == DIRECTIVE_LINE); enum State { LINE_NUMBER, FILE_NUMBER }; bool valid = true; int line = 0, file = 0; int state = LINE_NUMBER; MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics); macroExpander.lex(token); while ((token->type != '\n') && (token->type != Token::LAST)) { switch (state++) { case LINE_NUMBER: if (valid && (token->type != Token::CONST_INT)) { mDiagnostics->report(Diagnostics::PP_INVALID_LINE_NUMBER, token->location, token->text); valid = false; } if (valid && !token->iValue(&line)) { mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); valid = false; } break; case FILE_NUMBER: if (valid && (token->type != Token::CONST_INT)) { mDiagnostics->report(Diagnostics::PP_INVALID_FILE_NUMBER, token->location, token->text); valid = false; } if (valid && !token->iValue(&file)) { mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); valid = false; } break; default: if (valid) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; } break; } macroExpander.lex(token); } if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1)) { mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text); valid = false; } if (valid) { mTokenizer->setLineNumber(line); if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file); } }
int OPCodes::getDirectiveSize(string code, int numReserved) { return getDirective(code,numReserved).size; }
void DirectiveParser::parseExtension(Token *token) { assert(getDirective(token) == DIRECTIVE_EXTENSION); enum State { EXT_NAME, COLON, EXT_BEHAVIOR }; bool valid = true; std::string name, behavior; int state = EXT_NAME; mTokenizer->lex(token); while ((token->type != '\n') && (token->type != Token::LAST)) { switch (state++) { case EXT_NAME: if (valid && (token->type != Token::IDENTIFIER)) { mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location, token->text); valid = false; } if (valid) name = token->text; break; case COLON: if (valid && (token->type != ':')) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; } break; case EXT_BEHAVIOR: if (valid && (token->type != Token::IDENTIFIER)) { mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, token->location, token->text); valid = false; } if (valid) behavior = token->text; break; default: if (valid) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; } break; } mTokenizer->lex(token); } if (valid && (state != EXT_BEHAVIOR + 1)) { mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location, token->text); valid = false; } if (valid) mDirectiveHandler->handleExtension(token->location, name, behavior); }
void DirectiveParser::parseVersion(Token *token) { assert(getDirective(token) == DIRECTIVE_VERSION); if (mPastFirstStatement) { mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location, token->text); skipUntilEOD(mTokenizer, token); return; } enum State { VERSION_NUMBER, VERSION_PROFILE, VERSION_ENDLINE }; bool valid = true; int version = 0; int state = VERSION_NUMBER; mTokenizer->lex(token); while (valid && (token->type != '\n') && (token->type != Token::LAST)) { switch (state) { case VERSION_NUMBER: if (token->type != Token::CONST_INT) { mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location, token->text); valid = false; } if (valid && !token->iValue(&version)) { mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); valid = false; } if (valid) { state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; } break; case VERSION_PROFILE: if (token->type != Token::IDENTIFIER || token->text != "es") { mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, token->text); valid = false; } state = VERSION_ENDLINE; break; default: mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; break; } mTokenizer->lex(token); } if (valid && (state != VERSION_ENDLINE)) { mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, token->text); valid = false; } if (valid) { mDirectiveHandler->handleVersion(token->location, version); } }
void DirectiveParser::parseDefine(Token *token) { assert(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, token->text); return; } if (isMacroNameReserved(token->text)) { mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } // Using double underscores is allowed, but may result in unintended // behavior, so a warning is issued. At the time of writing this was // specified in ESSL 3.10, but the intent judging from Khronos // discussions and dEQP tests was that double underscores should be // allowed in earlier ESSL versions too. if (hasDoubleUnderscores(token->text)) { mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location, token->text); } Macro macro; macro.type = Macro::kTypeObj; macro.name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. macro.type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end()) { mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES, token->location, token->text); return; } macro.parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. } while (token->type == ','); if (token->type != ')') { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. } while ((token->type != '\n') && (token->type != Token::LAST)) { // Reset the token location because it is unnecessary in replacement // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); macro.replacements.push_back(*token); mTokenizer->lex(token); } if (!macro.replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. macro.replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. MacroSet::const_iterator iter = mMacroSet->find(macro.name); if (iter != mMacroSet->end() && !macro.equals(iter->second)) { mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro.name); return; } mMacroSet->insert(std::make_pair(macro.name, macro)); }
void DirectiveParser::parseLine(Token *token) { assert(getDirective(token) == DIRECTIVE_LINE); bool valid = true; bool parsedFileNumber = false; int line = 0, file = 0; MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false); // Lex the first token after "#line" so we can check it for EOD. macroExpander.lex(token); if (isEOD(token)) { mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text); valid = false; } else { ExpressionParser expressionParser(¯oExpander, mDiagnostics); ExpressionParser::ErrorSettings errorSettings; // See GLES3 section 12.42 errorSettings.integerLiteralsMustFit32BitSignedRange = true; errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER; // The first token was lexed earlier to check if it was EOD. Include // the token in parsing for a second time by setting the // parsePresetToken flag to true. expressionParser.parse(token, &line, true, errorSettings, &valid); if (!isEOD(token) && valid) { errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER; // After parsing the line expression expressionParser has also // advanced to the first token of the file expression - this is the // token that makes the parser reduce the "input" rule for the line // expression and stop. So we're using parsePresetToken = true here // as well. expressionParser.parse(token, &file, true, errorSettings, &valid); parsedFileNumber = true; } if (!isEOD(token)) { if (valid) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; } skipUntilEOD(mTokenizer, token); } } if (valid) { mTokenizer->setLineNumber(line); if (parsedFileNumber) mTokenizer->setFileNumber(file); } }
void DirectiveParser::parseDirective(Token *token) { assert(token->type == Token::PP_HASH); mTokenizer->lex(token); if (isEOD(token)) { // Empty Directive. return; } DirectiveType directive = getDirective(token); // While in an excluded conditional block/group, // we only parse conditional directives. if (skipping() && !isConditionalDirective(directive)) { skipUntilEOD(mTokenizer, token); return; } switch(directive) { case DIRECTIVE_NONE: mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, token->location, token->text); skipUntilEOD(mTokenizer, token); break; case DIRECTIVE_DEFINE: parseDefine(token); break; case DIRECTIVE_UNDEF: parseUndef(token); break; case DIRECTIVE_IF: parseIf(token); break; case DIRECTIVE_IFDEF: parseIfdef(token); break; case DIRECTIVE_IFNDEF: parseIfndef(token); break; case DIRECTIVE_ELSE: parseElse(token); break; case DIRECTIVE_ELIF: parseElif(token); break; case DIRECTIVE_ENDIF: parseEndif(token); break; case DIRECTIVE_ERROR: parseError(token); break; case DIRECTIVE_PRAGMA: parsePragma(token); break; case DIRECTIVE_EXTENSION: parseExtension(token); break; case DIRECTIVE_VERSION: parseVersion(token); break; case DIRECTIVE_LINE: parseLine(token); break; default: assert(false); break; } skipUntilEOD(mTokenizer, token); if (token->type == Token::LAST) { mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text); } }
void DirectiveParser::parseDefine(Token *token) { assert(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, token->text); return; } if (isMacroNameReserved(token->text)) { mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } Macro macro; macro.type = Macro::kTypeObj; macro.name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. macro.type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; macro.parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. } while (token->type == ','); if (token->type != ')') { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. } while ((token->type != '\n') && (token->type != Token::LAST)) { // Reset the token location because it is unnecessary in replacement // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); macro.replacements.push_back(*token); mTokenizer->lex(token); } if (!macro.replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. macro.replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. MacroSet::const_iterator iter = mMacroSet->find(macro.name); if (iter != mMacroSet->end() && !macro.equals(iter->second)) { mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro.name); return; } mMacroSet->insert(std::make_pair(macro.name, macro)); }
//Does the assembly code verification, counting the instructions and data number. int checksAssembly() { FILE *file = NULL; char *line; char aux[300]; //Number of lines int lineNumber = 1; //Counts the program lines(only instructions, directives and labels) int lineCount = 0; //Tells which part of the reader program is int module = 0, end = 0, pseg = 0, dseg = 0; //Save the directive code int directiveCode = -2; int instructionState = 0; file = fopen(urlInputFile, "r"); while(fgets(aux, sizeof(aux), file)!= NULL) { //Verifies the line line = verifyLine(aux); //If is anything if(line!=NULL) { //Reads the directive code directiveCode = getDirective(line); //Asserts that the first instructions are the .module if(lineCount == 0 && directiveCode != 0){ informError(1, lineNumber); fclose(file); return 1; } //If is .module if(directiveCode == 0){ module = 1; end = 0; } //If is .pseg else if(directiveCode == 1){ pseg = 1; dseg = 0; } //If is .dseg else if(directiveCode == 2){ if(pseg == 0){ informError(6, lineNumber); fclose(file); return 1; } pseg = 0; dseg = 1; } //If is .end else if(directiveCode == 4){ module = 0; end = 1; lineCount = 0; } //If is a wrong directive else if(directiveCode == -2){ informError(3, lineNumber); fclose(file); return 1; } //If is a instruction increments the number of instruction if(pseg == 1 && module == 1 && line[0] != '.' && directiveCode != 3){ addCommand(line, lineNumber); numberOfInstructions++; } else if(pseg == 1 && module == 1 && line[0] == '.' && directiveCode == 3){ informError(4, lineNumber); fclose(file); return 1; } //If is a word increments the number of instruction if(dseg == 1 && module == 1 && directiveCode == 3){ addCommand(line, lineNumber); numberOfData++; } else if(dseg == 1 && module == 1 && directiveCode == -1){ informError(5, lineNumber); fclose(file); return 1; } //Checks if the memory(64KB -> 16384 32-bits address) was exceeded if((numberOfData + numberOfInstructions) > 16384){ informError(2, lineNumber); fclose(file); return 1; } if(end != 1) lineCount++; } lineNumber++; } fclose(file); return 0; }