{"id":876,"date":"2010-01-17T09:12:21","date_gmt":"2010-01-17T17:12:21","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?p=876"},"modified":"2010-01-18T07:14:18","modified_gmt":"2010-01-18T15:14:18","slug":"whats-the-difference-between-qis-and","status":"publish","type":"post","link":"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-and\/","title":{"rendered":"What&#8217;s the Difference Between Qi&#8217;s &#8216;!&#8217; and &#8216;~&#8217;?"},"content":{"rendered":"<p>The Freenet #boost IRC channel amazes me every day with the amount of interest <em>Spirit<\/em> is getting from a lot of people. Thanks to everyone over there! But the best is those people are asking many interesting questions allowing me to come up with yet another Tip of the Day.<\/p>\n<p>Today&#8217;s question has been asked by @psicode: &#8220;What is the difference between the components created by the unary operators <span style=\"font-family: Courier New;\">&#8216;!&#8217;<\/span> and <span style=\"font-family: Courier New;\">&#8216;~&#8217;<\/span>?&#8221;. As the semantics of those operators are slightly dissimilar in <em>Qi<\/em> and <em>Karma<\/em>, I will talk about them separately. I will write about the <em>Qi<\/em> operators today and about the corresponding <em>Karma<\/em> operators in one of the next installments.<\/p>\n<p><!--more--><\/p>\n<p>Let us start with the commonality between the two operators: both negate whether the component they are being used with succeeds parsing. 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 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>The differences are more interesting. The unary <em>Qi<\/em> operator &#8216;~&#8217; is applicable to character and character class parsers only. It negates the set of characters matched by the parser component 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><\/td>\n<td width=\"491\" valign=\"top\">does not match anything<\/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\">matches everything except digits<\/td>\n<\/tr>\n<tr>\n<td width=\"109\" valign=\"top\"><span style=\"font-family: Courier New;\">~char_(&#8220;a-z&#8221;)<\/span><\/td>\n<td width=\"491\" valign=\"top\">matches every character outside the character range spanned by &#8216;a&#8217; and &#8216;z&#8217;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0<\/p>\n<p>The parsers created by the operator <span style=\"font-family: Courier New;\">&#8216;~&#8217;<\/span> do not wrap the underlying parser. It rather modifies the behavior of the component it is attached to. This means there is no performance difference if compared to the plain character parsers.<\/p>\n<p>The unary operator <span style=\"font-family: Courier New;\">&#8216;!&#8217;<\/span> is creating a not-predicate parser. It can be attached to any (arbitrarily complex) parser expression. The not-predicate is a look-ahead matching parser trying to match the expression it is attached to. This is done without moving the current input position forward. In other words, the not-predicate does not consume any input . If the attached parser fails matching the overall not-predicate will succeed. In this case the parsing resumes at the same point where the not-predicate started matching. The following (slightly artificial) example will succeed matching a floating point number after making sure it is not a Boolean expression:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nnamespace qi = boost::spirit::qi;\r\nstd::string input(&quot;1.0&quot;);\r\nstd::string::const_iterator b = input.begin();\r\ndouble result = 0;\r\nqi::parse(b, input.end(), !qi::bool_ &gt;&gt; qi::double_, result);\r\n<\/pre>\n<p>Any parser created by the not-predicate is neutral in terms of attribute handling because it exposes <span style=\"font-family: Courier New;\">unused_type<\/span> as its attribute. As a consequence, parser components augmented with <span style=\"font-family: Courier New;\">&#8216;!&#8217;<\/span> will never expose their attribute, and never will participate in any attribute propagation.<\/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-876\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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\/17\/whats-the-difference-between-qis-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\/17\/whats-the-difference-between-qis-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>The Freenet #boost IRC channel amazes me every day with the amount of interest Spirit is getting from a lot of people. Thanks to everyone over there! But the best is those people are asking many interesting questions allowing me to come up with yet another Tip of the Day. Today&#8217;s question has been asked [&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-876\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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-876\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/2010\/01\/17\/whats-the-difference-between-qis-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\/17\/whats-the-difference-between-qis-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\/17\/whats-the-difference-between-qis-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":[8],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pIHdZ-e8","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/876"}],"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=876"}],"version-history":[{"count":5,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/876\/revisions"}],"predecessor-version":[{"id":895,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/posts\/876\/revisions\/895"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=876"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/categories?post=876"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/tags?post=876"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}