Boost logo

Boost Users :

Subject: [Boost-users] [Proto] Strange behavior with semantic action and custom tag function
From: Joel Falcou (joel.falcou_at_[hidden])
Date: 2008-10-11 11:49:16


I'm stuck on some problem that may en dup silly.
I have a DSL defined by the following grammar :

struct dimen_grammar : bp::or_<

//////////////////////////////////////////////////////////////////////////
    // Terminals are dimensional values or integral values

//////////////////////////////////////////////////////////////////////////
   bp::or_< bp::terminal< dimensions<bp::_,bp::_> >
           , integer_grammar
>

//////////////////////////////////////////////////////////////////////////
    // dimen can be added together or scaled by an integer
   // or shifted left or right by an integer

//////////////////////////////////////////////////////////////////////////

   ,bp::or_< bp::plus<dimen_grammar,dimen_grammar>
        ,bp::multiplies<dimen_grammar,integer_grammar>
            ,bp::multiplies<integer_grammar,dimen_grammar>
         ,bp::shift_left<dimen_grammar,integer_grammar>
           ,bp::shift_right<dimen_grammar,integer_grammar>
>
> {};

I've defined a proper callable_context that take care of my special
terminals and built
a terminal class. At this point, everythign works perfect : i can build
expressions and evaluate them.

Now I add a grammar with semantic action that helps me computes an
aspect of those expression :

struct dimen_size : bp::or_<

//////////////////////////////////////////////////////////////////////////
    // dimensionnal values terminal contains its own size value

//////////////////////////////////////////////////////////////////////////
      bp::when< bp::terminal< dimensions<bp::_,bp::_> >
          , dimension_of< bp::_value>()
>

//////////////////////////////////////////////////////////////////////////
    // integral values has a size of 1

//////////////////////////////////////////////////////////////////////////
    , bp::when<integer_grammar, bm::size_t<1>()>

//////////////////////////////////////////////////////////////////////////
    // size(d1+d2) = max(size(d1),size(d2))

//////////////////////////////////////////////////////////////////////////

    , bp::when< bp::plus<dimen_grammar,dimen_grammar>
          , bm::max<dimen_size(bp::_left),dimen_size(bp::_right)>()
>

//////////////////////////////////////////////////////////////////////////
    // size(d1*i) = size(d1)

//////////////////////////////////////////////////////////////////////////

    , bp::when< bp::multiplies<dimen_grammar,integer_grammar>
          , dimen_size(bp::_left)
>

//////////////////////////////////////////////////////////////////////////
    // size(i*d2) = size(d2)

//////////////////////////////////////////////////////////////////////////

    , bp::when< bp::multiplies<integer_grammar,dimen_grammar>
          , dimen_size(bp::_right)
>

//////////////////////////////////////////////////////////////////////////
    // size(d1<<i) = size(d1)

//////////////////////////////////////////////////////////////////////////

    , bp::when< bp::shift_left<dimen_grammar,integer_grammar>
          , dimen_size(bp::_left)
>

//////////////////////////////////////////////////////////////////////////
    // size(d1>>i) = size(d1)

//////////////////////////////////////////////////////////////////////////

    , bp::when< bp::shift_right<dimen_grammar,integer_grammar>
          , dimen_size(bp::_left)
>

//////////////////////////////////////////////////////////////////////////
    // Other returns 0

//////////////////////////////////////////////////////////////////////////

    , bp::when<bp::_, bm::size_t<0>()>
> {};

This works. If I remove the bp::when<bp::_, bm::size_t<0>()>, it fails
to compile when I try to use a hand-overloaded operator<< for
displaying expression values on standard output.

So, is there anything I missed (like deactivating operator<< in the
grammar somehow ?) ?

Other question :
When defining custom tag to build new function, why does the make_expr
tempalte doesn't do check on its argument
to see if it's match the grammar of the domain it's bound to use ? Seems
I'm forced to add additional layer of SFINAE to prevent those
function to get called on w/e types.

Thanks in advance for help

-- 
___________________________________________
Joel Falcou - Assistant Professor
PARALL Team - LRI - Universite Paris Sud XI
Tel : (+33)1 69 15 66 35

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net