{"id":1355,"date":"2011-02-26T10:35:32","date_gmt":"2011-02-26T18:35:32","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?p=1355"},"modified":"2011-02-26T11:29:10","modified_gmt":"2011-02-26T19:29:10","slug":"using-_val-in-top-level-semantic-actions","status":"publish","type":"post","link":"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-semantic-actions\/","title":{"rendered":"Using _val in Top Level Semantic Actions"},"content":{"rendered":"<p>Frank Dellaert was asking a valid question on the Spirit mailing list where he pointed out some things he was not able to understand. His question clearly uncovered an inconsistency in <em>Spirit\u2019s<\/em> API. This lead us to implement some minor additional feature, which in the end turned out to make more uniform the way semantic actions are handled.<\/p>\n<p><!--more--><\/p>\n<p>Given the following definitions:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;boost\/spirit\/include\/qi.hpp&gt;\r\n#include &lt;boost\/spirit\/include\/phoenix.hpp&gt;\r\n\r\nnamespace qi = boost::spirit::qi;\r\nnamespace phoenix = boost::phoenix;\r\n\r\nclass Point3\r\n{\r\n    double x_, y_, z_;\r\npublic:\r\n    Point3() : x_(0), y_(0), z_(0) {}\r\n    Point3(double x, double y, double z) : x_(x), y_(y), z_(z) {}\r\n};\r\n\r\nPoint3 pt3;\r\nstd::string input(&quot;1.0,2.0,3.0&quot;);\r\n<\/pre>\n<p>He showed that this piece of code works fine:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::rule&lt;std::string::iterator, Point3()&gt; r =\r\n    (qi::double_ &gt;&gt; ',' &gt;&gt; qi::double_ &gt;&gt; ',' &gt;&gt; qi::double_)\r\n    [\r\n        qi::_val = phoenix::construct&lt;Point3&gt;(qi::_1, qi::_2, qi::_3)\r\n    ];\r\nqi::parse(input.begin(), input.end(), r, pt3);\r\n<\/pre>\n<p>At the same time, this code does not compile:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::parse(\r\n   input.begin(), input.end(),\r\n   (qi::double_ &gt;&gt; ',' &gt;&gt; qi::double_ &gt;&gt; ',' &gt;&gt; qi::double_)\r\n   [\r\n       qi::_val = phoenix::construct&lt;Point3&gt;(qi::_1, qi::_2, qi::_3)\r\n   ],\r\n   pt3);\r\n<\/pre>\n<p>The only difference between the two is that in the first case the parser is wrapped into a rule, while in the second example the parser is directly placed inline into the <span style=\"font-family: Courier New;\">parse()<\/span> API call. After some investigation I understood, that the placeholder <span style=\"font-family: Courier New;\">qi::_val<\/span> was only usable in semantic actions attached to some right hand side of a rule. In this context, it referred to the rule\u2019s attribute.<\/p>\n<p>After some discussions on IRC we decided that this limitation in the behavior of <span style=\"font-family: Courier New;\">qi::_val<\/span> is unneeded and confusing. It turned out that the fix is simple and does not break any existing code. The change, which will be available starting with the next release of Boost (V1.47), has been committed to SVN already. With this change in place it is possible to use the placeholder <span style=\"font-family: Courier New;\">qi::_val<\/span> in top level semantic actions as well, where it will refer to the whole attribute passed in by the user. This now allows to compile the second code example from above.<\/p>\n<p>Please feel free to try it in your code! Note that the fix has been applied not only to <em>Qi\u2019s<\/em> set of <span style=\"font-family: Courier New;\">parse()<\/span> API functions, but also to <em>Karma\u2019s<\/em> set of <span style=\"font-family: Courier New;\">generate()<\/span> functions.<\/p>\n<p>Thanks again to Frank for bringing up this detail, which in the end stirred some interesting discussions and which made Spirit a bit easier to use.<\/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-1355\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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\/2011\/02\/26\/using-_val-in-top-level-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\/2011\/02\/26\/using-_val-in-top-level-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>Frank Dellaert was asking a valid question on the Spirit mailing list where he pointed out some things he was not able to understand. His question clearly uncovered an inconsistency in Spirit\u2019s API. This lead us to implement some minor additional feature, which in the end turned out to make more uniform the way semantic [&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-1355\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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-1355\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2011\/02\/26\/using-_val-in-top-level-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\/2011\/02\/26\/using-_val-in-top-level-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\/2011\/02\/26\/using-_val-in-top-level-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":"yes","spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[9,10],"tags":[7,8],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pIHdZ-lR","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/1355"}],"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=1355"}],"version-history":[{"count":7,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/1355\/revisions"}],"predecessor-version":[{"id":1361,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/1355\/revisions\/1361"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=1355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/categories?post=1355"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/tags?post=1355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}