Fixed compilation on GCC, changed to handle keywords correctly.

This commit is contained in:
bubnikv 2017-11-26 10:54:54 +01:00
parent 708f416c84
commit 2312fa845e

View File

@ -28,7 +28,7 @@
// BOOST_SPIRIT_NO_PREDEFINED_TERMINALS defined, you are // BOOST_SPIRIT_NO_PREDEFINED_TERMINALS defined, you are
// responsible in creating instances of the terminals that // responsible in creating instances of the terminals that
// you need (e.g. see qi::uint_type uint_ below). // you need (e.g. see qi::uint_type uint_ below).
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS //#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define BOOST_RESULT_OF_USE_DECLTYPE #define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3 #define BOOST_SPIRIT_USE_PHOENIX_V3
@ -42,6 +42,7 @@
#include <boost/spirit/include/phoenix_stl.hpp> #include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp> #include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp> #include <boost/spirit/repository/include/qi_iter_pos.hpp>
#include <boost/variant/recursive_variant.hpp> #include <boost/variant/recursive_variant.hpp>
#include <boost/phoenix/bind/bind_function.hpp> #include <boost/phoenix/bind/bind_function.hpp>
@ -234,7 +235,7 @@ namespace client
// Used for throwing parse exceptions. // Used for throwing parse exceptions.
boost::iterator_range<Iterator> it_range; boost::iterator_range<Iterator> it_range;
expr unary_minus(Iterator &start_pos) const expr unary_minus(const Iterator start_pos) const
{ {
switch (this->type) { switch (this->type) {
case TYPE_INT : case TYPE_INT :
@ -564,6 +565,13 @@ namespace client
return os; return os;
} }
// Disable parsing int numbers (without decimals) and Inf/NaN symbols by the double parser.
struct strict_real_policies_without_nan_inf : public qi::strict_real_policies<double>
{
template <typename It, typename Attr> static bool parse_nan(It&, It const&, Attr&) { return false; }
template <typename It, typename Attr> static bool parse_inf(It&, It const&, Attr&) { return false; }
};
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Our calculator grammar // Our calculator grammar
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -572,6 +580,7 @@ namespace client
{ {
calculator() : calculator::base_type(start) calculator() : calculator::base_type(start)
{ {
using namespace qi::labels;
qi::alpha_type alpha; qi::alpha_type alpha;
qi::alnum_type alnum; qi::alnum_type alnum;
qi::eol_type eol; qi::eol_type eol;
@ -584,14 +593,14 @@ namespace client
qi::skip_type skip; qi::skip_type skip;
qi::no_skip_type no_skip; qi::no_skip_type no_skip;
qi::uint_type uint_; qi::uint_type uint_;
qi::real_parser<double, qi::strict_real_policies<double>> strict_double; qi::real_parser<double, strict_real_policies_without_nan_inf> strict_double;
spirit::ascii::char_type char_; spirit::ascii::char_type char_;
spirit::bool_type bool_; spirit::bool_type bool_;
spirit::int_type int_; spirit::int_type int_;
spirit::double_type double_; spirit::double_type double_;
spirit::ascii::string_type string; spirit::ascii::string_type string;
spirit::repository::qi::iter_pos_type iter_pos; spirit::repository::qi::iter_pos_type iter_pos;
using namespace qi::labels; auto kw = spirit::repository::qi::distinct(qi::copy(alnum | '_'));
qi::_val_type _val; qi::_val_type _val;
qi::_1_type _1; qi::_1_type _1;
@ -611,8 +620,8 @@ namespace client
// Allow back tracking after '{' in case of a text_block embedded inside a condition. // Allow back tracking after '{' in case of a text_block embedded inside a condition.
// In that case the inner-most {else} wins and the {if}/{elsif}/{else} shall be paired. // In that case the inner-most {else} wins and the {if}/{elsif}/{else} shall be paired.
// {elsif}/{else} without an {if} will be allowed to back track from the embedded text_block. // {elsif}/{else} without an {if} will be allowed to back track from the embedded text_block.
| lit('{') >> macro(_r1) [_val+=_1] > '}' | (lit('{') >> macro(_r1) [_val+=_1] > '}')
| lit('[') > legacy_variable_expansion(_r1) [_val+=_1] > ']' | (lit('[') > legacy_variable_expansion(_r1) [_val+=_1] > ']')
); );
text_block.name("text_block"); text_block.name("text_block");
@ -624,8 +633,8 @@ namespace client
// New style of macro expansion. // New style of macro expansion.
// The macro expansion may contain numeric or string expressions, ifs and cases. // The macro expansion may contain numeric or string expressions, ifs and cases.
macro = macro =
string("if") > if_else_output(_r1) [_val = _1] (kw["if"] > if_else_output(_r1) [_val = _1])
| string("switch") > switch_output(_r1) [_val = _1] | (kw["switch"] > switch_output(_r1) [_val = _1])
| expression(_r1) [ px::bind(&expr<Iterator>::to_string2, _1, _val) ]; | expression(_r1) [ px::bind(&expr<Iterator>::to_string2, _1, _val) ];
macro.name("macro"); macro.name("macro");
@ -634,11 +643,11 @@ namespace client
eps[_b=true] > eps[_b=true] >
bool_expr_eval(_r1)[_a=_1] > '}' > bool_expr_eval(_r1)[_a=_1] > '}' >
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{' > text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{' >
*("elsif" > bool_expr_eval(_r1)[_a=_1] > '}' > *(kw["elsif"] > bool_expr_eval(_r1)[_a=_1] > '}' >
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{') > text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{') >
-("else" > lit('}') > -(kw["else"] > lit('}') >
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _b, _b, _1, _val)] > '{') > text_block(_r1)[px::bind(&expr<Iterator>::set_if, _b, _b, _1, _val)] > '{') >
"endif"; kw["endif"];
if_else_output.name("if_else_output"); if_else_output.name("if_else_output");
// A switch expression enclosed in {} (the outmost {} are already parsed by the caller). // A switch expression enclosed in {} (the outmost {} are already parsed by the caller).
/* /*
@ -660,7 +669,7 @@ namespace client
legacy_variable_expansion.name("legacy_variable_expansion"); legacy_variable_expansion.name("legacy_variable_expansion");
identifier = identifier =
! keywords >> ! kw[keywords] >>
raw[lexeme[(alpha | '_') >> *(alnum | '_')]]; raw[lexeme[(alpha | '_') >> *(alnum | '_')]];
identifier.name("identifier"); identifier.name("identifier");
@ -714,8 +723,8 @@ namespace client
| (lit('+') > factor(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ] | (lit('+') > factor(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ] | (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ] | (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
| (bool_ > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ] | (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]
| raw[lexeme['"' > *(char_ - char_('\\') - char_('"') | '\\' > char_) > '"']] | raw[lexeme['"' > *(char_ - char_('\\') - char_('"') | ('\\' > char_)) > '"']]
[ px::bind(&FactorActions::string_, _1, _val) ] [ px::bind(&FactorActions::string_, _1, _val) ]
); );
factor.name("factor"); factor.name("factor");
@ -723,8 +732,8 @@ namespace client
scalar_variable_reference = scalar_variable_reference =
variable_reference(_r1)[_a=_1] >> variable_reference(_r1)[_a=_1] >>
( (
'[' > expression(_r1)[px::bind(&MyContext::evaluate_index<Iterator>, _1, _b)] > ']' > ('[' > expression(_r1)[px::bind(&MyContext::evaluate_index<Iterator>, _1, _b)] > ']' >
iter_pos[px::bind(&MyContext::vector_variable_reference<Iterator>, _r1, _a, _b, _1, _val)] iter_pos[px::bind(&MyContext::vector_variable_reference<Iterator>, _r1, _a, _b, _1, _val)])
| eps[px::bind(&MyContext::scalar_variable_reference<Iterator>, _r1, _a, _val)] | eps[px::bind(&MyContext::scalar_variable_reference<Iterator>, _r1, _a, _val)]
); );
scalar_variable_reference.name("scalar variable reference"); scalar_variable_reference.name("scalar variable reference");
@ -748,7 +757,9 @@ namespace client
//("inf") //("inf")
("else") ("else")
("elsif") ("elsif")
("endif"); ("endif")
("false")
("true");
if (0) { if (0) {
debug(start); debug(start);