// binoprhs // ::= ('+' unary)* std::unique_ptr<CExprAST> CParser::ParseBinOpRHS(int precedence, std::unique_ptr<CExprAST> lhs) { // If this is a binary operation, find its precedence while (true) { int p = GetTokenPrecedence(); // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done if (p < precedence) return lhs; int binop = m_CurrentToken; GetNextToken(); // eating that binop // Parsing unary expression after the binary operator auto rhs = ParseUnary(); if (!rhs) return nullptr; // If binop binds less tightly that the operator after rhs, // let the pending operator take rhs as it lhs int nextp = GetTokenPrecedence(); if (p < nextp) { rhs = ParseBinOpRHS(p + 1, std::move(rhs)); if (!rhs) return nullptr; } // Merge lhs/rhs lhs = std::make_unique<CBinaryExprAST>(binop, std::move(lhs), std::move(rhs)); } }
ASTExpression* ParseExpr(MemoryArena* arena, Lexer* lex) { auto parsePrimary = [](MemoryArena* arena, Lexer* lex) -> ASTExpression* { switch (lex->token.type) { case TOKEN_TRUE: { lex->nextToken(); return CreateIntegerLiteral(arena, 1); } case TOKEN_FALSE: { lex->nextToken(); return CreateIntegerLiteral(arena, 0); } case TOKEN_STRING: { auto str = CreateStringLiteral (arena, lex->token.string); lex->nextToken(); return str; } case TOKEN_NUMBER: { LOG_VERBOSE("Parsing a numberExpression!"); auto dotPos = lex->token.string.find("."); bool isFloat = dotPos == std::string::npos ? false : true; if (isFloat) { if (lex->token.string.substr(dotPos + 1).find(".") != std::string::npos) { // ReportError(worker, worker->token.site, "Floating Point value contains two decimal points!"); } auto value = std::stof(lex->token.string); auto result = CreateFloatLiteral(arena, value); lex->nextToken(); return result; } else { auto value = std::stoi(lex->token.string); auto result = CreateIntegerLiteral(arena, value); lex->nextToken(); return result; } } } return nullptr; }; std::function<ASTExpression*(MemoryArena*, Lexer*, ASTExpression*, int)> parseBinary = [&parsePrimary, &parseBinary](MemoryArena* arena, Lexer* lex, ASTExpression* lhs, int expressionPrec) -> ASTExpression* { assert(lhs != nullptr); while (true) { auto tokenPrec = GetTokenPrecedence(lex->token); if (tokenPrec < 0) return lhs; // Bail if there is no binop auto binopToken = lex->token; lex->nextToken(); // We have a binop lets see what is on the other side! ASTExpression* rhs = parsePrimary(arena, lex); if (rhs == nullptr) { //ReportError(worker, binopToken.site, "Could not parse primary expression to the right of binary opperator '" + binopToken.string + "'"); return nullptr; } auto nextPrec = GetTokenPrecedence (lex->token); if (tokenPrec < nextPrec) { rhs = parseBinary(arena, lex, rhs, tokenPrec + 1); if (rhs == nullptr) { LOG_ERROR("Could not parse recursive rhsParsing!"); return nullptr; } } lhs = (ASTExpression*)CreateBinaryOperation(arena, TokenToOperation(binopToken), lhs, rhs); } // Goes back to the while loop }; auto lhs = parsePrimary(arena, lex); if (lhs == nullptr) return nullptr; return parseBinary(arena, lex, lhs, 0); }
BOOL CodeTokenizer::GetNextTokenEval(String &token, BOOL *bFloatOccurance, int curPrecedence) { TSTR lpLastSafePos = lpTemp; String curVal, curToken; BOOL bFoundNumber = FALSE; BOOL bUsedBracers = FALSE; if(!GetNextToken(curToken)) return FALSE; if(curToken == TEXT("(")) { TSTR lpPrevPos = lpTemp; int newPrecedence = GetTokenPrecedence(curToken); if(!GetNextTokenEval(curToken, bFloatOccurance, newPrecedence)) return FALSE; if(!ValidFloatString(curToken)) { lpTemp = lpPrevPos; token = TEXT("("); return TRUE; } String nextToken; if(!GetNextToken(nextToken)) return FALSE; if(nextToken != TEXT(")")) { lpTemp = lpPrevPos; token = TEXT("("); return TRUE; } bUsedBracers = TRUE; } if(curToken == TEXT("-") && iswdigit(*lpTemp)) { String nextToken; if(!GetNextToken(nextToken)) return FALSE; curToken << nextToken; } if(ValidFloatString(curToken)) { bFoundNumber = TRUE; curVal = curToken; if(!ValidIntString(curVal) && bFloatOccurance) *bFloatOccurance = TRUE; } else { if(bFoundNumber) { lpTemp = lpLastSafePos; token = curVal; return TRUE; } else { token = curToken; return TRUE; } } lpLastSafePos = lpTemp; String operatorToken; while(GetNextToken(operatorToken)) { int newPrecedence = GetTokenPrecedence(operatorToken); if(newPrecedence <= curPrecedence) { lpTemp = lpLastSafePos; token = curVal; return TRUE; } String nextVal; if(!GetNextTokenEval(nextVal, bFloatOccurance, newPrecedence)) return FALSE; if(!ValidFloatString(nextVal)) { lpTemp = lpLastSafePos; token = curVal; return TRUE; } if(operatorToken == TEXT("<<")) { int val1 = tstoi(curVal); int val2 = tstoi(nextVal); val1 <<= val2; curVal = IntString(val1); } else if(operatorToken == TEXT(">>")) { int val1 = tstoi(curVal); int val2 = tstoi(nextVal); val1 >>= val2; curVal = IntString(val1); } else if(operatorToken == TEXT("*"))