{"id":898,"date":"2010-01-19T03:00:03","date_gmt":"2010-01-19T11:00:03","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?p=898"},"modified":"2010-01-19T08:53:21","modified_gmt":"2010-01-19T16:53:21","slug":"how-to-access-attributes-from-semantic-actions","status":"publish","type":"post","link":"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-semantic-actions\/","title":{"rendered":"How to Access Attributes from Semantic Actions?"},"content":{"rendered":"<p>The concept of semantic actions seems to be quite easy to understand. It appears to be at least easier to grasp than the concept of attribute propagation. This might be because semantic actions have been part of <em>Spirit<\/em> for almost a decade now. Additionally, with semantic actions data flow control is tightly connected to the component the semantic action is attached to, so the effect is highly localized and easy to spot.<\/p>\n<p><em>Spirit<\/em> has some new features related to semantics actions. That&#8217;s reason enough to talk about how attributes can be accessed from inside semantic actions.<\/p>\n<p><!--more--><\/p>\n<p>First of all, let us revisit the concept of semantic actions.<\/p>\n<blockquote><p>Semantic actions may be attached to any point in the grammar specification. These actions are C++ functions or function objects that are called at certain points during the process of parsing or output generation. In <em>Qi<\/em> a semantic action is called whenever a part of the parser successfully recognizes a portion of the input. In <em>Karma<\/em> they are called whenever a part of the generator is about to be invoked.<\/p><\/blockquote>\n<p>Let us assume\u00a0you have a component <span style=\"font-family: Courier New;\">C<\/span>, and a C++ function or function object <code>F<\/code>, then you can make the component call <code>F<\/code> by attaching it to the component:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nC[F]\r\n<\/pre>\n<p>The expression above links <code>F<\/code> to the component <code>C<\/code>.<\/p>\n<p>Even if it possible to utilize almost any separate C++ function as a semantic action, it is a lot simpler to write semantic actions using <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_41_0\/libs\/spirit\/phoenix\/doc\/html\/index.html\">Boost.Phoenix<\/a>. Phoenix enables to write semantic actions in a very straight forward way. The code to be executed is placed inline directly into the square brackets. Here is a very simple <em>Qi<\/em> example:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::int_[std::cout &lt;&lt; qi::_1]\r\n<\/pre>\n<p>Here <span style=\"font-family: Courier New;\">qi::_1<\/span> is a predefined (Phoenix) placeholder referencing the attribute of the parser the semantic actions has been attached to (the <span style=\"font-family: Courier New;\">qi::int_<\/span>). As the semantic action is invoked <span style=\"text-decoration: underline;\">after<\/span> the parser succeeded, the attribute will be set to the matched value. We can do something very similar in <em>Karma<\/em> as well:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nint i = 3;\r\nkarma::int_[karma::_1 = phoenix::ref(i)] \/\/ will emit: 3\r\n<\/pre>\n<p>Here we assign the value we want to be emitted to the (Phoenix) placeholder <span style=\"font-family: Courier New;\">karma::_1<\/span> (<span style=\"font-family: Courier New;\">phoenix::ref()<\/span> is almost identical to <span style=\"font-family: Courier New;\">boost::ref()<\/span>, except that it integrates nicely with any Phoenix expression). This works as semantic actions in Karma are invoked <span style=\"text-decoration: underline;\">before<\/span> the generator does its job, allowing to pass the current value of the variable <span style=\"font-family: Courier New;\">&#8216;i&#8217;<\/span> as the attribute for the generator <span style=\"font-family: Courier New;\">karma::int_<\/span>.<\/p>\n<p>A lesser known feature of <em>Spirit&#8217;s<\/em> semantic actions is that they can be attached to arbitrary complex parser (or generator) expressions, which is particularly useful if the expression is a sequence. In this case predefined placeholders enable to access the attributes of the sequence elements separately:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n(qi::int_ &gt;&gt; qi::double_)[std::cout &lt;&lt; (qi::_1 + qi::_2)]\r\n<\/pre>\n<p>Here <span style=\"font-family: Courier New;\">qi::_1<\/span> refers to the attribute of the component <span style=\"font-family: Courier New;\">qi::int_<\/span>, and <span style=\"font-family: Courier New;\">qi::_2<\/span> refers to the attribute of <span style=\"font-family: Courier New;\">qi::double_<\/span>. This feature is very handy as the semantic action will be invoked only after both parser components succeeded making sure the results will be evaluated only if the input has been matched completely. This is something which did not work in <em>Spirit.Classic. M<\/em>any developers have been complaining about the lack of any related functionality.<\/p>\n<p>Needless to say, similar constructs are available for <em>Karma<\/em> as well, even if this functionality is there not as important as in <em>Qi<\/em>.<\/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-898\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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\/19\/how-to-access-attributes-from-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\/19\/how-to-access-attributes-from-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>The concept of semantic actions seems to be quite easy to understand. It appears to be at least easier to grasp than the concept of attribute propagation. This might be because semantic actions have been part of Spirit for almost a decade now. Additionally, with semantic actions data flow control is tightly connected to the [&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-898\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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-898\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/19\/how-to-access-attributes-from-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\/19\/how-to-access-attributes-from-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\/19\/how-to-access-attributes-from-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,18],"tags":[7,8],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pIHdZ-eu","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/898"}],"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=898"}],"version-history":[{"count":10,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/898\/revisions"}],"predecessor-version":[{"id":902,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/898\/revisions\/902"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=898"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/categories?post=898"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/tags?post=898"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}