Boost logo

Boost Users :

Subject: Re: [Boost-users] Spirit Newbie (balanced parentheses)
From: EricB (eric.britz_at_[hidden])
Date: 2010-04-17 14:51:42


Thank you your example really helped me.

I'm using the following as a test case:

fdqfds
dd
d ^!for-each ( a/b/c()/e[]/d )
 (
item )

Here are the rules
{
boost::spirit::chlit<> LPAREN('(');
boost::spirit::chlit<> RPAREN(')');
boost::spirit::strlit<> CMDSWITCH("^!");

script = * ( (boost::spirit::anychar_p - CMDSWITCH) | command );
/* */
command
  = boost::spirit::discard_first_node_d[
    CMDSWITCH
>> (for_each
    | to_string
    | boost::spirit::eps_p
        [&calculator::error_log]
    ) ] ;
/* */
for_each
  = boost::spirit::discard_first_node_d[
    boost::spirit::as_lower_d["for-each"]
>> *boost::spirit::space_p
>> query
>> *boost::spirit::space_p
>> subscript
  ] ;
/* */
query
  = boost::spirit::inner_node_d[
    LPAREN >>
    * ( query_text1
      | query_text2
    )
>> RPAREN
  ] ;
{ // this is to handle balanced () inside query
  query_text1 = boost::spirit::anychar_p - (LPAREN|RPAREN);
  query_text2 = LPAREN >> * ( query_text1 | query_text2) >> RPAREN ;
}

subscript
  = boost::spirit::inner_node_d[
    LPAREN >>
    *( command
      | subscript1
      | subscript2
    )
>> RPAREN
  ] ;
{ // this is to handle balanced () and command inside subscript
  subscript1 = boost::spirit::anychar_p - (CMDSWITCH|LPAREN|RPAREN) ;
  subscript2 = LPAREN >> *( subscript1 | subscript2 | command ) >> RPAREN
  ;
}

to_string
  = boost::spirit::as_lower_d["to-string"] ;
}

I'm building an tree while parsing and then I'm printing it using
boost::spirit::tree_to_xml.

I have 2 additional questions :
1)
The for each statement produces the following AST. The nodes marked with
XXX at end of lines are produced due to the "*boost::spirit::space_p "
part of the for-each rule. Is there a way (a directive or something else
in the grammar) to skip this content so that the marked nodes (XXX)
would not appeared in the AST ?
(i have tried discar_node_d, and other directives but nothing works)
        <parsenode rule="for_eachID">
            <parsenode> XXX
                <value> </value> XXX
            </parsenode> XXX
            <parsenode rule="queryID">
                <parsenode>
                    ...
                </parsenode>
            </parsenode>
            <parsenode> XXX
                <value> </value> XXX
            </parsenode> XXX
            <parsenode> XXX
                <value>\n</value> XXX
            </parsenode> XXX
            <parsenode> XXX
                <value> </value> XXX
            </parsenode> XXX
            <parsenode rule="subscriptID">
                <parsenode>
                    ...
                </parsenode>
            </parsenode>
        </parsenode>

2)The query rule handles inner balanced parentheses but it produces the
following AST: =>input is b/c()/e

I Would like the AST produced from the inner () to be flatten. I would
like the node marked with XXX not to be generated. Is there a directive
for this ?
<parsenode>
    <value>b</value>
</parsenode>
<parsenode>
    <value>/</value>
</parsenode>
<parsenode>
    <value>c</value>
</parsenode>
<parsenode> XXX
    <parsenode>
        <value>(</value>
    </parsenode>
    <parsenode>
        <value>)</value>
    </parsenode>
</parsenode> XXX
<parsenode>
    <value>/</value>
</parsenode>
<parsenode>
    <value>e</value>
</parsenode>


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