ExpressionParser: expose ExpressionNode directly

This commit is contained in:
Michael M 2017-06-07 17:30:07 -07:00
parent 85301e2bae
commit 7e74961eb1
3 changed files with 26 additions and 64 deletions

View File

@ -37,7 +37,7 @@ void ControlReference::UpdateReference(const ciface::Core::DeviceContainer& devi
int ControlReference::BoundCount() const int ControlReference::BoundCount() const
{ {
if (m_parsed_expression) if (m_parsed_expression)
return m_parsed_expression->num_controls; return m_parsed_expression->CountNumControls();
else else
return 0; return 0;
} }

View File

@ -208,17 +208,7 @@ public:
} }
}; };
class ExpressionNode class ControlExpression : public Expression
{
public:
virtual ~ExpressionNode() {}
virtual ControlState GetValue() const { return 0; }
virtual void SetValue(ControlState state) {}
virtual int CountNumControls() const { return 0; }
virtual operator std::string() const { return ""; }
};
class ControlExpression : public ExpressionNode
{ {
public: public:
ControlQualifier qualifier; ControlQualifier qualifier;
@ -242,15 +232,15 @@ public:
operator std::string() const override { return "`" + static_cast<std::string>(qualifier) + "`"; } operator std::string() const override { return "`" + static_cast<std::string>(qualifier) + "`"; }
}; };
class BinaryExpression : public ExpressionNode class BinaryExpression : public Expression
{ {
public: public:
TokenType op; TokenType op;
std::unique_ptr<ExpressionNode> lhs; std::unique_ptr<Expression> lhs;
std::unique_ptr<ExpressionNode> rhs; std::unique_ptr<Expression> rhs;
BinaryExpression(TokenType op_, std::unique_ptr<ExpressionNode>&& lhs_, BinaryExpression(TokenType op_, std::unique_ptr<Expression>&& lhs_,
std::unique_ptr<ExpressionNode>&& rhs_) std::unique_ptr<Expression>&& rhs_)
: op(op_), lhs(std::move(lhs_)), rhs(std::move(rhs_)) : op(op_), lhs(std::move(lhs_)), rhs(std::move(rhs_))
{ {
} }
@ -292,13 +282,13 @@ public:
} }
}; };
class UnaryExpression : public ExpressionNode class UnaryExpression : public Expression
{ {
public: public:
TokenType op; TokenType op;
std::unique_ptr<ExpressionNode> inner; std::unique_ptr<Expression> inner;
UnaryExpression(TokenType op_, std::unique_ptr<ExpressionNode>&& inner_) UnaryExpression(TokenType op_, std::unique_ptr<Expression>&& inner_)
: op(op_), inner(std::move(inner_)) : op(op_), inner(std::move(inner_))
{ {
} }
@ -354,13 +344,13 @@ Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) const
struct ParseResult struct ParseResult
{ {
ParseResult(ParseStatus status_, std::unique_ptr<ExpressionNode>&& expr_ = {}) ParseResult(ParseStatus status_, std::unique_ptr<Expression>&& expr_ = {})
: status(status_), expr(std::move(expr_)) : status(status_), expr(std::move(expr_))
{ {
} }
ParseStatus status; ParseStatus status;
std::unique_ptr<ExpressionNode> expr; std::unique_ptr<Expression> expr;
}; };
class Parser class Parser
@ -449,7 +439,7 @@ private:
if (result.status == ParseStatus::SyntaxError) if (result.status == ParseStatus::SyntaxError)
return result; return result;
std::unique_ptr<ExpressionNode> expr = std::move(result.expr); std::unique_ptr<Expression> expr = std::move(result.expr);
while (IsBinaryToken(Peek().type)) while (IsBinaryToken(Peek().type))
{ {
Token tok = Chew(); Token tok = Chew();
@ -484,45 +474,19 @@ private:
ParseResult Toplevel() { return Binary(); } ParseResult Toplevel() { return Binary(); }
}; };
ControlState Expression::GetValue() const static ParseResult ParseExpressionInner(const std::string& str, ControlFinder& finder)
{
return node->GetValue();
}
void Expression::SetValue(ControlState value)
{
node->SetValue(value);
}
Expression::Expression(std::unique_ptr<ExpressionNode>&& node_)
{
node = std::move(node_);
if (node)
num_controls = node->CountNumControls();
}
Expression::~Expression()
{
}
static std::pair<ParseStatus, std::unique_ptr<Expression>>
ParseExpressionInner(const std::string& str, ControlFinder& finder)
{ {
if (StripSpaces(str).empty()) if (StripSpaces(str).empty())
return std::make_pair(ParseStatus::EmptyExpression, nullptr); return {ParseStatus::EmptyExpression};
Lexer l(str); Lexer l(str);
std::vector<Token> tokens; std::vector<Token> tokens;
ParseStatus tokenize_status = l.Tokenize(tokens); ParseStatus tokenize_status = l.Tokenize(tokens);
if (tokenize_status != ParseStatus::Successful) if (tokenize_status != ParseStatus::Successful)
return std::make_pair(tokenize_status, nullptr); return {tokenize_status};
ParseResult result = Parser(tokens, finder).Parse(); ParseResult result = Parser(tokens, finder).Parse();
if (result.status != ParseStatus::Successful) return result;
return std::make_pair(result.status, nullptr);
return std::make_pair(ParseStatus::Successful,
std::make_unique<Expression>(std::move(result.expr)));
} }
std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& str, std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& str,
@ -539,12 +503,12 @@ std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::s
Device::Control* control = finder.FindControl(qualifier); Device::Control* control = finder.FindControl(qualifier);
if (control) if (control)
{ {
return std::make_pair(ParseStatus::Successful, return std::make_pair(ParseStatus::Successful, std::make_unique<ControlExpression>(
std::make_unique<Expression>(std::make_unique<ControlExpression>( qualifier, std::move(device), control));
qualifier, std::move(device), control)));
} }
return ParseExpressionInner(str, finder); ParseResult result = ParseExpressionInner(str, finder);
return std::make_pair(result.status, std::move(result.expr));
} }
} }
} }

View File

@ -47,16 +47,14 @@ private:
bool is_input; bool is_input;
}; };
class ExpressionNode;
class Expression class Expression
{ {
public: public:
explicit Expression(std::unique_ptr<ExpressionNode>&& node = {}); virtual ~Expression() = default;
~Expression(); virtual ControlState GetValue() const = 0;
ControlState GetValue() const; virtual void SetValue(ControlState state) = 0;
void SetValue(ControlState state); virtual int CountNumControls() const = 0;
int num_controls; virtual operator std::string() const = 0;
std::unique_ptr<ExpressionNode> node;
}; };
enum class ParseStatus enum class ParseStatus