mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
ExpressionParser: operator precedence.
This commit is contained in:
parent
46c0ae7d1f
commit
fa75ab404f
@ -139,7 +139,7 @@ public:
|
||||
return '\'' + data + '\'';
|
||||
case TOK_VARIABLE:
|
||||
return '$' + data;
|
||||
case TOK_INVALID:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -528,7 +528,7 @@ public:
|
||||
ControlState GetValue() const override
|
||||
{
|
||||
constexpr int MAX_REPS = 10000;
|
||||
constexpr int COND_THRESHOLD = 0.5;
|
||||
constexpr ControlState COND_THRESHOLD = 0.5;
|
||||
|
||||
// Returns 1.0 on successful loop, 0.0 on reps exceeded. Sensible?
|
||||
|
||||
@ -543,7 +543,7 @@ public:
|
||||
return 0.0;
|
||||
}
|
||||
void SetValue(ControlState value) override {}
|
||||
std::string GetFuncName() const override { return "Sin"; }
|
||||
std::string GetFuncName() const override { return "While"; }
|
||||
};
|
||||
|
||||
std::unique_ptr<UnaryExpression> MakeUnaryExpression(std::string name,
|
||||
@ -782,22 +782,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool IsUnaryExpression(TokenType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TOK_UNARY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static bool IsUnaryExpression(TokenType type) { return TOK_UNARY == type; }
|
||||
|
||||
ParseResult Unary()
|
||||
{
|
||||
if (IsUnaryExpression(Peek().type))
|
||||
{
|
||||
Token tok = Chew();
|
||||
const Token tok = Chew();
|
||||
ParseResult result = Atom();
|
||||
if (result.status == ParseStatus::SyntaxError)
|
||||
return result;
|
||||
@ -807,29 +798,60 @@ private:
|
||||
return Atom();
|
||||
}
|
||||
|
||||
bool IsBinaryToken(TokenType type)
|
||||
static bool IsBinaryToken(TokenType type)
|
||||
{
|
||||
return type >= TOK_BINARY_OPS_BEGIN && type < TOK_BINARY_OPS_END;
|
||||
}
|
||||
|
||||
ParseResult Binary()
|
||||
static int BinaryOperatorPrecedence(TokenType type)
|
||||
{
|
||||
ParseResult result = Unary();
|
||||
if (result.status == ParseStatus::SyntaxError)
|
||||
return result;
|
||||
|
||||
std::unique_ptr<Expression> expr = std::move(result.expr);
|
||||
while (IsBinaryToken(Peek().type))
|
||||
switch (type)
|
||||
{
|
||||
Token tok = Chew();
|
||||
ParseResult unary_result = Unary();
|
||||
if (unary_result.status == ParseStatus::SyntaxError)
|
||||
case TOK_MUL:
|
||||
case TOK_DIV:
|
||||
case TOK_MOD:
|
||||
return 1;
|
||||
case TOK_ADD:
|
||||
case TOK_SUB:
|
||||
return 2;
|
||||
case TOK_GTHAN:
|
||||
case TOK_LTHAN:
|
||||
return 3;
|
||||
case TOK_AND:
|
||||
return 4;
|
||||
case TOK_OR:
|
||||
return 5;
|
||||
case TOK_COND:
|
||||
case TOK_ASSIGN:
|
||||
return 6;
|
||||
case TOK_COMMA:
|
||||
return 7;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ParseResult Binary(int precedence = 999)
|
||||
{
|
||||
ParseResult lhs = Unary();
|
||||
|
||||
if (lhs.status == ParseStatus::SyntaxError)
|
||||
return lhs;
|
||||
|
||||
std::unique_ptr<Expression> expr = std::move(lhs.expr);
|
||||
|
||||
// TODO: handle LTR/RTL associativity?
|
||||
while (IsBinaryToken(Peek().type) && BinaryOperatorPrecedence(Peek().type) < precedence)
|
||||
{
|
||||
const Token tok = Chew();
|
||||
ParseResult rhs = Binary(BinaryOperatorPrecedence(tok.type));
|
||||
if (rhs.status == ParseStatus::SyntaxError)
|
||||
{
|
||||
return unary_result;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
expr = std::make_unique<BinaryExpression>(tok.type, std::move(expr),
|
||||
std::move(unary_result.expr));
|
||||
expr = std::make_unique<BinaryExpression>(tok.type, std::move(expr), std::move(rhs.expr));
|
||||
}
|
||||
|
||||
return {ParseStatus::Successful, std::move(expr)};
|
||||
@ -851,7 +873,7 @@ private:
|
||||
}
|
||||
|
||||
ParseResult Toplevel() { return Binary(); }
|
||||
};
|
||||
}; // namespace ExpressionParser
|
||||
|
||||
static ParseResult ParseComplexExpression(const std::string& str)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user