UBB code parser

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

UBB code parser

Thomas Trummer
Hi,

I'm currently trying to get familiar with Spirit and trying to create
some kind of UBB code parser (similar to the ones used in web-based forums).

For example:

"This is a [b]test string ([i]with inverse content[/i]).[/b]"

Should be broken up into:

"This is a "
[b]
"test string ("
[i]
"with inverse content"
")."
[/b]


I created a grammer for all tags but cant't figure out, how to write the
final expression rule (without creating some infinite loop):


ubb_tag = ubb_color_start | ubb_color_end | ubb_bold_start |
ubb_bold_end | ubb_inverse_start | ubb_inverse_end;

expression = *ubb_tag >> *(*anychar_p - ubb_tag) >> *ubb_tag;


Any ideas?


Regards,
Tim


PS: The complete grammer if it helps:

uint_parser<unsigned, 16, 2, 2> hex2_p;


struct ubb_code : public grammar<ubb_code>
{
        template <typename ScannerT>
        struct definition
        {
                definition(ubb_code const& /*self*/)
                {

                        // Notation for: #rrggbb
                        hex_color3
                                = ch_p('#') >> hex2_p >> hex2_p >> hex2_p;

                        // Notation for: #rrggbbaa
                        hex_color4
                                = ch_p('#') >> hex2_p >> hex2_p >> hex2_p >> hex2_p;

                        //
                        hex_color
                                = longest_d[ hex_color3 | hex_color4 ];

                       
                        // Notation for: [color=hex_color], [/color]
                        ubb_color_start   = str_p("[color=") >> hex_color >> ch_p(']');
                        ubb_color_end     = str_p("[/color]");
                       
                        // Notation for: [b], [/b]
                        ubb_bold_start    = str_p("[b]");
                        ubb_bold_end      = str_p("[/b]");

                        // Notation for: [i], [/i]
                        ubb_inverse_start = str_p("[i]");
                        ubb_inverse_end   = str_p("[/i]");


                        ubb_tag
                                = ubb_color_start | ubb_color_end | ubb_bold_start | ubb_bold_end |
ubb_inverse_start | ubb_inverse_end;

                        expression
                                = *ubb_tag >> *anychar_p - ubb_tag >> *ubb_tag;
                }

                rule<ScannerT> expression, ubb_tag, ubb_inverse_start,
ubb_inverse_end, ubb_bold_start, ubb_bold_end, ubb_color_start,
ubb_color_end, hex_color, hex_color3, hex_color4;

                rule<ScannerT> const& start() const { return expression; }
        };
};


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: UBB code parser

Joel de Guzman-2
Thomas Trummer wrote:

> Hi,
>
> I'm currently trying to get familiar with Spirit and trying to create
> some kind of UBB code parser (similar to the ones used in web-based forums).
>
> For example:
>
> "This is a [b]test string ([i]with inverse content[/i]).[/b]"
>
> Should be broken up into:
>
> "This is a "
> [b]
> "test string ("
> [i]
> "with inverse content"
> ")."
> [/b]
>
>
> I created a grammer for all tags but cant't figure out, how to write the
> final expression rule (without creating some infinite loop):
>
>
> ubb_tag = ubb_color_start | ubb_color_end | ubb_bold_start |
> ubb_bold_end | ubb_inverse_start | ubb_inverse_end;
>
> expression = *ubb_tag >> *(*anychar_p - ubb_tag) >> *ubb_tag;
>
>
> Any ideas?

Have you seen the matching_tags.cpp example in the example/fundamental/
directory?

Cheers,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net



-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: UBB code parser

Carl Barron
In reply to this post by Thomas Trummer

On Sep 13, 2005, at 5:20 PM, Thomas Trummer wrote:

> Hi,
>
> I'm currently trying to get familiar with Spirit and trying to create
> some kind of UBB code parser (similar to the ones used in web-based
> forums).
>
> For example:
>
> "This is a [b]test string ([i]with inverse content[/i]).[/b]"
>
> Should be broken up into:
>
> "This is a "
> [b]
> "test string ("
> [i]
> "with inverse content"
> ")."
> [/b]
>
>
> I created a grammer for all tags but cant't figure out, how to write
> the
> final expression rule (without creating some infinite loop):
>
>
> ubb_tag = ubb_color_start | ubb_color_end | ubb_bold_start |
> ubb_bold_end | ubb_inverse_start | ubb_inverse_end;
>
> expression = *ubb_tag >> *(*anychar_p - ubb_tag) >> *ubb_tag;
>
>
   this grammar terminates.

namespace SP = boost::spirit;
struct ubb_code:SP::grammar<ubb_code>
{
        template <class Scan>
        struct definition
        {
               
                definition(const ubb_code &)
                {
                        item = special_item
                                | SP::anychar_p
                                ;
                        special_item = SP::str_p("[b]")
                                        >> *item
                                        >> "[/b]"
                                | "[i]"
                                        >> *item
                                        >> "[/i]"
                                | "[color="
                                        >> color_no
                                        >> ']'
                                        >> *item
                                        >> "[/color]"
                                ;
                        color_no = SP::ch_p('#')
                                >> SP::longest_d
                                [ hex2_p
                                        >> hex2_p
                                        >> hex2_p
                                 | hex2_p
                                  >> hex2_p
                                ]
                                ;
                        text = *item;
                }
                SP::rule<Scan> item,special_item,color_no,text;
                SP::uint_parser<unsigned,16,2,2> hex2_p;
                SP::rule<Scan> const &start() const
                { return text;}
        };
};

if there are many more alternatives re write using method described by
Joel.
If there are a couple of other special commands to add then this should
be fairly easy to add. Adding semantic actions should be easy to add,






-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: UBB code parser

Thomas Trummer
2005/9/14, Carl Barron <[hidden email]>:

> if there are many more alternatives re write using method described by
> Joel.
> If there are a couple of other special commands to add then this should
> be fairly easy to add. Adding semantic actions should be easy to add,

Thanks for your help, but that does only work if the tags are not
nested (although the idea is quite clever.

I played around a bit and came to this solution:

ubb_tag_a = color_start  [&my_action] | color_end  [&my_action] |
                                    bold_start   [&my_action] | bold_end   [&my_action] |
                                    inverse_start[&my_action] | inverse_end[&my_action] |
                                            eol_p        [&my_action2];

                        ubb_tag = color_start | color_end | bold_start | bold_end |
inverse_start | inverse_end | eol_p;


                        text = (*(anychar_p - ubb_tag))[&my_action] >> *(ubb_tag_a >>
(*(anychar_p - ubb_tag))[&my_action]);

(which is actually a modified list_p)

Regards,
Tom


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Re: UBB code parser

Thomas Trummer
In reply to this post by Joel de Guzman-2
2005/9/14, Joel de Guzman <[hidden email]>:

> Have you seen the matching_tags.cpp example in the example/fundamental/
> directory?

Yes, I have, but it doesn't handle text between two tags. I also don't
need to enforce closing tags neither do I need the tree structure.

It's more like parsing a comma-seperated list with some tags instead
of commas, like

Hello World<tag1>Hello World<tag2>...

(similar to list_p)


Regards
Tom


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: UBB code parser

Joel de Guzman-2
Thomas Trummer wrote:
> 2005/9/14, Joel de Guzman <[hidden email]>:
>
>
>>Have you seen the matching_tags.cpp example in the example/fundamental/
>>directory?
>
>
> Yes, I have, but it doesn't handle text between two tags. I also don't
> need to enforce closing tags neither do I need the tree structure.

C'mon! It's only because it's meant as an example. It's very
easy to add the text "between two tags". If you want to see
this in action, you need a real world example. See QuickBook
or QuickDoc, XML for real examples (http://tinyurl.com/29mcn).
All those are based on the simple example presented. A little
imagination goes a long way!

Cheers,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net



-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: UBB code parser

Joel de Guzman-2
In reply to this post by Thomas Trummer
Thomas Trummer wrote:

> 2005/9/14, Carl Barron <[hidden email]>:
>
>
>>if there are many more alternatives re write using method described by
>>Joel.
>>If there are a couple of other special commands to add then this should
>>be fairly easy to add. Adding semantic actions should be easy to add,
>
>
> Thanks for your help, but that does only work if the tags are not
> nested (although the idea is quite clever.

If you want nested tags, you need a tree structure. There's no
way around that. Recursion==nesting.

Cheers,
--
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net



-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general