{"id":943,"date":"2010-01-26T03:41:57","date_gmt":"2010-01-26T11:41:57","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?p=943"},"modified":"2010-01-26T03:51:48","modified_gmt":"2010-01-26T11:51:48","slug":"whats-the-difference-between-karmas-and","status":"publish","type":"post","link":"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/","title":{"rendered":"What&#8217;s the Difference Between Karma&#8217;s &#8216;!&#8217; and &#8216;~&#8217;?"},"content":{"rendered":"<p>A couple of days ago I promised to get back to this topic (if you want to refresh your memory, <a href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-and\/\">here<\/a> is the discussion of those operators in <em>Qi<\/em>). Today we will discuss <em>Karma&#8217;s<\/em> unary operators <span style=\"font-family: Courier New;\">&#8216;!&#8217;<\/span> and <span style=\"font-family: Courier New;\">&#8216;~&#8217;<\/span>. These have very similar semantics as their counterparts in <em>Qi<\/em>, but as usual, we have to turn things inside out in order to make them fit to output generation.<\/p>\n<p><!--more--><\/p>\n<p>The one commonality of the two operators is the same as in <em>Qi<\/em>: both negate whether the component they are being used with succeeds generating. If the component <span style=\"font-family: Courier New;\">&#8216;c&#8217;<\/span> succeeds, both compound constructs, <span style=\"font-family: Courier New;\">&#8216;!c&#8217;<\/span> and <span style=\"font-family: Courier New;\">&#8216;~c&#8217;<\/span> will fail, and similarly, if <span style=\"font-family: Courier New;\">&#8216;c&#8217;<\/span> fails, the execution of the components <span style=\"font-family: Courier New;\">&#8216;!c&#8217;<\/span> and <span style=\"font-family: Courier New;\">&#8216;~c&#8217;<\/span> will succeed.<\/p>\n<p>Similar to its counterpart in <em>Qi<\/em>, the unary <em>Karma<\/em> operator <span style=\"font-family: Courier New;\">&#8216;~&#8217;<\/span> is applicable to character and character class generators only. It negates the set of characters a generator will be allowed to emit. Let me explain. The <em>Karma<\/em> character set generators, such as <span style=\"font-family: Courier New;\">char_(&#8220;a-z&#8221;)<\/span> or <span style=\"font-family: Courier New;\">digit<\/span> will emit their attribute only if the attribute value belongs to the character set described. Consequently, applying the operator &#8216;~&#8217; will negate the character set the generator it is attached to. Here are some examples:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\" width=\"600\">\n<tbody>\n<tr>\n<td width=\"109\" valign=\"top\"><strong>Expression<\/strong><\/td>\n<td width=\"491\" valign=\"top\"><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"109\" valign=\"top\"><span style=\"font-family: Courier New;\">~char<span style=\"font-family: Courier New;\">_(&#8220;a-z&#8221;)<\/span> <\/span><\/td>\n<td width=\"491\" valign=\"top\">will emit character values outside the character range spanned by &#8216;a&#8217; and &#8216;z&#8217;<\/td>\n<\/tr>\n<tr>\n<td width=\"109\" valign=\"top\"><span style=\"font-family: Courier New;\">~digit<\/span><\/td>\n<td width=\"491\" valign=\"top\">will emit non-digits only<\/td>\n<\/tr>\n<tr>\n<td width=\"109\" valign=\"top\"><span style=\"font-family: Courier New;\">~char_(&#8216;a&#8217;)<\/span><\/td>\n<td width=\"491\" valign=\"top\">will emit everything but an <span style=\"font-family: Courier New;\">&#8216;a&#8217;<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0<\/p>\n<p>If a generator can&#8217;t emit its attribute it will fail. This is very similar to a failing parser component. The possibility for a generator component to fail is very useful. This can be utilized for alternatives, predicates and other constructs. But this is beyond today&#8217;s topic and will be discussed in a different installment of the &#8216;Tip of the Day&#8217;.<\/p>\n<p>The generators created by the operator <span style=\"font-family: Courier New;\">&#8216;~&#8217;<\/span> do not wrap the underlying generator. The operator rather modifies the behavior of the component it is attached to. This means there is no performance difference if compared to the plain character generators.<\/p>\n<p>The unary operator <span style=\"font-family: Courier New;\">&#8216;!&#8217;<\/span> creates a not-predicate generator. Again, similar to its counterpart in <em>Qi<\/em>, it can be attached to any (arbitrarily complex) generator. The not-predicate generator will succeed if the associated generator fails, and it will fail if its generator succeeds. It invokes the generator it is attached to but the emitted output will not show up in the overall output stream. So effectively, the not-predicate generator will never emit any output. The following example will succeed emitting a floating point number if the first attribute is false (which will make the <span style=\"font-family: Courier New;\">true_<\/span> generator fail), otherwise it will not emit anything and will fail all together:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nnamespace karma = boost::spirit::karma;\r\nstd::string output;\r\nstd::back_insert_iterator&lt;std::string&gt; sink(output);\r\nkarma::generate(sink, !true_ &lt;&lt; double_, false, 1.0); \/\/ will emit: 1.0\r\n<\/pre>\n<p>This example highlights another difference if compared to <em>Qi&#8217;s<\/em> not-predicate. The <em>Karma<\/em> not-predicate will always consume an attribute. More accurately, it will expose the attribute of the generator it is associated with (while in <em>Qi<\/em> the not-predicate never exposes any attribute). As mentioned earlier, we utilize the <span style=\"font-family: Courier New;\">true_<\/span> generator&#8217;s ability to fail to control what output is generated (or if any output is generated at all as in our case).<\/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-943\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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\/26\/whats-the-difference-between-karmas-and\/?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\/26\/whats-the-difference-between-karmas-and\/?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>A couple of days ago I promised to get back to this topic (if you want to refresh your memory, here is the discussion of those operators in Qi). Today we will discuss Karma&#8217;s unary operators &#8216;!&#8217; and &#8216;~&#8217;. These have very similar semantics as their counterparts in Qi, but as usual, we have to [&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-943\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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-943\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/26\/whats-the-difference-between-karmas-and\/?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\/26\/whats-the-difference-between-karmas-and\/?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\/26\/whats-the-difference-between-karmas-and\/?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],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pIHdZ-fd","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/943"}],"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=943"}],"version-history":[{"count":2,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/943\/revisions"}],"predecessor-version":[{"id":945,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/943\/revisions\/945"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/categories?post=943"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/tags?post=943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}