{"id":914,"date":"2010-01-21T03:00:00","date_gmt":"2010-01-21T11:00:00","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?p=914"},"modified":"2010-01-23T11:07:58","modified_gmt":"2010-01-23T19:07:58","slug":"what-are-rule-bound-semantic-actions","status":"publish","type":"post","link":"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/","title":{"rendered":"What are Rule Bound Semantic Actions?"},"content":{"rendered":"<p>In <a href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-semantic-actions\/\">the previous installment<\/a> of the &#8216;Tip of the Day&#8217; I started to talk about some lesser known features related to semantic actions. Today I will highlight some more details. If a semantic action is attached to a component which is part of an expression assigned to a rule (the rule&#8217;s right hand side) it is not only possible to access the attributes of the components it is connected with. In addition it is possible to access rule specific values! Sounds interesting? Read on!<\/p>\n<p><!--more--><\/p>\n<p>I chose this topic even if I got some comments asking me to avoid writing about things already covered in <em>Spirit&#8217;s<\/em> documentation. At the same time, I believe it&#8217;s valuable for some of you to repeat the facts from the docs but presented in a more pointed and descriptive way. Additionally, I think the articles as published here lay the ground for more detailed things not yet covered in the docs, but the basics need to be explained properly before we can touch the more advanced stuff. But please leave your comments below telling me what you would like to see highlighted. I am always interested in getting feedback on what works for you and what not.<\/p>\n<p>Ok, here we go \u2013 let us talk about rule bound semantic actions.<\/p>\n<p>Any semantic action attached to the right hand side of a rule (or a part of it) is special. We will call those &#8216;rule bound semantic actions&#8217;. <em>Spirit<\/em> provides you with extra placeholder variables (in addition to <span style=\"font-family: Courier New;\">_1<\/span>, <span style=\"font-family: Courier New;\">_2<\/span>, etc.) usable to access values related to the enclosing rule (the rule, the expression has been assigned to). For the purpose of this post I assume, that the semantic actions are written using <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/spirit\/phoenix\/doc\/html\/index.html\">Boost.Phoenix<\/a>. In fact, all placeholders described below are implemented using Phoenix and do not integrate very well with other, similar facilities available in Boost (such as <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/bind\/bind.html\">Boost.Bind<\/a> or <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/doc\/html\/lambda.html\">Boost.Lambda<\/a>). You should avoid mixing Phoenix placeholder with expressions built from those libraries. This is no limitation, as from my experience, using Phoenix is just the simplest way to write semantic actions.<\/p>\n<p>Let us assume further, that we have a component <span style=\"font-family: Courier New;\">c<\/span> with an attached semantic action <span style=\"font-family: Courier New;\">f<\/span>, which is assigned as the right hand side of a rule exposing a synthesized attribute of type <span style=\"font-family: Courier New;\">Attr<\/span> and providing local variables of types <span style=\"font-family: Courier New;\">L1<\/span>, <span style=\"font-family: Courier New;\">L2<\/span>, etc. (I will explain local variables shortly):<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nrule&lt;Iterator, Attr(), locals&lt;L1, L2, ...&gt; &gt; r = c[f];\r\n<\/pre>\n<p>Here is a list of all predefined placeholders available in the rule bound semantic action <span style=\"font-family: Courier New;\">F<\/span> (see also the related documentation <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/spirit\/doc\/html\/spirit\/qi\/quick_reference\/phoenix.html\">here<\/a> and <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/spirit\/doc\/html\/spirit\/karma\/quick_reference\/phoenix.html\">here<\/a>):<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\" width=\"600\">\n<tbody>\n<tr>\n<td width=\"181\" valign=\"top\"><strong>Placeholders<\/strong><\/td>\n<td width=\"419\" valign=\"top\"><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\"><code>_1, _2 ... , _N<\/code><\/td>\n<td width=\"419\" valign=\"top\">Nth attribute of <code>c<\/code><\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\"><code>_val<\/code><\/td>\n<td width=\"419\" valign=\"top\">The enclosing rule&#8217;s synthesized attribute (of type <span style=\"font-family: Courier New;\">Attr<\/span>)<\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\">\n<dt><code>_a, _b ... , _j<\/code><\/dt>\n<\/td>\n<td width=\"419\" valign=\"top\">The enclosing rule&#8217;s local variables (<code>_a<\/code> refers to the first of type <span style=\"font-family: Courier New;\">L1<\/span>, <span style=\"font-family: Courier New;\">_b<\/span> to the next of type <span style=\"font-family: Courier New;\">L2<\/span>, etc.)<\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\"><code>_r1, _r2 ... , _rN<\/code><\/td>\n<td width=\"419\" valign=\"top\">The enclosing rule&#8217;s Nth inherited attribute<\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\">\n<dt><code>_pass<\/code><\/dt>\n<\/td>\n<td width=\"419\" valign=\"top\">Assign <code>false<\/code> to <code>_pass<\/code> to force a parser or generator failure<\/td>\n<\/tr>\n<tr>\n<td width=\"181\" valign=\"top\">\u00a0\u00a0<\/td>\n<td width=\"419\" valign=\"top\">\u00a0\u00a0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We already talked about <span style=\"font-family: Courier New;\">_val<\/span>, <span style=\"font-family: Courier New;\">_1<\/span>, <span style=\"font-family: Courier New;\">_2<\/span>, etc. last time, and I will not describe inherited attributes today, that is for another day. I would like to concentrate on local variables here.<\/p>\n<p>Local variables allow to associate arbitrary typed data instances with each rule invocation. These variables are very similar to local variables in a function. They are valid only during the invocation of the rule they are defined in and they automatically go out of scope after the right hand side of the rule has finished executing. Further, each invocation of a rule creates a new set of (default constructed) local variables, even if the same rule is invoked recursively.<\/p>\n<p>Here is a small <em>Karma<\/em> example generating a list of items prefixed with a sequence number (note: <span style=\"font-family: Courier New;\">_a<\/span>, <span style=\"font-family: Courier New;\">eps<\/span>, <span style=\"font-family: Courier New;\">string<\/span>, <span style=\"font-family: Courier New;\">lit<\/span>, <span style=\"font-family: Courier New;\">rule<\/span>, and <span style=\"font-family: Courier New;\">locals<\/span> are imported from <span style=\"font-family: Courier New;\">namespace boost::spirit::karma<\/span>).<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nrule&lt;OutIter, locals&lt;int&gt;, std::vector&lt;std::string&gt;()&gt; r =\r\n    eps[_a = 1] &lt;&lt; (lit(_a) &lt;&lt; eps[++_a] &lt;&lt; &quot; &quot; &lt;&lt; string) % '\\n';\r\n<\/pre>\n<p>Let us analyze, what this rule definition does.\u00a0<\/p>\n<ul>\n<li>The attribute of this rule is <span style=\"font-family: Courier New;\">std::vector&lt;std::string&gt;<\/span>, for the sake of simplicity we will pass in all items stored in this type of container. The items are emitted using the list operator\u00a0(<span style=\"font-family: Courier New;\">%<\/span>), causing them to be interleaved with newlines.<\/li>\n<li>One of the rule&#8217;s template parameters is <span style=\"font-family: Courier New;\">locals&lt;int&gt;<\/span>. That is the way we declare the types of the local variables. The template <span style=\"font-family: Courier New;\">locals&lt;&gt;<\/span> is a type container you can use to list the types for all local variables to instantiate for each of the rule&#8217;s invocations.<\/li>\n<li>In our example, we have a single local variable of type <span style=\"font-family: Courier New;\">int<\/span>\u00a0 and we reference it from the right hand side of the rule definition using the placeholder <span style=\"font-family: Courier New;\">_a<\/span>.<\/li>\n<li>The generator <span style=\"font-family: Courier New;\">eps<\/span> is utilized to inject invocations of semantic actions initializing and incrementing the local variable. The generator <span style=\"font-family: Courier New;\">eps<\/span> is perfect for doing this as it succeeds always while emitting nothing.<\/li>\n<li>The most notable construct is <span style=\"font-family: Courier New;\">lit(_a)<\/span> showing that it is possible to directly create a generator component from the local variable. Many of <em>Spirit&#8217;s<\/em> construct are enabled for lazy evaluation, and <span style=\"font-family: Courier New;\">lit()<\/span> is one of them.<\/li>\n<\/ul>\n<p>The only additional thing I want to add is that everything shown above works equally well in <em>Qi<\/em>, but you probably already guessed this. For your convenience, the corresponding symbols are available from the <span style=\"font-family: Courier New;\">namespace boost::spirit::qi<\/span> as well. If you are interested in seeing locals in action\u00a0in a more complete\u00a0<em>Qi<\/em> example you should have a look at the mini-xml series as described in the docs <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/spirit\/doc\/html\/spirit\/qi\/tutorials\/mini_xml___asts_.html\">here<\/a>.<\/p>\n<p>This &#8216;Tip of the Day&#8217; got a little longer than usual, but I hope it is worth reading anyways. Spirit is a large library and there are uncounted hidden gems waiting not only to be described, but some of them are still waiting to be discovered. Happy hacking and experimenting!<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li><a href=\"#\" class=\"sharing-anchor sd-button share-more\"><span>Share<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><div class=\"sharing-hidden\"><div class=\"inner\" style=\"display: none;\"><ul><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-914\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\" ><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-914\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\" ><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-pinterest\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-pinterest-914\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=pinterest\" target=\"_blank\" title=\"Click to share on Pinterest\" ><span>Pinterest<\/span><\/a><\/li><li class=\"share-linkedin\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-linkedin-914\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=linkedin\" target=\"_blank\" title=\"Click to share on LinkedIn\" ><span>LinkedIn<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-reddit\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-reddit sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=reddit\" target=\"_blank\" title=\"Click to share on Reddit\" ><span>Reddit<\/span><\/a><\/li><li class=\"share-tumblr\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-tumblr sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=tumblr\" target=\"_blank\" title=\"Click to share on Tumblr\" ><span>Tumblr<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>In the previous installment of the &#8216;Tip of the Day&#8217; I started to talk about some lesser known features related to semantic actions. Today I will highlight some more details. If a semantic action is attached to a component which is part of an expression assigned to a rule (the rule&#8217;s right hand side) it [&hellip;]<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li><a href=\"#\" class=\"sharing-anchor sd-button share-more\"><span>Share<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><div class=\"sharing-hidden\"><div class=\"inner\" style=\"display: none;\"><ul><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-914\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\" ><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-914\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\" ><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-pinterest\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-pinterest-914\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=pinterest\" target=\"_blank\" title=\"Click to share on Pinterest\" ><span>Pinterest<\/span><\/a><\/li><li class=\"share-linkedin\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-linkedin-914\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=linkedin\" target=\"_blank\" title=\"Click to share on LinkedIn\" ><span>LinkedIn<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-reddit\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-reddit sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=reddit\" target=\"_blank\" title=\"Click to share on Reddit\" ><span>Reddit<\/span><\/a><\/li><li class=\"share-tumblr\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-tumblr sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/21\/what-are-rule-bound-semantic-actions\/?share=tumblr\" target=\"_blank\" title=\"Click to share on Tumblr\" ><span>Tumblr<\/span><\/a><\/li><li class=\"share-end\"><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div><\/div><\/div>","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_s2mail":"","spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[19,20,18],"tags":[7,8],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pIHdZ-eK","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/914"}],"collection":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/comments?post=914"}],"version-history":[{"count":10,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/914\/revisions"}],"predecessor-version":[{"id":923,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/914\/revisions\/923"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/categories?post=914"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/tags?post=914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}