boost::spirit block of C++ code

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

boost::spirit block of C++ code

elviin
I created this parser and it is working for me
except the detail:

//------------------
                                                 //the body of the block
            cpp_code_block_text = *(anychar_p-ch_p('{')-ch_p('}'));
                                                 //the code begins with '{'
            cpp_code_block_begin_p = ch_p('{');
                                                //the code ends with '}'
            cpp_code_block_end_p = ch_p('}');

//parser:

            cpp_code_block_p =
                    cpp_code_block_begin_p
                >>
                    repeat_p (0, 100)[(cpp_code_block_p|cpp_code_block_text)]
                >>
                    cpp_code_block_end_p;



----------------------
Here is the text I'm using for tests:

{asas
{bbbbbb
bbb b b { asa}bb
bbb b bb
}
as
{aaaa}
{aaaacc}
asasa
{}
aaa
}

And the problem is in repeat_p (0, 100). I'd like to use * instead but
it does not work for me because the parser runs forever. 100 means the
number of blocks  cpp_code_block_p or cpp_code_block_text.

Where is the problem?
Thank you very much for reply.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::spirit block of C++ code

João Abecasis-2
Hi!

elviin wrote:
> I created this parser and it is working for me
> except the detail:

[snip code]

> And the problem is in repeat_p (0, 100). I'd like to use * instead but
> it does not work for me because the parser runs forever. 100 means the
> number of blocks  cpp_code_block_p or cpp_code_block_text.
>
> Where is the problem?

The code sample you provided can be summarized as

     continuation = *(anychar_p - (begin|end));
     all = begin >> *continuation >> end;

Which, substituting continuation, is the same as:

     all = begin >> *(*(anychar_p - (begin|end))) >> end;

The problem here is the double kleene star. The outer kleene will
continue matching, in an infinite loop, as long as the inner one returns
matches -- even if they're zero matches. Btw, this is a FAQ and is
addressed here http://tinyurl.com/art36.

When you substitute the outer * for repeat_p(0, 100) you only limit the
loop. You still get 100 matches, even if they're all empty.

The solution is pretty simple, and it is to remove one of the
*/repeat_p. For instance,

     continuation = *(anychar_p - (begin|end));
     all = begin >> continuation >> end;

Best regards,


João

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::spirit block of C++ code

elviin
Hi João!

I have adjusted the code according to your advise and the FAQ and it
is now working for me.
Here is the update:

//----------------
            cpp_code_block_text = anychar_p-(ch_p('{')|ch_p('}'));
            cpp_code_block_begin_p = ch_p('{');
            cpp_code_block_end_p = ch_p('}');


            cpp_code_block_p =
                    cpp_code_block_begin_p
                >>
                        *(cpp_code_block_p|cpp_code_block_text)
                >>
                    cpp_code_block_end_p;


At the first sight the boost::spirit seems to be difficult to use but
with more experience I recognize that it is realy nice/good tool.
Thank you João.

On 17/01/06, João Abecasis <[hidden email]> wrote:

> Hi!
>
> elviin wrote:
> > I created this parser and it is working for me
> > except the detail:
>
> [snip code]
>
> > And the problem is in repeat_p (0, 100). I'd like to use * instead but
> > it does not work for me because the parser runs forever. 100 means the
> > number of blocks  cpp_code_block_p or cpp_code_block_text.
> >
> > Where is the problem?
>
> The code sample you provided can be summarized as
>
>      continuation = *(anychar_p - (begin|end));
>      all = begin >> *continuation >> end;
>
> Which, substituting continuation, is the same as:
>
>      all = begin >> *(*(anychar_p - (begin|end))) >> end;
>
> The problem here is the double kleene star. The outer kleene will
> continue matching, in an infinite loop, as long as the inner one returns
> matches -- even if they're zero matches. Btw, this is a FAQ and is
> addressed here http://tinyurl.com/art36.
>
> When you substitute the outer * for repeat_p(0, 100) you only limit the
> loop. You still get 100 matches, even if they're all empty.
>
> The solution is pretty simple, and it is to remove one of the
> */repeat_p. For instance,
>
>      continuation = *(anychar_p - (begin|end));
>      all = begin >> continuation >> end;
>
> Best regards,
>
>
> João
>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users