ReqLine_t parseRequestLine (int fd) { enum ReqKind_t kind; ReqLine_t reqline; switch(token.kind){ case TOKEN_HEAD: kind = REQ_KIND_HEAD; break; case TOKEN_GET: kind = REQ_KIND_GET; break; default: parseError(fd); break; } advance(fd, 1); eatToken(TOKEN_SPACE, fd, 1); char *uri = eatToken(TOKEN_STR, fd, 1); eatToken(TOKEN_SPACE, fd, 1); eatToken(TOKEN_HTTP_ONE_ONE, fd, 1); eatToken(TOKEN_CRLF, fd, 1); if (DEBUG){ fprintf (stderr, "uri=%s\n", uri); } reqline = ReqLine_new (0 , uri , HTTP_ONE_ONE); ReqLine_print (1, reqline); return reqline; }
void parseHeaders (int fd) { advance(fd,1); int i = 0; fprintf (stderr, "header starting\n"); while (token.kind != TOKEN_CRLF){ // this should not be string..., // a dirty hack /*if(i) advance(fd, 1); i = 1;*/ char *str1 = eatToken(TOKEN_STR, fd, 1); advance (fd, 1); eatToken(TOKEN_SPACE, fd, 0); advance (fd, 0); char *str2 = eatToken(TOKEN_STR, fd, 1); if(strcmp(str1,"Content-Length:") == 0) { printf("Content-Length Match sucess Length = %s..\n",str2); //read length number of body gLength = atoi(str2); } advance (fd, 1); eatToken(TOKEN_CRLF, fd, 1); //fprintf (stderr, "eeee"); advance(fd, 1); //printf("kind = %d\n",token.kind); } return; }
ReqLine_t Parse_reqLine (int fd) { enum ReqKind_t kind; ReqLine_t reqline; getToken(fd, 1); //modify //printf("parse(F) uri = %s; kind = %d; n = %d\n", token.lexeme, token.kind, TOKEN_POST); switch(token.kind){ case TOKEN_HEAD: kind = REQ_KIND_HEAD; break; case TOKEN_GET: kind = REQ_KIND_GET; break; case TOKEN_POST: kind = REQ_KIND_POST; break; default: parseError(fd); break; } advance(fd, 1); eatToken(TOKEN_SPACE, fd, 1); advance (fd, 1); //modify char *uri = eatToken(TOKEN_STR, fd, 1); //eatToken(TOKEN_SPACE, fd, 1); advance (fd, 1); eatToken(TOKEN_SPACE, fd , 1); advance(fd, 1); eatToken(TOKEN_HTTP_ONE_ONE, fd, 1); advance(fd, 1); eatToken(TOKEN_CRLF, fd, 1); ///no more eat token if (DEBUG){ fprintf (stderr, "uri=%s\n", uri); } reqline = ReqLine_new ( kind , uri , HTTP_ONE_ONE); ReqLine_print (1, reqline); return reqline; }
void parseHeaders (int fd) { fprintf (stderr, "header starting\n"); while (token.kind != TOKEN_CRLF){ // this should not be string..., // a dirty hack eatToken(TOKEN_STR, fd, 1); eatToken(TOKEN_SPACE, fd, 0); eatToken(TOKEN_STR, fd, 1); eatToken(TOKEN_CRLF, fd, 1); fprintf (stderr, "eeee"); } return; }
CAssemblerCommand* Parser::handleError() { // skip the rest of the line const Token& token = nextToken(); while (peekToken().line == token.line) eatToken(); clearError(); return new InvalidCommand(); }
bool Parser::matchToken(TokenType type, bool optional) { if (optional) { const Token& token = peekToken(); if (token.type == type) eatToken(); return true; } return nextToken().type == type; }
bool Parser::parseExpressionList(std::vector<Expression>& list, int min, int max) { bool valid = true; list.clear(); list.reserve(max >= 0 ? max : 32); const Token& start = peekToken(); Expression exp = parseExpression(); list.push_back(exp); if (exp.isLoaded() == false) { printError(start,L"Parameter failure"); getTokenizer()->skipLookahead(); valid = false; } while (peekToken().type == TokenType::Comma) { eatToken(); exp = parseExpression(); list.push_back(exp); if (exp.isLoaded() == false) { printError(start,L"Parameter failure"); getTokenizer()->skipLookahead(); valid = false; } } if (list.size() < (size_t) min) { printError(start,L"Not enough parameters (min %d)",min); return false; } if (max != -1 && (size_t) max < list.size()) { printError(start,L"Too many parameters (max %d)",max); return false; } return valid; }
CAssemblerCommand* Parser::parseDirective(const DirectiveMap &directiveSet) { const Token &tok = peekToken(); if (tok.type != TokenType::Identifier) return nullptr; const std::wstring stringValue = tok.getStringValue(); auto matchRange = directiveSet.equal_range(stringValue); for (auto it = matchRange.first; it != matchRange.second; ++it) { const DirectiveEntry &directive = it->second; if (directive.flags & DIRECTIVE_DISABLED) continue; if ((directive.flags & DIRECTIVE_NOCASHOFF) && Global.nocash == true) continue; if ((directive.flags & DIRECTIVE_NOCASHON) && Global.nocash == false) continue; if ((directive.flags & DIRECTIVE_NOTINMEMORY) && Global.memoryMode == true) continue; if (directive.flags & DIRECTIVE_MIPSRESETDELAY) Arch->NextSection(); eatToken(); CAssemblerCommand* result = directive.function(*this,directive.flags); if (result == nullptr) { if (hasError() == false) printError(tok,L"Directive parameter failure"); return nullptr; } return result; } return nullptr; }
CAssemblerCommand* Parser::parseMacroCall() { const Token& start = peekToken(); if (start.type != TokenType::Identifier) return nullptr; auto it = macros.find(start.getStringValue()); if (it == macros.end()) return nullptr; ParserMacro& macro = it->second; eatToken(); // create a token stream for the macro content, // registering replacements for parameter values TokenStreamTokenizer macroTokenizer; std::set<std::wstring> identifierParameters; for (size_t i = 0; i < macro.parameters.size(); i++) { if (i != 0) { if (nextToken().type != TokenType::Comma) return nullptr; } if (i == macro.parameters.size()) { size_t count = macro.parameters.size(); while (peekToken().type == TokenType::Comma) { eatToken(); parseExpression(); } printError(start,L"Not enough macro arguments (%d vs %d)",count,macro.parameters.size()); return nullptr; } TokenizerPosition startPos = getTokenizer()->getPosition(); Expression exp = parseExpression(); if (exp.isLoaded() == false) return nullptr; TokenizerPosition endPos = getTokenizer()->getPosition(); std::vector<Token> tokens = getTokenizer()->getTokens(startPos,endPos); // remember any single identifier parameters for the label replacement if (tokens.size() == 1 && tokens[0].type == TokenType::Identifier) identifierParameters.insert(tokens[0].getStringValue()); // give them as a replacement to new tokenizer macroTokenizer.registerReplacement(macro.parameters[i],tokens); } if (peekToken().type == TokenType::Comma) { size_t count = macro.parameters.size(); while (peekToken().type == TokenType::Comma) { eatToken(); parseExpression(); count++; } printError(start,L"Too many macro arguments (%d vs %d)",count,macro.parameters.size()); return nullptr; } // a macro is fully parsed once when it's loaded // to gather all labels. it's not necessary to // instantiate other macros at that time if (initializingMacro) return new DummyCommand(); // the first time a macro is instantiated, it needs to be analyzed // for labels if (macro.counter == 0) { initializingMacro = true; // parse the short lived next command macroTokenizer.init(macro.content); CAssemblerCommand* command = parse(¯oTokenizer,true); delete command; macro.labels = macroLabels; macroLabels.clear(); initializingMacro = false; } // register labels and replacements for (const std::wstring& label: macro.labels) { // check if the label is using the name of a parameter // in that case, don't register a unique replacement if (identifierParameters.find(label) != identifierParameters.end()) continue; // otherwise make sure the name is unique std::wstring fullName; if (Global.symbolTable.isLocalSymbol(label)) fullName = formatString(L"@@%s_%s_%08X",macro.name,label.substr(2),macro.counter); else if (Global.symbolTable.isStaticSymbol(label)) fullName = formatString(L"@%s_%s_%08X",macro.name,label.substr(1),macro.counter); else fullName = formatString(L"%s_%s_%08X",macro.name,label,macro.counter); macroTokenizer.registerReplacement(label,fullName); } macroTokenizer.init(macro.content); macro.counter++; return parse(¯oTokenizer,true); }
bool Parser::checkMacroDefinition() { const Token& first = peekToken(); if (first.type != TokenType::Identifier) return false; if (!first.stringValueStartsWith(L'.') || first.getStringValue() != L".macro") return false; eatToken(); // nested macro definitions are not allowed if (initializingMacro) { printError(first,L"Nested macro definitions not allowed"); while (!atEnd()) { const Token& token = nextToken(); if (token.type == TokenType::Identifier && token.getStringValue() == L".endmacro") break; } return true; } std::vector<Expression> parameters; if (parseExpressionList(parameters,1,-1) == false) return false; // load name std::wstring macroName; if (parameters[0].evaluateIdentifier(macroName) == false) return false; // duplicate check the macro ParserMacro ¯o = macros[macroName]; if (macro.name.length() != 0) { printError(first,L"Macro \"%s\" already defined",macro.name); return false; } // and register it macro.name = macroName; macro.counter = 0; // load parameters for (size_t i = 1; i < parameters.size(); i++) { std::wstring name; if (parameters[i].evaluateIdentifier(name) == false) return false; macro.parameters.push_back(name); } // load macro content TokenizerPosition start = getTokenizer()->getPosition(); bool valid = false; while (atEnd() == false) { const Token& tok = nextToken(); if (tok.type == TokenType::Identifier && tok.getStringValue() == L".endmacro") { valid = true; break; } } // no .endmacro, not valid if (valid == false) return true; // get content TokenizerPosition end = getTokenizer()->getPosition().previous(); macro.content = getTokenizer()->getTokens(start,end); return true; }