ParserGrammar.hh
9.17 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#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;
#define PARSERGRAMMAR_ADD_OPERATOR(operation, next, operator) fold<operation>(next.alias())[operator >> next]
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_ = equal_.alias();
equal_ = PARSERGRAMMAR_ADD_OPERATOR(EqualOperation, unequal_, equalOperator_);
unequal_ = PARSERGRAMMAR_ADD_OPERATOR(UnequalOperation, greaterOrEqual_, unequalOperator_);
greaterOrEqual_ = PARSERGRAMMAR_ADD_OPERATOR(GreaterOrEqualOperation, lowerOrEqual_, greaterOrEqualOperator_);
lowerOrEqual_ = PARSERGRAMMAR_ADD_OPERATOR(LowerOrEqualOperation, greater_, lowerOrEqualOperator_);
greater_ = PARSERGRAMMAR_ADD_OPERATOR(GreaterOperation, lower_, greaterOperator_);
lower_ = PARSERGRAMMAR_ADD_OPERATOR(LowerOperation, or_, lowerOperator_);
or_ = PARSERGRAMMAR_ADD_OPERATOR(OrOperation, sum_, orOperator_);
sum_ = PARSERGRAMMAR_ADD_OPERATOR(SumOperation, difference_, sumOperator_);
difference_ = PARSERGRAMMAR_ADD_OPERATOR(DifferenceOperation, and_, differenceOperator_);
and_ = PARSERGRAMMAR_ADD_OPERATOR(AndOperation, factor_, andOperator_);
factor_ = PARSERGRAMMAR_ADD_OPERATOR(FactorOperation, division_, factorOperator_);
division_ = PARSERGRAMMAR_ADD_OPERATOR(DivisionOperation, powerTen_, divisionOperator_);
powerTen_ = PARSERGRAMMAR_ADD_OPERATOR(PowerTenOperation, powerTenD_, powerTenOperator_);
powerTenD_ = PARSERGRAMMAR_ADD_OPERATOR(PowerTenDOperation, pow_, powerTenDOperator_);
pow_ = PARSERGRAMMAR_ADD_OPERATOR(PowerOperation, plusSign_, powOperator_);
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_) ) > not_) [_val = boost::phoenix::construct<MinusSignOperation>(_1)] | not_[_val = _1];
not_ = (notOperator_ > functions_) [_val = boost::phoenix::construct<NotOperation>(_1)] | functions_[_val = _1];
functions_ = (threeArgsFunction>>"(">>funArgs_>>argumentSeparator_>>funArgs_>>argumentSeparator_>>funArgs_>>")")[_val= boost::phoenix::construct<FunctionOperation>(_1,_2,_3,_4)] ||
(twoArgsFunction>>"(">>funArgs_>>argumentSeparator_>>funArgs_>>")")[_val= boost::phoenix::construct<FunctionOperation>(_1,_2,_3)]||
(oneArgsFunction>>"(">>funArgs_>>")")[_val= boost::phoenix::construct<FunctionOperation>(_1,_2)]|const_[_val=_1];
// UNARY OPERATIONS
const_ = (definedConstants) [_val = boost::phoenix::construct<ConstantOperation>(_1)] | param_[_val = _1];
param_= ((localParams_ | derivedParam_ | uploadedParam_ | impexParam_ | themisParam_ | cdaWebParam_ | templatedParam_) >>('(' >> componentValue_ >> componentSeparator_ >> componentValue_ >>')'))[_val=boost::phoenix::construct<ParameterDef>(_1,_2,_3)] ||
((localParams_ | derivedParam_ | uploadedParam_ | impexParam_ | themisParam_ | cdaWebParam_ | templatedParam_) >>('(' >> componentValue_ >> ')'))[_val=boost::phoenix::construct<ParameterDef>(_1,_2)] ||
((localParams_ | derivedParam_ | uploadedParam_ | impexParam_ | themisParam_ | cdaWebParam_ | templatedParam_))[_val=boost::phoenix::construct<ParameterDef>(_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')));
componentValue_ = (+qi::char_('0','9') | qi::char_('*') | (qi::string("range[") >> var_ >> qi::char_(',') >> var_ >> qi::string("]")) | (qi::string("indexes[") >> indexValue_ >> qi::char_(',') >> indexValue_ >> qi::string("]")));
indexValue_ = +qi::char_('0','9');
derivedParam_ = (qi::string("ws_") >> +(qi::alnum | qi::char_('_')));
uploadedParam_ = (qi::string("wsd_") >> +(qi::alnum | qi::char_('_')));
impexParam_ = (qi::string("spase___IMPEX_") >> +(qi::alnum | qi::char_('_')));
themisParam_ = (qi::string("th") >> qi::char_('a','e') >> qi::char_('_') >> +(qi::alnum | qi::char_('_')));
cdaWebParam_ = (qi::string("cdaweb_") >> +(qi::alnum | qi::char_('_')));
powOperator_ = qi::char_('^');
powerTenOperator_ = qi::char_('e');
powerTenDOperator_ = qi::char_('d');
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_("<");
argumentSeparator_ = qi::char_(",");
componentSeparator_ = 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 local params
std::vector<std::string> existingParams = ParserToolbox::getParameters(lProperties);
for(std::vector<std::string>::iterator it = existingParams.begin(); it != existingParams.end(); ++it) {
localParams_.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) && (!x.second.hasPromptedArg())) {
oneArgsFunction.add(x.second.getIHMName(), x.second.getKernelName());
}else if ((x.second.getNbArgs() == 2) || ((x.second.getNbArgs() == 1) && x.second.hasPromptedArg())) {
twoArgsFunction.add(x.second.getIHMName(), x.second.getKernelName());
}else {
threeArgsFunction.add(x.second.getIHMName(), x.second.getKernelName());
}
}
// Defined templated parameters
TemplateParamsList existingTemplateParams = ParserToolbox::getTemplateParams(lProperties);
templatedParam_ = (qi::string("fakeparam"));
for(auto const& t : existingTemplateParams ) {
templatedParam_ = (templatedParam_.copy() | (qi::string(t.getParamId()) >> +(qi::alnum | qi::char_('_'))));;
}
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_, componentValue_, indexValue_, derivedParam_, uploadedParam_, impexParam_, themisParam_, cdaWebParam_, templatedParam_;
qi::rule<It, Expression::ExpressionContainer(), Skipper> not_
, pow_
, powerTen_
, powerTenD_
, 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_
, powerTenDOperator_
, andOperator_
, orOperator_
, equalOperator_
, unequalOperator_
, sumOperator_
, differenceOperator_
, factorOperator_
, divisionOperator_
, greaterOperator_
, greaterOrEqualOperator_
, lowerOrEqualOperator_
, lowerOperator_
, argumentSeparator_
, componentSeparator_;
qi::symbols<char, std::string> definedConstants;
qi::symbols<char, std::string> localParams_;
qi::symbols<char, std::string> twoArgsFunction;
qi::symbols<char, std::string> oneArgsFunction;
qi::symbols<char, std::string> threeArgsFunction;
};
}
}
#endif