From 08692f811b008636012a2f44058b5e9276c73056 Mon Sep 17 00:00:00 2001 From: Eivind Kvedalen Date: Sat, 26 Mar 2016 15:46:28 +0100 Subject: [PATCH] Expressions: Added support for aggregate functions and ranges. --- src/App/Application.cpp | 2 + src/App/CMakeLists.txt | 2 + src/App/Expression.cpp | 306 +++++++++++++-- src/App/Expression.h | 45 +++ src/App/ExpressionParser.l | 180 ++++----- src/App/ExpressionParser.tab.c | 682 ++++++++++++++++++--------------- src/App/ExpressionParser.y | 14 +- src/App/Range.cpp | 244 ++++++++++++ src/App/Range.h | 139 +++++++ src/App/lex.ExpressionParser.c | 180 ++++----- 10 files changed, 1269 insertions(+), 525 deletions(-) create mode 100644 src/App/Range.cpp create mode 100644 src/App/Range.h diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 0c3311381..e8adf1132 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1141,6 +1141,8 @@ void Application::initTypes(void) App ::StringExpression ::init(); App ::FunctionExpression ::init(); App ::BooleanExpression ::init(); + App ::RangeExpression ::init(); + } void Application::initConfig(int argc, char ** argv) diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 6efca1390..e03e21ec0 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -70,6 +70,7 @@ SET(Document_CPP_SRCS MeasureDistance.cpp Placement.cpp Plane.cpp + Range.cpp Transactions.cpp VRMLObject.cpp MaterialObject.cpp @@ -96,6 +97,7 @@ SET(Document_HPP_SRCS MeasureDistance.h Placement.h Plane.h + Range.h Transactions.h VRMLObject.h MaterialObject.h diff --git a/src/App/Expression.cpp b/src/App/Expression.cpp index 286d07f0e..312c3ac16 100644 --- a/src/App/Expression.cpp +++ b/src/App/Expression.cpp @@ -581,18 +581,50 @@ FunctionExpression::FunctionExpression(const DocumentObject *_owner, Function _f , args(_args) { switch (f) { - case NONE: - throw ExpressionError("Unknown function"); + case ACOS: + case ASIN: + case ATAN: + case ABS: + case EXP: + case LOG: + case LOG10: + case SIN: + case SINH: + case TAN: + case TANH: + case SQRT: + case COS: + case COSH: + case ROUND: + case TRUNC: + case CEIL: + case FLOOR: + if (args.size() != 1) + throw ExpressionError("Invalid number of arguments: exactly one required."); + break; case MOD: case ATAN2: case POW: if (args.size() != 2) - throw ExpressionError("Invalid number of arguments."); + throw ExpressionError("Invalid number of arguments: eaxctly two required."); break; + case STDDEV: + if (args.size() < 2) + throw ExpressionError("Invalid number of arguments: at least two required."); + break; + case SUM: + case AVERAGE: + case COUNT: + case MIN: + case MAX: + if (args.size() == 0) + throw ExpressionError("Invalid number of arguments: at least one required."); + break; + case NONE: + case AGGREGATES: + case LAST: default: - if (args.size() != 1) - throw ExpressionError("Invalid number of arguments."); - break; + throw ExpressionError("Unknown function"); } } @@ -625,6 +657,136 @@ bool FunctionExpression::isTouched() const return false; } +Expression * FunctionExpression::evalAggregate() const +{ + + class Collector { + + public: + + Collector(Function _f) + : f(_f) + , first(true) + , n(0) { + + } + + void collect(Quantity value) { + if (first) { + q.setUnit(value.getUnit()); + mean.setUnit(value.getUnit()); + M2.setUnit(value.getUnit()); + } + + switch (f) { + case AVERAGE: + n++; + case SUM: + q = q + value; + break; + case STDDEV: { + n++; + + const Quantity delta = value - mean; + mean = mean + delta / n; + M2 = M2 + delta * (value - mean); + break; + } + case COUNT: + q = q + 1; + break; + case MIN: + if (first || value < q) + q = value; + break; + case MAX: + if (first || value > q) + q = value; + break; + default: + break; + } + + first = false; + + } + + Quantity getQuantity() const { + switch (static_cast(f)) { + case AVERAGE: + return q / (double)n; + case STDDEV: + if (n < 2) + return Quantity(); + else + return (M2 / (n - 1.0)).pow(Quantity(0.5)); + default: + break; + } + + return q; + } + + private: + Function f; + bool first; + int n; + Quantity q; + Quantity mean; + Quantity M2; + }; + + switch (f) { + case SUM: + case AVERAGE: + case STDDEV: + case COUNT: + case MIN: + case MAX: { + Collector c(f); + + for (size_t i = 0; i< args.size(); ++i) { + + if (args[i]->isDerivedFrom(RangeExpression::getClassTypeId())) { + RangeExpression * v = static_cast(args[i]); + Range range(v->getRange()); + + do { + Property * p = owner->getPropertyByName(range.address().c_str()); + PropertyQuantity * qp; + PropertyFloat * fp; + + if (!p) + continue; + + if ((qp = freecad_dynamic_cast(p)) != 0) + c.collect(qp->getQuantityValue()); + else if ((fp = freecad_dynamic_cast(p)) != 0) + c.collect(fp->getValue()); + else + throw Exception("Invalid property type for aggregate"); + } while (range.next()); + } + else if (args[i]->isDerivedFrom(App::VariableExpression::getClassTypeId())) { + std::auto_ptr e(args[i]->eval()); + NumberExpression * n(freecad_dynamic_cast(e.get())); + + if (n) + c.collect(n->getQuantity()); + } + else if (args[i]->isDerivedFrom(App::NumberExpression::getClassTypeId())) { + c.collect(static_cast(args[i])->getQuantity()); + } + } + + return new NumberExpression(owner, c.getQuantity()); + } + default: + assert(0); + return 0; + } +} + /** * Evaluate function. Returns a NumberExpression if evaluation is successfuly. * Throws an ExpressionError exception if something fails. @@ -634,6 +796,10 @@ bool FunctionExpression::isTouched() const Expression * FunctionExpression::eval() const { + // Handle aggregate functions + if (f > AGGREGATES) + return evalAggregate(); + std::auto_ptr e1(args[0]->eval()); std::auto_ptr e2(args.size() > 1 ? args[1]->eval() : 0); NumberExpression * v1 = freecad_dynamic_cast(e1.get()); @@ -873,49 +1039,69 @@ Expression *FunctionExpression::simplify() const std::string FunctionExpression::toString() const { + std::stringstream ss; + + for (size_t i = 0; i < args.size(); ++i) { + ss << args[i]->toString(); + if (i != args.size() - 1) + ss << "; "; + } + switch (f) { case ACOS: - return "acos(" + args[0]->toString() + ")"; + return "acos(" + ss.str() + ")"; case ASIN: - return "asin(" + args[0]->toString() + ")"; + return "asin(" + ss.str() + ")"; case ATAN: - return "atan(" + args[0]->toString() + ")"; + return "atan(" + ss.str() + ")"; case ABS: - return "abs(" + args[0]->toString() + ")"; + return "abs(" + ss.str() + ")"; case EXP: - return "exp(" + args[0]->toString() + ")"; + return "exp(" + ss.str() + ")"; case LOG: - return "log(" + args[0]->toString() + ")"; + return "log(" + ss.str() + ")"; case LOG10: - return "log10(" + args[0]->toString() + ")"; + return "log10(" + ss.str() + ")"; case SIN: - return "sin(" + args[0]->toString() + ")"; + return "sin(" + ss.str() + ")"; case SINH: - return "sinh(" + args[0]->toString() + ")"; + return "sinh(" + ss.str() + ")"; case TAN: - return "tan(" + args[0]->toString() + ")"; + return "tan(" + ss.str() + ")"; case TANH: - return "tanh(" + args[0]->toString() + ")"; + return "tanh(" + ss.str() + ")"; case SQRT: - return "sqrt(" + args[0]->toString() + ")"; + return "sqrt(" + ss.str() + ")"; case COS: - return "cos(" + args[0]->toString() + ")"; + return "cos(" + ss.str() + ")"; case COSH: - return "cosh(" + args[0]->toString() + ")"; + return "cosh(" + ss.str() + ")"; case MOD: - return "mod(" + args[0]->toString() + ", " + args[1]->toString() + ")"; + return "mod(" + ss.str() + ")"; case ATAN2: - return "atan2(" + args[0]->toString() + ", " + args[1]->toString() + ")"; + return "atan2(" + ss.str() + ")"; case POW: - return "pow(" + args[0]->toString() + ", " + args[1]->toString() + ")"; + return "pow(" + ss.str() + ")"; case ROUND: - return "round(" + args[0]->toString() + ")"; + return "round(" + ss.str() + ")"; case TRUNC: - return "trunc(" + args[0]->toString() + ")"; + return "trunc(" + ss.str() + ")"; case CEIL: - return "ceil(" + args[0]->toString() + ")"; + return "ceil(" + ss.str() + ")"; case FLOOR: - return "floor(" + args[0]->toString() + ")"; + return "floor(" + ss.str() + ")"; + case SUM: + return "sum(" + ss.str() + ")"; + case COUNT: + return "count(" + ss.str() + ")"; + case AVERAGE: + return "average(" + ss.str() + ")"; + case STDDEV: + return "stddev(" + ss.str() + ")"; + case MIN: + return "min(" + ss.str() + ")"; + case MAX: + return "max(" + ss.str() + ")"; default: assert(0); return std::string(); @@ -1303,6 +1489,62 @@ Expression *BooleanExpression::copy() const return new BooleanExpression(owner, getValue() > 0.5 ? true : false); } +TYPESYSTEM_SOURCE(App::RangeExpression, App::Expression); + +RangeExpression::RangeExpression(const DocumentObject *_owner, const std::string &begin, const std::string &end) + : Expression(_owner) + , range((begin + ":" + end).c_str()) +{ +} + +bool RangeExpression::isTouched() const +{ + Range i(range); + + do { + Property * prop = owner->getPropertyByName(i.address().c_str()); + + if (prop && prop->isTouched()) + return true; + } while (i.next()); + + return false; +} + +Expression *RangeExpression::eval() const +{ + throw Exception("Range expression cannot be evaluated"); +} + +std::string RangeExpression::toString() const +{ + return range.rangeString(); +} + +Expression *RangeExpression::copy() const +{ + return new RangeExpression(owner, range.fromCellString(), range.toCellString()); +} + +void RangeExpression::getDeps(std::set &props) const +{ + Range i(range); + + do { + props.insert(ObjectIdentifier(owner, i.address())); + } while (i.next()); +} + +Expression *RangeExpression::simplify() const +{ + return copy(); +} + +void RangeExpression::setRange(const Range &r) +{ + range = r; +} + namespace App { namespace ExpressionParser { @@ -1311,7 +1553,7 @@ namespace ExpressionParser { * Error function for parser. Throws a generic Base::Exception with the parser error. */ -void ExpressionParser_yyerror(char *errorinfo) +void ExpressionParser_yyerror(const char *errorinfo) { } @@ -1404,6 +1646,14 @@ static void initParser(const App::DocumentObject *owner) registered_functions["ceil"] = FunctionExpression::CEIL; registered_functions["floor"] = FunctionExpression::FLOOR; + // Aggregates + registered_functions["sum"] = FunctionExpression::SUM; + registered_functions["count"] = FunctionExpression::COUNT; + registered_functions["average"] = FunctionExpression::AVERAGE; + registered_functions["stddev"] = FunctionExpression::STDDEV; + registered_functions["min"] = FunctionExpression::MIN; + registered_functions["max"] = FunctionExpression::MAX; + has_registered_functions = true; } } diff --git a/src/App/Expression.h b/src/App/Expression.h index 6da8408de..3f3c0b523 100644 --- a/src/App/Expression.h +++ b/src/App/Expression.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace App { @@ -314,6 +315,18 @@ public: TRUNC, CEIL, FLOOR, + + // Aggregates + AGGREGATES, + + SUM, + AVERAGE, + STDDEV, + COUNT, + MIN, + MAX, + + // Last one LAST, }; @@ -338,6 +351,8 @@ public: virtual void visit(ExpressionVisitor & v); protected: + Expression *evalAggregate() const; + Function f; /**< Function to execute */ std::vector args; /** Arguments to function*/ }; @@ -419,6 +434,35 @@ protected: std::string text; /**< Text string */ }; +class AppExport RangeExpression : public App::Expression { + TYPESYSTEM_HEADER(); +public: + RangeExpression(const App::DocumentObject * _owner = 0, const std::string & begin = std::string(), const std::string & end = std::string()); + + virtual ~RangeExpression() { } + + virtual bool isTouched() const; + + virtual Expression * eval() const; + + virtual std::string toString() const; + + virtual Expression * copy() const; + + virtual int priority() const { return 20; } + + virtual void getDeps(std::set &props) const; + + virtual App::Expression * simplify() const; + + Range getRange() const { return range; } + + void setRange(const Range & r); + +protected: + Range range; +}; + namespace ExpressionParser { AppExport Expression * parse(const App::DocumentObject *owner, const char *buffer); AppExport UnitExpression * parseUnit(const App::DocumentObject *owner, const char *buffer); @@ -446,6 +490,7 @@ public: double fvalue; } constant; std::vector arguments; + std::vector list; std::string string; FunctionExpression::Function func; ObjectIdentifier::String string_or_identifier; diff --git a/src/App/ExpressionParser.l b/src/App/ExpressionParser.l index 050f3fe57..dbaa6e8ba 100644 --- a/src/App/ExpressionParser.l +++ b/src/App/ExpressionParser.l @@ -16,7 +16,7 @@ extern std::stack functions; /**< F extern int last_column; extern int column; -#define COUNT do { last_column = column; column += yyleng; } while (0) +#define COUNTCHARS do { last_column = column; column += yyleng; } while (0) %} @@ -141,114 +141,114 @@ EXPO [eE][-+]?[0-9]+ %% /*** Filter language Part ***/ -[ \t]+ COUNT; +[ \t]+ COUNTCHARS; [\n] column = 0; -\<\<(\\(.|\n)|[^\\>\n])*\>\> COUNT; yylval.string = unquote(yytext); return STRING; +\<\<(\\(.|\n)|[^\\>\n])*\>\> COUNTCHARS; yylval.string = unquote(yytext); return STRING; -[+()=/*^,\.\{\}\[\]:;@\?#] COUNT; return *yytext; +[+()=/*^,\.\{\}\[\]:;@\?#] COUNTCHARS; return *yytext; -"==" COUNT; return EQ; -"!=" COUNT; return NEQ; -">" COUNT; return GT; -"<" COUNT; return LT; -">=" COUNT; return GTE; -"<=" COUNT; return LTE; +"==" COUNTCHARS; return EQ; +"!=" COUNTCHARS; return NEQ; +">" COUNTCHARS; return GT; +"<" COUNTCHARS; return LT; +">=" COUNTCHARS; return GTE; +"<=" COUNTCHARS; return LTE; -"-" COUNT; return MINUSSIGN; -"\xe2\x88\x92" COUNT; return MINUSSIGN; +"-" COUNTCHARS; return MINUSSIGN; +"\xe2\x88\x92" COUNTCHARS; return MINUSSIGN; -"nm" COUNT; yylval.quantity.scaler = Quantity::NanoMetre; yylval.quantity.unitStr = yytext; return UNIT; // nano meter -"um" COUNT; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = yytext; return UNIT; // micro meter -"\xC2\xB5m" COUNT; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = yytext; return UNIT; // micro meter (greek micro in UTF8) -"mm" COUNT; yylval.quantity.scaler = Quantity::MilliMetre; yylval.quantity.unitStr = yytext; return UNIT; // milli meter (internal standard length) -"cm" COUNT; yylval.quantity.scaler = Quantity::CentiMetre; yylval.quantity.unitStr = yytext; return UNIT; // centi meter -"dm" COUNT; yylval.quantity.scaler = Quantity::DeciMetre; yylval.quantity.unitStr = yytext; return UNIT; // deci meter -"m" COUNT; yylval.quantity.scaler = Quantity::Metre; yylval.quantity.unitStr = yytext; return UNIT; // metre -"km" COUNT; yylval.quantity.scaler = Quantity::KiloMetre; yylval.quantity.unitStr = yytext; return UNIT; // kilo meter +"nm" COUNTCHARS; yylval.quantity.scaler = Quantity::NanoMetre; yylval.quantity.unitStr = yytext; return UNIT; // nano meter +"um" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = yytext; return UNIT; // micro meter +"\xC2\xB5m" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = yytext; return UNIT; // micro meter (greek micro in UTF8) +"mm" COUNTCHARS; yylval.quantity.scaler = Quantity::MilliMetre; yylval.quantity.unitStr = yytext; return UNIT; // milli meter (internal standard length) +"cm" COUNTCHARS; yylval.quantity.scaler = Quantity::CentiMetre; yylval.quantity.unitStr = yytext; return UNIT; // centi meter +"dm" COUNTCHARS; yylval.quantity.scaler = Quantity::DeciMetre; yylval.quantity.unitStr = yytext; return UNIT; // deci meter +"m" COUNTCHARS; yylval.quantity.scaler = Quantity::Metre; yylval.quantity.unitStr = yytext; return UNIT; // metre +"km" COUNTCHARS; yylval.quantity.scaler = Quantity::KiloMetre; yylval.quantity.unitStr = yytext; return UNIT; // kilo meter -"l" COUNT; yylval.quantity.scaler = Quantity::Liter; yylval.quantity.unitStr = yytext; return UNIT; // Liter dm^3 +"l" COUNTCHARS; yylval.quantity.scaler = Quantity::Liter; yylval.quantity.unitStr = yytext; return UNIT; // Liter dm^3 -"ug" COUNT; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = yytext; return UNIT; // micro gram -"\xC2\xB5g" COUNT; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = yytext; return UNIT; // micro gram -"mg" COUNT; yylval.quantity.scaler = Quantity::MilliGram; yylval.quantity.unitStr = yytext; return UNIT; // milli gram -"g" COUNT; yylval.quantity.scaler = Quantity::Gram; yylval.quantity.unitStr = yytext; return UNIT; // gram -"kg" COUNT; yylval.quantity.scaler = Quantity::KiloGram; yylval.quantity.unitStr = yytext; return UNIT; // kilo gram (internal standard for mass) -"t" COUNT; yylval.quantity.scaler = Quantity::Ton; yylval.quantity.unitStr = yytext; return UNIT; // Metric Tonne +"ug" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = yytext; return UNIT; // micro gram +"\xC2\xB5g" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = yytext; return UNIT; // micro gram +"mg" COUNTCHARS; yylval.quantity.scaler = Quantity::MilliGram; yylval.quantity.unitStr = yytext; return UNIT; // milli gram +"g" COUNTCHARS; yylval.quantity.scaler = Quantity::Gram; yylval.quantity.unitStr = yytext; return UNIT; // gram +"kg" COUNTCHARS; yylval.quantity.scaler = Quantity::KiloGram; yylval.quantity.unitStr = yytext; return UNIT; // kilo gram (internal standard for mass) +"t" COUNTCHARS; yylval.quantity.scaler = Quantity::Ton; yylval.quantity.unitStr = yytext; return UNIT; // Metric Tonne -"s" COUNT; yylval.quantity.scaler = Quantity::Second; yylval.quantity.unitStr = yytext; return UNIT; // second (internal standard time) -"min" COUNT; yylval.quantity.scaler = Quantity::Minute; yylval.quantity.unitStr = yytext; return UNIT; // minute -"h" COUNT; yylval.quantity.scaler = Quantity::Hour; yylval.quantity.unitStr = yytext; return UNIT; // hour +"s" COUNTCHARS; yylval.quantity.scaler = Quantity::Second; yylval.quantity.unitStr = yytext; return UNIT; // second (internal standard time) +"min" COUNTCHARS; yylval.quantity.scaler = Quantity::Minute; yylval.quantity.unitStr = yytext; return UNIT; // minute +"h" COUNTCHARS; yylval.quantity.scaler = Quantity::Hour; yylval.quantity.unitStr = yytext; return UNIT; // hour -"A" COUNT; yylval.quantity.scaler = Quantity::Ampere; yylval.quantity.unitStr = yytext; return UNIT; // Ampere (internal standard electric current) -"mA" COUNT; yylval.quantity.scaler = Quantity::MilliAmpere; yylval.quantity.unitStr = yytext; return UNIT; // milli Ampere -"kA" COUNT; yylval.quantity.scaler = Quantity::KiloAmpere; yylval.quantity.unitStr = yytext; return UNIT; // kilo Ampere -"MA" COUNT; yylval.quantity.scaler = Quantity::MegaAmpere; yylval.quantity.unitStr = yytext; return UNIT; // Mega Ampere +"A" COUNTCHARS; yylval.quantity.scaler = Quantity::Ampere; yylval.quantity.unitStr = yytext; return UNIT; // Ampere (internal standard electric current) +"mA" COUNTCHARS; yylval.quantity.scaler = Quantity::MilliAmpere; yylval.quantity.unitStr = yytext; return UNIT; // milli Ampere +"kA" COUNTCHARS; yylval.quantity.scaler = Quantity::KiloAmpere; yylval.quantity.unitStr = yytext; return UNIT; // kilo Ampere +"MA" COUNTCHARS; yylval.quantity.scaler = Quantity::MegaAmpere; yylval.quantity.unitStr = yytext; return UNIT; // Mega Ampere -"K" COUNT; yylval.quantity.scaler = Quantity::Kelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin (internal standard thermodynamic temperature) -"mK" COUNT; yylval.quantity.scaler = Quantity::MilliKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin -"\xC2\xB5K" COUNT; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin -"uK" COUNT; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin +"K" COUNTCHARS; yylval.quantity.scaler = Quantity::Kelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin (internal standard thermodynamic temperature) +"mK" COUNTCHARS; yylval.quantity.scaler = Quantity::MilliKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin +"\xC2\xB5K" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin +"uK" COUNTCHARS; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = yytext; return UNIT; // Kelvin -"mol" COUNT; yylval.quantity.scaler = Quantity::Mole; yylval.quantity.unitStr = yytext; return UNIT; // Mole (internal standard amount of substance) +"mol" COUNTCHARS; yylval.quantity.scaler = Quantity::Mole; yylval.quantity.unitStr = yytext; return UNIT; // Mole (internal standard amount of substance) -"cd" COUNT; yylval.quantity.scaler = Quantity::Candela; yylval.quantity.unitStr = yytext; return UNIT; // Candela (internal standard luminous intensity) +"cd" COUNTCHARS; yylval.quantity.scaler = Quantity::Candela; yylval.quantity.unitStr = yytext; return UNIT; // Candela (internal standard luminous intensity) -"in" COUNT; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch -"\"" COUNT; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch -"ft" COUNT; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot -"'" COUNT; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot -"thou" COUNT; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // thou (in/1000) -"mil" COUNT; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // mil (the thou in US) -"yd" COUNT; yylval.quantity.scaler = Quantity::Yard; yylval.quantity.unitStr = yytext; return UNIT; // yard -"mi" COUNT; yylval.quantity.scaler = Quantity::Mile; yylval.quantity.unitStr = yytext; return UNIT; // mile +"in" COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch +"\"" COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch +"ft" COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot +"'" COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot +"thou" COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // thou (in/1000) +"mil" COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // mil (the thou in US) +"yd" COUNTCHARS; yylval.quantity.scaler = Quantity::Yard; yylval.quantity.unitStr = yytext; return UNIT; // yard +"mi" COUNTCHARS; yylval.quantity.scaler = Quantity::Mile; yylval.quantity.unitStr = yytext; return UNIT; // mile -"lb" COUNT; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = yytext; return UNIT; // pound -"lbm" COUNT; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = yytext; return UNIT; // pound -"oz" COUNT; yylval.quantity.scaler = Quantity::Ounce; yylval.quantity.unitStr = yytext; return UNIT; // ounce -"st" COUNT; yylval.quantity.scaler = Quantity::Stone; yylval.quantity.unitStr = yytext; return UNIT; // Stone -"cwt" COUNT; yylval.quantity.scaler = Quantity::Hundredweights; yylval.quantity.unitStr = yytext; return UNIT; // hundredweights +"lb" COUNTCHARS; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = yytext; return UNIT; // pound +"lbm" COUNTCHARS; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = yytext; return UNIT; // pound +"oz" COUNTCHARS; yylval.quantity.scaler = Quantity::Ounce; yylval.quantity.unitStr = yytext; return UNIT; // ounce +"st" COUNTCHARS; yylval.quantity.scaler = Quantity::Stone; yylval.quantity.unitStr = yytext; return UNIT; // Stone +"cwt" COUNTCHARS; yylval.quantity.scaler = Quantity::Hundredweights; yylval.quantity.unitStr = yytext; return UNIT; // hundredweights -"lbf" COUNT; yylval.quantity.scaler = Quantity::PoundForce; yylval.quantity.unitStr = yytext; return UNIT; // pound +"lbf" COUNTCHARS; yylval.quantity.scaler = Quantity::PoundForce; yylval.quantity.unitStr = yytext; return UNIT; // pound -"N" COUNT; yylval.quantity.scaler = Quantity::Newton; yylval.quantity.unitStr = yytext; return UNIT; // Newton (kg*m/s^2)a-za-za-z -"kN" COUNT; yylval.quantity.scaler = Quantity::KiloNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton -"MN" COUNT; yylval.quantity.scaler = Quantity::MegaNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton -"mN" COUNT; yylval.quantity.scaler = Quantity::MilliNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton +"N" COUNTCHARS; yylval.quantity.scaler = Quantity::Newton; yylval.quantity.unitStr = yytext; return UNIT; // Newton (kg*m/s^2)a-za-za-z +"kN" COUNTCHARS; yylval.quantity.scaler = Quantity::KiloNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton +"MN" COUNTCHARS; yylval.quantity.scaler = Quantity::MegaNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton +"mN" COUNTCHARS; yylval.quantity.scaler = Quantity::MilliNewton; yylval.quantity.unitStr = yytext; return UNIT; // Newton -"Pa" COUNT; yylval.quantity.scaler = Quantity::Pascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal (kg/m*s^2 or N/m^2) -"kPa" COUNT; yylval.quantity.scaler = Quantity::KiloPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal -"MPa" COUNT; yylval.quantity.scaler = Quantity::MegaPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal -"GPa" COUNT; yylval.quantity.scaler = Quantity::GigaPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal +"Pa" COUNTCHARS; yylval.quantity.scaler = Quantity::Pascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal (kg/m*s^2 or N/m^2) +"kPa" COUNTCHARS; yylval.quantity.scaler = Quantity::KiloPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal +"MPa" COUNTCHARS; yylval.quantity.scaler = Quantity::MegaPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal +"GPa" COUNTCHARS; yylval.quantity.scaler = Quantity::GigaPascal; yylval.quantity.unitStr = yytext; return UNIT; // Pascal -"Torr" COUNT; yylval.quantity.scaler = Quantity::Torr; yylval.quantity.unitStr = yytext; return UNIT; // portion of Pascal ( 101325/760 ) -"mTorr" COUNT; yylval.quantity.scaler = Quantity::mTorr; yylval.quantity.unitStr = yytext; return UNIT; // -"uTorr" COUNT; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = yytext; return UNIT; // -"\xC2\xB5Torr" COUNT; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = yytext; return UNIT; // +"Torr" COUNTCHARS; yylval.quantity.scaler = Quantity::Torr; yylval.quantity.unitStr = yytext; return UNIT; // portion of Pascal ( 101325/760 ) +"mTorr" COUNTCHARS; yylval.quantity.scaler = Quantity::mTorr; yylval.quantity.unitStr = yytext; return UNIT; // +"uTorr" COUNTCHARS; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = yytext; return UNIT; // +"\xC2\xB5Torr" COUNTCHARS; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = yytext; return UNIT; // -"psi" COUNT; yylval.quantity.scaler = Quantity::PSI; yylval.quantity.unitStr = yytext; return UNIT; // pounds/in^2 -"ksi" COUNT; yylval.quantity.scaler = Quantity::KSI; yylval.quantity.unitStr = yytext; return UNIT; // 1000 x pounds/in^2 +"psi" COUNTCHARS; yylval.quantity.scaler = Quantity::PSI; yylval.quantity.unitStr = yytext; return UNIT; // pounds/in^2 +"ksi" COUNTCHARS; yylval.quantity.scaler = Quantity::KSI; yylval.quantity.unitStr = yytext; return UNIT; // 1000 x pounds/in^2 -"W" COUNT; yylval.quantity.scaler = Quantity::Watt; yylval.quantity.unitStr = yytext; return UNIT; // Watt (kg*m^2/s^3) -"VA" COUNT; yylval.quantity.scaler = Quantity::VoltAmpere; yylval.quantity.unitStr = yytext; return UNIT; // VoltAmpere (kg*m^2/s^3) +"W" COUNTCHARS; yylval.quantity.scaler = Quantity::Watt; yylval.quantity.unitStr = yytext; return UNIT; // Watt (kg*m^2/s^3) +"VA" COUNTCHARS; yylval.quantity.scaler = Quantity::VoltAmpere; yylval.quantity.unitStr = yytext; return UNIT; // VoltAmpere (kg*m^2/s^3) -"J" COUNT; yylval.quantity.scaler = Quantity::Joule; yylval.quantity.unitStr = yytext; return UNIT; // Joule (kg*m^2/s^2) -"Nm" COUNT; yylval.quantity.scaler = Quantity::NewtonMeter; yylval.quantity.unitStr = yytext; return UNIT; // N*m = Joule -"VAs" COUNT; yylval.quantity.scaler = Quantity::VoltAmpereSecond; yylval.quantity.unitStr = yytext; return UNIT; // V*A*s = Joule -"CV" COUNT; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = yytext; return UNIT; // -"Ws" COUNT; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = yytext; return UNIT; // W*s = Joule +"J" COUNTCHARS; yylval.quantity.scaler = Quantity::Joule; yylval.quantity.unitStr = yytext; return UNIT; // Joule (kg*m^2/s^2) +"Nm" COUNTCHARS; yylval.quantity.scaler = Quantity::NewtonMeter; yylval.quantity.unitStr = yytext; return UNIT; // N*m = Joule +"VAs" COUNTCHARS; yylval.quantity.scaler = Quantity::VoltAmpereSecond; yylval.quantity.unitStr = yytext; return UNIT; // V*A*s = Joule +"CV" COUNTCHARS; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = yytext; return UNIT; // +"Ws" COUNTCHARS; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = yytext; return UNIT; // W*s = Joule -"\xC2\xB0" COUNT; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = yytext; return UNIT; // degree (internal standard angle) -"deg" COUNT; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = yytext; return UNIT; // degree (internal standard angle) -"rad" COUNT; yylval.quantity.scaler = Quantity::Radian; yylval.quantity.unitStr = yytext; return UNIT; // radian -"gon" COUNT; yylval.quantity.scaler = Quantity::Gon; yylval.quantity.unitStr = yytext; return UNIT; // gon +"\xC2\xB0" COUNTCHARS; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = yytext; return UNIT; // degree (internal standard angle) +"deg" COUNTCHARS; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = yytext; return UNIT; // degree (internal standard angle) +"rad" COUNTCHARS; yylval.quantity.scaler = Quantity::Radian; yylval.quantity.unitStr = yytext; return UNIT; // radian +"gon" COUNTCHARS; yylval.quantity.scaler = Quantity::Gon; yylval.quantity.unitStr = yytext; return UNIT; // gon -{DIGIT}*"."{DIGIT}+{EXPO}? COUNT; yylval.fvalue = num_change(yytext,'.',','); return yylval.fvalue == 1 ? ONE : NUM; -{DIGIT}*","{DIGIT}+{EXPO}? COUNT; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; -{DIGIT}+{EXPO} COUNT; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; -{DIGIT}+ { COUNT; +{DIGIT}*"."{DIGIT}+{EXPO}? COUNTCHARS; yylval.fvalue = num_change(yytext,'.',','); return yylval.fvalue == 1 ? ONE : NUM; +{DIGIT}*","{DIGIT}+{EXPO}? COUNTCHARS; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; +{DIGIT}+{EXPO} COUNTCHARS; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; +{DIGIT}+ { COUNTCHARS; yylval.ivalue = strtoll( yytext, NULL, 0 ); if (yylval.ivalue == LLONG_MIN) throw Base::Exception("Integer underflow"); @@ -257,15 +257,15 @@ EXPO [eE][-+]?[0-9]+ if (yylval.ivalue == 1) { yylval.fvalue = 1; return ONE; } else return INTEGER; } -"pi" COUNT; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi -"e" COUNT; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e +"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 -$[A-Za-z]{1,2}+${DIGIT}+ COUNT; yylval.string = yytext; return CELLADDRESS; -[A-Za-z]{1,2}${DIGIT}+ COUNT; yylval.string = yytext; return CELLADDRESS; -$[A-Za-z]{1,2}{DIGIT}+ COUNT; 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; +$[A-Za-z]{1,2}{DIGIT}+ COUNTCHARS; yylval.string = yytext; return CELLADDRESS; ({L}{M}*)({L}{M}*|{N}|_)*[\20\t]*\( { - COUNT; + COUNTCHARS; std::string s = yytext; size_t i = s.size() - 2; while (isspace(s[i])) @@ -279,4 +279,4 @@ $[A-Za-z]{1,2}{DIGIT}+ COUNT; yylval.string = yytext; return CELLADDRESS; return FUNC; } -({L}{M}*)({L}{M}*|{N}|_)* COUNT; yylval.string = yytext; return IDENTIFIER; +({L}{M}*)({L}{M}*|{N}|_)* COUNTCHARS; yylval.string = yytext; return IDENTIFIER; diff --git a/src/App/ExpressionParser.tab.c b/src/App/ExpressionParser.tab.c index a222fbb91..ce7a5ce19 100644 --- a/src/App/ExpressionParser.tab.c +++ b/src/App/ExpressionParser.tab.c @@ -65,7 +65,7 @@ #line 7 "ExpressionParser.y" /* yacc.c:339 */ -#define YYSTYPE semantic_type +#define YYSTYPE App::ExpressionParser::semantic_type std::stack functions; /**< Function identifier */ @@ -381,18 +381,18 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 37 +#define YYFINAL 40 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 171 +#define YYLAST 198 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 39 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 14 +#define YYNNTS 15 /* YYNRULES -- Number of rules. */ -#define YYNRULES 69 +#define YYNRULES 76 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 125 +#define YYNSTATES 136 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -440,13 +440,14 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 68, 68, 69, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 88, 89, - 90, 93, 94, 95, 96, 99, 100, 101, 104, 105, - 106, 107, 108, 109, 112, 113, 114, 115, 116, 117, - 118, 121, 125, 130, 135, 143, 144, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 171, 172, 175, 176 + 0, 69, 69, 70, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 89, 90, + 91, 94, 95, 96, 97, 100, 101, 102, 103, 104, + 105, 108, 109, 110, 111, 114, 115, 116, 117, 118, + 119, 122, 123, 124, 125, 126, 127, 128, 131, 135, + 140, 145, 153, 154, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 181, 182, 185, 186 }; #endif @@ -460,7 +461,7 @@ static const char *const yytname[] = "GTE", "LTE", "STRING", "MINUSSIGN", "PROPERTY_REF", "DOCUMENT", "OBJECT", "EXPONENT", "'?'", "':'", "'+'", "'*'", "'/'", "NEG", "POS", "'^'", "'('", "')'", "','", "';'", "'.'", "'#'", "'['", "']'", "$accept", - "input", "exp", "basic_num", "num", "args", "cond", "unit_exp", + "input", "exp", "basic_num", "num", "args", "range", "cond", "unit_exp", "identifier", "integer", "path", "subpath", "document", "object", YY_NULLPTR }; #endif @@ -477,12 +478,12 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -85 +#define YYPACT_NINF -56 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-85))) + (!!((Yystate) == (-56))) -#define YYTABLE_NINF -70 +#define YYTABLE_NINF -77 #define yytable_value_is_error(Yytable_value) \ 0 @@ -491,19 +492,20 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 56, 74, -11, -85, -22, -85, -85, 1, -14, -29, - 74, 74, 56, 22, 124, 1, -85, 5, 4, -85, - -85, -9, 20, -85, 74, 124, 137, 1, 96, 139, - -11, 1, 4, 26, 26, 82, 136, -85, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 56, 74, -85, - 74, 1, 1, 15, 115, 66, -85, 74, 74, 39, - 53, -85, -85, -85, -85, 32, -85, 37, 65, -85, - -85, 124, 124, 124, 124, 124, 124, 41, 41, 26, - 26, 39, -85, 104, 39, 39, 81, -85, 89, -85, - -85, 69, -85, -85, 124, 124, 96, 140, 75, 76, - 88, 74, -85, 66, -85, 95, 103, 117, 96, 96, - 96, 134, -85, 92, 118, 123, -85, -85, -85, 96, - 96, 96, -85, -85, -85 + 61, 79, -20, -56, 132, -56, -56, 1, -19, 39, + 97, 97, 61, 22, 168, 1, -56, 7, 28, -56, + -56, 16, 2, -56, -12, -15, 97, 168, 155, -56, + 1, 137, 23, -20, 1, 28, 27, 27, 126, 100, + -56, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 61, 97, -56, 97, 1, 1, 10, 140, 71, 89, + 103, -56, 79, 79, 50, -18, -56, -56, -56, -56, + 55, -56, 60, 70, -56, -56, 168, 168, 168, 168, + 168, 168, 46, 46, 27, 27, 50, -56, 148, 50, + 50, 86, -56, 82, -56, -56, 96, -56, -56, -56, + -56, -56, -56, 168, -56, 168, -56, 137, 112, 98, + 110, 113, 97, -56, 71, -56, 83, 111, 117, 137, + 137, 137, 8, -56, 130, 141, 142, -56, -56, -56, + 137, 137, 137, -56, -56, -56 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -511,80 +513,85 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 18, 19, 47, 34, 20, 22, 48, 5, + 0, 0, 18, 19, 54, 41, 20, 22, 55, 5, 0, 0, 0, 0, 2, 21, 4, 0, 3, 6, - 41, 0, 0, 18, 0, 25, 0, 0, 0, 0, - 0, 0, 24, 7, 8, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, - 0, 0, 0, 0, 0, 0, 16, 0, 0, 35, - 56, 58, 57, 55, 46, 0, 45, 0, 0, 15, - 40, 28, 29, 30, 31, 32, 33, 10, 9, 11, - 12, 13, 14, 0, 37, 36, 0, 38, 47, 68, - 43, 0, 48, 42, 26, 27, 0, 0, 52, 51, - 49, 0, 39, 0, 65, 0, 0, 0, 0, 0, - 0, 17, 44, 62, 61, 59, 54, 53, 50, 0, - 0, 0, 64, 63, 60 + 48, 0, 0, 18, 54, 55, 0, 25, 0, 26, + 0, 0, 0, 0, 0, 24, 7, 8, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 42, 63, 65, 64, 62, 53, + 0, 52, 0, 0, 15, 47, 35, 36, 37, 38, + 39, 40, 10, 9, 11, 12, 13, 14, 0, 44, + 43, 0, 45, 54, 75, 50, 0, 55, 49, 34, + 33, 32, 31, 27, 29, 28, 30, 0, 0, 59, + 58, 56, 0, 46, 0, 72, 0, 0, 0, 0, + 0, 0, 17, 51, 69, 68, 66, 61, 60, 57, + 0, 0, 0, 71, 70, 67 }; /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = +static const yytype_int16 yypgoto[] = { - -85, -85, 0, -35, -85, -85, -85, 2, -85, 68, - -51, -84, -85, 113 + -56, -56, 0, -52, -56, -56, 108, -56, 6, -56, + 77, -55, 4, -56, 133 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 13, 35, 15, 16, 26, 17, 36, 19, 68, - 20, 63, 21, 22 + -1, 13, 38, 15, 16, 28, 29, 17, 39, 19, + 73, 20, 68, 21, 22 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int8 yytable[] = +static const yytype_int16 yytable[] = { - 14, 25, 18, 90, 93, 30, -68, -66, 5, 32, - 33, 34, 104, 28, -67, 29, 27, 49, 87, 23, - 3, -69, 37, 6, 116, 117, 118, 54, 50, 59, - 51, 52, 31, 86, 53, 122, 123, 124, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 82, 81, - 83, 102, 112, 84, 85, 55, 48, 94, 95, 1, - 2, 3, 4, 5, 6, 7, 8, 46, 47, 53, - 98, 48, 88, 9, 10, 99, 92, 1, 23, 3, - 4, 11, 6, 7, 8, 23, 3, 12, 96, 6, - 97, 9, 10, 38, 39, 40, 41, 42, 43, 11, - 44, 111, 60, 100, 103, 24, 61, 45, 46, 47, - 108, 109, 48, 62, 69, 38, 39, 40, 41, 42, - 43, 88, 44, 110, 28, 8, 29, 119, 101, 45, - 46, 47, 89, 113, 48, 38, 39, 40, 41, 42, - 43, 114, 44, 64, 64, 65, 105, 66, 66, 45, - 46, 47, 44, 120, 48, 115, 67, 106, 121, 45, - 46, 47, 51, 52, 48, 107, 53, 91, 70, 56, - 57, 58 + 14, 27, 95, 98, 92, 33, 18, 30, 5, 60, + 36, 37, 59, 35, 23, 3, -76, 107, 6, 108, + -76, 52, 40, 31, -74, 32, 47, 69, 91, 70, + 53, 71, 34, 48, 49, 50, 64, 58, 51, 113, + 72, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 87, 57, 88, 54, 55, 86, 51, 56, 123, + 89, 90, 103, 105, 1, 2, 3, 4, 5, 6, + 7, 8, 49, 50, -75, -73, 51, 93, 9, 10, + 56, 97, 1, 23, 3, 24, 11, 6, 7, 25, + 23, 3, 12, 109, 6, 99, 9, 10, 110, 100, + 1, 23, 3, 4, 11, 6, 7, 8, 111, 101, + 26, 115, 122, 102, 9, 10, 69, 31, 116, 32, + 71, 124, 11, 127, 128, 129, 54, 55, 26, 117, + 56, 114, 75, 119, 133, 134, 135, 41, 42, 43, + 44, 45, 46, 65, 47, 120, 93, 66, 121, 125, + 8, 48, 49, 50, 67, 126, 51, 94, 74, 41, + 42, 43, 44, 45, 46, 130, 47, 31, -74, 32, + 104, 106, 112, 48, 49, 50, 131, 132, 51, 41, + 42, 43, 44, 45, 46, 118, 47, 61, 62, 63, + 96, 0, 0, 48, 49, 50, 0, 0, 51 }; -static const yytype_uint8 yycheck[] = +static const yytype_int16 yycheck[] = { - 0, 1, 0, 54, 55, 4, 35, 36, 7, 7, - 10, 11, 96, 35, 36, 37, 27, 15, 53, 4, - 5, 35, 0, 8, 108, 109, 110, 36, 23, 27, - 26, 27, 31, 18, 30, 119, 120, 121, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 47, - 50, 86, 103, 51, 52, 35, 30, 57, 58, 3, - 4, 5, 6, 7, 8, 9, 10, 26, 27, 30, - 38, 30, 6, 17, 18, 38, 10, 3, 4, 5, - 6, 25, 8, 9, 10, 4, 5, 31, 35, 8, - 37, 17, 18, 11, 12, 13, 14, 15, 16, 25, - 18, 101, 6, 38, 35, 31, 10, 25, 26, 27, - 35, 35, 30, 17, 32, 11, 12, 13, 14, 15, - 16, 6, 18, 35, 35, 10, 37, 35, 24, 25, - 26, 27, 17, 38, 30, 11, 12, 13, 14, 15, - 16, 38, 18, 4, 4, 6, 6, 8, 8, 25, - 26, 27, 18, 35, 30, 38, 17, 17, 35, 25, - 26, 27, 26, 27, 30, 97, 30, 54, 32, 32, - 33, 34 + 0, 1, 57, 58, 56, 4, 0, 27, 7, 24, + 10, 11, 24, 7, 4, 5, 35, 35, 8, 37, + 35, 15, 0, 35, 36, 37, 18, 4, 18, 6, + 23, 8, 31, 25, 26, 27, 30, 35, 30, 91, + 17, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 36, 53, 26, 27, 50, 30, 30, 114, + 54, 55, 62, 63, 3, 4, 5, 6, 7, 8, + 9, 10, 26, 27, 35, 36, 30, 6, 17, 18, + 30, 10, 3, 4, 5, 6, 25, 8, 9, 10, + 4, 5, 31, 38, 8, 6, 17, 18, 38, 10, + 3, 4, 5, 6, 25, 8, 9, 10, 38, 6, + 31, 107, 112, 10, 17, 18, 4, 35, 6, 37, + 8, 38, 25, 119, 120, 121, 26, 27, 31, 17, + 30, 35, 32, 35, 130, 131, 132, 11, 12, 13, + 14, 15, 16, 6, 18, 35, 6, 10, 35, 38, + 10, 25, 26, 27, 17, 38, 30, 17, 32, 11, + 12, 13, 14, 15, 16, 35, 18, 35, 36, 37, + 62, 63, 24, 25, 26, 27, 35, 35, 30, 11, + 12, 13, 14, 15, 16, 108, 18, 32, 33, 34, + 57, -1, -1, 25, 26, 27, -1, -1, 30 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -592,18 +599,19 @@ static const yytype_uint8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 17, - 18, 25, 31, 40, 41, 42, 43, 45, 46, 47, - 49, 51, 52, 4, 31, 41, 44, 27, 35, 37, - 4, 31, 46, 41, 41, 41, 46, 0, 11, 12, - 13, 14, 15, 16, 18, 25, 26, 27, 30, 46, - 23, 26, 27, 30, 36, 35, 32, 33, 34, 46, - 6, 10, 17, 50, 4, 6, 8, 17, 48, 32, - 32, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 46, 41, 41, 46, 46, 18, 42, 6, 17, - 49, 52, 10, 49, 41, 41, 35, 37, 38, 38, - 38, 24, 42, 35, 50, 6, 17, 48, 35, 35, - 35, 41, 49, 38, 38, 38, 50, 50, 50, 35, - 35, 35, 50, 50, 50 + 18, 25, 31, 40, 41, 42, 43, 46, 47, 48, + 50, 52, 53, 4, 6, 10, 31, 41, 44, 45, + 27, 35, 37, 4, 31, 47, 41, 41, 41, 47, + 0, 11, 12, 13, 14, 15, 16, 18, 25, 26, + 27, 30, 47, 23, 26, 27, 30, 36, 35, 24, + 24, 32, 33, 34, 47, 6, 10, 17, 51, 4, + 6, 8, 17, 49, 32, 32, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 47, 41, 41, 47, + 47, 18, 42, 6, 17, 50, 53, 10, 50, 6, + 10, 6, 10, 41, 45, 41, 45, 35, 37, 38, + 38, 38, 24, 42, 35, 51, 6, 17, 49, 35, + 35, 35, 41, 50, 38, 38, 38, 51, 51, 51, + 35, 35, 35, 51, 51, 51 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -611,11 +619,12 @@ static const yytype_uint8 yyr1[] = { 0, 39, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, - 42, 43, 43, 43, 43, 44, 44, 44, 45, 45, - 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, - 46, 47, 47, 47, 47, 48, 48, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 51, 51, 52, 52 + 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, 47, 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 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -623,11 +632,12 @@ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 1, 1, - 1, 1, 1, 2, 2, 1, 3, 3, 3, 3, - 3, 3, 3, 3, 1, 3, 3, 3, 3, 4, - 3, 1, 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 + 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 3, 3, 3, 3, 4, 3, 1, 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 }; @@ -1051,27 +1061,27 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) switch (yytype) { case 41: /* exp */ -#line 61 "ExpressionParser.y" /* yacc.c:1257 */ +#line 62 "ExpressionParser.y" /* yacc.c:1257 */ { delete ((*yyvaluep).expr); } -#line 1057 "ExpressionParser.tab.c" /* yacc.c:1257 */ +#line 1067 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; case 44: /* args */ -#line 62 "ExpressionParser.y" /* yacc.c:1257 */ +#line 63 "ExpressionParser.y" /* yacc.c:1257 */ { std::vector::const_iterator i = ((*yyvaluep).arguments).begin(); while (i != ((*yyvaluep).arguments).end()) { delete *i; ++i; } } -#line 1063 "ExpressionParser.tab.c" /* yacc.c:1257 */ +#line 1073 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; - case 45: /* cond */ -#line 61 "ExpressionParser.y" /* yacc.c:1257 */ + case 46: /* cond */ +#line 62 "ExpressionParser.y" /* yacc.c:1257 */ { delete ((*yyvaluep).expr); } -#line 1069 "ExpressionParser.tab.c" /* yacc.c:1257 */ +#line 1079 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; - case 46: /* unit_exp */ -#line 61 "ExpressionParser.y" /* yacc.c:1257 */ + case 47: /* unit_exp */ +#line 62 "ExpressionParser.y" /* yacc.c:1257 */ { delete ((*yyvaluep).expr); } -#line 1075 "ExpressionParser.tab.c" /* yacc.c:1257 */ +#line 1085 "ExpressionParser.tab.c" /* yacc.c:1257 */ break; @@ -1333,431 +1343,473 @@ yyreduce: switch (yyn) { case 2: -#line 68 "ExpressionParser.y" /* yacc.c:1646 */ +#line 69 "ExpressionParser.y" /* yacc.c:1646 */ { ScanResult = (yyvsp[0].expr); valueExpression = true; } -#line 1339 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1349 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 3: -#line 69 "ExpressionParser.y" /* yacc.c:1646 */ +#line 70 "ExpressionParser.y" /* yacc.c:1646 */ { ScanResult = (yyvsp[0].expr); unitExpression = true; } -#line 1345 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1355 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 4: -#line 72 "ExpressionParser.y" /* yacc.c:1646 */ +#line 73 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 1351 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1361 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 5: -#line 73 "ExpressionParser.y" /* yacc.c:1646 */ +#line 74 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new StringExpression(DocumentObject, (yyvsp[0].string)); } -#line 1357 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1367 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 6: -#line 74 "ExpressionParser.y" /* yacc.c:1646 */ +#line 75 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new VariableExpression(DocumentObject, (yyvsp[0].path)); } -#line 1363 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1373 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 7: -#line 75 "ExpressionParser.y" /* yacc.c:1646 */ +#line 76 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::NEG, new NumberExpression(DocumentObject, -1)); } -#line 1369 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1379 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 8: -#line 76 "ExpressionParser.y" /* yacc.c:1646 */ +#line 77 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::POS, new NumberExpression(DocumentObject, 1)); } -#line 1375 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1385 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 9: -#line 77 "ExpressionParser.y" /* yacc.c:1646 */ +#line 78 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::ADD, (yyvsp[0].expr)); } -#line 1381 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1391 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 10: -#line 78 "ExpressionParser.y" /* yacc.c:1646 */ +#line 79 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::SUB, (yyvsp[0].expr)); } -#line 1387 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1397 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 11: -#line 79 "ExpressionParser.y" /* yacc.c:1646 */ +#line 80 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } -#line 1393 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1403 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 12: -#line 80 "ExpressionParser.y" /* yacc.c:1646 */ +#line 81 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1399 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1409 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 13: -#line 81 "ExpressionParser.y" /* yacc.c:1646 */ +#line 82 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1405 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1415 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 14: -#line 82 "ExpressionParser.y" /* yacc.c:1646 */ +#line 83 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); } -#line 1411 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1421 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 15: -#line 83 "ExpressionParser.y" /* yacc.c:1646 */ +#line 84 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[-1].expr); } -#line 1417 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1427 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 16: -#line 84 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new FunctionExpression(DocumentObject, (yyvsp[-2].func), (yyvsp[-1].arguments)); } -#line 1423 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 85 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new FunctionExpression(DocumentObject, (yyvsp[-2].func), (yyvsp[-1].arguments)); } +#line 1433 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 17: -#line 85 "ExpressionParser.y" /* yacc.c:1646 */ +#line 86 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new ConditionalExpression(DocumentObject, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 1429 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1439 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 18: -#line 88 "ExpressionParser.y" /* yacc.c:1646 */ +#line 89 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new NumberExpression(DocumentObject, (yyvsp[0].fvalue)); } -#line 1435 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1445 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 19: -#line 89 "ExpressionParser.y" /* yacc.c:1646 */ +#line 90 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new NumberExpression(DocumentObject, (yyvsp[0].fvalue)); } -#line 1441 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1451 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 20: -#line 90 "ExpressionParser.y" /* yacc.c:1646 */ +#line 91 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new NumberExpression(DocumentObject, (double)(yyvsp[0].ivalue)); } -#line 1447 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1457 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 21: -#line 93 "ExpressionParser.y" /* yacc.c:1646 */ +#line 94 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 1453 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1463 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 22: -#line 94 "ExpressionParser.y" /* yacc.c:1646 */ +#line 95 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new ConstantExpression(DocumentObject, (yyvsp[0].constant).name, (yyvsp[0].constant).fvalue); } -#line 1459 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1469 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 23: -#line 95 "ExpressionParser.y" /* yacc.c:1646 */ +#line 96 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-1].expr), OperatorExpression::UNIT, (yyvsp[0].expr)); } -#line 1465 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1475 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 24: -#line 96 "ExpressionParser.y" /* yacc.c:1646 */ +#line 97 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.expr) = new OperatorExpression(DocumentObject, new ConstantExpression(DocumentObject, (yyvsp[-1].constant).name, (yyvsp[-1].constant).fvalue), OperatorExpression::UNIT, (yyvsp[0].expr)); } -#line 1471 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1481 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 25: -#line 99 "ExpressionParser.y" /* yacc.c:1646 */ +#line 100 "ExpressionParser.y" /* yacc.c:1646 */ { (yyval.arguments).push_back((yyvsp[0].expr)); } -#line 1477 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1487 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 26: -#line 100 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1483 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 101 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.arguments).push_back((yyvsp[0].expr)); } +#line 1493 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 27: -#line 101 "ExpressionParser.y" /* yacc.c:1646 */ +#line 102 "ExpressionParser.y" /* yacc.c:1646 */ { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } -#line 1489 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1499 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 28: -#line 104 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::EQ, (yyvsp[0].expr)); } -#line 1495 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 103 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } +#line 1505 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 29: -#line 105 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::NEQ, (yyvsp[0].expr)); } -#line 1501 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 104 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } +#line 1511 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 30: -#line 106 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LT, (yyvsp[0].expr)); } -#line 1507 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 105 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); } +#line 1517 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 31: -#line 107 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GT, (yyvsp[0].expr)); } -#line 1513 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 108 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } +#line 1523 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 32: -#line 108 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GTE, (yyvsp[0].expr)); } -#line 1519 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 109 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } +#line 1529 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 33: -#line 109 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LTE, (yyvsp[0].expr)); } -#line 1525 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 110 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } +#line 1535 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 34: -#line 112 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); } -#line 1531 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 111 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); } +#line 1541 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 35: -#line 113 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, (yyvsp[-2].fvalue)), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1537 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 114 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::EQ, (yyvsp[0].expr)); } +#line 1547 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 36: -#line 114 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } -#line 1543 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 115 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::NEQ, (yyvsp[0].expr)); } +#line 1553 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 37: -#line 115 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } -#line 1549 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 116 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LT, (yyvsp[0].expr)); } +#line 1559 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 38: -#line 116 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); } -#line 1555 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 117 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GT, (yyvsp[0].expr)); } +#line 1565 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 39: -#line 117 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::POW, new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::NEG, new NumberExpression(DocumentObject, -1))); } -#line 1561 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 118 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GTE, (yyvsp[0].expr)); } +#line 1571 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 40: -#line 118 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 1567 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 119 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LTE, (yyvsp[0].expr)); } +#line 1577 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 41: -#line 121 "ExpressionParser.y" /* yacc.c:1646 */ +#line 122 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); } +#line 1583 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 42: +#line 123 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, (yyvsp[-2].fvalue)), OperatorExpression::DIV, (yyvsp[0].expr)); } +#line 1589 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 43: +#line 124 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); } +#line 1595 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 44: +#line 125 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); } +#line 1601 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 45: +#line 126 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); } +#line 1607 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 46: +#line 127 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::POW, new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::NEG, new NumberExpression(DocumentObject, -1))); } +#line 1613 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 47: +#line 128 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.expr) = (yyvsp[-1].expr); } +#line 1619 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 48: +#line 131 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property within document object */ (yyval.path) = ObjectIdentifier(DocumentObject); (yyval.path).addComponents((yyvsp[0].components)); } -#line 1576 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1628 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; - case 42: -#line 125 "ExpressionParser.y" /* yacc.c:1646 */ + case 49: +#line 135 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property within document object */ (yyval.path) = ObjectIdentifier(DocumentObject); (yyval.path).setDocumentObjectName((yyvsp[-2].string_or_identifier), true); (yyval.path).addComponents((yyvsp[0].components)); } -#line 1586 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1638 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; - case 43: -#line 130 "ExpressionParser.y" /* yacc.c:1646 */ + case 50: +#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((yyvsp[-2].string_or_identifier), true); (yyval.path).addComponents((yyvsp[0].components)); } -#line 1596 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1648 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; - case 44: -#line 135 "ExpressionParser.y" /* yacc.c:1646 */ + case 51: +#line 145 "ExpressionParser.y" /* yacc.c:1646 */ { /* Path to property from an external document, within a named document object */ (yyval.path) = ObjectIdentifier(DocumentObject); (yyval.path).setDocumentName((yyvsp[-4].string_or_identifier), true); (yyval.path).setDocumentObjectName((yyvsp[-2].string_or_identifier), true); (yyval.path).addComponents((yyvsp[0].components)); } -#line 1607 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 45: -#line 143 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.ivalue) = (yyvsp[0].ivalue); } -#line 1613 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 46: -#line 144 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.ivalue) = (yyvsp[0].fvalue); } -#line 1619 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 47: -#line 148 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } -#line 1625 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 48: -#line 149 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } -#line 1631 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 49: -#line 150 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-3].string), (yyvsp[-1].ivalue))); } -#line 1637 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 50: -#line 151 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-5].string), (yyvsp[-3].ivalue))); (yyval.components) = (yyvsp[0].components); } -#line 1643 "ExpressionParser.tab.c" /* yacc.c:1646 */ - break; - - case 51: -#line 152 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), ObjectIdentifier::String((yyvsp[-1].string), true))); } -#line 1649 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1659 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 52: #line 153 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), (yyvsp[-1].string))); } -#line 1655 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.ivalue) = (yyvsp[0].ivalue); } +#line 1665 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 53: #line 154 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components) = (yyvsp[0].components); } -#line 1661 "ExpressionParser.tab.c" /* yacc.c:1646 */ + { (yyval.ivalue) = (yyvsp[0].fvalue); } +#line 1671 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 54: -#line 155 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), (yyvsp[-3].string))); (yyval.components) = (yyvsp[0].components); } -#line 1667 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 158 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } +#line 1677 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 55: -#line 156 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } -#line 1673 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 159 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } +#line 1683 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 56: -#line 159 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } -#line 1679 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 160 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-3].string), (yyvsp[-1].ivalue))); } +#line 1689 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 57: -#line 160 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } -#line 1685 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 161 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-5].string), (yyvsp[-3].ivalue))); (yyval.components) = (yyvsp[0].components); } +#line 1695 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 58: -#line 161 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } -#line 1691 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 162 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), ObjectIdentifier::String((yyvsp[-1].string), true))); } +#line 1701 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 59: -#line 162 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-3].string), (yyvsp[-1].ivalue))); } -#line 1697 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 163 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), (yyvsp[-1].string))); } +#line 1707 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 60: -#line 163 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-5].string), (yyvsp[-3].ivalue))); (yyval.components) = (yyvsp[0].components); } -#line 1703 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 164 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components) = (yyvsp[0].components); } +#line 1713 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 61: -#line 164 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), ObjectIdentifier::String((yyvsp[-1].string), true))); } -#line 1709 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 165 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), (yyvsp[-3].string))); (yyval.components) = (yyvsp[0].components); } +#line 1719 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 62: -#line 165 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), (yyvsp[-1].string))); } -#line 1715 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 166 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } +#line 1725 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 63: -#line 166 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components) = (yyvsp[0].components); } -#line 1721 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 169 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } +#line 1731 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 64: -#line 167 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), (yyvsp[-3].string))); (yyval.components) = (yyvsp[0].components); } -#line 1727 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 170 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } +#line 1737 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 65: -#line 168 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyvsp[0].components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } -#line 1733 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 171 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[0].string))); } +#line 1743 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 66: -#line 171 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } -#line 1739 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 172 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-3].string), (yyvsp[-1].ivalue))); } +#line 1749 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 67: -#line 172 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string)); } -#line 1745 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 173 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::ArrayComponent((yyvsp[-5].string), (yyvsp[-3].ivalue))); (yyval.components) = (yyvsp[0].components); } +#line 1755 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 68: -#line 175 "ExpressionParser.y" /* yacc.c:1646 */ - { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } -#line 1751 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 174 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), ObjectIdentifier::String((yyvsp[-1].string), true))); } +#line 1761 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; case 69: +#line 175 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-3].string), (yyvsp[-1].string))); } +#line 1767 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 70: #line 176 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), ObjectIdentifier::String((yyvsp[-3].string), true))); (yyval.components) = (yyvsp[0].components); } +#line 1773 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 71: +#line 177 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::MapComponent((yyvsp[-5].string), (yyvsp[-3].string))); (yyval.components) = (yyvsp[0].components); } +#line 1779 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 72: +#line 178 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyvsp[0].components).push_front(ObjectIdentifier::Component::SimpleComponent((yyvsp[-2].string))); (yyval.components) = (yyvsp[0].components); } +#line 1785 "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 1757 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1791 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 74: +#line 182 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string)); } +#line 1797 "ExpressionParser.tab.c" /* yacc.c:1646 */ + break; + + case 75: +#line 185 "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 76: +#line 186 "ExpressionParser.y" /* yacc.c:1646 */ + { (yyval.string_or_identifier) = ObjectIdentifier::String((yyvsp[0].string), true); } +#line 1809 "ExpressionParser.tab.c" /* yacc.c:1646 */ break; -#line 1761 "ExpressionParser.tab.c" /* yacc.c:1646 */ +#line 1813 "ExpressionParser.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1985,5 +2037,5 @@ yyreturn: #endif return yyresult; } -#line 179 "ExpressionParser.y" /* yacc.c:1906 */ +#line 189 "ExpressionParser.y" /* yacc.c:1906 */ diff --git a/src/App/ExpressionParser.y b/src/App/ExpressionParser.y index 652e979f5..c8297c990 100644 --- a/src/App/ExpressionParser.y +++ b/src/App/ExpressionParser.y @@ -6,7 +6,7 @@ %{ -#define YYSTYPE semantic_type +#define YYSTYPE App::ExpressionParser::semantic_type std::stack functions; /**< Function identifier */ @@ -39,6 +39,7 @@ std::stack functions; /**< Function %type CONSTANT %type num %type basic_num + %type range %type identifier %type path subpath %type FUNC @@ -81,7 +82,7 @@ exp: num { $$ = $1; | exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); } | exp '^' exp %prec EXPONENT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); } | '(' exp ')' { $$ = $2; } - | FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1, $2); } + | FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1, $2); } | cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); } ; @@ -97,10 +98,19 @@ num: basic_num { $$ = $1; } ; args: exp { $$.push_back($1); } + | range { $$.push_back($1); } | args ',' exp { $1.push_back($3); $$ = $1; } | args ';' exp { $1.push_back($3); $$ = $1; } + | args ',' range { $1.push_back($3); $$ = $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); } + ; + cond: exp EQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3); } | exp NEQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::NEQ, $3); } | exp LT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LT, $3); } diff --git a/src/App/Range.cpp b/src/App/Range.cpp new file mode 100644 index 000000000..e0c8d361a --- /dev/null +++ b/src/App/Range.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** + * Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#include "Range.h" +#include +#include +#include +#include + +using namespace App; + +const int App::CellAddress::MAX_ROWS = 16384; +const int App::CellAddress::MAX_COLUMNS = 26 * 26 + 26; + +Range::Range(const char * range) +{ + std::string from; + std::string to; + + assert(range != NULL); + + if (strchr(range, ':') == NULL) { + from = range; + to = range; + } + else { + std::string s = range; + from = s.substr(0, s.find(':')); + to = s.substr(s.find(':') + 1); + } + + CellAddress begin(from); + CellAddress end(to); + + row_begin = begin.row(); + col_begin = begin.col(); + row_end = end.row(); + col_end = end.col(); + + row_curr = row_begin; + col_curr = col_begin; +} + +Range::Range(int _row_begin, int _col_begin, int _row_end, int _col_end) + : row_curr(_row_begin) + , col_curr(_col_begin) + , row_begin(_row_begin) + , col_begin(_col_begin) + , row_end(_row_end) + , col_end(_col_end) +{ +} + +Range::Range(const CellAddress &from, const CellAddress &to) + : row_curr(from.row()) + , col_curr(from.col()) + , row_begin(from.row()) + , col_begin(from.col()) + , row_end(to.row()) + , col_end(to.col()) +{ +} + +bool Range::next() +{ + if (row_curr < row_end) { + row_curr++; + + return true; + } + if (col_curr < col_end) { + if (row_curr == row_end + 1) + return false; + row_curr = row_begin; + ++col_curr; + return true; + } + return false; +} + +/** + * Decode a row specification into a 0-based integer. + * + * @param rowstr Row specified as a string, with "1" being the first row. + * + * @returns The row. + */ + +int App::decodeRow(const std::string &rowstr) +{ + int row = validRow(rowstr); + + if (row >= 0) + return row; + else + throw Base::Exception("Invalid row specification."); +} + +/** + * Decode a column specification into a 0-based integer. + * + * @param colstr Column specified as a string, with "A" begin the first column. + * + * @returns The column. + * + */ + +int App::decodeColumn(const std::string &colstr) +{ + int col = validColumn(colstr); + + if (col >= 0) + return col; + else + throw Base::Exception("Invalid column specification"); +} + +/** + * Determine wheter a row specification is valid or not. + * + * @param rowstr Row specified as a string, with "1" being the first row. + * + * @returns 0 or positive on success, -1 on error. + */ + +int App::validRow(const std::string &rowstr) +{ + char * end; + int i = strtol(rowstr.c_str(), &end, 10); + + if (i <0 || i >= CellAddress::MAX_ROWS || *end) + return -1; + + return i - 1; +} + +/** + * Determine whether a column specification is valid or not. + * + * @param colstr Column specified as a string, with "A" begin the first column. + * + * @returns 0 or positive on success, -1 on error. + * + */ + +int App::validColumn(const std::string &colstr) +{ + int col = 0; + + if (colstr.length() == 1) { + if ((colstr[0] >= 'A' && colstr[0] <= 'Z')) + col = colstr[0] - 'A'; + else + return -1; + } + else { + col = 0; + for (std::string::const_reverse_iterator i = colstr.rbegin(); i != colstr.rend(); ++i) { + int v; + + if ((*i >= 'A' && *i <= 'Z')) + v = *i - 'A'; + else + return -1; + + col = col * 26 + v; + } + col += 26; + } + return col; +} + +/** + * Convert a string address into integer \a row and \a column. + * row and col are 0-based. + * + * This function will throw an exception if the specified \a address is invalid. + * + * @param address Address to parse. + * @param row Reference to integer where row position is stored. + * @param col Reference to integer where col position is stored. + * + */ + +App::CellAddress App::stringToAddress(const char * strAddress) +{ + static const boost::regex e("\\${0,1}([A-Z]{1,2})\\${0,1}([0-9]{1,5})"); + boost::cmatch cm; + + assert(strAddress != 0); + + if (boost::regex_match(strAddress, cm, e)) { + const boost::sub_match colstr = cm[1]; + const boost::sub_match rowstr = cm[2]; + + return CellAddress(decodeRow(rowstr.str()), decodeColumn(colstr.str())); + } + else + throw Base::Exception("Invalid cell specifier."); +} + +/** + * Convert given \a cell address into its string representation. + * + * @returns Address given as a string. + */ + +std::string App::CellAddress::toString() const +{ + std::stringstream s; + + if (col() < 26) + s << (char)('A' + col()); + else { + int colnum = col() - 26; + + s << (char)('A' + (colnum / 26)); + s << (char)('A' + (colnum % 26)); + } + + s << (row() + 1); + + return s.str(); +} diff --git a/src/App/Range.h b/src/App/Range.h new file mode 100644 index 000000000..4f4fd41ec --- /dev/null +++ b/src/App/Range.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * Copyright (c) Eivind Kvedalen (eivind@kvedalen.name) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef RANGE_H +#define RANGE_H + +#include + +namespace App { + +struct CellAddress; + +AppExport CellAddress stringToAddress(const char *strAddress); +AppExport int decodeColumn(const std::string &colstr); +AppExport int decodeRow(const std::string &rowstr); +AppExport int validColumn(const std::string &colstr); +AppExport int validRow(const std::string &rowstr); + +struct AppExport CellAddress { + + CellAddress(int row = -1, int col = -1) : _row(row), _col(col) { } + + CellAddress(const char * address) { + *this = stringToAddress(address); + } + + CellAddress(const std::string & address) { + *this = stringToAddress(address.c_str()); + } + + inline int row() const { return _row; } + + inline int col() const { return _col; } + + inline bool operator<(const CellAddress & other) const { return asInt() < other.asInt(); } + + inline bool operator==(const CellAddress & other) const { return asInt() == other.asInt(); } + + inline bool operator!=(const CellAddress & other) const { return asInt() != other.asInt(); } + + inline bool isValid() { return (row() >=0 && row() < MAX_ROWS && col() >= 0 && col() < MAX_COLUMNS); } + + std::string toString() const; + + // Static members + + static const int MAX_ROWS; + + static const int MAX_COLUMNS; + +protected: + + inline unsigned int asInt() const { return ((_row << 16) | _col); } + + short _row; + short _col; +}; + +/** + * @brief The Range class is a spreadsheet range iterator. It takes + * a starting (row, col) and an ending (row, col). Notice that ranges + * are always at least one element. The next() functions is therefore + * used e.g as follows: + * + * do { + * ... + * while (range.next()); + * + */ + +class AppExport Range { +public: + Range(const char *range); + + Range(int _row_begin, int _col_begin, int _row_end, int _col_end); + + Range(const CellAddress & from, const CellAddress & to); + + bool next(); + + /** Current row */ + inline int row() const { return row_curr; } + + /** Current column */ + inline int column() const { return col_curr; } + + /** Position of start of range */ + inline CellAddress from() const { return CellAddress(row_begin, col_begin); } + + /** Position of end of range */ + inline CellAddress to() const { return CellAddress(row_end, col_end); } + + /** Start of range as a string */ + inline std::string fromCellString() const { return CellAddress(row_begin, col_begin).toString(); } + + /** End of range as a string */ + inline std::string toCellString() const { return CellAddress(row_end, col_end).toString(); } + + /** Current cell as a string */ + inline std::string address() const { return CellAddress(row_curr, col_curr).toString(); } + + /** The raneg as a string */ + inline std::string rangeString() const { + return CellAddress(row_begin, col_begin).toString() + ":" + CellAddress(row_end, col_end).toString(); + } + + CellAddress operator*() const { return CellAddress(row_curr, col_curr); } + + /** Number of elements in range */ + inline int size() const { return (row_end - row_begin + 1) * (col_end - col_begin + 1); } + +private: + int row_curr, col_curr; + int row_begin, col_begin; + int row_end, col_end; +}; + +} + +#endif // RANGE_H diff --git a/src/App/lex.ExpressionParser.c b/src/App/lex.ExpressionParser.c index bcef09180..dff026292 100644 --- a/src/App/lex.ExpressionParser.c +++ b/src/App/lex.ExpressionParser.c @@ -5615,7 +5615,7 @@ extern std::stack functions; /**< F extern int last_column; extern int column; -#define COUNT do { last_column = column; column += ExpressionParserleng; } while (0) +#define COUNTCHARS do { last_column = column; column += ExpressionParserleng; } while (0) /*** Flex Declarations and Options ***/ /* change the name of the scanner class. */ @@ -5892,7 +5892,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP #line 144 "ExpressionParser.l" -COUNT; +COUNTCHARS; YY_BREAK case 2: /* rule 2 can match eol */ @@ -5904,407 +5904,407 @@ case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 147 "ExpressionParser.l" -COUNT; yylval.string = unquote(ExpressionParsertext); return STRING; +COUNTCHARS; yylval.string = unquote(ExpressionParsertext); return STRING; YY_BREAK case 4: YY_RULE_SETUP #line 149 "ExpressionParser.l" -COUNT; return *ExpressionParsertext; +COUNTCHARS; return *ExpressionParsertext; YY_BREAK case 5: YY_RULE_SETUP #line 151 "ExpressionParser.l" -COUNT; return EQ; +COUNTCHARS; return EQ; YY_BREAK case 6: YY_RULE_SETUP #line 152 "ExpressionParser.l" -COUNT; return NEQ; +COUNTCHARS; return NEQ; YY_BREAK case 7: YY_RULE_SETUP #line 153 "ExpressionParser.l" -COUNT; return GT; +COUNTCHARS; return GT; YY_BREAK case 8: YY_RULE_SETUP #line 154 "ExpressionParser.l" -COUNT; return LT; +COUNTCHARS; return LT; YY_BREAK case 9: YY_RULE_SETUP #line 155 "ExpressionParser.l" -COUNT; return GTE; +COUNTCHARS; return GTE; YY_BREAK case 10: YY_RULE_SETUP #line 156 "ExpressionParser.l" -COUNT; return LTE; +COUNTCHARS; return LTE; YY_BREAK case 11: YY_RULE_SETUP #line 158 "ExpressionParser.l" -COUNT; return MINUSSIGN; +COUNTCHARS; return MINUSSIGN; YY_BREAK case 12: YY_RULE_SETUP #line 159 "ExpressionParser.l" -COUNT; return MINUSSIGN; +COUNTCHARS; return MINUSSIGN; YY_BREAK case 13: YY_RULE_SETUP #line 161 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::NanoMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // nano meter +COUNTCHARS; yylval.quantity.scaler = Quantity::NanoMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // nano meter YY_BREAK case 14: YY_RULE_SETUP #line 162 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro meter +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro meter YY_BREAK case 15: YY_RULE_SETUP #line 163 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro meter (greek micro in UTF8) +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro meter (greek micro in UTF8) YY_BREAK case 16: YY_RULE_SETUP #line 164 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MilliMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli meter (internal standard length) +COUNTCHARS; yylval.quantity.scaler = Quantity::MilliMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli meter (internal standard length) YY_BREAK case 17: YY_RULE_SETUP #line 165 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::CentiMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // centi meter +COUNTCHARS; yylval.quantity.scaler = Quantity::CentiMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // centi meter YY_BREAK case 18: YY_RULE_SETUP #line 166 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::DeciMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // deci meter +COUNTCHARS; yylval.quantity.scaler = Quantity::DeciMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // deci meter YY_BREAK case 19: YY_RULE_SETUP #line 167 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Metre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // metre +COUNTCHARS; yylval.quantity.scaler = Quantity::Metre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // metre YY_BREAK case 20: YY_RULE_SETUP #line 168 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KiloMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo meter +COUNTCHARS; yylval.quantity.scaler = Quantity::KiloMetre; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo meter YY_BREAK case 21: YY_RULE_SETUP #line 170 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Liter; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Liter dm^3 +COUNTCHARS; yylval.quantity.scaler = Quantity::Liter; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Liter dm^3 YY_BREAK case 22: YY_RULE_SETUP #line 172 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro gram +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro gram YY_BREAK case 23: YY_RULE_SETUP #line 173 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro gram +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // micro gram YY_BREAK case 24: YY_RULE_SETUP #line 174 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MilliGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli gram +COUNTCHARS; yylval.quantity.scaler = Quantity::MilliGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli gram YY_BREAK case 25: YY_RULE_SETUP #line 175 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Gram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // gram +COUNTCHARS; yylval.quantity.scaler = Quantity::Gram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // gram YY_BREAK case 26: YY_RULE_SETUP #line 176 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KiloGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo gram (internal standard for mass) +COUNTCHARS; yylval.quantity.scaler = Quantity::KiloGram; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo gram (internal standard for mass) YY_BREAK case 27: YY_RULE_SETUP #line 177 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Ton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Metric Tonne +COUNTCHARS; yylval.quantity.scaler = Quantity::Ton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Metric Tonne YY_BREAK case 28: YY_RULE_SETUP #line 179 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Second; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // second (internal standard time) +COUNTCHARS; yylval.quantity.scaler = Quantity::Second; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // second (internal standard time) YY_BREAK case 29: YY_RULE_SETUP #line 180 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Minute; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // minute +COUNTCHARS; yylval.quantity.scaler = Quantity::Minute; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // minute YY_BREAK case 30: YY_RULE_SETUP #line 181 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Hour; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // hour +COUNTCHARS; yylval.quantity.scaler = Quantity::Hour; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // hour YY_BREAK case 31: YY_RULE_SETUP #line 183 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Ampere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Ampere (internal standard electric current) +COUNTCHARS; yylval.quantity.scaler = Quantity::Ampere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Ampere (internal standard electric current) YY_BREAK case 32: YY_RULE_SETUP #line 184 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MilliAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli Ampere +COUNTCHARS; yylval.quantity.scaler = Quantity::MilliAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // milli Ampere YY_BREAK case 33: YY_RULE_SETUP #line 185 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KiloAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo Ampere +COUNTCHARS; yylval.quantity.scaler = Quantity::KiloAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // kilo Ampere YY_BREAK case 34: YY_RULE_SETUP #line 186 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MegaAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Mega Ampere +COUNTCHARS; yylval.quantity.scaler = Quantity::MegaAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Mega Ampere YY_BREAK case 35: YY_RULE_SETUP #line 188 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Kelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin (internal standard thermodynamic temperature) +COUNTCHARS; yylval.quantity.scaler = Quantity::Kelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin (internal standard thermodynamic temperature) YY_BREAK case 36: YY_RULE_SETUP #line 189 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MilliKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin +COUNTCHARS; yylval.quantity.scaler = Quantity::MilliKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin YY_BREAK case 37: YY_RULE_SETUP #line 190 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin YY_BREAK case 38: YY_RULE_SETUP #line 191 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin +COUNTCHARS; yylval.quantity.scaler = Quantity::MicroKelvin; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Kelvin YY_BREAK case 39: YY_RULE_SETUP #line 193 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Mole; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Mole (internal standard amount of substance) +COUNTCHARS; yylval.quantity.scaler = Quantity::Mole; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Mole (internal standard amount of substance) YY_BREAK case 40: YY_RULE_SETUP #line 195 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Candela; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Candela (internal standard luminous intensity) +COUNTCHARS; yylval.quantity.scaler = Quantity::Candela; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Candela (internal standard luminous intensity) YY_BREAK case 41: YY_RULE_SETUP #line 197 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // inch +COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // inch YY_BREAK case 42: YY_RULE_SETUP #line 198 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // inch +COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // inch YY_BREAK case 43: YY_RULE_SETUP #line 199 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // foot +COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // foot YY_BREAK case 44: YY_RULE_SETUP #line 200 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // foot +COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // foot YY_BREAK case 45: YY_RULE_SETUP #line 201 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // thou (in/1000) +COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // thou (in/1000) YY_BREAK case 46: YY_RULE_SETUP #line 202 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // mil (the thou in US) +COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // mil (the thou in US) YY_BREAK case 47: YY_RULE_SETUP #line 203 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Yard; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // yard +COUNTCHARS; yylval.quantity.scaler = Quantity::Yard; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // yard YY_BREAK case 48: YY_RULE_SETUP #line 204 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Mile; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // mile +COUNTCHARS; yylval.quantity.scaler = Quantity::Mile; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // mile YY_BREAK case 49: YY_RULE_SETUP #line 208 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound +COUNTCHARS; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound YY_BREAK case 50: YY_RULE_SETUP #line 209 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound +COUNTCHARS; yylval.quantity.scaler = Quantity::Pound; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound YY_BREAK case 51: YY_RULE_SETUP #line 210 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Ounce; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // ounce +COUNTCHARS; yylval.quantity.scaler = Quantity::Ounce; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // ounce YY_BREAK case 52: YY_RULE_SETUP #line 211 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Stone; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Stone +COUNTCHARS; yylval.quantity.scaler = Quantity::Stone; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Stone YY_BREAK case 53: YY_RULE_SETUP #line 212 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Hundredweights; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // hundredweights +COUNTCHARS; yylval.quantity.scaler = Quantity::Hundredweights; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // hundredweights YY_BREAK case 54: YY_RULE_SETUP #line 214 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::PoundForce; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound +COUNTCHARS; yylval.quantity.scaler = Quantity::PoundForce; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pound YY_BREAK case 55: YY_RULE_SETUP #line 216 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Newton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton (kg*m/s^2)a-za-za-z +COUNTCHARS; yylval.quantity.scaler = Quantity::Newton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton (kg*m/s^2)a-za-za-z YY_BREAK case 56: YY_RULE_SETUP #line 217 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KiloNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton +COUNTCHARS; yylval.quantity.scaler = Quantity::KiloNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton YY_BREAK case 57: YY_RULE_SETUP #line 218 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MegaNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton +COUNTCHARS; yylval.quantity.scaler = Quantity::MegaNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton YY_BREAK case 58: YY_RULE_SETUP #line 219 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MilliNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton +COUNTCHARS; yylval.quantity.scaler = Quantity::MilliNewton; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Newton YY_BREAK case 59: YY_RULE_SETUP #line 221 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Pascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal (kg/m*s^2 or N/m^2) +COUNTCHARS; yylval.quantity.scaler = Quantity::Pascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal (kg/m*s^2 or N/m^2) YY_BREAK case 60: YY_RULE_SETUP #line 222 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KiloPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal +COUNTCHARS; yylval.quantity.scaler = Quantity::KiloPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal YY_BREAK case 61: YY_RULE_SETUP #line 223 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::MegaPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal +COUNTCHARS; yylval.quantity.scaler = Quantity::MegaPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal YY_BREAK case 62: YY_RULE_SETUP #line 224 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::GigaPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal +COUNTCHARS; yylval.quantity.scaler = Quantity::GigaPascal; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Pascal YY_BREAK case 63: YY_RULE_SETUP #line 226 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Torr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // portion of Pascal ( 101325/760 ) +COUNTCHARS; yylval.quantity.scaler = Quantity::Torr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // portion of Pascal ( 101325/760 ) YY_BREAK case 64: YY_RULE_SETUP #line 227 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::mTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // +COUNTCHARS; yylval.quantity.scaler = Quantity::mTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // YY_BREAK case 65: YY_RULE_SETUP #line 228 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // +COUNTCHARS; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // YY_BREAK case 66: YY_RULE_SETUP #line 229 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // +COUNTCHARS; yylval.quantity.scaler = Quantity::yTorr; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // YY_BREAK case 67: YY_RULE_SETUP #line 231 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::PSI; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pounds/in^2 +COUNTCHARS; yylval.quantity.scaler = Quantity::PSI; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // pounds/in^2 YY_BREAK case 68: YY_RULE_SETUP #line 232 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::KSI; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // 1000 x pounds/in^2 +COUNTCHARS; yylval.quantity.scaler = Quantity::KSI; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // 1000 x pounds/in^2 YY_BREAK case 69: YY_RULE_SETUP #line 234 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Watt; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Watt (kg*m^2/s^3) +COUNTCHARS; yylval.quantity.scaler = Quantity::Watt; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Watt (kg*m^2/s^3) YY_BREAK case 70: YY_RULE_SETUP #line 235 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::VoltAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // VoltAmpere (kg*m^2/s^3) +COUNTCHARS; yylval.quantity.scaler = Quantity::VoltAmpere; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // VoltAmpere (kg*m^2/s^3) YY_BREAK case 71: YY_RULE_SETUP #line 237 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Joule; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Joule (kg*m^2/s^2) +COUNTCHARS; yylval.quantity.scaler = Quantity::Joule; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // Joule (kg*m^2/s^2) YY_BREAK case 72: YY_RULE_SETUP #line 238 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::NewtonMeter; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // N*m = Joule +COUNTCHARS; yylval.quantity.scaler = Quantity::NewtonMeter; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // N*m = Joule YY_BREAK case 73: YY_RULE_SETUP #line 239 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::VoltAmpereSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // V*A*s = Joule +COUNTCHARS; yylval.quantity.scaler = Quantity::VoltAmpereSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // V*A*s = Joule YY_BREAK case 74: YY_RULE_SETUP #line 240 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // +COUNTCHARS; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // YY_BREAK case 75: YY_RULE_SETUP #line 241 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // W*s = Joule +COUNTCHARS; yylval.quantity.scaler = Quantity::WattSecond; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // W*s = Joule YY_BREAK case 76: YY_RULE_SETUP #line 243 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // degree (internal standard angle) +COUNTCHARS; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // degree (internal standard angle) YY_BREAK case 77: YY_RULE_SETUP #line 244 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // degree (internal standard angle) +COUNTCHARS; yylval.quantity.scaler = Quantity::Degree; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // degree (internal standard angle) YY_BREAK case 78: YY_RULE_SETUP #line 245 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Radian; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // radian +COUNTCHARS; yylval.quantity.scaler = Quantity::Radian; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // radian YY_BREAK case 79: YY_RULE_SETUP #line 246 "ExpressionParser.l" -COUNT; yylval.quantity.scaler = Quantity::Gon; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // gon +COUNTCHARS; yylval.quantity.scaler = Quantity::Gon; yylval.quantity.unitStr = ExpressionParsertext; return UNIT; // gon YY_BREAK case 80: YY_RULE_SETUP #line 248 "ExpressionParser.l" -COUNT; yylval.fvalue = num_change(ExpressionParsertext,'.',','); return yylval.fvalue == 1 ? ONE : NUM; +COUNTCHARS; yylval.fvalue = num_change(ExpressionParsertext,'.',','); return yylval.fvalue == 1 ? ONE : NUM; YY_BREAK case 81: YY_RULE_SETUP #line 249 "ExpressionParser.l" -COUNT; yylval.fvalue = num_change(ExpressionParsertext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; +COUNTCHARS; yylval.fvalue = num_change(ExpressionParsertext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; YY_BREAK case 82: YY_RULE_SETUP #line 250 "ExpressionParser.l" -COUNT; yylval.fvalue = num_change(ExpressionParsertext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; +COUNTCHARS; yylval.fvalue = num_change(ExpressionParsertext,',','.'); return yylval.fvalue == 1 ? ONE : NUM; YY_BREAK case 83: YY_RULE_SETUP #line 251 "ExpressionParser.l" -{ COUNT; +{ COUNTCHARS; yylval.ivalue = strtoll( ExpressionParsertext, NULL, 0 ); if (yylval.ivalue == LLONG_MIN) throw Base::Exception("Integer underflow"); @@ -6316,33 +6316,33 @@ YY_RULE_SETUP case 84: YY_RULE_SETUP #line 260 "ExpressionParser.l" -COUNT; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi +COUNTCHARS; yylval.constant.fvalue = M_PI; yylval.constant.name = "pi"; return CONSTANT; // constant pi YY_BREAK case 85: YY_RULE_SETUP #line 261 "ExpressionParser.l" -COUNT; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e +COUNTCHARS; yylval.constant.fvalue = M_E; yylval.constant.name = "e"; return CONSTANT; // constant e YY_BREAK case 86: YY_RULE_SETUP #line 263 "ExpressionParser.l" -COUNT; yylval.string = ExpressionParsertext; return CELLADDRESS; +COUNTCHARS; yylval.string = ExpressionParsertext; return CELLADDRESS; YY_BREAK case 87: YY_RULE_SETUP #line 264 "ExpressionParser.l" -COUNT; yylval.string = ExpressionParsertext; return CELLADDRESS; +COUNTCHARS; yylval.string = ExpressionParsertext; return CELLADDRESS; YY_BREAK case 88: YY_RULE_SETUP #line 265 "ExpressionParser.l" -COUNT; yylval.string = ExpressionParsertext; return CELLADDRESS; +COUNTCHARS; yylval.string = ExpressionParsertext; return CELLADDRESS; YY_BREAK case 89: YY_RULE_SETUP #line 267 "ExpressionParser.l" { - COUNT; + COUNTCHARS; std::string s = ExpressionParsertext; size_t i = s.size() - 2; while (isspace(s[i])) @@ -6359,7 +6359,7 @@ YY_RULE_SETUP case 90: YY_RULE_SETUP #line 282 "ExpressionParser.l" -COUNT; yylval.string = ExpressionParsertext; return IDENTIFIER; +COUNTCHARS; yylval.string = ExpressionParsertext; return IDENTIFIER; YY_BREAK case 91: YY_RULE_SETUP