ParserGrammar.hh
7.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef PARSERGRAMMAR_HH_
#define PARSERGRAMMAR_HH_
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#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 <typename It, typename Skipper = boost::spirit::standard_wide::space_type>
class ParserGrammar : public qi::grammar<It, Expression::ExpressionContainer(), Skipper>
{
public:
ParserGrammar(AMDA::helpers::Properties& lProperties) : ParserGrammar::base_type(expr_)
{
expr_ = or_.alias();
// Logical Operators
or_ = fold<OrOperation>(and_.alias())[orOperator_ >> and_];
and_ = fold<AndOperation>(equal_.alias())[andOperator_ >> equal_];
equal_ = fold<EqualOperation>(unequal_.alias())[equalOperator_ >> unequal_];
unequal_ = fold<UnequalOperation>(greaterOrEqual_.alias())[unequalOperator_ >>greaterOrEqual_];
greaterOrEqual_ = fold<GreaterOrEqualOperation>(lowerOrEqual_.alias())[greaterOrEqualOperator_ >> lowerOrEqual_];
lowerOrEqual_ = fold<LowerOrEqualOperation>(plusSign_.alias())[lowerOrEqualOperator_ >> plusSign_];
plusSign_ = ((sumOperator_ >>-*sumOperator_)> minusSign_ ) [_val = boost::phoenix::construct<PlusSignOperation>(_1)] ||
((differenceOperator_ >>differenceOperator_)> minusSign_ ) [_val = boost::phoenix::construct<PlusSignOperation>(_1)] |minusSign_ [_val = _1];
minusSign_ = (-*sumOperator_>>differenceOperator_ >>-*sumOperator_> sum_) [_val = boost::phoenix::construct<MinusSignOperation>(_1)] | sum_[_val = _1];
// Numerical Operators
sum_ = fold<SumOperation>(difference_.alias())[sumOperator_ >> difference_];
difference_ = fold<DifferenceOperation>(powerTen_.alias())[differenceOperator_ >> powerTen_];
powerTen_ = fold<PowerTenOperation>(division_.alias())[powerTenOperator_ >> division_];
factor_ = fold<FactorOperation>(division_.alias())[factorOperator_ >> division_];
division_ = fold<DivisionOperation>(pow_.alias())[divisionOperator_ >> pow_];
pow_ = fold<funcop<op_power> >(greater_.alias())[powOperator_ >> greater_];
greater_= fold<GreaterOperation>(lower_.alias())[greaterOperator_ >> lower_];
lower_ = fold<LowerOperation>( functions_.alias())[lowerOperator_ >> functions_];
functions_ = (threeArgsFunction>>"(">>funArgs_>>componentOperator_>>funArgs_>>componentOperator_>>funArgs_>>")")[_val= boost::phoenix::construct<Expression::forop <fun_three>>(_1,_2,_3,_4)] ||
(twoArgsFunction>>"(">>funArgs_>>componentOperator_>>funArgs_>>")")[_val= boost::phoenix::construct<Expression::triop <fun_two>>(_1,_2,_3)]||
(oneArgsFunction>>"(">>funArgs_>>")")[_val= boost::phoenix::construct<Expression::binop <fun_one>>(_1,_2)]|not_[_val=_1];
// UNARY OPERATIONS
not_ = (notOperator_ > const_) [_val = boost::phoenix::construct<NotOperation>(_1)] | const_[_val = _1];
const_ = (definedConstants) [_val = boost::phoenix::construct<ConstantOperation>(_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<std::string, std::string> existingConstants = ParserToolbox::getConstants(lProperties);
for(std::map<std::string, std::string>::iterator it = existingConstants.begin(); it != existingConstants.end(); ++it) {
definedConstants.add (it->first, it->second);
}
// Define available params
std::vector<std::string> existingParams = ParserToolbox::getParameters(lProperties);
for(std::vector<std::string>::iterator it = existingParams.begin(); it != existingParams.end(); ++it) {
definedParams.add(*it,*it);
}
// Defined functions available
std::map<std::string,FunctionInfo> 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<It, Expression::var(), Skipper> var_, vectorArgs_, spectArgs_;;
qi::rule<It, Expression::ExpressionContainer(), Skipper> 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<It, Skipper> notOperator_
, powOperator_
, powerTenOperator_
, andOperator_
, orOperator_
, equalOperator_
, unequalOperator_
, sumOperator_
, differenceOperator_
, factorOperator_
, divisionOperator_
, greaterOperator_
, greaterOrEqualOperator_
,lowerOrEqualOperator_
,componentOperator_
,lowerOperator_ ;
qi::symbols<char, std::string> definedConstants;
qi::symbols<char, std::string> definedParams;
qi::symbols<char, std::string> twoArgsFunction;
qi::symbols<char, std::string> oneArgsFunction;
qi::symbols<char, std::string> threeArgsFunction;
};
}
}
#endif