|
Boost Users : |
Subject: Re: [Boost-users] [Spirit.Qi] How do I get Rule Name/Id through Semantic Action / Phoenix variable
From: HT4N - (ht4n_at_[hidden])
Date: 2009-11-22 17:13:25
"i bing u bing"
----------------------------------------
> From: hartmut.kaiser_at_[hidden]
> To: boost-users_at_[hidden]
> Date: Sun, 22 Nov 2009 09:02:21 -0600
> Subject: Re: [Boost-users] [Spirit.Qi] How do I get Rule Name/Id through Semantic Action / Phoenix variable
>
>> I want to create a generic Parse Tree from a simple expression grammar
>> (see below code snippet). Using the Mini_XML as the reference, I was
>> able to create a Parse Tree close to what I want.
>>
>> If I run my simple program and parse an expressions "[foo=1 bar=2]",
>> for example, it will printout the following Parse Tree:
>>
>> [foo=1 bar=2]
>> -------------------------
>> Parsing succeeded
>>
>> {
>>
>> {
>> foo
>> 1
>> }
>>
>> {
>> bar
>> 2
>> }
>> }
>>
>> The next thing I want to achieve is to have the Parse Tree looks very
>> similar to the one produced in Spirit.Classic. In Spirit.Classic for
>> each node it has RuleId for which we associate it with a RuleName so
>> that when we are iterating the node of the Parse Tree we can printout
>> the RuleName. In other words, instead I want the above Parse Tree to
>> look like the following :
>>
>>
>>
>> foo
>> 1
>>
>>
>> bar
>> 2
>>
>>
>>
>> In other words, what I need to know is how I can get the Rule Name/Id
>> through semantic actions/phoenix variable. Any pointer is appreciated.
>
> You should be able to bind the rule's member function name() and call it
> from inside a semantic action:
>
> rule<...> r;
> r.name("my_rule");
>
> r = p[... = bind(&rule<...>::name, r)];
>
> Regards Hartmut
>
> -------------------
> Meet me at BoostCon
> http://boostcon.com
>
>>
>> Thanks again.
>>
>> HT
>>
>>
>> Code Snippet:
>> namespace client
>> {
>> struct ptnode;
>> typedef boost::variant<
>> nil,
>> unsigned int,
>> string,
>> boost::recursive_wrapper
>>> ptnode_var;
>>
>> ///////////////////////////////////////////////////////////////////////
>> ////
>> // Our AST
>>
>> ///////////////////////////////////////////////////////////////////////
>> ////
>> struct ptnode
>> {
>> ptnode()
>> : data(nil())
>> {
>> }
>> template
>> ptnode(const T& data)
>> : data(data)
>> {
>> }
>> ptnode_var data;
>> vector children;
>> };
>> }
>> // We need to tell fusion about our mini_xml struct
>> // to make it a first-class fusion citizen
>> //[tutorial_xml1_adapt_structures
>> BOOST_FUSION_ADAPT_STRUCT(
>> client::ptnode,
>> (client::ptnode_var, data)
>> (std::vector, children)
>> )
>> //]
>> namespace client
>> {
>> template
>> struct ExpressionGrammar : qi::grammar>> ascii::space_type>
>> {
>> ExpressionGrammar() : ExpressionGrammar::base_type(Option)
>> {
>> using qi::_val;
>> using qi::_1;
>> using qi::char_;
>> using qi::alnum;
>> using qi::alpha;
>> using qi::lexeme;
>> using qi::raw;
>> using qi::uint_;
>> using phoenix::at_c;
>> using phoenix::push_back;
>> Option = char_('[')
>>>> *Expression
>> [push_back(at_c<1>(_val), _1)]
>>>> char_(']');
>> Expression = ParameterName
>> [push_back(at_c<1>(_val), _1)]
>>>> (char_('=')>> ParameterValue
>> [push_back(at_c<1>(_val), _1)]);
>> ParameterName = lexeme[+(alnum) [_val
>> += _1]];
>> ParameterValue = uint_ [_val =
>> _1];
>> Option.name("Option");
>> Expression.name("Expression");
>> ParameterName.name("ParameterName");
>> ParameterValue.name("ParameterValue");
>> }
>> qi::rule Option;
>> qi::rule Expression;
>> qi::rule ParameterName;
>> qi::rule ParameterValue;
>> };
>>
>>
>> ///////////////////////////////////////////////////////////////////////
>> ////
>> // Print out the mini xml tree
>>
>> ///////////////////////////////////////////////////////////////////////
>> ////
>> int const tabsize = 4;
>> void tab(int indent)
>> {
>> for (int i = 0; i < indent; ++i)
>> {
>> printf_s(" ");
>> }
>> }
>>
>> struct ptnode_printer
>> {
>> ptnode_printer(int indent = 0)
>> : indent(indent)
>> {
>> }
>> void operator()(ptnode const& node) const;
>> int indent;
>> };
>>
>> struct ptnode_var_printer : boost::static_visitor<>
>> {
>> ptnode_var_printer(int indent = 0)
>> : indent(indent)
>> {
>> }
>>
>> void operator()(const ptnode& var) const
>> {
>> ptnode_printer(indent+tabsize)(var);
>> }
>>
>> void operator()(const nil&) const
>> {
>> // Print node type ...
>> tab(indent);
>> printf_s("\n");
>> }
>>
>> void operator()(const string& val) const
>> {
>> tab(indent+tabsize);
>> printf_s("%s\n", val.c_str());
>> }
>>
>> void operator()(const int& val) const
>> {
>> tab(indent+tabsize);
>> printf_s("%d\n", val);
>> }
>>
>> int indent;
>> };
>>
>> void ptnode_printer::operator()(const ptnode& node) const
>> {
>> boost::apply_visitor(ptnode_var_printer(indent), node.data);
>> tab(indent);
>> printf_s("{\n");
>> BOOST_FOREACH(const ptnode_var& child, node.children)
>> {
>> boost::apply_visitor(ptnode_var_printer(indent), child);
>> }
>> tab(indent);
>> printf_s("}\n");
>> }
>> }
>>
>> _________________________________________________________________
>> Windows 7: I wanted simpler, now it's simpler. I'm a rock star.
>> http://www.microsoft.com/Windows/windows-
>> 7/default.aspx?h=myidea?ocid=PID24727::T:WLMTAGL:ON:WL:en-
>> US:WWL_WIN_myidea:112009
>> _______________________________________________
>> Boost-users mailing list
>> Boost-users_at_[hidden]
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
_________________________________________________________________
Windows 7: It works the way you want. Learn more.
http://www.microsoft.com/Windows/windows-7/default.aspx?ocid=PID24727::T:WLMTAGL:ON:WL:en-US:WWL_WIN_evergreen:112009v2
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