(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