CAssemblerCommand* Parser::parseLabel() { updateFileInfo(); const Token& start = peekToken(0); if (peekToken(0).type == TokenType::Identifier && peekToken(1).type == TokenType::Colon) { const std::wstring name = peekToken(0).getStringValue(); eatTokens(2); if (initializingMacro) macroLabels.insert(name); if (Global.symbolTable.isValidSymbolName(name) == false) { printError(start,L"Invalid label name"); return nullptr; } return new CAssemblerLabel(name); } return nullptr; }
CAssemblerCommand* Parser::parseCommand() { CAssemblerCommand* command; while (checkEquLabel() || checkMacroDefinition()) { // do nothing, just parse all the equs and macros there are if (hasError()) return handleError(); } updateFileInfo(); if (atEnd()) return new DummyCommand(); if ((command = parseLabel()) != nullptr) return command; if (hasError()) return handleError(); if ((command = parseMacroCall()) != nullptr) return command; if (hasError()) return handleError(); if ((command = Arch->parseDirective(*this)) != nullptr) return command; if (hasError()) return handleError(); if ((command = parseDirective(directives)) != nullptr) return command; if (hasError()) return handleError(); if ((command = Arch->parseOpcode(*this)) != nullptr) return command; if (hasError()) return handleError(); const Token& token = peekToken(); printError(token,L"Parse error '%s'",token.getOriginalText()); return handleError(); }
bool Parser::checkEquLabel() { updateFileInfo(); const Token& start = peekToken(); if (start.type == TokenType::Identifier) { int pos = 1; if (peekToken(pos).type == TokenType::Colon) pos++; if (peekToken(pos).type == TokenType::Equ && peekToken(pos+1).type == TokenType::EquValue) { std::wstring name = peekToken(0).getStringValue(); std::wstring value = peekToken(pos+1).getStringValue(); eatTokens(pos+2); // equs are not allowed in macros if (initializingMacro) { printError(start,L"equ not allowed in macro"); return true; } if (Global.symbolTable.isValidSymbolName(name) == false) { printError(start,L"Invalid equation name %s",name); return true; } if (Global.symbolTable.symbolExists(name,Global.FileInfo.FileNum,Global.Section)) { printError(start,L"Equation name %s already defined",name); return true; } addEquation(start,name,value); return true; } } return false; }
void parse( ObjFilePtr* file, const char* filename ) { // expect the worst *file = NULL; char fullname[MAX_STRING_LENGTH]; /* if a path was given include it in the full file name */ if (path == NULL) { strcpy(fullname, filename); } else { fullname[0] = '\0'; strcat(fullname, path); int len = strlen(fullname); if (fullname[len - 1] != '/') { fullname[len] = '/'; fullname[len + 1] = '\0'; } strcat(fullname, filename); } // open the .obj file FILE* f; f = fopen(fullname, "r"); if (NULL == f) { return; } // create the ObjFile object. ObjFile* objFile = createObjFile(filename); if (NULL == objFile) { return; } // get neccessary information about the file // until the end of the file, read the file in line by line char line[MAX_STRING_LENGTH]; while (NULL != fgets(line, MAX_STRING_LENGTH, f)) { updateFileInfo(objFile, line); } // alloc memory for positions, normals, texcoords, groups, faces and objects // TODO: check if all allocations // succeed objFile->positions = (ObjVector3F*)malloc( sizeof(ObjVector3F)*(objFile->numPositions + 1) ); objFile->normals = (ObjVector3F*)malloc( sizeof(ObjVector3F)*(objFile->numNormals + 1) ); objFile->texCoords = (ObjVector2F*)malloc( sizeof(ObjVector2F)*(objFile->numTexCoords + 1) ); if (objFile->numFaces) { objFile->faces = (ObjFace*)malloc(sizeof(ObjFace)*objFile->numFaces); } objFile->objects = (ObjObject*)malloc( sizeof(ObjObject)*(objFile->numObjects + 1) ); objFile->groups = (ObjGroup*)malloc( sizeof(ObjGroup)*(objFile->numObjects + 1 + objFile->numGroups) ); // once again iterate through the file and copy the data rewind(f); prepareForProcessing(objFile); while (NULL != fgets(line, MAX_STRING_LENGTH, f)) { updateFile(objFile, line); } // clean up fclose(f); // return result *file = objFile; }