Expression: split Expression.h to ExpressionParser.h
Split Expression details into a separate header to reduce recompilation time on changes.
This commit is contained in:
@@ -108,7 +108,7 @@
|
||||
#include "Origin.h"
|
||||
#include "MaterialObject.h"
|
||||
#include "TextDocument.h"
|
||||
#include "Expression.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include "Transactions.h"
|
||||
#include <App/MaterialPy.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
|
||||
@@ -184,6 +184,7 @@ SET(Document_HPP_SRCS
|
||||
DocumentObserver.h
|
||||
DocumentObserverPython.h
|
||||
Expression.h
|
||||
ExpressionParser.h
|
||||
ExpressionVisitors.h
|
||||
FeatureCustom.h
|
||||
FeaturePython.h
|
||||
|
||||
@@ -95,6 +95,7 @@ recompute path. Also, it enables more complicated dependencies beyond trees.
|
||||
#include "Application.h"
|
||||
#include "DocumentObject.h"
|
||||
#include "MergeDocuments.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include <App/DocumentPy.h>
|
||||
|
||||
#include <Base/Console.h>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <Base/MatrixPy.h>
|
||||
#include "DocumentObject.h"
|
||||
#include "Document.h"
|
||||
#include "Expression.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include "GeoFeature.h"
|
||||
#include "GroupExtension.h"
|
||||
#include "GeoFeatureGroupExtension.h"
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include <stack>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include "Expression.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include <Base/Unit.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <App/ObjectIdentifier.h>
|
||||
@@ -2385,13 +2385,13 @@ Py::Object PyObjectExpression::getPyValue() const {
|
||||
return Py::Object(pyObj);
|
||||
}
|
||||
|
||||
void PyObjectExpression::setPyObject(Py::Object obj) {
|
||||
void PyObjectExpression::setPyValue(Py::Object obj) {
|
||||
Py::_XDECREF(pyObj);
|
||||
pyObj = obj.ptr();
|
||||
Py::_XINCREF(pyObj);
|
||||
}
|
||||
|
||||
void PyObjectExpression::setPyObject(PyObject *obj, bool owned) {
|
||||
void PyObjectExpression::setPyValue(PyObject *obj, bool owned) {
|
||||
if(pyObj == obj)
|
||||
return;
|
||||
Py::_XDECREF(pyObj);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <deque>
|
||||
#include <App/Range.h>
|
||||
|
||||
//FIXME: PyObjectExpression hides overloaded virtual functions
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Woverloaded-virtual"
|
||||
@@ -203,490 +202,6 @@ public:
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
/**
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport UnitExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
UnitExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & _quantity = Base::Quantity(), const std::string & _unitStr = std::string());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
void setUnit(const Base::Quantity &_quantity);
|
||||
|
||||
double getValue() const { return quantity.getValue(); }
|
||||
|
||||
const Base::Unit & getUnit() const { return quantity.getUnit(); }
|
||||
|
||||
const Base::Quantity & getQuantity() const { return quantity; }
|
||||
|
||||
const std::string getUnitString() const { return unitStr; }
|
||||
|
||||
double getScaler() const { return quantity.getValue(); }
|
||||
|
||||
boost::any getValueAsAny() const { return quantity.getUnit().isEmpty() ? boost::any(quantity.getValue()) : boost::any(quantity); }
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
Base::Quantity quantity;
|
||||
std::string unitStr; /**< The unit string from the original parsed string */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a number with an optional unit
|
||||
*/
|
||||
|
||||
class AppExport NumberExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
NumberExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & quantity = Base::Quantity());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
void negate();
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
bool isInteger(long *v=0) const;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class AppExport ConstantExpression : public NumberExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConstantExpression(const App::DocumentObject *_owner = 0, std::string _name = "", const Base::Quantity &_quantity = Base::Quantity());
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
std::string getName() const { return name; }
|
||||
|
||||
protected:
|
||||
std::string name; /**< Constant's name */
|
||||
};
|
||||
|
||||
class AppExport BooleanExpression : public NumberExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
BooleanExpression(const App::DocumentObject *_owner = 0, bool _value = false);
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport OperatorExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Operator {
|
||||
NONE,
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
MOD,
|
||||
POW,
|
||||
EQ,
|
||||
NEQ,
|
||||
LT,
|
||||
GT,
|
||||
LTE,
|
||||
GTE,
|
||||
UNIT,
|
||||
NEG,
|
||||
POS
|
||||
};
|
||||
OperatorExpression(const App::DocumentObject *_owner = 0, Expression * _left = 0, Operator _op = NONE, Expression * _right = 0);
|
||||
|
||||
virtual ~OperatorExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual void _visit(ExpressionVisitor & v);
|
||||
|
||||
Operator getOperator() const { return op; }
|
||||
|
||||
Expression * getLeft() const { return left; }
|
||||
|
||||
Expression * getRight() const { return right; }
|
||||
|
||||
virtual boost::any getValueAsAny() const;
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool isCommutative() const;
|
||||
|
||||
virtual bool isLeftAssociative() const;
|
||||
|
||||
virtual bool isRightAssociative() const;
|
||||
|
||||
Operator op; /**< Operator working on left and right */
|
||||
Expression * left; /**< Left operand */
|
||||
Expression * right; /**< Right operand */
|
||||
};
|
||||
|
||||
class AppExport ConditionalExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConditionalExpression(const App::DocumentObject *_owner = 0, Expression * _condition = 0,Expression * _trueExpr = 0, Expression * _falseExpr = 0);
|
||||
|
||||
virtual ~ConditionalExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const;
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const;
|
||||
virtual void _visit(ExpressionVisitor & v);
|
||||
bool evalCond() const;
|
||||
|
||||
protected:
|
||||
|
||||
Expression * condition; /**< Condition */
|
||||
Expression * trueExpr; /**< Expression if abs(condition) is > 0.5 */
|
||||
Expression * falseExpr; /**< Expression if abs(condition) is < 0.5 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport FunctionExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Function {
|
||||
NONE,
|
||||
|
||||
// Normal functions taking one or two arguments
|
||||
ACOS,
|
||||
ASIN,
|
||||
ATAN,
|
||||
ABS,
|
||||
EXP,
|
||||
LOG,
|
||||
LOG10,
|
||||
SIN,
|
||||
SINH,
|
||||
TAN,
|
||||
TANH,
|
||||
SQRT,
|
||||
COS,
|
||||
COSH,
|
||||
ATAN2,
|
||||
MOD,
|
||||
POW,
|
||||
ROUND,
|
||||
TRUNC,
|
||||
CEIL,
|
||||
FLOOR,
|
||||
HYPOT,
|
||||
CATH,
|
||||
|
||||
// Aggregates
|
||||
AGGREGATES,
|
||||
|
||||
SUM,
|
||||
AVERAGE,
|
||||
STDDEV,
|
||||
COUNT,
|
||||
MIN,
|
||||
MAX,
|
||||
|
||||
// Last one
|
||||
LAST,
|
||||
};
|
||||
|
||||
FunctionExpression(const App::DocumentObject *_owner = 0, Function _f = NONE, std::vector<Expression *> _args = std::vector<Expression*>());
|
||||
|
||||
virtual ~FunctionExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual void _visit(ExpressionVisitor & v);
|
||||
|
||||
virtual boost::any getValueAsAny() const;
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
|
||||
protected:
|
||||
Expression *evalAggregate() const;
|
||||
|
||||
Function f; /**< Function to execute */
|
||||
std::vector<Expression *> args; /** Arguments to function*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a reference to a property. If the name is unqualified,
|
||||
* the owner of the expression is searched. If it is qualified, the document
|
||||
* that contains the owning document object is searched for other document
|
||||
* objects to search. Both labels and internal document names are searched.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport VariableExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
VariableExpression(const App::DocumentObject *_owner = 0, ObjectIdentifier _var = ObjectIdentifier());
|
||||
|
||||
~VariableExpression();
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
std::string name() const { return var.getPropertyName(); }
|
||||
|
||||
ObjectIdentifier getPath() const { return var; }
|
||||
|
||||
void setPath(const ObjectIdentifier & path);
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const;
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
virtual void _getDeps(ExpressionDeps &) const;
|
||||
virtual void _getDepObjects(std::set<App::DocumentObject*> &, std::vector<std::string> *) const;
|
||||
virtual void _getIdentifiers(std::set<App::ObjectIdentifier> &) const;
|
||||
virtual bool _adjustLinks(const std::set<App::DocumentObject*> &, ExpressionVisitor &);
|
||||
virtual void _importSubNames(const ObjectIdentifier::SubNameMap &);
|
||||
virtual void _updateLabelReference(App::DocumentObject *, const std::string &, const char *);
|
||||
virtual bool _updateElementReference(App::DocumentObject *,bool,ExpressionVisitor &);
|
||||
virtual bool _relabeledDocument(const std::string &, const std::string &, ExpressionVisitor &);
|
||||
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &);
|
||||
virtual void _collectReplacement(std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const App::DocumentObject *parent, App::DocumentObject *oldObj,
|
||||
App::DocumentObject *newObj) const;
|
||||
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &);
|
||||
virtual void _offsetCells(int, int, ExpressionVisitor &);
|
||||
|
||||
protected:
|
||||
|
||||
ObjectIdentifier var; /**< Variable name */
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport PyObjectExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
PyObjectExpression(const App::DocumentObject *_owner=0, PyObject *pyobj=0, bool owned=false)
|
||||
:Expression(_owner)
|
||||
{
|
||||
setPyObject(pyobj,owned);
|
||||
}
|
||||
|
||||
virtual ~PyObjectExpression();
|
||||
|
||||
void setPyObject(Py::Object pyobj);
|
||||
void setPyObject(PyObject *pyobj, bool owned=false);
|
||||
|
||||
virtual std::string toString(bool) const;
|
||||
virtual boost::any getValueAsAny() const;
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
virtual Expression * eval() const { return copy(); }
|
||||
virtual Expression * simplify() const { return copy(); }
|
||||
|
||||
protected:
|
||||
virtual Expression* _copy() const;
|
||||
|
||||
protected:
|
||||
PyObject *pyObj = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a string. Used to signal either a genuine string or
|
||||
* a failed evaluation of an expression.
|
||||
*/
|
||||
|
||||
class AppExport StringExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
StringExpression(const App::DocumentObject *_owner = 0, const std::string & _text = std::string());
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual Expression * simplify() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual std::string getText() const { return text; }
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const;
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const;
|
||||
|
||||
std::string text; /**< Text string */
|
||||
};
|
||||
|
||||
class AppExport RangeExpression : public App::Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
RangeExpression(const App::DocumentObject * _owner = 0, const std::string & begin = std::string(), const std::string & end = std::string());
|
||||
|
||||
virtual ~RangeExpression() { }
|
||||
|
||||
virtual bool isTouched() const;
|
||||
|
||||
virtual Expression * eval() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
virtual int priority() const;
|
||||
|
||||
virtual App::Expression * simplify() const;
|
||||
|
||||
Range getRange() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const { return boost::any(); }
|
||||
|
||||
virtual Py::Object getPyValue() const;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const;
|
||||
virtual void _getDeps(ExpressionDeps &) const;
|
||||
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &);
|
||||
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &);
|
||||
virtual void _offsetCells(int, int, ExpressionVisitor &);
|
||||
|
||||
protected:
|
||||
std::string begin;
|
||||
std::string end;
|
||||
};
|
||||
|
||||
namespace ExpressionParser {
|
||||
AppExport Expression * parse(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport ObjectIdentifier parsePath(const App::DocumentObject *owner, const char* buffer);
|
||||
AppExport bool isTokenAnIndentifier(const std::string & str);
|
||||
AppExport bool isTokenAUnit(const std::string & str);
|
||||
AppExport std::vector<boost::tuple<int, int, std::string> > tokenize(const std::string & str);
|
||||
|
||||
/// Convenient class to mark begin of importing
|
||||
class AppExport ExpressionImporter {
|
||||
public:
|
||||
ExpressionImporter(Base::XMLReader &reader);
|
||||
~ExpressionImporter();
|
||||
static Base::XMLReader *reader();
|
||||
};
|
||||
|
||||
AppExport bool isModuleImported(PyObject *);
|
||||
|
||||
/**
|
||||
* @brief The semantic_type class encapsulates the value in the parse tree during parsing.
|
||||
*/
|
||||
|
||||
class semantic_type {
|
||||
public:
|
||||
struct {
|
||||
Base::Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression * expr;
|
||||
ObjectIdentifier path;
|
||||
std::deque<ObjectIdentifier::Component> components;
|
||||
long long int ivalue;
|
||||
double fvalue;
|
||||
struct {
|
||||
std::string name;
|
||||
double fvalue = 0;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
std::vector<Expression*> list;
|
||||
std::string string;
|
||||
FunctionExpression::Function func;
|
||||
ObjectIdentifier::String string_or_identifier;
|
||||
semantic_type() : expr(0), ivalue(0), fvalue(0), func(FunctionExpression::NONE) {}
|
||||
};
|
||||
|
||||
#define YYSTYPE semantic_type
|
||||
#include "ExpressionParser.tab.h"
|
||||
#undef YYTOKENTYPE
|
||||
#undef YYSTYPE
|
||||
#undef YYSTYPE_ISDECLARED
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
527
src/App/ExpressionParser.h
Normal file
527
src/App/ExpressionParser.h
Normal file
@@ -0,0 +1,527 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2015 Eivind Kvedalen (eivind@kvedalen.name) *
|
||||
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef EXPRESSION_PARSER_H
|
||||
#define EXPRESSION_PARSER_H
|
||||
|
||||
#include <Base/Interpreter.h>
|
||||
#include "Expression.h"
|
||||
|
||||
namespace App {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expecting the extended expression is going to be constantly amended (to
|
||||
// conform to Python), we move most of the class declarations here to avoid
|
||||
// constant recompiling of the whole FC code base, as the expression header is
|
||||
// included by everyone
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport UnitExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
UnitExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & _quantity = Base::Quantity(), const std::string & _unitStr = std::string());
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
void setUnit(const Base::Quantity &_quantity);
|
||||
|
||||
double getValue() const { return quantity.getValue(); }
|
||||
|
||||
const Base::Unit & getUnit() const { return quantity.getUnit(); }
|
||||
|
||||
const Base::Quantity & getQuantity() const { return quantity; }
|
||||
|
||||
const std::string getUnitString() const { return unitStr; }
|
||||
|
||||
double getScaler() const { return quantity.getValue(); }
|
||||
|
||||
boost::any getValueAsAny() const override { return quantity.getUnit().isEmpty() ? boost::any(quantity.getValue()) : boost::any(quantity); }
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
protected:
|
||||
Base::Quantity quantity;
|
||||
std::string unitStr; /**< The unit string from the original parsed string */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a number with an optional unit
|
||||
*/
|
||||
|
||||
class AppExport NumberExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
NumberExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & quantity = Base::Quantity());
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
void negate();
|
||||
|
||||
virtual std::string toString(bool persistent=false) const;
|
||||
|
||||
bool isInteger(long *v=0) const;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
};
|
||||
|
||||
class AppExport ConstantExpression : public NumberExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConstantExpression(const App::DocumentObject *_owner = 0, std::string _name = "", const Base::Quantity &_quantity = Base::Quantity());
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
std::string getName() const { return name; }
|
||||
|
||||
protected:
|
||||
std::string name; /**< Constant's name */
|
||||
};
|
||||
|
||||
class AppExport BooleanExpression : public NumberExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
BooleanExpression(const App::DocumentObject *_owner = 0, bool _value = false);
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport OperatorExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Operator {
|
||||
NONE,
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
MOD,
|
||||
POW,
|
||||
EQ,
|
||||
NEQ,
|
||||
LT,
|
||||
GT,
|
||||
LTE,
|
||||
GTE,
|
||||
UNIT,
|
||||
NEG,
|
||||
POS
|
||||
};
|
||||
OperatorExpression(const App::DocumentObject *_owner = 0, Expression * _left = 0, Operator _op = NONE, Expression * _right = 0);
|
||||
|
||||
virtual ~OperatorExpression();
|
||||
|
||||
virtual bool isTouched() const override;
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
Operator getOperator() const { return op; }
|
||||
|
||||
Expression * getLeft() const { return left; }
|
||||
|
||||
Expression * getRight() const { return right; }
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
virtual void _visit(ExpressionVisitor & v) override;
|
||||
|
||||
virtual bool isCommutative() const;
|
||||
|
||||
virtual bool isLeftAssociative() const;
|
||||
|
||||
virtual bool isRightAssociative() const;
|
||||
|
||||
Operator op; /**< Operator working on left and right */
|
||||
Expression * left; /**< Left operand */
|
||||
Expression * right; /**< Right operand */
|
||||
};
|
||||
|
||||
class AppExport ConditionalExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
ConditionalExpression(const App::DocumentObject *_owner = 0, Expression * _condition = 0,Expression * _trueExpr = 0, Expression * _falseExpr = 0);
|
||||
|
||||
virtual ~ConditionalExpression();
|
||||
|
||||
virtual bool isTouched() const override;
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const;
|
||||
virtual void _visit(ExpressionVisitor & v) override;
|
||||
bool evalCond() const;
|
||||
|
||||
protected:
|
||||
|
||||
Expression * condition; /**< Condition */
|
||||
Expression * trueExpr; /**< Expression if abs(condition) is > 0.5 */
|
||||
Expression * falseExpr; /**< Expression if abs(condition) is < 0.5 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing various functions, e.g sin, cos, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport FunctionExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
enum Function {
|
||||
NONE,
|
||||
|
||||
// Normal functions taking one or two arguments
|
||||
ACOS,
|
||||
ASIN,
|
||||
ATAN,
|
||||
ABS,
|
||||
EXP,
|
||||
LOG,
|
||||
LOG10,
|
||||
SIN,
|
||||
SINH,
|
||||
TAN,
|
||||
TANH,
|
||||
SQRT,
|
||||
COS,
|
||||
COSH,
|
||||
ATAN2,
|
||||
MOD,
|
||||
POW,
|
||||
ROUND,
|
||||
TRUNC,
|
||||
CEIL,
|
||||
FLOOR,
|
||||
HYPOT,
|
||||
CATH,
|
||||
|
||||
// Aggregates
|
||||
AGGREGATES,
|
||||
|
||||
SUM,
|
||||
AVERAGE,
|
||||
STDDEV,
|
||||
COUNT,
|
||||
MIN,
|
||||
MAX,
|
||||
|
||||
// Last one
|
||||
LAST,
|
||||
};
|
||||
|
||||
FunctionExpression(const App::DocumentObject *_owner = 0, Function _f = NONE, std::vector<Expression *> _args = std::vector<Expression*>());
|
||||
|
||||
virtual ~FunctionExpression();
|
||||
|
||||
virtual bool isTouched() const override;
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
virtual void _visit(ExpressionVisitor & v) override;
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
|
||||
protected:
|
||||
Expression *evalAggregate() const;
|
||||
|
||||
Function f; /**< Function to execute */
|
||||
std::vector<Expression *> args; /** Arguments to function*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a reference to a property. If the name is unqualified,
|
||||
* the owner of the expression is searched. If it is qualified, the document
|
||||
* that contains the owning document object is searched for other document
|
||||
* objects to search. Both labels and internal document names are searched.
|
||||
*
|
||||
*/
|
||||
|
||||
class AppExport VariableExpression : public UnitExpression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
VariableExpression(const App::DocumentObject *_owner = 0, ObjectIdentifier _var = ObjectIdentifier());
|
||||
|
||||
~VariableExpression();
|
||||
|
||||
virtual bool isTouched() const override;
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
std::string name() const { return var.getPropertyName(); }
|
||||
|
||||
ObjectIdentifier getPath() const { return var; }
|
||||
|
||||
void setPath(const ObjectIdentifier & path);
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual void _getDeps(ExpressionDeps &) const override;
|
||||
virtual void _getDepObjects(std::set<App::DocumentObject*> &, std::vector<std::string> *) const override;
|
||||
virtual void _getIdentifiers(std::set<App::ObjectIdentifier> &) const override;
|
||||
virtual bool _adjustLinks(const std::set<App::DocumentObject*> &, ExpressionVisitor &) override;
|
||||
virtual void _importSubNames(const ObjectIdentifier::SubNameMap &) override;
|
||||
virtual void _updateLabelReference(App::DocumentObject *, const std::string &, const char *) override;
|
||||
virtual bool _updateElementReference(App::DocumentObject *,bool,ExpressionVisitor &) override;
|
||||
virtual bool _relabeledDocument(const std::string &, const std::string &, ExpressionVisitor &) override;
|
||||
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &) override;
|
||||
virtual void _collectReplacement(std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const App::DocumentObject *parent, App::DocumentObject *oldObj,
|
||||
App::DocumentObject *newObj) const override;
|
||||
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) override;
|
||||
virtual void _offsetCells(int, int, ExpressionVisitor &) override;
|
||||
|
||||
protected:
|
||||
|
||||
ObjectIdentifier var; /**< Variable name */
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AppExport PyObjectExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
PyObjectExpression(const App::DocumentObject *_owner=0, PyObject *pyobj=0, bool owned=false)
|
||||
:Expression(_owner)
|
||||
{
|
||||
setPyValue(pyobj,owned);
|
||||
}
|
||||
|
||||
virtual ~PyObjectExpression();
|
||||
|
||||
void setPyValue(Py::Object pyobj);
|
||||
void setPyValue(PyObject *pyobj, bool owned=false);
|
||||
|
||||
virtual std::string toString(bool) const override;
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
virtual Expression * eval() const override { return copy(); }
|
||||
virtual Expression * simplify() const override { return copy(); }
|
||||
|
||||
protected:
|
||||
virtual Expression* _copy() const override;
|
||||
|
||||
protected:
|
||||
PyObject *pyObj = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class implementing a string. Used to signal either a genuine string or
|
||||
* a failed evaluation of an expression.
|
||||
*/
|
||||
|
||||
class AppExport StringExpression : public Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
StringExpression(const App::DocumentObject *_owner = 0, const std::string & _text = std::string());
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual Expression * simplify() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual std::string getText() const { return text; }
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
std::string text; /**< Text string */
|
||||
};
|
||||
|
||||
class AppExport RangeExpression : public App::Expression {
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
RangeExpression(const App::DocumentObject * _owner = 0, const std::string & begin = std::string(), const std::string & end = std::string());
|
||||
|
||||
virtual ~RangeExpression() { }
|
||||
|
||||
virtual bool isTouched() const override;
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const override;
|
||||
|
||||
virtual int priority() const override;
|
||||
|
||||
virtual App::Expression * simplify() const override;
|
||||
|
||||
Range getRange() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const override { return boost::any(); }
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
virtual void _getDeps(ExpressionDeps &) const override;
|
||||
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &) override;
|
||||
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) override;
|
||||
virtual void _offsetCells(int, int, ExpressionVisitor &) override;
|
||||
|
||||
protected:
|
||||
std::string begin;
|
||||
std::string end;
|
||||
};
|
||||
|
||||
namespace ExpressionParser {
|
||||
AppExport Expression * parse(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer);
|
||||
AppExport ObjectIdentifier parsePath(const App::DocumentObject *owner, const char* buffer);
|
||||
AppExport bool isTokenAnIndentifier(const std::string & str);
|
||||
AppExport bool isTokenAUnit(const std::string & str);
|
||||
AppExport std::vector<boost::tuple<int, int, std::string> > tokenize(const std::string & str);
|
||||
|
||||
/// Convenient class to mark begin of importing
|
||||
class AppExport ExpressionImporter {
|
||||
public:
|
||||
ExpressionImporter(Base::XMLReader &reader);
|
||||
~ExpressionImporter();
|
||||
static Base::XMLReader *reader();
|
||||
};
|
||||
|
||||
AppExport bool isModuleImported(PyObject *);
|
||||
|
||||
/**
|
||||
* @brief The semantic_type class encapsulates the value in the parse tree during parsing.
|
||||
*/
|
||||
|
||||
class semantic_type {
|
||||
public:
|
||||
struct {
|
||||
Base::Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression * expr;
|
||||
ObjectIdentifier path;
|
||||
std::deque<ObjectIdentifier::Component> components;
|
||||
long long int ivalue;
|
||||
double fvalue;
|
||||
struct {
|
||||
std::string name;
|
||||
double fvalue = 0;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
std::vector<Expression*> list;
|
||||
std::string string;
|
||||
FunctionExpression::Function func;
|
||||
ObjectIdentifier::String string_or_identifier;
|
||||
semantic_type() : expr(0), ivalue(0), fvalue(0), func(FunctionExpression::NONE) {}
|
||||
};
|
||||
|
||||
#define YYSTYPE semantic_type
|
||||
#include "ExpressionParser.tab.h"
|
||||
#undef YYTOKENTYPE
|
||||
#undef YYSTYPE
|
||||
#undef YYSTYPE_ISDECLARED
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //EXPRESSION_PARSER_H
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "Document.h"
|
||||
#include "DocumentObject.h"
|
||||
#include "ObjectIdentifier.h"
|
||||
#include "Expression.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/QuantityPy.h>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Console.h>
|
||||
#include <App/Application.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/DocumentObject.h>
|
||||
|
||||
using namespace App;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <App/ObjectIdentifier.h>
|
||||
#include "ExpressionCompleter.h"
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
|
||||
FC_LOG_LEVEL_INIT("Completer",true,true)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Application.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include "ExpressionCompleter.h"
|
||||
#include "Command.h"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
#include <sstream>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "DlgExpressionInput.h"
|
||||
#include "Command.h"
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include "QuantitySpinBox_p.h"
|
||||
#include <App/PropertyUnits.h>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
|
||||
#include "Command.h"
|
||||
#include "Widgets.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <Base/QuantityPy.h>
|
||||
#include <App/ObjectIdentifier.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
|
||||
#include "PropertyConstraintList.h"
|
||||
#include "ConstraintPy.h"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Console.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include "Sheet.h"
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "Utils.h"
|
||||
#include <PropertySheetPy.h>
|
||||
#include <App/ExpressionVisitors.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
FC_LOG_LEVEL_INIT("Spreadsheet", true, true)
|
||||
|
||||
using namespace App;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <App/Document.h>
|
||||
#include <App/DynamicProperty.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Placement.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Range.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <Gui/Command.h>
|
||||
#include "ui_PropertiesDialog.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user