diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/spirit/repository | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'libs/spirit/repository')
103 files changed, 10474 insertions, 0 deletions
diff --git a/libs/spirit/repository/doc/Jamfile b/libs/spirit/repository/doc/Jamfile new file mode 100644 index 0000000000..d4ed5501aa --- /dev/null +++ b/libs/spirit/repository/doc/Jamfile @@ -0,0 +1,33 @@ +#============================================================================== +# Copyright (c) 2001-2011 Joel de Guzman +# Copyright (c) 2001-2011 Hartmut Kaiser +# +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +project spirit/repository/doc ; + +import boostbook ; +import quickbook ; + +path-constant images_location : html ; + +boostbook spirit2_repository + : + spirit2_repository.qbk + : + <xsl:param>boost.root=../../../../.. + <xsl:param>chunk.section.depth=4 + <xsl:param>chunk.first.sections=1 + <xsl:param>toc.section.depth=3 + <xsl:param>toc.max.depth=3 + <xsl:param>generate.section.toc.level=4 + <format>html:<xsl:param>admon.graphics.path=images/ + + <include>. + <format>pdf:<xsl:param>img.src.path=$(images_location)/ + <format>pdf:<xsl:param>draft.mode="no" + <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/spirit/repository/doc/html + ; diff --git a/libs/spirit/repository/doc/acknowledgements.qbk b/libs/spirit/repository/doc/acknowledgements.qbk new file mode 100644 index 0000000000..42fbe9fc2a --- /dev/null +++ b/libs/spirit/repository/doc/acknowledgements.qbk @@ -0,0 +1,34 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section Acknowledgments] + +The __spirit__ repository is the result of the contributions of active members +of the Spirit community. We would like to express our thanks to all who +directly contributed and to everybody directly or indirectly involved in the +discussions, which led to the creation of the parser and generator components. + +The following people have directly contributed code to this repository: + +[*Aaron Graham] wrote the __qi_advance__ parser component, which allows the +parser to skip (advance) through a specified number of iterations without +performing unnecessary work. + +[*Chris Hoeppler] submitted the __qi_confix__ parser directive allowing to +embed a parser (the subject) inside an opening (the prefix) and a closing +sequence (the suffix). + +[*Francois Barel] contributed the __qi_subrule__ parser and __karma_subrule__ +generator components, allowing to create a named parser or generator, and +to refer to it by name. These components are in fact fully static versions of +the corresponding `rule` component. + +[*Thomas Bernard] contributed the __qi_keywords__ and __qi_keywords_list__ +parser components, allowing to define keyword parsers. + +[endsect] diff --git a/libs/spirit/repository/doc/html/images/alert.png b/libs/spirit/repository/doc/html/images/alert.png Binary files differnew file mode 100644 index 0000000000..101b5f780b --- /dev/null +++ b/libs/spirit/repository/doc/html/images/alert.png diff --git a/libs/spirit/repository/doc/html/images/callouts/1.png b/libs/spirit/repository/doc/html/images/callouts/1.png Binary files differnew file mode 100644 index 0000000000..6003ad3af4 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/1.png diff --git a/libs/spirit/repository/doc/html/images/callouts/10.png b/libs/spirit/repository/doc/html/images/callouts/10.png Binary files differnew file mode 100644 index 0000000000..0426f516a4 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/10.png diff --git a/libs/spirit/repository/doc/html/images/callouts/11.png b/libs/spirit/repository/doc/html/images/callouts/11.png Binary files differnew file mode 100644 index 0000000000..821afc4fa8 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/11.png diff --git a/libs/spirit/repository/doc/html/images/callouts/12.png b/libs/spirit/repository/doc/html/images/callouts/12.png Binary files differnew file mode 100644 index 0000000000..7cec72720f --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/12.png diff --git a/libs/spirit/repository/doc/html/images/callouts/13.png b/libs/spirit/repository/doc/html/images/callouts/13.png Binary files differnew file mode 100644 index 0000000000..5b41e02a67 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/13.png diff --git a/libs/spirit/repository/doc/html/images/callouts/14.png b/libs/spirit/repository/doc/html/images/callouts/14.png Binary files differnew file mode 100644 index 0000000000..de5bdbd3eb --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/14.png diff --git a/libs/spirit/repository/doc/html/images/callouts/15.png b/libs/spirit/repository/doc/html/images/callouts/15.png Binary files differnew file mode 100644 index 0000000000..3fd6ac3860 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/15.png diff --git a/libs/spirit/repository/doc/html/images/callouts/2.png b/libs/spirit/repository/doc/html/images/callouts/2.png Binary files differnew file mode 100644 index 0000000000..f7c1578846 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/2.png diff --git a/libs/spirit/repository/doc/html/images/callouts/3.png b/libs/spirit/repository/doc/html/images/callouts/3.png Binary files differnew file mode 100644 index 0000000000..3ff0a93931 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/3.png diff --git a/libs/spirit/repository/doc/html/images/callouts/4.png b/libs/spirit/repository/doc/html/images/callouts/4.png Binary files differnew file mode 100644 index 0000000000..6aa29fc0b4 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/4.png diff --git a/libs/spirit/repository/doc/html/images/callouts/5.png b/libs/spirit/repository/doc/html/images/callouts/5.png Binary files differnew file mode 100644 index 0000000000..36e785867a --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/5.png diff --git a/libs/spirit/repository/doc/html/images/callouts/6.png b/libs/spirit/repository/doc/html/images/callouts/6.png Binary files differnew file mode 100644 index 0000000000..c943676bea --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/6.png diff --git a/libs/spirit/repository/doc/html/images/callouts/7.png b/libs/spirit/repository/doc/html/images/callouts/7.png Binary files differnew file mode 100644 index 0000000000..20940de30d --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/7.png diff --git a/libs/spirit/repository/doc/html/images/callouts/8.png b/libs/spirit/repository/doc/html/images/callouts/8.png Binary files differnew file mode 100644 index 0000000000..d8e34d4a09 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/8.png diff --git a/libs/spirit/repository/doc/html/images/callouts/9.png b/libs/spirit/repository/doc/html/images/callouts/9.png Binary files differnew file mode 100644 index 0000000000..abe636072b --- /dev/null +++ b/libs/spirit/repository/doc/html/images/callouts/9.png diff --git a/libs/spirit/repository/doc/html/images/caution.png b/libs/spirit/repository/doc/html/images/caution.png Binary files differnew file mode 100644 index 0000000000..4be6d07237 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/caution.png diff --git a/libs/spirit/repository/doc/html/images/important.png b/libs/spirit/repository/doc/html/images/important.png Binary files differnew file mode 100644 index 0000000000..994325ed7d --- /dev/null +++ b/libs/spirit/repository/doc/html/images/important.png diff --git a/libs/spirit/repository/doc/html/images/note.png b/libs/spirit/repository/doc/html/images/note.png Binary files differnew file mode 100644 index 0000000000..c425ecb301 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/note.png diff --git a/libs/spirit/repository/doc/html/images/tip.png b/libs/spirit/repository/doc/html/images/tip.png Binary files differnew file mode 100644 index 0000000000..f5e54323b2 --- /dev/null +++ b/libs/spirit/repository/doc/html/images/tip.png diff --git a/libs/spirit/repository/doc/html/index.html b/libs/spirit/repository/doc/html/index.html new file mode 100644 index 0000000000..0ebcd7f447 --- /dev/null +++ b/libs/spirit/repository/doc/html/index.html @@ -0,0 +1,103 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Spirit Repository 0.2</title> +<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="index.html" title="Spirit Repository 0.2"> +<link rel="next" href="spirit_repository/preface.html" title="Preface"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> +<td align="center"><a href="../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"><a accesskey="n" href="spirit_repository/preface.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div> +<div class="article"> +<div class="titlepage"> +<div> +<div><h2 class="title"> +<a name="spirit_repository"></a>Spirit Repository 0.2</h2></div> +<div><div class="authorgroup"> +<div class="author"><h3 class="author"> +<span class="firstname">Joel</span> <span class="surname">de Guzman</span> +</h3></div> +<div class="author"><h3 class="author"> +<span class="firstname">Hartmut</span> <span class="surname">Kaiser</span> +</h3></div> +</div></div> +<div><p class="copyright">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser</p></div> +<div><div class="legalnotice"> +<a name="spirit_repository.legal"></a><p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></div> +</div> +<hr> +</div> +<div class="toc"> +<p><b>Table of Contents</b></p> +<dl> +<dt><span class="section"><a href="spirit_repository/preface.html">Preface</a></span></dt> +<dt><span class="section"><a href="spirit_repository/what_s_new.html">What's New</a></span></dt> +<dd><dl><dt><span class="section"><a href="spirit_repository/what_s_new/spirit_2_5_1.html">Spirit V2.5.1</a></span></dt></dl></dd> +<dt><span class="section"><a href="spirit_repository/qi_components.html">Qi Components</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="spirit_repository/qi_components/primitive.html">Qi Parser + Primitives</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="spirit_repository/qi_components/primitive/advance.html">Qi + advance Parser</a></span></dt> +<dt><span class="section"><a href="spirit_repository/qi_components/primitive/flush_multi_pass.html">Qi + flush_multi_pass parser</a></span></dt> +</dl></dd> +<dt><span class="section"><a href="spirit_repository/qi_components/directives.html">Qi Parser + Directives</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="spirit_repository/qi_components/directives/confix.html">Qi + Confix Parser Directive</a></span></dt> +<dt><span class="section"><a href="spirit_repository/qi_components/directives/distinct.html">Qi + Distinct Parser Directive</a></span></dt> +<dt><span class="section"><a href="spirit_repository/qi_components/directives/kwd.html">Qi + Keyword Parser Directive </a></span></dt> +<dt><span class="section"><a href="spirit_repository/qi_components/directives/seek.html">Qi + Seek Parser Directive </a></span></dt> +</dl></dd> +<dt><span class="section"><a href="spirit_repository/qi_components/nonterminal.html">Qi Parser + Non-terminals</a></span></dt> +<dd><dl><dt><span class="section"><a href="spirit_repository/qi_components/nonterminal/subrule.html">Qi + subrules</a></span></dt></dl></dd> +<dt><span class="section"><a href="spirit_repository/qi_components/operators.html">Qi Parser + Operators</a></span></dt> +<dd><dl><dt><span class="section"><a href="spirit_repository/qi_components/operators/keyword_list.html">Keyword + List Operator</a></span></dt></dl></dd> +</dl></dd> +<dt><span class="section"><a href="spirit_repository/karma_components.html">Karma Components</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="spirit_repository/karma_components/directives.html">Karma + Generator Directives</a></span></dt> +<dd><dl><dt><span class="section"><a href="spirit_repository/karma_components/directives/karma_confix_generator.html">Karma + Confix Generator</a></span></dt></dl></dd> +<dt><span class="section"><a href="spirit_repository/karma_components/nonterminal.html">Karma + Generator Non-terminals</a></span></dt> +<dd><dl><dt><span class="section"><a href="spirit_repository/karma_components/nonterminal/subrule.html">Karma + subrules</a></span></dt></dl></dd> +</dl></dd> +<dt><span class="section"><a href="spirit_repository/acknowledgments.html">Acknowledgments</a></span></dt> +</dl> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"><p><small>Last revised: February 20, 2012 at 20:34:34 GMT</small></p></td> +<td align="right"><div class="copyright-footer"></div></td> +</tr></table> +<hr> +<div class="spirit-nav"><a accesskey="n" href="spirit_repository/preface.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit2_repository_HTML.manifest b/libs/spirit/repository/doc/html/spirit2_repository_HTML.manifest new file mode 100755 index 0000000000..d40d303761 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit2_repository_HTML.manifest @@ -0,0 +1,23 @@ +index.html +spirit_repository/preface.html +spirit_repository/what_s_new.html +spirit_repository/what_s_new/spirit_2_5_1.html +spirit_repository/qi_components.html +spirit_repository/qi_components/primitive.html +spirit_repository/qi_components/primitive/advance.html +spirit_repository/qi_components/primitive/flush_multi_pass.html +spirit_repository/qi_components/directives.html +spirit_repository/qi_components/directives/confix.html +spirit_repository/qi_components/directives/distinct.html +spirit_repository/qi_components/directives/kwd.html +spirit_repository/qi_components/directives/seek.html +spirit_repository/qi_components/nonterminal.html +spirit_repository/qi_components/nonterminal/subrule.html +spirit_repository/qi_components/operators.html +spirit_repository/qi_components/operators/keyword_list.html +spirit_repository/karma_components.html +spirit_repository/karma_components/directives.html +spirit_repository/karma_components/directives/karma_confix_generator.html +spirit_repository/karma_components/nonterminal.html +spirit_repository/karma_components/nonterminal/subrule.html +spirit_repository/acknowledgments.html diff --git a/libs/spirit/repository/doc/html/spirit_repository/acknowledgments.html b/libs/spirit/repository/doc/html/spirit_repository/acknowledgments.html new file mode 100755 index 0000000000..7ad03b36bc --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/acknowledgments.html @@ -0,0 +1,73 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Acknowledgments</title> +<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../index.html" title="Spirit Repository 0.2"> +<link rel="prev" href="karma_components/nonterminal/subrule.html" title="Karma subrules"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="karma_components/nonterminal/subrule.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="spirit_repository.acknowledgments"></a><a class="link" href="acknowledgments.html" title="Acknowledgments">Acknowledgments</a> +</h2></div></div></div> +<p> + The <a href="http://boost-spirit.com" target="_top">Spirit</a> repository is the result + of the contributions of active members of the Spirit community. We would like + to express our thanks to all who directly contributed and to everybody directly + or indirectly involved in the discussions, which led to the creation of the + parser and generator components. + </p> +<p> + The following people have directly contributed code to this repository: + </p> +<p> + <span class="bold"><strong>Aaron Graham</strong></span> wrote the <a class="link" href="qi_components/primitive/advance.html" title="Qi advance Parser"><code class="computeroutput"><span class="identifier">advance</span></code></a> parser component, which allows + the parser to skip (advance) through a specified number of iterations without + performing unnecessary work. + </p> +<p> + <span class="bold"><strong>Chris Hoeppler</strong></span> submitted the <a class="link" href="qi_components/directives/confix.html" title="Qi Confix Parser Directive"><code class="computeroutput"><span class="identifier">confix</span></code></a> parser directive allowing to + embed a parser (the subject) inside an opening (the prefix) and a closing sequence + (the suffix). + </p> +<p> + <span class="bold"><strong>Francois Barel</strong></span> contributed the <a class="link" href="qi_components/nonterminal/subrule.html" title="Qi subrules"><code class="computeroutput"><span class="identifier">subrule</span></code></a> parser and <a class="link" href="karma_components/nonterminal/subrule.html" title="Karma subrules"><code class="computeroutput"><span class="identifier">subrule</span></code></a> generator components, allowing + to create a named parser or generator, and to refer to it by name. These components + are in fact fully static versions of the corresponding <code class="computeroutput"><span class="identifier">rule</span></code> + component. + </p> +<p> + <span class="bold"><strong>Thomas Bernard</strong></span> contributed the <a class="link" href="qi_components/operators/keyword_list.html" title="Keyword List Operator">keyword_list</a> + and <a class="link" href="qi_components/directives/kwd.html" title="Qi Keyword Parser Directive"><code class="computeroutput"><span class="identifier">kwd</span><span class="special">()[]</span></code></a> + parser components, allowing to define keyword parsers. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="karma_components/nonterminal/subrule.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/karma_components.html b/libs/spirit/repository/doc/html/spirit_repository/karma_components.html new file mode 100755 index 0000000000..5b1a65c7d6 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/karma_components.html @@ -0,0 +1,53 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Karma Components</title> +<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../index.html" title="Spirit Repository 0.2"> +<link rel="prev" href="qi_components/operators/keyword_list.html" title="Keyword List Operator"> +<link rel="next" href="karma_components/directives.html" title="Karma Generator Directives"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="qi_components/operators/keyword_list.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="karma_components/directives.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="spirit_repository.karma_components"></a><a class="link" href="karma_components.html" title="Karma Components">Karma Components</a> +</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="karma_components/directives.html">Karma + Generator Directives</a></span></dt> +<dd><dl><dt><span class="section"><a href="karma_components/directives/karma_confix_generator.html">Karma + Confix Generator</a></span></dt></dl></dd> +<dt><span class="section"><a href="karma_components/nonterminal.html">Karma + Generator Non-terminals</a></span></dt> +<dd><dl><dt><span class="section"><a href="karma_components/nonterminal/subrule.html">Karma + subrules</a></span></dt></dl></dd> +</dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="qi_components/operators/keyword_list.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="karma_components/directives.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives.html b/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives.html new file mode 100755 index 0000000000..13d5e5f879 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives.html @@ -0,0 +1,46 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Karma Generator Directives</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../karma_components.html" title="Karma Components"> +<link rel="prev" href="../karma_components.html" title="Karma Components"> +<link rel="next" href="directives/karma_confix_generator.html" title="Karma Confix Generator"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../karma_components.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.karma_components.directives"></a><a class="link" href="directives.html" title="Karma Generator Directives">Karma + Generator Directives</a> +</h3></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="directives/karma_confix_generator.html">Karma + Confix Generator</a></span></dt></dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../karma_components.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html b/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html new file mode 100755 index 0000000000..82c20de684 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html @@ -0,0 +1,326 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Karma Confix Generator</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../directives.html" title="Karma Generator Directives"> +<link rel="prev" href="../directives.html" title="Karma Generator Directives"> +<link rel="next" href="../nonterminal.html" title="Karma Generator Non-terminals"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.karma_components.directives.karma_confix_generator"></a><a class="link" href="karma_confix_generator.html" title="Karma Confix Generator">Karma + Confix Generator</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h0"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.description"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Karma</em></span> <code class="computeroutput"><span class="identifier">confix</span></code> + generator is a generator directive component allowing to embed any generated + ouput inside an opening (a prefix) and a closing (a suffix). A simple example + is a C comment: <code class="computeroutput"><span class="comment">/* This is a C comment */</span></code> + which can be generated using the <code class="computeroutput"><span class="identifier">confix</span></code> + generator as: <code class="computeroutput"><span class="identifier">confix</span><span class="special">(</span><span class="string">"/*"</span><span class="special">,</span> + <span class="string">"*/"</span><span class="special">)[</span><span class="string">"This is a C comment"</span><span class="special">]</span></code>. + The general syntax for using the <code class="computeroutput"><span class="identifier">confix</span></code> + is: + </p> +<pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span> +</pre> +<p> + which results in generating a sequence equivalent to + </p> +<pre class="programlisting"><span class="identifier">prefix</span> <span class="special"><<</span> <span class="identifier">subject</span> <span class="special"><<</span> <span class="identifier">suffix</span> +</pre> +<p> + Using the <code class="computeroutput"><span class="identifier">confix</span></code> component + instead of the explicit sequence has the advantage of being able to encapsulate + the prefix and the suffix into a separate generator construct. The following + code snippet illustrates the idea: + </p> +<pre class="programlisting"><span class="comment">// Define a metafunction allowing to compute the type of the confix()</span> +<span class="comment">// construct</span> +<span class="keyword">namespace</span> <span class="identifier">traits</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> + + <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Prefix</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Suffix</span> <span class="special">=</span> <span class="identifier">Prefix</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">confix_spec</span> + <span class="special">:</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">confix</span><span class="special">(</span><span class="identifier">Prefix</span><span class="special">,</span> <span class="identifier">Suffix</span><span class="special">)></span> + <span class="special">{};</span> +<span class="special">};</span> + +<span class="comment">// Define a helper function allowing to create a confix() construct from </span> +<span class="comment">// arbitrary prefix and suffix generators</span> +<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Prefix</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Suffix</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">Prefix</span><span class="special">,</span> <span class="identifier">Suffix</span><span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">confix_spec</span><span class="special">(</span><span class="identifier">Prefix</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">Suffix</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">suffix</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">repository</span><span class="special">::</span><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">);</span> +<span class="special">}</span> + +<span class="comment">// Define a helper function to construct a HTML tag from the tag name</span> +<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">tag</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">tagname</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">confix_spec</span><span class="special">(</span><span class="string">"<"</span> <span class="special">+</span> <span class="identifier">tagname</span> <span class="special">+</span> <span class="string">">"</span><span class="special">,</span> <span class="string">"</"</span> <span class="special">+</span> <span class="identifier">tagname</span> <span class="special">+</span> <span class="string">">"</span><span class="special">);</span> +<span class="special">}</span> + +<span class="comment">// Define generators for different HTML tags the HTML tag</span> +<span class="keyword">typedef</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">ol</span> <span class="special">=</span> <span class="identifier">tag</span><span class="special">(</span><span class="string">"ol"</span><span class="special">);</span> <span class="comment">// <ol>...</ol> </span> +<span class="keyword">typedef</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">li</span> <span class="special">=</span> <span class="identifier">tag</span><span class="special">(</span><span class="string">"li"</span><span class="special">);</span> <span class="comment">// <li>...</li> </span> +</pre> +<p> + Now, for instance, the above definitions allow to generate the HTML 'ol' + tag using a simple: <code class="computeroutput"><span class="identifier">ol</span><span class="special">[</span><span class="string">"Some text"</span><span class="special">]</span></code> (which results in <code class="computeroutput"><span class="special"><</span><span class="identifier">ol</span><span class="special">></span><span class="identifier">Some</span> <span class="identifier">text</span><span class="special"></</span><span class="identifier">ol</span><span class="special">></span></code>). + </p> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h1"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.header"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/karma/directive/confix.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h2"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.synopsis"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.synopsis">Synopsis</a> + </h6> +<pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span> +</pre> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h3"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.parameters"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.parameters">Parameters</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">prefix</span></code> + </p> + </td> +<td> + <p> + The generator construct to use to format the opening (the prefix). + The prefix is the part generated <span class="emphasis"><em>before</em></span> + any output as generated by the <code class="computeroutput"><span class="identifier">subject</span></code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">suffix</span></code> + </p> + </td> +<td> + <p> + The generator construct to use to format the ending (the suffix). + The suffix is the part generated <span class="emphasis"><em>after</em></span> any + output as generated by the <code class="computeroutput"><span class="identifier">subject</span></code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">subject</span></code> + </p> + </td> +<td> + <p> + The generator construct to use to format the actual output in + between the <code class="computeroutput"><span class="identifier">prefix</span></code> + and <code class="computeroutput"><span class="identifier">suffix</span></code> parts. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + All three parameters can be arbitrary complex generators themselves. + </p> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h4"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.attribute"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.attribute">Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">confix</span></code> component exposes + the attribute type of its subject as its own attribute type. If the <code class="computeroutput"><span class="identifier">subject</span></code> does not expose any attribute + (the type is <code class="computeroutput"><span class="identifier">unused_type</span></code>), + then the <code class="computeroutput"><span class="identifier">confix</span></code> does not + expose any attribute either. + </p> +<pre class="programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">confix</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="identifier">s</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">A</span> +</pre> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This notation is used all over the Spirit documentation and reads as: + Given, <code class="computeroutput"><span class="identifier">a</span></code> is generator, + and <code class="computeroutput"><span class="identifier">A</span></code> is the type of + the attribute of generator <code class="computeroutput"><span class="identifier">a</span></code>, + then the type of the attribute exposed by <code class="computeroutput"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="identifier">s</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> will be <code class="computeroutput"><span class="identifier">A</span></code> + as well. + </p></td></tr> +</table></div> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h5"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.example"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.example">Example</a> + </h6> +<p> + The following example shows simple use cases of the <code class="computeroutput"><span class="identifier">confix</span></code> + generator. We will illustrate its usage by generating different comment + styles and a function prototype (for the full example code see here: <a href="../../../../../example/karma/confix.cpp" target="_top">confix.cpp</a>) + </p> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h6"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.prerequisites"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.prerequisites">Prerequisites</a> + </h6> +<p> + In addition to the main header file needed to include the core components + implemented in <span class="emphasis"><em>Spirit.Karma</em></span> we add the header file + needed for the new <code class="computeroutput"><span class="identifier">confix</span></code> + generator. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + To make all the code below more readable we introduce the following namespaces. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">confix</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h7"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.generating_different_comment_styles"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.generating_different_comment_styles">Generating + Different Comment Styles</a> + </h6> +<p> + We will show how to generate different comment styles. First we will generate + a C++ comment: + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// C++ comment</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> + <span class="identifier">karma</span><span class="special">::</span><span class="identifier">format_delimited</span><span class="special">(</span> + <span class="identifier">confix</span><span class="special">(</span><span class="string">"//"</span><span class="special">,</span> <span class="identifier">eol</span><span class="special">)[</span><span class="identifier">string</span><span class="special">],</span> <span class="comment">// format description</span> + <span class="identifier">space</span><span class="special">,</span> <span class="comment">// delimiter</span> + <span class="string">"This is a comment"</span> <span class="comment">// data</span> + <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + This code snippet will obviouly generate <code class="computeroutput"><span class="comment">// + This is a comment \n </span></code>. Similarily generating a 'C'-style + comment proves to be straightforward: + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// C comment</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> + <span class="identifier">karma</span><span class="special">::</span><span class="identifier">format_delimited</span><span class="special">(</span> + <span class="identifier">confix</span><span class="special">(</span><span class="string">"/*"</span><span class="special">,</span> <span class="string">"*/"</span><span class="special">)[</span><span class="identifier">string</span><span class="special">],</span> <span class="comment">// format description</span> + <span class="identifier">space</span><span class="special">,</span> <span class="comment">// delimiter</span> + <span class="string">"This is a comment"</span> <span class="comment">// data</span> + <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + which again will generate <code class="computeroutput"><span class="comment">/* This is a comment + */</span> </code>. + </p> +<h6> +<a name="spirit_repository.karma_components.directives.karma_confix_generator.h8"></a> + <span><a name="spirit_repository.karma_components.directives.karma_confix_generator.generating_a_function_prototype"></a></span><a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.generating_a_function_prototype">Generating + a Function Prototype</a> + </h6> +<p> + Generating a function prototype given a function name a vector or parameter + names is simple as well: + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Generate a function call with an arbitrary parameter list</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">></span> <span class="identifier">parameters</span><span class="special">;</span> +<span class="identifier">parameters</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"par1"</span><span class="special">);</span> +<span class="identifier">parameters</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"par2"</span><span class="special">);</span> +<span class="identifier">parameters</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"par3"</span><span class="special">);</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> + <span class="identifier">karma</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span> + <span class="identifier">string</span> <span class="special"><<</span> <span class="identifier">confix</span><span class="special">(</span><span class="char">'('</span><span class="special">,</span> <span class="char">')'</span><span class="special">)[</span><span class="identifier">string</span> <span class="special">%</span> <span class="char">','</span><span class="special">],</span> <span class="comment">// format description</span> + <span class="string">"func"</span><span class="special">,</span> <span class="comment">// function name</span> + <span class="identifier">parameters</span> <span class="comment">// parameter names</span> + <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + which generates the expected output: <code class="computeroutput"><span class="identifier">func</span><span class="special">(</span><span class="identifier">par1</span><span class="special">,</span><span class="identifier">par2</span><span class="special">,</span><span class="identifier">par3</span><span class="special">)</span></code>. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html b/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html new file mode 100755 index 0000000000..511203a5cb --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html @@ -0,0 +1,46 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Karma Generator Non-terminals</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../karma_components.html" title="Karma Components"> +<link rel="prev" href="directives/karma_confix_generator.html" title="Karma Confix Generator"> +<link rel="next" href="nonterminal/subrule.html" title="Karma subrules"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.karma_components.nonterminal"></a><a class="link" href="nonterminal.html" title="Karma Generator Non-terminals">Karma + Generator Non-terminals</a> +</h3></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="nonterminal/subrule.html">Karma + subrules</a></span></dt></dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html b/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html new file mode 100755 index 0000000000..bf90b32d11 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html @@ -0,0 +1,510 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Karma subrules</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../nonterminal.html" title="Karma Generator Non-terminals"> +<link rel="prev" href="../nonterminal.html" title="Karma Generator Non-terminals"> +<link rel="next" href="../../acknowledgments.html" title="Acknowledgments"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../acknowledgments.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.karma_components.nonterminal.subrule"></a><a class="link" href="subrule.html" title="Karma subrules">Karma + subrules</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h0"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.description"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Karma</em></span> <code class="computeroutput"><span class="identifier">subrule</span></code> + is a component allowing to create a named generator, and to refer to it + by name -- much like rules and grammars. It is in fact a fully static version + of the rule. + </p> +<p> + The strength of subrules is performance. Replacing some rules with subrules + can make a generator slightly faster (see <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.performance">Performance</a> + below for measurements). The reason is that subrules allow aggressive inlining + by the C++ compiler, whereas the implementation of rules is based on a + virtual function call which, depending on the compiler, can have some run-time + overhead and stop inlining. + </p> +<p> + The weaknesses of subrules are: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + subrules can only be defined and used within the same generator expression. + A subrule cannot be defined at one location, and then used in another + location. + </li> +<li class="listitem"> + subrules put a massive strain on the C++ compiler. They increase compile + times and memory usage during compilation, and also increase the risk + of hitting compiler limits and/or bugs. + </li> +</ul></div> +<p> +</p> +<pre class="programlisting"><span class="identifier">entry</span> <span class="special">%=</span> <span class="special">(</span> + <span class="identifier">ast_node</span> <span class="special">%=</span> <span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">binary_node</span> <span class="special">|</span> <span class="identifier">unary_node</span> + + <span class="special">,</span> <span class="identifier">binary_node</span> <span class="special">%=</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="identifier">char_</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="char">')'</span> + + <span class="special">,</span> <span class="identifier">unary_node</span> <span class="special">%=</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">char_</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="char">')'</span> +<span class="special">);</span> +</pre> +<p> + </p> +<p> + The example above can be found here: <a href="../../../../../example/karma/calc2_ast_dump_sr.cpp" target="_top">../../example/karma/calc2_ast_dump_sr.cpp</a> + </p> +<p> + As shown in this code snippet (an extract from the calc2_ast_dump_sr example), + subrules can be freely mixed with rules and grammars. Here, a group of + 3 subrules (<code class="computeroutput"><span class="identifier">ast_node</span></code>, + <code class="computeroutput"><span class="identifier">binary_node</span></code>, <code class="computeroutput"><span class="identifier">unary_node</span></code>) is assigned to a rule (named + <code class="computeroutput"><span class="identifier">entry</span></code>). This means that + parts of a generator can use subrules (typically the innermost, most performance-critical + parts), whereas the rest can use rules and grammars. + </p> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h1"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.header"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/karma/nonterminal/subrule.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h2"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.synopsis__declaration_"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.synopsis__declaration_">Synopsis + (declaration)</a> + </h6> +<pre class="programlisting"><span class="identifier">subrule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">,</span> <span class="identifier">A2</span><span class="special">></span> <span class="identifier">sr</span><span class="special">(</span><span class="identifier">name</span><span class="special">);</span> +</pre> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h3"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.parameters__declaration_"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.parameters__declaration_">Parameters + (declaration)</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">ID</span></code> + </p> + </td> +<td> + <p> + Required numeric argument. Gives the subrule a unique 'identification + tag'. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">A1</span></code>, <code class="computeroutput"><span class="identifier">A2</span></code> + </p> + </td> +<td> + <p> + Optional types, can be specified in any order. Can be one of + 1. signature, 2. locals (see rules reference for more information + on those parameters). + </p> + <p> + Note that the delimiter type need not be specified in the parameters, + unlike with grammars and rules. Subrules will automatically use + the delimiter type which is in effect when they are invoked. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">name</span></code> + </p> + </td> +<td> + <p> + Optional string. Gives the subrule a name, useful for debugging + and error handling. + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h4"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.synopsis__usage_"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.synopsis__usage_">Synopsis + (usage)</a> + </h6> +<p> + Subrules are defined and used within groups, typically (and by convention) + enclosed inside parentheses. + </p> +<pre class="programlisting"><span class="comment">// Group containing N subrules</span> +<span class="special">(</span> + <span class="identifier">sr1</span> <span class="special">=</span> <span class="identifier">expr1</span> + <span class="special">,</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="identifier">expr2</span> + <span class="special">,</span> <span class="special">...</span> <span class="comment">// Any number of subrules</span> +<span class="special">}</span> +</pre> +<p> + The IDs of all subrules defined within the same group must be different. + It is an error to define several subrules with the same ID (or to define + the same subrule multiple times) in the same group. + </p> +<pre class="programlisting"><span class="comment">// Auto-subrules and inherited attributes</span> +<span class="special">(</span> + <span class="identifier">srA</span> <span class="special">%=</span> <span class="identifier">exprA</span> <span class="special"><<</span> <span class="identifier">srB</span> <span class="special"><<</span> <span class="identifier">srC</span><span class="special">(</span><span class="identifier">c1</span><span class="special">,</span> <span class="identifier">c2</span><span class="special">,</span> <span class="special">...)</span> <span class="comment">// Arguments to subrule srC</span> + <span class="special">,</span> <span class="identifier">srB</span> <span class="special">%=</span> <span class="identifier">exprB</span> + <span class="special">,</span> <span class="identifier">srC</span> <span class="special">=</span> <span class="identifier">exprC</span> + <span class="special">,</span> <span class="special">...</span> +<span class="special">)(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...)</span> <span class="comment">// Arguments to group, i.e. to start subrule srA</span> +</pre> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h5"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.parameters__usage_"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.parameters__usage_">Parameters + (usage)</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">sr1</span></code>, <code class="computeroutput"><span class="identifier">sr2</span></code> + </p> + </td> +<td> + <p> + Subrules with different IDs. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">expr1</span></code>, <code class="computeroutput"><span class="identifier">expr2</span></code> + </p> + </td> +<td> + <p> + Generator expressions. Can include <code class="computeroutput"><span class="identifier">sr1</span></code> + and <code class="computeroutput"><span class="identifier">sr2</span></code>, as well + as any other valid generator expressions. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srA</span></code> + </p> + </td> +<td> + <p> + Subrule with a synthesized attribute and inherited attributes. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srB</span></code> + </p> + </td> +<td> + <p> + Subrule with a synthesized attribute. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srC</span></code> + </p> + </td> +<td> + <p> + Subrule with inherited attributes. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">exprA</span></code>, <code class="computeroutput"><span class="identifier">exprB</span></code>, <code class="computeroutput"><span class="identifier">exprC</span></code> + </p> + </td> +<td> + <p> + Generator expressions. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">a1</span></code>, <code class="computeroutput"><span class="identifier">a2</span></code> + </p> + </td> +<td> + <p> + Arguments passed to the subrule group. They are passed as inherited + attributes to the group's start subrule, <code class="computeroutput"><span class="identifier">srA</span></code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">c1</span></code>, <code class="computeroutput"><span class="identifier">c2</span></code> + </p> + </td> +<td> + <p> + Arguments passed as inherited attributes to subrule <code class="computeroutput"><span class="identifier">srC</span></code>. + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h6"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.groups"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.groups">Groups</a> + </h6> +<p> + A subrule group (a set of subrule definitions) is a generator, which can + be used anywhere in a generator expression (in assignments to rules, as + well as directly in arguments to functions such as <code class="computeroutput"><span class="identifier">generate</span></code>). + In a group, generation proceeds from the start subrule, which is the first + (topmost) subrule defined in that group. In the two groups in the synopsis + above, <code class="computeroutput"><span class="identifier">sr1</span></code> and <code class="computeroutput"><span class="identifier">srA</span></code> are the start subrules respectively + -- for example when the first subrule group is called forth, the <code class="computeroutput"><span class="identifier">sr1</span></code> subrule is called. + </p> +<p> + A subrule can only be used in a group which defines it. Groups can be viewed + as scopes: a definition of a subrule is limited to its enclosing group. + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">outiter_type</span><span class="special">></span> <span class="identifier">r1</span><span class="special">,</span> <span class="identifier">r2</span><span class="special">,</span> <span class="identifier">r3</span><span class="special">;</span> +<span class="identifier">subrule</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="identifier">sr1</span><span class="special">;</span> +<span class="identifier">subrule</span><span class="special"><</span><span class="number">2</span><span class="special">></span> <span class="identifier">sr2</span><span class="special">;</span> + +<span class="identifier">r1</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special"><<</span> <span class="identifier">space</span> <span class="special">)</span> <span class="comment">// First group in r1.</span> + <span class="special"><<</span> <span class="special">(</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">sr1</span> <span class="special">)</span> <span class="comment">// Second group in r1.</span> + <span class="comment">// ^^^</span> + <span class="comment">// DOES NOT COMPILE: sr1 is not defined in this</span> + <span class="comment">// second group, it cannot be used here (its</span> + <span class="comment">// previous definition is out of scope).</span> +<span class="special">;</span> + +<span class="identifier">r2</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special"><<</span> <span class="identifier">space</span> <span class="special">)</span> <span class="comment">// Only group in r2.</span> + <span class="special"><<</span> <span class="identifier">sr1</span> + <span class="comment">// ^^^</span> + <span class="comment">// DOES NOT COMPILE: not in a subrule group,</span> + <span class="comment">// sr1 cannot be used here (here too, its</span> + <span class="comment">// previous definition is out of scope).</span> +<span class="special">;</span> + +<span class="identifier">r3</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="identifier">space</span> <span class="special"><<</span> <span class="char">'x'</span> <span class="special">)</span> <span class="comment">// Another group. The same subrule `sr1`</span> + <span class="comment">// can have another, independent</span> + <span class="comment">// definition in this group.</span> +<span class="special">;</span> +</pre> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h7"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.attributes"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.attributes">Attributes</a> + </h6> +<p> + A subrule has the same behavior as a rule with respect to attributes. In + particular: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + the type of its synthesized attribute is the one specified in the subrule's + signature, if any. Otherwise it is <code class="computeroutput"><span class="identifier">unused_type</span></code>. + </li> +<li class="listitem"> + the types of its inherited attributes are the ones specified in the + subrule's signature, if any. Otherwise the subrule has no inherited + attributes. + </li> +<li class="listitem"> + an auto-subrule can be defined by assigning it with the <code class="computeroutput"><span class="special">%=</span></code> syntax. In this case, the subrule's + synthesized attribute is automatically propagated to the RHS generator's + attribute. + </li> +<li class="listitem"> + the Phoenix placeholders <code class="computeroutput"><span class="identifier">_val</span></code>, + <code class="computeroutput"><span class="identifier">_r1</span></code>, <code class="computeroutput"><span class="identifier">_r2</span></code>, ... are available to refer to + the subrule's synthesized and inherited attributes, if present. + </li> +</ul></div> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h8"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.locals"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.locals">Locals</a> + </h6> +<p> + A subrule has the same behavior as a rule with respect to locals. In particular, + the Phoenix placeholders <code class="computeroutput"><span class="identifier">_a</span></code>, + <code class="computeroutput"><span class="identifier">_b</span></code>, ... are available to + refer to the subrule's locals, if present. + </p> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h9"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.example"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.example">Example</a> + </h6> +<p> + Some includes: + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_fusion</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + Some using declarations: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + A grammar containing only one rule, defined with a group of 2 subrules: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">OutputIterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">mini_xml_generator</span> + <span class="special">:</span> <span class="identifier">karma</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">OutputIterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">()></span> +<span class="special">{</span> + <span class="identifier">mini_xml_generator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">mini_xml_generator</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">entry</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">entry</span> <span class="special">%=</span> <span class="special">(</span> + <span class="identifier">xml</span> <span class="special">=</span> + <span class="char">'<'</span> <span class="special"><<</span> <span class="identifier">string</span><span class="special">[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'>'</span> + <span class="special"><<</span> <span class="special">(*</span><span class="identifier">node</span><span class="special">)[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span> + <span class="special"><<</span> <span class="string">"</"</span> <span class="special"><<</span> <span class="identifier">string</span><span class="special">[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'>'</span> + + <span class="special">,</span> <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">string</span> <span class="special">|</span> <span class="identifier">xml</span> + <span class="special">);</span> + <span class="special">}</span> + + <span class="identifier">karma</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">OutputIterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">()></span> <span class="identifier">entry</span><span class="special">;</span> + + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">karma</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">0</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">()></span> <span class="identifier">xml</span><span class="special">;</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">karma</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">()></span> <span class="identifier">node</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + The definitions of the <code class="computeroutput"><span class="identifier">mini_xml</span></code> + and <code class="computeroutput"><span class="identifier">mini_xml_node</span></code> data + structures are not shown here. The full example above can be found here: + <a href="../../../../../example/karma/mini_xml_karma_sr.cpp" target="_top">../../example/karma/mini_xml_karma_sr.cpp</a> + </p> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h10"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.performance"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.performance">Performance</a> + </h6> +<p> + For comparison of run-time and compile-time performance when using subrules, + please see the <a class="link" href="../../qi_components/nonterminal/subrule.html#spirit_repository.qi_components.nonterminal.subrule.performance">Performance</a> + section of <span class="emphasis"><em>Spirit.Qi</em></span> subrules (the implementation + of <span class="emphasis"><em>Spirit.Karma</em></span> and <span class="emphasis"><em>Spirit.Qi</em></span> + subrules is very similar, so performance is very similar too). + </p> +<h6> +<a name="spirit_repository.karma_components.nonterminal.subrule.h11"></a> + <span><a name="spirit_repository.karma_components.nonterminal.subrule.notes"></a></span><a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.notes">Notes</a> + </h6> +<p> + Subrules push the C++ compiler hard. A group of subrules is a single C++ + expression. Current C++ compilers cannot handle very complex expressions + very well. One restricting factor is the typical compiler's limit on template + recursion depth. Some, but not all, compilers allow this limit to be configured. + </p> +<p> + g++'s maximum can be set using a compiler flag: <code class="computeroutput"><span class="special">-</span><span class="identifier">ftemplate</span><span class="special">-</span><span class="identifier">depth</span></code>. Set this appropriately if you + use relatively complex subrules. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../acknowledgments.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/preface.html b/libs/spirit/repository/doc/html/spirit_repository/preface.html new file mode 100755 index 0000000000..beaa62b504 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/preface.html @@ -0,0 +1,238 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Preface</title> +<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../index.html" title="Spirit Repository 0.2"> +<link rel="prev" href="../index.html" title="Spirit Repository 0.2"> +<link rel="next" href="what_s_new.html" title="What's New"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="what_s_new.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="spirit_repository.preface"></a><a class="link" href="preface.html" title="Preface">Preface</a> +</h2></div></div></div> +<h4> +<a name="spirit_repository.preface.h0"></a> + <span><a name="spirit_repository.preface.the_spirit_repository"></a></span><a class="link" href="preface.html#spirit_repository.preface.the_spirit_repository">The + Spirit Repository</a> + </h4> +<p> + The <a href="http://boost-spirit.com" target="_top">Spirit</a> repository is a community + effort collecting different reusable components (primitives, directives, grammars, + etc.) for <span class="emphasis"><em>Spirit.Qi</em></span> parsers and <span class="emphasis"><em>Spirit.Karma</em></span> + generators. All components in the repository have been peer reviewed and/or + discussed on the <a href="http://www.nabble.com/The-Spirit-Parser-Library-f3430.html" target="_top">Spirit + General List</a>. The aim is to broaden the scope of the <a href="http://boost-spirit.com" target="_top">Spirit</a> + library while being able to maintain its high standards in terms of code quality, + flexibility, and maintainability. At the same time it encourages people to + contribute even small components as it lessens the hurdle of becoming a <a href="http://www.boost.org/" target="_top">Boost</a> and <a href="http://boost-spirit.com" target="_top">Spirit</a> + author. + </p> +<p> + Maintainability of the code and author commitment over a longer period of time + are crucial for <span class="emphasis"><em>Spirit's</em></span> success (as it is for the whole + <a href="http://www.boost.org/" target="_top">Boost</a> project). That allows the + repository to play an additional role in terms of being a proving ground for + interested authors. It is a lot easier to remove code from the repository than + from the <span class="emphasis"><em>Spirit</em></span> core library. So if an author can't maintain + his/her contribution anymore for any reason, we are able to remove those parts + from the repository more easily. + </p> +<p> + The repository is an excellent way of evolving things. The <span class="emphasis"><em>Spirit</em></span> + core has been developed for years, so we have a certain confidence of it being + properly designed and exposing a proven API. On the other hand, new ideas often + need some time to 'come to the point'. Changing API's is part of this business. + At the same time changing API's always mean user disruption, which we want + to keep to a minimum. Again, changing things in the repository is ought to + be a lot easier than in the core library. + </p> +<p> + The quality of contributions is another key to success. That includes not only + the code itself, but takes into consideration such things as documentation, + tests, examples. The authors activity on the mailing list is related as well, + it's an important point. Only well supported things will evolve over time into + usable, high quality components. The mandatory discussions and the review of + contributions on the <a href="http://www.nabble.com/The-Spirit-Parser-Library-f3430.html" target="_top">Spirit + General List</a> ensure the targeted high quality standards. + </p> +<p> + Based on the user feedback and general usability of things it is possible over + time to move repository components/grammars into the <span class="emphasis"><em>Spirit</em></span> + core library. + </p> +<h4> +<a name="spirit_repository.preface.h1"></a> + <span><a name="spirit_repository.preface.how_to_use_this_manual"></a></span><a class="link" href="preface.html#spirit_repository.preface.how_to_use_this_manual">How + to use this manual</a> + </h4> +<p> + Some icons are used to mark certain topics indicative of their relevance. These + icons precede some text to indicate: + </p> +<div class="table"> +<a name="spirit_repository.preface.t0"></a><p class="title"><b>Table 1. Icons</b></p> +<div class="table-contents"><table class="table" summary="Icons"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Icon + </p> + </th> +<th> + <p> + Name + </p> + </th> +<th> + <p> + Meaning + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> + </p> + </td> +<td> + <p> + Note + </p> + </td> +<td> + <p> + Generally useful information (an aside that doesn't fit in the flow + of the text) + </p> + </td> +</tr> +<tr> +<td> + <p> + <span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> + </p> + </td> +<td> + <p> + Tip + </p> + </td> +<td> + <p> + Suggestion on how to do something (especially something that not + be obvious) + </p> + </td> +</tr> +<tr> +<td> + <p> + <span class="inlinemediaobject"><img src="../images/important.png" alt="important"></span> + </p> + </td> +<td> + <p> + Important + </p> + </td> +<td> + <p> + Important note on something to take particular notice of + </p> + </td> +</tr> +<tr> +<td> + <p> + <span class="inlinemediaobject"><img src="../images/caution.png" alt="caution"></span> + </p> + </td> +<td> + <p> + Caution + </p> + </td> +<td> + <p> + Take special care with this - it may not be what you expect and may + cause bad results + </p> + </td> +</tr> +<tr> +<td> + <p> + <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> + </p> + </td> +<td> + <p> + Danger + </p> + </td> +<td> + <p> + This is likely to cause serious trouble if ignored + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><p> + This documentation is automatically generated by Boost QuickBook documentation + tool. QuickBook can be found in the <a href="http://www.boost.org/tools/index.html" target="_top">Boost + Tools</a>. + </p> +<h4> +<a name="spirit_repository.preface.h2"></a> + <span><a name="spirit_repository.preface.support"></a></span><a class="link" href="preface.html#spirit_repository.preface.support">Support</a> + </h4> +<p> + Please direct all questions to Spirit's mailing list. You can subscribe to + the <a href="http://www.nabble.com/The-Spirit-Parser-Library-f3430.html" target="_top">Spirit + General List</a>. The mailing list has a searchable archive. A search link + to this archive is provided in <a href="http://boost-spirit.com" target="_top">Spirit</a>'s + home page. You may also read and post messages to the mailing list through + <a href="news://news.gmane.org/gmane.comp.spirit.general" target="_top">Spirit General + NNTP news portal</a> (thanks to <a href="http://www.gmane.org" target="_top">Gmane</a>). + The news group mirrors the mailing list. Here is a link to the archives: <a href="http://news.gmane.org/gmane.comp.parsers.spirit.general" target="_top">http://news.gmane.org/gmane.comp.parsers.spirit.general</a>. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="what_s_new.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components.html new file mode 100755 index 0000000000..bcd1bc9f59 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components.html @@ -0,0 +1,73 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Components</title> +<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../index.html" title="Spirit Repository 0.2"> +<link rel="prev" href="what_s_new/spirit_2_5_1.html" title="Spirit V2.5.1"> +<link rel="next" href="qi_components/primitive.html" title="Qi Parser Primitives"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="what_s_new/spirit_2_5_1.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="qi_components/primitive.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="spirit_repository.qi_components"></a><a class="link" href="qi_components.html" title="Qi Components">Qi Components</a> +</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="qi_components/primitive.html">Qi Parser + Primitives</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="qi_components/primitive/advance.html">Qi + advance Parser</a></span></dt> +<dt><span class="section"><a href="qi_components/primitive/flush_multi_pass.html">Qi + flush_multi_pass parser</a></span></dt> +</dl></dd> +<dt><span class="section"><a href="qi_components/directives.html">Qi Parser + Directives</a></span></dt> +<dd><dl> +<dt><span class="section"><a href="qi_components/directives/confix.html">Qi + Confix Parser Directive</a></span></dt> +<dt><span class="section"><a href="qi_components/directives/distinct.html">Qi + Distinct Parser Directive</a></span></dt> +<dt><span class="section"><a href="qi_components/directives/kwd.html">Qi + Keyword Parser Directive </a></span></dt> +<dt><span class="section"><a href="qi_components/directives/seek.html">Qi + Seek Parser Directive </a></span></dt> +</dl></dd> +<dt><span class="section"><a href="qi_components/nonterminal.html">Qi Parser + Non-terminals</a></span></dt> +<dd><dl><dt><span class="section"><a href="qi_components/nonterminal/subrule.html">Qi + subrules</a></span></dt></dl></dd> +<dt><span class="section"><a href="qi_components/operators.html">Qi Parser + Operators</a></span></dt> +<dd><dl><dt><span class="section"><a href="qi_components/operators/keyword_list.html">Keyword + List Operator</a></span></dt></dl></dd> +</dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="what_s_new/spirit_2_5_1.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="qi_components/primitive.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives.html new file mode 100755 index 0000000000..d82fbc5de0 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives.html @@ -0,0 +1,54 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Parser Directives</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../qi_components.html" title="Qi Components"> +<link rel="prev" href="primitive/flush_multi_pass.html" title="Qi flush_multi_pass parser"> +<link rel="next" href="directives/confix.html" title="Qi Confix Parser Directive"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="primitive/flush_multi_pass.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="directives/confix.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.qi_components.directives"></a><a class="link" href="directives.html" title="Qi Parser Directives">Qi Parser + Directives</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="directives/confix.html">Qi + Confix Parser Directive</a></span></dt> +<dt><span class="section"><a href="directives/distinct.html">Qi + Distinct Parser Directive</a></span></dt> +<dt><span class="section"><a href="directives/kwd.html">Qi + Keyword Parser Directive </a></span></dt> +<dt><span class="section"><a href="directives/seek.html">Qi + Seek Parser Directive </a></span></dt> +</dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="primitive/flush_multi_pass.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="directives/confix.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html new file mode 100755 index 0000000000..7eb65dd5e1 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html @@ -0,0 +1,333 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Confix Parser Directive</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../directives.html" title="Qi Parser Directives"> +<link rel="prev" href="../directives.html" title="Qi Parser Directives"> +<link rel="next" href="distinct.html" title="Qi Distinct Parser Directive"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="distinct.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.directives.confix"></a><a class="link" href="confix.html" title="Qi Confix Parser Directive">Qi + Confix Parser Directive</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h0"></a> + <span><a name="spirit_repository.qi_components.directives.confix.description"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">confix</span></code> + directive is a unary parser component allowing to embed a parser (the subject) + inside an opening (the prefix) and a closing (the suffix): + </p> +<pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span> +</pre> +<p> + This results in a parser that is equivalent to the sequence + </p> +<pre class="programlisting"><span class="identifier">omit</span><span class="special">[</span><span class="identifier">prefix</span><span class="special">]</span> <span class="special">>></span> <span class="identifier">subject</span> <span class="special">>></span> <span class="identifier">omit</span><span class="special">[</span><span class="identifier">suffix</span><span class="special">]</span> +</pre> +<p> + A simple example is a parser for non-nested comments which can now be written + as: + </p> +<pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="string">"/*"</span><span class="special">,</span> <span class="string">"*/"</span><span class="special">)[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="string">"*/"</span><span class="special">)]</span> <span class="comment">// C style comment</span> +<span class="identifier">confix</span><span class="special">(</span><span class="string">"//"</span><span class="special">,</span> <span class="identifier">eol</span><span class="special">)[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)]</span> <span class="comment">// C++ style comment</span> +</pre> +<p> + Using the <code class="computeroutput"><span class="identifier">confix</span></code> directive + instead of the explicit sequence has the advantage of being able to encapsulate + the prefix and the suffix into a separate construct. The following code + snippet illustrates the idea: + </p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">spirit</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span> + +<span class="comment">// Define a metafunction allowing to compute the type</span> +<span class="comment">// of the confix() construct</span> +<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Prefix</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Suffix</span> <span class="special">=</span> <span class="identifier">Prefix</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">confix_spec</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">confix</span><span class="special">(</span><span class="identifier">Prefix</span><span class="special">,</span> <span class="identifier">Suffix</span><span class="special">)</span> + <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span> +<span class="special">};</span> + +<span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">c_comment</span> <span class="special">=</span> <span class="identifier">repo</span><span class="special">::</span><span class="identifier">confix</span><span class="special">(</span><span class="string">"/*"</span><span class="special">,</span> <span class="string">"*/"</span><span class="special">);</span> +<span class="identifier">confix_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">cpp_comment</span> <span class="special">=</span> <span class="identifier">repo</span><span class="special">::</span><span class="identifier">confix</span><span class="special">(</span><span class="string">"//"</span><span class="special">,</span> <span class="string">"\n"</span><span class="special">);</span> +</pre> +<p> + Now, the comment parsers can be written as + </p> +<pre class="programlisting"><span class="identifier">c_comment</span><span class="special">[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="string">"*/"</span><span class="special">)]</span> <span class="comment">// C style comment</span> +<span class="identifier">cpp_comment</span><span class="special">[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)]</span> <span class="comment">// C++ style comment</span> +</pre> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + While the <code class="computeroutput"><span class="identifier">confix_p</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">subject</span><span class="special">,</span> + <span class="identifier">suffix</span><span class="special">)</span></code> + parser in <span class="emphasis"><em>Spirit.Classic</em></span> was equivalent to the sequence + <code class="computeroutput"><span class="identifier">prefix</span> <span class="special">>></span> + <span class="special">*(</span><span class="identifier">subject</span> + <span class="special">-</span> <span class="identifier">suffix</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">suffix</span><span class="special">,</span> <span class="identifier">the</span> <span class="emphasis"><em>Spirit.Qi</em></span> </code>confix` + directive will not perform this refactoring any more. This simplifies + the code and makes things more explicit. + </p></td></tr> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h1"></a> + <span><a name="spirit_repository.qi_components.directives.confix.header"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/confix.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h2"></a> + <span><a name="spirit_repository.qi_components.directives.confix.synopsis"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.synopsis">Synopsis</a> + </h6> +<pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h3"></a> + <span><a name="spirit_repository.qi_components.directives.confix.parameters"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parameters">Parameters</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">prefix</span></code> + </p> + </td> +<td> + <p> + The parser for the opening (the prefix). + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">suffix</span></code> + </p> + </td> +<td> + <p> + The parser for the ending (the suffix). + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">subject</span></code> + </p> + </td> +<td> + <p> + The parser for the input sequence between the <code class="computeroutput"><span class="identifier">prefix</span></code> + and <code class="computeroutput"><span class="identifier">suffix</span></code> parts. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + All three parameters can be arbitrarily complex parsers themselves. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h4"></a> + <span><a name="spirit_repository.qi_components.directives.confix.attribute"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.attribute">Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">confix</span></code> directive exposes + the attribute type of its subject as its own attribute type. If the <code class="computeroutput"><span class="identifier">subject</span></code> does not expose any attribute + (the type is <code class="computeroutput"><span class="identifier">unused_type</span></code>), + then the <code class="computeroutput"><span class="identifier">confix</span></code> does not + expose any attribute either. + </p> +<pre class="programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">p</span><span class="special">:</span> <span class="identifier">P</span><span class="special">,</span> <span class="identifier">s</span><span class="special">:</span> <span class="identifier">S</span><span class="special">:</span> <span class="special">--></span> <span class="identifier">confix</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="identifier">s</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">A</span> +</pre> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This notation is used all over the Spirit documentation and reads as: + Given, <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">p</span></code>, and <code class="computeroutput"><span class="identifier">s</span></code> + are parsers, and <code class="computeroutput"><span class="identifier">A</span></code>, + <code class="computeroutput"><span class="identifier">P</span></code>, and <code class="computeroutput"><span class="identifier">S</span></code> are the types of their attributes, + then the type of the attribute exposed by <code class="computeroutput"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="identifier">s</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> will be <code class="computeroutput"><span class="identifier">A</span></code>. + </p></td></tr> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h5"></a> + <span><a name="spirit_repository.qi_components.directives.confix.example"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.example">Example</a> + </h6> +<p> + The following example shows simple use cases of the <code class="computeroutput"><span class="identifier">confix</span></code> + directive. We will illustrate its usage by generating parsers for different + comment styles and for some simple tagged data (for the full example code + see <a href="../../../../../example/qi/confix.cpp" target="_top">confix.cpp</a>) + </p> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h6"></a> + <span><a name="spirit_repository.qi_components.directives.confix.prerequisites"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.prerequisites">Prerequisites</a> + </h6> +<p> + In addition to the main header file needed to include the core components + implemented in <span class="emphasis"><em>Spirit.Qi</em></span> we add the header file needed + for the new <code class="computeroutput"><span class="identifier">confix</span></code> directive. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + In order to make the examples below more readable we import a number of + elements into the current namespace: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">eol</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">alnum</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">confix</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h7"></a> + <span><a name="spirit_repository.qi_components.directives.confix.parsing_different_comment_styles"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parsing_different_comment_styles">Parsing + Different Comment Styles</a> + </h6> +<p> + We will show how to parse different comment styles. First we will parse + a C++ comment: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_cpp_comment</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + <span class="identifier">confix</span><span class="special">(</span><span class="string">"//"</span><span class="special">,</span> <span class="identifier">eol</span><span class="special">)[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)],</span> <span class="comment">// grammar</span> + <span class="identifier">attr</span><span class="special">);</span> <span class="comment">// attribute</span> + + <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">r</span> <span class="special">||</span> <span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + This function will obviously parse input such as "<code class="computeroutput"><span class="comment">// + This is a comment \n </span></code>". Similarily parsing a 'C'-style + comment proves to be straightforward: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_c_comment</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + <span class="identifier">confix</span><span class="special">(</span><span class="string">"/*"</span><span class="special">,</span> <span class="string">"*/"</span><span class="special">)[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="string">"*/"</span><span class="special">)],</span> <span class="comment">// grammar</span> + <span class="identifier">attr</span><span class="special">);</span> <span class="comment">// attribute</span> + + <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">r</span> <span class="special">||</span> <span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + which again will be able to parse e.g. "<code class="computeroutput"><span class="comment">/* + This is a comment */</span> </code>". + </p> +<h6> +<a name="spirit_repository.qi_components.directives.confix.h8"></a> + <span><a name="spirit_repository.qi_components.directives.confix.parsing_tagged_data"></a></span><a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parsing_tagged_data">Parsing + Tagged Data</a> + </h6> +<p> + Generating a parser that extracts the body from the HTML snippet "<code class="computeroutput"><span class="special"><</span><span class="identifier">b</span><span class="special">></span><span class="identifier">The</span> <span class="identifier">Body</span><span class="special"></</span><span class="identifier">b</span><span class="special">></span></code>" + is not very hard, either: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">bool</span> <span class="identifier">parse_tagged</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> + <span class="identifier">confix</span><span class="special">(</span><span class="string">"<b>"</span><span class="special">,</span> <span class="string">"</b>"</span><span class="special">)[</span><span class="identifier">lexeme</span><span class="special">[*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)]],</span> <span class="comment">// grammar</span> + <span class="identifier">space</span><span class="special">,</span> <span class="comment">// skip</span> + <span class="identifier">attr</span><span class="special">);</span> <span class="comment">// attribute</span> + + <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">r</span> <span class="special">||</span> <span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">)</span> <span class="comment">// fail if we did not get a full match</span> + <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">r</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="distinct.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html new file mode 100755 index 0000000000..d79269f778 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html @@ -0,0 +1,325 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Distinct Parser Directive</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../directives.html" title="Qi Parser Directives"> +<link rel="prev" href="confix.html" title="Qi Confix Parser Directive"> +<link rel="next" href="kwd.html" title="Qi Keyword Parser Directive"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="confix.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="kwd.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.directives.distinct"></a><a class="link" href="distinct.html" title="Qi Distinct Parser Directive">Qi + Distinct Parser Directive</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h0"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.description"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">distinct</span></code> + parser is a directive component allowing to avoid partial matches while + parsing using a skipper. A simple example is the common task of matching + a C keyword. Consider: + </p> +<pre class="programlisting"><span class="string">"description"</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">":"</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> +</pre> +<p> + intended to match a line in a configuration file. Let's assume further, + that this rule is used with a <code class="computeroutput"><span class="identifier">space</span></code> + skipper and that we have the following strings in the input: + </p> +<pre class="programlisting"><span class="string">"description: ident\n"</span> +<span class="string">"description ident\n"</span> +<span class="string">"descriptionident\n"</span> +</pre> +<p> + It might seem unexpected, but the parser above matches all three inputs + just fine, even if the third input should not match at all! In order to + avoid the unwanted match we are forced to make our rule more complicated: + </p> +<pre class="programlisting"><span class="identifier">lexeme</span><span class="special">[</span><span class="string">"description"</span> <span class="special">>></span> <span class="special">!</span><span class="identifier">char_</span><span class="special">(</span><span class="string">"a-zA-Z_0-9"</span><span class="special">)]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">":"</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> +</pre> +<p> + (the rule reads as: match <code class="computeroutput"><span class="string">"description"</span></code> + as long as it's not <span class="emphasis"><em>directly</em></span> followed by a valid identifier). + </p> +<p> + The <code class="computeroutput"><span class="identifier">distinct</span><span class="special">[]</span></code> + directive is meant to simplify the rule above: + </p> +<pre class="programlisting"><span class="identifier">distinct</span><span class="special">(</span><span class="identifier">char_</span><span class="special">(</span><span class="string">"a-zA-Z_0-9"</span><span class="special">))[</span><span class="string">"description"</span><span class="special">]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">":"</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> +</pre> +<p> + Using the <code class="computeroutput"><span class="identifier">distinct</span><span class="special">[]</span></code> + component instead of the explicit sequence has the advantage of being able + to encapsulate the tail (i.e the <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="string">"a-zA-Z_0-9"</span><span class="special">)</span></code>) as a separate parser construct. The following + code snippet illustrates the idea (for the full code of this example please + see <a href="../../../../../test/qi/distinct.cpp" target="_top">distinct.cpp</a>): + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">spirit</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">ascii</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span> + +<span class="comment">// Define metafunctions allowing to compute the type of the distinct()</span> +<span class="comment">// and ascii::char_() constructs</span> +<span class="keyword">namespace</span> <span class="identifier">traits</span> +<span class="special">{</span> + <span class="comment">// Metafunction allowing to get the type of any repository::distinct(...) </span> + <span class="comment">// construct</span> + <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tail</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">distinct_spec</span> + <span class="special">:</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">repo</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">distinct</span><span class="special">(</span><span class="identifier">Tail</span><span class="special">)></span> + <span class="special">{};</span> + + <span class="comment">// Metafunction allowing to get the type of any ascii::char_(...) construct</span> + <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">String</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">char_spec</span> + <span class="special">:</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="identifier">String</span><span class="special">)></span> + <span class="special">{};</span> +<span class="special">};</span> + +<span class="comment">// Define a helper function allowing to create a distinct() construct from </span> +<span class="comment">// an arbitrary tail parser</span> +<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tail</span><span class="special">></span> +<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">distinct_spec</span><span class="special"><</span><span class="identifier">Tail</span><span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">distinct_spec</span><span class="special">(</span><span class="identifier">Tail</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">tail</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">repo</span><span class="special">::</span><span class="identifier">distinct</span><span class="special">(</span><span class="identifier">tail</span><span class="special">);</span> +<span class="special">}</span> + +<span class="comment">// Define a helper function allowing to create a ascii::char_() construct </span> +<span class="comment">// from an arbitrary string representation</span> +<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">String</span><span class="special">></span> +<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">char_spec</span><span class="special"><</span><span class="identifier">String</span><span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">char_spec</span><span class="special">(</span><span class="identifier">String</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">str</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="identifier">str</span><span class="special">);</span> +<span class="special">}</span> + +<span class="comment">// the following constructs the type of a distinct_spec holding a</span> +<span class="comment">// charset("0-9a-zA-Z_") as its tail parser</span> +<span class="keyword">typedef</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">char_spec</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">charset_tag_type</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">traits</span><span class="special">::</span><span class="identifier">distinct_spec</span><span class="special"><</span><span class="identifier">charset_tag_type</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">keyword_tag_type</span><span class="special">;</span> + +<span class="comment">// Define a new Qi 'keyword' directive usable as a shortcut for a</span> +<span class="comment">// repository::distinct(char_(std::string("0-9a-zA-Z_")))</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">keyword_spec</span><span class="special">(</span><span class="string">"0-9a-zA-Z_"</span><span class="special">);</span> +<span class="identifier">keyword_tag_type</span> <span class="keyword">const</span> <span class="identifier">keyword</span> <span class="special">=</span> <span class="identifier">distinct_spec</span><span class="special">(</span><span class="identifier">char_spec</span><span class="special">(</span><span class="identifier">keyword_spec</span><span class="special">));</span> +</pre> +<p> + </p> +<p> + These definitions define a new Qi parser recognizing keywords! This allows + to rewrite our declaration parser expression as: + </p> +<pre class="programlisting"><span class="identifier">keyword</span><span class="special">[</span><span class="string">"description"</span><span class="special">]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">":"</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> +</pre> +<p> + which is much more readable and concise if compared to the original parser + expression. In addition the new <code class="computeroutput"><span class="identifier">keyword</span><span class="special">[]</span></code> directive has the advantage to be usable + for wrapping any parser expression, not only strings as in the example + above. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h1"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.header"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/distinct.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_distinct</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h2"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.synopsis"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.synopsis">Synopsis</a> + </h6> +<pre class="programlisting"><span class="identifier">distinct</span><span class="special">(</span><span class="identifier">tail</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h3"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.parameters"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.parameters">Parameters</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">tail</span></code> + </p> + </td> +<td> + <p> + The parser construct specifying what whould not follow the subject + in order to match the overall expression. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">subject</span></code> + </p> + </td> +<td> + <p> + The parser construct to use to match the current input. The distinct + directive makes sure that no unexpected partial matches occur. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + All two parameters can be arbitrary complex parsers themselves. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h4"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.attribute"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.attribute">Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">distinct</span></code> component + exposes the attribute type of its subject as its own attribute type. If + the <code class="computeroutput"><span class="identifier">subject</span></code> does not expose + any attribute (the type is <code class="computeroutput"><span class="identifier">unused_type</span></code>), + then the <code class="computeroutput"><span class="identifier">distinct</span></code> does + not expose any attribute either. + </p> +<pre class="programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">B</span> <span class="special">--></span> <span class="identifier">distinct</span><span class="special">(</span><span class="identifier">b</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">A</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h5"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.example"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.example">Example</a> + </h6> +<p> + The following example shows simple use cases of the <code class="computeroutput"><span class="identifier">distinct</span></code> + parser. <a href="../../../../../example/qi/distinct.cpp" target="_top">distinct.cpp</a>) + </p> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h6"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.prerequisites"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.prerequisites">Prerequisites</a> + </h6> +<p> + In addition to the main header file needed to include the core components + implemented in <span class="emphasis"><em>Spirit.Qi</em></span> we add the header file needed + for the new <code class="computeroutput"><span class="identifier">distinct</span></code> generator. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_distinct</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + To make all the code below more readable we introduce the following namespaces. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">distinct</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.directives.distinct.h7"></a> + <span><a name="spirit_repository.qi_components.directives.distinct.using_the_distinct_directive_to_match_keywords"></a></span><a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.using_the_distinct_directive_to_match_keywords">Using + The Distinct Directive to Match keywords</a> + </h6> +<p> + We show several examples of how the <code class="computeroutput"><span class="identifier">distinct</span><span class="special">[]</span></code> directive can be used to force correct + behavior while matching keywords. The first two code snippets show the + correct matching of the <code class="computeroutput"><span class="identifier">description</span></code> + keyword (in this hypothetical example we allow keywords to be directly + followed by an optional <code class="computeroutput"><span class="string">"--"</span></code>): + </p> +<p> +</p> +<pre class="programlisting"><span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">(</span><span class="string">"description ident"</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">distinct</span><span class="special">(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)[</span><span class="string">"description"</span><span class="special">]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"--"</span><span class="special">)</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">space</span><span class="special">);</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">r</span> <span class="special">&&</span> <span class="identifier">first</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> +</p> +<pre class="programlisting"><span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">(</span><span class="string">"description--ident"</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">distinct</span><span class="special">(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)[</span><span class="string">"description"</span><span class="special">]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"--"</span><span class="special">)</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">space</span><span class="special">);</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">r</span> <span class="special">&&</span> <span class="identifier">first</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The last example shows that the <code class="computeroutput"><span class="identifier">distinct</span><span class="special">[]</span></code> parser component correctly refuses to + match "description-ident": + </p> +<p> +</p> +<pre class="programlisting"><span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">(</span><span class="string">"description-ident"</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> + <span class="keyword">bool</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">distinct</span><span class="special">(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)[</span><span class="string">"description"</span><span class="special">]</span> <span class="special">>></span> <span class="special">-</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"--"</span><span class="special">)</span> <span class="special">>></span> <span class="special">+(</span><span class="identifier">alnum</span> <span class="special">|</span> <span class="char">'_'</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">space</span><span class="special">);</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(!</span><span class="identifier">r</span> <span class="special">&&</span> <span class="identifier">first</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="confix.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="kwd.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/kwd.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/kwd.html new file mode 100755 index 0000000000..16224739f7 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/kwd.html @@ -0,0 +1,367 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Keyword Parser Directive</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../directives.html" title="Qi Parser Directives"> +<link rel="prev" href="distinct.html" title="Qi Distinct Parser Directive"> +<link rel="next" href="seek.html" title="Qi Seek Parser Directive"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="distinct.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="seek.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.directives.kwd"></a><a class="link" href="kwd.html" title="Qi Keyword Parser Directive">Qi + Keyword Parser Directive </a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h0"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.description"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.description">Description</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">kwd</span><span class="special">[]</span></code> + and <code class="computeroutput"><span class="identifier">ikwd</span><span class="special">[]</span></code> + provide a powerful and flexible mechanism for parsing keyword based input. + It works in conjuction with the / operator to create an effective keyword + parsing loop. The keyword parsing loop doesn't require the keywords to + appear in a defined order in the input but also provides the possibility + to check how many times a keyword appears in the input. + </p> +<p> + The kwd directive will parse the keywords respecting case sensitivity whereas + the ikwd direcive is case insensitive. You can mix the kwd and ikwd directives + inside a set of keywords, but be aware that this has a small overhead. + It should be prefered not to mix the kwd and ikwd directives. + </p> +<p> + The kwd directive is very similar to the repeat directive in that it enables + to enforce keyword occurence constraints but also provides very interesting + speed improvement over the pure EBNF syntax or the Nabialek-Trick. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h1"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.header"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/kwd.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_kwd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h2"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.synopsis"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.synopsis">Synopsis</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Parse ( <code class="computeroutput"><span class="string">"keyword"</span></code> + > <code class="computeroutput"><span class="identifier">subject</span></code>) + zero or more times. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span><span class="identifier">n</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Parse ( <code class="computeroutput"><span class="string">"keyword"</span></code> + > <code class="computeroutput"><span class="identifier">subject</span></code>) + exactly <code class="computeroutput"><span class="identifier">n</span></code> times. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> + <span class="identifier">max</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Parse ( <code class="computeroutput"><span class="string">"keyword"</span></code> + > <code class="computeroutput"><span class="identifier">subject</span></code>) + at least <code class="computeroutput"><span class="identifier">min</span></code> + times and at most <code class="computeroutput"><span class="identifier">max</span></code> + times. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> + <span class="identifier">inf</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Parse ( <code class="computeroutput"><span class="string">"keyword"</span></code> + > <code class="computeroutput"><span class="identifier">subject</span></code>) + at least <code class="computeroutput"><span class="identifier">min</span></code> + or more. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + For non case sensitive keywords use the ikwd directive. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h3"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.parameters"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.parameters">Parameters</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">keyword</span></code> + </p> + </td> +<td> + <p> + The parser for the opening (the prefix). + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">subject</span></code> + </p> + </td> +<td> + <p> + The parser for the input sequence following the keyword part. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">n</span></code> + </p> + </td> +<td> + <p> + Int representing the exact number of times the keyword must be + repeated. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">min</span></code> + </p> + </td> +<td> + <p> + Int representing the minimum number of times the keyword must + be repeated. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">max</span></code> + </p> + </td> +<td> + <p> + Int representing the maximum number of times the keyword must + be repeated. + </p> + </td> +</tr> +</tbody> +</table></div> +<p> + All three parameters can be arbitrarily complex parsers themselves. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h4"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.attributes"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.attributes">Attributes</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Attribute + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> <span class="keyword">or</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">Unused</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">n</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">n</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> <span class="keyword">or</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">n</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">Unused</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> + <span class="identifier">max</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> <span class="keyword">or</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> <span class="identifier">max</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">Unused</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> + <span class="identifier">inf</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> <span class="identifier">inf</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> <span class="keyword">or</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">,</span><span class="identifier">min</span><span class="special">,</span> <span class="identifier">inf</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">Unused</span></pre> +<p> + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h5"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.complexity"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.complexity">Complexity</a> + </h6> +<div class="blockquote"><blockquote class="blockquote"> +<p> + The overall complexity is defined by the complexity of its subject parser. + The complexity of the keyword list construct <code class="computeroutput"><span class="identifier">kwd</span></code> + itself is O(N), where N is the number of repetitions executed. + </p> +<p> + The complexity of the keyword list itself determined by the complexity + of the internal TST contents : + </p> +<p> + O(log n+k) + </p> +<p> + Where k is the length of the string to be searched in a TST with n strings. + </p> +</blockquote></div> +<h6> +<a name="spirit_repository.qi_components.directives.kwd.h6"></a> + <span><a name="spirit_repository.qi_components.directives.kwd.example"></a></span><a class="link" href="kwd.html#spirit_repository.qi_components.directives.kwd.example">Example</a> + </h6> +<p> + Please refer to keyword_list. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="distinct.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="seek.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/seek.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/seek.html new file mode 100755 index 0000000000..f4d23870da --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/seek.html @@ -0,0 +1,260 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Seek Parser Directive</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../directives.html" title="Qi Parser Directives"> +<link rel="prev" href="kwd.html" title="Qi Keyword Parser Directive"> +<link rel="next" href="../nonterminal.html" title="Qi Parser Non-terminals"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="kwd.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.directives.seek"></a><a class="link" href="seek.html" title="Qi Seek Parser Directive">Qi + Seek Parser Directive </a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h0"></a> + <span><a name="spirit_repository.qi_components.directives.seek.description"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.description">Description</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">seek</span><span class="special">[]</span></code> + parser-directive skips all input until the subject parser matches. On failure, + the current position is the end of the input. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h1"></a> + <span><a name="spirit_repository.qi_components.directives.seek.header"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/seek.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_seek</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + Also, see <a href="../../../../../../doc/html/spirit/structure/include.html" target="_top">Include + Structure</a>. + </p> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h2"></a> + <span><a name="spirit_repository.qi_components.directives.seek.namespace"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.namespace">Namespace</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup><col></colgroup> +<thead><tr><th> + <p> + Name + </p> + </th></tr></thead> +<tbody><tr><td> + <p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">seek</span></code> + </p> + </td></tr></tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h3"></a> + <span><a name="spirit_repository.qi_components.directives.seek.model_of"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.model_of">Model + of</a> + </h6> +<div class="blockquote"><blockquote class="blockquote"><p> + <a href="../../../../../../doc/html/spirit/qi/reference/parser_concepts/unaryparser.html" target="_top"><code class="computeroutput"><span class="identifier">UnaryParser</span></code></a> + </p></blockquote></div> +<div class="variablelist"> +<p class="title"><b>Notation</b></p> +<dl> +<dt><span class="term"><code class="computeroutput"><span class="identifier">a</span></code></span></dt> +<dd><p> + A <a href="../../../../../../doc/html/spirit/qi/reference/parser_concepts/parser.html" target="_top"><code class="computeroutput"><span class="identifier">Parser</span></code></a>. + </p></dd> +</dl> +</div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h4"></a> + <span><a name="spirit_repository.qi_components.directives.seek.expression_semantics"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.expression_semantics">Expression + Semantics</a> + </h6> +<p> + Semantics of an expression is defined only where it differs from, or is + not defined in <a href="../../../../../../doc/html/spirit/qi/reference/parser_concepts/unaryparser.html" target="_top"><code class="computeroutput"><span class="identifier">UnaryParser</span></code></a>. + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">seek</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Advances until the parser <code class="computeroutput"><span class="identifier">a</span></code> + matches. + </p> + </td> +</tr></tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h5"></a> + <span><a name="spirit_repository.qi_components.directives.seek.attributes"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.attributes">Attributes</a> + </h6> +<p> + See <a href="../../../../../../doc/html/spirit/qi/quick_reference/compound_attribute_rules.html#spirit.qi.quick_reference.compound_attribute_rules.notation" target="_top">Compound + Attribute Notation</a>. + </p> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Attribute + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">seek</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">--></span> <span class="identifier">seek</span><span class="special">[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">A</span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="identifier">seek</span><span class="special">[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">Unused</span></pre> +<p> + </p> + </td> +</tr></tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h6"></a> + <span><a name="spirit_repository.qi_components.directives.seek.complexity"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.complexity">Complexity</a> + </h6> +<div class="blockquote"><blockquote class="blockquote"><p> + The overall complexity is defined by the complexity of its subject parser. + The complexity of <code class="computeroutput"><span class="identifier">seek</span></code> + itself is O(N), where N is the number of unsuccessful matches. + </p></blockquote></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>seeking sequence with skipping</strong></span> + </p> +<p> + Using <code class="computeroutput"><span class="identifier">seek</span><span class="special">[</span><span class="identifier">a</span> <span class="special">>></span> + <span class="identifier">b</span><span class="special">]</span></code> + with skipping is inefficient, because when sequence fails, the backtracked + position is non-skipped. The solution is to ensure the input will always + be pre-skipped, for example: +</p> +<pre class="programlisting"><span class="identifier">seek</span><span class="special">[</span><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">skip</span><span class="special">[</span><span class="identifier">a</span> <span class="special">>></span> <span class="identifier">b</span><span class="special">]]]</span> +</pre> +<p> + does the trick. + </p> +</td></tr> +</table></div> +<h6> +<a name="spirit_repository.qi_components.directives.seek.h7"></a> + <span><a name="spirit_repository.qi_components.directives.seek.example"></a></span><a class="link" href="seek.html#spirit_repository.qi_components.directives.seek.example">Example</a> + </h6> +<p> + The following example shows a simple use case of the <code class="computeroutput"><span class="identifier">seek</span><span class="special">[]</span></code> directive, parsing C-style comment. (For + the full source of the example, see <a href="../../../../../example/qi/seek.cpp" target="_top">seek.cpp</a>) + </p> +<p> + Some namespace aliases: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">qi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + The input string and its iterators: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">(</span><span class="string">"/*C-style comment*/"</span><span class="special">);</span> +<span class="identifier">iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> +<span class="identifier">iterator</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> +</pre> +<p> + </p> +<p> + Parsing and showing the result: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">it</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="string">"/*"</span> <span class="special">>></span> <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">seek</span><span class="special">[</span><span class="string">"*/"</span><span class="special">]))</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------------- \n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing succeeded.\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"---------------------------------\n"</span><span class="special">;</span> +<span class="special">}</span> +<span class="keyword">else</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------------- \n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Unterminated /* comment.\n"</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"-------------------------------- \n"</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="kwd.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal.html new file mode 100755 index 0000000000..9fb912e466 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal.html @@ -0,0 +1,46 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Parser Non-terminals</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../qi_components.html" title="Qi Components"> +<link rel="prev" href="directives/seek.html" title="Qi Seek Parser Directive"> +<link rel="next" href="nonterminal/subrule.html" title="Qi subrules"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="directives/seek.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.qi_components.nonterminal"></a><a class="link" href="nonterminal.html" title="Qi Parser Non-terminals">Qi Parser + Non-terminals</a> +</h3></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="nonterminal/subrule.html">Qi + subrules</a></span></dt></dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="directives/seek.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html new file mode 100755 index 0000000000..d21f182115 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html @@ -0,0 +1,787 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi subrules</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../nonterminal.html" title="Qi Parser Non-terminals"> +<link rel="prev" href="../nonterminal.html" title="Qi Parser Non-terminals"> +<link rel="next" href="../operators.html" title="Qi Parser Operators"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../operators.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.nonterminal.subrule"></a><a class="link" href="subrule.html" title="Qi subrules">Qi + subrules</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h0"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.description"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">subrule</span></code> + is a component allowing to create a named parser, and to refer to it by + name -- much like rules and grammars. It is in fact a fully static version + of the rule. + </p> +<p> + The strength of subrules is performance. Replacing some rules with subrules + can make a parser slightly faster (see <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.performance">Performance</a> + below for measurements). The reason is that subrules allow aggressive inlining + by the C++ compiler, whereas the implementation of rules is based on a + virtual function call which, depending on the compiler, can have some run-time + overhead and stop inlining. + </p> +<p> + The weaknesses of subrules are: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + subrules can only be defined and used within the same parser expression. + A subrule cannot be defined at one location, and then used in another + location. + </li> +<li class="listitem"> + subrules put a massive strain on the C++ compiler. They increase compile + times and memory usage during compilation, and also increase the risk + of hitting compiler limits and/or bugs. + </li> +</ul></div> +<p> +</p> +<pre class="programlisting"><span class="identifier">entry</span> <span class="special">=</span> <span class="special">(</span> + <span class="identifier">expression</span> <span class="special">=</span> + <span class="identifier">term</span> + <span class="special">>></span> <span class="special">*(</span> <span class="special">(</span><span class="char">'+'</span> <span class="special">>></span> <span class="identifier">term</span><span class="special">)</span> + <span class="special">|</span> <span class="special">(</span><span class="char">'-'</span> <span class="special">>></span> <span class="identifier">term</span><span class="special">)</span> + <span class="special">)</span> + + <span class="special">,</span> <span class="identifier">term</span> <span class="special">=</span> + <span class="identifier">factor</span> + <span class="special">>></span> <span class="special">*(</span> <span class="special">(</span><span class="char">'*'</span> <span class="special">>></span> <span class="identifier">factor</span><span class="special">)</span> + <span class="special">|</span> <span class="special">(</span><span class="char">'/'</span> <span class="special">>></span> <span class="identifier">factor</span><span class="special">)</span> + <span class="special">)</span> + + <span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> + <span class="identifier">uint_</span> + <span class="special">|</span> <span class="char">'('</span> <span class="special">>></span> <span class="identifier">expression</span> <span class="special">>></span> <span class="char">')'</span> + <span class="special">|</span> <span class="special">(</span><span class="char">'-'</span> <span class="special">>></span> <span class="identifier">factor</span><span class="special">)</span> + <span class="special">|</span> <span class="special">(</span><span class="char">'+'</span> <span class="special">>></span> <span class="identifier">factor</span><span class="special">)</span> +<span class="special">);</span> +</pre> +<p> + </p> +<p> + The example above can be found here: <a href="../../../../../example/qi/calc1_sr.cpp" target="_top">../../example/qi/calc1_sr.cpp</a> + </p> +<p> + As shown in this code snippet (an extract from the calc1_sr example), subrules + can be freely mixed with rules and grammars. Here, a group of 3 subrules + (<code class="computeroutput"><span class="identifier">expression</span></code>, <code class="computeroutput"><span class="identifier">term</span></code>, <code class="computeroutput"><span class="identifier">factor</span></code>) + is assigned to a rule (named <code class="computeroutput"><span class="identifier">entry</span></code>). + This means that parts of a parser can use subrules (typically the innermost, + most performance-critical parts), whereas the rest can use rules and grammars. + </p> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h1"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.header"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/nonterminal/subrule.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h2"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.synopsis__declaration_"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.synopsis__declaration_">Synopsis + (declaration)</a> + </h6> +<pre class="programlisting"><span class="identifier">subrule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">,</span> <span class="identifier">A2</span><span class="special">></span> <span class="identifier">sr</span><span class="special">(</span><span class="identifier">name</span><span class="special">);</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h3"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.parameters__declaration_"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.parameters__declaration_">Parameters + (declaration)</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">ID</span></code> + </p> + </td> +<td> + <p> + Required numeric argument. Gives the subrule a unique 'identification + tag'. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">A1</span></code>, <code class="computeroutput"><span class="identifier">A2</span></code> + </p> + </td> +<td> + <p> + Optional types, can be specified in any order. Can be one of + 1. signature, 2. locals (see rules reference for more information + on those parameters). + </p> + <p> + Note that the skipper type need not be specified in the parameters, + unlike with grammars and rules. Subrules will automatically use + the skipper type which is in effect when they are invoked. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">name</span></code> + </p> + </td> +<td> + <p> + Optional string. Gives the subrule a name, useful for debugging + and error handling. + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h4"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.synopsis__usage_"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.synopsis__usage_">Synopsis + (usage)</a> + </h6> +<p> + Subrules are defined and used within groups, typically (and by convention) + enclosed inside parentheses. + </p> +<pre class="programlisting"><span class="comment">// Group containing N subrules</span> +<span class="special">(</span> + <span class="identifier">sr1</span> <span class="special">=</span> <span class="identifier">expr1</span> + <span class="special">,</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="identifier">expr2</span> + <span class="special">,</span> <span class="special">...</span> <span class="comment">// Any number of subrules</span> +<span class="special">}</span> +</pre> +<p> + The IDs of all subrules defined within the same group must be different. + It is an error to define several subrules with the same ID (or to define + the same subrule multiple times) in the same group. + </p> +<pre class="programlisting"><span class="comment">// Auto-subrules and inherited attributes</span> +<span class="special">(</span> + <span class="identifier">srA</span> <span class="special">%=</span> <span class="identifier">exprA</span> <span class="special">>></span> <span class="identifier">srB</span> <span class="special">>></span> <span class="identifier">srC</span><span class="special">(</span><span class="identifier">c1</span><span class="special">,</span> <span class="identifier">c2</span><span class="special">,</span> <span class="special">...)</span> <span class="comment">// Arguments to subrule srC</span> + <span class="special">,</span> <span class="identifier">srB</span> <span class="special">%=</span> <span class="identifier">exprB</span> + <span class="special">,</span> <span class="identifier">srC</span> <span class="special">=</span> <span class="identifier">exprC</span> + <span class="special">,</span> <span class="special">...</span> +<span class="special">)(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...)</span> <span class="comment">// Arguments to group, i.e. to start subrule srA</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h5"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.parameters__usage_"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.parameters__usage_">Parameters + (usage)</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">sr1</span></code>, <code class="computeroutput"><span class="identifier">sr2</span></code> + </p> + </td> +<td> + <p> + Subrules with different IDs. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">expr1</span></code>, <code class="computeroutput"><span class="identifier">expr2</span></code> + </p> + </td> +<td> + <p> + Parser expressions. Can include <code class="computeroutput"><span class="identifier">sr1</span></code> + and <code class="computeroutput"><span class="identifier">sr2</span></code>, as well + as any other valid parser expressions. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srA</span></code> + </p> + </td> +<td> + <p> + Subrule with a synthesized attribute and inherited attributes. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srB</span></code> + </p> + </td> +<td> + <p> + Subrule with a synthesized attribute. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">srC</span></code> + </p> + </td> +<td> + <p> + Subrule with inherited attributes. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">exprA</span></code>, <code class="computeroutput"><span class="identifier">exprB</span></code>, <code class="computeroutput"><span class="identifier">exprC</span></code> + </p> + </td> +<td> + <p> + Parser expressions. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">a1</span></code>, <code class="computeroutput"><span class="identifier">a2</span></code> + </p> + </td> +<td> + <p> + Arguments passed to the subrule group. They are passed as inherited + attributes to the group's start subrule, <code class="computeroutput"><span class="identifier">srA</span></code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">c1</span></code>, <code class="computeroutput"><span class="identifier">c2</span></code> + </p> + </td> +<td> + <p> + Arguments passed as inherited attributes to subrule <code class="computeroutput"><span class="identifier">srC</span></code>. + </p> + </td> +</tr> +</tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h6"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.groups"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.groups">Groups</a> + </h6> +<p> + A subrule group (a set of subrule definitions) is a parser, which can be + used anywhere in a parser expression (in assignments to rules, as well + as directly in arguments to functions such as <code class="computeroutput"><span class="identifier">parse</span></code>). + In a group, parsing proceeds from the start subrule, which is the first + (topmost) subrule defined in that group. In the two groups in the synopsis + above, <code class="computeroutput"><span class="identifier">sr1</span></code> and <code class="computeroutput"><span class="identifier">srA</span></code> are the start subrules respectively + -- for example when the first subrule group is called forth, the <code class="computeroutput"><span class="identifier">sr1</span></code> subrule is called. + </p> +<p> + A subrule can only be used in a group which defines it. Groups can be viewed + as scopes: a definition of a subrule is limited to its enclosing group. + </p> +<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*></span> <span class="identifier">r1</span><span class="special">,</span> <span class="identifier">r2</span><span class="special">,</span> <span class="identifier">r3</span><span class="special">;</span> +<span class="identifier">subrule</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="identifier">sr1</span><span class="special">;</span> +<span class="identifier">subrule</span><span class="special"><</span><span class="number">2</span><span class="special">></span> <span class="identifier">sr2</span><span class="special">;</span> + +<span class="identifier">r1</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special">>></span> <span class="identifier">int_</span> <span class="special">)</span> <span class="comment">// First group in r1.</span> + <span class="special">>></span> <span class="special">(</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">sr1</span> <span class="special">)</span> <span class="comment">// Second group in r1.</span> + <span class="comment">// ^^^</span> + <span class="comment">// DOES NOT COMPILE: sr1 is not defined in this</span> + <span class="comment">// second group, it cannot be used here (its</span> + <span class="comment">// previous definition is out of scope).</span> +<span class="special">;</span> + +<span class="identifier">r2</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special">>></span> <span class="identifier">int_</span> <span class="special">)</span> <span class="comment">// Only group in r2.</span> + <span class="special">>></span> <span class="identifier">sr1</span> + <span class="comment">// ^^^</span> + <span class="comment">// DOES NOT COMPILE: not in a subrule group,</span> + <span class="comment">// sr1 cannot be used here (here too, its</span> + <span class="comment">// previous definition is out of scope).</span> +<span class="special">;</span> + +<span class="identifier">r3</span> <span class="special">=</span> + <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'x'</span> <span class="special">>></span> <span class="identifier">double_</span> <span class="special">)</span> <span class="comment">// Another group. The same subrule `sr1`</span> + <span class="comment">// can have another, independent</span> + <span class="comment">// definition in this group.</span> +<span class="special">;</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h7"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.attributes"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.attributes">Attributes</a> + </h6> +<p> + A subrule has the same behavior as a rule with respect to attributes. In + particular: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + the type of its synthesized attribute is the one specified in the subrule's + signature, if any. Otherwise it is <code class="computeroutput"><span class="identifier">unused_type</span></code>. + </li> +<li class="listitem"> + the types of its inherited attributes are the ones specified in the + subrule's signature, if any. Otherwise the subrule has no inherited + attributes. + </li> +<li class="listitem"> + an auto-subrule can be defined by assigning it with the <code class="computeroutput"><span class="special">%=</span></code> syntax. In this case, the RHS parser's + attribute is automatically propagated to the subrule's synthesized + attribute. + </li> +<li class="listitem"> + the Phoenix placeholders <code class="computeroutput"><span class="identifier">_val</span></code>, + <code class="computeroutput"><span class="identifier">_r1</span></code>, <code class="computeroutput"><span class="identifier">_r2</span></code>, ... are available to refer to + the subrule's synthesized and inherited attributes, if present. + </li> +</ul></div> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h8"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.locals"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.locals">Locals</a> + </h6> +<p> + A subrule has the same behavior as a rule with respect to locals. In particular, + the Phoenix placeholders <code class="computeroutput"><span class="identifier">_a</span></code>, + <code class="computeroutput"><span class="identifier">_b</span></code>, ... are available to + refer to the subrule's locals, if present. + </p> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h9"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.example"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.example">Example</a> + </h6> +<p> + Some includes: + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + Some using declarations: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">qi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">ascii</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + A grammar containing only one rule, defined with a group of 5 subrules: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span> + <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">mini_xml_grammar</span><span class="special">()</span> + <span class="special">:</span> <span class="identifier">mini_xml_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">entry</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</span> + + <span class="identifier">entry</span> <span class="special">%=</span> <span class="special">(</span> + <span class="identifier">xml</span> <span class="special">%=</span> + <span class="identifier">start_tag</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">*</span><span class="identifier">node</span> + <span class="special">>></span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> + + <span class="special">,</span> <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span> + + <span class="special">,</span> <span class="identifier">text</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'<'</span><span class="special">)]</span> + + <span class="special">,</span> <span class="identifier">start_tag</span> <span class="special">%=</span> + <span class="char">'<'</span> + <span class="special">>></span> <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span> + <span class="special">>></span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'>'</span><span class="special">)]</span> + <span class="special">>></span> <span class="char">'>'</span> + + <span class="special">,</span> <span class="identifier">end_tag</span> <span class="special">%=</span> + <span class="string">"</"</span> + <span class="special">>></span> <span class="identifier">string</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span> + <span class="special">>></span> <span class="char">'>'</span> + <span class="special">);</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">></span> <span class="identifier">entry</span><span class="special">;</span> + + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">0</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">></span> <span class="special">></span> <span class="identifier">xml</span><span class="special">;</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">()></span> <span class="identifier">node</span><span class="special">;</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">2</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">()></span> <span class="identifier">text</span><span class="special">;</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">3</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">()></span> <span class="identifier">start_tag</span><span class="special">;</span> + <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special"><</span><span class="number">4</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)></span> <span class="identifier">end_tag</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + The definitions of the <code class="computeroutput"><span class="identifier">mini_xml</span></code> + and <code class="computeroutput"><span class="identifier">mini_xml_node</span></code> data + structures are not shown here. The full example above can be found here: + <a href="../../../../../example/qi/mini_xml2_sr.cpp" target="_top">../../example/qi/mini_xml2_sr.cpp</a> + </p> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h10"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.performance"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.performance">Performance</a> + </h6> +<p> + This table compares run-time and compile-time performance when converting + examples to subrules, with various compilers. + </p> +<div class="table"> +<a name="spirit_repository.qi_components.nonterminal.subrule.t0"></a><p class="title"><b>Table 2. Subrules performance</b></p> +<div class="table-contents"><table class="table" summary="Subrules performance"> +<colgroup> +<col> +<col> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Example + </p> + </th> +<th> + <p> + Compiler + </p> + </th> +<th> + <p> + Speed (run-time) + </p> + </th> +<th> + <p> + Time (compile-time) + </p> + </th> +<th> + <p> + Memory (compile-time) + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + calc1_sr + </p> + </td> +<td> + <p> + gcc 4.4.1 + </p> + </td> +<td> + <p> + +6% + </p> + </td> +<td> + <p> + n/a + </p> + </td> +<td> + <p> + n/a + </p> + </td> +</tr> +<tr> +<td> + <p> + calc1_sr + </p> + </td> +<td> + <p> + Visual C++ 2008 (VC9) + </p> + </td> +<td> + <p> + +5% + </p> + </td> +<td> + <p> + n/a + </p> + </td> +<td> + <p> + n/a + </p> + </td> +</tr> +<tr> +<td> + <p> + mini_xml2_sr + </p> + </td> +<td> + <p> + gcc 3.4.6 + </p> + </td> +<td> + <p> + -1% + </p> + </td> +<td> + <p> + +54% + </p> + </td> +<td> + <p> + +32% + </p> + </td> +</tr> +<tr> +<td> + <p> + mini_xml2_sr + </p> + </td> +<td> + <p> + gcc 4.1.2 + </p> + </td> +<td> + <p> + +5% + </p> + </td> +<td> + <p> + +58% + </p> + </td> +<td> + <p> + +25% + </p> + </td> +</tr> +<tr> +<td> + <p> + mini_xml2_sr + </p> + </td> +<td> + <p> + gcc 4.4.1 + </p> + </td> +<td> + <p> + +8% + </p> + </td> +<td> + <p> + +20% + </p> + </td> +<td> + <p> + +14% + </p> + </td> +</tr> +<tr> +<td> + <p> + mini_xml2_sr + </p> + </td> +<td> + <p> + Visual C++ 2005 (VC8) SP1 + </p> + </td> +<td> + <p> + +1% + </p> + </td> +<td> + <p> + +33% + </p> + </td> +<td> + <p> + +27% + </p> + </td> +</tr> +<tr> +<td> + <p> + mini_xml2_sr + </p> + </td> +<td> + <p> + Visual C++ 2008 (VC9) + </p> + </td> +<td> + <p> + +9% + </p> + </td> +<td> + <p> + +52% + </p> + </td> +<td> + <p> + +40% + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><p> + The columns are: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + <span class="bold"><strong>Speed (run-time)</strong></span>: speed-up of the + parser resulting from the use of subrules (higher is better). + </li> +<li class="listitem"> + <span class="bold"><strong>Time (compile-time)</strong></span>: increase in compile + time (lower is better). + </li> +<li class="listitem"> + <span class="bold"><strong>Memory (compile-time)</strong></span>: increase in + compiler memory usage (lower is better). + </li> +</ul></div> +<h6> +<a name="spirit_repository.qi_components.nonterminal.subrule.h11"></a> + <span><a name="spirit_repository.qi_components.nonterminal.subrule.notes"></a></span><a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.notes">Notes</a> + </h6> +<p> + Subrules push the C++ compiler hard. A group of subrules is a single C++ + expression. Current C++ compilers cannot handle very complex expressions + very well. One restricting factor is the typical compiler's limit on template + recursion depth. Some, but not all, compilers allow this limit to be configured. + </p> +<p> + g++'s maximum can be set using a compiler flag: <code class="computeroutput"><span class="special">-</span><span class="identifier">ftemplate</span><span class="special">-</span><span class="identifier">depth</span></code>. Set this appropriately if you + use relatively complex subrules. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../operators.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators.html new file mode 100755 index 0000000000..d63f6c7c32 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators.html @@ -0,0 +1,46 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Parser Operators</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../qi_components.html" title="Qi Components"> +<link rel="prev" href="nonterminal/subrule.html" title="Qi subrules"> +<link rel="next" href="operators/keyword_list.html" title="Keyword List Operator"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="operators/keyword_list.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.qi_components.operators"></a><a class="link" href="operators.html" title="Qi Parser Operators">Qi Parser + Operators</a> +</h3></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="operators/keyword_list.html">Keyword + List Operator</a></span></dt></dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="nonterminal/subrule.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="operators/keyword_list.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators/keyword_list.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators/keyword_list.html new file mode 100755 index 0000000000..f4568b6b81 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/operators/keyword_list.html @@ -0,0 +1,364 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Keyword List Operator</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../operators.html" title="Qi Parser Operators"> +<link rel="prev" href="../operators.html" title="Qi Parser Operators"> +<link rel="next" href="../../karma_components.html" title="Karma Components"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../operators.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../operators.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../karma_components.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.operators.keyword_list"></a><a class="link" href="keyword_list.html" title="Keyword List Operator">Keyword + List Operator</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h0"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.description"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.description">Description</a> + </h6> +<p> + The keyword list operator, <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="string">"k1"</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"k2"</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]</span></code>, + works tightly with the kwd, ikwd directives to effeciently match keyword + lists. As long as one of the keywords specified through the kwd or ikwd + directive matches, the keyword will be immediatly followed by the the keyword's + associated subject parser. The parser will continue parsing input as long + as the one of the keywords and it's associated parser succeed. Writing + : (kwd("k1")[a] / kwd("k2")[b] / ... ) is equivalent + to: *( "k1" > a | "k2" > b ... ). + </p> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h1"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.header"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/operator/keywords.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_keywords</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h2"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.expression_semantics"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.expression_semantics">Expression + Semantics</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> + Match <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)</span> + <span class="special">></span> <span class="identifier">a</span></code> + or <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)</span> + <span class="special">></span> <span class="identifier">b</span></code>, + equivalent to <code class="computeroutput"><span class="identifier">lit</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)</span> <span class="special">></span> + <span class="identifier">a</span> <span class="special">|</span> + <span class="identifier">lit</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)</span> + <span class="special">></span> <span class="identifier">b</span></code> + </p> + </td> +</tr></tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h3"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.attributes"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.attributes">Attributes</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Attribute + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">kwd</span><span class="special">(</span><span class="string">"k1"</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"k2"</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]</span></code> + </p> + </td> +<td> + <p> +</p> +<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">B</span> <span class="special">--></span> <span class="special">(</span><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]):</span> <span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="special">(</span><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]):</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">B</span> <span class="special">--></span> <span class="special">(</span><span class="identifier">kwd</span><span class="special">(</span><span class="string">"k1"</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]):</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">B</span><span class="special">></span> +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">Unused</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">Unused</span> <span class="special">--></span> <span class="special">(</span><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]):</span> <span class="identifier">Unused</span> + +<span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">A</span> <span class="special">-->(</span><span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k1</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]</span> <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="identifier">k2</span><span class="special">)[</span><span class="identifier">b</span><span class="special">]):</span> <span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span></pre> +<p> + </p> + </td> +</tr></tbody> +</table></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + The keyword list parser works tightly with the kwd and ikwd directives + and can't be used without it. A compile time error will warn you of any + mistakes. This parser collects all the kwd directives and extracts the + keyword literals from the directives to internaly build a Ternary Search + Tree (TST) to effectively parse the keywords. Because you we can't mix + character types inside a TST you must take care not to mix wide strings + with normal strings in the keyword you supply to a keyword list. Should + it happen the compiler will trap the mistake for you. + </p></td></tr> +</table></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + The kwd directive also works a bit like the repeat directive and can + be used to formulate additional contraints on the number of times a keyword + can occur while parsing a keyword list. + </p></td></tr> +</table></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + The kwd and ikwd directives can be mixed inside a keyword list. This + has however a small overhead and should be avoided when possible. + </p></td></tr> +</table></div> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h4"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.complexity"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.complexity">Complexity</a> + </h6> +<div class="blockquote"><blockquote class="blockquote"> +<p> + The overall complexity of the keyword list parser is defined by the sum + of the complexities of its elements. The complexity of the keyword list + itself is determined by the complexity of the internal TST contents : + </p> +<p> + O(log n+k) + </p> +<p> + Where k is the length of the string to be searched in a TST with n strings. + </p> +</blockquote></div> +<h6> +<a name="spirit_repository.qi_components.operators.keyword_list.h5"></a> + <span><a name="spirit_repository.qi_components.operators.keyword_list.example"></a></span><a class="link" href="keyword_list.html#spirit_repository.qi_components.operators.keyword_list.example">Example</a> + </h6> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + The test harness for the example(s) below is presented in the <a href="../../../../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.examples" target="_top">Basics + Examples</a> section. + </p></td></tr> +</table></div> +<p> + Declare a small data structure representing a person: + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Data structure definitions to test the kwd directive</span> +<span class="comment">// and the keywords list operator</span> + +<span class="keyword">struct</span> <span class="identifier">person</span> <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span> + <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span> + <span class="keyword">double</span> <span class="identifier">size</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">></span> <span class="identifier">favorite_colors</span><span class="special">;</span> + +<span class="special">};</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">person</span> <span class="special">&</span><span class="identifier">p</span><span class="special">)</span> +<span class="special">{</span> + <span class="identifier">os</span><span class="special"><<</span><span class="string">"Person : "</span><span class="special"><<</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">name</span><span class="special"><<</span><span class="string">", "</span><span class="special"><<</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">age</span><span class="special"><<</span><span class="string">", "</span><span class="special"><<</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">size</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">favorite_colors</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">favorite_colors</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream_iterator</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>(</span><span class="identifier">os</span><span class="special">,</span><span class="string">"\n"</span><span class="special">));</span> + <span class="keyword">return</span> <span class="identifier">os</span><span class="special">;</span> +<span class="special">}</span> + +<span class="identifier">BOOST_FUSION_ADAPT_STRUCT</span><span class="special">(</span> <span class="identifier">person</span><span class="special">,</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">name</span><span class="special">)</span> + <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">age</span><span class="special">)</span> + <span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">size</span><span class="special">)</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>,</span> <span class="identifier">favorite_colors</span><span class="special">)</span> +<span class="special">)</span> +</pre> +<p> + </p> +<p> + Some using declarations: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">kwd</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">inf</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + Now let's declare a keyword parser: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">no_constraint_person_rule</span> <span class="special">%=</span> + <span class="identifier">kwd</span><span class="special">(</span><span class="string">"name"</span><span class="special">)[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">parse_string</span> <span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"age"</span><span class="special">)</span> <span class="special">[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">int_</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"size"</span><span class="special">)</span> <span class="special">[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">double_</span> <span class="special">></span> <span class="char">'m'</span><span class="special">]</span> + <span class="special">;</span> +</pre> +<p> + </p> +<p> + A couple of input string variations run on the same parser: + </p> +<p> + Parsing a keyword list: + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Let's declare a small list of people for which we want to collect information.</span> +<span class="identifier">person</span> <span class="identifier">John</span><span class="special">,</span><span class="identifier">Mary</span><span class="special">,</span><span class="identifier">Mike</span><span class="special">,</span><span class="identifier">Hellen</span><span class="special">,</span><span class="identifier">Johny</span><span class="special">;</span> +<span class="identifier">test_phrase_parser_attr</span><span class="special">(</span> + <span class="string">"name = \"John\" \n age = 10 \n size = 1.69m "</span> + <span class="special">,</span><span class="identifier">no_constraint_person_rule</span> + <span class="special">,</span><span class="identifier">John</span><span class="special">);</span> <span class="comment">// full in orginal order</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">John</span><span class="special">;</span> + +<span class="identifier">test_phrase_parser_attr</span><span class="special">(</span> + <span class="string">"age = 10 \n size = 1.69m \n name = \"Mary\""</span> + <span class="special">,</span><span class="identifier">no_constraint_person_rule</span> + <span class="special">,</span><span class="identifier">Mary</span><span class="special">);</span> <span class="comment">// keyword oder doesn't matter</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">Mary</span><span class="special">;</span> + +<span class="identifier">test_phrase_parser_attr</span><span class="special">(</span> + <span class="string">"size = 1.69m \n name = \"Mike\" \n age = 10 "</span> + <span class="special">,</span><span class="identifier">no_constraint_person_rule</span> + <span class="special">,</span><span class="identifier">Mike</span><span class="special">);</span> <span class="comment">// still the same result</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">Mike</span><span class="special">;</span> +</pre> +<p> + </p> +<p> + The code above will print: + </p> +<pre class="programlisting">Person : John, 10, 1.69 +Person : Mary, 10, 1.69 +Person : Mike, 10, 1.69 +</pre> +<p> + Now let's delcare a parser with some occurence constraints: + </p> +<p> + The parser definition below uses the kwd directive occurence constraint + variants to make sure that the name and age keyword occur only once and + allows the favorite color entry to appear 0 or more times. + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">constraint_person_rule</span> <span class="special">%=</span> + <span class="identifier">kwd</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span><span class="number">1</span><span class="special">)</span> <span class="special">[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">parse_string</span> <span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"age"</span> <span class="special">,</span><span class="number">1</span><span class="special">)</span> <span class="special">[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">int_</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"size"</span> <span class="special">,</span><span class="number">1</span><span class="special">)</span> <span class="special">[</span><span class="char">'='</span> <span class="special">></span> <span class="identifier">double_</span> <span class="special">></span> <span class="char">'m'</span><span class="special">]</span> + <span class="special">/</span> <span class="identifier">kwd</span><span class="special">(</span><span class="string">"favorite color"</span><span class="special">,</span><span class="number">0</span><span class="special">,</span><span class="identifier">inf</span><span class="special">)</span> <span class="special">[</span> <span class="char">'='</span> <span class="special">></span> <span class="identifier">parse_string</span> <span class="special">]</span> + <span class="special">;</span> +</pre> +<p> + </p> +<p> + And see how it works in these two cases: + </p> +<p> +</p> +<pre class="programlisting"> <span class="comment">// Here all the give constraint are resepected : parsing will succeed.</span> + <span class="identifier">test_phrase_parser_attr</span><span class="special">(</span> + <span class="string">"name = \"Hellen\" \n age = 10 \n size = 1.80m \n favorite color = \"blue\" \n favorite color = \"green\" "</span> + <span class="special">,</span><span class="identifier">constraint_person_rule</span> + <span class="special">,</span><span class="identifier">Hellen</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">Hellen</span><span class="special">;</span> + +<span class="comment">// Parsing this string will fail because the age and size minimum occurence requirements aren't met.</span> +<span class="identifier">test_phrase_parser_attr</span><span class="special">(</span> + <span class="string">"name = \"Johny\" \n favorite color = \"blue\" \n favorite color = \"green\" "</span> + <span class="special">,</span><span class="identifier">constraint_person_rule</span> + <span class="special">,</span><span class="identifier">Johny</span> <span class="special">);</span> +</pre> +<p> + </p> +<p> + Parsing the first string will succeed but fail for the second string as + the occurence constraints aren't met. This code should print: + </p> +<pre class="programlisting">Person : Hellen, 10, 1.8 +blue +green +</pre> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../operators.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../operators.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../karma_components.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive.html new file mode 100755 index 0000000000..e0eae41fc7 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive.html @@ -0,0 +1,50 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi Parser Primitives</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../qi_components.html" title="Qi Components"> +<link rel="prev" href="../qi_components.html" title="Qi Components"> +<link rel="next" href="primitive/advance.html" title="Qi advance Parser"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../qi_components.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="primitive/advance.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.qi_components.primitive"></a><a class="link" href="primitive.html" title="Qi Parser Primitives">Qi Parser + Primitives</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="primitive/advance.html">Qi + advance Parser</a></span></dt> +<dt><span class="section"><a href="primitive/flush_multi_pass.html">Qi + flush_multi_pass parser</a></span></dt> +</dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../qi_components.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_components.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="primitive/advance.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/advance.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/advance.html new file mode 100755 index 0000000000..d445a33a38 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/advance.html @@ -0,0 +1,304 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi advance Parser</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../primitive.html" title="Qi Parser Primitives"> +<link rel="prev" href="../primitive.html" title="Qi Parser Primitives"> +<link rel="next" href="flush_multi_pass.html" title="Qi flush_multi_pass parser"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../primitive.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../primitive.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="flush_multi_pass.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.primitive.advance"></a><a class="link" href="advance.html" title="Qi advance Parser">Qi + advance Parser</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h0"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.description"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">advance</span></code> + is a primitive parser component allowing the parser to skip (advance) through + a specified number of iterations without performing unnecessary work: + </p> +<pre class="programlisting"><span class="identifier">advance</span><span class="special">(</span><span class="identifier">distance</span><span class="special">)</span> +</pre> +<p> + The most obvious existing alternative to this, the <code class="computeroutput"><span class="identifier">repeat</span></code> + directive, will cause the parser to advance one iterator at a time while + usually performing operations at each step. In some cases that work is + unnecessary, as in the case where large binary objects are being parsed. + Take, for example, the following binary data: + </p> +<pre class="programlisting">00 00 00 01 77 fc b4 51 0a b3 b7 ... 1e 60 70 b6 00 00 01 00 +</pre> +<p> + If the first 4 bytes are a little-endian 32-bit integer describing the + length of the subsequent data, but the data itself is not relevant to parsing, + then the repeat directive would cause all of the subsequent 16 MB of data + to be consumed one byte at a time while generating page faults or other + superfluous I/O. If the value is large, as it is in this case, the parser + becomes very slow. + </p> +<pre class="programlisting"><span class="identifier">little_dword</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> <span class="special">>></span> <span class="identifier">repeat</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)[</span><span class="identifier">byte_</span><span class="special">]</span> <span class="special">>></span> <span class="identifier">little_dword</span><span class="special">...</span> +</pre> +<p> + The <code class="computeroutput"><span class="identifier">advance</span></code> parser component + solves this problem by performing as little work as possible to advance + the parser's iterator, and will optimize for the case of random-access + iterators by advancing directly to the desired relative iterator position. + </p> +<pre class="programlisting"><span class="identifier">little_dword</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> <span class="special">>></span> <span class="identifier">advance</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">little_dword</span><span class="special">...</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h1"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.header"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/primitive/advance.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_advance</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h2"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.synopsis"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.synopsis">Synopsis</a> + </h6> +<pre class="programlisting"><span class="identifier">advance</span><span class="special">(</span><span class="identifier">distance</span><span class="special">)</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h3"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.parameters"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.parameters">Parameters</a> + </h6> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Parameter + </p> + </th> +<th> + <p> + Description + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> + 'distance' + </p> + </td> +<td> + <p> + The distance that the iterator shall be advanced + </p> + </td> +</tr></tbody> +</table></div> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h4"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.attribute"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.attribute">Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">advance</span></code> component exposes + no attribute (the exposed attribute type is <code class="computeroutput"><span class="identifier">unused_type</span></code>): + </p> +<pre class="programlisting"><span class="identifier">advance</span> <span class="special">--></span> <span class="identifier">unused</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h5"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.example"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.example">Example</a> + </h6> +<p> + The following example shows simple use cases of the <code class="computeroutput"><span class="identifier">advance</span></code> + component. We will illustrate its usage by generating parsers for some + binary data (for the full example code see <a href="../../../../../example/qi/advance.cpp" target="_top">advance.cpp</a>) + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h6"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.prerequisites"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.prerequisites">Prerequisites</a> + </h6> +<p> + In addition to the main header file needed to include the core components + implemented in <span class="emphasis"><em>Spirit.Qi</em></span> we add the header file needed + for the new <code class="computeroutput"><span class="identifier">advance</span></code> component. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_advance</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + In order to make the examples below more readable we introduce or use the + following namespaces. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">qi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">advance</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h7"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.setting_up_the_grammar"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.setting_up_the_grammar">Setting + up the Grammar</a> + </h6> +<p> + This is a very simple grammar that recognizes several fields of a binary + stream of data. There are two fields explicitly delimited by a field indicating + the number of bytes that are spanned. They are separated by a literal string. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">advance_grammar</span> <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">></span> +<span class="special">{</span> + <span class="identifier">advance_grammar</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">advance_grammar</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">start</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">byte_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">eoi</span><span class="special">;</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</span> + + <span class="identifier">start</span> + <span class="special">=</span> <span class="identifier">byte_</span> <span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="identifier">advance</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> + <span class="special">>></span> <span class="string">"boost"</span> + <span class="special">>></span> <span class="identifier">byte_</span> <span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span> + <span class="special">>></span> <span class="special">(</span><span class="identifier">advance</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span> <span class="special">|</span> <span class="string">"qi"</span><span class="special">)</span> <span class="comment">// note alternative when advance fails</span> + <span class="special">>></span> <span class="identifier">eoi</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">></span> <span class="identifier">start</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Note that the second binary field may either contain the number of specified + bytes, or the word "qi". If the <code class="computeroutput"><span class="identifier">advance</span></code> + parser component fails to advance the specified number of bytes before + reaching the end of input, it will fail and the parser will attempt to + descend into alternatives. + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h8"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.parsing_a_correctly_delimited_string_of_data"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.parsing_a_correctly_delimited_string_of_data">Parsing + a Correctly-delimited String of Data</a> + </h6> +<p> + The data below is correctly delimited and will thus result in a valid parse. + Note that both random-access and bidirectional iterators are used here. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">unsigned</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">alt1</span><span class="special">[]</span> <span class="special">=</span> +<span class="special">{</span> + <span class="number">5</span><span class="special">,</span> <span class="comment">// number of bytes to advance</span> + <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="comment">// data to advance through</span> + <span class="char">'b'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'s'</span><span class="special">,</span> <span class="char">'t'</span><span class="special">,</span> <span class="comment">// word to parse</span> + <span class="number">2</span><span class="special">,</span> <span class="comment">// number of bytes to advance</span> + <span class="number">11</span><span class="special">,</span> <span class="number">12</span> <span class="comment">// more data to advance through</span> + <span class="comment">// eoi</span> +<span class="special">};</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">alt1_string</span><span class="special">(</span><span class="identifier">alt1</span><span class="special">,</span> <span class="identifier">alt1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="identifier">alt1</span><span class="special">);</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">alt1_list</span><span class="special">(</span><span class="identifier">alt1</span><span class="special">,</span> <span class="identifier">alt1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="identifier">alt1</span><span class="special">);</span> + +<span class="identifier">result</span> <span class="special">=</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">alt1_string</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">alt1_string</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">client</span><span class="special">::</span><span class="identifier">advance_grammar</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">>())</span> + <span class="special">?</span> <span class="string">"succeeded"</span> <span class="special">:</span> <span class="string">"failed"</span><span class="special">;</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing alt1 using random access iterator "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + +<span class="identifier">result</span> <span class="special">=</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">alt1_list</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">alt1_list</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">client</span><span class="special">::</span><span class="identifier">advance_grammar</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">>::</span><span class="identifier">const_iterator</span><span class="special">>())</span> + <span class="special">?</span> <span class="string">"succeeded"</span> <span class="special">:</span> <span class="string">"failed"</span><span class="special">;</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing alt1 using bidirectional iterator "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h9"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.parsing_the_alternative_representation"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.parsing_the_alternative_representation">Parsing + the Alternative Representation</a> + </h6> +<p> + The data below is not correctly delimited, but will correctly parse because + the alternative word "qi" is available. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">unsigned</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">alt2</span><span class="special">[]</span> <span class="special">=</span> +<span class="special">{</span> + <span class="number">2</span><span class="special">,</span> <span class="comment">// number of bytes to advance</span> + <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="comment">// data to advance through</span> + <span class="char">'b'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'s'</span><span class="special">,</span> <span class="char">'t'</span><span class="special">,</span> <span class="comment">// word to parse</span> + <span class="number">4</span><span class="special">,</span> <span class="comment">// number of bytes to advance</span> + <span class="char">'q'</span><span class="special">,</span> <span class="char">'i'</span> <span class="comment">// alternative (advance won't work)</span> + <span class="comment">// eoi</span> +<span class="special">};</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">alt2_string</span><span class="special">(</span><span class="identifier">alt2</span><span class="special">,</span> <span class="identifier">alt2</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="identifier">alt2</span><span class="special">);</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">alt2_list</span><span class="special">(</span><span class="identifier">alt2</span><span class="special">,</span> <span class="identifier">alt2</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="identifier">alt2</span><span class="special">);</span> + +<span class="identifier">result</span> <span class="special">=</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">alt2_string</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">alt2_string</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">client</span><span class="special">::</span><span class="identifier">advance_grammar</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">>())</span> + <span class="special">?</span> <span class="string">"succeeded"</span> <span class="special">:</span> <span class="string">"failed"</span><span class="special">;</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing alt2 using random access iterator "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + +<span class="identifier">result</span> <span class="special">=</span> + <span class="identifier">qi</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">alt2_list</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">alt2_list</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">client</span><span class="special">::</span><span class="identifier">advance_grammar</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">>::</span><span class="identifier">const_iterator</span><span class="special">>())</span> + <span class="special">?</span> <span class="string">"succeeded"</span> <span class="special">:</span> <span class="string">"failed"</span><span class="special">;</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Parsing alt2 using bidirectional iterator "</span> <span class="special"><<</span> <span class="identifier">result</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.advance.h10"></a> + <span><a name="spirit_repository.qi_components.primitive.advance.notes"></a></span><a class="link" href="advance.html#spirit_repository.qi_components.primitive.advance.notes">Notes</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">advance</span></code> parser component + will fail unconditionally on negative values. It will never attempt to + advance the iterator in the reverse direction. + </p> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../primitive.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../primitive.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="flush_multi_pass.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html new file mode 100755 index 0000000000..e87a0a8afe --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html @@ -0,0 +1,204 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Qi flush_multi_pass parser</title> +<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../primitive.html" title="Qi Parser Primitives"> +<link rel="prev" href="advance.html" title="Qi advance Parser"> +<link rel="next" href="../directives.html" title="Qi Parser Directives"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="advance.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../primitive.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../directives.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass"></a><a class="link" href="flush_multi_pass.html" title="Qi flush_multi_pass parser">Qi + flush_multi_pass parser</a> +</h4></div></div></div> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h0"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.description"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.description">Description</a> + </h6> +<p> + The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> + parser is a primitive (pseudo) parser component allowing to clear the internal + buffer of a <code class="computeroutput"><span class="identifier">multi_pass</span></code> + iterator. Clearing the buffer of a <code class="computeroutput"><span class="identifier">multi_pass</span></code> + might be beneficial for grammars where it is clear that no backtracking + can occur. The general syntax for using the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> + is: + </p> +<pre class="programlisting"><span class="identifier">flush_multi_pass</span> +</pre> +<p> + which will call the <code class="computeroutput"><span class="identifier">clear_queue</span><span class="special">()</span></code> member function if the current iterators + are of the type <code class="computeroutput"><span class="identifier">multi_pass</span></code>. + This will cause any buffered data to be erased. This also will invalidate + all other copies of multi_pass and they should not be used. If they are, + an <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">illegal_backtracking</span></code> exception will be + thrown. For all other iterator types this is a no-op. The <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> generates a parser component + which always succeeds and which does not consume any input (very much like + <code class="computeroutput"><span class="identifier">eps</span></code>). + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h1"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.header"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.header">Header</a> + </h6> +<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_flush_multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h2"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.synopsis"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.synopsis">Synopsis</a> + </h6> +<pre class="programlisting"><span class="identifier">flush_multi_pass</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h3"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.parameters"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.parameters">Parameters</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> does + not require any parameters. + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h4"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.attribute"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.attribute">Attribute</a> + </h6> +<p> + The <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> component + exposes no attribute (the exposed attribute type is <code class="computeroutput"><span class="identifier">unused_type</span></code>): + </p> +<pre class="programlisting"><span class="identifier">flush_multi_pass</span> <span class="special">--></span> <span class="identifier">unused</span> +</pre> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h5"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.example"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.example">Example</a> + </h6> +<p> + The following example shows a simple use case of the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> + parser. + </p> +<p> + We will illustrate its usage by generating different comment styles and + a function prototype (for the full example code see here: <a href="../../../../../example/qi/flush_multi_pass.cpp" target="_top">flush_multi_pass.cpp</a>) + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h6"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.prerequisites"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.prerequisites">Prerequisites</a> + </h6> +<p> + In addition to the main header file needed to include the core components + implemented in <span class="emphasis"><em>Spirit.Qi</em></span> we add the header file needed + for the new <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> + parser. + </p> +<p> +</p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_flush_multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + </p> +<p> + To make all the code below more readable we introduce the following namespaces. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">spirit</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">::</span><span class="identifier">flush_multi_pass</span><span class="special">;</span> +</pre> +<p> + </p> +<h6> +<a name="spirit_repository.qi_components.primitive.flush_multi_pass.h7"></a> + <span><a name="spirit_repository.qi_components.primitive.flush_multi_pass.clearing_the_internal_buffer"></a></span><a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.clearing_the_internal_buffer">Clearing + the internal buffer</a> + </h6> +<p> + The example grammar recognizes the (simplified) preprocessor commands + <code class="computeroutput"><span class="preprocessor">#define</span></code> and <code class="computeroutput"><span class="preprocessor">#undef</span></code> both of which are constraint + to a single line. This makes it possible to delete all internal iterator + buffers on each detected line break. This is safe as no backtracking will + occur after any line end. The following code snippet shows the usage of + <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> for this + purpose. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Skipper</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">preprocessor</span> <span class="special">:</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Skipper</span><span class="special">></span> +<span class="special">{</span> + <span class="comment">// This is a simplified preprocessor grammar recognizing</span> + <span class="comment">//</span> + <span class="comment">// #define MACRONAME something</span> + <span class="comment">// #undef MACRONAME</span> + <span class="comment">//</span> + <span class="comment">// Its sole purpose is to show an example how to use the </span> + <span class="comment">// flush_multi_pass parser. At the end of each line no backtracking can</span> + <span class="comment">// occur anymore so that it's safe to clear all internal buffers in the </span> + <span class="comment">// multi_pass.</span> + <span class="identifier">preprocessor</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">preprocessor</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">file</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">eol</span><span class="special">;</span> + <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span> + + <span class="identifier">file</span> <span class="special">=</span> + <span class="special">*</span><span class="identifier">line</span> + <span class="special">;</span> + + <span class="identifier">line</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">command</span> <span class="special">|</span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> <span class="special">)</span> + <span class="special">>></span> <span class="identifier">eol</span> + <span class="special">>></span> <span class="identifier">flush_multi_pass</span> + <span class="special">;</span> + + <span class="identifier">command</span> <span class="special">=</span> + <span class="string">"#define"</span> <span class="special">>></span> <span class="special">*</span><span class="identifier">lit</span><span class="special">(</span><span class="char">' '</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">' '</span><span class="special">)</span> <span class="special">>></span> <span class="special">*</span><span class="identifier">lit</span><span class="special">(</span><span class="char">' '</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> + <span class="special">|</span> <span class="string">"#undef"</span> <span class="special">>></span> <span class="special">*</span><span class="identifier">lit</span><span class="special">(</span><span class="char">' '</span><span class="special">)</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> + <span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special"><</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Skipper</span><span class="special">></span> <span class="identifier">file</span><span class="special">,</span> <span class="identifier">line</span><span class="special">,</span> <span class="identifier">command</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Using the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> + parser component with iterators other than <code class="computeroutput"><span class="identifier">multi_pass</span></code> + is safe as it has no effect on the parsing. + </p></td></tr> +</table></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="advance.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../primitive.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../directives.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/what_s_new.html b/libs/spirit/repository/doc/html/spirit_repository/what_s_new.html new file mode 100755 index 0000000000..d8c65c3b4d --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/what_s_new.html @@ -0,0 +1,44 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>What's New</title> +<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../index.html" title="Spirit Repository 0.2"> +<link rel="prev" href="preface.html" title="Preface"> +<link rel="next" href="what_s_new/spirit_2_5_1.html" title="Spirit V2.5.1"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="preface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="what_s_new/spirit_2_5_1.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="spirit_repository.what_s_new"></a><a class="link" href="what_s_new.html" title="What's New">What's New</a> +</h2></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="what_s_new/spirit_2_5_1.html">Spirit V2.5.1</a></span></dt></dl></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="preface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="what_s_new/spirit_2_5_1.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/html/spirit_repository/what_s_new/spirit_2_5_1.html b/libs/spirit/repository/doc/html/spirit_repository/what_s_new/spirit_2_5_1.html new file mode 100755 index 0000000000..00c1342394 --- /dev/null +++ b/libs/spirit/repository/doc/html/spirit_repository/what_s_new/spirit_2_5_1.html @@ -0,0 +1,55 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Spirit V2.5.1</title> +<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../../index.html" title="Spirit Repository 0.2"> +<link rel="up" href="../what_s_new.html" title="What's New"> +<link rel="prev" href="../what_s_new.html" title="What's New"> +<link rel="next" href="../qi_components.html" title="Qi Components"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"><tr> +<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td> +<td align="center"><a href="../../../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../what_s_new.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../what_s_new.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../qi_components.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="spirit_repository.what_s_new.spirit_2_5_1"></a><a class="link" href="spirit_2_5_1.html" title="Spirit V2.5.1">Spirit V2.5.1</a> +</h3></div></div></div> +<p> + This section is added since V2.5.1 (Boost V1.48.0). + </p> +<h5> +<a name="spirit_repository.what_s_new.spirit_2_5_1.h0"></a> + <span><a name="spirit_repository.what_s_new.spirit_2_5_1.new_features_in_qi"></a></span><a class="link" href="spirit_2_5_1.html#spirit_repository.what_s_new.spirit_2_5_1.new_features_in_qi">New + Features in Qi</a> + </h5> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> + Added the <span class="emphasis"><em>Spirit.Qi</em></span> directive <a class="link" href="../qi_components/directives/seek.html" title="Qi Seek Parser Directive"><code class="computeroutput"><span class="identifier">seek</span><span class="special">[]</span></code></a> + enabling skipping over the input, getting to the interested portion. + </li></ul></div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) + </p> +</div></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../what_s_new.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../what_s_new.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../qi_components.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/libs/spirit/repository/doc/karma.qbk b/libs/spirit/repository/doc/karma.qbk new file mode 100644 index 0000000000..2deab0399b --- /dev/null +++ b/libs/spirit/repository/doc/karma.qbk @@ -0,0 +1,16 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section Karma Components] + +[/include karma/primitive_generators.qbk] +[include karma/directives.qbk] +[include karma/nonterminals.qbk] +[/include karma/compound_generators.qbk] + +[endsect] diff --git a/libs/spirit/repository/doc/karma/compound_generators.qbk b/libs/spirit/repository/doc/karma/compound_generators.qbk new file mode 100644 index 0000000000..9c2124439e --- /dev/null +++ b/libs/spirit/repository/doc/karma/compound_generators.qbk @@ -0,0 +1,10 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:compound Karma Compound Generators] +[endsect] diff --git a/libs/spirit/repository/doc/karma/confix.qbk b/libs/spirit/repository/doc/karma/confix.qbk new file mode 100644 index 0000000000..c483eb3bbc --- /dev/null +++ b/libs/spirit/repository/doc/karma/confix.qbk @@ -0,0 +1,151 @@ +[/============================================================================== + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2001-2011 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section Karma Confix Generator] + +[heading Description] + +The __karma__ `confix` generator is a generator directive component +allowing to embed any generated ouput inside an opening (a prefix) and a +closing (a suffix). A simple example is a C comment: `/* This is a C comment */` +which can be generated using the `confix` generator as: +`confix("/*", "*/")["This is a C comment"]`. The general syntax for using the +`confix` is: + + confix(prefix, suffix)[subject] + +which results in generating a sequence equivalent to + + prefix << subject << suffix + +Using the `confix` component instead of the explicit sequence has the advantage +of being able to encapsulate the prefix and the suffix into a separate generator +construct. The following code snippet illustrates the idea: + + // Define a metafunction allowing to compute the type of the confix() + // construct + namespace traits + { + using namespace boost::spirit; + + template <typename Prefix, typename Suffix = Prefix> + struct confix_spec + : spirit::result_of::terminal<repository::tag::confix(Prefix, Suffix)> + {}; + }; + + // Define a helper function allowing to create a confix() construct from + // arbitrary prefix and suffix generators + template <typename Prefix, typename Suffix> + typename traits::confix_spec<Prefix, Suffix>::type + confix_spec(Prefix const& prefix, Suffix const& suffix) + { + using namespace boost::spirit; + return repository::confix(prefix, suffix); + } + + // Define a helper function to construct a HTML tag from the tag name + inline typename traits::confix_spec<std::string>::type + tag (std::string const& tagname) + { + return confix_spec("<" + tagname + ">", "</" + tagname + ">"); + } + + // Define generators for different HTML tags the HTML tag + typedef traits::confix_spec<std::string>::type ol = tag("ol"); // <ol>...</ol> + typedef traits::confix_spec<std::string>::type li = tag("li"); // <li>...</li> + +Now, for instance, the above definitions allow to generate the HTML 'ol' tag +using a simple: `ol["Some text"]` (which results in `<ol>Some text</ol>`). + +[heading Header] + + // forwards to <boost/spirit/repository/home/karma/directive/confix.hpp> + #include <boost/spirit/repository/include/karma_confix.hpp> + +[heading Synopsis] + + confix(prefix, suffix)[subject] + +[heading Parameters] + +[table + [[Parameter] [Description]] + [[`prefix`] [The generator construct to use to format the + opening (the prefix). The prefix is the part + generated /before/ any output as generated by + the `subject`.]] + [[`suffix`] [The generator construct to use to format the + ending (the suffix). The suffix is the part + generated /after/ any output as generated by + the `subject`.]] + [[`subject`] [The generator construct to use to format the + actual output in between the `prefix` and `suffix` + parts.]] +] + +All three parameters can be arbitrary complex generators themselves. + +[heading Attribute] + +The `confix` component exposes the attribute type of its subject as its own +attribute type. If the `subject` does not expose any attribute (the type is +`unused_type`), then the `confix` does not expose any attribute either. + + a: A --> confix(p, s)[a]: A + +[note This notation is used all over the Spirit documentation and reads as: + Given, `a` is generator, and `A` is the type of the attribute of generator + `a`, then the type of the attribute exposed by `confix(p, s)[a]` will be + `A` as well.] + +[heading Example] + +The following example shows simple use cases of the `confix` generator. We will +illustrate its usage by generating different comment styles and a function +prototype (for the full example code see here: +[@../../example/karma/confix.cpp confix.cpp]) + +[import ../example/karma/confix.cpp] + +[heading Prerequisites] + +In addition to the main header file needed to include the core components +implemented in __karma__ we add the header file needed for the new `confix` +generator. + +[karma_confix_includes] + +To make all the code below more readable we introduce the following namespaces. + +[karma_confix_namespace] + +[heading Generating Different Comment Styles] + +We will show how to generate different comment styles. First we will generate +a C++ comment: + +[karma_confix_cpp_comment] + +This code snippet will obviouly generate `// This is a comment \n `. Similarily +generating a 'C'-style comment proves to be straightforward: + +[karma_confix_c_comment] + +which again will generate `/* This is a comment */ `. + +[heading Generating a Function Prototype] + +Generating a function prototype given a function name a vector or parameter +names is simple as well: + +[karma_confix_function] + +which generates the expected output: `func(par1,par2,par3)`. + +[endsect] diff --git a/libs/spirit/repository/doc/karma/directives.qbk b/libs/spirit/repository/doc/karma/directives.qbk new file mode 100644 index 0000000000..8c6cf3e340 --- /dev/null +++ b/libs/spirit/repository/doc/karma/directives.qbk @@ -0,0 +1,11 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:directives Karma Generator Directives] +[include confix.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/karma/nonterminals.qbk b/libs/spirit/repository/doc/karma/nonterminals.qbk new file mode 100644 index 0000000000..82dd82b045 --- /dev/null +++ b/libs/spirit/repository/doc/karma/nonterminals.qbk @@ -0,0 +1,11 @@ +[/============================================================================== + Copyright (C) 2001-2010 Joel de Guzman + Copyright (C) 2001-2010 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:nonterminal Karma Generator Non-terminals] +[include subrule.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/karma/primitive_generators.qbk b/libs/spirit/repository/doc/karma/primitive_generators.qbk new file mode 100644 index 0000000000..d32c5905fc --- /dev/null +++ b/libs/spirit/repository/doc/karma/primitive_generators.qbk @@ -0,0 +1,10 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:primitive Karma Generator Primitives] +[endsect] diff --git a/libs/spirit/repository/doc/karma/subrule.qbk b/libs/spirit/repository/doc/karma/subrule.qbk new file mode 100644 index 0000000000..0d6b070e72 --- /dev/null +++ b/libs/spirit/repository/doc/karma/subrule.qbk @@ -0,0 +1,221 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:subrule Karma subrules] + +[heading Description] + +The __karma__ `subrule` is a component allowing to create a named generator, and +to refer to it by name -- much like rules and grammars. It is in fact a fully +static version of the rule. + +The strength of subrules is performance. Replacing some rules with subrules +can make a generator slightly faster (see +[link spirit_repository.karma_components.nonterminal.subrule.performance Performance] +below for measurements). The reason is that subrules allow aggressive inlining +by the C++ compiler, whereas the implementation of rules is based on a virtual +function call which, depending on the compiler, can have some run-time overhead +and stop inlining. + +The weaknesses of subrules are: + +* subrules can only be defined and used within the same generator expression. A + subrule cannot be defined at one location, and then used in another location. +* subrules put a massive strain on the C++ compiler. They increase compile + times and memory usage during compilation, and also increase the risk of + hitting compiler limits and/or bugs. + +[import ../../example/karma/calc2_ast_dump_sr.cpp] + +[calc2_ast_dump_sr_def] + +The example above can be found here: [@../../example/karma/calc2_ast_dump_sr.cpp] + +As shown in this code snippet (an extract from the calc2_ast_dump_sr example), +subrules can be freely mixed with rules and grammars. Here, a group of +3 subrules (`ast_node`, `binary_node`, `unary_node`) is assigned to a rule (named +`entry`). This means that parts of a generator can use subrules (typically +the innermost, most performance-critical parts), whereas the rest can use +rules and grammars. + +[heading Header] + + // forwards to <boost/spirit/repository/home/karma/nonterminal/subrule.hpp> + #include <boost/spirit/repository/include/karma_subrule.hpp> + +[heading Synopsis (declaration)] + + subrule<ID, A1, A2> sr(name); + +[heading Parameters (declaration)] + +[table + [[Parameter] [Description]] + [[`ID`] [Required numeric argument. Gives the subrule + a unique 'identification tag'.]] + [[`A1`, `A2`] [Optional types, can be specified in any order. + Can be one of 1. signature, 2. locals + (see rules reference for more information on + those parameters). + + Note that the delimiter type need not be specified + in the parameters, unlike with grammars and rules. + Subrules will automatically use the delimiter type + which is in effect when they are invoked.]] + [[`name`] [Optional string. Gives the subrule a name, + useful for debugging and error handling.]] +] + +[heading Synopsis (usage)] + +Subrules are defined and used within groups, typically (and by convention) +enclosed inside parentheses. + + // Group containing N subrules + ( + sr1 = expr1 + , sr2 = expr2 + , ... // Any number of subrules + } + +The IDs of all subrules defined within the same group must be different. It is +an error to define several subrules with the same ID (or to define the same +subrule multiple times) in the same group. + + // Auto-subrules and inherited attributes + ( + srA %= exprA << srB << srC(c1, c2, ...) // Arguments to subrule srC + , srB %= exprB + , srC = exprC + , ... + )(a1, a2, ...) // Arguments to group, i.e. to start subrule srA + +[heading Parameters (usage)] + +[table + [[Parameter] [Description]] + [[`sr1`, `sr2`] [Subrules with different IDs.]] + [[`expr1`, `expr2`] [Generator expressions. Can include `sr1` and `sr2`, + as well as any other valid generator expressions.]] + [[`srA`] [Subrule with a synthesized attribute and inherited + attributes.]] + [[`srB`] [Subrule with a synthesized attribute.]] + [[`srC`] [Subrule with inherited attributes.]] + [[`exprA`, `exprB`, `exprC`] + [Generator expressions.]] + [[`a1`, `a2`] [Arguments passed to the subrule group. They are + passed as inherited attributes to the group's + start subrule, `srA`.]] + [[`c1`, `c2`] [Arguments passed as inherited attributes to + subrule `srC`.]] +] + +[heading Groups] + +A subrule group (a set of subrule definitions) is a generator, which can be +used anywhere in a generator expression (in assignments to rules, as well as +directly in arguments to functions such as `generate`). +In a group, generation proceeds from the start subrule, which is the first +(topmost) subrule defined in that group. In the two groups in the synopsis +above, `sr1` and `srA` are the start subrules respectively -- for example +when the first subrule group is called forth, the `sr1` subrule is called. + +A subrule can only be used in a group which defines it. Groups can be viewed +as scopes: a definition of a subrule is limited to its enclosing group. + + rule<outiter_type> r1, r2, r3; + subrule<1> sr1; + subrule<2> sr2; + + r1 = + ( sr1 = 'a' << space ) // First group in r1. + << ( sr2 = +sr1 ) // Second group in r1. + // ^^^ + // DOES NOT COMPILE: sr1 is not defined in this + // second group, it cannot be used here (its + // previous definition is out of scope). + ; + + r2 = + ( sr1 = 'a' << space ) // Only group in r2. + << sr1 + // ^^^ + // DOES NOT COMPILE: not in a subrule group, + // sr1 cannot be used here (here too, its + // previous definition is out of scope). + ; + + r3 = + ( sr1 = space << 'x' ) // Another group. The same subrule `sr1` + // can have another, independent + // definition in this group. + ; + +[heading Attributes] + +A subrule has the same behavior as a rule with respect to attributes. In +particular: + +* the type of its synthesized attribute is the one specified in the + subrule's signature, if any. Otherwise it is `unused_type`. +* the types of its inherited attributes are the ones specified in the + subrule's signature, if any. Otherwise the subrule has no inherited + attributes. +* an auto-subrule can be defined by assigning it with the `%=` syntax. + In this case, the subrule's synthesized attribute is automatically + propagated to the RHS generator's attribute. +* the Phoenix placeholders `_val`, `_r1`, `_r2`, ... are available to + refer to the subrule's synthesized and inherited attributes, if present. + +[heading Locals] + +A subrule has the same behavior as a rule with respect to locals. In +particular, the Phoenix placeholders `_a`, `_b`, ... are available to +refer to the subrule's locals, if present. + +[heading Example] + +[import ../../example/karma/mini_xml_karma_sr.cpp] + +Some includes: + +[mini_xml_karma_sr_includes] + +Some using declarations: + +[mini_xml_karma_sr_using] + +A grammar containing only one rule, defined with a group of 2 subrules: + +[mini_xml_karma_sr_grammar] + +The definitions of the `mini_xml` and `mini_xml_node` data structures +are not shown here. The full example above can be found here: +[@../../example/karma/mini_xml_karma_sr.cpp] + +[heading Performance] + +For comparison of run-time and compile-time performance when using subrules, +please see the +[link spirit_repository.qi_components.nonterminal.subrule.performance Performance] +section of __qi__ subrules (the implementation of __karma__ and __qi__ subrules +is very similar, so performance is very similar too). + +[heading Notes] + +Subrules push the C++ compiler hard. A group of subrules is a single C++ +expression. Current C++ compilers cannot handle very complex expressions very +well. One restricting factor is the typical compiler's limit on template +recursion depth. Some, but not all, compilers allow this limit to be +configured. + +g++'s maximum can be set using a compiler flag: `-ftemplate-depth`. Set this +appropriately if you use relatively complex subrules. + +[endsect] diff --git a/libs/spirit/repository/doc/preface.qbk b/libs/spirit/repository/doc/preface.qbk new file mode 100644 index 0000000000..e88172d5a7 --- /dev/null +++ b/libs/spirit/repository/doc/preface.qbk @@ -0,0 +1,88 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section Preface] + +[heading The Spirit Repository] + +The __spirit__ repository is a community effort collecting different reusable +components (primitives, directives, grammars, etc.) for __qi__ parsers and +__karma__ generators. All components in the repository have been peer reviewed +and/or discussed on the __spirit_list__. The aim is to broaden the scope of the +__spirit__ library while being able to maintain its high standards in terms of +code quality, flexibility, and maintainability. At the same time it encourages +people to contribute even small components as it lessens the hurdle of becoming +a __boost__ and __spirit__ author. + +Maintainability of the code and author commitment over a longer period of time +are crucial for /Spirit's/ success (as it is for the whole __boost__ project). +That allows the repository to play an additional role in terms of being a +proving ground for interested authors. It is a lot easier to remove code from +the repository than from the /Spirit/ core library. So if an author can't +maintain his/her contribution anymore for any reason, we are able to remove +those parts from the repository more easily. + +The repository is an excellent way of evolving things. The /Spirit/ core has +been developed for years, so we have a certain confidence of it being properly +designed and exposing a proven API. On the other hand, new ideas often need +some time to 'come to the point'. Changing API's is part of this business. At +the same time changing API's always mean user disruption, which we want to keep +to a minimum. Again, changing things in the repository is ought to be a lot +easier than in the core library. + +The quality of contributions is another key to success. That includes not only +the code itself, but takes into consideration such things as documentation, +tests, examples. The authors activity on the mailing list is related as well, +it's an important point. Only well supported things will evolve over time into +usable, high quality components. The mandatory discussions and the review of +contributions on the __spirit_list__ ensure the targeted high quality +standards. + +Based on the user feedback and general usability of things it is possible over +time to move repository components/grammars into the /Spirit/ core library. + +[heading How to use this manual] + +Some icons are used to mark certain topics indicative of their relevance. +These icons precede some text to indicate: + +[table Icons + + [[Icon] [Name] [Meaning]] + + [[__note__] [Note] [Generally useful information (an aside that + doesn't fit in the flow of the text)]] + + [[__tip__] [Tip] [Suggestion on how to do something + (especially something that not be obvious)]] + + [[__important__] [Important] [Important note on something to take + particular notice of]] + + [[__caution__] [Caution] [Take special care with this - it may + not be what you expect and may cause bad + results]] + + [[__danger__] [Danger] [This is likely to cause serious + trouble if ignored]] +] + +This documentation is automatically generated by Boost QuickBook documentation +tool. QuickBook can be found in the __boost_tools__. + +[heading Support] + +Please direct all questions to Spirit's mailing list. You can subscribe to the +__spirit_list__. The mailing list has a searchable archive. A search link to +this archive is provided in __spirit__'s home page. You may also read and post +messages to the mailing list through __spirit_general__ (thanks to __gmane__). +The news group mirrors the mailing list. Here is a link to the archives: +__mlist_archive__. + +[endsect] [/ Preface] + diff --git a/libs/spirit/repository/doc/qi.qbk b/libs/spirit/repository/doc/qi.qbk new file mode 100644 index 0000000000..f5c1377f59 --- /dev/null +++ b/libs/spirit/repository/doc/qi.qbk @@ -0,0 +1,18 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section Qi Components] + +[include qi/primitive_parsers.qbk] +[include qi/directives.qbk] +[include qi/nonterminals.qbk] +[include qi/operators.qbk] +[/include qi/compound_parsers.qbk] + +[endsect] [/ Qi] + diff --git a/libs/spirit/repository/doc/qi/advance.qbk b/libs/spirit/repository/doc/qi/advance.qbk new file mode 100644 index 0000000000..51ff4f0170 --- /dev/null +++ b/libs/spirit/repository/doc/qi/advance.qbk @@ -0,0 +1,122 @@ +[/============================================================================== + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2011 Aaron Graham + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:advance Qi advance Parser] + +[heading Description] + +The __qi__ `advance` is a primitive parser component allowing the parser to +skip (advance) through a specified number of iterations without performing +unnecessary work: + + advance(distance) + +The most obvious existing alternative to this, the `repeat` directive, will +cause the parser to advance one iterator at a time while usually performing +operations at each step. In some cases that work is unnecessary, as in the case +where large binary objects are being parsed. Take, for example, the following +binary data: + +[pre + 00 00 00 01 77 fc b4 51 0a b3 b7 ... 1e 60 70 b6 00 00 01 00 +] + +If the first 4 bytes are a little-endian 32-bit integer describing the length +of the subsequent data, but the data itself is not relevant to parsing, then the +repeat directive would cause all of the subsequent 16 MB of data to be consumed +one byte at a time while generating page faults or other superfluous I/O. If the +value is large, as it is in this case, the parser becomes very slow. + + little_dword[_a = _1] >> repeat(_a)[byte_] >> little_dword... + +The `advance` parser component solves this problem by performing as little work +as possible to advance the parser's iterator, and will optimize for the case of +random-access iterators by advancing directly to the desired relative iterator +position. + + little_dword[_a = _1] >> advance(_a) >> little_dword... + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/primitive/advance.hpp> + #include <boost/spirit/repository/include/qi_advance.hpp> + +[heading Synopsis] + + advance(distance) + +[heading Parameters] + +[table + [[Parameter] [Description]] + [['distance'] [The distance that the iterator shall be advanced]] +] + +[heading Attribute] + +The `advance` component exposes no attribute (the exposed attribute type is +`unused_type`): + + advance --> unused + +[heading Example] + +The following example shows simple use cases of the `advance` component. We will +illustrate its usage by generating parsers for some binary data (for the full +example code see +[@../../example/qi/advance.cpp advance.cpp]) + +[import ../example/qi/advance.cpp] + +[heading Prerequisites] + +In addition to the main header file needed to include the core components +implemented in __qi__ we add the header file needed for the new `advance` +component. + +[qi_advance_includes] + +In order to make the examples below more readable we introduce or use the +following namespaces. + +[qi_advance_namespaces] + +[heading Setting up the Grammar] + +This is a very simple grammar that recognizes several fields of a binary stream +of data. There are two fields explicitly delimited by a field indicating the +number of bytes that are spanned. They are separated by a literal string. + +[qi_advance_grammar] + +Note that the second binary field may either contain the number of specified +bytes, or the word "qi". If the `advance` parser component fails to advance the +specified number of bytes before reaching the end of input, it will fail and +the parser will attempt to descend into alternatives. + +[heading Parsing a Correctly-delimited String of Data] + +The data below is correctly delimited and will thus result in a valid parse. +Note that both random-access and bidirectional iterators are used here. + +[qi_advance_example1] + +[heading Parsing the Alternative Representation] + +The data below is not correctly delimited, but will correctly parse because the +alternative word "qi" is available. + +[qi_advance_example2] + +[heading Notes] + +The `advance` parser component will fail unconditionally on negative values. +It will never attempt to advance the iterator in the reverse direction. + +[endsect] diff --git a/libs/spirit/repository/doc/qi/compound_parsers.qbk b/libs/spirit/repository/doc/qi/compound_parsers.qbk new file mode 100644 index 0000000000..e7cf8aff1b --- /dev/null +++ b/libs/spirit/repository/doc/qi/compound_parsers.qbk @@ -0,0 +1,10 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:compound Qi Compound Parsers] +[endsect] diff --git a/libs/spirit/repository/doc/qi/confix.qbk b/libs/spirit/repository/doc/qi/confix.qbk new file mode 100644 index 0000000000..31443b48c0 --- /dev/null +++ b/libs/spirit/repository/doc/qi/confix.qbk @@ -0,0 +1,137 @@ +[/============================================================================== + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2009 Chris Hoeppler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:confix Qi Confix Parser Directive] + +[heading Description] + +The __qi__ `confix` directive is a unary parser component allowing to embed a +parser (the subject) inside an opening (the prefix) and a closing (the suffix): + + confix(prefix, suffix)[subject] + +This results in a parser that is equivalent to the sequence + + omit[prefix] >> subject >> omit[suffix] + +A simple example is a parser for non-nested comments which can now be written +as: + + confix("/*", "*/")[*(char_ - "*/")] // C style comment + confix("//", eol)[*(char_ - eol)] // C++ style comment + +Using the `confix` directive instead of the explicit sequence has the advantage +of being able to encapsulate the prefix and the suffix into a separate construct. +The following code snippet illustrates the idea: + + namespace spirit = boost::spirit; + namespace repo = boost::spirit::repository; + + // Define a metafunction allowing to compute the type + // of the confix() construct + template <typename Prefix, typename Suffix = Prefix> + struct confix_spec + { + typedef typename spirit::result_of::terminal< + repo::tag::confix(Prefix, Suffix) + >::type type; + }; + + confix_spec<std::string>::type const c_comment = repo::confix("/*", "*/"); + confix_spec<std::string>::type const cpp_comment = repo::confix("//", "\n"); + +Now, the comment parsers can be written as + + c_comment[*(char_ - "*/")] // C style comment + cpp_comment[*(char_ - eol)] // C++ style comment + +[note While the `confix_p(prefix, subject, suffix)` parser in __classic__ + was equivalent to the sequence `prefix >> *(subject - suffix) >> suffix, + the __qi__ `confix` directive will not perform this refactoring any more. + This simplifies the code and makes things more explicit.] + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/directive/confix.hpp> + #include <boost/spirit/repository/include/qi_confix.hpp> + +[heading Synopsis] + + confix(prefix, suffix)[subject] + +[heading Parameters] + +[table + [[Parameter] [Description]] + [[`prefix`] [The parser for the opening (the prefix).]] + [[`suffix`] [The parser for the ending (the suffix).]] + [[`subject`] [The parser for the input sequence between the + `prefix` and `suffix` parts.]] +] + +All three parameters can be arbitrarily complex parsers themselves. + +[heading Attribute] + +The `confix` directive exposes the attribute type of its subject as its own +attribute type. If the `subject` does not expose any attribute (the type is +`unused_type`), then the `confix` does not expose any attribute either. + + a: A, p: P, s: S: --> confix(p, s)[a]: A + +[note This notation is used all over the Spirit documentation and reads as: + Given, `a`, `p`, and `s` are parsers, and `A`, `P`, and `S` are the types + of their attributes, then the type of the attribute exposed by + `confix(p, s)[a]` will be `A`.] + +[heading Example] + +The following example shows simple use cases of the `confix` directive. We will +illustrate its usage by generating parsers for different comment styles and +for some simple tagged data (for the full example code see +[@../../example/qi/confix.cpp confix.cpp]) + +[import ../example/qi/confix.cpp] + +[heading Prerequisites] + +In addition to the main header file needed to include the core components +implemented in __qi__ we add the header file needed for the new `confix` +directive. + +[qi_confix_includes] + +In order to make the examples below more readable we import a number of +elements into the current namespace: + +[qi_confix_using] + +[heading Parsing Different Comment Styles] + +We will show how to parse different comment styles. First we will parse +a C++ comment: + +[qi_confix_cpp_comment] + +This function will obviously parse input such as "`// This is a comment \n `". +Similarily parsing a 'C'-style comment proves to be straightforward: + +[qi_confix_c_comment] + +which again will be able to parse e.g. "`/* This is a comment */ `". + +[heading Parsing Tagged Data] + +Generating a parser that extracts the body from the HTML snippet "`<b>The Body</b>`" +is not very hard, either: + +[qi_confix_tagged_data] + + +[endsect] diff --git a/libs/spirit/repository/doc/qi/directives.qbk b/libs/spirit/repository/doc/qi/directives.qbk new file mode 100644 index 0000000000..94c3245feb --- /dev/null +++ b/libs/spirit/repository/doc/qi/directives.qbk @@ -0,0 +1,14 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:directives Qi Parser Directives] +[include confix.qbk] +[include distinct.qbk] +[include kwd.qbk] +[include seek.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/qi/distinct.qbk b/libs/spirit/repository/doc/qi/distinct.qbk new file mode 100644 index 0000000000..9e7667deed --- /dev/null +++ b/libs/spirit/repository/doc/qi/distinct.qbk @@ -0,0 +1,125 @@ +[/============================================================================== + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2001-2011 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:distinct Qi Distinct Parser Directive] + +[heading Description] + +The __qi__ `distinct` parser is a directive component allowing to avoid partial +matches while parsing using a skipper. A simple example is the common task of +matching a C keyword. +Consider: + + "description" >> -lit(":") >> *(char_ - eol) + +intended to match a line in a configuration file. Let's assume further, that +this rule is used with a `space` skipper and that we have the following strings +in the input: + + "description: ident\n" + "description ident\n" + "descriptionident\n" + +It might seem unexpected, but the parser above matches all three inputs just +fine, even if the third input should not match at all! In order to avoid the +unwanted match we are forced to make our rule more complicated: + + lexeme["description" >> !char_("a-zA-Z_0-9")] >> -lit(":") >> *(char_ - eol) + +(the rule reads as: match `"description"` as long as it's not /directly/ +followed by a valid identifier). + +The `distinct[]` directive is meant to simplify the rule above: + + distinct(char_("a-zA-Z_0-9"))["description"] >> -lit(":") >> *(char_ - eol) + +Using the `distinct[]` component instead of the explicit sequence has the +advantage of being able to encapsulate the tail (i.e the `char_("a-zA-Z_0-9")`) +as a separate parser construct. The following code snippet illustrates the idea +(for the full code of this example please see +[@../../test/qi/distinct.cpp distinct.cpp]): + +[import ../test/qi/distinct.cpp] +[qi_distinct_encapsulation] + +These definitions define a new Qi parser recognizing keywords! This allows to +rewrite our declaration parser expression as: + + keyword["description"] >> -lit(":") >> *(char_ - eol) + +which is much more readable and concise if compared to the original parser +expression. In addition the new `keyword[]` directive has the advantage to be +usable for wrapping any parser expression, not only strings as in the example +above. + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/directive/distinct.hpp> + #include <boost/spirit/repository/include/qi_distinct.hpp> + +[heading Synopsis] + + distinct(tail)[subject] + +[heading Parameters] + +[table + [[Parameter] [Description]] + [[`tail`] [The parser construct specifying what whould not + follow the subject in order to match the overall + expression.]] + [[`subject`] [The parser construct to use to match the current + input. The distinct directive makes sure that no + unexpected partial matches occur.]] +] + +All two parameters can be arbitrary complex parsers themselves. + +[heading Attribute] + +The `distinct` component exposes the attribute type of its subject as its own +attribute type. If the `subject` does not expose any attribute (the type is +`unused_type`), then the `distinct` does not expose any attribute either. + + a: A, b: B --> distinct(b)[a]: A + +[heading Example] + +The following example shows simple use cases of the `distinct` parser. +[@../../example/qi/distinct.cpp distinct.cpp]) + +[import ../example/qi/distinct.cpp] + +[heading Prerequisites] + +In addition to the main header file needed to include the core components +implemented in __qi__ we add the header file needed for the new `distinct` +generator. + +[qi_distinct_includes] + +To make all the code below more readable we introduce the following namespaces. + +[qi_distinct_namespace] + +[heading Using The Distinct Directive to Match keywords] + +We show several examples of how the `distinct[]` directive can be used to force +correct behavior while matching keywords. The first two code snippets show +the correct matching of the `description` keyword (in this hypothetical example +we allow keywords to be directly followed by an optional `"--"`): + +[qi_distinct_description_ident] +[qi_distinct_description__ident] + +The last example shows that the `distinct[]` parser component correctly refuses +to match "description-ident": + +[qi_distinct_description_ident_error] + +[endsect] diff --git a/libs/spirit/repository/doc/qi/flush_multi_pass.qbk b/libs/spirit/repository/doc/qi/flush_multi_pass.qbk new file mode 100644 index 0000000000..1fdf02425f --- /dev/null +++ b/libs/spirit/repository/doc/qi/flush_multi_pass.qbk @@ -0,0 +1,84 @@ +[/============================================================================== + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2001-2011 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:flush_multi_pass Qi flush_multi_pass parser] + +[heading Description] + +The __qi__ `flush_multi_pass` parser is a primitive (pseudo) parser component +allowing to clear the internal buffer of a `multi_pass` iterator. Clearing the +buffer of a `multi_pass` might be beneficial for grammars where it is clear +that no backtracking can occur. +The general syntax for using the `flush_multi_pass` is: + + flush_multi_pass + +which will call the `clear_queue()` member function if the current iterators +are of the type `multi_pass`. This will cause any buffered data to be erased. +This also will invalidate all other copies of multi_pass and they should not +be used. If they are, an `boost::illegal_backtracking` exception will be +thrown. For all other iterator types this is a no-op. The `flush_multi_pass` +generates a parser component which always succeeds and which does not consume +any input (very much like `eps`). + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp> + #include <boost/spirit/repository/include/qi_flush_multi_pass.hpp> + +[heading Synopsis] + + flush_multi_pass + +[heading Parameters] + +The `flush_multi_pass` does not require any parameters. + +[heading Attribute] + +The `flush_multi_pass` component exposes no attribute (the exposed attribute +type is `unused_type`): + + flush_multi_pass --> unused + +[heading Example] + +The following example shows a simple use case of the `flush_multi_pass` parser. + +We will illustrate its usage by generating different comment styles and a +function prototype (for the full example code see here: +[@../../example/qi/flush_multi_pass.cpp flush_multi_pass.cpp]) + +[import ../example/qi/flush_multi_pass.cpp] + +[heading Prerequisites] + +In addition to the main header file needed to include the core components +implemented in __qi__ we add the header file needed for the new +`flush_multi_pass` parser. + +[qi_flush_multi_pass_includes] + +To make all the code below more readable we introduce the following namespaces. + +[qi_flush_multi_pass_namespace] + +[heading Clearing the internal buffer] + +The example grammar recognizes the (simplified) preprocessor commands `#define` +and `#undef` both of which are constraint to a single line. This makes it +possible to delete all internal iterator buffers on each detected line break. +This is safe as no backtracking will occur after any line end. The following +code snippet shows the usage of `flush_multi_pass` for this purpose. + +[qi_flush_multi_pass_clear_buffer] + +[note Using the `flush_multi_pass` parser component with iterators other than + `multi_pass` is safe as it has no effect on the parsing.] + +[endsect] diff --git a/libs/spirit/repository/doc/qi/keywords.qbk b/libs/spirit/repository/doc/qi/keywords.qbk new file mode 100644 index 0000000000..4b7c0cbd1c --- /dev/null +++ b/libs/spirit/repository/doc/qi/keywords.qbk @@ -0,0 +1,107 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2011 Thomas Bernard + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:keyword_list Keyword List Operator] + +[heading Description] + +The keyword list operator, `kwd("k1")[a] / kwd("k2")[b]`, works tightly with the kwd, ikwd directives +to effeciently match keyword lists. As long as one of the keywords specified through the kwd or ikwd directive +matches, the keyword will be immediatly followed by the the keyword's associated subject parser. +The parser will continue parsing input as long as the one of the keywords and it's associated parser succeed. +Writing : +(kwd("k1")[a] / kwd("k2")[b] / ... ) +is equivalent to: +*( "k1" > a | "k2" > b ... ). + + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/operator/keywords.hpp> + #include <boost/spirit/repository/include/qi_keywords.hpp> + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`kwd(k1)[a] / kwd(k2)[b]`] [Match `lit(k1) > a` or `lit(k2) > b`, equivalent to `lit(k1) > a | lit(k2) > b`]] +] + +[heading Attributes] + + +[table + [[Expression] [Attribute]] + [[`kwd("k1")[a] / kwd("k2")[b]`] +[``a: A, b: B --> (kwd(k1)[a] / kwd(k2)[b]): tuple<A, B> +a: A, b: Unused --> (kwd(k1)[a] / kwd(k2)[b]): optional<A> +a: Unused, b: B --> (kwd("k1")[a] / kwd(k2)[b]): optional<B> +a: Unused, b: Unused --> (kwd(k1)[a] / kwd(k2)[b]): Unused + +a: A, b: A -->(kwd(k1)[a] / kwd(k2)[b]): tuple<A, A>``]] +] + +[note The keyword list parser works tightly with the kwd and ikwd directives + and can't be used without it. A compile time error will warn you + of any mistakes. This parser collects all the kwd directives and + extracts the keyword literals from the directives to internaly + build a Ternary Search Tree (TST) to effectively parse the keywords. + Because you we can't mix character types inside a TST you must take + care not to mix wide strings with normal strings in the keyword you supply + to a keyword list. Should it happen the compiler will trap the mistake for you.] + +[note The kwd directive also works a bit like the repeat directive + and can be used to formulate additional contraints on the number of + times a keyword can occur while parsing a keyword list.] + +[note The kwd and ikwd directives can be mixed inside a keyword list. This has + however a small overhead and should be avoided when possible.] + +[heading Complexity] + +[:The overall complexity of the keyword list parser is defined by the +sum of the complexities of its elements. The complexity of the +keyword list itself is determined by the complexity of the internal TST contents : + +O(log n+k) + +Where k is the length of the string to be searched in a TST with n strings.] + +[heading Example] + +[import ../example/qi/keywords.cpp] + +[note The test harness for the example(s) below is presented in the +__qi_basics_examples__ section.] + +Declare a small data structure representing a person: + +[reference_keyword_list_test_data_structure] + +Some using declarations: + +[reference_using_declarations_keyword_list] + +Now let's declare a keyword parser: + +[reference_keyword_list_no_constraint_rule] + +A couple of input string variations run on the same parser: + +[reference_keyword_list] + +Now let's delcare a parser with some occurence constraints: + +[reference_keyword_list_constraint_rule] + +And see how it works in these two cases: + +[reference_keyword_list_constraints] + +[endsect] [/ Keyword list] diff --git a/libs/spirit/repository/doc/qi/kwd.qbk b/libs/spirit/repository/doc/qi/kwd.qbk new file mode 100644 index 0000000000..016ae2270c --- /dev/null +++ b/libs/spirit/repository/doc/qi/kwd.qbk @@ -0,0 +1,95 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2011 Thomas Bernard + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:kwd Qi Keyword Parser Directive ] + +[heading Description] + +The `kwd[]` and `ikwd[]` provide a powerful and flexible mechanism for parsing keyword +based input. It works in conjuction with the / operator to create an effective +keyword parsing loop. The keyword parsing loop doesn't require the +keywords to appear in a defined order in the input but also provides the possibility +to check how many times a keyword appears in the input. + +The kwd directive will parse the keywords respecting case sensitivity whereas the ikwd +direcive is case insensitive. You can mix the kwd and ikwd directives inside a set of +keywords, but be aware that this has a small overhead. It should be prefered not to +mix the kwd and ikwd directives. + +The kwd directive is very similar to the repeat directive in that it enables to enforce +keyword occurence constraints but also provides very interesting speed improvement +over the pure EBNF syntax or the Nabialek-Trick. + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/directive/kwd.hpp> + #include <boost/spirit/repository/include/qi_kwd.hpp> + +[heading Synopsis] + +[table + [[Expression] [Semantics]] + [[`kwd(keyword)[subject]`] [Parse ( `"keyword"` > `subject`) zero or more times.]] + [[`kwd(keyword,n)[subject]`] [Parse ( `"keyword"` > `subject`) exactly `n` times.]] + [[`kwd(keyword,min, max)[subject]`] [Parse ( `"keyword"` > `subject`) at least `min` times and at most `max` times.]] + [[`kwd(keyword,min, inf)[subject]`] [Parse ( `"keyword"` > `subject`) at least `min` or more. ]] +] + +For non case sensitive keywords use the ikwd directive. + +[heading Parameters] + +[table + [[Parameter] [Description]] + [[`keyword`] [The parser for the opening (the prefix).]] + [[`subject`] [The parser for the input sequence following the keyword part.]] + [[`n`] [Int representing the exact number of times the keyword must be repeated.]] + [[`min`] [Int representing the minimum number of times the keyword must be repeated.]] + [[`max`] [Int representing the maximum number of times the keyword must be repeated.]] +] + +All three parameters can be arbitrarily complex parsers themselves. + + +[heading Attributes] + +[table + [[Expression] [Attribute]] + [[`kwd(k1)[a]`] +[``a: A --> kwd(k1)[a]: optional<A> or vector<A> +a: Unused --> kwd(k1)[a]: Unused``]] + [[`kwd(k1,n)[a]`] +[``a: A --> kwd(k1,n)[a]: optional<A> or vector<A> +a: Unused --> kwd(k1,n)[a]: Unused``]] + [[`kwd(k1,min, max)[a]`] +[``a: A --> kwd(k1,min, max)[a]: optional<A> or vector<A> +a: Unused --> kwd(k1,min, max)[a]: Unused``]] + [[`kwd(k1,min, inf)[a]`] +[``a: A --> kwd(k1,min, inf)[a]: optional<A> or vector<A> +a: Unused --> kwd(k1,min, inf)[a]: Unused``]] +] + +[heading Complexity] + +[:The overall complexity is defined by the complexity of its subject +parser. The complexity of the keyword list construct `kwd` itself is O(N), where N is the number +of repetitions executed. + +The complexity of the keyword list itself determined by the complexity of the internal TST contents : + +O(log n+k) + +Where k is the length of the string to be searched in a TST with n strings. +] + +[heading Example] + +Please refer to keyword_list. + +[endsect] diff --git a/libs/spirit/repository/doc/qi/nonterminals.qbk b/libs/spirit/repository/doc/qi/nonterminals.qbk new file mode 100644 index 0000000000..26e5ecaad6 --- /dev/null +++ b/libs/spirit/repository/doc/qi/nonterminals.qbk @@ -0,0 +1,11 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:nonterminal Qi Parser Non-terminals] +[include subrule.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/qi/operators.qbk b/libs/spirit/repository/doc/qi/operators.qbk new file mode 100644 index 0000000000..eba96419e6 --- /dev/null +++ b/libs/spirit/repository/doc/qi/operators.qbk @@ -0,0 +1,11 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:operators Qi Parser Operators] +[include keywords.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/qi/primitive_parsers.qbk b/libs/spirit/repository/doc/qi/primitive_parsers.qbk new file mode 100644 index 0000000000..7abcd78f1a --- /dev/null +++ b/libs/spirit/repository/doc/qi/primitive_parsers.qbk @@ -0,0 +1,12 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:primitive Qi Parser Primitives] +[include advance.qbk] +[include flush_multi_pass.qbk] +[endsect] diff --git a/libs/spirit/repository/doc/qi/seek.qbk b/libs/spirit/repository/doc/qi/seek.qbk new file mode 100644 index 0000000000..70fda9561e --- /dev/null +++ b/libs/spirit/repository/doc/qi/seek.qbk @@ -0,0 +1,94 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2011 Jamboree + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:seek Qi Seek Parser Directive ] + +[heading Description] + +The `seek[]` parser-directive skips all input until the subject parser matches. +On failure, the current position is the end of the input. + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/directive/seek.hpp> + #include <boost/spirit/repository/include/qi_seek.hpp> + +Also, see __include_structure__. + +[heading Namespace] + +[table + [[Name]] + [[`boost::spirit::repository::qi::seek`]] +] + +[heading Model of] + +[:__unary_parser_concept__] + +[variablelist Notation + [[`a`] [A __parser_concept__.]] +] + +[heading Expression Semantics] + +Semantics of an expression is defined only where it differs from, or is +not defined in __unary_parser_concept__. + +[table + [[Expression] [Semantics]] + [[`seek[a]`] [Advances until the parser `a` matches.]] +] + +[heading Attributes] + +See __qi_comp_attr_notation__. + +[table + [[Expression] [Attribute]] + [[`seek[a]`] +[``a: A --> seek[a]: A +a: Unused --> seek[a]: Unused``]] +] + +[heading Complexity] + +[:The overall complexity is defined by the complexity of its subject +parser. The complexity of `seek` itself is O(N), where N is the number +of unsuccessful matches.] + +[note *seeking sequence with skipping* + +Using `seek[a >> b]` with skipping is inefficient, because when sequence fails, the backtracked position is non-skipped. +The solution is to ensure the input will always be pre-skipped, for example: +`` + seek[lexeme[skip[a >> b]]] +`` +does the trick.] + +[heading Example] + +[import ../../example/qi/seek.cpp] + +The following example shows a simple use case of the `seek[]` directive, parsing C-style comment. +(For the full source of the example, see [@../../example/qi/seek.cpp seek.cpp]) + +Some namespace aliases: + +[reference_qi_seek_namespace] + +The input string and its iterators: + +[reference_qi_seek_vars] + +Parsing and showing the result: + +[reference_qi_seek_parse] + +[endsect] diff --git a/libs/spirit/repository/doc/qi/subrule.qbk b/libs/spirit/repository/doc/qi/subrule.qbk new file mode 100644 index 0000000000..f51f34f6a9 --- /dev/null +++ b/libs/spirit/repository/doc/qi/subrule.qbk @@ -0,0 +1,240 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + Copyright (C) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section:subrule Qi subrules] + +[heading Description] + +The __qi__ `subrule` is a component allowing to create a named parser, and +to refer to it by name -- much like rules and grammars. It is in fact a fully +static version of the rule. + +The strength of subrules is performance. Replacing some rules with subrules +can make a parser slightly faster (see +[link spirit_repository.qi_components.nonterminal.subrule.performance Performance] +below for measurements). The reason is that subrules allow aggressive inlining +by the C++ compiler, whereas the implementation of rules is based on a virtual +function call which, depending on the compiler, can have some run-time overhead +and stop inlining. + +The weaknesses of subrules are: + +* subrules can only be defined and used within the same parser expression. A + subrule cannot be defined at one location, and then used in another location. +* subrules put a massive strain on the C++ compiler. They increase compile + times and memory usage during compilation, and also increase the risk of + hitting compiler limits and/or bugs. + +[import ../../example/qi/calc1_sr.cpp] + +[calc1_sr_def] + +The example above can be found here: [@../../example/qi/calc1_sr.cpp] + +As shown in this code snippet (an extract from the calc1_sr example), +subrules can be freely mixed with rules and grammars. Here, a group of +3 subrules (`expression`, `term`, `factor`) is assigned to a rule (named +`entry`). This means that parts of a parser can use subrules (typically +the innermost, most performance-critical parts), whereas the rest can use +rules and grammars. + +[heading Header] + + // forwards to <boost/spirit/repository/home/qi/nonterminal/subrule.hpp> + #include <boost/spirit/repository/include/qi_subrule.hpp> + +[heading Synopsis (declaration)] + + subrule<ID, A1, A2> sr(name); + +[heading Parameters (declaration)] + +[table + [[Parameter] [Description]] + [[`ID`] [Required numeric argument. Gives the subrule + a unique 'identification tag'.]] + [[`A1`, `A2`] [Optional types, can be specified in any order. + Can be one of 1. signature, 2. locals + (see rules reference for more information on + those parameters). + + Note that the skipper type need not be specified + in the parameters, unlike with grammars and rules. + Subrules will automatically use the skipper type + which is in effect when they are invoked.]] + [[`name`] [Optional string. Gives the subrule a name, + useful for debugging and error handling.]] +] + +[heading Synopsis (usage)] + +Subrules are defined and used within groups, typically (and by convention) +enclosed inside parentheses. + + // Group containing N subrules + ( + sr1 = expr1 + , sr2 = expr2 + , ... // Any number of subrules + } + +The IDs of all subrules defined within the same group must be different. It is +an error to define several subrules with the same ID (or to define the same +subrule multiple times) in the same group. + + // Auto-subrules and inherited attributes + ( + srA %= exprA >> srB >> srC(c1, c2, ...) // Arguments to subrule srC + , srB %= exprB + , srC = exprC + , ... + )(a1, a2, ...) // Arguments to group, i.e. to start subrule srA + +[heading Parameters (usage)] + +[table + [[Parameter] [Description]] + [[`sr1`, `sr2`] [Subrules with different IDs.]] + [[`expr1`, `expr2`] [Parser expressions. Can include `sr1` and `sr2`, + as well as any other valid parser expressions.]] + [[`srA`] [Subrule with a synthesized attribute and inherited + attributes.]] + [[`srB`] [Subrule with a synthesized attribute.]] + [[`srC`] [Subrule with inherited attributes.]] + [[`exprA`, `exprB`, `exprC`] + [Parser expressions.]] + [[`a1`, `a2`] [Arguments passed to the subrule group. They are + passed as inherited attributes to the group's + start subrule, `srA`.]] + [[`c1`, `c2`] [Arguments passed as inherited attributes to + subrule `srC`.]] +] + +[heading Groups] + +A subrule group (a set of subrule definitions) is a parser, which can be +used anywhere in a parser expression (in assignments to rules, as well as +directly in arguments to functions such as `parse`). +In a group, parsing proceeds from the start subrule, which is the first +(topmost) subrule defined in that group. In the two groups in the synopsis +above, `sr1` and `srA` are the start subrules respectively -- for example +when the first subrule group is called forth, the `sr1` subrule is called. + +A subrule can only be used in a group which defines it. Groups can be viewed +as scopes: a definition of a subrule is limited to its enclosing group. + + rule<char const*> r1, r2, r3; + subrule<1> sr1; + subrule<2> sr2; + + r1 = + ( sr1 = 'a' >> int_ ) // First group in r1. + >> ( sr2 = +sr1 ) // Second group in r1. + // ^^^ + // DOES NOT COMPILE: sr1 is not defined in this + // second group, it cannot be used here (its + // previous definition is out of scope). + ; + + r2 = + ( sr1 = 'a' >> int_ ) // Only group in r2. + >> sr1 + // ^^^ + // DOES NOT COMPILE: not in a subrule group, + // sr1 cannot be used here (here too, its + // previous definition is out of scope). + ; + + r3 = + ( sr1 = 'x' >> double_ ) // Another group. The same subrule `sr1` + // can have another, independent + // definition in this group. + ; + +[heading Attributes] + +A subrule has the same behavior as a rule with respect to attributes. In +particular: + +* the type of its synthesized attribute is the one specified in the + subrule's signature, if any. Otherwise it is `unused_type`. +* the types of its inherited attributes are the ones specified in the + subrule's signature, if any. Otherwise the subrule has no inherited + attributes. +* an auto-subrule can be defined by assigning it with the `%=` syntax. + In this case, the RHS parser's attribute is automatically propagated + to the subrule's synthesized attribute. +* the Phoenix placeholders `_val`, `_r1`, `_r2`, ... are available to + refer to the subrule's synthesized and inherited attributes, if present. + +[heading Locals] + +A subrule has the same behavior as a rule with respect to locals. In +particular, the Phoenix placeholders `_a`, `_b`, ... are available to +refer to the subrule's locals, if present. + +[heading Example] + +[import ../../example/qi/mini_xml2_sr.cpp] + +Some includes: + +[mini_xml2_sr_includes] + +Some using declarations: + +[mini_xml2_sr_using] + +A grammar containing only one rule, defined with a group of 5 subrules: + +[mini_xml2_sr_grammar] + +The definitions of the `mini_xml` and `mini_xml_node` data structures +are not shown here. The full example above can be found here: +[@../../example/qi/mini_xml2_sr.cpp] + +[heading Performance] + +This table compares run-time and compile-time performance when converting +examples to subrules, with various compilers. + +[table Subrules performance + +[[Example] [Compiler] + [Speed (run-time)] [Time (compile-time)] [Memory (compile-time)]] + +[[calc1_sr] [gcc 4.4.1] [ +6%] [ n/a] [ n/a]] +[[calc1_sr] [Visual C++ 2008 (VC9)] [ +5%] [ n/a] [ n/a]] +[[mini_xml2_sr] [gcc 3.4.6] [ -1%] [+54%] [+32%]] +[[mini_xml2_sr] [gcc 4.1.2] [ +5%] [+58%] [+25%]] +[[mini_xml2_sr] [gcc 4.4.1] [ +8%] [+20%] [+14%]] +[[mini_xml2_sr] [Visual C++ 2005 (VC8) SP1] [ +1%] [+33%] [+27%]] +[[mini_xml2_sr] [Visual C++ 2008 (VC9)] [ +9%] [+52%] [+40%]] + +] + +The columns are: + +* *Speed (run-time)*: speed-up of the parser resulting from the use of + subrules (higher is better). +* *Time (compile-time)*: increase in compile time (lower is better). +* *Memory (compile-time)*: increase in compiler memory usage (lower is better). + +[heading Notes] + +Subrules push the C++ compiler hard. A group of subrules is a single C++ +expression. Current C++ compilers cannot handle very complex expressions very +well. One restricting factor is the typical compiler's limit on template +recursion depth. Some, but not all, compilers allow this limit to be +configured. + +g++'s maximum can be set using a compiler flag: `-ftemplate-depth`. Set this +appropriately if you use relatively complex subrules. + +[endsect] diff --git a/libs/spirit/repository/doc/repository_template.qbk b/libs/spirit/repository/doc/repository_template.qbk new file mode 100644 index 0000000000..3f86d8a677 --- /dev/null +++ b/libs/spirit/repository/doc/repository_template.qbk @@ -0,0 +1,38 @@ +[/============================================================================== + Copyright (C) <year> <name> + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section <name of component>] + +[heading Description] + +[/ describe the component here] + +[heading Header] + + #include <boost/spirit/repository/include/...> + +[heading Synopsis] + +[/ short usage synopsis] + +[heading Parameters] + +[table + [[Parameter] [Description]] + [[parameter in synopsis] [describe parameter]] +] + +[heading Attribute] + +[/ describe the rules for attribute construction and propagation of your + component, use the same notation as used in the main Spirit docs] + +[heading Example] + +[/ describe some examples here, use uiqckbooks import feature to show the code] + +[endsect] diff --git a/libs/spirit/repository/doc/spirit2_repository.qbk b/libs/spirit/repository/doc/spirit2_repository.qbk new file mode 100644 index 0000000000..e36e861d33 --- /dev/null +++ b/libs/spirit/repository/doc/spirit2_repository.qbk @@ -0,0 +1,115 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[article Spirit Repository + [quickbook 1.4] + [version 0.2] + [authors [de Guzman, Joel], [Kaiser, Hartmut]] + [copyright 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 Joel de Guzman, Hartmut Kaiser] + [/ purpose Parser and Generator Library] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + +[/ May 26, 2009 ] + +[def __spirit__ [@http://boost-spirit.com Spirit]] +[def __spirit_list__ [@http://www.nabble.com/The-Spirit-Parser-Library-f3430.html Spirit General List]] +[def __phoenix__ [@../../phoenix/doc/html/index.html Phoenix]] +[def __boost_phoenix__ [@../../phoenix/doc/html/index.html Phoenix2]] +[def __fusion__ [@http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.html Fusion]] +[def __mpl__ [@http://www.boost.org/libs/mpl/index.html MPL]] +[def __boost__ [@http://www.boost.org/ Boost]] +[def __boost_tools__ [@http://www.boost.org/tools/index.html Boost Tools]] +[def __spirit_list__ [@https://lists.sourceforge.net/lists/listinfo/spirit-general Spirit Mailing List]] +[def __spirit_general__ [@news://news.gmane.org/gmane.comp.spirit.general Spirit General NNTP news portal]] +[def __gmane__ [@http://www.gmane.org Gmane]] +[def __mlist_archive__ [@http://news.gmane.org/gmane.comp.parsers.spirit.general]] + +[def __classic__ /Spirit.Classic/] +[def __qi__ /Spirit.Qi/] +[def __karma__ /Spirit.Karma/] +[def __lex__ /Spirit.Lex/] + +[def __qi_advance__ [link spirit_repository.qi_components.primitive.advance `advance`]] +[def __qi_subrule__ [link spirit_repository.qi_components.nonterminal.subrule `subrule`]] +[def __qi_confix__ [link spirit_repository.qi_components.directives.confix `confix`]] +[def __qi_keywords__ [link spirit_repository.qi_components.operators.keyword_list keyword_list]] +[def __qi_keywords_list__ [link spirit_repository.qi_components.directives.kwd `kwd()[]`]] +[def __qi_seek__ [link spirit_repository.qi_components.directives.seek `seek[]`]] + +[def __karma_subrule__ [link spirit_repository.karma_components.nonterminal.subrule `subrule`]] + +[/ Some images ] + +[def __note__ [$images/note.png]] +[def __tip__ [$images/tip.png]] +[def __important__ [$images/important.png]] +[def __caution__ [$images/caution.png]] +[def __danger__ [$images/alert.png]] + +[/ ----------------------------------------------------------------------------] +[/ $$$ Refer to spirit2.qbk $$$] + +[/ References to abstracts ] + +[def __include_structure__ [@../../../doc/html/spirit/structure/include.html Include Structure]] + +[/ quick-ref] +[def __qi_comp_attr_notation__ [@../../../doc/html/spirit/qi/quick_reference/compound_attribute_rules.html#spirit.qi.quick_reference.compound_attribute_rules.notation Compound Attribute Notation]] + +[/ concepts] +[def __parser_concept__ [@../../../doc/html/spirit/qi/reference/parser_concepts/parser.html `Parser`]] +[def __primitive_parser_concept__ [@../../../doc/html/spirit/qi/reference/parser_concepts/primitiveparser.html `PrimitiveParser`]] +[def __unary_parser_concept__ [@../../../doc/html/spirit/qi/reference/parser_concepts/unaryparser.html `UnaryParser`]] +[def __binary_parser_concept__ [@../../../doc/html/spirit/qi/reference/parser_concepts/binaryparser.html `BinaryParser`]] +[def __nary_parser_concept__ [@../../../doc/html/spirit/qi/reference/parser_concepts/naryparser.html `NaryParser`]] +[def __qi_nonterminal__ [@../../../doc/html/spirit/qi/reference/parser_concepts/nonterminal.html `Nonterminal`]] +[def __qi_nonterminal_attribute__ [@../../../doc/html/spirit/qi/reference/parser_concepts/nonterminal.html#spirit.qi.reference.parser_concepts.nonterminal.attributes `Attribute`]] + +[/ basics] +[def __qi_lazy_argument__ [@../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.lazy_argument Lazy Argument]] +[def __qi_lazy_arguments__ [@../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.lazy_argument Lazy Arguments]] +[def __char_encoding_namespace__ [@../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.character_encoding_namespace Character Encoding Namespace]] +[def __string__ [@../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.string String]] +[def __qi_basics_examples__ [@../../../doc/html/spirit/qi/reference/basics.html#spirit.qi.reference.basics.examples Basics Examples]] + +[/ quick-ref] +[def __karma_comp_attr_notation__ [@../../../doc/html/spirit/karma/quick_reference/compound_attribute_rules.html#spirit.karma.quick_reference.compound_attribute_rules.notation Compound Attribute Notation]] + +[/ concepts] +[def __generator_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/generator.html `Generator`]] +[def __primitive_generator_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/primitivegenerator.html `PrimitiveGenerator`]] +[def __unary_generator_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/unarygenerator.html `UnaryGenerator`]] +[def __binary_generator_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/binarygenerator.html `BinaryGenerator`]] +[def __nary_generator_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/narygenerator.html `NaryGenerator`]] +[def __karma_nonterminal_concept__ [@../../../doc/html/spirit/karma/reference/generator_concepts/nonterminal.html `Nonterminal`]] +[def __karma_nonterminal_attribute__ [@../../../doc/html/spirit/karma/reference/generator_concepts/nonterminal.html#spirit.karma.reference.generator_concepts.nonterminal.attributes `Attribute`]] + +[/ basics] +[def __karma_lazy_argument__ [@../../../doc/html/spirit/karma/reference/basics.html#spirit.karma.reference.basics.lazy_argument Lazy Argument]] +[def __karma_lazy_arguments__ [@../../../doc/html/spirit/karma/reference/basics.html#spirit.karma.reference.basics.lazy_argument Lazy Arguments]] +[def __karma_basics_examples__ [@../../../doc/html/spirit/karma/reference/basics.html#spirit.karma.reference.basics.examples Basics Examples]] + +[/ ----------------------------------------------------------------------------] + +[/ Here we go ] + +[include preface.qbk] + +[include what_s_new.qbk] + +[include qi.qbk] + +[include karma.qbk] + +[include acknowledgements.qbk] + diff --git a/libs/spirit/repository/doc/what_s_new.qbk b/libs/spirit/repository/doc/what_s_new.qbk new file mode 100644 index 0000000000..8ad19b0d69 --- /dev/null +++ b/libs/spirit/repository/doc/what_s_new.qbk @@ -0,0 +1,23 @@ +[/============================================================================== + Copyright (C) 2001-2011 Joel de Guzman + Copyright (C) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +===============================================================================/] + +[section What's New] + +[/////////////////////////////////////////////////////////////////////////////] +[section:spirit_2_5_1 Spirit V2.5.1] + +This section is added since V2.5.1 (Boost V1.48.0). + +[heading New Features in Qi] + +* Added the __qi__ directive __qi_seek__ enabling skipping over the input, + getting to the interested portion. + +[endsect] + +[endsect] diff --git a/libs/spirit/repository/example/karma/Jamfile b/libs/spirit/repository/example/karma/Jamfile new file mode 100644 index 0000000000..78abdb04f9 --- /dev/null +++ b/libs/spirit/repository/example/karma/Jamfile @@ -0,0 +1,17 @@ +#============================================================================== +# Copyright (c) 2009 Chris Hoeppler +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +project spirit_v2_repository/example_karma + : requirements + <toolset>gcc:<cxxflags>-ftemplate-depth-300 + <toolset>darwin:<cxxflags>-ftemplate-depth-300 + ; + +exe karma_confix : confix.cpp ; +exe calc2_ast_dump_sr : calc2_ast_dump_sr.cpp ; +exe mini_xml_karma_sr : mini_xml_karma_sr.cpp ; + diff --git a/libs/spirit/repository/example/karma/calc2_ast.hpp b/libs/spirit/repository/example/karma/calc2_ast.hpp new file mode 100644 index 0000000000..53fadf76b6 --- /dev/null +++ b/libs/spirit/repository/example/karma/calc2_ast.hpp @@ -0,0 +1,179 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2001-2012 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// A Calculator example demonstrating generation of AST which gets dumped into +// a human readable format afterwards. +// +// [ JDG April 28, 2008 ] +// [ HK April 28, 2008 ] +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM) +#define SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM + +#include <boost/variant.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_function.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> +#include <boost/spirit/home/karma/domain.hpp> +#include <boost/spirit/include/support_attributes_fwd.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// Our AST +/////////////////////////////////////////////////////////////////////////////// +struct binary_op; +struct unary_op; +struct nil {}; + +struct expression_ast +{ + typedef + boost::variant< + nil // can't happen! + , int + , boost::recursive_wrapper<binary_op> + , boost::recursive_wrapper<unary_op> + > + type; + + // expose variant types + typedef type::types types; + + // expose variant functionality + int which() const { return expr.which(); } + + // constructors + expression_ast() + : expr(nil()) {} + + expression_ast(unary_op const& expr) + : expr(expr) {} + + expression_ast(binary_op const& expr) + : expr(expr) {} + + expression_ast(unsigned int expr) + : expr(expr) {} + + expression_ast(type const& expr) + : expr(expr) {} + + expression_ast& operator+=(expression_ast const& rhs); + expression_ast& operator-=(expression_ast const& rhs); + expression_ast& operator*=(expression_ast const& rhs); + expression_ast& operator/=(expression_ast const& rhs); + + type expr; +}; + +// expose variant functionality +namespace boost +{ + // this function has to live in namespace boost for ADL to correctly find it + template <typename T> + inline T get(expression_ast const& expr) + { + return boost::get<T>(expr.expr); + } + + // the specialization below tells Spirit to handle expression_ast as if it + // where a 'real' variant + namespace spirit { namespace traits + { + // the specialization below tells Spirit to handle expression_ast as + // if it where a 'real' variant (if used with Spirit.Karma) + template <> + struct not_is_variant<expression_ast, karma::domain> + : mpl::false_ {}; + + // the specialization of variant_which allows to generically extract + // the current type stored in the given variant like type + template <> + struct variant_which<expression_ast> + { + static int call(expression_ast const& v) + { + return v.which(); + } + }; + }} +} + +/////////////////////////////////////////////////////////////////////////////// +struct binary_op +{ + binary_op() {} + + binary_op( + char op + , expression_ast const& left + , expression_ast const& right) + : op(op), left(left), right(right) {} + + char op; + expression_ast left; + expression_ast right; +}; + +struct unary_op +{ + unary_op( + char op + , expression_ast const& right) + : op(op), right(right) {} + + char op; + expression_ast right; +}; + +inline expression_ast& expression_ast::operator+=(expression_ast const& rhs) +{ + expr = binary_op('+', expr, rhs); + return *this; +} + +inline expression_ast& expression_ast::operator-=(expression_ast const& rhs) +{ + expr = binary_op('-', expr, rhs); + return *this; +} + +inline expression_ast& expression_ast::operator*=(expression_ast const& rhs) +{ + expr = binary_op('*', expr, rhs); + return *this; +} + +inline expression_ast& expression_ast::operator/=(expression_ast const& rhs) +{ + expr = binary_op('/', expr, rhs); + return *this; +} + +// We should be using expression_ast::operator-. There's a bug +// in phoenix type deduction mechanism that prevents us from +// doing so. Phoenix will be switching to BOOST_TYPEOF. In the +// meantime, we will use a phoenix::function below: +template <char Op> +struct unary_expr +{ + template <typename T> + struct result { typedef T type; }; + + expression_ast operator()(expression_ast const& expr) const + { + return unary_op(Op, expr); + } +}; + +boost::phoenix::function<unary_expr<'+'> > pos; +boost::phoenix::function<unary_expr<'-'> > neg; + +#endif diff --git a/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp b/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp new file mode 100644 index 0000000000..12f1893160 --- /dev/null +++ b/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp @@ -0,0 +1,181 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// A Calculator example demonstrating generation of AST which gets dumped into +// a human readable format afterwards. +// +// [ JDG April 28, 2008 ] +// [ HK April 28, 2008 ] +// +/////////////////////////////////////////////////////////////////////////////// +#include <boost/config/warning_disable.hpp> + +#include <iostream> +#include <vector> +#include <string> + +#include "calc2_ast.hpp" + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/repository/include/karma_subrule.hpp> +#include <boost/fusion/include/adapt_struct.hpp> + +using namespace boost::spirit; +using namespace boost::spirit::ascii; +namespace repo = boost::spirit::repository; + +/////////////////////////////////////////////////////////////////////////////// +// Our calculator parser grammar +/////////////////////////////////////////////////////////////////////////////// +template <typename Iterator> +struct calculator + : qi::grammar<Iterator, expression_ast(), space_type> +{ + calculator() : calculator::base_type(expression) + { + expression = + term [_val = _1] + >> *( ('+' >> term [_val += _1]) + | ('-' >> term [_val -= _1]) + ) + ; + + term = + factor [_val = _1] + >> *( ('*' >> factor [_val *= _1]) + | ('/' >> factor [_val /= _1]) + ) + ; + + factor = + uint_ [_val = _1] + | '(' >> expression [_val = _1] >> ')' + | ('-' >> factor [_val = neg(_1)]) + | ('+' >> factor [_val = pos(_1)]) + ; + } + + qi::rule<Iterator, expression_ast(), space_type> expression, term, factor; +}; + +// We need to tell fusion about our binary_op and unary_op structs +// to make them a first-class fusion citizen +// +// Note: we register the members exactly in the same sequence as we need them +// in the grammar +BOOST_FUSION_ADAPT_STRUCT( + binary_op, + (expression_ast, left) + (char, op) + (expression_ast, right) +) + +BOOST_FUSION_ADAPT_STRUCT( + unary_op, + (char, op) + (expression_ast, right) +) + +/////////////////////////////////////////////////////////////////////////////// +// Our AST grammar for the generator, this just dumps the AST as a expression +/////////////////////////////////////////////////////////////////////////////// +template <typename OuputIterator> +struct dump_ast + : karma::grammar<OuputIterator, expression_ast(), space_type> +{ + dump_ast() : dump_ast::base_type(entry) + { + //[calc2_ast_dump_sr_def + entry %= ( + ast_node %= int_ | binary_node | unary_node + + , binary_node %= '(' << ast_node << char_ << ast_node << ')' + + , unary_node %= '(' << char_ << ast_node << ')' + ); + //] + } + + karma::rule<OuputIterator, expression_ast(), space_type> entry; + + repo::karma::subrule<0, expression_ast()> ast_node; + repo::karma::subrule<1, binary_op()> binary_node; + repo::karma::subrule<2, unary_op()> unary_node; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Main program +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + std::cout << "/////////////////////////////////////////////////////////\n\n"; + std::cout << "Dump AST's for simple expressions...\n\n"; + std::cout << "/////////////////////////////////////////////////////////\n\n"; + std::cout << "Type an expression...or [q or Q] to quit\n\n"; + + // Our parser grammar definitions + typedef std::string::const_iterator iterator_type; + typedef calculator<iterator_type> calculator; + + calculator calc; + + // Our generator grammar definitions + typedef std::back_insert_iterator<std::string> output_iterator_type; + typedef dump_ast<output_iterator_type> dump_ast; + + dump_ast ast_grammar; + + std::string str; + while (std::getline(std::cin, str)) + { + if (str.empty() || str[0] == 'q' || str[0] == 'Q') + break; + + expression_ast ast; + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + bool r = qi::phrase_parse(iter, end, calc, space, ast); + + if (r && iter == end) + { + std::string generated; + output_iterator_type outit(generated); + r = karma::generate_delimited(outit, ast_grammar, space, ast); + + if (r) + { + std::cout << "Got AST:" << std::endl << generated + << std::endl; + std::cout << "-------------------------\n"; + } + else + { + std::cout << "-------------------------\n"; + std::cout << "Generating failed\n"; + std::cout << "-------------------------\n"; + } + } + else + { + std::string rest(iter, end); + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "stopped at: \": " << rest << "\"\n"; + std::cout << "-------------------------\n"; + } + } + + std::cout << "Bye... :-) \n\n"; + return 0; +} + + diff --git a/libs/spirit/repository/example/karma/confix.cpp b/libs/spirit/repository/example/karma/confix.cpp new file mode 100644 index 0000000000..4ea6f21c10 --- /dev/null +++ b/libs/spirit/repository/example/karma/confix.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to demonstrate different use cases for the +// confix generator. + +#include <iostream> +#include <string> +#include <vector> + +//[karma_confix_includes +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/repository/include/karma_confix.hpp> +//] + +//[karma_confix_namespace +using namespace boost::spirit; +using namespace boost::spirit::ascii; +using boost::spirit::repository::confix; +//] + +int main() +{ +//[karma_confix_cpp_comment + // C++ comment + std::cout << + karma::format_delimited( + confix("//", eol)[string], // format description + space, // delimiter + "This is a comment" // data + ) << std::endl; +//] + +//[karma_confix_c_comment + // C comment + std::cout << + karma::format_delimited( + confix("/*", "*/")[string], // format description + space, // delimiter + "This is a comment" // data + ) << std::endl; +//] + +//[karma_confix_function + // Generate a function call with an arbitrary parameter list + std::vector<std::string> parameters; + parameters.push_back("par1"); + parameters.push_back("par2"); + parameters.push_back("par3"); + + std::cout << + karma::format( + string << confix('(', ')')[string % ','], // format description + "func", // function name + parameters // parameter names + ) << std::endl; +//] + + return 0; +} + diff --git a/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp b/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp new file mode 100644 index 0000000000..677cb2637d --- /dev/null +++ b/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp @@ -0,0 +1,235 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// A mini XML-like parser, Karma is used to print out the generated AST +// +// [ JDG March 25, 2007 ] spirit2 +// [ HK April 02, 2007 ] spirit2 +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/config/warning_disable.hpp> + +#include <boost/spirit/include/qi.hpp> +//[mini_xml_karma_sr_includes +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/repository/include/karma_subrule.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_fusion.hpp> +//] +#include <boost/spirit/include/phoenix_function.hpp> +#include <boost/spirit/include/phoenix_stl.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/variant/recursive_variant.hpp> + +#include <iostream> +#include <fstream> +#include <string> +#include <vector> + +//[mini_xml_karma_sr_using +using namespace boost::spirit; +using namespace boost::spirit::ascii; +namespace repo = boost::spirit::repository; +//] + +namespace fusion = boost::fusion; +namespace phoenix = boost::phoenix; + +using phoenix::at_c; +using phoenix::push_back; + +/////////////////////////////////////////////////////////////////////////////// +// Our mini XML tree representation +/////////////////////////////////////////////////////////////////////////////// +struct mini_xml; + +typedef + boost::variant< + boost::recursive_wrapper<mini_xml> + , std::string + > +mini_xml_node; + +struct mini_xml +{ + std::string name; // tag name + std::vector<mini_xml_node> children; // children +}; + +// We need to tell fusion about our mini_xml struct +// to make it a first-class fusion citizen +BOOST_FUSION_ADAPT_STRUCT( + mini_xml, + (std::string, name) + (std::vector<mini_xml_node>, children) +) + +/////////////////////////////////////////////////////////////////////////////// +// Our mini XML grammar definition +/////////////////////////////////////////////////////////////////////////////// +template <typename Iterator> +struct mini_xml_parser : + qi::grammar<Iterator, mini_xml(), space_type> +{ + mini_xml_parser() : mini_xml_parser::base_type(xml) + { + text = lexeme[+(char_ - '<') [_val += _1]]; + node = (xml | text) [_val = _1]; + + start_tag = + '<' + >> !lit('/') + >> lexeme[+(char_ - '>') [_val += _1]] + >> '>' + ; + + end_tag = + "</" + >> lit(_r1) + >> '>' + ; + + xml = + start_tag [at_c<0>(_val) = _1] + >> *node [push_back(at_c<1>(_val), _1)] + >> end_tag(at_c<0>(_val)) + ; + } + + qi::rule<Iterator, mini_xml(), space_type> xml; + qi::rule<Iterator, mini_xml_node(), space_type> node; + qi::rule<Iterator, std::string(), space_type> text; + qi::rule<Iterator, std::string(), space_type> start_tag; + qi::rule<Iterator, void(std::string), space_type> end_tag; +}; + +/////////////////////////////////////////////////////////////////////////////// +// A couple of phoenix functions helping to access the elements of the +// generated AST +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct get_element +{ + template <typename T1> + struct result { typedef T const& type; }; + + T const& operator()(mini_xml_node const& node) const + { + return boost::get<T>(node); + } +}; + +phoenix::function<get_element<std::string> > _string; +phoenix::function<get_element<mini_xml> > _xml; + +/////////////////////////////////////////////////////////////////////////////// +// The output grammar defining the format of the generated data +/////////////////////////////////////////////////////////////////////////////// +//[mini_xml_karma_sr_grammar +template <typename OutputIterator> +struct mini_xml_generator + : karma::grammar<OutputIterator, mini_xml()> +{ + mini_xml_generator() : mini_xml_generator::base_type(entry) + { + entry %= ( + xml = + '<' << string[_1 = at_c<0>(_val)] << '>' + << (*node)[_1 = at_c<1>(_val)] + << "</" << string[_1 = at_c<0>(_val)] << '>' + + , node %= string | xml + ); + } + + karma::rule<OutputIterator, mini_xml()> entry; + + repo::karma::subrule<0, mini_xml()> xml; + repo::karma::subrule<1, mini_xml_node()> node; +}; +//] + +/////////////////////////////////////////////////////////////////////////////// +// Main program +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char **argv) +{ + char const* filename; + if (argc > 1) + { + filename = argv[1]; + } + else + { + std::cerr << "Error: No input file provided." << std::endl; + return 1; + } + + std::ifstream in(filename, std::ios_base::in); + + if (!in) + { + std::cerr << "Error: Could not open input file: " + << filename << std::endl; + return 1; + } + + std::string storage; // We will read the contents here. + in.unsetf(std::ios::skipws); // No white space skipping! + std::copy( + std::istream_iterator<char>(in), + std::istream_iterator<char>(), + std::back_inserter(storage)); + + typedef mini_xml_parser<std::string::const_iterator> mini_xml_parser; + mini_xml_parser xmlin; // Our grammar definition + mini_xml ast; // our tree + + std::string::const_iterator iter = storage.begin(); + std::string::const_iterator end = storage.end(); + bool r = qi::phrase_parse(iter, end, xmlin, space, ast); + + if (r && iter == end) + { + std::cout << "-------------------------\n"; + std::cout << "Parsing succeeded\n"; + std::cout << "-------------------------\n"; + + typedef std::back_insert_iterator<std::string> outiter_type; + typedef mini_xml_generator<outiter_type> mini_xml_generator; + + mini_xml_generator xmlout; // Our grammar definition + + std::string generated; + outiter_type outit(generated); + bool r = karma::generate(outit, xmlout, ast); + + if (r) + std::cout << generated << std::endl; + return 0; + } + else + { + std::string::const_iterator begin = storage.begin(); + std::size_t dist = std::distance(begin, iter); + std::string::const_iterator some = + iter + (std::min)(storage.size()-dist, std::size_t(30)); + std::string context(iter, some); + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "stopped at: \": " << context << "...\"\n"; + std::cout << "-------------------------\n"; + return 1; + } +} + + diff --git a/libs/spirit/repository/example/qi/Jamfile b/libs/spirit/repository/example/qi/Jamfile new file mode 100644 index 0000000000..b0a92c8ecb --- /dev/null +++ b/libs/spirit/repository/example/qi/Jamfile @@ -0,0 +1,24 @@ +#============================================================================== +# Copyright (c) 2001-2009 Joel de Guzman +# Copyright (c) 2001-2009 Hartmut Kaiser +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +project spirit_v2_repository/example_qi + : requirements + <toolset>gcc:<cxxflags>-ftemplate-depth-300 + <toolset>darwin:<cxxflags>-ftemplate-depth-300 + ; + +exe qi_confix : confix.cpp ; +exe qi_distinct : distinct.cpp ; +exe flush_multi_pass : flush_multi_pass.cpp ; +exe calc1_sr : calc1_sr.cpp ; +exe mini_xml2_sr : mini_xml2_sr.cpp ; +exe advance : advance.cpp ; +exe keywords : keywords.cpp ; +exe derived : derived.cpp ; +exe options : options.cpp ; +exe seek : seek.cpp ; diff --git a/libs/spirit/repository/example/qi/advance.cpp b/libs/spirit/repository/example/qi/advance.cpp new file mode 100644 index 0000000000..e47d32ee1e --- /dev/null +++ b/libs/spirit/repository/example/qi/advance.cpp @@ -0,0 +1,110 @@ +// Copyright (c) 2011 Aaron Graham +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to demonstrate the use of the advance parser. + +//[qi_advance_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/repository/include/qi_advance.hpp> +//] + +#include <list> +#include <string> + +//[qi_advance_namespaces +namespace qi = boost::spirit::qi; +using boost::spirit::repository::qi::advance; +//] + +namespace client +{ + //[qi_advance_grammar + template <typename Iterator> + struct advance_grammar : qi::grammar<Iterator, qi::locals<int> > + { + advance_grammar() : advance_grammar::base_type(start) + { + using qi::byte_; + using qi::eoi; + using namespace qi::labels; + + start + = byte_ [_a = _1] + >> advance(_a) + >> "boost" + >> byte_ [_a = _1] + >> (advance(_a) | "qi") // note alternative when advance fails + >> eoi + ; + } + + qi::rule<Iterator, qi::locals<int> > start; + }; + //] +} + +int main() +{ + // This parser is tested with both random access iterators (std::string) + // and bidirectional iterators (std::list). + char const* result; + + //[qi_advance_example1 + unsigned char const alt1[] = + { + 5, // number of bytes to advance + 1, 2, 3, 4, 5, // data to advance through + 'b', 'o', 'o', 's', 't', // word to parse + 2, // number of bytes to advance + 11, 12 // more data to advance through + // eoi + }; + + std::string const alt1_string(alt1, alt1 + sizeof alt1); + std::list<unsigned char> const alt1_list(alt1, alt1 + sizeof alt1); + + result = + qi::parse(alt1_string.begin(), alt1_string.end() + , client::advance_grammar<std::string::const_iterator>()) + ? "succeeded" : "failed"; + std::cout << "Parsing alt1 using random access iterator " << result << std::endl; + + result = + qi::parse(alt1_list.begin(), alt1_list.end() + , client::advance_grammar<std::list<unsigned char>::const_iterator>()) + ? "succeeded" : "failed"; + std::cout << "Parsing alt1 using bidirectional iterator " << result << std::endl; + //] + + //[qi_advance_example2 + unsigned char const alt2[] = + { + 2, // number of bytes to advance + 1, 2, // data to advance through + 'b', 'o', 'o', 's', 't', // word to parse + 4, // number of bytes to advance + 'q', 'i' // alternative (advance won't work) + // eoi + }; + + std::string const alt2_string(alt2, alt2 + sizeof alt2); + std::list<unsigned char> const alt2_list(alt2, alt2 + sizeof alt2); + + result = + qi::parse(alt2_string.begin(), alt2_string.end() + , client::advance_grammar<std::string::const_iterator>()) + ? "succeeded" : "failed"; + std::cout << "Parsing alt2 using random access iterator " << result << std::endl; + + result = + qi::parse(alt2_list.begin(), alt2_list.end() + , client::advance_grammar<std::list<unsigned char>::const_iterator>()) + ? "succeeded" : "failed"; + std::cout << "Parsing alt2 using bidirectional iterator " << result << std::endl; + //] + + return 0; +} diff --git a/libs/spirit/repository/example/qi/calc1_sr.cpp b/libs/spirit/repository/example/qi/calc1_sr.cpp new file mode 100644 index 0000000000..031a33f50a --- /dev/null +++ b/libs/spirit/repository/example/qi/calc1_sr.cpp @@ -0,0 +1,118 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// Plain calculator example demonstrating the grammar. The parser is a +// syntax checker only and does not do any semantic evaluation. +// +// [ JDG May 10, 2002 ] spirit1 +// [ JDG March 4, 2007 ] spirit2 +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_subrule.hpp> +#include <iostream> +#include <string> + +namespace client +{ + namespace qi = boost::spirit::qi; + namespace repo = boost::spirit::repository; + namespace ascii = boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////////////// + // Our calculator grammar + /////////////////////////////////////////////////////////////////////////////// + template <typename Iterator> + struct calculator : qi::grammar<Iterator, ascii::space_type> + { + calculator() : calculator::base_type(entry) + { + using qi::uint_; + + //[calc1_sr_def + entry = ( + expression = + term + >> *( ('+' >> term) + | ('-' >> term) + ) + + , term = + factor + >> *( ('*' >> factor) + | ('/' >> factor) + ) + + , factor = + uint_ + | '(' >> expression >> ')' + | ('-' >> factor) + | ('+' >> factor) + ); + //] + } + + qi::rule<Iterator, ascii::space_type> entry; + + repo::qi::subrule<0> expression; + repo::qi::subrule<1> term; + repo::qi::subrule<2> factor; + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// Main program +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + std::cout << "/////////////////////////////////////////////////////////\n\n"; + std::cout << "Expression parser...\n\n"; + std::cout << "/////////////////////////////////////////////////////////\n\n"; + std::cout << "Type an expression...or [q or Q] to quit\n\n"; + + using boost::spirit::ascii::space; + typedef std::string::const_iterator iterator_type; + typedef client::calculator<iterator_type> calculator; + + calculator calc; // Our grammar + + std::string str; + while (std::getline(std::cin, str)) + { + if (str.empty() || str[0] == 'q' || str[0] == 'Q') + break; + + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + bool r = phrase_parse(iter, end, calc, space); + + if (r && iter == end) + { + std::cout << "-------------------------\n"; + std::cout << "Parsing succeeded\n"; + std::cout << "-------------------------\n"; + } + else + { + std::string rest(iter, end); + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "stopped at: \": " << rest << "\"\n"; + std::cout << "-------------------------\n"; + } + } + + std::cout << "Bye... :-) \n\n"; + return 0; +} + + diff --git a/libs/spirit/repository/example/qi/confix.cpp b/libs/spirit/repository/example/qi/confix.cpp new file mode 100644 index 0000000000..2426e824ce --- /dev/null +++ b/libs/spirit/repository/example/qi/confix.cpp @@ -0,0 +1,113 @@ +// Copyright (c) 2009 Chris Hoeppler +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to demonstrate different use cases for the +// confix directive. + +#include <iostream> +#include <string> +#include <vector> + +//[qi_confix_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_confix.hpp> +//] + +namespace client { +//[qi_confix_using + using boost::spirit::eol; + using boost::spirit::lexeme; + using boost::spirit::ascii::alnum; + using boost::spirit::ascii::char_; + using boost::spirit::ascii::space; + using boost::spirit::qi::parse; + using boost::spirit::qi::phrase_parse; + using boost::spirit::repository::confix; +//] + +//[qi_confix_cpp_comment + template <typename Iterator> + bool parse_cpp_comment(Iterator first, Iterator last, std::string& attr) + { + bool r = parse(first, last, + confix("//", eol)[*(char_ - eol)], // grammar + attr); // attribute + + if (!r || first != last) // fail if we did not get a full match + return false; + return r; + } +//] + +//[qi_confix_c_comment + template <typename Iterator> + bool parse_c_comment(Iterator first, Iterator last, std::string& attr) + { + bool r = parse(first, last, + confix("/*", "*/")[*(char_ - "*/")], // grammar + attr); // attribute + + if (!r || first != last) // fail if we did not get a full match + return false; + return r; + } +//] + +//[qi_confix_tagged_data + template <typename Iterator> + bool parse_tagged(Iterator first, Iterator last, std::string& attr) + { + bool r = phrase_parse(first, last, + confix("<b>", "</b>")[lexeme[*(char_ - '<')]], // grammar + space, // skip + attr); // attribute + + if (!r || first != last) // fail if we did not get a full match + return false; + return r; + } +//] +} + + +int main() +{ + // C++ comment + std::string comment("// This is a comment\n"); + std::string attr; + bool r = client::parse_cpp_comment(comment.begin(), comment.end(), attr); + + std::cout << "Parsing a C++ comment"; + if (r && attr == " This is a comment") + std::cout << " succeeded." << std::endl; + else + std::cout << " failed" << std::endl; + + // C comment + comment = "/* This is another comment */"; + attr.clear(); + r = client::parse_c_comment(comment.begin(), comment.end(), attr); + + std::cout << "Parsing a C comment"; + if (r && attr == " This is another comment ") + std::cout << " succeeded." << std::endl; + else + std::cout << " failed" << std::endl; + + // Tagged data + std::string data = "<b> This is the body. </b>"; + attr.clear(); + + r = client::parse_tagged(data.begin(), data.end(), attr); + + std::cout << "Parsing tagged data"; + if (r && attr == "This is the body. ") + std::cout << " succeeded." << std::endl; + else + std::cout << " failed" << std::endl; + + return 0; +} + diff --git a/libs/spirit/repository/example/qi/derived.cpp b/libs/spirit/repository/example/qi/derived.cpp new file mode 100644 index 0000000000..a92490a989 --- /dev/null +++ b/libs/spirit/repository/example/qi/derived.cpp @@ -0,0 +1,158 @@ +/*============================================================================= + Copyright (c) 2011 Thomas Bernard + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +//[reference_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_fusion.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/spirit/repository/include/qi_kwd.hpp> +#include <boost/spirit/repository/include/qi_keywords.hpp> +#include <iostream> +#include <string> +#include <cstdlib> +#include <iterator> +//] + + +// Data structure definitions + +struct base_type { + base_type(const std::string &name) : name(name) {} + std::string name; + + virtual std::ostream &output(std::ostream &os) const + { + os<<"Base : "<<name; + return os; + } + +}; + +struct derived1 : public base_type { + derived1(const std::string &name, unsigned int data1) : base_type(name), data1(data1) {} + unsigned int data1; + + virtual std::ostream &output(std::ostream &os) const + { + base_type::output(os); + os<<", "<<data1; + return os; + } + +}; + +struct derived2 : public base_type { + derived2(const std::string &name, unsigned int data2) : base_type(name), data2(data2) {} + unsigned int data2; + virtual std::ostream &output(std::ostream &os) const + { + base_type::output(os); + os<<", "<<data2; + return os; + } + +}; + +struct derived3 : public derived2 { + derived3(const std::string &name, unsigned int data2, double data3) : + derived2(name,data2), + data3(data3) {} + double data3; + + virtual std::ostream &output(std::ostream &os) const + { + derived2::output(os); + os<<", "<<data3; + return os; + } + + +}; + +std::ostream &operator<<(std::ostream &os, const base_type &obj) +{ + return obj.output(os); +} + +BOOST_FUSION_ADAPT_STRUCT( base_type, + (std::string, name) +) + +BOOST_FUSION_ADAPT_STRUCT( derived1, + (std::string , name) + (unsigned int , data1) +) +BOOST_FUSION_ADAPT_STRUCT( derived2, + (std::string , name) + (unsigned int, data2) +) +BOOST_FUSION_ADAPT_STRUCT( derived3, + (std::string , name) + (unsigned int, data2) + (double, data3) +) +//] + +int +main() +{ + + + using boost::spirit::repository::qi::kwd; + using boost::spirit::qi::inf; + using boost::spirit::ascii::space_type; + using boost::spirit::ascii::char_; + using boost::spirit::qi::double_; + using boost::spirit::qi::int_; + using boost::spirit::qi::rule; + using boost::spirit::_val; + using boost::spirit::_1; + using boost::spirit::_2; + using boost::spirit::_3; + + + //Rule declarations + rule<const char *, std::string(), space_type> parse_string; + rule<const char *, std::vector<base_type*>(), space_type> kwd_rule; + + // Our string parsing helper + parse_string %= '"'> *(char_-'"') > '"'; + + namespace phx=boost::phoenix; + //[ kwd rule + kwd_rule = + kwd("derived1")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived1>(_1,_2))] ] + / kwd("derived2")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived2>(_1,_2))]] + / kwd("derived3")[ ('=' > parse_string > int_ > double_) [phx::push_back(_val,phx::new_<derived3>(_1,_2,_3))] ] + ; + //] + + using boost::spirit::qi::phrase_parse; + using boost::spirit::qi::ascii::space; + + // The result vector + std::vector<base_type*> result; + + char const input[]="derived2 = \"object1\" 10 derived3= \"object2\" 40 20.0 "; + char const* f(input); + char const* l(f + strlen(f)); + + if (phrase_parse(f, l, kwd_rule, space,result) && (f == l)) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; + + using namespace boost::phoenix::arg_names; + std::for_each(result.begin(),result.end(),std::cout<<*arg1<<std::endl); + // Clean up the vector of pointers + std::for_each(result.begin(),result.end(),phx::delete_(arg1)); + return 0; +} diff --git a/libs/spirit/repository/example/qi/distinct.cpp b/libs/spirit/repository/example/qi/distinct.cpp new file mode 100644 index 0000000000..78bac6ed23 --- /dev/null +++ b/libs/spirit/repository/example/qi/distinct.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to demonstrate different use cases for the +// distinct parser. + +#include <iostream> +#include <string> +#include <vector> + +//[qi_distinct_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_distinct.hpp> +//] + +//[qi_distinct_namespace +using namespace boost::spirit; +using namespace boost::spirit::ascii; +using boost::spirit::repository::distinct; +//] + +int main() +{ + //[qi_distinct_description_ident + { + std::string str("description ident"); + std::string::iterator first(str.begin()); + bool r = qi::phrase_parse(first, str.end() + , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_') + , space); + BOOST_ASSERT(r && first == str.end()); + } + //] + + //[qi_distinct_description__ident + { + std::string str("description--ident"); + std::string::iterator first(str.begin()); + bool r = qi::phrase_parse(first, str.end() + , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_') + , space); + BOOST_ASSERT(r && first == str.end()); + } + //] + + //[qi_distinct_description_ident_error + { + std::string str("description-ident"); + std::string::iterator first(str.begin()); + bool r = qi::phrase_parse(first, str.end() + , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_') + , space); + BOOST_ASSERT(!r && first == str.begin()); + } + //] + + return 0; +} diff --git a/libs/spirit/repository/example/qi/flush_multi_pass.cpp b/libs/spirit/repository/example/qi/flush_multi_pass.cpp new file mode 100644 index 0000000000..79fa2e5717 --- /dev/null +++ b/libs/spirit/repository/example/qi/flush_multi_pass.cpp @@ -0,0 +1,98 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to demonstrate a simple use case for the +// flush_multi_pass parser. + +#include <iostream> +#include <fstream> +#include <string> + +//[qi_flush_multi_pass_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_flush_multi_pass.hpp> +//] + +//[qi_flush_multi_pass_namespace +namespace spirit = boost::spirit; +using boost::spirit::repository::flush_multi_pass; +//] + +namespace client +{ + //[qi_flush_multi_pass_clear_buffer + template <typename Iterator, typename Skipper> + struct preprocessor : spirit::qi::grammar<Iterator, Skipper> + { + // This is a simplified preprocessor grammar recognizing + // + // #define MACRONAME something + // #undef MACRONAME + // + // Its sole purpose is to show an example how to use the + // flush_multi_pass parser. At the end of each line no backtracking can + // occur anymore so that it's safe to clear all internal buffers in the + // multi_pass. + preprocessor() : preprocessor::base_type(file) + { + using spirit::ascii::char_; + using spirit::qi::eol; + using spirit::qi::lit; + + file = + *line + ; + + line = ( command | *(char_ - eol) ) + >> eol + >> flush_multi_pass + ; + + command = + "#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol) + | "#undef" >> *lit(' ') >> *(char_ - eol) + ; + } + + spirit::qi::rule<Iterator, Skipper> file, line, command; + }; + //] +} + +template <typename Iterator, typename Skipper> +bool parse(Iterator& first, Iterator end, Skipper const& skipper) +{ + client::preprocessor<Iterator, Skipper> g; + return boost::spirit::qi::phrase_parse(first, end, g, skipper); +} + +int main() +{ + namespace spirit = boost::spirit; + using spirit::ascii::char_; + using spirit::qi::eol; + + std::ifstream in("flush_multi_pass.txt"); // we get our input from this file + if (!in.is_open()) { + std::cout << "Could not open input file: 'flush_multi_pass.txt'" << std::endl; + return -1; + } + + typedef std::istreambuf_iterator<char> base_iterator_type; + spirit::multi_pass<base_iterator_type> first = + spirit::make_default_multi_pass(base_iterator_type(in)); + spirit::multi_pass<base_iterator_type> end = + spirit::make_default_multi_pass(base_iterator_type()); + + bool result = parse(first, end, '#' >> *(char_ - eol) >> eol); + if (!result) { + std::cout << "Failed parsing input file!" << std::endl; + return -2; + } + + std::cout << "Successfully parsed input file!" << std::endl; + return 0; +} + diff --git a/libs/spirit/repository/example/qi/flush_multi_pass.txt b/libs/spirit/repository/example/qi/flush_multi_pass.txt new file mode 100644 index 0000000000..46cd92eb30 --- /dev/null +++ b/libs/spirit/repository/example/qi/flush_multi_pass.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2001-2009 Hartmut Kaiser +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#define MACRO foo +#undef MACRO + diff --git a/libs/spirit/repository/example/qi/iter_pos_parser.cpp b/libs/spirit/repository/example/qi/iter_pos_parser.cpp new file mode 100644 index 0000000000..28081405cd --- /dev/null +++ b/libs/spirit/repository/example/qi/iter_pos_parser.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// The purpose of this example is to show how a simple custom primitive parser +// component can be written. We develop a custom parser exposing the current +// iterator position as its attribute. +// +// For more information see: http://spirit.sourceforge.net/home/?page_id=567 + +#include <boost/spirit/include/qi_parse_attr.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/repository/include/qi_iter_pos.hpp> + +#include <string> + +namespace qi = boost::spirit::qi; + +int main() +{ + using boost::spirit::repository::qi::iter_pos; + + std::string prefix, suffix; // attributes receiving the + std::string::iterator position; // parsed values + + std::string input("prefix1234567"); + std::string::iterator first = input.begin(); + bool result = + qi::parse(first, input.end() + , +qi::alpha >> iter_pos >> +qi::digit + , prefix, position, suffix); + + if (result) + { + std::cout << "-------------------------------- \n"; + std::cout << "Parsing succeeded\n"; + std::cout << "prefix is: " << prefix << "\n"; + std::cout << "suffix is: " << suffix << "\n"; + std::cout << "position is: " << std::distance(input.begin(), position) << "\n"; + std::cout << "-------------------------------- \n"; + } + else + { + std::cout << "-------------------------------- \n"; + std::cout << "Parsing failed\n"; + std::cout << "-------------------------------- \n"; + } + return 0; +} diff --git a/libs/spirit/repository/example/qi/keywords.cpp b/libs/spirit/repository/example/qi/keywords.cpp new file mode 100644 index 0000000000..9d52b41d0f --- /dev/null +++ b/libs/spirit/repository/example/qi/keywords.cpp @@ -0,0 +1,214 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +//[reference_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/spirit/repository/include/qi_kwd.hpp> +#include <boost/spirit/repository/include/qi_keywords.hpp> +#include <iostream> +#include <string> +#include <cstdlib> +#include <iterator> +//] + +//[reference_test +template <typename P> +void test_parser( + char const* input, P const& p, bool full_match = true) +{ + using boost::spirit::qi::parse; + + char const* f(input); + char const* l(f + strlen(f)); + if (parse(f, l, p) && (!full_match || (f == l))) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; +} + +template <typename P> +void test_phrase_parser( + char const* input, P const& p, bool full_match = true) +{ + using boost::spirit::qi::phrase_parse; + using boost::spirit::qi::ascii::space; + + char const* f(input); + char const* l(f + strlen(f)); + if (phrase_parse(f, l, p, space) && (!full_match || (f == l))) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; +} +//] + +//[reference_test_attr +template <typename P, typename T> +void test_parser_attr( + char const* input, P const& p, T& attr, bool full_match = true) +{ + using boost::spirit::qi::parse; + + char const* f(input); + char const* l(f + strlen(f)); + if (parse(f, l, p, attr) && (!full_match || (f == l))) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; +} + +template <typename P, typename T> +void test_phrase_parser_attr( + char const* input, P const& p, T& attr, bool full_match = true) +{ + using boost::spirit::qi::phrase_parse; + using boost::spirit::qi::ascii::space; + + char const* f(input); + char const* l(f + strlen(f)); + if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l))) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; +} +//] + + + +//[reference_keyword_list_test_data_structure +// Data structure definitions to test the kwd directive +// and the keywords list operator + +struct person { + std::string name; + int age; + double size; + std::vector<std::string> favorite_colors; + +}; + +std::ostream &operator<<(std::ostream &os, const person &p) +{ + os<<"Person : "<<p.name<<", "<<p.age<<", "<<p.size<<std::endl; + std::copy(p.favorite_colors.begin(),p.favorite_colors.end(),std::ostream_iterator<std::string>(os,"\n")); + return os; +} + +BOOST_FUSION_ADAPT_STRUCT( person, + (std::string, name) + (int, age) + (double, size) + (std::vector<std::string>, favorite_colors) +) +//] + +int +main() +{ + + // keyword_list + { + //[reference_using_declarations_keyword_list + using boost::spirit::repository::qi::kwd; + using boost::spirit::qi::inf; + using boost::spirit::ascii::space_type; + using boost::spirit::ascii::char_; + using boost::spirit::qi::double_; + using boost::spirit::qi::int_; + using boost::spirit::qi::rule; + //] + + //[reference_keyword_list_rule_declarations + rule<const char *, std::string(), space_type> parse_string; + rule<const char *, person(), space_type> no_constraint_person_rule, constraint_person_rule; + + parse_string %= '"'> *(char_-'"') > '"'; + //] + + //[reference_keyword_list_no_constraint_rule + no_constraint_person_rule %= + kwd("name")['=' > parse_string ] + / kwd("age") ['=' > int_] + / kwd("size") ['=' > double_ > 'm'] + ; + //] + + + //[reference_keyword_list + //`Parsing a keyword list: + // Let's declare a small list of people for which we want to collect information. + person John,Mary,Mike,Hellen,Johny; + test_phrase_parser_attr( + "name = \"John\" \n age = 10 \n size = 1.69m " + ,no_constraint_person_rule + ,John); // full in orginal order + std::cout<<John; + + test_phrase_parser_attr( + "age = 10 \n size = 1.69m \n name = \"Mary\"" + ,no_constraint_person_rule + ,Mary); // keyword oder doesn't matter + std::cout<<Mary; + + test_phrase_parser_attr( + "size = 1.69m \n name = \"Mike\" \n age = 10 " + ,no_constraint_person_rule + ,Mike); // still the same result + + std::cout<<Mike; + + /*`The code above will print:[teletype] + + Person : John, 10, 1.69 + Person : Mary, 10, 1.69 + Person : Mike, 10, 1.69 + */ + //] + + //[reference_keyword_list_constraint_rule + /*`The parser definition below uses the kwd directive occurence constraint variants to + make sure that the name and age keyword occur only once and allows the favorite color + entry to appear 0 or more times. */ + constraint_person_rule %= + kwd("name",1) ['=' > parse_string ] + / kwd("age" ,1) ['=' > int_] + / kwd("size" ,1) ['=' > double_ > 'm'] + / kwd("favorite color",0,inf) [ '=' > parse_string ] + ; + //] + + //[reference_keyword_list_constraints + + // Here all the give constraint are resepected : parsing will succeed. + test_phrase_parser_attr( + "name = \"Hellen\" \n age = 10 \n size = 1.80m \n favorite color = \"blue\" \n favorite color = \"green\" " + ,constraint_person_rule + ,Hellen); + std::cout<<Hellen; + + // Parsing this string will fail because the age and size minimum occurence requirements aren't met. + test_phrase_parser_attr( + "name = \"Johny\" \n favorite color = \"blue\" \n favorite color = \"green\" " + ,constraint_person_rule + ,Johny ); + + /*`Parsing the first string will succeed but fail for the second string as the + occurence constraints aren't met. This code should print:[teletype] + + Person : Hellen, 10, 1.8 + blue + green + */ + //] + } + + + return 0; +} diff --git a/libs/spirit/repository/example/qi/mini_xml2_sr.cpp b/libs/spirit/repository/example/qi/mini_xml2_sr.cpp new file mode 100644 index 0000000000..0cd223debd --- /dev/null +++ b/libs/spirit/repository/example/qi/mini_xml2_sr.cpp @@ -0,0 +1,246 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +/////////////////////////////////////////////////////////////////////////////// +// +// A mini XML-like parser +// +// [ JDG March 25, 2007 ] spirit2 +// +/////////////////////////////////////////////////////////////////////////////// + +#include <boost/config/warning_disable.hpp> +//[mini_xml2_sr_includes +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_subrule.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +//] +#include <boost/spirit/include/phoenix_fusion.hpp> +#include <boost/spirit/include/phoenix_stl.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/variant/recursive_variant.hpp> +#include <boost/foreach.hpp> + +#include <iostream> +#include <fstream> +#include <string> +#include <vector> + +namespace client +{ + namespace fusion = boost::fusion; + namespace phoenix = boost::phoenix; + //[mini_xml2_sr_using + namespace qi = boost::spirit::qi; + namespace repo = boost::spirit::repository; + namespace ascii = boost::spirit::ascii; + //] + + /////////////////////////////////////////////////////////////////////////// + // Our mini XML tree representation + /////////////////////////////////////////////////////////////////////////// + struct mini_xml; + + typedef + boost::variant< + boost::recursive_wrapper<mini_xml> + , std::string + > + mini_xml_node; + + struct mini_xml + { + std::string name; // tag name + std::vector<mini_xml_node> children; // children + }; +} + +// We need to tell fusion about our mini_xml struct +// to make it a first-class fusion citizen +BOOST_FUSION_ADAPT_STRUCT( + client::mini_xml, + (std::string, name) + (std::vector<client::mini_xml_node>, children) +) + +namespace client +{ + /////////////////////////////////////////////////////////////////////////// + // Print out the mini xml tree + /////////////////////////////////////////////////////////////////////////// + int const tabsize = 4; + + void tab(int indent) + { + for (int i = 0; i < indent; ++i) + std::cout << ' '; + } + + struct mini_xml_printer + { + mini_xml_printer(int indent = 0) + : indent(indent) + { + } + + void operator()(mini_xml const& xml) const; + + int indent; + }; + + struct mini_xml_node_printer : boost::static_visitor<> + { + mini_xml_node_printer(int indent = 0) + : indent(indent) + { + } + + void operator()(mini_xml const& xml) const + { + mini_xml_printer(indent+tabsize)(xml); + } + + void operator()(std::string const& text) const + { + tab(indent+tabsize); + std::cout << "text: \"" << text << '"' << std::endl; + } + + int indent; + }; + + void mini_xml_printer::operator()(mini_xml const& xml) const + { + tab(indent); + std::cout << "tag: " << xml.name << std::endl; + tab(indent); + std::cout << '{' << std::endl; + + BOOST_FOREACH(mini_xml_node const& node, xml.children) + { + boost::apply_visitor(mini_xml_node_printer(indent), node); + } + + tab(indent); + std::cout << '}' << std::endl; + } + + /////////////////////////////////////////////////////////////////////////// + // Our mini XML grammar definition + /////////////////////////////////////////////////////////////////////////// + //[mini_xml2_sr_grammar + template <typename Iterator> + struct mini_xml_grammar + : qi::grammar<Iterator, mini_xml(), ascii::space_type> + { + mini_xml_grammar() + : mini_xml_grammar::base_type(entry) + { + using qi::lit; + using qi::lexeme; + using ascii::char_; + using ascii::string; + using namespace qi::labels; + + entry %= ( + xml %= + start_tag[_a = _1] + >> *node + >> end_tag(_a) + + , node %= xml | text + + , text %= lexeme[+(char_ - '<')] + + , start_tag %= + '<' + >> !lit('/') + >> lexeme[+(char_ - '>')] + >> '>' + + , end_tag %= + "</" + >> string(_r1) + >> '>' + ); + } + + qi::rule<Iterator, mini_xml(), ascii::space_type> entry; + + repo::qi::subrule<0, mini_xml(), qi::locals<std::string> > xml; + repo::qi::subrule<1, mini_xml_node()> node; + repo::qi::subrule<2, std::string()> text; + repo::qi::subrule<3, std::string()> start_tag; + repo::qi::subrule<4, void(std::string)> end_tag; + }; + //] +} + +/////////////////////////////////////////////////////////////////////////////// +// Main program +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char **argv) +{ + char const* filename; + if (argc > 1) + { + filename = argv[1]; + } + else + { + std::cerr << "Error: No input file provided." << std::endl; + return 1; + } + + std::ifstream in(filename, std::ios_base::in); + + if (!in) + { + std::cerr << "Error: Could not open input file: " + << filename << std::endl; + return 1; + } + + std::string storage; // We will read the contents here. + in.unsetf(std::ios::skipws); // No white space skipping! + std::copy( + std::istream_iterator<char>(in), + std::istream_iterator<char>(), + std::back_inserter(storage)); + + typedef client::mini_xml_grammar<std::string::const_iterator> mini_xml_grammar; + mini_xml_grammar xml; // Our grammar + client::mini_xml ast; // Our tree + + using boost::spirit::ascii::space; + std::string::const_iterator iter = storage.begin(); + std::string::const_iterator end = storage.end(); + bool r = phrase_parse(iter, end, xml, space, ast); + + if (r && iter == end) + { + std::cout << "-------------------------\n"; + std::cout << "Parsing succeeded\n"; + std::cout << "-------------------------\n"; + client::mini_xml_printer printer; + printer(ast); + return 0; + } + else + { + std::string::const_iterator some = iter+30; + std::string context(iter, (some>end)?end:some); + std::cout << "-------------------------\n"; + std::cout << "Parsing failed\n"; + std::cout << "stopped at: \": " << context << "...\"\n"; + std::cout << "-------------------------\n"; + return 1; + } +} + + diff --git a/libs/spirit/repository/example/qi/options.cpp b/libs/spirit/repository/example/qi/options.cpp new file mode 100644 index 0000000000..3bad27c283 --- /dev/null +++ b/libs/spirit/repository/example/qi/options.cpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/spirit/repository/include/qi_kwd.hpp> +#include <boost/spirit/repository/include/qi_keywords.hpp> +#include <boost/optional.hpp> +#include <boost/cstdint.hpp> +#include <iostream> +#include <string> +#include <cstdlib> +#include <iterator> +#include <map> +#include <vector> + +// Data structure definitions + +// preprocessor constants +typedef std::pair<std::string, boost::int32_t> preprocessor_symbol; + +BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol, + (std::string, first) + (boost::int32_t, second) +) + +// A data structure to store our program options +struct program_options { + std::vector<std::string> includes; // include paths + typedef std::vector< preprocessor_symbol > preprocessor_symbols_container; // symbol container type definition + preprocessor_symbols_container preprocessor_symbols; // preprocessor symbols + boost::optional<std::string> output_filename; // output file name + std::string source_filename; // source file name + +}; + +// Make the program_options compatible with fusion sequences +BOOST_FUSION_ADAPT_STRUCT( program_options, + (std::vector<std::string>, includes) + (program_options::preprocessor_symbols_container, preprocessor_symbols) + (boost::optional<std::string>, output_filename) + (std::string, source_filename) +) + + +// Output helper to check that the data parsed matches what we expect +std::ostream &operator<<(std::ostream &os, const program_options &obj) +{ + using boost::spirit::karma::string; + using boost::spirit::karma::int_; + using boost::spirit::karma::lit; + using boost::spirit::karma::buffer; + using boost::spirit::karma::eol; + using boost::spirit::karma::format; + return os<<format( + lit("Includes:") << (string % ',') << eol + << lit("Preprocessor symbols:") << ((string <<"="<< int_) % ',') << eol + << buffer[-( lit("Output file:")<< string << eol)] + << lit("Source file:")<< string << eol + ,obj); + return os; +} + + +int +main() +{ + + { + // Pull everything we need from qi into this scope + using boost::spirit::repository::qi::kwd; + using boost::spirit::qi::inf; + using boost::spirit::ascii::space_type; + using boost::spirit::ascii::alnum; + using boost::spirit::qi::int_; + using boost::spirit::qi::rule; + using boost::spirit::qi::lit; + using boost::spirit::qi::attr; + using boost::spirit::qi::lexeme; + using boost::spirit::qi::hold; + using boost::spirit::qi::ascii::space; + + //Rule declarations + rule<const char *, std::string(), space_type> parse_string; + rule<const char *, program_options(), space_type> kwd_rule; + + // A string parser + parse_string %= lexeme[*alnum]; + + namespace phx=boost::phoenix; + // kwd rule + kwd_rule %= + kwd("--include")[ parse_string ] + / kwd("--define")[ parse_string >> ((lit('=') > int_) | attr(1)) ] + / kwd("--output",0,1)[ parse_string ] + / hold [kwd("--source",1)[ parse_string ]] + ; + // + + using boost::spirit::qi::phrase_parse; + + // Let's check what that parser can do + program_options result; + + char const input[]="--include path1 --source file1 --define SYMBOL1=10 --include path2 --source file2"; + char const* f(input); + char const* l(f + strlen(f)); + if (phrase_parse(f, l, kwd_rule, space,result) && (f == l)) + std::cout << "ok" << std::endl; + else + std::cout << "fail" << std::endl; + + // Output the result to the console + std::cout<<result<<std::endl; +} + return 0; +} diff --git a/libs/spirit/repository/example/qi/seek.cpp b/libs/spirit/repository/example/qi/seek.cpp new file mode 100644 index 0000000000..d854c02195 --- /dev/null +++ b/libs/spirit/repository/example/qi/seek.cpp @@ -0,0 +1,48 @@ +/*////////////////////////////////////////////////////////////////////////////// + Copyright (c) 2011 Jamboree + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +//////////////////////////////////////////////////////////////////////////////*/ + +// [ Jamboree Oct 27, 2011 ] new example. + + +#include <cstdlib> +#include <iostream> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/repository/include/qi_seek.hpp> + + +int main(int argc, char *argv[]) +{ + //[reference_qi_seek_namespace + namespace qi = boost::spirit::qi; + namespace repo = boost::spirit::repository; + //] + + typedef std::string::const_iterator iterator; + + //[reference_qi_seek_vars + std::string str("/*C-style comment*/"); + iterator it = str.begin(); + iterator end = str.end(); + //] + + //[reference_qi_seek_parse + if (qi::parse(it, end, "/*" >> repo::qi::seek["*/"])) + { + std::cout << "-------------------------------- \n"; + std::cout << "Parsing succeeded.\n"; + std::cout << "---------------------------------\n"; + } + else + { + std::cout << "-------------------------------- \n"; + std::cout << "Unterminated /* comment.\n"; + std::cout << "-------------------------------- \n"; + }//] + + return EXIT_SUCCESS; +} diff --git a/libs/spirit/repository/test/Jamfile b/libs/spirit/repository/test/Jamfile new file mode 100644 index 0000000000..1f38c45874 --- /dev/null +++ b/libs/spirit/repository/test/Jamfile @@ -0,0 +1,38 @@ +#============================================================================== +# Copyright (c) 2001-2009 Joel de Guzman +# Copyright (c) 2001-2009 Hartmut Kaiser +# +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== +project spirit_v2_repository/test + : requirements + <include>. + <toolset>gcc:<cxxflags>-ftemplate-depth-300 <linkflags>-lrt + <toolset>darwin:<cxxflags>-ftemplate-depth-300 + : + : + ; + +# bring in rules for testing +import testing ; + +{ + test-suite spirit_v2_repository : + + # run Qi repository tests + [ run qi/advance.cpp : : : : qi_repo_advance ] + [ run qi/confix.cpp : : : : qi_repo_confix ] + [ run qi/distinct.cpp : : : : qi_repo_distinct ] + [ run qi/subrule.cpp : : : : qi_repo_subrule ] + [ run qi/keywords.cpp : : : : qi_repo_keywords ] + [ run qi/seek.cpp : : : : qi_repo_seek ] + + # run Karma repository tests + [ run karma/confix.cpp : : : : karma_repo_confix ] + [ run karma/subrule.cpp : : : : karma_repo_subrule ] + + ; +} + diff --git a/libs/spirit/repository/test/karma/confix.cpp b/libs/spirit/repository/test/karma/confix.cpp new file mode 100644 index 0000000000..074894a063 --- /dev/null +++ b/libs/spirit/repository/test/karma/confix.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include <boost/spirit/repository/include/karma_confix.hpp> + +#include <iostream> +#include "test.hpp" + +namespace html +{ + namespace spirit = boost::spirit; + namespace repo = boost::spirit::repository; + + /////////////////////////////////////////////////////////////////////////////// + // define a HTML tag helper generator + namespace traits + { + template <typename Prefix, typename Suffix = Prefix> + struct confix_spec + : spirit::result_of::terminal<repo::tag::confix(Prefix, Suffix)> + {}; + }; + + template <typename Prefix, typename Suffix> + inline typename traits::confix_spec<Prefix, Suffix>::type + confix_spec(Prefix const& prefix, Suffix const& suffix) + { + return repo::confix(prefix, suffix); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Traits, typename Allocator> + inline typename traits::confix_spec< + std::basic_string<Char, Traits, Allocator> + >::type + tag (std::basic_string<Char, Traits, Allocator> const& tagname) + { + typedef std::basic_string<Char, Traits, Allocator> string_type; + return confix_spec(string_type("<") + tagname + ">" + , string_type("</") + tagname + ">"); + } + + inline traits::confix_spec<std::string>::type + tag (char const* tagname) + { + return tag(std::string(tagname)); + } + + /////////////////////////////////////////////////////////////////////////// + typedef traits::confix_spec<std::string>::type html_tag_type; + + html_tag_type const ol = tag("ol"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::repository; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST((test("<tag>a</tag>", + confix("<tag>", "</tag>")[char_('a')]))); + BOOST_TEST((test("<tag>a</tag>", + confix("<tag>", "</tag>")[char_], 'a'))); + BOOST_TEST((test("// some C++ comment\n", + confix(string("//"), eol)[" some C++ comment"]))); + BOOST_TEST((test("// some C++ comment\n", + confix(string("//"), eol)[string], " some C++ comment"))); + + BOOST_TEST((test("<ol>some text</ol>", html::ol["some text"]))); + BOOST_TEST((test("<ol>some text</ol>", html::ol[string], "some text"))); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST((test(L"<tag>a</tag>", + confix(L"<tag>", L"</tag>")[char_(L'a')]))); + BOOST_TEST((test(L"// some C++ comment\n", + confix(string(L"//"), eol)[L" some C++ comment"]))); + + BOOST_TEST((test(L"<ol>some text</ol>", html::ol[L"some text"]))); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST((test_delimited("<tag> a </tag> ", + confix("<tag>", "</tag>")[char_('a')], space))); + BOOST_TEST((test_delimited("// some C++ comment \n ", + confix(string("//"), eol)["some C++ comment"], space))); + + BOOST_TEST((test_delimited("<ol> some text </ol> ", + html::ol["some text"], space))); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST((test_delimited(L"<tag> a </tag> ", + confix(L"<tag>", L"</tag>")[char_(L'a')], space))); + BOOST_TEST((test_delimited(L"// some C++ comment \n ", + confix(string(L"//"), eol)[L"some C++ comment"], space))); + + BOOST_TEST((test_delimited(L"<ol> some text </ol> ", + html::ol[L"some text"], space))); + } + + return boost::report_errors(); +} diff --git a/libs/spirit/repository/test/karma/subrule.cpp b/libs/spirit/repository/test/karma/subrule.cpp new file mode 100644 index 0000000000..dd6bdabed2 --- /dev/null +++ b/libs/spirit/repository/test/karma/subrule.cpp @@ -0,0 +1,186 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> +#include <boost/spirit/include/phoenix_fusion.hpp> + +#include <boost/spirit/repository/include/karma_subrule.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::karma; +// using namespace boost::spirit::ascii; + using boost::spirit::repository::karma::subrule; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + // basic tests + { + rule<outiter_type> start; + subrule<0> sr; + + start = ( + sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4] + ); + BOOST_TEST(test("a1012.4", start)); + + BOOST_TEST(test("a1012.4", ( + sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4] + ))); + + subrule<1> a; + subrule<2> b; + subrule<3> c; + + start = ( + sr = a << b << c + , a = char_[_1 = 'a'] + , b = int_[_1 = 10] + , c = double_[_1 = 12.4] + ); + BOOST_TEST(test("a1012.4", start)); + } + + // basic tests with delimiter + { + rule<outiter_type, space_type> start; + subrule<0> sr; + + start = ( + sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4] + ); + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + + BOOST_TEST(test_delimited("a 10 12.4 ", ( + sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4] + ), space)); + + subrule<1> a; + subrule<2> b; + subrule<3> c; + + start = ( + sr = a << b << c + , a = char_[_1 = 'a'] + , b = int_[_1 = 10] + , c = double_[_1 = 12.4] + ); + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + } + + // basic tests involving a direct parameter + { + typedef variant<char, int, double> var_type; + + rule<outiter_type, var_type()> start; + subrule<0, var_type()> sr; + + start = ( + sr = (char_ | int_ | double_)[_1 = _r0] + )[_1 = _val]; + + var_type v ('a'); + BOOST_TEST(test("a", start, v)); + v = 10; + BOOST_TEST(test("10", start, v)); + v = 12.4; + BOOST_TEST(test("12.4", start, v)); + } + + { + typedef variant<char, int, double> var_type; + + rule<outiter_type, space_type, var_type()> start; + subrule<0, var_type()> sr; + + start %= ( + sr = (char_ | int_ | double_)[_1 = _r0] + ); + + var_type v ('a'); + BOOST_TEST(test_delimited("a ", start, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", start, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", start, v, space)); + } + + { + rule<outiter_type, void(char, int, double)> start; + subrule<0, void(char, int, double)> sr; + + start = ( + sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3] + )(_r1, _r2, _r3); + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + + BOOST_TEST(test("a1012.4", ( + sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3] + )('a', 10, 12.4))); + + subrule<1, void(char, int, double)> entry; + subrule<2, void(char)> a; + subrule<3, void(int)> b; + subrule<4, void(double)> c; + + start = ( + entry = a(_r1) << b(_r2) << c(_r3) + , a = char_[_1 = _r1] + , b = int_[_1 = _r1] + , c = double_[_1 = _r1] + )(_r1, _r2, _r3); + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + } + + { + rule<outiter_type, space_type, void(char, int, double)> start; + subrule<0, void(char, int, double)> sr; + + start = ( + sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3] + )(_r1, _r2, _r3); + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + + BOOST_TEST(test_delimited("a 10 12.4 ", ( + sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3] + )('a', 10, 12.4), space)); + + subrule<1, void(char, int, double)> entry; + subrule<2, void(char)> a; + subrule<3, void(int)> b; + subrule<4, void(double)> c; + + start = ( + entry = a(_r1) << b(_r2) << c(_r3) + , a = char_[_1 = _r1] + , b = int_[_1 = _r1] + , c = double_[_1 = _r1] + )(_r1, _r2, _r3); + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/karma/test.hpp b/libs/spirit/repository/test/karma/test.hpp new file mode 100644 index 0000000000..70b89ce522 --- /dev/null +++ b/libs/spirit/repository/test/karma/test.hpp @@ -0,0 +1,297 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM) +#define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <typeinfo> + +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_what.hpp> + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + struct display_type + { + template<typename T> + void operator()(T const &) const + { + std::cout << typeid(T).name() << std::endl; + } + + template<typename T> + static void print() + { + std::cout << typeid(T).name() << std::endl; + } + }; + + display_type const display = {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char> + struct output_iterator + { + typedef std::basic_string<Char> string_type; + typedef std::back_insert_iterator<string_type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename T> + void print_if_failed(char const* func, bool result + , std::basic_string<Char> const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated != expected) + std::cerr << "in " << func << ": generated \"" + << std::string(generated.begin(), generated.end()) + << "\"" << std::endl; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator> + inline bool test(Char const *expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator> + inline bool test(std::basic_string<Char> const& expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Attribute> + inline bool test(Char const *expected, Generator const& g, + Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attr); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Attribute> + inline bool test(std::basic_string<Char> const& expected, Generator const& g, + Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attr); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter> + inline bool test_delimited(Char const *expected, Generator const& g, + Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Delimiter> + inline bool test_delimited(std::basic_string<Char> const& expected, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Attribute, + typename Delimiter> + inline bool test_delimited(Char const *expected, Generator const& g, + Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Attribute, + typename Delimiter> + inline bool test_delimited(std::basic_string<Char> const& expected, + Generator const& g, Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator> + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Attribute> + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g, Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attr); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Delimiter> + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Attribute, typename Delimiter> + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + +} // namespace spirit_test + +#endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM diff --git a/libs/spirit/repository/test/qi/advance.cpp b/libs/spirit/repository/test/qi/advance.cpp new file mode 100644 index 0000000000..160ac55f38 --- /dev/null +++ b/libs/spirit/repository/test/qi/advance.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2001-2010 Joel de Guzman +// Copyright (c) 2011 Aaron Graham +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_binary.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/repository/include/qi_advance.hpp> + +#include <boost/assign/std/list.hpp> +#include "test.hpp" + +namespace spirit_test +{ + template <typename Container, typename Parser> + bool test_c(Container const& in, Parser const& p, bool full_match = true) + { + // we don't care about the results of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + typename Container::const_iterator first = in.begin(); + typename Container::const_iterator const last = in.end(); + return boost::spirit::qi::parse(first, last, p) + && (!full_match || (first == last)); + } +} + +int main() +{ + using spirit_test::test; + using spirit_test::test_c; + + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::uint_; + using boost::spirit::qi::byte_; + + using namespace boost::assign; + using boost::spirit::repository::qi::advance; + + { // test basic functionality with random-access iterators + rule<char const*> start; + + start = 'a' >> advance(3) >> "bc"; + BOOST_TEST(test("a123bc", start)); + + start = (advance(3) | 'q') >> 'i'; + BOOST_TEST(test("qi", start)); + + start = advance(-1); + BOOST_TEST(!test("0", start)); + + start = advance(-1) | "qi"; + BOOST_TEST(test("qi", start)); + + start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0) + >> advance(8) >> 'z'; + BOOST_TEST(test("abcdefghijklmnopqrstuvwxyz", start)); + } + + { // test locals + rule<char const*, locals<unsigned> > start; + + start = byte_ [_a = _1] >> advance(_a) >> "345"; + BOOST_TEST(test("\x02""12345", start)); + BOOST_TEST(!test("\x60""345", start)); + } + + { // test basic functionality with bidirectional iterators + rule<std::list<char>::const_iterator, locals<int> > start; + std::list<char> list; + + list.clear(); + list += 1,2,'a','b','c'; + start = byte_ [_a = _1] >> advance(_a) >> "abc"; + BOOST_TEST(test_c(list, start)); + + list.clear(); + list += 3,'q','i'; + start = byte_ [_a = _1] >> advance(_a); + BOOST_TEST(!test_c(list, start)); + + start = byte_ [_a = _1] >> (advance(_a) | "qi"); + BOOST_TEST(test_c(list, start)); + + list.clear(); + list += 'a','b','c','d','e','f','g','h','i','j','k','l','m'; + list += 'n','o','p','q','r','s','t','u','v','w','x','y','z'; + start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0) + >> advance(8) >> 'z'; + BOOST_TEST(test_c(list, start)); + } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/qi/confix.cpp b/libs/spirit/repository/test/qi/confix.cpp new file mode 100644 index 0000000000..e045026c01 --- /dev/null +++ b/libs/spirit/repository/test/qi/confix.cpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 2009 Chris Hoeppler + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/repository/include/qi_confix.hpp> + +#include <string> +#include "test.hpp" + +namespace comment { + namespace spirit = boost::spirit; + namespace repo = boost::spirit::repository; + + // Define a metafunction allowing to compute the type + // of the confix() construct + template <typename Prefix, typename Suffix = Prefix> + struct confix_spec_traits + { + typedef typename spirit::result_of::terminal< + repo::tag::confix(Prefix, Suffix) + >::type type; + }; + + template <typename Prefix, typename Suffix> + inline typename confix_spec_traits<Prefix, Suffix>::type + confix_spec(Prefix const& prefix, Suffix const& suffix) + { + return repo::confix(prefix, suffix); + } + + inline confix_spec_traits<std::string>::type + confix_spec(const char* prefix, const char* suffix) + { + return repo::confix(std::string(prefix), std::string(suffix)); + } + confix_spec_traits<std::string>::type const c_comment = confix_spec("/*", "*/"); + confix_spec_traits<std::string>::type const cpp_comment = confix_spec("//", "\n"); +} + +int main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::debug; + + namespace phx = boost::phoenix; + namespace repo = boost::spirit::repository; + + { // basic tests + + rule<char const*> start; + + start = repo::confix('a', 'c')['b']; + BOOST_TEST(test("abc", start)); + + start = repo::confix('a', 'c')['b'] | "abd"; + BOOST_TEST(test("abd", start)); + + start = repo::confix("/*", "*/")[*(alpha - "*/")]; + BOOST_TEST(test("/*aaaabababaaabbb*/", start)); + + start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"]; + BOOST_TEST(test("/*aaaabababaaabba*/", start)); + + start = comment::c_comment[*(alpha - "*/")]; + BOOST_TEST(test("/*aaaabababaaabbb*/", start)); + + // ignore the skipper! + BOOST_TEST(!test("/* aaaabababaaabba*/", start, space)); + } + + { // basic tests w/ skipper + + rule<char const*, space_type> start; + + start = repo::confix('a', 'c')['b']; + BOOST_TEST(test(" a b c ", start, space)); + + start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"]; + BOOST_TEST(test(" / *a b a b a b a a a b b b * / ", start, space)); + } + + { // context tests + char ch; + rule<char const*, char()> a; + a = repo::confix("/*", "*/")[alpha][_val = _1]; + + BOOST_TEST(test("/*x*/", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= repo::confix("/*", "*/")[alpha]; + BOOST_TEST(test_attr("/*z*/", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // rules test + rule<char const*> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + + debug(a); + debug(b); + debug(c); + debug(start); + + start = repo::confix(a.alias(), c.alias())[b]; + BOOST_TEST(test("abc", start)); + } + + { // modifiers test + rule<char const*> start; + start = no_case[repo::confix("_A_", "_Z_")["heLLo"]]; + BOOST_TEST(test("_a_hello_z_", start)); + } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/qi/distinct.cpp b/libs/spirit/repository/test/qi/distinct.cpp new file mode 100644 index 0000000000..219492c45e --- /dev/null +++ b/libs/spirit/repository/test/qi/distinct.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2001-2010 Joel de Guzman +// Copyright (c) 2003 Vaclav Vesely +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/mpl/print.hpp> +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_operator.hpp> + +#include <boost/spirit/repository/include/qi_distinct.hpp> + +#include <iostream> +#include "test.hpp" + +using namespace boost; + +/////////////////////////////////////////////////////////////////////////////// +namespace distinct +{ + //[qi_distinct_encapsulation + namespace spirit = boost::spirit; + namespace ascii = boost::spirit::ascii; + namespace repo = boost::spirit::repository; + + // Define metafunctions allowing to compute the type of the distinct() + // and ascii::char_() constructs + namespace traits + { + // Metafunction allowing to get the type of any repository::distinct(...) + // construct + template <typename Tail> + struct distinct_spec + : spirit::result_of::terminal<repo::tag::distinct(Tail)> + {}; + + // Metafunction allowing to get the type of any ascii::char_(...) construct + template <typename String> + struct char_spec + : spirit::result_of::terminal<spirit::tag::ascii::char_(String)> + {}; + }; + + // Define a helper function allowing to create a distinct() construct from + // an arbitrary tail parser + template <typename Tail> + inline typename traits::distinct_spec<Tail>::type + distinct_spec(Tail const& tail) + { + return repo::distinct(tail); + } + + // Define a helper function allowing to create a ascii::char_() construct + // from an arbitrary string representation + template <typename String> + inline typename traits::char_spec<String>::type + char_spec(String const& str) + { + return ascii::char_(str); + } + + // the following constructs the type of a distinct_spec holding a + // charset("0-9a-zA-Z_") as its tail parser + typedef traits::char_spec<std::string>::type charset_tag_type; + typedef traits::distinct_spec<charset_tag_type>::type keyword_tag_type; + + // Define a new Qi 'keyword' directive usable as a shortcut for a + // repository::distinct(char_(std::string("0-9a-zA-Z_"))) + std::string const keyword_spec("0-9a-zA-Z_"); + keyword_tag_type const keyword = distinct_spec(char_spec(keyword_spec)); + //] +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + qi::rule<char const*, space_type> r; + r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"]; + + BOOST_TEST(test("description ident", r, space)); + BOOST_TEST(test("description:ident", r, space)); + BOOST_TEST(test("description: ident", r, space)); + BOOST_TEST(!test("descriptionident", r, space)); + } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/qi/keywords.cpp b/libs/spirit/repository/test/qi/keywords.cpp new file mode 100644 index 0000000000..fb04f16ff4 --- /dev/null +++ b/libs/spirit/repository/test/qi/keywords.cpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2011 Thomas Bernard + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <string> +#include <vector> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/spirit/repository/include/qi_kwd.hpp> +#include <boost/spirit/repository/include/qi_keywords.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +struct x_attr +{ + +}; + +namespace boost { namespace spirit { namespace traits +{ + + + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + + template <> + struct push_back_container<x_attr, char> + { + static bool call(x_attr& /*c*/, char /*val*/) + { + // push back value type into container + return true; + } + }; +}}} + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + using boost::spirit::repository::kwd; + using boost::spirit::repository::ikwd; + using boost::spirit::qi::inf; + using boost::spirit::qi::omit; + using boost::spirit::qi::int_; + using boost::spirit::qi::lit; + using boost::spirit::qi::_1; + using boost::spirit::qi::lexeme; + + { + + // no constraints + boost::fusion::vector<char,char,int> data; + BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space)); + BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + + // Exact + BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space)); + + // Min - Max + BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + + // Min - inf + BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + } + + { // Single keyword, empty string + BOOST_TEST(test(" ", kwd("aad")[char_],space)); + BOOST_TEST(test("aad E ", kwd("aad")[char_],space)); + //BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space)); + + } + + { + // Vector container + boost::fusion::vector<std::vector<int>,std::vector<int>,std::vector<int> > data; + BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space) + && (boost::fusion::at_c<0>(data).size()==1) + && (boost::fusion::at_c<0>(data)[0]==1) + + &&(boost::fusion::at_c<1>(data).size()==2) + &&(boost::fusion::at_c<1>(data)[0]==2) + &&(boost::fusion::at_c<1>(data)[1]==5) + + &&(boost::fusion::at_c<2>(data).size()==1) + &&(boost::fusion::at_c<2>(data)[0]==3) + ); + } + + { + // no_case test + BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space)); + BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space)); + BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + } + + { + // iterator restoration + BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) | lit("ba=") > char_, space)); + BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) | lit("ba=") > char_, space)); + } + + { // actions + namespace phx = boost::phoenix; + + std::vector<int> v; + BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) && + v[0] == 2 ); + } + + { // attribute customization + + x_attr x; +// test_attr("a = b c = d", kwd("a")['=' > char_] / kwd("c")['=' > char_], x); + } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/qi/seek.cpp b/libs/spirit/repository/test/qi/seek.cpp new file mode 100644 index 0000000000..f4dbd976a4 --- /dev/null +++ b/libs/spirit/repository/test/qi/seek.cpp @@ -0,0 +1,101 @@ +/*////////////////////////////////////////////////////////////////////////////// + Copyright (c) 2011 Jamboree + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +//////////////////////////////////////////////////////////////////////////////*/ + + +#include <vector> + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_int.hpp> +#include <boost/spirit/include/qi_sequence.hpp> +#include <boost/spirit/include/qi_plus.hpp> +#include <boost/spirit/include/qi_eoi.hpp> +#include <boost/spirit/include/qi_action.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/repository/include/qi_seek.hpp> + +#include "test.hpp" + + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + namespace qi = boost::spirit::qi; + namespace phx = boost::phoenix; + using boost::spirit::repository::qi::seek; + using boost::spirit::standard::space; + + // test eoi + { + using qi::eoi; + + BOOST_TEST(test("", seek[eoi])); + BOOST_TEST(test(" ", seek[eoi], space)); + BOOST_TEST(test("a", seek[eoi])); + BOOST_TEST(test(" a", seek[eoi], space)); + } + + // test literal finding + { + using qi::int_; + using qi::char_; + + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&*KEY:123", seek["KEY:"] >> int_, i) + && i == 123 + ); + } + + // test sequence finding + { + using qi::int_; + using qi::lit; + + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&* KEY : 123", seek[lit("KEY") >> ':'] >> int_, i, space) + && i == 123 + ); + } + + // test attr finding + { + using qi::int_; + + std::vector<int> v; + + BOOST_TEST( // expect partial match + test_attr("a06b78c3d", +seek[int_], v, false) + && v[0] == 6 && v[1] == 78 && v[2] == 3 + ); + } + + // test action + { + using phx::ref; + + bool b = false; + + BOOST_TEST( // expect partial match + test("abcdefg", seek["def"][ref(b) = true], false) + && b + ); + } + + return boost::report_errors(); +} diff --git a/libs/spirit/repository/test/qi/subrule.cpp b/libs/spirit/repository/test/qi/subrule.cpp new file mode 100644 index 0000000000..33362e8b40 --- /dev/null +++ b/libs/spirit/repository/test/qi/subrule.cpp @@ -0,0 +1,379 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2009 Francois Barel + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <boost/spirit/repository/include/qi_subrule.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::repository::qi::subrule; + + namespace phx = boost::phoenix; + + + { // basic tests + + subrule<99> entry; + subrule<42> a; + subrule<48> b; + subrule<16> c; + rule<char const*> start; + + entry.name("entry"); + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + +// debug(entry); +// debug(a); +// debug(b); +// debug(c); + debug(start); + + // subrules with no rule + BOOST_TEST(test("abcabcacb", ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ))); + + // check subrule group behaves as a parser + BOOST_TEST(test("xabcabcacb", 'x' >> ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ))); + + // subrules in a rule + start = ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ); + BOOST_TEST(test("abcabcacb", start)); + + // subrule -> rule call + start = ( + entry = (a | b) >> (start | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // subrule recursion + start = ( + entry = (a | b) >> (entry | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // no-ops + a = a; + subrule<42> aa(a); + } + + { // basic tests w/ skipper, subrules declared const + + subrule<0> const entry("entry"); + subrule<1> const a("a"); + subrule<2> const b("b"); + subrule<3> const c("c"); + rule<char const*, space_type> start("start"); + +// debug(entry); +// debug(a); +// debug(b); +// debug(c); + debug(start); + + start = ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ); + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + + start = ( + entry = (a | b) >> (entry | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space)); + BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false)); + + // no-ops + a = a; + subrule<1> aa(a); + } + + { // context tests + + char ch; + rule<char const*, char()> a; + subrule<0, char()> entry; + + a = (entry = alpha[_val = _1])[_val = _1]; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= (entry = alpha[_val = _1]); + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto subrules tests + + char ch; + rule<char const*, char()> a; + subrule<0, char()> entry; + + a = (entry %= alpha)[_val = _1]; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= (entry %= alpha); + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto subrules tests: allow stl containers as attributes to + // sequences (in cases where attributes of the elements + // are convertible to the value_type of the container or if + // the element itself is an stl container with value_type + // that is convertible to the value_type of the attribute). + + std::string s; + rule<char const*, std::string()> r; + subrule<0, std::string()> entry; + + r %= (entry %= char_ >> *(',' >> char_)); + BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + + BOOST_TEST(test("abcdef", ( + entry %= char_ >> char_ >> char_ >> char_ >> char_ >> char_ + )[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + } + + { // synth attribute value-init + + std::string s; + subrule<0, char()> sr; + BOOST_TEST(test_attr("abcdef", +(sr = alpha[_val += _1]), s)); + BOOST_TEST(s == "abcdef"); + } + + { // auto subrules aliasing tests + + char ch; + rule<char const*, char()> r; + subrule<0, char()> a; + subrule<1, char()> b; + r %= ( + a %= b + , b %= alpha + ); + + BOOST_TEST(test("x", r[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + BOOST_TEST(test_attr("z", r, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // context (w/arg) tests + + char ch; + + // entry subrule with 1 arg + rule<char const*, char(int)> a; + subrule<1, char(int)> sr1; + a %= ( + sr1 = alpha[_val = _1 + _r1] + )(_r1); + BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x' + 1); + + // other subrule with 1 arg + subrule<0, char()> sr0; + a %= ( + sr0 %= sr1(1) + , sr1 = alpha[_val = _1 + _r1] + ); + + // allow scalars as subrule args too + rule<char const*, char()> b; + b %= ( + sr1 = alpha[_val = _1 + _r1] + )(1); + BOOST_TEST(test_attr("b", b, ch)); + BOOST_TEST(ch == 'b' + 1); + + // entry subrule with 2 args + subrule<2, char(int, int)> sr2; + BOOST_TEST(test_attr("a", ( + sr2 = alpha[_val = _1 + _r1 + _r2] + )(1, 2), ch)); + BOOST_TEST(ch == 'a' + 1 + 2); + + // multiple subrules + args + BOOST_TEST(test_attr("ba", ( + sr2 = alpha[_val = _1 + _r1 + _r2] >> sr1(3)[_val -= _1] + , sr1 = alpha[_val = _1 + _r1] + )(1, 2), ch)); + BOOST_TEST(ch == ('b' + 1 + 2) - ('a' + 3)); + } + + { // context (w/ reference arg) tests + + char ch; + subrule<0, void(char&)> sr; // 1 arg (reference) - direct + BOOST_TEST(test("x", (sr = alpha[_r1 = _1])(phx::ref(ch)))); + BOOST_TEST(ch == 'x'); + + rule<char const*, void(char&)> a; // forwarded via a rule + a = (sr = alpha[_r1 = _1])(_r1); + BOOST_TEST(test("y", a(phx::ref(ch)))); + BOOST_TEST(ch == 'y'); + } + + { // context (w/locals) tests + + rule<char const*> r; + subrule<0, locals<char> > a; // 1 local + r = ( + a = alpha[_a = _1] >> char_(_a) + ); + BOOST_TEST(test("aa", r)); + BOOST_TEST(!test("ax", r)); + } + + { // context (w/args and locals) tests + + rule<char const*, void(int)> a; + subrule<0, void(int), locals<char> > sr; // 1 arg + 1 local + a = ( + sr = alpha[_a = _1 + _r1] >> char_(_a) + )(_r1); + BOOST_TEST(test("ab", a(phx::val(1)))); + BOOST_TEST(test("xy", a(phx::val(1)))); + BOOST_TEST(!test("ax", a(phx::val(1)))); + } + + { // void() has unused type (void == unused_type) + + std::pair<int, char> attr; + subrule<0, void()> sr; + BOOST_TEST(test_attr("123ax", int_ >> char_ >> (sr = char_), attr)); + BOOST_TEST(attr.first == 123); + BOOST_TEST(attr.second == 'a'); + } + + { // test that injected attributes are ok + + rule<char const*> r; + subrule<0, char(int)> sr; + + r = ( + sr = char_(_r1)[_val = _1] + )(42); + } + + { // show that sra = srb and sra %= srb works as expected + subrule<0, int()> sra; + subrule<1, int()> srb; + int attr; + + BOOST_TEST(test_attr("123", (sra %= int_), attr)); + BOOST_TEST(attr == 123); + + BOOST_TEST(test_attr("123", (srb %= sra, sra %= int_), attr)); + BOOST_TEST(attr == 123); + + BOOST_TEST(test_attr("123", (srb = sra, sra %= int_), attr)); + BOOST_TEST(attr == 123); + } + + { // std::string as container attribute with auto subrules + + subrule<0, std::string()> text; + std::string attr; + BOOST_TEST(test_attr("x", ( + text %= +(!char_(')') >> !char_('>') >> char_) + ), attr)); + BOOST_TEST(attr == "x"); + } + +// { // error handling +// +// using namespace boost::spirit::ascii; +// using boost::phoenix::construct; +// using boost::phoenix::bind; +// +// rule<char const*> r; +// r = '(' > int_ > ',' > int_ > ')'; +// +// on_error<fail> +// ( +// r, std::cout +// << phx::val("Error! Expecting: ") +// << _4 +// << phx::val(", got: \"") +// << construct<std::string>(_3, _2) +// << phx::val("\"") +// << std::endl +// ); +// +// BOOST_TEST(test("(123,456)", r)); +// BOOST_TEST(!test("(abc,def)", r)); +// BOOST_TEST(!test("(123,456]", r)); +// BOOST_TEST(!test("(123;456)", r)); +// BOOST_TEST(!test("[123,456]", r)); +// } + + return boost::report_errors(); +} + diff --git a/libs/spirit/repository/test/qi/test.hpp b/libs/spirit/repository/test/qi/test.hpp new file mode 100644 index 0000000000..fba0781fb9 --- /dev/null +++ b/libs/spirit/repository/test/qi/test.hpp @@ -0,0 +1,103 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM) +#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_what.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <boost/foreach.hpp> +#include <iostream> + +namespace spirit_test +{ + template <typename Char, typename Parser> + bool test(Char const* in, Parser const& p, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::parse(in, last, p) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Skipper> + bool test(Char const* in, Parser const& p + , Skipper const& s, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr> + bool test_attr(Char const* in, Parser const& p + , Attr& attr, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::parse(in, last, p, attr) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr, typename Skipper> + bool test_attr(Char const* in, Parser const& p + , Attr& attr, Skipper const& s, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s, attr) + && (!full_match || (in == last)); + } + + struct printer + { + typedef boost::spirit::utf8_string string; + + void element(string const& tag, string const& value, int depth) const + { + for (int i = 0; i < (depth*4); ++i) // indent to depth + std::cout << ' '; + + std::cout << "tag: " << tag; + if (value != "") + std::cout << ", value: " << value; + std::cout << std::endl; + } + }; + + void print_info(boost::spirit::info const& what) + { + using boost::spirit::basic_info_walker; + + printer pr; + basic_info_walker<printer> walker(pr, what.tag, 0); + boost::apply_visitor(walker, what.value); + } +} + +#endif diff --git a/libs/spirit/repository/test/test_headers/Jamfile b/libs/spirit/repository/test/test_headers/Jamfile new file mode 100644 index 0000000000..4e35ec778c --- /dev/null +++ b/libs/spirit/repository/test/test_headers/Jamfile @@ -0,0 +1,82 @@ +# Jamfile +# +# Copyright (c) 2007-2008 Steven Watanabe +# Copyright (c) 2009 Joel de Guzman +# Copyright (c) 2009 Hartmut Kaiser +# Copyright (c) 2009 Francois Barel +# +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt + +import testing ; +import path ; +import regex ; +import print ; +import sequence ; +import feature ; + +project boost/spirit/repository/test/test_headers + : requirements + <include>$(BOOST_ROOT) + <include>../../../../.. + <toolset>gcc:<cxxflags>-ftemplate-depth-300 + <toolset>darwin:<cxxflags>-ftemplate-depth-300 + ; + +headers = +[ + path.glob-tree ../../../../../boost/spirit/repository/include : *.hpp +] ; + +main_headers = +[ + path.glob-tree ../../../../../boost/spirit/include : *.hpp : classic* phoenix1* +] ; + +for local file in $(headers) +{ + compile test.cpp + : # requirements + <define>BOOST_SPIRIT_HEADER_NAME=$(file) + <dependency>$(file) + : # test name + [ regex.replace [ path.relative-to ../../../../../boost/spirit/repository $(file) ] "/" "_" ] + ; +} + +feature.feature <generate-include-all-order> : forward reverse : incidental ; + +rule generate-include-all ( target : sources * : properties * ) +{ + print.output $(target) ; + + if <generate-include-all-order>reverse in $(properties) + { + sources = [ sequence.reverse $(sources) ] ; + } + + for local file in $(sources) + { + print.text "#include <$(file:G=)> +" : overwrite ; + } + +} + +make auto_all1.cpp + : $(headers) $(main_headers) + : @generate-include-all + ; + +make auto_all2.cpp + : $(headers) $(main_headers) + : @generate-include-all + : <generate-include-all-order>reverse + ; + +# this ought to catch non-inlined functions and other duplicate definitions +link auto_all1.cpp auto_all2.cpp main.cpp + : <include>. + : auto_all_headers + ; diff --git a/libs/spirit/repository/test/test_headers/main.cpp b/libs/spirit/repository/test/test_headers/main.cpp new file mode 100644 index 0000000000..99aacc627a --- /dev/null +++ b/libs/spirit/repository/test/test_headers/main.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +int main() +{ + return 0; +} diff --git a/libs/spirit/repository/test/test_headers/test.cpp b/libs/spirit/repository/test/test_headers/test.cpp new file mode 100644 index 0000000000..c6814198ae --- /dev/null +++ b/libs/spirit/repository/test/test_headers/test.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_SPIRIT_STRINGIZE_IMPL(x) #x +#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x) + +#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME) + +#include BOOST_SPIRIT_HEADER +#include BOOST_SPIRIT_HEADER + +int main() +{ + return 0; +} |