App: extend Expression syntax
* Support sub-object reference syntax using the following syntax,
Part.<<Box.>>.Placement
or, with sub-object label referencing
Part.<<$Cube.>>.Placement
* Extend indexing support, including range based indexing, e.g.
A1[B2+1][C3][D4:-1]
* Add new constants, None, True, true, False, false.
This commit is contained in:
@@ -1750,7 +1750,6 @@ void Application::initTypes(void)
|
||||
App ::ConditionalExpression ::init();
|
||||
App ::StringExpression ::init();
|
||||
App ::FunctionExpression ::init();
|
||||
App ::BooleanExpression ::init();
|
||||
App ::RangeExpression ::init();
|
||||
App ::PyObjectExpression ::init();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -124,15 +124,16 @@ public:
|
||||
|
||||
virtual bool isTouched() const { return false; }
|
||||
|
||||
virtual Expression * eval() const = 0;
|
||||
Expression * eval() const;
|
||||
|
||||
virtual std::string toString(bool persistent=false) const = 0;
|
||||
std::string toString(bool persistent=false, bool checkPriority=false, int indent=0) const;
|
||||
void toString(std::ostream &os, bool persistent=false, bool checkPriority=false, int indent=0) const;
|
||||
|
||||
static Expression * parse(const App::DocumentObject * owner, const std::string& buffer);
|
||||
|
||||
Expression * copy() const;
|
||||
|
||||
virtual int priority() const { return 0; }
|
||||
virtual int priority() const;
|
||||
|
||||
void getIdentifiers(std::set<App::ObjectIdentifier> &) const;
|
||||
std::set<App::ObjectIdentifier> getIdentifiers() const;
|
||||
@@ -163,17 +164,30 @@ public:
|
||||
};
|
||||
|
||||
App::DocumentObject * getOwner() const { return owner; }
|
||||
struct Component;
|
||||
|
||||
virtual boost::any getValueAsAny() const = 0;
|
||||
virtual void addComponent(Component* component);
|
||||
|
||||
virtual Py::Object getPyValue() const = 0;
|
||||
typedef std::vector<Component*> ComponentList;
|
||||
|
||||
static Component *createComponent(const std::string &n);
|
||||
static Component *createComponent(Expression *e1, Expression *e2=0,
|
||||
Expression *e3=0, bool isRange=false);
|
||||
|
||||
bool hasComponent() const {return !components.empty();}
|
||||
|
||||
boost::any getValueAsAny() const;
|
||||
|
||||
Py::Object getPyValue() const;
|
||||
|
||||
bool isSame(const Expression &other) const;
|
||||
|
||||
friend ExpressionVisitor;
|
||||
|
||||
protected:
|
||||
virtual bool _isIndexable() const {return false;}
|
||||
virtual Expression *_copy() const = 0;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent=0) const = 0;
|
||||
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 {}
|
||||
@@ -193,11 +207,14 @@ protected:
|
||||
}
|
||||
virtual void _moveCells(const CellAddress &, int, int, ExpressionVisitor &) {}
|
||||
virtual void _offsetCells(int, int, ExpressionVisitor &) {}
|
||||
virtual Py::Object _getPyValue() const = 0;
|
||||
virtual void _visit(ExpressionVisitor &) {}
|
||||
|
||||
protected:
|
||||
App::DocumentObject * owner; /**< The document object used to access unqualified variables (i.e local scope) */
|
||||
|
||||
ComponentList components;
|
||||
|
||||
public:
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
@@ -37,6 +37,32 @@ namespace App {
|
||||
// included by everyone
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AppExport Expression::Component {
|
||||
ObjectIdentifier::Component comp;
|
||||
Expression* e1;
|
||||
Expression* e2;
|
||||
Expression* e3;
|
||||
|
||||
Component(const std::string &n);
|
||||
Component(Expression *e1, Expression *e2, Expression *e3, bool isRange=false);
|
||||
Component(const ObjectIdentifier::Component &comp);
|
||||
Component(const Component &other);
|
||||
~Component();
|
||||
Component &operator=(const Component &)=delete;
|
||||
|
||||
void visit(ExpressionVisitor &v);
|
||||
bool isTouched() const;
|
||||
void toString(std::ostream &ss, bool persistent) const;
|
||||
Component *copy() const;
|
||||
Component *eval() const;
|
||||
|
||||
Py::Object get(const Expression *owner, const Py::Object &pyobj) const;
|
||||
void set(const Expression *owner, Py::Object &pyobj, const Py::Object &value) const;
|
||||
void del(const Expression *owner, Py::Object &pyobj) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Part of an expressions that contains a unit.
|
||||
*
|
||||
@@ -47,16 +73,14 @@ class AppExport UnitExpression : public Expression {
|
||||
public:
|
||||
UnitExpression(const App::DocumentObject *_owner = 0, const Base::Quantity & _quantity = Base::Quantity(), const std::string & _unitStr = std::string());
|
||||
|
||||
virtual Expression * eval() const override;
|
||||
~UnitExpression();
|
||||
|
||||
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);
|
||||
|
||||
void setQuantity(const Base::Quantity &_quantity);
|
||||
|
||||
double getValue() const { return quantity.getValue(); }
|
||||
|
||||
const Base::Unit & getUnit() const { return quantity.getUnit(); }
|
||||
@@ -67,14 +91,15 @@ public:
|
||||
|
||||
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;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
mutable PyObject *cache = 0;
|
||||
|
||||
private:
|
||||
Base::Quantity quantity;
|
||||
std::string unitStr; /**< The unit string from the original parsed string */
|
||||
};
|
||||
@@ -88,51 +113,37 @@ class AppExport NumberExpression : public UnitExpression {
|
||||
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;
|
||||
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) 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;
|
||||
ConstantExpression(const App::DocumentObject *_owner = 0,
|
||||
const char *_name = "",
|
||||
const Base::Quantity &_quantity = Base::Quantity());
|
||||
|
||||
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);
|
||||
bool isNumber() const;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Expression* _copy() const override;
|
||||
|
||||
protected:
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class implementing an infix expression.
|
||||
*
|
||||
@@ -165,12 +176,8 @@ public:
|
||||
|
||||
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; }
|
||||
@@ -179,13 +186,13 @@ public:
|
||||
|
||||
Expression * getRight() const { return right; }
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
|
||||
virtual void _visit(ExpressionVisitor & v) override;
|
||||
|
||||
virtual bool isCommutative() const;
|
||||
@@ -208,22 +215,15 @@ public:
|
||||
|
||||
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;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -290,25 +290,16 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
static Py::Object evaluate(const Expression *owner, int type, const std::vector<Expression*> &args);
|
||||
|
||||
protected:
|
||||
Expression *evalAggregate() const;
|
||||
static Py::Object evalAggregate(const Expression *owner, int type, const std::vector<Expression*> &args);
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
virtual Expression * _copy() const override;
|
||||
virtual void _visit(ExpressionVisitor & v) override;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
|
||||
Function f; /**< Function to execute */
|
||||
std::vector<Expression *> args; /** Arguments to function*/
|
||||
@@ -331,16 +322,8 @@ public:
|
||||
|
||||
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; }
|
||||
@@ -349,11 +332,13 @@ public:
|
||||
|
||||
const App::Property *getProperty() const;
|
||||
|
||||
virtual boost::any getValueAsAny() const override;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
virtual void addComponent(Component* component) override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual bool _isIndexable() const override;
|
||||
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;
|
||||
@@ -391,16 +376,12 @@ public:
|
||||
|
||||
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;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
|
||||
protected:
|
||||
PyObject *pyObj = 0;
|
||||
@@ -415,25 +396,20 @@ 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;
|
||||
~StringExpression();
|
||||
|
||||
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;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
virtual bool _isIndexable() const override { return true; }
|
||||
|
||||
private:
|
||||
std::string text; /**< Text string */
|
||||
mutable PyObject *cache = 0;
|
||||
};
|
||||
|
||||
class AppExport RangeExpression : public App::Expression {
|
||||
@@ -445,22 +421,14 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
virtual Py::Object getPyValue() const override;
|
||||
|
||||
protected:
|
||||
virtual Expression * _copy() const override;
|
||||
virtual void _toString(std::ostream &ss, bool persistent, int indent) const override;
|
||||
virtual Py::Object _getPyValue() const override;
|
||||
virtual void _getDeps(ExpressionDeps &) const override;
|
||||
virtual bool _renameObjectIdentifier(const std::map<ObjectIdentifier,ObjectIdentifier> &,
|
||||
const ObjectIdentifier &, ExpressionVisitor &) override;
|
||||
@@ -500,13 +468,14 @@ public:
|
||||
Base::Quantity scaler;
|
||||
std::string unitStr;
|
||||
} quantity;
|
||||
Expression::Component *component;
|
||||
Expression * expr;
|
||||
ObjectIdentifier path;
|
||||
std::deque<ObjectIdentifier::Component> components;
|
||||
long long int ivalue;
|
||||
double fvalue;
|
||||
struct {
|
||||
std::string name;
|
||||
const char *name = "";
|
||||
double fvalue = 0;
|
||||
} constant;
|
||||
std::vector<Expression*> arguments;
|
||||
|
||||
@@ -264,6 +264,12 @@ EXPO [eE][-+]?[0-9]+
|
||||
"pi" COUNTCHARS; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi
|
||||
"e" COUNTCHARS; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e
|
||||
|
||||
"None" COUNTCHARS; yylval.constant.fvalue = 0; yylval.constant.name = "None"; return CONSTANT;
|
||||
"True" COUNTCHARS; yylval.constant.fvalue = 1; yylval.constant.name = "True"; return CONSTANT;
|
||||
"true" COUNTCHARS; yylval.constant.fvalue = 1; yylval.constant.name = "True"; return CONSTANT;
|
||||
"False" COUNTCHARS; yylval.constant.fvalue = 0; yylval.constant.name = "False"; return CONSTANT;
|
||||
"false" COUNTCHARS; yylval.constant.fvalue = 0; yylval.constant.name = "False"; return CONSTANT;
|
||||
|
||||
$[A-Za-z]{1,2}+${DIGIT}+ COUNTCHARS; yylval.string = yytext; return CELLADDRESS;
|
||||
[A-Za-z]{1,2}${DIGIT}+ COUNTCHARS; yylval.string = yytext; return CELLADDRESS;
|
||||
$[A-Za-z]{1,2}{DIGIT}+ COUNTCHARS; yylval.string = yytext; return CELLADDRESS;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,9 +29,9 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
%token DOCUMENT OBJECT
|
||||
%token EXPONENT
|
||||
%type <arguments> args
|
||||
%type <expr> input exp unit_exp cond
|
||||
%type <expr> input exp unit_exp cond indexable
|
||||
%type <quantity> UNIT
|
||||
%type <string> STRING IDENTIFIER CELLADDRESS
|
||||
%type <string> id_or_cell STRING IDENTIFIER CELLADDRESS
|
||||
%type <ivalue> INTEGER
|
||||
%type <string> PROPERTY_REF
|
||||
%type <fvalue> ONE
|
||||
@@ -39,8 +39,8 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
%type <constant> CONSTANT
|
||||
%type <expr> num
|
||||
%type <expr> range
|
||||
%type <path> identifier
|
||||
%type <components> path subpath
|
||||
%type <path> identifier iden
|
||||
%type <component> indexer
|
||||
%type <func> FUNC
|
||||
%type <string_or_identifier> document
|
||||
%type <string_or_identifier> object
|
||||
@@ -56,7 +56,8 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
%left NEG /* negation--unary minus */
|
||||
%left POS /* unary plus */
|
||||
|
||||
%destructor { delete $$; } exp cond unit_exp
|
||||
%destructor { delete $$; } num range exp cond unit_exp indexable
|
||||
%destructor { delete $$; } <component>
|
||||
%destructor { std::vector<Expression*>::const_iterator i = $$.begin(); while (i != $$.end()) { delete *i; ++i; } } args
|
||||
|
||||
%start input
|
||||
@@ -64,7 +65,7 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
%%
|
||||
|
||||
input: exp { ScanResult = $1; valueExpression = true; }
|
||||
| unit_exp { ScanResult = $1; unitExpression = true; }
|
||||
| unit_exp { ScanResult = $1; unitExpression = true; }
|
||||
;
|
||||
|
||||
exp: num { $$ = $1; }
|
||||
@@ -80,7 +81,7 @@ exp: num { $$ = $1;
|
||||
| exp '%' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MOD, $3); }
|
||||
| exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
|
||||
| exp '^' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
| indexable { $$ = $1; }
|
||||
| FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1, $2); }
|
||||
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
|
||||
;
|
||||
@@ -98,10 +99,7 @@ args: exp { $$.push_back($1);
|
||||
| args ';' range { $1.push_back($3); $$ = $1; }
|
||||
;
|
||||
|
||||
range: CELLADDRESS ':' CELLADDRESS { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| CELLADDRESS ':' IDENTIFIER { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| IDENTIFIER ':' CELLADDRESS { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
| IDENTIFIER ':' IDENTIFIER { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
range: id_or_cell ':' id_or_cell { $$ = new RangeExpression(DocumentObject, $1, $3); }
|
||||
;
|
||||
|
||||
cond: exp EQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3); }
|
||||
@@ -120,72 +118,87 @@ unit_exp: UNIT { $$ = new UnitExpression(Docume
|
||||
| '(' unit_exp ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
identifier: path { /* Path to property within document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.addComponents($1);
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| '.' path { /* Path to property of the current document object */
|
||||
$$ = ObjectIdentifier(DocumentObject,true);
|
||||
$$.setDocumentObjectName(DocumentObject);
|
||||
$$.addComponents($2);
|
||||
}
|
||||
| object '.' path { /* Path to property within document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$1.checkImport(DocumentObject);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($1));
|
||||
$$.addComponents($3);
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| document '#' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName(std::move($1), true);
|
||||
$$.addComponents($3);
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| document '#' object '.' path { /* Path to property from an external document, within a named document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName(std::move($1), true);
|
||||
$$.setDocumentObjectName(std::move($3), true);
|
||||
$$.addComponents($5);
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
;
|
||||
|
||||
integer: INTEGER { $$ = $1; }
|
||||
| ONE { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
path: IDENTIFIER { $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| CELLADDRESS { $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' { $$.push_front(ObjectIdentifier::ArrayComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' '.' subpath { $6.push_front(ObjectIdentifier::ArrayComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); $$ = $6; }
|
||||
| IDENTIFIER '[' STRING ']' { $$.push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String($3, true))); }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' { $$.push_front(ObjectIdentifier::MapComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' STRING ']' '.' subpath { $6.push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String($3, true))); $$.push_front(ObjectIdentifier::SimpleComponent($1)); $$ = $6; }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' '.' subpath { $6.push_front(ObjectIdentifier::MapComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); $$ = $6; }
|
||||
| IDENTIFIER '.' subpath { $3.push_front(ObjectIdentifier::SimpleComponent($1)); $$ = $3; }
|
||||
id_or_cell
|
||||
: IDENTIFIER { $$ = std::move($1); }
|
||||
| CELLADDRESS { $$ = std::move($1); }
|
||||
;
|
||||
|
||||
subpath: IDENTIFIER { $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| STRING { $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| CELLADDRESS { $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' { $$.push_front(ObjectIdentifier::ArrayComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' integer ']' '.' subpath { $6.push_front(ObjectIdentifier::ArrayComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1));$$ = $6; }
|
||||
| IDENTIFIER '[' STRING ']' { $$.push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String($3, true))); $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' { $$.push_front(ObjectIdentifier::MapComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1)); }
|
||||
| IDENTIFIER '[' STRING ']' '.' subpath { $6.push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String($3, true))); $$.push_front(ObjectIdentifier::SimpleComponent($1));$$ = $6; }
|
||||
| IDENTIFIER '[' IDENTIFIER ']' '.' subpath { $6.push_front(ObjectIdentifier::MapComponent($3)); $$.push_front(ObjectIdentifier::SimpleComponent($1));$$ = $6; }
|
||||
| IDENTIFIER '.' subpath { $3.push_front(ObjectIdentifier::SimpleComponent($1)); $$ = $3; }
|
||||
identifier
|
||||
: id_or_cell { $$ = ObjectIdentifier(DocumentObject); $$ << ObjectIdentifier::SimpleComponent($1); }
|
||||
| iden { $$ = std::move($1); }
|
||||
;
|
||||
|
||||
document: STRING { $$ = ObjectIdentifier::String($1, true); }
|
||||
| IDENTIFIER { $$ = ObjectIdentifier::String($1); }
|
||||
;
|
||||
iden
|
||||
: '.' STRING '.' id_or_cell { /* Path to property of a sub-object of the current object*/
|
||||
$$ = ObjectIdentifier(DocumentObject,true);
|
||||
$$.setDocumentObjectName(DocumentObject,false,ObjectIdentifier::String(std::move($2),true),true);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($4));
|
||||
}
|
||||
| '.' id_or_cell { /* Path to property of the current document object */
|
||||
$$ = ObjectIdentifier(DocumentObject,true);
|
||||
$$.setDocumentObjectName(DocumentObject);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($2));
|
||||
}
|
||||
| object '.' STRING '.' id_or_cell { /* Path to property of a sub-object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentObjectName(std::move($1), true, ObjectIdentifier::String(std::move($3),true),true);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| object '.' id_or_cell { /* Path to property of a given document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$1.checkImport(DocumentObject);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($1));
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($3));
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| document '#' object '.' id_or_cell { /* Path to property from an external document, within a named document object */
|
||||
$$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName(std::move($1), true);
|
||||
$$.setDocumentObjectName(std::move($3), true);
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| document '#' object '.' STRING '.' id_or_cell
|
||||
{ $$ = ObjectIdentifier(DocumentObject);
|
||||
$$.setDocumentName(std::move($1), true);
|
||||
$$.setDocumentObjectName(std::move($3), true, ObjectIdentifier::String(std::move($5),true));
|
||||
$$.addComponent(ObjectIdentifier::SimpleComponent($7));
|
||||
$$.resolveAmbiguity();
|
||||
}
|
||||
| iden '.' IDENTIFIER { $$= std::move($1); $$.addComponent(ObjectIdentifier::SimpleComponent($3)); }
|
||||
;
|
||||
|
||||
object: STRING { $$ = ObjectIdentifier::String($1, true); }
|
||||
| CELLADDRESS { $$ = ObjectIdentifier::String($1, true); }
|
||||
;
|
||||
indexer
|
||||
: '[' exp ']' { $$ = Expression::createComponent($2); }
|
||||
| '[' exp ':' ']' { $$ = Expression::createComponent($2,0,0,true); }
|
||||
| '[' ':' exp ']' { $$ = Expression::createComponent(0,$3); }
|
||||
| '[' ':' ':' exp ']' { $$ = Expression::createComponent(0,0,$4); }
|
||||
| '[' exp ':' exp ']' { $$ = Expression::createComponent($2,$4);}
|
||||
| '[' exp ':' ':' exp ']' { $$ = Expression::createComponent($2,0,$5); }
|
||||
| '[' ':' exp ':' exp ']' { $$ = Expression::createComponent(0,$3,$5); }
|
||||
| '[' exp ':' exp ':' exp ']' { $$ = Expression::createComponent($2,$4,$6);}
|
||||
;
|
||||
|
||||
indexable
|
||||
: '(' exp ')' { $$ = $2; }
|
||||
| identifier indexer { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
|
||||
| indexable indexer { $1->addComponent(std::move($2)); $$ = $1; }
|
||||
| indexable '.' IDENTIFIER { $1->addComponent(Expression::createComponent($3)); $$ = $1; }
|
||||
;
|
||||
|
||||
document
|
||||
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
|
||||
| IDENTIFIER { $$ = ObjectIdentifier::String(std::move($1), false, true);}
|
||||
;
|
||||
|
||||
object
|
||||
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
|
||||
| id_or_cell { $$ = ObjectIdentifier::String(std::move($1), false);}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
@@ -553,8 +553,7 @@ DocumentObjectExecReturn *App::PropertyExpressionEngine::execute(ExecuteOption o
|
||||
App::any value;
|
||||
try {
|
||||
// Evaluate expression
|
||||
std::unique_ptr<Expression> e(expressions[*it].expression->eval());
|
||||
value = e->getValueAsAny();
|
||||
value = expressions[*it].expression->getValueAsAny();
|
||||
if(option == ExecuteOnRestore && prop->testStatus(Property::EvalOnRestore)) {
|
||||
if(isAnyEqual(value, prop->getPathValue(*it)))
|
||||
continue;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -692,7 +692,11 @@ void Sheet::updateProperty(CellAddress key)
|
||||
auto number = freecad_dynamic_cast<NumberExpression>(output.get());
|
||||
if(number) {
|
||||
long l;
|
||||
if (!number->getUnit().isEmpty())
|
||||
auto constant = freecad_dynamic_cast<ConstantExpression>(output.get());
|
||||
if(constant && !constant->isNumber()) {
|
||||
Base::PyGILStateLocker lock;
|
||||
setObjectProperty(key, constant->getPyValue());
|
||||
} else if (!number->getUnit().isEmpty())
|
||||
setQuantityProperty(key, number->getValue(), number->getUnit());
|
||||
else if(number->isInteger(&l))
|
||||
setIntegerProperty(key,l);
|
||||
|
||||
Reference in New Issue
Block a user