Esempio n. 1
0
// 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));
	}
}
Esempio n. 2
0
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);
}
Esempio n. 3
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("*"))