#ifndef PARSERGRAMMAR_HH_ #define PARSERGRAMMAR_HH_ #include #include #include "ExpressionContainer.hh" #include "CustomFoldDirective.hh" #include "ParserToolbox.hh" #include "Properties.hh" #include "FunctionInfo.hh" namespace AMDA { namespace parser { namespace qi = boost::spirit::qi; using namespace qi; using namespace Expression; template class ParserGrammar : public qi::grammar { public: ParserGrammar(AMDA::helpers::Properties& lProperties) : ParserGrammar::base_type(expr_) { expr_ = or_.alias(); // Logical Operators or_ = fold(and_.alias())[orOperator_ >> and_]; and_ = fold(equal_.alias())[andOperator_ >> equal_]; equal_ = fold(unequal_.alias())[equalOperator_ >> unequal_]; unequal_ = fold(greaterOrEqual_.alias())[unequalOperator_ >>greaterOrEqual_]; greaterOrEqual_ = fold(lowerOrEqual_.alias())[greaterOrEqualOperator_ >> lowerOrEqual_]; lowerOrEqual_ = fold(plusSign_.alias())[lowerOrEqualOperator_ >> plusSign_]; plusSign_ = ((sumOperator_ >>-*sumOperator_)> minusSign_ ) [_val = boost::phoenix::construct(_1)] || ((differenceOperator_ >>differenceOperator_)> minusSign_ ) [_val = boost::phoenix::construct(_1)] |minusSign_ [_val = _1]; minusSign_ = (-*sumOperator_>>differenceOperator_ >>-*sumOperator_> sum_) [_val = boost::phoenix::construct(_1)] | sum_[_val = _1]; // Numerical Operators sum_ = fold(difference_.alias())[sumOperator_ >> difference_]; difference_ = fold(powerTen_.alias())[differenceOperator_ >> powerTen_]; powerTen_ = fold(division_.alias())[powerTenOperator_ >> division_]; factor_ = fold(division_.alias())[factorOperator_ >> division_]; division_ = fold(pow_.alias())[divisionOperator_ >> pow_]; pow_ = fold >(greater_.alias())[powOperator_ >> greater_]; greater_= fold(lower_.alias())[greaterOperator_ >> lower_]; lower_ = fold( functions_.alias())[lowerOperator_ >> functions_]; functions_ = (threeArgsFunction>>"(">>funArgs_>>componentOperator_>>funArgs_>>componentOperator_>>funArgs_>>")")[_val= boost::phoenix::construct>(_1,_2,_3,_4)] || (twoArgsFunction>>"(">>funArgs_>>componentOperator_>>funArgs_>>")")[_val= boost::phoenix::construct>(_1,_2,_3)]|| (oneArgsFunction>>"(">>funArgs_>>")")[_val= boost::phoenix::construct>(_1,_2)]|not_[_val=_1]; // UNARY OPERATIONS not_ = (notOperator_ > const_) [_val = boost::phoenix::construct(_1)] | const_[_val = _1]; const_ = (definedConstants) [_val = boost::phoenix::construct(_1)] | param_[_val = _1]; param_= (definedParams >>('(' >> (spectArgs_|vectorArgs_)>>')'))[_val='$'+_1+"["+qi::_2+"]"] || definedParams[_val='$'+_1]| simple[_val = _1]; funArgs_=((expr_ |var_) |functions_); simple = (('(' > expr_ > ')') | var_); var_ = (+qi::char_('0','9') >> -qi::char_('.') >> -(+qi::char_('0','9'))) | ((qi::char_('.') >> +qi::char_('0','9'))); vectorArgs_%=qi::raw[qi::int_ > -(qi::char_(',')>>qi::int_) ]; spectArgs_ %=qi::raw[(qi::int_>>qi::char_(',')>>'*')|(qi::char_('*')>>qi::char_(',')>>qi::int_)]; powOperator_ = qi::char_('^'); powerTenOperator_ = qi::char_('e'); notOperator_ = qi::char_('!'); andOperator_ = qi::string("&"); orOperator_ = qi::string("|"); equalOperator_ = qi::string("="); unequalOperator_ = qi::string("!="); sumOperator_ = qi::char_('+'); differenceOperator_ = qi::char_('-'); factorOperator_ = qi::char_("*"); divisionOperator_ = qi::char_("/"); greaterOperator_ = qi::char_(">"); greaterOrEqualOperator_ = qi::string(">="); lowerOrEqualOperator_ = qi::string("<="); lowerOperator_ = qi::char_("<"); componentOperator_ = qi::char_(","); // Define available constants std::map existingConstants = ParserToolbox::getConstants(lProperties); for(std::map::iterator it = existingConstants.begin(); it != existingConstants.end(); ++it) { definedConstants.add (it->first, it->second); } // Define available params std::vector existingParams = ParserToolbox::getParameters(lProperties); for(std::vector::iterator it = existingParams.begin(); it != existingParams.end(); ++it) { definedParams.add(*it,*it); } // Defined functions available std::map existingFunctions = ParserToolbox::getFunctions(lProperties); for(auto const& x : existingFunctions ) { if (x.second.getNbArgs()==1) { oneArgsFunction.add(x.second.getIHMName(), x.second.getKernelName()); }else if (x.second.getNbArgs()==2) { twoArgsFunction.add(x.second.getIHMName(), x.second.getKernelName()); }else { threeArgsFunction.add(x.second.getIHMName(), x.second.getKernelName()); } } BOOST_SPIRIT_DEBUG_NODES((expr_)(or_)(and_)(equal_)(unequal_)(greaterOrEqual_)(lowerOrEqual_)(lower_)(sum_) (difference_)(factor_)(division_)(simple)(notOperator_)(andOperator_)(orOperator_)(equalOperator_)(unequalOperator_) (sumOperator_)(differenceOperator_)(factorOperator_)(divisionOperator_)(greater_)(lower_)(functions_)); } private: qi::rule var_, vectorArgs_, spectArgs_;; qi::rule not_ , pow_ , powerTen_ , and_ , or_ , equal_ , unequal_ , sum_ , difference_ , factor_ , division_ , simple , expr_ ,plusSign_ ,minusSign_ ,greater_ ,greaterOrEqual_ ,lowerOrEqual_ ,lower_ ,const_ ,param_ ,functions_ ,funArgs_; qi::rule notOperator_ , powOperator_ , powerTenOperator_ , andOperator_ , orOperator_ , equalOperator_ , unequalOperator_ , sumOperator_ , differenceOperator_ , factorOperator_ , divisionOperator_ , greaterOperator_ , greaterOrEqualOperator_ ,lowerOrEqualOperator_ ,componentOperator_ ,lowerOperator_ ; qi::symbols definedConstants; qi::symbols definedParams; qi::symbols twoArgsFunction; qi::symbols oneArgsFunction; qi::symbols threeArgsFunction; }; } } #endif