[proto]is_const fails and expr::operator= accepts wrong value.

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[proto]is_const fails and expr::operator= accepts wrong value.

Larry Evans
Eric,

I've got code:

       result_type
     operator()(expr_type& a_expr, ctx_type& a_ctx)const
     {
         proto::functional::left a_left_getter;
         typedef typename proto::result_of::left<expr_type>::reference
left_type;
         BOOST_MPL_ASSERT_NOT((is_const<left_type>));
         BOOST_MPL_ASSERT_NOT((is_const<const left_type>));
//        BOOST_MPL_ASSERT_NOT((is_const<const int>));
         left_type a_left_expr=a_left_getter(a_expr);
         a_left_expr.put_empty(lookahead::empty_not);
         typename remove_const<left_type>::type a_left_mut(a_left_expr);
         a_left_mut.put_empty(lookahead::empty_not);

which, when compiled, does not fail either BOOST_MPL_ASSERT_NOT's.
Although it's a type_traits bug, I'm guessing you're a little
concerned also ;)

I've also got code:

                         typedef
                       i<addop>::type
                     addop_var_type;
                   #if 0
                         typedef
                       lookahead::expr
                       < inp
                       , proto::expr
                         < proto::tag::shift_right
                         , proto::args2
                           < addop_var_type
                           , addop_var_type
                           >
                         , 2l
                         >
                       >
                     rs_i_i_type;
                     rs_i_i_type a_expr;
                   #else
                     BOOST_AUTO(a_expr,(i_addop >> i_addop));
                   #endif
                     a_expr=static_cast<addop_var_type*>(0);

which compiles without complaint about the a_expr assignment.
I also tried something like static_cast<int*>(0) and it
didn't complain either.  That's not the expected behaviour,
is it? (BTW, the only reason I was doing this was to
have the compiler show me what type a_expr was.  I
wanted to see if it was const).

I'll post the code in the vault in the next few minutes; however,
it's kinda big.

-regards,
Larry


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

Re: [proto]is_const fails and expr::operator= accepts wrong value.

Larry Evans
On 06/16/2007 12:44 PM, Larry Evans wrote:
[snip]
>
> I'll post the code in the vault in the next few minutes; however,
> it's kinda big.
>
It's now in directory:

   Strings - Text Processing

in zip:

   cfg_lookahead_extends.zip

The problem I'm trying to solve is the one mentioned previously about
calculating 3 attributes of each grammar subexpression:

   empty
   first
   follow

The code uploaded is trying to just do the empty.
AFAICT, the problem is that the expression:

    x >> y >> z

results in a constant subexpression; yet, it needs to be
non-const so that the attributes can be calculated.  The
attributes are all stored in an proto extension to the
base proto expression.  The extension is defined in the
lookahead_expr.hpp file.

Let me know if you need for info.

-regards,
Larry


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

more complete LL1 docs in vault ( Re: [proto]is_const fails and expr::operator= accepts wrong value.

Larry Evans
On 06/16/2007 01:02 PM, Larry Evans wrote:
[snip]
>
> The problem I'm trying to solve is the one mentioned previously about
> calculating 3 attributes of each grammar subexpression:
>
>    empty
>    first
>    follow
>
[snip]
I just uploaded some docs to vault which should explain
in more detail my ultimate goal.  The docs
might give you or someone else some ideas about how
to do it better than my current way.

The docs are, of course, in the:

  String - Text Processing

directory in LewiLL1.zip.


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

Re: [proto]is_const fails and expr::operator= accepts wrong value.

Eric Niebler
In reply to this post by Larry Evans

Larry Evans wrote:
>          typedef typename proto::result_of::left<expr_type>::reference
> left_type;
>          BOOST_MPL_ASSERT_NOT((is_const<left_type>));
>          BOOST_MPL_ASSERT_NOT((is_const<const left_type>));
>
> which, when compiled, does not fail either BOOST_MPL_ASSERT_NOT's.
> Although it's a type_traits bug, I'm guessing you're a little
> concerned also ;)

No, I'm not concerned.

     BOOST_MPL_ASSERT_NOT((boost::is_const<int const &>));
     BOOST_MPL_ASSERT_NOT((boost::is_const<int const & const>));

Remember that cv qualifiers are ignored when applied to reference types.


> I've also got code:
>
>                          typedef
>                        i<addop>::type
>                      addop_var_type;
>                    #if 0
>                          typedef
>                        lookahead::expr
>                        < inp
>                        , proto::expr
>                          < proto::tag::shift_right
>                          , proto::args2
>                            < addop_var_type
>                            , addop_var_type
>                            >
>                          , 2l
>                          >
>                        >
>                      rs_i_i_type;
>                      rs_i_i_type a_expr;
>                    #else
>                      BOOST_AUTO(a_expr,(i_addop >> i_addop));
>                    #endif
>                      a_expr=static_cast<addop_var_type*>(0);
>
> which compiles without complaint about the a_expr assignment.
> I also tried something like static_cast<int*>(0) and it
> didn't complain either.  That's not the expected behaviour,
> is it? (BTW, the only reason I was doing this was to
> have the compiler show me what type a_expr was.  I
> wanted to see if it was const).


Yes, it's expected behavior. a_expr is an expression template.
a_expr=<anything> is also an expression template. You're creating an
expression tree, not doing an assignment.

However, the code is wrong in a very subtle way. In proto expressions,
everything is held by reference, even temporary intermediate nodes in
the tree. So when you say BOOST_AUTO(foo, some>>proto>>expr), you're
guaranteed to have dangling references. Use BOOST_PROTO_AUTO instead,
which deep-copies the tree.

Also, could I suggest that when you post code you use a more
conventional formatting style? I have a very hard time reading your code.

--
Eric Niebler
Boost Consulting
www.boost-consulting.com

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

Re: [proto]is_const fails and expr::operator= accepts wrong value.

Eric Niebler
In reply to this post by Larry Evans
Larry Evans wrote:

> The code uploaded is trying to just do the empty.
> AFAICT, the problem is that the expression:
>
>     x >> y >> z
>
> results in a constant subexpression; yet, it needs to be
> non-const so that the attributes can be calculated.  The
> attributes are all stored in an proto extension to the
> base proto expression.  The extension is defined in the
> lookahead_expr.hpp file.

I haven't looked at the code, but I think I understand from your
description. You have a data members in a proto::extends<> wrapper for
tracking the empty, first and follow sets, is that right? And then you
are writing a transform or an evaluation context to fill them in.

Well the proto expression tree is made up of temporary objects, which is
why they are const. You can make the data members mutable. Or you can
write a transform that builds a new tree and decorates each node with
empty/first/follow. Or (and I've never done something like this, but it
should be do-able), your wrapper can calculate the empty/first/follow in
its constructor. You'd be building it piecemeal, as you build your
expression, instead of in a separate transformation pass.

--
Eric Niebler
Boost Consulting
www.boost-consulting.com

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

Re: [proto]is_const fails and expr::operator= accepts wrong value.

Larry Evans
In reply to this post by Eric Niebler
On 06/16/2007 03:07 PM, Eric Niebler wrote:
> Larry Evans wrote:
[snip]
>> which, when compiled, does not fail either BOOST_MPL_ASSERT_NOT's.
>> Although it's a type_traits bug, I'm guessing you're a little
>> concerned also ;)
[snip]
> Remember that cv qualifiers are ignored when applied to reference types.

I'm guilty :(  Thanks for the hand-holding ;) .  You saved me
a lot of time.

>> I've also got code:
[snip]
>>                      a_expr=static_cast<addop_var_type*>(0);
>>
>> which compiles without complaint about the a_expr assignment.
[snip]
> Yes, it's expected behavior. a_expr is an expression template.
> a_expr=<anything> is also an expression template. You're creating an
> expression tree, not doing an assignment.
Yes. Guilty again.  I changed to BOOST_PROTO_AUTO and it compiles
and runs OK now.  Again, what was obvious to you was escaping
me and you saved me lots of time and headache.  I actually
used operator= to define a production so it should have been
obvious to me, but I guess not.  Thanks again!
[snip]


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

proto lookahead complete and distant future compile time lookahead(was Re: [proto]is_const fails and expr::operator= accepts wrong value.

Larry Evans
In reply to this post by Eric Niebler
On 06/16/2007 03:16 PM, Eric Niebler wrote:
 > Larry Evans wrote:
 >> The code uploaded is trying to just do the empty.

Newly uploaded code

(in <boost-vault>/Strings - Text Processing/cfg_lookahead_extends.zip)

now does first and follow as well.

[snip]
 > I haven't looked at the code, but I think I understand from your
 > description. You have a data members in a proto::extends<> wrapper for
 > tracking the empty, first and follow sets, is that right? And then you
 > are writing a transform or an evaluation context to fill them in.

Yes.

 > Well the proto expression tree is made up of temporary objects,
 > which is why they are const. You can make the data members
 > mutable. Or you can write a transform that builds a new tree and
 > decorates each node with empty/first/follow.

The uploaded code does the former, but I'd like to try the latter. The
reason is that the operator= produces in it's first argument( i.e. the
lhs of the assignment) an extended proto terminal whose extension
(i.e. the empty/first/follow attributes) are never modified; hence,
it's wasted space.  Since the operator, is used to create a list of
operator= expression in the grammar, that's num_prods wasted
extensions, where num_prods is the number of productions in the
grammar.  That's not a lot; however, it will also confuse any future
code maintainer who may search vainly for any use of these lhs
extensions.  The ideal would be a proto terminal which just stores the
production number.  This is used to update the estimate of lookahead
attributes for the grammar nonterminals during iterative solution for
these lookahead attributes.

 > Or (and I've never done something like this, but it should be
 > do-able), your wrapper can calculate the empty/first/follow in its
 > constructor. You'd be building it piecemeal, as you build your
 > expression, instead of in a separate transformation pass.

The lookahead attributes cannot be built in one transformation pass.
Their solution method has to be iterative.  This is because the
equations defining the attributes have the unknowns (the grammar
nonterminals) on both the lhs and rhs of the equations.  The
soln_context<AttrNum,,>::solve method in the uploaded code performs
this iterative solution, where AttrNum is the attribute
(empty/first/follow).

Now this need for iterative solution means the lookahead attributes
are not calculated at compile time; hence, the parse functions will
only partially calculated at compile time.  The e.dirsymb attribute
(a function of all attributes.  See the LewLL1.zip in value for the
definition) is calculated at runtime; hence, the parsing will be a
little slower.  However, I just thought I'd try and see if the
lookaheaads could be calculated a compile time.  That's what I
attempted in:

   <boost-vault>/Strings - Text Proccesing/gram_lookahead.zip

As the comments indicate, it's not completed.  I ran against a problem
with the first/follow attributes which is, I think, related to proto's
terminals.  If you recall, about a week or month ago, there was some
discussion about the arity of proto terminals.  You decided to change
the arity to 0.  This was good because it was consistent with the way
algebra's and their morphisms are defined.  However, in the case of
gram_lookahead.zip, this lead to the aforementioned problem with
first/follow calculation.  In gram_lookahead.zip, the morphisms
cannot proceed down the expression tree after a node with arity==0 is
reached. However, with the first and follow algebra, the terminal
values are not single values like true or false, but instead multiple
values like {ident,value,lpar} (e.g. the first attribute of factor
nonterminal in arith_expression grammar).  So, the reduction of values
in this grammar must continue through the value contained in the proto
terminal (which is an instance of mpl::set on grammar terminals, like
ident, value, or lpar).  This lead me to search for something in
algebra literature to handle this, and that lead to something called
"heirarchical albebras" where the arity-0 expressions are actually
values in some other algebra (if I'm interpresting things correctly).
This sounds like what I was looking for.  I would be interesting if
the transforms in proto actually were more like heirarchical algebra
morphisms. Just something to think about (probably in the distant
future ;) ).


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto lookahead complete and distant future compile time lookahead

Eric Niebler

(This seems to be drifting off-topic for this Spirit-devel list. Perhaps
we should move this discussion to the boost list.)

Larry Evans wrote:
> Now this need for iterative solution means the lookahead attributes
> are not calculated at compile time; hence, the parse functions will
> only partially calculated at compile time.  The e.dirsymb attribute
> (a function of all attributes.  See the LewLL1.zip in value for the
> definition) is calculated at runtime; hence, the parsing will be a
> little slower.


Of course, ET transforms are not purely compile-time, or at least, they
don't have to be. They can have a run-time counterpart, too. I've added
some examples recently to demonstrate this. Have a look at the
CountLeaves transform at http://tinyurl.com/2qme82 for an example that
uses std::plus to accumulate a runtime value.


   However, I just thought I'd try and see if the

> lookaheaads could be calculated a compile time.  That's what I
> attempted in:
>
>    <boost-vault>/Strings - Text Proccesing/gram_lookahead.zip
>
> As the comments indicate, it's not completed.  I ran against a problem
> with the first/follow attributes which is, I think, related to proto's
> terminals.  If you recall, about a week or month ago, there was some
> discussion about the arity of proto terminals.  You decided to change
> the arity to 0.  This was good because it was consistent with the way
> algebra's and their morphisms are defined.  However, in the case of
> gram_lookahead.zip, this lead to the aforementioned problem with
> first/follow calculation.


Which problem?


   In gram_lookahead.zip, the morphisms
> cannot proceed down the expression tree after a node with arity==0 is
> reached.


Huh, there is nothing "down" after a node with arity 0. That's all you
get. :-)


  However, with the first and follow algebra, the terminal
> values are not single values like true or false, but instead multiple
> values like {ident,value,lpar} (e.g. the first attribute of factor
> nonterminal in arith_expression grammar).


OK, so your terminal is a 3-tuple. It's still a terminal.


   So, the reduction of values
> in this grammar must continue through the value contained in the proto
> terminal (which is an instance of mpl::set on grammar terminals, like
> ident, value, or lpar).


I don't think you need proto to "recurse" into your terminals. I just
think you need to write a custom transform that does something
appropriate with your terminals.


   This lead me to search for something in
> algebra literature to handle this, and that lead to something called
> "heirarchical albebras" where the arity-0 expressions are actually
> values in some other algebra (if I'm interpresting things correctly).
> This sounds like what I was looking for.  I would be interesting if
> the transforms in proto actually were more like heirarchical algebra
> morphisms. Just something to think about (probably in the distant
> future ;) ).


Well, that's one approach. In fact, you can approximate that in proto
today by wrapping a proto expression in a template, effectively hiding
its proto-ness from proto, which would then treat it like any other
terminal. You would be responsible for writing the transforms and/or
contexts that knew about these special terminals and recursed into them.


--
Eric Niebler
Boost Consulting
www.boost-consulting.com

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Spirit-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-devel