(a || b) is not the same as (a >> -b | b) !!!!
Juan Dent <[email protected]> Sun, 18 Oct 2020 17:25:55 +0000
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <BYAPR14MB307775F605F15512D801D7969B010@BYAPR14MB3077.namprd14.prod.outlook.com> |
Hi ! According to Boost.Spirit: https://www.boost.org/doc/libs/1_74_0/libs/spiri= t/doc/html/spirit/qi/tutorials/roman_numerals.html (a || b) is the same as (a >> -b | b) yet experimentation does not agree = with this. Check this code: std::string s =3D "50 43.3"; = first =3D s.begin(); last =3D s.end(); = double p1; int p2; int p3; std::vector<double> v; = = bool r =3D phrase_parse(first, last, // begin grammar ( double_ >> -int_ | int_ ), space, v); this when run, delivers 2 elements in the v vector attribute ( 50.000, 43.0= 00). When we change the grammar to this: std::string s =3D "50 43.3"; //"34.555 60"; first =3D s.begin(); last =3D s.end(); = double p1; int p2; int p3; std::vector<double> v; = = bool r =3D phrase_parse(first, last, // begin grammar ( double_ || int_ ), space, v); v vector attribute delivers only one element (50.0000) THUS: the 2 grammars are NOT the same!! Please confirm and also answer this question: how do I pass a tuple instead= of a vector to phrase_parse? (in order to use tuple<double,int>) Regards, Juan Dent -----Original Message----- From: Larry Evans <[email protected]> = Sent: Saturday, October 17, 2020 9:11 AM To: [email protected] Subject: Re: [Spirit-general] How to use functions in the semantic actions? On 10/12/20 6:50 PM, Juan Dent wrote: > amount =3D uint3_p[_val =3D _1] > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 >> *(',' > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 >> uint3_3_p)[_val *=3D 100= 0][_val +=3D _1] > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 >> +('.' > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 >> uint1_7_p)[_val +=3D _1/= 10000.0][_val =3D = > produce_decimal_value(_val)] > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ; > = > } > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 template<typename T> > = > =A0=A0=A0 constexpr T produce_decimal_value(T local) > = > =A0=A0=A0 { > = > =A0=A0=A0=A0=A0=A0=A0 if (local =3D=3D 0)=A0=A0=A0=A0 // error C2451: con= ditional expression of = > type 'const boost::phoenix::actor<Expr>' is illegal > = > =A0=A0=A0=A0=A0=A0=A0 {} > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // need t= o manipulate the value of _val which I = > capture here using templates > = > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // > = > =A0=A0=A0=A0=A0=A0=A0=A0return local; > = > =A0=A0=A0 } > = > =A0 > = > How can I manipulate the value of=A0=A0 _/val in a member function of the = > grammar (i.e. produce/_decimal_value)? > = > I need to check when local reaches 0 in order to calculate the digits = > after the decimal point but it won't allow me from method of grammar = > class. > = > =A0 > = > Please some direction here. > It's funny, I can manipulate the numeric vales or _val and _1 inside = > the constructor of the grammar but not from a user defined method of = > same grammar. When I try to use _val =A0as a number it throws errors. > = > =A0 > = > Regards, > = > Juan > = Using phoenix::bind gets right result in following code: #include <iostream> #include <iomanip> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_bind.hpp> #include <boost/optional/optional_io.hpp> namespace qi=3Dboost::spirit::qi; namespace phoenix =3D boost::phoenix; namespace ascii =3D boost::spirit::ascii; using result_type=3Dlong double; namespace client { template <typename Iterator> struct Base10_grammar : qi::grammar<Iterator, result_type(), ascii::space_type > { static void whole_fract ( result_type& value , unsigned const& attr1 , std::vector<unsigned> const& attr2 , boost::optional<std::vector<unsigned int> >const& attr3 ) { value=3Dresult_type(attr1); result_type factor=3D1000.0; for(unsigned part:attr2) { value=3Dvalue*factor+result_type(part); } if (attr3) { factor=3D1.0; auto const& digits=3D*attr3; for(unsigned part:digits) { factor*=3D0.1; value+=3Dpart*factor; } } } Base10_grammar() : Base10_grammar::base_type(amount) { amount =3D ( ( uint1_3_p >> *( ',' >> uint3_3_p ) ) >> -( '.' >> (*uint1_1_p) ) ) [ phoenix::bind ( &whole_fract , qi::_val , qi::_1 , qi::_2 , qi::_3 ) ] ; } qi::rule<Iterator, result_type(), ascii::space_type> amount; qi::uint_parser<unsigned, 10, 1, 3> uint1_3_p; // 1..3 digits qi::uint_parser<unsigned, 10, 3, 3> uint3_3_p; // exactly 3 digits qi::uint_parser<unsigned, 10, 1, 1> uint1_1_p; // exactly 1 digit }; }//client namespace ///////////////////////////// // called from: int main(int argc, char** argv) { std::locale loc(""); std::cout.imbue(loc); std::string storage =3D "100,200,300.00123"; std::cout<<"storage=3D"<<storage<<"\n"; typedef client::Base10_grammar <std::string::const_iterator> Base10_gra= mmar; Base10_grammar g; // Our grammar using boost::spirit::ascii::space; std::string::const_iterator iter =3D storage.begin(); std::string::const_iterator end =3D storage.end(); result_type value; bool r =3D qi::phrase_parse(iter, end, g, space, value); if (r && iter =3D=3D end) { std::cout << "-------------------------\n"; std::cout << "Parsing succeeded\n"; std::cout << "-------------------------\n"; std::cout << "value=3D"<<std::fixed<<std::setprecision(10)<<value<<"\n"; return 0; } else { std::cout << "-------------------------\n"; std::cout << "Parsing failed\n"; std::cout << "-------------------------\n"; return 1; } } the std::cout output is: storage=3D100,200,300.00123 ------------------------- Parsing succeeded ------------------------- value=3D100,200,300.0012300000 _______________________________________________ Spirit-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/spirit-general