Skip to content

Commit

Permalink
Checkpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Jul 27, 2020
1 parent 4a9605e commit 88095bc
Show file tree
Hide file tree
Showing 11 changed files with 731 additions and 39 deletions.
7 changes: 0 additions & 7 deletions filters/private/expr/AssignExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,11 @@ namespace expr
class AssignExpression : public Expression
{
public:
AssignExpression();
AssignExpression(const Expression& expr);
AssignExpression& operator=(const Expression& expr);
~AssignExpression();

bool parse(const std::string& s);
Utils::StatusWithReason prepare(PointLayoutPtr layout);
Expression& valueExpr();
Expression& conditionalExpr();

private:
std::string m_error;
Expression m_valueExpr;
Expression m_conditionalExpr;

Expand Down
111 changes: 105 additions & 6 deletions filters/private/expr/AssignParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace pdal
namespace expr
{

bool AssignParser::parse(const std::string& s, AssignExpression& expr)
bool AssignParser::parse(AssignExpression& expr, Lexer& lexer)
{
m_expression.clear();

Expand Down Expand Up @@ -41,7 +41,8 @@ bool AssignParser::assignment(AssignExpession& expr)
return false;
}

if (!valueexpr(expr.valueExpr()))
MathParser parser(m_lexer);
if (!parser.expression(expr));
{
setError("No value for assignment.");
return false;
Expand All @@ -64,15 +65,66 @@ bool AssignParser::where(AssignExpression& expr)
return false;
}
}
return expression(expr.conditionalExpr());
ConditionalParser parser(m_lexer);
return parser.expression(expr);
}

bool AssignParser::valueexpr(Expression& expr)

bool MathParser::valueexpr(Expression& expr)
{
return addexpr(expr);
}

bool AssignParser::multexpr(Expression& expr)
bool MathParser::addexpr(Expression& expr)
{
if (!multexpr(expr))
return false;

while (true)
{
NodeType type;

if (match(TokenType::Plus))
type = NodeType::Add;
else if (match(TokenType::Dash))
type = NodeType::Subtract;
else
return true;

if (!multexpr(expr))
{
setError("Expected expression following '" +
curToken().sval() + "'.");
return false;
}

NodePtr right = expr.popNode();
NodePtr left = expr.popNode();

ConstValueNode *leftVal = dynamic_cast<ConstValueNode *>(left.get());
ConstValueNode *rightVal = dynamic_cast<ConstValueNode *>(right.get());
if (leftVal && rightVal)
{
double v = (type == NodeType::Add) ?
leftVal->value() + rightVal->value() :
leftVal->value() - rightVal->value();
expr.pushNode(NodePtr(new ConstValueNode(v)));
}
else
{
if (left->isBool() || right->isBool())
{
setError("Can't apply '" + curToken().sval() + "' to "
"logical expression.");
return false;
}
expr.pushNode(NodePtr(new BinMathNode(type, std::move(left), std::move(right))));
}
}
return true;
}

bool MathParser::multexpr(Expression& expr)
{
if (!uminus(expr))
return false;
Expand Down Expand Up @@ -130,7 +182,54 @@ bool AssignParser::multexpr(Expression& expr)
return true;
}

bool AssignParser::parexpr(Expression& expr)
bool MathParser::uminus(Expression& expr)
{
if (!match(TokenType::Dash))
return primary(expr);

if (!primary(expr))
{
setError("Expecting expression following '-'.");
return false;
}

NodePtr sub = expr.popNode();
ConstValueNode *node = dynamic_cast<ConstValueNode *>(sub.get());
if (node)
{
double v = -(node->value());
expr.pushNode(NodePtr(new ConstValueNode(v)));
}
else
{
if (node->isBool())
{
setError("Can't apply '-' to logical expression '" +
sub->print() + "'.");
return false;
}
expr.pushNode(NodePtr(new UnMathNode(NodeType::Negative, std::move(sub))));
}
return true;
}

bool MathParser::primary(Expression& expr)
{
if (match(TokenType::Number))
{
expr.pushNode(NodePtr(new ConstValueNode(curToken().dval())));
return true;
}
else if (match(TokenType::Identifier))
{
expr.pushNode(NodePtr(new VarNode(curToken().sval())));
return true;
}

return parexpr(expr);
}

bool MathParser::parexpr(Expression& expr)
{
if (!match(TokenType::Lparen))
return false;
Expand Down
52 changes: 52 additions & 0 deletions filters/private/expr/BaseParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "Parser.hpp"

namespace pdal
{
namespace expr
{

bool Parser::parse(Expression& expr)
{
m_lexer.reset(s);
m_error.clear();

expr.clear();
bool ok = expression(expr);
if (ok)
{
// If we're at the end, we should have exhausted all tokens.
Token tok = m_lexer.get();
if (tok != TokenType::Eof)
{
m_error = "Found '" + tok.sval() + "' after valid expression.";
return false;
}
}
return ok;
}

Token Parser::curToken() const
{
return m_curTok;
}

bool Parser::match(TokenType type)
{
Token t = m_lexer.get();
if (t.type() == type)
{
m_curTok = t;
return true;
}
m_lexer.put(t);
return false;
}

void Parser::setError(const std::string& err)
{
if (m_error.empty())
m_error = err;
}

} // namespace expr
} // namespace pdal
41 changes: 41 additions & 0 deletions filters/private/expr/BaseParser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <queue>
#include <stack>
#include <iostream>
#include <iomanip>

#include "Lexer.hpp"
#include "Expression.hpp"

namespace pdal
{
namespace expr
{

class BaseParser
{
public:
Parser(Lexer& lexer) : m_lexer(lexer)
{}

bool parse(Expression& expr);
std::string error() const
{ return m_error; }

protected:
bool match(TokenType type);
Token curToken() const;
Token lastToken() const;
void setError(const std::string& err);
Lexer& lexer()
{ return m_lexer; }

private:
Lexer& m_lexer;
Token m_curTok;
std::string m_error;
};

} // namespace expr
} // namespace pdal

0 comments on commit 88095bc

Please sign in to comment.