{"id":424,"date":"2009-11-06T12:30:21","date_gmt":"2009-11-06T20:30:21","guid":{"rendered":"http:\/\/boost-spirit.com\/home\/?page_id=424"},"modified":"2010-01-17T20:31:38","modified_gmt":"2010-01-18T04:31:38","slug":"spirit-v2-1-will-be-released-with-boost-v1-41","status":"publish","type":"page","link":"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/","title":{"rendered":"Spirit V2.1 will be released with Boost V1.41"},"content":{"rendered":"<p>Now, as the release of the new <em>Spirit<\/em> version is at our doorstep, I would like to whet your appetite. Let\u2019s start with a list of high level things worth knowing. Here is the one floor elevator speech I stole from <a href=\"http:\/\/boost-spirit.com\/home\/spirit2\/libs\/spirit\/doc\/html\/index.html\" target=\"_blank\">Spirit\u2019s documentation<\/a>:<\/p>\n<blockquote><p><strong>Spirit<\/strong> is an object-oriented, recursive-descent parser and output generation library for C++. It allows you to write grammars and format descriptions using a domain specific embedded language (DSEL) directly in C++. The DSEL has a format similar to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Parsing_expression_grammar\">Parsing Expression Grammars<\/a> (PEG). These inline grammar specifications can mix freely with other C++ code and, thanks to the generative power of C++ templates, they are immediately executable.<\/p><\/blockquote>\n<p>Let\u2019s try to digest this piecewise. I think I do not need to dig into <em>Spirit<\/em> being \u2018object-oriented\u2019, that stands for itself. &#8216;Recursive descent&#8217; is a way to write parsers. <a href=\"http:\/\/en.wikipedia.org\/wiki\/Recursive_descent\">Wikipedia<\/a> says:<\/p>\n<blockquote><p>A <strong>recursive descent parser<\/strong> is a top-down parser built from a set of mutually-recursive procedures (or a non-recursive equivalent) where each such procedure usually implements one of the production rules of the grammar. Thus the structure of the resulting program closely mirrors that of the grammar it recognizes.<\/p><\/blockquote>\n<p><em>Spirit<\/em> is special as it applies the technology of using mutually recursive procedures not only for implementing parsers, but it uses the same approach for creating output generators. We are quite proud of this as we do not know of anybody doing this before. Compared to earlier <em>Spirit<\/em> versions this extends the scope of the library considerably, as we now support two very important steps in any data transformation flow: <em>Spirit.Qi<\/em> (the sub-library responsible for parsing) helps converting arbitrary formatted (text) input into some internal structured data format, while <em>Spirit.Karma<\/em> (the sub-library for output generation) simplifies the opposite: converting the internal binary data structures into arbitrary formatted (text) output. This picture shows what I mean:<\/p>\n<p><img loading=\"lazy\" title=\"The place of Spirit.Qi and Spirit.Karma in a data transformation flow of a typical application\" src=\"http:\/\/boost-spirit.com\/home\/spirit2\/libs\/spirit\/doc\/html\/images\/spiritkarmaflow.png\" alt=\"The place of Spirit.Qi and Spirit.Karma in a data transformation flow of a typical application\" width=\"576\" height=\"218\" \/><br \/>\nThe place of Spirit.Qi and Spirit.Karma in a data transformation flow of a typical application<\/p>\n<p>Grammars for <em>Spirit.Qi<\/em> and <em>Spirit.Karma<\/em> are written directly in C++. We use extensive operator overloading to make the grammar syntax very similar to PEG, a well known way to unambiguously describe formal grammars. Let\u2019s have a look at a simple example. The following PEG grammar describes a trivial infix calculator supporting &#8216;*&#8217;, &#8216;\/&#8217;, &#8216;+&#8217;, &#8216;\u2013&#8217;, and allowing to group sub-expressions with parentheses:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nfact \u2190 integer \/ '(' expr ')'\r\nterm \u2190 fact (('*' fact) \/ ('\/' fact))*\r\nexpr \u2190 term (('+' term) \/ ('-' term))*\r\n<\/pre>\n<p>Here is the same grammar, but written in <em>Spirit.Qi<\/em>, and yes, that\u2019s perfectly valid C++.<em> <\/em>This code defines a parser which recognizes infix calculator expressions:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nnamespace qi = boost::spirit::qi;\r\ntypedef qi::rule&lt;std::string::iterator&gt; rule;\r\nrule fact, term, expr;\r\n\r\nfact = qi::int_ | '(' &gt;&gt; expr &gt;&gt; ')' ;\r\nterm = fact &gt;&gt; *(('*' &gt;&gt; fact) | ('\/' &gt;&gt; fact)) ;\r\nexpr = term &gt;&gt; *(('+' &gt;&gt; term) | ('-' &gt;&gt; term)) ;\r\n<\/pre>\n<p>The last three lines look almost similar to the original PEG grammar above, except for the &#8216;&gt;&gt;&#8217; used to denote concatenation. Grammars written for output formatting in <em>Spirit.Karma<\/em> look very similar, the most notable difference is probably that they use the left shift operator &#8216;&lt;&lt;&#8216; instead of S<em>pirit.Qi<\/em>\u2019s right shift operator &#8216;&gt;&gt;&#8217; for concatenation. Any C++ programmer will find that non-surprising as it follows the convention of using &#8216;&lt;&lt;&#8216; and &#8216;&gt;&gt;&#8217; for normal input and output code.<\/p>\n<p>The last fact in our one floor elevator speech from above is obvious now. <em>Spirit<\/em> is pure C++, uses only language constructs as provided by C++, and for this reason, integrates smoothly with any surrounding code. All data items in your program are easily accessible as the destination for parsing results or as the source for generating output. No additional (external) tools as normally required for conventional parser generators have to be utilized.<\/p>\n<p>Interested in trying out <em>Spirit<\/em>? I suggest you start reading the documentation (<a href=\"http:\/\/boost-spirit.com\/home\/spirit2\/libs\/spirit\/doc\/html\/index.html\" target=\"_blank\">here<\/a>) or browse through the extensive examples coming with the library as soon as Boost V1.41 has been released (or grab the beta <a href=\"http:\/\/sourceforge.net\/projects\/boost\/files\/\" target=\"_blank\">here<\/a>). In the meantime, if you have any questions, leave a comment or use <em>Spirit&#8217;s<\/em> <a href=\"http:\/\/news.gmane.org\/thread.php?group=gmane.comp.parsers.spirit.general\" target=\"_blank\">mailing list<\/a>.<\/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-424\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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>Now, as the release of the new Spirit version is at our doorstep, I would like to whet your appetite. Let\u2019s start with a list of high level things worth knowing. Here is the one floor elevator speech I stole from Spirit\u2019s documentation: Spirit is an object-oriented, recursive-descent parser and output generation library for C++. [&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-424\" class=\"share-facebook sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-twitter sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-pinterest sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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-424\" class=\"share-linkedin sd-button share-icon\" href=\"http:\/\/boost-spirit.com\/home\/articles\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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\/spirit2-1-release\/spirit-v2-1-will-be-released-with-boost-v1-41\/?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,"parent":377,"menu_order":1,"comment_status":"open","ping_status":"open","template":"article-page.php","meta":{"_s2mail":"","spay_email":""},"jetpack_shortlink":"https:\/\/wp.me\/PIHdZ-6Q","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/424"}],"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\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/comments?post=424"}],"version-history":[{"count":8,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/424\/revisions"}],"predecessor-version":[{"id":889,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/424\/revisions\/889"}],"up":[{"embeddable":true,"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/pages\/377"}],"wp:attachment":[{"href":"http:\/\/boost-spirit.com\/home\/wp-json\/wp\/v2\/media?parent=424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}