{"id":793,"date":"2009-12-21T22:53:42","date_gmt":"2009-12-22T06:53:42","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?page_id=793"},"modified":"2011-05-13T07:59:00","modified_gmt":"2011-05-13T14:59:00","slug":"faq","status":"publish","type":"page","link":"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/","title":{"rendered":"FAQ"},"content":{"rendered":"<p>This page will contain FAQ entries which will eventually be incorporated into the FAQ section of the documentation.<\/p>\n<ul>\n<li><a href=\"#aliases\">Aliases<\/a><\/li>\n<li><a href=\"#memory\">Large Memory Consumption Compiling Spirit Parser on g++<\/a><\/li>\n<li><a href=\"#identifiers\">Correctly Parsing Identifiers<\/a><\/li>\n<li><a href=\"#attributes\">Rule and Grammar Attributes<\/a><\/li>\n<li><a href=\"#mismatches\">Semantic Action for Mismatches<\/a><\/li>\n<li><a href=\"#default\">Parse Or Supply a Default<\/a><\/li>\n<li><a href=\"#alternatives-attributes\">Alternatives and Attributes<\/a><\/li>\n<li><a href=\"#skipper-less-rules\">Skipper-less Rules in Phrase Parsing<\/a><\/li>\n<\/ul>\n<hr \/>\n<h3><a id=\"aliases\" name=\"aliases\"><\/a><a href=\"#aliases\">Aliases<\/a><\/h3>\n<p><strong>Question:<\/strong> I am trying to assign a rule, y, to another rule, x:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nx = y;\r\n<\/pre>\n<p>This fails at runtime with a Boost Assertion saying that I&#8217;m trying to initialize a rule from an uninitialized one. What is happening?<\/p>\n<p><strong>Answer:<\/strong> Spirit 2 rules conform to &#8216;proper&#8217; C++ copy\/assign semantics. This gives you the freedom to copy\/store\/assign your rules as you do any C++ object (pass them as arguments, return them from functions, store them in STL containers, etc). This is a major difference between <em>Classic Spirit<\/em> and <em>Spirit 2<\/em>.<\/p>\n<p>You are trying to assign a rule (in the c++ sense instead of the BNF sense) to a different instance of the same type. There is no way to directly deduce your intention of referring to the right hand side rule instead of making a (C++) copy. So in this situation you need to write:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nx = y.alias();\r\n<\/pre>\n<p>to make the lhs a &#8216;logical&#8217; copy of the rhs (and not a copy in the pure C++ sense).<\/p>\n<p><strong>Question:<\/strong> Hmm&#8230; then how about<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nx = eps &gt;&gt; y;\r\n<\/pre>\n<p>should there be alias too?<\/p>\n<p><strong>Answer: <\/strong>No. Only when there is a single rule in the RHS.<\/p>\n<hr \/>\n<h3><a id=\"memory\" name=\"memory\"><\/a><a href=\"#memory\">Large Memory Consumption Compiling Spirit Parser on g++<\/a><\/h3>\n<p><strong>Question: <\/strong>I wrote a spirit parser to read in a file which acts as a parameter file for a finite-element simulation code. The file itself has approx. 200 to 300 lines but the grammar for this is quite large, because you have very few repetitions in the job-file.<\/p>\n<p>During the implementation I discoverd that the compilation process needs more and more memory (and time) with increasing grammar. Right now I need 8GB at peak, to compile the parser!<\/p>\n<p>Is there a way to reduce the ram needed for computation? The machines where I have access easily have up to 8GB RAM only.<\/p>\n<p><strong>Answer: <\/strong>With gcc, the debugging information uses up a lot of ram. Try compiling with the &#8216;-g0&#8217; flag.<\/p>\n<hr \/>\n<h3><a id=\"identifiers\" name=\"identifiers\"><\/a><a href=\"#identifiers\">Correctly Parsing Identifiers<\/a><\/h3>\n<p><strong>Question:<\/strong> I store identifiers in a symbol table. My problem is that prefixes are being incorrectly matched. I don&#8217;t want that. For example, if I have an identifier named &#8220;bat&#8221; in the symbol table, &#8220;battery&#8221; is being incorrectly parsed as &#8220;bat&#8221; followed by a trailing &#8220;tery&#8221;. Is there a way to allow whole identifiers only?<\/p>\n<p><strong>Answer: <\/strong>Sure. The not-predicate is your friend. Check out calc6 code, for example:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvariable =\r\n  (\r\n    lexeme[\r\n      vars\r\n      &gt;&gt; !(alnum | '_') \/\/ make sure we have whole words\r\n    ]\r\n  )\r\n<\/pre>\n<p>ensures that a variable does not follow an alnum or underscore.<\/p>\n<hr \/>\n<h3><a id=\"attributes\" name=\"attributes\"><\/a><a href=\"#attributes\">Rule and Grammar Attributes<\/a><\/h3>\n<p><strong>Question:<\/strong> Why do I have to specify the attribute for rules and grammars using the strange function declaration style:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::rule&lt;Iterator, std::string(), skipper&gt; r;\r\n<\/pre>\n<p><strong>Answer:<\/strong> This syntax is equivalent to:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ntypedef std::string f_type();\r\nrule&lt;Iterator, f_type, skipper&gt; r;\r\n<\/pre>\n<p>The C++ specs call it a &#8216;type-id&#8217; &#8220;which is a declaration for an object or function of that type that omits the name of the object or function&#8221;.\u00a0We usually\u00a0call it<em> function declaration syntax<\/em> (even if it probably should be called <em>function type-id syntax<\/em>). It is used not only in Spirit but by several other libraries as well (see boost::function for instance).<\/p>\n<p>The main reason for this is not because we wanted it that way, but because it is a nice and concise way of specifying a function interface. If you think about what a rule is, you quickly realize that it is like a function: it may return a value (the parsed result, i.e. synthesized attribute). Additionally, it may take one or more arguments (the inherited attributes).<\/p>\n<p>A second, but minor reason is that we need to be able to distinguish the different template parameters of a rule. The template parameters can be specified in any order (except for the iterator), so we need some means of figuring out what&#8217;s what. The function declaration syntax is sufficiently different from the skipper or the encoding to allow it to be recognized at compile time.<\/p>\n<hr \/>\n<h3><a id=\"mismatches\" name=\"mismatches\"><\/a><a href=\"#mismatches\">Semantic Action for Mismatches<\/a><\/h3>\n<p><strong>Question:<\/strong> If a rule matches, and thus executes its semantic actions, but a rule which includes that rule mismatches, there seems to be no way to &#8220;unwind&#8221; the code executed down the chain. For example, if one of your semantic actions allocates memory or increments a reference count, how do you free\/release that reference in the mismatch scenario?<\/p>\n<p><strong>Answer:<\/strong> Sure:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nr = p | eps[cleanup];\r\n<\/pre>\n<p>If p fails with side-effects from its direct or indirect semantic actions, the cleanup semantic action can roll them back.<\/p>\n<hr \/>\n<h3><a id=\"default\" name=\"default\"><\/a><a href=\"#default\">Parse Or Supply a Default<\/a><\/h3>\n<p><strong>Question: <\/strong>There are times when you want to parse, say, a number or provide a default if it isn&#8217;t in the input. How can you do that? (Thanks to Robert Stewart and Michael Caisse for this entry)<\/p>\n<p><strong>Answer: <\/strong>The parser for that value is optional, so the usual mechanism is something like this:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n-(uint_ &gt;&gt; 's')\r\n<\/pre>\n<p>(The &#8216;s&#8217; parser is present just to illustrate that there can be more expected to follow the optional part of interest.)<\/p>\n<p>The problem is how to provide a default value should there be no number (and whatever follows it). A naive approach is the following:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nrule&lt;Iterator, unsigned()&gt; s;\r\ns = (uint_ &gt;&gt; 's') | eps[_val = 0];\r\n<\/pre>\n<p>Because there&#8217;s a semantic action in that rule, attribute compatibility rules are disabled. Thus, %= is needed rather than =. Secondly, the assignment must be lazy, so <code>boost::phoenix::val()<\/code> must be used:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ns %= (uint_ &gt;&gt; 's') | eps[_val = val(0)];\r\n<\/pre>\n<p>This can be done more easily using <code>boost::spirit::qi::attr()<\/code>, however, which obviates the semantic action and thereby eliminates the need for %=. This leaves us with the following simple solution:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ns = (uint_ &gt;&gt; 's') | attr(0);\r\n<\/pre>\n<hr \/>\n<h3><a id=\"alternatives-attributes\" name=\"alternatives-attributes\"><\/a><a href=\"#alternatives-attributes\">Alternatives and Attributes<\/a><\/h3>\n<p><strong>Question<\/strong>: I have this rule:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nr = a | b;\r\n<\/pre>\n<p>where both <em>a<\/em> and <em>b<\/em> and the <em>r<\/em> have an attribute which is a container (e.g. std::vector). When <em>a<\/em> fails and Qi backtracks and tries <em>b<\/em>, it doesn&#8217;t clear the vector before trying the second alternative and the final attribute ends up doubled. That seems like a bug to me.<\/p>\n<p><strong>Answer<\/strong>: If<em> a<\/em> fails, then it backtracks and tries<em> b<\/em>. The side-effect being that the work done by<em> a<\/em> is not rolled back. Why is the action not undone? Well, for the sake of efficiency. We&#8217;ve found that it is very expensive to roll back the attribute to its original state on a failed match. Doing so would involve lots of copying and swapping. Consider this pseudo code:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nAttr save = attr;\r\nif (parse(f, l, attr)) \/\/ if successful\r\n{\r\n    return true;\r\n}\r\nelse\r\n{\r\n    swap(attr, save);\r\n    return false;\r\n}\r\n<\/pre>\n<p>Take note that you always pay for that extra copy every time!<\/p>\n<p>To be very honest with you, we are actually violating a post condition required by parsers where: On a failed match, the attribute is left untouched. You can still <a href=\"http:\/\/www.boost.org\/doc\/libs\/1_46_0\/libs\/spirit\/doc\/html\/spirit\/qi\/reference\/parser_concepts\/parser.html\">see this in the docs until 2.4.2<\/a>. Now, to avoid further confusion, this post condition has been changed to:<\/p>\n<blockquote><p><strong>On a failed match, the attribute state is undefined.<\/strong><\/p><\/blockquote>\n<p>And with that, it will be clear that when <em>a<\/em> fails, we make no guarantee that the attribute will be in a consistent state. Actually, if you think about it, it is the same as:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nr = a[f] | b[f];\r\n<\/pre>\n<p>where when <em>a<\/em> fails, it does not roll back what it has already done by <em>f<\/em>. So, there&#8217;s really consistency with how semantic actions work.<\/p>\n<p>How do you deal with cases like this? The <em>hold <\/em>directive is your friend: see<a href=\"http:\/\/www.boost.org\/doc\/libs\/1_46_0\/libs\/spirit\/doc\/html\/spirit\/qi\/reference\/directive\/hold.html\"> Parser Directive for Attribute Commit\/Rollback<\/a>. For example:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nr = hold[a] | b;\r\n<\/pre>\n<p><em>hold <\/em>does the saving and swapping for you.<\/p>\n<hr \/>\n<h3><a id=\"skipper-less-rules\" name=\"skipper-less-rules\"><\/a><a href=\"#skipper-less-rules\">Skipper-less Rules in Phrase Parsing<\/a><\/h3>\n<p><strong>Question<\/strong>: I have this start rule:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::rule&lt;iterator_type, qi::space_type&gt; start;\r\nstart = (int_ % ',');\r\n<\/pre>\n<p>This parser works great using qi::phrase_parse. However, parsing fails when I refactor the RHS into another rule and use an alias of that in my start rule:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::rule&lt;iterator_type&gt; vec;\r\nvec = (int_ % ',');\r\nstart = vec.alias();\r\n<\/pre>\n<p>What am I doing wrong?<\/p>\n<p><strong>Answer<\/strong>: A rule needs to know what skipper to use. Calling a rule inside phrase_parse which has no skipper is equivalent to an implicit lexeme[] around its right hand side. You don&#8217;t want that. You need to declare your vec rule with a skipper, just as you did with your start rule:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nqi::rule&lt;iterator_type, qi::space_type&gt; vec;\r\n<\/pre>\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-793\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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\/articles\/doc-addendum\/faq\/?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\/articles\/doc-addendum\/faq\/?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>This page will contain FAQ entries which will eventually be incorporated into the FAQ section of the documentation. Aliases Large Memory Consumption Compiling Spirit Parser on g++ Correctly Parsing Identifiers Rule and Grammar Attributes Semantic Action for Mismatches Parse Or Supply a Default Alternatives and Attributes Skipper-less Rules in Phrase Parsing Aliases Question: I am [&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-793\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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-793\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/doc-addendum\/faq\/?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\/articles\/doc-addendum\/faq\/?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\/articles\/doc-addendum\/faq\/?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":2,"featured_media":0,"parent":538,"menu_order":4,"comment_status":"open","ping_status":"open","template":"","meta":{"_s2mail":"yes","spay_email":""},"jetpack_shortlink":"https:\/\/wp.me\/PIHdZ-cN","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/793"}],"collection":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/comments?post=793"}],"version-history":[{"count":57,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/793\/revisions"}],"predecessor-version":[{"id":796,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/793\/revisions\/796"}],"up":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/538"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}