ExpressionParser: replace bare pointers with unique_ptrs

This commit is contained in:
Michael M 2017-06-07 15:29:00 -07:00
parent c33e391d26
commit 3df945f8d0
3 changed files with 41 additions and 39 deletions

View File

@ -31,9 +31,7 @@ void ControlReference::UpdateReference(const ciface::Core::DeviceContainer& devi
const ciface::Core::DeviceQualifier& default_device) const ciface::Core::DeviceQualifier& default_device)
{ {
ControlFinder finder(devices, default_device, IsInput()); ControlFinder finder(devices, default_device, IsInput());
Expression* expr; std::tie(m_parse_status, m_parsed_expression) = ParseExpression(expression, finder);
std::tie(m_parse_status, expr) = ParseExpression(expression, finder);
m_parsed_expression.reset(expr);
} }
int ControlReference::BoundCount() const int ControlReference::BoundCount() const

View File

@ -253,18 +253,14 @@ class BinaryExpression : public ExpressionNode
{ {
public: public:
TokenType op; TokenType op;
ExpressionNode* lhs; std::unique_ptr<ExpressionNode> lhs;
ExpressionNode* rhs; std::unique_ptr<ExpressionNode> rhs;
BinaryExpression(TokenType op_, ExpressionNode* lhs_, ExpressionNode* rhs_) BinaryExpression(TokenType op_, std::unique_ptr<ExpressionNode>&& lhs_,
: op(op_), lhs(lhs_), rhs(rhs_) std::unique_ptr<ExpressionNode>&& rhs_)
: op(op_), lhs(std::move(lhs_)), rhs(std::move(rhs_))
{ {
} }
virtual ~BinaryExpression()
{
delete lhs;
delete rhs;
}
ControlState GetValue() const override ControlState GetValue() const override
{ {
@ -307,10 +303,12 @@ class UnaryExpression : public ExpressionNode
{ {
public: public:
TokenType op; TokenType op;
ExpressionNode* inner; std::unique_ptr<ExpressionNode> inner;
UnaryExpression(TokenType op_, ExpressionNode* inner_) : op(op_), inner(inner_) {} UnaryExpression(TokenType op_, std::unique_ptr<ExpressionNode>&& inner_)
virtual ~UnaryExpression() { delete inner; } : op(op_), inner(std::move(inner_))
{
}
ControlState GetValue() const override ControlState GetValue() const override
{ {
ControlState value = inner->GetValue(); ControlState value = inner->GetValue();
@ -363,11 +361,13 @@ Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) const
struct ParseResult struct ParseResult
{ {
ParseResult(ParseStatus status_, ExpressionNode* expr_ = nullptr) : status(status_), expr(expr_) ParseResult(ParseStatus status_, std::unique_ptr<ExpressionNode>&& expr_ = {})
: status(status_), expr(std::move(expr_))
{ {
} }
ParseStatus status; ParseStatus status;
ExpressionNode* expr; std::unique_ptr<ExpressionNode> expr;
}; };
class Parser class Parser
@ -402,9 +402,10 @@ private:
std::shared_ptr<Device> device = finder.FindDevice(tok.qualifier); std::shared_ptr<Device> device = finder.FindDevice(tok.qualifier);
Device::Control* control = finder.FindControl(tok.qualifier); Device::Control* control = finder.FindControl(tok.qualifier);
if (control == nullptr) if (control == nullptr)
return {ParseStatus::NoDevice, new DummyExpression(tok.qualifier)}; return {ParseStatus::NoDevice, std::make_unique<DummyExpression>(tok.qualifier)};
return {ParseStatus::Successful, new ControlExpression(tok.qualifier, device, control)}; return {ParseStatus::Successful,
std::make_unique<ControlExpression>(tok.qualifier, device, control)};
} }
case TOK_LPAREN: case TOK_LPAREN:
return Paren(); return Paren();
@ -432,7 +433,8 @@ private:
ParseResult result = Atom(); ParseResult result = Atom();
if (result.status == ParseStatus::SyntaxError) if (result.status == ParseStatus::SyntaxError)
return result; return result;
return {ParseStatus::Successful, new UnaryExpression(tok.type, result.expr)}; return {ParseStatus::Successful,
std::make_unique<UnaryExpression>(tok.type, std::move(result.expr))};
} }
return Atom(); return Atom();
@ -457,21 +459,21 @@ private:
if (result.status == ParseStatus::SyntaxError) if (result.status == ParseStatus::SyntaxError)
return result; return result;
ExpressionNode* expr = result.expr; std::unique_ptr<ExpressionNode> expr = std::move(result.expr);
while (IsBinaryToken(Peek().type)) while (IsBinaryToken(Peek().type))
{ {
Token tok = Chew(); Token tok = Chew();
ParseResult unary_result = Unary(); ParseResult unary_result = Unary();
if (unary_result.status == ParseStatus::SyntaxError) if (unary_result.status == ParseStatus::SyntaxError)
{ {
delete expr;
return unary_result; return unary_result;
} }
expr = new BinaryExpression(tok.type, expr, unary_result.expr); expr = std::make_unique<BinaryExpression>(tok.type, std::move(expr),
std::move(unary_result.expr));
} }
return {ParseStatus::Successful, expr}; return {ParseStatus::Successful, std::move(expr)};
} }
ParseResult Paren() ParseResult Paren()
@ -483,7 +485,6 @@ private:
if (!Expects(TOK_RPAREN)) if (!Expects(TOK_RPAREN))
{ {
delete result.expr;
return {ParseStatus::SyntaxError}; return {ParseStatus::SyntaxError};
} }
@ -503,19 +504,19 @@ void Expression::SetValue(ControlState value)
node->SetValue(value); node->SetValue(value);
} }
Expression::Expression(ExpressionNode* node_) Expression::Expression(std::unique_ptr<ExpressionNode>&& node_)
{ {
node = node_; node = std::move(node_);
num_controls = node->CountNumControls(); if (node)
num_controls = node->CountNumControls();
} }
Expression::~Expression() Expression::~Expression()
{ {
delete node;
} }
static std::pair<ParseStatus, Expression*> ParseExpressionInner(const std::string& str, static std::pair<ParseStatus, std::unique_ptr<Expression>>
ControlFinder& finder) ParseExpressionInner(const std::string& str, ControlFinder& finder)
{ {
if (str == "") if (str == "")
return std::make_pair(ParseStatus::Successful, nullptr); return std::make_pair(ParseStatus::Successful, nullptr);
@ -530,10 +531,12 @@ static std::pair<ParseStatus, Expression*> ParseExpressionInner(const std::strin
if (result.status != ParseStatus::Successful) if (result.status != ParseStatus::Successful)
return std::make_pair(result.status, nullptr); return std::make_pair(result.status, nullptr);
return std::make_pair(ParseStatus::Successful, new Expression(result.expr)); return std::make_pair(ParseStatus::Successful,
std::make_unique<Expression>(std::move(result.expr)));
} }
std::pair<ParseStatus, Expression*> ParseExpression(const std::string& str, ControlFinder& finder) std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& str,
ControlFinder& finder)
{ {
// Add compatibility with old simple expressions, which are simple // Add compatibility with old simple expressions, which are simple
// barewords control names. // barewords control names.
@ -546,8 +549,9 @@ std::pair<ParseStatus, Expression*> ParseExpression(const std::string& str, Cont
Device::Control* control = finder.FindControl(qualifier); Device::Control* control = finder.FindControl(qualifier);
if (control) if (control)
{ {
Expression* expr = new Expression(new ControlExpression(qualifier, device, control)); return std::make_pair(ParseStatus::Successful,
return std::make_pair(ParseStatus::Successful, expr); std::make_unique<Expression>(
std::make_unique<ControlExpression>(qualifier, device, control)));
} }
return ParseExpressionInner(str, finder); return ParseExpressionInner(str, finder);

View File

@ -51,13 +51,12 @@ class ExpressionNode;
class Expression class Expression
{ {
public: public:
Expression() : node(nullptr) {} explicit Expression(std::unique_ptr<ExpressionNode>&& node = {});
Expression(ExpressionNode* node);
~Expression(); ~Expression();
ControlState GetValue() const; ControlState GetValue() const;
void SetValue(ControlState state); void SetValue(ControlState state);
int num_controls; int num_controls;
ExpressionNode* node; std::unique_ptr<ExpressionNode> node;
}; };
enum class ParseStatus enum class ParseStatus
@ -67,6 +66,7 @@ enum class ParseStatus
NoDevice, NoDevice,
}; };
std::pair<ParseStatus, Expression*> ParseExpression(const std::string& expr, ControlFinder& finder); std::pair<ParseStatus, std::unique_ptr<Expression>> ParseExpression(const std::string& expr,
ControlFinder& finder);
} }
} }