diff --git a/src/App/Expression.cpp b/src/App/Expression.cpp index 33f6400cb8..4ca75f5cf3 100644 --- a/src/App/Expression.cpp +++ b/src/App/Expression.cpp @@ -656,6 +656,25 @@ bool isAnyEqual(const App::any &v1, const App::any &v2) { return !!res; } +Expression* expressionFromPy(const DocumentObject *owner, const Py::Object &value) { + if (value.isNone()) { + return new PyObjectExpression(owner); + } + if(value.isString()) { + return new StringExpression(owner,value.as_string()); + } else if (PyObject_TypeCheck(value.ptr(),&QuantityPy::Type)) { + return new NumberExpression(owner, + *static_cast(value.ptr())->getQuantityPtr()); + } else if (value.isBoolean()) { + return new BooleanExpression(owner,value.isTrue()); + } else { + Quantity q; + if(pyToQuantity(q,value)) + return new NumberExpression(owner,q); + } + return new PyObjectExpression(owner,value.ptr()); +} + } // namespace App @@ -987,6 +1006,10 @@ int UnitExpression::priority() const return 20; } +Py::Object UnitExpression::getPyValue() const { + return pyFromQuantity(quantity); +} + // // NumberExpression class // @@ -1089,6 +1112,148 @@ bool OperatorExpression::isTouched() const return left->isTouched() || right->isTouched(); } +static Py::Object calc(const Expression *expr, int op, + const Expression *left, const Expression *right, bool inplace) +{ + Py::Object l = left->getPyValue(); + + // For security reason, restrict supported types + if(!PyObject_TypeCheck(l.ptr(),&PyObjectBase::Type) + && !l.isNumeric() && !l.isString() && !l.isList() && !l.isDict()) + { + __EXPR_THROW(Base::TypeError,"Unsupported operator", expr); + } + + // check possible unary operation first + switch(op) { + case OperatorExpression::POS:{ + PyObject *res = PyNumber_Positive(l.ptr()); + if(!res) EXPR_PY_THROW(expr); + return Py::asObject(res); + } + case OperatorExpression::NEG:{ + PyObject *res = PyNumber_Negative(l.ptr()); + if(!res) EXPR_PY_THROW(expr); + return Py::asObject(res); + } default: + break; + } + + Py::Object r = right->getPyValue(); + // For security reason, restrict supported types + if((op!=OperatorExpression::MOD || !l.isString()) + && !PyObject_TypeCheck(r.ptr(),&PyObjectBase::Type) + && !r.isNumeric() + && !r.isString() + && !r.isList() + && !r.isDict()) + { + __EXPR_THROW(Base::TypeError,"Unsupported operator", expr); + } + + switch(op) { +#define RICH_COMPARE(_op,_pyop) \ + case OperatorExpression::_op: {\ + int res = PyObject_RichCompareBool(l.ptr(),r.ptr(),Py_##_pyop);\ + if(res<0) EXPR_PY_THROW(expr);\ + return Py::Boolean(!!res);\ + } + RICH_COMPARE(LT,LT) + RICH_COMPARE(LTE,LE) + RICH_COMPARE(GT,GT) + RICH_COMPARE(GTE,GE) + RICH_COMPARE(EQ,EQ) + RICH_COMPARE(NEQ,NE) + +#define _BINARY_OP(_pyop) \ + res = inplace?PyNumber_InPlace##_pyop(l.ptr(),r.ptr()):\ + PyNumber_##_pyop(l.ptr(),r.ptr());\ + if(!res) EXPR_PY_THROW(expr);\ + return Py::asObject(res); + +#define BINARY_OP(_op,_pyop) \ + case OperatorExpression::_op: {\ + PyObject *res;\ + _BINARY_OP(_pyop);\ + } + + BINARY_OP(SUB,Subtract) + BINARY_OP(MUL,Multiply) + BINARY_OP(UNIT,Multiply) + BINARY_OP(DIV,TrueDivide) + case OperatorExpression::ADD: { + PyObject *res; +#if PY_MAJOR_VERSION < 3 + if (PyString_CheckExact(*l) && PyString_CheckExact(*r)) { + Py_ssize_t v_len = PyString_GET_SIZE(*l); + Py_ssize_t w_len = PyString_GET_SIZE(*r); + Py_ssize_t new_len = v_len + w_len; + if (new_len < 0) + __EXPR_THROW(OverflowError, "strings are too large to concat", expr); + + if (l.ptr()->ob_refcnt==1 && !PyString_CHECK_INTERNED(l.ptr())) { + res = Py::new_reference_to(l); + // Must make sure ob_refcnt is still 1 + l = Py::Object(); + if (_PyString_Resize(&res, new_len) != 0) + EXPR_PY_THROW(expr); + memcpy(PyString_AS_STRING(res) + v_len, PyString_AS_STRING(*r), w_len); + }else{ + res = Py::new_reference_to(l); + l = Py::Object(); + PyString_Concat(&res,*r); + if(!res) EXPR_PY_THROW(expr); + } + return Py::asObject(res); + } +#else + if (PyUnicode_CheckExact(*l) && PyUnicode_CheckExact(*r)) { + if(inplace) { + res = Py::new_reference_to(l); + // Try to make sure ob_refcnt is 1, although unlike + // PyString_Resize above, PyUnicode_Append can handle other + // cases. + l = Py::Object(); + PyUnicode_Append(&res, r.ptr()); + }else + res = PyUnicode_Concat(l.ptr(),r.ptr()); + if(!res) EXPR_PY_THROW(expr); + return Py::asObject(res); + } +#endif + _BINARY_OP(Add); + } + case OperatorExpression::POW: { + PyObject *res; + if(inplace) + res = PyNumber_InPlacePower(l.ptr(),r.ptr(),Py::None().ptr()); + else + res = PyNumber_Power(l.ptr(),r.ptr(),Py::None().ptr()); + if(!res) EXPR_PY_THROW(expr); + return Py::asObject(res); + } + case OperatorExpression::MOD: { + PyObject *res; +#if PY_MAJOR_VERSION < 3 + if (PyString_CheckExact(l.ptr()) && + (!PyString_Check(r.ptr()) || PyString_CheckExact(r.ptr()))) + res = PyString_Format(l.ptr(), r.ptr()); +#else + if (PyUnicode_CheckExact(l.ptr()) && + (!PyUnicode_Check(r.ptr()) || PyUnicode_CheckExact(r.ptr()))) + res = PyUnicode_Format(l.ptr(), r.ptr()); +#endif + else if(inplace) + res = PyNumber_InPlaceRemainder(l.ptr(),r.ptr()); + else + res = PyNumber_InPlaceRemainder(l.ptr(),r.ptr()); + if(!res) EXPR_PY_THROW(expr); + return Py::asObject(res); + } + default: + __EXPR_THROW(RuntimeError,"Unsupported operator",expr); + } +} /** * Evaluate the expression. Returns a new Expression with the result, or throws @@ -1097,83 +1262,17 @@ bool OperatorExpression::isTouched() const Expression * OperatorExpression::eval() const { - std::unique_ptr e1(left->eval()); - NumberExpression * v1; - std::unique_ptr e2(right->eval()); - NumberExpression * v2; - Expression * output; + Base::PyGILStateLocker lock; + return expressionFromPy(owner,getPyValue()); +} - v1 = freecad_dynamic_cast(e1.get()); - v2 = freecad_dynamic_cast(e2.get()); +boost::any OperatorExpression::getValueAsAny() const { + Base::PyGILStateLocker lock; + return pyObjectToAny(getPyValue(),true); +} - if (v1 == 0 || v2 == 0) - throw ExpressionError("Invalid expression"); - - switch (op) { - case ADD: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for + operator"); - output = new NumberExpression(owner, v1->getQuantity() + v2->getQuantity()); - break; - case SUB: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for - operator"); - output = new NumberExpression(owner, v1->getQuantity()- v2->getQuantity()); - break; - case MUL: - case UNIT: - output = new NumberExpression(owner, v1->getQuantity() * v2->getQuantity()); - break; - case DIV: - output = new NumberExpression(owner, v1->getQuantity() / v2->getQuantity()); - break; - case POW: - output = new NumberExpression(owner, v1->getQuantity().pow(v2->getQuantity()) ); - break; - case EQ: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the = operator"); - output = new BooleanExpression(owner, essentiallyEqual(v1->getValue(), v2->getValue()) ); - break; - case NEQ: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the != operator"); - output = new BooleanExpression(owner, !essentiallyEqual(v1->getValue(), v2->getValue()) ); - break; - case LT: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the < operator"); - output = new BooleanExpression(owner, definitelyLessThan(v1->getValue(), v2->getValue()) ); - break; - case GT: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the > operator"); - output = new BooleanExpression(owner, definitelyGreaterThan(v1->getValue(), v2->getValue()) ); - break; - case LTE: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the <= operator"); - output = new BooleanExpression(owner, definitelyLessThan(v1->getValue(), v2->getValue()) || - essentiallyEqual(v1->getValue(), v2->getValue())); - break; - case GTE: - if (v1->getUnit() != v2->getUnit()) - throw ExpressionError("Incompatible units for the >= operator"); - output = new BooleanExpression(owner, essentiallyEqual(v1->getValue(), v2->getValue()) || - definitelyGreaterThan(v1->getValue(), v2->getValue())); - break; - case NEG: - output = new NumberExpression(owner, -v1->getQuantity() ); - break; - case POS: - output = new NumberExpression(owner, v1->getQuantity() ); - break; - default: - output = 0; - assert(0); - } - - return output; +Py::Object OperatorExpression::getPyValue() const { + return calc(this,op,left,right,true); } /** @@ -1252,6 +1351,9 @@ std::string OperatorExpression::toString(bool persistent) const case DIV: s << " / "; break; + case MOD: + s << " % "; + break; case POW: s << " ^ "; break; @@ -1334,6 +1436,7 @@ int OperatorExpression::priority() const return 3; case MUL: case DIV: + case MOD: return 4; case POW: return 5; @@ -1879,6 +1982,16 @@ Expression * FunctionExpression::eval() const return new NumberExpression(owner, Quantity(scaler * output, unit)); } +boost::any FunctionExpression::getValueAsAny() const { + ExpressionPtr e(eval()); + return e->getValueAsAny(); +} + +Py::Object FunctionExpression::getPyValue() const { + ExpressionPtr e(eval()); + return e->getPyValue(); +} + /** * Try to simplify the expression, i.e calculate all constant expressions. * @@ -2087,65 +2200,17 @@ const Property * VariableExpression::getProperty() const Expression * VariableExpression::eval() const { - const Property * prop = getProperty(); - PropertyContainer * parent = prop->getContainer(); + Base::PyGILStateLocker lock; + return expressionFromPy(owner,getPyValue()); +} - if (!parent->isDerivedFrom(App::DocumentObject::getClassTypeId())) - throw ExpressionError("Property must belong to a document object."); +boost::any VariableExpression::getValueAsAny() const { + Base::PyGILStateLocker lock; + return pyObjectToAny(getPyValue()); +} - boost::any value = prop->getPathValue(var); - - if (value.type() == typeid(Quantity)) { - Quantity qvalue = boost::any_cast(value); - - return new NumberExpression(owner, qvalue); - } - else if (value.type() == typeid(double)) { - double dvalue = boost::any_cast(value); - - return new NumberExpression(owner, Quantity(dvalue)); - } - else if (value.type() == typeid(float)) { - double fvalue = boost::any_cast(value); - - return new NumberExpression(owner, Quantity(fvalue)); - } - else if (value.type() == typeid(int)) { - int ivalue = boost::any_cast(value); - - return new NumberExpression(owner, Quantity(ivalue)); - } - else if (value.type() == typeid(long)) { - long lvalue = boost::any_cast(value); - - return new NumberExpression(owner, Quantity(lvalue)); - } - else if (value.type() == typeid(bool)) { - double bvalue = boost::any_cast(value) ? 1.0 : 0.0; - - return new NumberExpression(owner, Quantity(bvalue)); - } - else if (value.type() == typeid(std::string)) { - std::string svalue = boost::any_cast(value); - - return new StringExpression(owner, svalue); - } - else if (value.type() == typeid(char*)) { - char* svalue = boost::any_cast(value); - - return new StringExpression(owner, svalue); - } - else if (value.type() == typeid(const char*)) { - const char* svalue = boost::any_cast(value); - - return new StringExpression(owner, svalue); - } - else if (isAnyPyObject(value)) { - Base::PyGILStateLocker lock; - return new PyObjectExpression(owner,__pyObjectFromAny(value).ptr()); - } - - throw ExpressionError("Property is of invalid type."); +Py::Object VariableExpression::getPyValue() const { + return var.getPyValue(true); } std::string VariableExpression::toString(bool persistent) const { @@ -2314,7 +2379,7 @@ PyObjectExpression::~PyObjectExpression() { } } -Py::Object PyObjectExpression::getPyObject() const { +Py::Object PyObjectExpression::getPyValue() const { if(!pyObj) return Py::Object(); return Py::Object(pyObj); @@ -2406,6 +2471,14 @@ Expression *StringExpression::_copy() const return new StringExpression(owner, text); } +boost::any StringExpression::getValueAsAny() const { + return text; +} + +Py::Object StringExpression::getPyValue() const { + return Py::String(text); +} + TYPESYSTEM_SOURCE(App::ConditionalExpression, App::Expression) ConditionalExpression::ConditionalExpression(const DocumentObject *_owner, Expression *_condition, Expression *_trueExpr, Expression *_falseExpr) @@ -2428,20 +2501,37 @@ bool ConditionalExpression::isTouched() const return condition->isTouched() || trueExpr->isTouched() || falseExpr->isTouched(); } -Expression *ConditionalExpression::eval() const -{ +bool ConditionalExpression::evalCond() const { std::unique_ptr e(condition->eval()); NumberExpression * v = freecad_dynamic_cast(e.get()); if (v == 0) throw ExpressionError("Invalid expression"); - if (fabs(v->getValue()) > 0.5) + return fabs(v->getValue()) > 0.5; +} + +Expression *ConditionalExpression::eval() const { + if(evalCond()) return trueExpr->eval(); else return falseExpr->eval(); } +boost::any ConditionalExpression::getValueAsAny() const { + if(evalCond()) + return trueExpr->getValueAsAny(); + else + return falseExpr->getValueAsAny(); +} + +Py::Object ConditionalExpression::getPyValue() const { + if(evalCond()) + return trueExpr->getPyValue(); + else + return falseExpr->getPyValue(); +} + Expression *ConditionalExpression::simplify() const { std::unique_ptr e(condition->simplify()); @@ -2550,6 +2640,10 @@ Expression *RangeExpression::eval() const throw Exception("Range expression cannot be evaluated"); } +Py::Object RangeExpression::getPyValue() const { + return Py::Object(); +} + std::string RangeExpression::toString(bool) const { return begin + ":" + end; diff --git a/src/App/Expression.h b/src/App/Expression.h index 599bc4ba3f..aad5c365a7 100644 --- a/src/App/Expression.h +++ b/src/App/Expression.h @@ -165,7 +165,9 @@ public: App::DocumentObject * getOwner() const { return owner; } - virtual boost::any getValueAsAny() const { static boost::any empty; return empty; } + virtual boost::any getValueAsAny() const = 0; + + virtual Py::Object getPyValue() const = 0; bool isSame(const Expression &other) const; @@ -235,6 +237,8 @@ public: 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 */ @@ -307,6 +311,7 @@ public: SUB, MUL, DIV, + MOD, POW, EQ, NEQ, @@ -342,6 +347,10 @@ public: Expression * getRight() const { return right; } + virtual boost::any getValueAsAny() const; + + virtual Py::Object getPyValue() const; + protected: virtual bool isCommutative() const; @@ -370,11 +379,16 @@ public: virtual std::string toString(bool persistent=false) const; - virtual Expression * _copy() 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: @@ -451,6 +465,11 @@ public: virtual void _visit(ExpressionVisitor & v); + virtual boost::any getValueAsAny() const; + + virtual Py::Object getPyValue() const; + + protected: Expression *evalAggregate() const; @@ -493,6 +512,10 @@ public: 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 &, std::vector *) const; @@ -529,13 +552,12 @@ public: virtual ~PyObjectExpression(); - Py::Object getPyObject() const; - 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(); } @@ -567,9 +589,12 @@ public: virtual int priority() const; - virtual Expression * _copy() const; + virtual boost::any getValueAsAny() const; + + virtual Py::Object getPyValue() const; protected: + virtual Expression * _copy() const; std::string text; /**< Text string */ }; @@ -587,15 +612,18 @@ public: virtual std::string toString(bool persistent=false) const; - virtual Expression * _copy() 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 &, const ObjectIdentifier &, ExpressionVisitor &); diff --git a/src/App/ExpressionParser.l b/src/App/ExpressionParser.l index d52035c717..cd3a0ebf35 100644 --- a/src/App/ExpressionParser.l +++ b/src/App/ExpressionParser.l @@ -146,7 +146,7 @@ EXPO [eE][-+]?[0-9]+ \<\<(\\(.|\n)|[^\\>\n])*\>\> COUNTCHARS; yylval.string = unquote(yytext); return STRING; -[+()=/*^,\.\{\}\[\]:;@\?#] COUNTCHARS; return *yytext; +[%+()=/*^,\.\{\}\[\]:;@\?#] COUNTCHARS; return *yytext; "==" COUNTCHARS; return EQ; "!=" COUNTCHARS; return NEQ; diff --git a/src/App/ExpressionParser.tab.c b/src/App/ExpressionParser.tab.c index a1ae17ad86..47fdc50124 100644 --- a/src/App/ExpressionParser.tab.c +++ b/src/App/ExpressionParser.tab.c @@ -91,7 +91,10 @@ std::stack functions; /**< Function # define YYERROR_VERBOSE 0 #endif - +/* In a future release of Bison, this section will be replaced + by #include "ExpressionParser.tab.h". */ +#ifndef YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED +# define YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -138,11 +141,11 @@ extern YYSTYPE yylval; int yyparse (void); - +#endif /* !YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 146 "ExpressionParser.tab.c" /* yacc.c:358 */ +#line 149 "ExpressionParser.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -384,16 +387,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 38 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 196 +#define YYLAST 202 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 40 +#define YYNTOKENS 41 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 14 /* YYNRULES -- Number of rules. */ -#define YYNRULES 74 +#define YYNRULES 75 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 132 +#define YYNSTATES 134 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -410,13 +413,13 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, - 32, 33, 26, 25, 34, 2, 36, 27, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 24, 35, + 2, 2, 2, 2, 2, 38, 2, 28, 2, 2, + 33, 34, 26, 25, 35, 2, 37, 27, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 24, 36, 2, 2, 2, 23, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 38, 2, 39, 29, 2, 2, 2, 2, 2, + 2, 39, 2, 40, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -434,8 +437,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 28, 30, - 31 + 15, 16, 17, 18, 19, 20, 21, 22, 29, 31, + 32 }; #if YYDEBUG @@ -443,13 +446,13 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyrline[] = { 0, 66, 66, 67, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 87, - 88, 89, 90, 92, 93, 94, 95, 96, 97, 100, - 101, 102, 103, 106, 107, 108, 109, 110, 111, 114, - 115, 116, 117, 118, 119, 122, 126, 131, 136, 141, - 149, 150, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 177, 178, 181, 182 + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, + 101, 102, 103, 104, 107, 108, 109, 110, 111, 112, + 115, 116, 117, 118, 119, 120, 123, 128, 133, 140, + 146, 155, 156, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 183, 184, 187, 188 }; #endif @@ -461,11 +464,11 @@ static const char *const yytname[] = "$end", "error", "$undefined", "FUNC", "ONE", "NUM", "IDENTIFIER", "UNIT", "INTEGER", "CONSTANT", "CELLADDRESS", "EQ", "NEQ", "LT", "GT", "GTE", "LTE", "STRING", "MINUSSIGN", "PROPERTY_REF", "DOCUMENT", - "OBJECT", "EXPONENT", "'?'", "':'", "'+'", "'*'", "'/'", "NUM_AND_UNIT", - "'^'", "NEG", "POS", "'('", "')'", "','", "';'", "'.'", "'#'", "'['", - "']'", "$accept", "input", "exp", "num", "args", "range", "cond", - "unit_exp", "identifier", "integer", "path", "subpath", "document", - "object", YY_NULLPTR + "OBJECT", "EXPONENT", "'?'", "':'", "'+'", "'*'", "'/'", "'%'", + "NUM_AND_UNIT", "'^'", "NEG", "POS", "'('", "')'", "','", "';'", "'.'", + "'#'", "'['", "']'", "$accept", "input", "exp", "num", "args", "range", + "cond", "unit_exp", "identifier", "integer", "path", "subpath", + "document", "object", YY_NULLPTR }; #endif @@ -476,17 +479,18 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 63, 58, 43, 42, 47, 278, 94, - 279, 280, 40, 41, 44, 59, 46, 35, 91, 93 + 275, 276, 277, 63, 58, 43, 42, 47, 37, 278, + 94, 279, 280, 40, 41, 44, 59, 46, 35, 91, + 93 }; # endif -#define YYPACT_NINF -102 +#define YYPACT_NINF -94 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-102))) + (!!((Yystate) == (-94))) -#define YYTABLE_NINF -75 +#define YYTABLE_NINF -76 #define yytable_value_is_error(Yytable_value) \ 0 @@ -495,20 +499,20 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 67, 92, -102, -102, 131, -102, -102, -102, -32, -2, - 117, 117, 67, 3, 24, 167, -4, 15, 86, -102, - -102, 23, 45, -7, -18, 117, 167, 153, -102, 73, - 74, -102, -102, 125, 60, 19, -102, -102, -102, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 67, 117, - -4, 59, 117, -4, -4, 4, 101, 3, 13, 26, - -102, 92, 92, 30, -102, -102, -102, -102, 55, -102, - 75, 77, -102, -102, 167, 167, 167, 167, 167, 167, - 103, 103, 90, 90, 59, -102, 148, 59, 59, 29, - -102, -102, -102, 95, -102, -102, -102, -102, -102, 167, - -102, 167, -102, 73, 140, 97, 109, 111, 117, -102, - 3, -102, 116, 126, 132, 73, 73, 73, 38, -102, - 120, 134, 154, -102, -102, -102, 73, 73, 73, -102, - -102, -102 + 68, 86, -94, -94, -24, -94, -94, -94, -33, 44, + 112, 112, 68, 78, 32, 172, -5, 15, 98, -94, + -94, 21, 31, -21, -16, 112, 172, 157, -94, 17, + 130, -94, -94, 128, 53, 19, -94, -94, -94, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 68, 112, + 112, -5, 70, 112, -5, -5, 1, 92, 78, 102, + 121, -94, 86, 86, 60, -94, -94, -94, -94, 67, + -94, 93, 95, -94, -94, 172, 172, 172, 172, 172, + 172, 3, 3, 96, 96, 70, 96, -94, 152, 70, + 70, 165, -94, -94, -94, 114, -94, -94, -94, -94, + -94, 172, -94, 172, -94, 17, 144, 120, 122, 123, + 112, -94, 78, -94, 131, 132, 134, 17, 17, 17, + 39, -94, 138, 158, 159, -94, -94, -94, 17, 17, + 17, -94, -94, -94 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -516,34 +520,34 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 19, 20, 52, 39, 21, 22, 53, 6, + 0, 0, 20, 21, 53, 40, 22, 23, 54, 6, 0, 0, 0, 0, 0, 2, 4, 0, 3, 7, - 45, 0, 0, 52, 53, 0, 23, 0, 24, 0, - 0, 8, 9, 0, 0, 52, 53, 46, 1, 0, + 46, 0, 0, 53, 54, 0, 24, 0, 25, 0, + 0, 8, 9, 0, 0, 53, 54, 47, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 17, 0, 0, 61, 63, 62, 60, 51, 0, 50, - 0, 0, 16, 44, 33, 34, 35, 36, 37, 38, - 11, 10, 12, 13, 14, 15, 0, 41, 40, 0, - 42, 73, 48, 0, 47, 32, 31, 30, 29, 25, - 27, 26, 28, 0, 0, 57, 56, 54, 0, 43, - 0, 70, 0, 0, 0, 0, 0, 0, 18, 49, - 67, 66, 64, 59, 58, 55, 0, 0, 0, 69, - 68, 65 + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 0, 0, 62, 64, 63, 61, 52, 0, + 51, 0, 0, 17, 45, 34, 35, 36, 37, 38, + 39, 11, 10, 12, 13, 15, 14, 16, 0, 42, + 41, 0, 43, 74, 49, 0, 48, 33, 32, 31, + 30, 26, 28, 27, 29, 0, 0, 58, 57, 55, + 0, 44, 0, 71, 0, 0, 0, 0, 0, 0, + 19, 50, 68, 67, 65, 60, 59, 56, 0, 0, + 0, 70, 69, 66 }; /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = +static const yytype_int8 yypgoto[] = { - -102, -102, 0, -102, -102, 44, -102, 5, -102, -35, - -6, -101, -102, 128 + -94, -94, 0, -94, -94, 51, -94, 6, -94, -36, + -6, -93, -94, 75 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 14, 33, 16, 27, 28, 17, 34, 19, 71, - 20, 66, 21, 22 + -1, 14, 33, 16, 27, 28, 17, 34, 19, 72, + 20, 67, 21, 22 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -551,50 +555,52 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 15, 26, 111, 5, -74, 18, 59, 37, 67, 35, - 31, 32, 69, 36, 123, 124, 125, 58, -74, 95, - 90, 51, 89, 96, 38, 129, 130, 131, 50, 29, - -72, 30, 97, 67, -73, -71, 98, 69, 52, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, - 92, 94, 86, 84, 109, 29, 45, 30, 87, 88, - 56, 99, 101, 46, 47, 48, 103, 49, 104, 114, - 1, 2, 3, 4, 5, 6, 7, 8, 67, 63, - 68, 57, 69, 64, 9, 10, 53, 54, 55, 55, - 65, 70, 11, 73, 105, 1, 2, 3, 23, 12, - 6, 7, 24, 13, 119, 100, 102, 35, 118, 9, - 10, 8, 53, 54, 106, 55, 107, 11, 91, 49, - 1, 2, 3, 4, 25, 6, 7, 8, 13, 47, - 48, 110, 49, 115, 9, 10, 39, 40, 41, 42, - 43, 44, 11, 45, 67, 116, 112, 117, 69, 25, - 46, 47, 48, 13, 49, 120, 126, 113, 72, 39, - 40, 41, 42, 43, 44, 121, 45, 29, -72, 30, - 127, 122, 108, 46, 47, 48, 0, 49, 39, 40, - 41, 42, 43, 44, 93, 45, 60, 61, 62, 0, - 128, 0, 46, 47, 48, 0, 49 + 15, 26, 5, 59, -75, 68, 18, 37, 60, 70, + 31, 32, 113, 29, -73, 30, 29, -73, 30, 91, + 92, -75, 52, 64, 125, 126, 127, 65, 51, 47, + 48, 49, 38, 50, 66, 131, 132, 133, 53, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, + 87, 94, 96, 88, 85, 111, 29, 45, 30, 57, + 89, 90, 101, 103, 46, 47, 48, 49, 58, 50, + 116, 1, 2, 3, 4, 5, 6, 7, 8, 54, + 55, -74, -72, 56, 35, 9, 10, 74, 36, 1, + 2, 3, 23, 11, 6, 7, 24, 105, 35, 106, + 56, 12, 8, 9, 10, 13, 121, 107, 97, 93, + 120, 11, 98, 102, 104, 1, 2, 3, 4, 25, + 6, 7, 8, 13, 54, 55, 50, 99, 56, 9, + 10, 100, 95, 108, 68, 109, 69, 11, 70, 39, + 40, 41, 42, 43, 44, 25, 45, 71, 68, 13, + 114, 112, 70, 46, 47, 48, 49, 117, 50, 118, + 119, 115, 73, 39, 40, 41, 42, 43, 44, 68, + 45, 122, 123, 70, 124, 128, 110, 46, 47, 48, + 49, 0, 50, 39, 40, 41, 42, 43, 44, 0, + 45, 61, 62, 63, 0, 129, 130, 46, 47, 48, + 49, 0, 50 }; static const yytype_int16 yycheck[] = { - 0, 1, 103, 7, 36, 0, 24, 13, 4, 6, - 10, 11, 8, 10, 115, 116, 117, 24, 36, 6, - 55, 16, 18, 10, 0, 126, 127, 128, 32, 36, - 37, 38, 6, 4, 36, 37, 10, 8, 23, 39, + 0, 1, 7, 24, 37, 4, 0, 13, 24, 8, + 10, 11, 105, 37, 38, 39, 37, 38, 39, 18, + 56, 37, 16, 6, 117, 118, 119, 10, 33, 26, + 27, 28, 0, 30, 17, 128, 129, 130, 23, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 56, 57, 52, 48, 89, 36, 18, 38, 53, 54, - 37, 61, 62, 25, 26, 27, 36, 29, 38, 104, - 3, 4, 5, 6, 7, 8, 9, 10, 4, 6, - 6, 36, 8, 10, 17, 18, 26, 27, 29, 29, - 17, 17, 25, 33, 39, 3, 4, 5, 6, 32, - 8, 9, 10, 36, 110, 61, 62, 6, 108, 17, - 18, 10, 26, 27, 39, 29, 39, 25, 17, 29, - 3, 4, 5, 6, 32, 8, 9, 10, 36, 26, - 27, 36, 29, 36, 17, 18, 11, 12, 13, 14, - 15, 16, 25, 18, 4, 36, 6, 36, 8, 32, - 25, 26, 27, 36, 29, 39, 36, 17, 33, 11, - 12, 13, 14, 15, 16, 39, 18, 36, 37, 38, - 36, 39, 24, 25, 26, 27, -1, 29, 11, 12, - 13, 14, 15, 16, 56, 18, 33, 34, 35, -1, - 36, -1, 25, 26, 27, -1, 29 + 50, 57, 58, 53, 48, 91, 37, 18, 39, 38, + 54, 55, 62, 63, 25, 26, 27, 28, 37, 30, + 106, 3, 4, 5, 6, 7, 8, 9, 10, 26, + 27, 37, 38, 30, 6, 17, 18, 34, 10, 3, + 4, 5, 6, 25, 8, 9, 10, 37, 6, 39, + 30, 33, 10, 17, 18, 37, 112, 40, 6, 17, + 110, 25, 10, 62, 63, 3, 4, 5, 6, 33, + 8, 9, 10, 37, 26, 27, 30, 6, 30, 17, + 18, 10, 57, 40, 4, 40, 6, 25, 8, 11, + 12, 13, 14, 15, 16, 33, 18, 17, 4, 37, + 6, 37, 8, 25, 26, 27, 28, 37, 30, 37, + 37, 17, 34, 11, 12, 13, 14, 15, 16, 4, + 18, 40, 40, 8, 40, 37, 24, 25, 26, 27, + 28, -1, 30, 11, 12, 13, 14, 15, 16, -1, + 18, 34, 35, 36, -1, 37, 37, 25, 26, 27, + 28, -1, 30 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -602,45 +608,45 @@ static const yytype_int16 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 17, - 18, 25, 32, 36, 41, 42, 43, 46, 47, 48, - 50, 52, 53, 6, 10, 32, 42, 44, 45, 36, - 38, 42, 42, 42, 47, 6, 10, 50, 0, 11, - 12, 13, 14, 15, 16, 18, 25, 26, 27, 29, - 32, 47, 23, 26, 27, 29, 37, 36, 24, 24, - 33, 34, 35, 6, 10, 17, 51, 4, 6, 8, - 17, 49, 33, 33, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 47, 42, 42, 47, 47, 18, - 49, 17, 50, 53, 50, 6, 10, 6, 10, 42, - 45, 42, 45, 36, 38, 39, 39, 39, 24, 49, - 36, 51, 6, 17, 49, 36, 36, 36, 42, 50, - 39, 39, 39, 51, 51, 51, 36, 36, 36, 51, - 51, 51 + 18, 25, 33, 37, 42, 43, 44, 47, 48, 49, + 51, 53, 54, 6, 10, 33, 43, 45, 46, 37, + 39, 43, 43, 43, 48, 6, 10, 51, 0, 11, + 12, 13, 14, 15, 16, 18, 25, 26, 27, 28, + 30, 33, 48, 23, 26, 27, 30, 38, 37, 24, + 24, 34, 35, 36, 6, 10, 17, 52, 4, 6, + 8, 17, 50, 34, 34, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 48, 43, 43, 43, 48, + 48, 18, 50, 17, 51, 54, 51, 6, 10, 6, + 10, 43, 46, 43, 46, 37, 39, 40, 40, 40, + 24, 50, 37, 52, 6, 17, 50, 37, 37, 37, + 43, 51, 40, 40, 40, 52, 52, 52, 37, 37, + 37, 52, 52, 52 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 40, 41, 41, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, - 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, - 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, - 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 52, 52, 53, 53 + 0, 41, 42, 42, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, + 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, + 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, + 49, 50, 50, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 53, 53, 54, 54 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 2, 1, 1, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 5, 1, - 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, - 3, 3, 3, 4, 3, 1, 2, 3, 3, 5, - 1, 1, 1, 1, 4, 6, 4, 4, 6, 6, - 3, 1, 1, 1, 4, 6, 4, 4, 6, 6, - 3, 1, 1, 1, 1 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 3, 3, 3, 4, 3, 1, 2, 3, 3, + 5, 1, 1, 1, 1, 4, 6, 4, 4, 6, + 6, 3, 1, 1, 1, 4, 6, 4, 4, 6, + 6, 3, 1, 1, 1, 1 }; @@ -1063,30 +1069,30 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN switch (yytype) { - case 42: /* exp */ + case 43: /* exp */ #line 59 "ExpressionParser.y" /* yacc.c:1257 */ { delete ((*yyvaluep).expr); } -#line 1070 "ExpressionParser.tab.c" /* yacc.c:1257 */ - break; - - case 44: /* args */ -#line 60 "ExpressionParser.y" /* yacc.c:1257 */ - { std::vector::const_iterator i = ((*yyvaluep).arguments).begin(); while (i != ((*yyvaluep).arguments).end()) { delete *i; ++i; } } #line 1076 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; - case 46: /* cond */ -#line 59 "ExpressionParser.y" /* yacc.c:1257 */ - { delete ((*yyvaluep).expr); } + case 45: /* args */ +#line 60 "ExpressionParser.y" /* yacc.c:1257 */ + { std::vector::const_iterator i = ((*yyvaluep).arguments).begin(); while (i != ((*yyvaluep).arguments).end()) { delete *i; ++i; } } #line 1082 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; - case 47: /* unit_exp */ + case 47: /* cond */ #line 59 "ExpressionParser.y" /* yacc.c:1257 */ { delete ((*yyvaluep).expr); } #line 1088 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; + case 48: /* unit_exp */ +#line 59 "ExpressionParser.y" /* yacc.c:1257 */ + { delete ((*yyvaluep).expr); } +#line 1094 "ExpressionParser.tab.c" /* yacc.c:1257 */ + break; + default: break; @@ -1348,283 +1354,289 @@ yyreduce: case 2: #line 66 "ExpressionParser.y" /* yacc.c:1646 */ { ScanResult = (yyvsp[0].expr); valueExpression = true; } -#line 1352 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1358 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 3: #line 67 "ExpressionParser.y" /* yacc.c:1646 */ { ScanResult = (yyvsp[0].expr); unitExpression = true; } -#line 1358 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1364 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 4: #line 70 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 1364 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1370 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 5: #line 71 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-1].expr), OperatorExpression::UNIT, (yyvsp[0].expr)); } -#line 1370 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1376 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 6: #line 72 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new StringExpression(DocumentObject, (yyvsp[0].string)); } -#line 1376 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1382 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 7: #line 73 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new VariableExpression(DocumentObject, (yyvsp[0].path)); } -#line 1382 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1388 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 8: #line 74 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1))); } -#line 1388 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1394 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 9: #line 75 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::POS, new NumberExpression(DocumentObject, Quantity(1))); } -#line 1394 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1400 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 10: #line 76 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::ADD, (yyvsp[0].expr)); } -#line 1400 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1406 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 11: #line 77 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::SUB, (yyvsp[0].expr)); } -#line 1406 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1412 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 12: #line 78 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } -#line 1412 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1418 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 13: #line 79 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1418 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1424 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 14: #line 80 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1424 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MOD, (yyvsp[0].expr)); } +#line 1430 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 15: #line 81 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); } -#line 1430 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } +#line 1436 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 16: #line 82 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 1436 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); } +#line 1442 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 17: #line 83 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new FunctionExpression(DocumentObject, (yyvsp[-2].func), (yyvsp[-1].arguments)); } -#line 1442 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = (yyvsp[-1].expr); } +#line 1448 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 18: #line 84 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new ConditionalExpression(DocumentObject, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1448 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new FunctionExpression(DocumentObject, (yyvsp[-2].func), (yyvsp[-1].arguments)); } +#line 1454 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 19: -#line 87 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new NumberExpression(DocumentObject, Quantity((yyvsp[0].fvalue))); } -#line 1454 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 85 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new ConditionalExpression(DocumentObject, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } +#line 1460 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 20: #line 88 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new NumberExpression(DocumentObject, Quantity((yyvsp[0].fvalue))); } -#line 1460 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1466 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 21: #line 89 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))); } -#line 1466 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new NumberExpression(DocumentObject, Quantity((yyvsp[0].fvalue))); } +#line 1472 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 22: #line 90 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new ConstantExpression(DocumentObject, (yyvsp[0].constant).name, Quantity((yyvsp[0].constant).fvalue)); } -#line 1472 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))); } +#line 1478 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 23: -#line 92 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.arguments).push_back((yyvsp[0].expr)); } -#line 1478 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 91 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new ConstantExpression(DocumentObject, (yyvsp[0].constant).name, Quantity((yyvsp[0].constant).fvalue)); } +#line 1484 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 24: #line 93 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.arguments).push_back((yyvsp[0].expr)); } -#line 1484 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1490 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 25: #line 94 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1490 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.arguments).push_back((yyvsp[0].expr)); } +#line 1496 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 26: #line 95 "ExpressionParser.y" /* yacc.c:1646 */ { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1496 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1502 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 27: #line 96 "ExpressionParser.y" /* yacc.c:1646 */ { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1502 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1508 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 28: #line 97 "ExpressionParser.y" /* yacc.c:1646 */ { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1508 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1514 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 29: -#line 100 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } -#line 1514 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 98 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } +#line 1520 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 30: #line 101 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } -#line 1520 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1526 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 31: #line 102 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } -#line 1526 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1532 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 32: #line 103 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } -#line 1532 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1538 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 33: -#line 106 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::EQ, (yyvsp[0].expr)); } -#line 1538 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 104 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } +#line 1544 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 34: #line 107 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::NEQ, (yyvsp[0].expr)); } -#line 1544 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::EQ, (yyvsp[0].expr)); } +#line 1550 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 35: #line 108 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LT, (yyvsp[0].expr)); } -#line 1550 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::NEQ, (yyvsp[0].expr)); } +#line 1556 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 36: #line 109 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GT, (yyvsp[0].expr)); } -#line 1556 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LT, (yyvsp[0].expr)); } +#line 1562 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 37: #line 110 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GTE, (yyvsp[0].expr)); } -#line 1562 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GT, (yyvsp[0].expr)); } +#line 1568 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 38: #line 111 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LTE, (yyvsp[0].expr)); } -#line 1568 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GTE, (yyvsp[0].expr)); } +#line 1574 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 39: -#line 114 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); } -#line 1574 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 112 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LTE, (yyvsp[0].expr)); } +#line 1580 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 40: #line 115 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1580 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); } +#line 1586 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 41: #line 116 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } -#line 1586 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } +#line 1592 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 42: #line 117 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue)))); } -#line 1592 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } +#line 1598 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 43: #line 118 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::POW, new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1)))); } -#line 1598 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue)))); } +#line 1604 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 44: #line 119 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 1604 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::POW, new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1)))); } +#line 1610 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 45: -#line 122 "ExpressionParser.y" /* yacc.c:1646 */ +#line 120 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = (yyvsp[-1].expr); } +#line 1616 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 46: +#line 123 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property within document object */ (yyval.path) = ObjectIdentifier(DocumentObject); (yyval.path).addComponents((yyvsp[0].components)); (yyval.path).resolveAmbiguity(); } -#line 1613 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1626 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; - case 46: -#line 126 "ExpressionParser.y" /* yacc.c:1646 */ + case 47: +#line 128 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property of the current document object */ (yyval.path) = ObjectIdentifier(DocumentObject,true); (yyval.path).setDocumentObjectName(DocumentObject); (yyval.path).addComponents((yyvsp[0].components)); } -#line 1623 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1636 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; - case 47: -#line 131 "ExpressionParser.y" /* yacc.c:1646 */ + case 48: +#line 133 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property within document object */ (yyval.path) = ObjectIdentifier(DocumentObject); (yyvsp[-2].string_or_identifier).checkImport(DocumentObject); @@ -1632,188 +1644,184 @@ yyreduce: (yyval.path).addComponents((yyvsp[0].components)); (yyval.path).resolveAmbiguity(); } -#line 1633 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 48: -#line 136 "ExpressionParser.y" /* yacc.c:1646 */ - { /* Path to property from an external document, within a named document object */ - (yyval.path) = ObjectIdentifier(DocumentObject); - (yyval.path).setDocumentName(std::move(yyvsp[-2].string_or_identifier), true); - if((yyvsp[0].components).size()) { - (yyval.path).setDocumentObjectName(ObjectIdentifier::String((yyvsp[0].components).front().getName(),false,true), true); - (yyvsp[0].components).pop_front(); - } - (yyval.path).addComponents((yyvsp[0].components)); - (yyval.path).resolveAmbiguity(); - } -#line 1643 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1648 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 49: -#line 141 "ExpressionParser.y" /* yacc.c:1646 */ +#line 140 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property from an external document, within a named document object */ (yyval.path) = ObjectIdentifier(DocumentObject); - (yyval.path).setDocumentName(std::move(yyvsp[-4].string_or_identifier), true); - (yyval.path).setDocumentObjectName(std::move(yyvsp[-2].string_or_identifier), true); + (yyval.path).setDocumentName(std::move((yyvsp[-2].string_or_identifier)), true); (yyval.path).addComponents((yyvsp[0].components)); (yyval.path).resolveAmbiguity(); } -#line 1654 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1659 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 50: -#line 149 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.ivalue) = (yyvsp[0].ivalue); } -#line 1660 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 146 "ExpressionParser.y" /* yacc.c:1646 */ + { /* Path to property from an external document, within a named document object */ + (yyval.path) = ObjectIdentifier(DocumentObject); + (yyval.path).setDocumentName(std::move((yyvsp[-4].string_or_identifier)), true); + (yyval.path).setDocumentObjectName(std::move((yyvsp[-2].string_or_identifier)), true); + (yyval.path).addComponents((yyvsp[0].components)); + (yyval.path).resolveAmbiguity(); + } +#line 1671 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 51: -#line 150 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.ivalue) = (yyvsp[0].fvalue); } -#line 1666 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 155 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.ivalue) = (yyvsp[0].ivalue); } +#line 1677 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 52: -#line 154 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } -#line 1672 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 156 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.ivalue) = (yyvsp[0].fvalue); } +#line 1683 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 53: -#line 155 "ExpressionParser.y" /* yacc.c:1646 */ +#line 160 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } -#line 1678 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1689 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 54: -#line 156 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-1].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1684 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 161 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } +#line 1695 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 55: -#line 157 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-3].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1690 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 162 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-1].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } +#line 1701 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 56: -#line 158 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-1].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1696 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 163 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-3].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } +#line 1707 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 57: -#line 159 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::MapComponent((yyvsp[-1].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1702 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 164 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-1].string), true))); } +#line 1713 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 58: -#line 160 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1708 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 165 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::MapComponent((yyvsp[-1].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } +#line 1719 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 59: -#line 161 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent((yyvsp[-3].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1714 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 166 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } +#line 1725 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 60: -#line 162 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } -#line 1720 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 167 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent((yyvsp[-3].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } +#line 1731 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 61: -#line 165 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } -#line 1726 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 168 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } +#line 1737 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 62: -#line 166 "ExpressionParser.y" /* yacc.c:1646 */ +#line 171 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } -#line 1732 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1743 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 63: -#line 167 "ExpressionParser.y" /* yacc.c:1646 */ +#line 172 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } -#line 1738 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1749 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 64: -#line 168 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-1].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1744 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 173 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); } +#line 1755 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 65: -#line 169 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-3].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1750 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 174 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-1].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } +#line 1761 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 66: -#line 170 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-1].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1756 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 175 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::ArrayComponent((yyvsp[-3].ivalue))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string)));(yyval.components) = (yyvsp[0].components); } +#line 1767 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 67: -#line 171 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::MapComponent((yyvsp[-1].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } -#line 1762 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 176 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-1].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } +#line 1773 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 68: -#line 172 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1768 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 177 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::MapComponent((yyvsp[-1].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-3].string))); } +#line 1779 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 69: -#line 173 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent((yyvsp[-3].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string))); (yyval.components) = (yyvsp[0].components); } -#line 1774 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 178 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent(ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string)));(yyval.components) = (yyvsp[0].components); } +#line 1785 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 70: -#line 174 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } -#line 1780 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 179 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::MapComponent((yyvsp[-3].string))); (yyval.components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-5].string)));(yyval.components) = (yyvsp[0].components); } +#line 1791 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 71: -#line 177 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } -#line 1786 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 180 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } +#line 1797 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 72: -#line 178 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string)); } -#line 1792 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 183 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } +#line 1803 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 73: -#line 181 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } -#line 1798 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 184 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string)); } +#line 1809 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 74: -#line 182 "ExpressionParser.y" /* yacc.c:1646 */ +#line 187 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } -#line 1804 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1815 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 75: +#line 188 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } +#line 1821 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; -#line 1808 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1825 "ExpressionParser.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2041,5 +2049,5 @@ yyreturn: #endif return yyresult; } -#line 185 "ExpressionParser.y" /* yacc.c:1906 */ +#line 191 "ExpressionParser.y" /* yacc.c:1906 */ diff --git a/src/App/ExpressionParser.tab.h b/src/App/ExpressionParser.tab.h index 806b158509..906d447a65 100644 --- a/src/App/ExpressionParser.tab.h +++ b/src/App/ExpressionParser.tab.h @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program 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 General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,50 +26,56 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +#ifndef YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED +# define YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif -/* Tokens. */ +/* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - FUNC = 258, - ONE = 259, - NUM = 260, - IDENTIFIER = 261, - UNIT = 262, - INTEGER = 263, - CONSTANT = 264, - CELLADDRESS = 265, - EQ = 266, - NEQ = 267, - LT = 268, - GT = 269, - GTE = 270, - LTE = 271, - STRING = 272, - MINUSSIGN = 273, - PROPERTY_REF = 274, - DOCUMENT = 275, - OBJECT = 276, - EXPONENT = 277, - NEG = 278, - POS = 279 - }; + enum yytokentype + { + FUNC = 258, + ONE = 259, + NUM = 260, + IDENTIFIER = 261, + UNIT = 262, + INTEGER = 263, + CONSTANT = 264, + CELLADDRESS = 265, + EQ = 266, + NEQ = 267, + LT = 268, + GT = 269, + GTE = 270, + LTE = 271, + STRING = 272, + MINUSSIGN = 273, + PROPERTY_REF = 274, + DOCUMENT = 275, + OBJECT = 276, + EXPONENT = 277, + NUM_AND_UNIT = 278, + NEG = 279, + POS = 280 + }; #endif +/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - extern YYSTYPE yylval; +int yyparse (void); +#endif /* !YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED */ diff --git a/src/App/ExpressionParser.y b/src/App/ExpressionParser.y index 6ad9635d64..3c7f7ccca5 100644 --- a/src/App/ExpressionParser.y +++ b/src/App/ExpressionParser.y @@ -49,7 +49,7 @@ std::stack functions; /**< Function %left EQ NEQ LT GT GTE LTE %left '?' ':' %left MINUSSIGN '+' - %left '*' '/' + %left '*' '/' '%' %precedence NUM_AND_UNIT %left '^' /* exponentiation */ %left EXPONENT @@ -77,6 +77,7 @@ exp: num { $$ = $1; | exp MINUSSIGN exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::SUB, $3); } | exp '*' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); } | exp '/' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); } + | 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; } @@ -158,12 +159,12 @@ integer: INTEGER { $$ = $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 '[' 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 '[' 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; } ; diff --git a/src/App/lex.ExpressionParser.c b/src/App/lex.ExpressionParser.c index b5506ad619..994320e3aa 100644 --- a/src/App/lex.ExpressionParser.c +++ b/src/App/lex.ExpressionParser.c @@ -986,7 +986,7 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 5, 6, 7, 8, 9, 1, 1, 10, 11, + 1, 5, 6, 7, 8, 9, 8, 1, 10, 11, 8, 8, 12, 13, 14, 15, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 17, 18, 19, 8, 20, 21, 22, 23, 22, 24, 22, diff --git a/src/Mod/Spreadsheet/App/Sheet.cpp b/src/Mod/Spreadsheet/App/Sheet.cpp index 261ae353d7..355071e918 100644 --- a/src/Mod/Spreadsheet/App/Sheet.cpp +++ b/src/Mod/Spreadsheet/App/Sheet.cpp @@ -705,7 +705,7 @@ void Sheet::updateProperty(CellAddress key) Base::PyGILStateLocker lock; auto py_expr = freecad_dynamic_cast(output.get()); if(py_expr) - setObjectProperty(key, py_expr->getPyObject()); + setObjectProperty(key, py_expr->getPyValue()); else setObjectProperty(key, Py::Object()); } diff --git a/src/Mod/Spreadsheet/TestSpreadsheet.py b/src/Mod/Spreadsheet/TestSpreadsheet.py index 49277b8852..846013a387 100644 --- a/src/Mod/Spreadsheet/TestSpreadsheet.py +++ b/src/Mod/Spreadsheet/TestSpreadsheet.py @@ -136,7 +136,7 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.H2, u'ERR: Quantity::operator <(): quantities need to have same unit to compare') self.assertEqual(sheet.H3, u'ERR: Quantity::operator >(): quantities need to have same unit to compare') self.assertEqual(sheet.H4, 4) - self.assertEqual(sheet.H5, u'ERR: Quantity::operator +(): Unit mismatch in minus operation') + self.assertEqual(sheet.H5, u'ERR: Quantity::operator -(): Unit mismatch in minus operation') self.assertEqual(sheet.H6, u'ERR: Quantity::operator +=(): Unit mismatch in plus operation') def assertMostlyEqual(self, a, b):