Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53436 - trunk/libs/spirit/doc/qi
From: joel_at_[hidden]
Date: 2009-05-30 06:07:54


Author: djowel
Date: 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
New Revision: 53436
URL: http://svn.boost.org/trac/boost/changeset/53436

Log:
separating qi and karma
Added:
   trunk/libs/spirit/doc/qi/
   trunk/libs/spirit/doc/qi/actions.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/attributes.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/complex.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/debugging.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/directives.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/employee.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/error_handling.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/generating.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/grammars.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/mini_xml.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/num_list2.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/num_list3.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/num_list4.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/operators.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/parse_trees_and_asts.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/parsing.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/peg.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/primitives.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/quick_reference.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/roman.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/rules.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/semantic_actions.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/sum_tutorial.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/tutorial_intro.qbk (contents, props changed)
   trunk/libs/spirit/doc/qi/warming_up.qbk (contents, props changed)

Added: trunk/libs/spirit/doc/qi/actions.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/actions.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,103 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Semantic Actions]
+
+Our parser above is really nothing but a recognizer. It answers the question
+"did the input match our grammar?", but it does not do anything other than that.
+It does not extract any information from what was parsed. For example, whenever
+we parse a real number, we wish to store the parsed number after a successful
+match.
+
+Enter Semantic actions. Semantic actions may be attached to any point in the
+grammar specification. These actions are C++ functions or function objects that
+are called whenever a part of the parser successfully recognizes a portion of
+the input. Say you have a parser `P`, and a C++ function `F`, you can make the
+parser call `F` whenever it matches an input by attaching `F`:
+
+ P[F]
+
+The expression above links `F` to the parser, `P`.
+
+The function/function object signature depends on the type of the parser to
+which it is attached. The parser `double_` passes the parsed number. Thus, if we
+were to attach a function `F` to `double_`, we need `F` to be declared as:
+
+ void F(double n);
+
+There are actually 2 more arguments being passed (the parser context and a
+reference to a boolean 'hit' parameter). We don't need these, for now, but we'll
+see more on these other arguments later. Spirit.Qi allows us to bind a single
+argument function, like above. The other arguments are simply ignored.
+
+Presented are various ways to attach semantic actions:
+
+* Using plain function pointer
+* Using simple function object
+* Using __boost_bind__ with a plain function
+* Using __boost_bind__ with a member function
+* Using __boost_lambda__
+
+[import ../../example/qi/actions.cpp]
+
+Given:
+
+[tutorial_semantic_action_functions]
+
+Take note that with function objects, we need to have an `operator()` with 3
+arguments. Since we don't care about the other two, we can use `unused_type` for
+these. We'll see more of `unused_type` elsewhere. Get used to it. `unused_type`
+is a Spirit supplied support class.
+
+All examples parse inputs of the form:
+
+ "{integer}"
+
+An integer inside the curly braces.
+
+The first example shows how to attach a plain function:
+
+[tutorial_attach_actions1]
+
+What's new? Well `int_` is the sibbling of `double_`. I'm sure you can guess
+what this parser does.
+
+The next example shows how to attach a simple function object:
+
+[tutorial_attach_actions2]
+
+We can use __boost_bind__ to 'bind' member functions:
+
+[tutorial_attach_actions4]
+
+Likewise, we can also use __boost_bind__ to 'bind' plain functions:
+
+[tutorial_attach_actions3]
+
+Yep, we can also use __boost_lambda__:
+
+[tutorial_attach_actions5]
+
+There are more ways to bind semantic action functions, but the examples above
+are the most common. Attaching semantic actions is the first hurdle one has
+to tackle when getting started with parsing with Spirit. Familiarize yourself
+with this task and get intimate with the tools behind it such as __boost_bind__
+and __boost_lambda__.
+
+The examples above can be found here: [@../../example/qi/actions.cpp]
+
+[heading Phoenix]
+
+__phoenix__, a companion library bundled with Spirit, is specifically suited
+for binding semantic actions. It is like __boost_lambda__ in steroids, with
+special custom features that make it easy to integrate semantic actions with
+Spirit. If your requirements go beyond simple to moderate parsing, I suggest you
+use this library. Examples presented henceforth shall be using the library
+exclusively
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/attributes.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/attributes.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Attributes]
+[endsect]

Added: trunk/libs/spirit/doc/qi/complex.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/complex.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,52 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Complex - Our first complex parser]
+
+Well, not really a complex parser, but a parser that parses complex numbers.
+This time, we're using __phoenix__ to do the semantic actions.
+
+Here's a simple parser expression for complex numbers:
+
+ '(' >> double_ >> -(',' >> double_) >> ')'
+ | double_
+
+What's new? Well, we have:
+
+# Alternates: e.g. `a | b`. Try `a` first. If it succeeds, good. If not, try the
+ next alternative, `b`.
+# Optionals: e.g. -p. Match the parser p zero or one time.
+
+The complex parser presented above reads as:
+
+* One or two real number in parantheses, separated by comma (the second number is optional)
+* *OR* a single real number.
+
+This parser can parse complex numbers of the form:
+
+ (123.45, 987.65)
+ (123.45)
+ 123.45
+
+[import ../../example/qi/complex_number.cpp]
+
+Here goes, this time with actions:
+
+[tutorial_complex_number]
+
+The full cpp file for this example can be found here: [@../../example/qi/complex_number.cpp]
+
+The `double_` parser attaches this action:
+
+ ref(n) = _1
+
+This assigns the parsed result (actually, the attribute of `double_`) to n.
+`ref(n)` tells Phoenix that `n` is a mutable reference. `_1` is a Phoenix
+placeholder for the parsed result attribute.
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/debugging.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/debugging.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Debugging]
+[endsect]

Added: trunk/libs/spirit/doc/qi/directives.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/directives.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Directives]
+[endsect]

Added: trunk/libs/spirit/doc/qi/employee.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/employee.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,218 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Employee - Parsing into structs]
+
+It's a common question in the __spirit_list__: how do I parse and place the
+results into a C++ struct? Of course, at this point, you already know various
+ways to do it, using semantic actions. There are many ways to skin a cat.
+Spirit2, being fully attributed, makes it even easier. The next example
+demonstrates some features of Spirit2 that makes this easy. In the process,
+you'll learn about:
+
+* More about attributes
+* Auto rules
+* Some more built-in parsers
+* Directives
+
+[import ../../example/qi/employee.cpp]
+
+First, let's create a struct representing an employee:
+
+[tutorial_employee_struct]
+
+Then, we need to tell __fusion__ about our employee struct to make it a first-
+class fusion citizen. If you don't know fusion yet, it is a __boost__ library
+for working with heterogenous collections of data, commonly referred to as
+tuples. Spirit uses fusion extensively as part of its infrastructure.
+
+In fusion's view, a struct is just a form of a tuple. You can adapt any struct
+to be a fully conforming fusion tuple:
+
+[tutorial_employee_adapt_struct]
+
+Now we'll write a parser for our employee. Inputs will be of the form:
+
+ employee{ age, "surname", "forename", salary }
+
+Here goes:
+
+[tutorial_employee_parser]
+
+The full cpp file for this example can be found here: [@../../example/qi/employee.cpp]
+
+Let's walk through this one step at a time (not necessarily from top to bottom).
+
+ template <typename Iterator>
+ struct employee_parser : grammar<Iterator, employee(), space_type>
+
+`employee_parser` is a grammar. Like before, we make it a template so that we can
+reuse it for different iterator types. The grammar's signature is:
+
+ employee()
+
+meaning, the parser generates employee structs. `employee_parser` skips white
+spaces using `space_type` as its skip parser.
+
+ employee_parser() : employee_parser::base_type(start)
+
+Initializes the base class.
+
+ rule<Iterator, std::string(), space_type> quoted_string;
+ rule<Iterator, employee(), space_type> start;
+
+Declares two rules: `quoted_string` and `start`. `start` has the same template
+parameters as the grammar itself. `quoted_string` has a `std::string` attribute.
+
+[heading Lexeme]
+
+ lexeme['"' >> +(char_ - '"') >> '"'];
+
+`lexeme` inhibits space skipping from the open brace to the closing brace.
+The expression parses quoted strings.
+
+ +(char_ - '"')
+
+parses one or more chars, except the double quote. It stops when it sees
+a double quote.
+
+[heading Difference]
+
+The expression:
+
+ a - b
+
+parses `a` but not `b`. Its attribute is just `A`, the attribute of `a`. `b`'s
+attribute is ignored. Hence, the attribute of:
+
+ char_ - '"'
+
+is just `char`.
+
+[heading Plus]
+
+ +a
+
+is the close kin of the kleene star we got so used to in our tutorial. Like it's
+kin, the kleene star, its attribute is a `std::vector<A>` where `A` is the
+attribute of `a`. So, putting all these together, the attribute of
+
+ +(char_ - '"')
+
+is then:
+
+ std::vector<char>
+
+[heading Sequence Attribute]
+
+Now what's the attribute of
+
+ '"' >> +(char_ - '"') >> '"'
+
+?
+
+Well, typically, the attribute of:
+
+ a >> b >> c
+
+is:
+
+ fusion::vector<A, B, C>
+
+where `A` is the attribute of `a`, `B` is the attribute of `b` and `C` is the
+attribute of `c`. What is `fusion::vector`? - a tuple.
+
+[note If you don't know what I am talking about, see: [@http://tinyurl.com/6xun4j
+Fusion Vector]. It might be a good idea to have a look into __fusion__ at this
+point. You'll definitely see more of it in the coming pages.]
+
+[heading Attribute Collapsing]
+
+Some parsers, especially those very little literal parsers you see, like `'"'`,
+do not have attributes.
+
+Nodes without attributes are disregarded. In a sequence, like above, all nodes
+with no attributes are filtered out of the `fusion:vector`. So, since `'"'` has
+no attribute, and `+(char_ - '"')` has a `std::vector<char>` attribute, the
+whole expression's attribute should have been:
+
+ fusion::vector<std::vector<char> >
+
+But wait, there's one more collapsing rule: If after the attribute is a single
+element `fusion::vector`, The element is stripped naked from its container. So,
+to make a long story short, the attribute of the expression:
+
+ '"' >> +(char_ - '"') >> '"'
+
+is:
+
+ std::vector<char>
+
+[heading Auto Rules]
+
+It is typical to see rules like:
+
+ r = p[_val = _1];
+
+If you have a rule definition like above where the attribute of the RHS (right
+hand side) of the rule is compatibe with the attribute of the LHS (left hand
+side), then you can rewrite it as:
+
+ r %= p;
+
+The attribute of `p` automatically uses the attribute of `r`.
+
+So, going back to our `quoted_string` rule:
+
+ quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
+
+is a simplified version of:
+
+ quoted_string = lexeme['"' >> +(char_ - '"') >> '"'][val_ = _1];
+
+The attribute of the `quoted_string` rule: `std::string` *is compatible* with
+the attribute of the RHS: `std::vector<char>`. The RHS extracts the parsed
+attribute directly into the rule's attribute, in-situ.
+
+[heading Finally]
+
+We're down to one rule, the start rule:
+
+ start %=
+ lit("employee")
+ >> '{'
+ >> int_ >> ','
+ >> quoted_string >> ','
+ >> quoted_string >> ','
+ >> double_
+ >> '}'
+ ;
+
+Applying our collapsing rules above, the RHS has an attribute of:
+
+ fusion::vector<int, std::string, std::string, double>
+
+These nodes do not have an attribute:
+
+* `lit("employee")`
+* `'{'`
+* `'}'`
+
+[note In case you are wondering, `lit("employee")` is the same as "employee". We
+had to wrap it inside `lit` because immediately after it is `>> '{'`. You can't
+right-shift a `char[]` and a `char` - you know, C++ syntax rules.]
+
+Recall that the attribute of `start` is the `employee` struct:
+
+[tutorial_employee_struct]
+
+Now everything is clear, right? The `struct employee` *IS* compatible with
+`fusion::vector<int, std::string, std::string, double>`. So, the RHS of `start`
+uses start's attribute (a `struct employee`) in-situ when it does its work.
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/error_handling.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/error_handling.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,121 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Mini XML - Error Handling]
+
+A parser will not be complete without error handling. Spirit2 provides some
+facilities to make it easy to adapt a grammar for error handling. We'll wrap up
+the Qi tutorial with another version of the mini xml parser, this time, with
+error handling.
+
+[@../../example/qi/mini_xml1.cpp] and here: [@../../example/qi/mini_xml2.cpp]
+
+[/ import ../example/qi/mini_xml3.cpp /]
+
+Here's the grammar:
+
+[/ tutorial_xml3_grammar /]
+
+What's new?
+
+[heading Readable Names]
+
+First, when we call the base class, we give the grammar a name:
+
+ : mini_xml_grammar::base_type(xml, "xml")
+
+Then, we name all our rules:
+
+ xml.name("xml");
+ node.name("node");
+ text.name("text");
+ start_tag.name("start_tag");
+ end_tag.name("end_tag");
+
+[heading On Error]
+
+`on_error` declares our error handler:
+
+ on_error<Action>(rule, handler)
+
+This will specify what we will do when we get an error. We will print out an
+error message using phoenix:
+
+ on_error<fail>
+ (
+ xml
+ , std::cout
+ << val("Error! Expecting ")
+ << _4 // what failed?
+ << val(" here: \"")
+ << construct<std::string>(_3, _2) // iterators to error-pos, end
+ << val("\"")
+ << std::endl
+ );
+
+we choose to `fail` in our example for the `Action`: Quit and fail. Return a
+no_match (false). It can be one of:
+
+[table
+ [[`Action`] [Description]]
+ [[fail] [Quit and fail. Return a no_match.]]
+ [[retry] [Attempt error recovery, possibly moving the iterator position.]]
+ [[accept] [Force success, moving the iterator position appropriately.]]
+ [[rethrow] [Rethrows the error.]]
+]
+
+
+`rule` is the rule we attach the handler to. In our case, we are attaching to the
+`xml` rule.
+
+`handler` is the actual error handling function. It expects 4 arguments:
+
+[table
+ [[Arg] [Description]]
+ [[first] [The position of the iterator when the rule with the handler was entered.]]
+ [[last] [The end of input.]]
+ [[error-pos] [The actual position of the iterator where the error occurred.]]
+ [[what] [What failed: a string decribing the failure.]]
+]
+
+[heading Expectation Points]
+
+You might not have noticed it, but some of our expressions changed from using
+the `>>` to `>`. Look, for example:
+
+ end_tag =
+ "</"
+ > lit(_r1)
+ > '>'
+ ;
+
+What is it? It's the /expectation/ operator. You will have some "deterministic
+points" in the grammar. Those are the places where backtracking *cannot* occur.
+For our example above, when you get a `"</"`, you definitely must see a valid
+end-tag label next. It should be the one you got from the start-tag. After that,
+you definitely must have a `'>'` next. Otherwise, there is no point in
+proceeding forward and trying other branches, regardless where they are. The
+input is definitely erroneous. When this happens, an expectation_failure
+exception is thrown. Somewhere outward, the error handler will catch the
+exception.
+
+Try building the parser: [@../../example/qi/mini_xml2.cpp]. You can find some
+examples in: [@../../example/qi/mini_xml_samples] for testing purposes.
+"4.toyxml" has an error in it:
+
+ <foo><bar></foo></bar>
+
+Running the example with this gives you:
+
+ Error! Expecting "bar" here: "foo></bar>"
+ Error! Expecting end_tag here: "<bar></foo></bar>"
+ -------------------------
+ Parsing failed
+ -------------------------
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/generating.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/generating.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,22 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Parsing and Generating]
+
+[heading The API functions exposed by __qi__ ]
+
+[heading The parse() function]
+
+[heading The phrase_parse() function]
+
+[heading The tokenize_and_parse() function]
+
+[heading The tokenize_and_phrase_parse() function]
+
+[endsect]
+

Added: trunk/libs/spirit/doc/qi/grammars.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/grammars.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Grammars]
+[endsect]

Added: trunk/libs/spirit/doc/qi/mini_xml.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/mini_xml.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,237 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Mini XML - ASTs!]
+
+Stop and think about it... We've come very close to generating an AST in our
+last example. We parsed a single structure and generated an in-memory
+representation of it in the form of a struct: the `struct employee`. If we
+changed the implementation to parse one or more employees, the result would be a
+`std::vector<employee>`. We can go on and add more hierarchy: teams,
+departments, corporations. Then we'll have an AST representation of it all.
+
+In this example (actually two examples), we'll now explore parsers how to create
+ASTs. We will parse a minimalistic XML like language and compile the results
+into our data structures in the form of a tree.
+
+Along the way, we'll see new features:
+
+* Inherited attributes
+* Variant attributes
+* Local Variables
+* Not Predicate
+* Lazy Lit
+
+The full cpp files for these examples can be found here:
+[@../../example/qi/mini_xml1.cpp] and here: [@../../example/qi/mini_xml2.cpp]
+
+There are a couple of sample toy-xml files in: [@../../example/qi/mini_xml_samples]
+for testing purposes. "4.toyxml" has an error in it.
+
+[import ../../example/qi/mini_xml1.cpp]
+[import ../../example/qi/mini_xml2.cpp]
+
+[heading First Cut]
+
+Without further delay, here's the first version of the XML grammar:
+
+[tutorial_xml1_grammar]
+
+Going bottom up, let's examine the `text` rule:
+
+ rule<Iterator, std::string(), space_type> text;
+
+and its definition:
+
+ text = lexeme[+(char_ - '<') [_val += _1]];
+
+The semantic action collects the chars and appends them (via +=) to the
+`std::string` attribute of the rule (represented by the placeholder `_val`).
+
+[heading Alternates]
+
+ rule<Iterator, mini_xml_node(), space_type> node;
+
+and its definition:
+
+ node = (xml | text) [_val = _1];
+
+We'll see what a `mini_xml_node` structure later. Looking at the rule
+definition, we see some alternation goiing on here. An xml `node` is
+either an `xml` OR `text`. Hmmm... hold on to that thought...
+
+ rule<Iterator, std::string(), space_type> start_tag;
+
+Again, with an attribute of `std::string`. Then, it's definition:
+
+ start_tag =
+ '<'
+ >> !char_('/')
+ >> lexeme[+(char_ - '>') [_val += _1]]
+ >> '>'
+ ;
+
+[heading Not Predicate]
+
+`start_tag` is similar to the `text` rule apart from the added `'<'` and `'>'`.
+But wait, to make sure that the `start_tag` does not parse `end_tag`s too, we
+add: `!char_('/')`. This is a "Not Predicate":
+
+ !p
+
+It will try the parser, `p`. If it is successful, fail, otherwise, pass. In
+other words, it negates the result of `p`. Like the `eps`, it does not consume
+any input though. It will always rewind the iterator position to where it
+was upon entry. So, the expression:
+
+ !char_('/')
+
+basically says: we should not have a `'/'` at this point.
+
+[heading Inherited Attribute]
+
+The `end_tag`:
+
+ rule<Iterator, void(std::string), space_type> end_tag;
+
+Ohh! Now we see an inherited attribute there: `std::string`. The `end_tag` does
+not have a synthesized attribute. Let's see its definition:
+
+ end_tag =
+ "</"
+ >> lit(_r1)
+ >> '>'
+ ;
+
+`_r1` is yet another __phoenix__ placeholder for the 1st inherited attribute (we
+have only one, use `_r2`, `_r3`, etc. if you have more).
+
+[heading A Lazy Lit]
+
+Check out how we used `lit` here, this time, not with a literal string, but with
+the value of the 1st inherited attribute, which is specified as `std::string` in
+our rule declaration.
+
+Finally, our `xml` rule:
+
+ rule<Iterator, mini_xml(), space_type> xml;
+
+`mini_xml` is our attribute here. We'll see later what it is. Let's see its
+definition:
+
+ xml =
+ start_tag [at_c<0>(_val) = _1]
+ >> *node [push_back(at_c<1>(_val), _1)]
+ >> end_tag(at_c<0>(_val))
+ ;
+
+Those who know __fusion__ now will notice `at_c<0>` and `at_c<1>`. This gives us
+a hint that `mini_xml` is a sort of a tuple - a fusion sequence. `at_c<N>` here
+is a lazy version of the tuple accessors, provided by __phoenix__.
+
+[heading How it all works]
+
+So, what's happening?
+
+# Upon parsing `start_tag`, the parsed start-tag string is placed in
+ `at_c<0>(_val)`.
+
+# Then we parse zero or more `node`s. At each step, we `push_back` the result
+ into `at_c<1>(_val)`.
+
+# Finally, we parse the `end_tag` giving it an inherited attribute: `at_c<0>(_val)`.
+ This is the string we obtained from the `start_tag`. Investigate `end_tag` above.
+ It will fail to parse if it gets something different from what we got from the
+ `start_tag`. This ensures that our tags are balanced.
+
+To give the last item some more light, what happens is this:
+
+ end_tag(at_c<0>(_val))
+
+calls:
+
+ end_tag =
+ "</"
+ >> lit(_r1)
+ >> '>'
+ ;
+
+passing in `at_c<0>(_val)`, the string from start tag. This is referred to in the
+`end_tag` body as `_r1`.
+
+[heading The Structures]
+
+Let's see our structures. It will definitely be hierarchical: xml is
+hierarchical. It will also be recursive: xml is recursive.
+
+[tutorial_xml1_structures]
+
+[heading Of Alternates and Variants]
+
+So that's how a `mini_xml_node` looks like. We had a hint that it is either
+a `string` or a `mini_xml`. For this, we use __boost_variant__. `boost::recursive_wrapper`
+wraps `mini_xml`, making it a recursive data structure.
+
+Yep, you got that right: the attribute of an alternate:
+
+ a | b
+
+is a
+
+ boost::variant<A, B>
+
+where `A` is the attribute of `a` and `B` is the attribute of `b`.
+
+[heading Adapting structs again]
+
+`mini_xml` is no brainier. It is a plain ol' struct. But as we've seen in our
+employee example, we can adapt that to be a __fusion__ sequence:
+
+[tutorial_xml1_adapt_structures]
+
+[heading One More Take]
+
+Here's another version. The AST structure remains the same, but this time,
+you'll see that we make use of auto-rules making the grammar semantic-action-
+less. Here it is:
+
+[tutorial_xml2_grammar]
+
+This one shouldn't be any more difficult to understand after going through the
+first xml parser example. The rules are almost the same, except that, we got rid
+of semantic actions and used auto-rules (see the employee example if you missed
+that). There are a couple of new stuff, though. It's all in the `xml` rule:
+
+[heading Local Variables]
+
+ rule<Iterator, mini_xml(), locals<std::string>, space_type> xml;
+
+Wow, we have four template parameters now. What's that `locals` guy doing there?
+Well, it declares that the rule `xml` will have one local variable: a `string`.
+Let's see how this is used in action:
+
+ xml %=
+ start_tag[_a = _1]
+ >> *node
+ >> end_tag(_a)
+ ;
+
+# Upon parsing `start_tag`, the parsed start-tag string is placed in
+ the local variable specified by (yet another) __phoenix__ placeholder:
+ `_a`. We have only one local variable. If we had more, these are designated
+ by `_b`..`_z`.
+
+# Then we parse zero or more `node`s.
+
+# Finally, we parse the `end_tag` giving it an inherited attribute: `_a`, our
+ local variable.
+
+There are no actions involved in stuffing data into our `xml` attribute. It's
+all taken cared of thatnks to the auto-rule.
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/num_list2.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/num_list2.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,30 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Number List - stuffing numbers into a std::vector]
+
+This sample demontrates a parser for a comma separated list of numbers. The
+numbers are inserted in a vector using phoenix.
+
+[import ../../example/qi/num_list2.cpp]
+
+[tutorial_numlist2]
+
+The full cpp file for this example can be found here: [@../../example/qi/num_list2.cpp]
+
+This, again, is the same parser as before. This time, instead of summing up the
+numbers, we stuff them in a `std::vector`. `push_back` is supplied by
+__phoenix__. The expression:
+
+ push_back(ref(v), _1)
+
+appends the parsed number. Like before, `_1` is a __phoenix__ placeholder for
+the parsed result attribute. Also, like before, `ref(v)` tells __phoenix__ that
+`v`, the `std::vector`, is a mutable reference.
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/num_list3.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/num_list3.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,33 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Number List Redux - list syntax]
+
+
+So far, we've been using the syntax:
+
+ double_ >> *(',' >> double_)
+
+to parse a comma-delimited list of numbers. Such lists are common in parsing and
+Spirit provides a simpler shortcut for them. The expression above can be
+simplified to:
+
+ double_ % ','
+
+read as: a list of doubles separated by `','`.
+
+
+This sample, again a variation of our previous example, demonstrates just that:
+
+[import ../../example/qi/num_list3.cpp]
+
+[tutorial_numlist3]
+
+The full cpp file for this example can be found here: [@../../example/qi/num_list3.cpp]
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/num_list4.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/num_list4.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,50 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Number List Attribute - one more, with style]
+
+You've seen that the `double_` parser has a `double` attribute. All parsers have
+an attribute, even complex parsers, those that are composed from primitives
+using operators, like the list parser, also have an attribute. It so happens that
+the the attribute of a list parser:
+
+ p % d
+
+is a `std::vector` of the attribute of `p`. So, for our parser:
+
+
+ double_ % ','
+
+we'll have an attribute of:
+
+ std::vector<double>
+
+
+So, what does this give us? Well, we can simply pass in a `std::vector<double>`
+to our number list parser and it will happily churn out our result in our
+vector. For that to happen, we'll use a variation of the `phrase_parse` with
+an additional argument: the parser's attribute:
+
+# An iterator pointing to the start of the input
+# An iterator pointing to one past the end of the input
+# The parser object
+# The parser's attribute
+# Another parser called the skip parser
+
+So, our parser now is further simplified to:
+
+[import ../../example/qi/num_list4.cpp]
+
+[tutorial_numlist4]
+
+The full cpp file for this example can be found here: [@../../example/qi/num_list4.cpp]
+
+[*Hey, no more actions!!!] Now we're entering the realm of attribute grammars.
+Cool eh?
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/operators.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/operators.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Operators]
+[endsect]

Added: trunk/libs/spirit/doc/qi/parse_trees_and_asts.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/parse_trees_and_asts.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Parse Trees and ASTs]
+[endsect]

Added: trunk/libs/spirit/doc/qi/parsing.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/parsing.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,48 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Parsing]
+
+Central to the library is the parser. The parser does the actual
+work of recognizing a linear input stream of data read sequentially
+from start to end by the supplied iterators. The parser attempts to
+match the input following a well-defined set of specifications known
+as grammar rules. The parser returns a `bool` to report the success or
+failure. When successful, the parser calls a client-supplied semantic
+action, if there is one. The semantic action extracts structural
+information depending on the data passed by the parser and the
+hierarchical context of the parser it is attached to.
+
+Parsers come in different flavors. The Spirit library comes bundled with an
+extensive set of pre-defined parsers that perform various parsing tasks from
+the trivial to the complex. The parser, as a concept, has a public conceptual
+interface contract. Following the contract, anyone can write a conforming
+parser that will play along well with the library's predefined components. We
+shall provide a blueprint detailing the conceptual interface of the parser
+later.
+
+Clients of the library generally do not need to write their own hand-coded
+parsers at all. Spirit has an immense repertoire of pre-defined parsers
+covering all aspects of syntax and semantic analysis. We shall examine this
+repertoire of parsers in the following sections. In the rare case where a
+specific functionality is not available, it is extremely easy to write a
+user-defined parser. The ease in writing a parser entity is the main reason
+for Spirit's extensibility.
+
+[heading The API functions exposed by __qi__ ]
+
+[heading The parse() function]
+
+[heading The phrase_parse() function]
+
+[heading The tokenize_and_parse() function]
+
+[heading The tokenize_and_phrase_parse() function]
+
+[endsect]
+

Added: trunk/libs/spirit/doc/qi/peg.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/peg.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Parsing Expression Grammar]
+[endsect]

Added: trunk/libs/spirit/doc/qi/primitives.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/primitives.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Primitives]
+[endsect]

Added: trunk/libs/spirit/doc/qi/quick_reference.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/quick_reference.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,455 @@
+[/==============================================================================
+ 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)
+===============================================================================/]
+
+This quick reference section is provided for convenience. You can use
+this section as a sort of a "cheat-sheet" on the most commonly used Qi
+components. It is not intended to be complete, but should give you an
+easy way to recall a particular component without having to dig up on
+pages and pages of reference doumentation.
+
+[section Quick Reference]
+
+[variablelist Notation
+ [[`P`] [Parser type]]
+ [[`p, a, b, c`] [Parser objects]]
+ [[`A, B, C`] [Attribute types of parsers A, B and C]]
+ [[`I`] [The iterator type used for parsing]]
+ [[`Unused`] [An `unused_type`]]
+ [[`Context`] [The enclosing rule's `Context` type]]
+ [[`Attr`] [An attribute type]]
+ [[`b`] [A boolean expression]]
+ [[`fp`] [A (lazy parser) function with signature `P(Unused, Context)`]]
+ [[`fa`] [A (semantic action) function with signature `void(Attr, Context, bool&)`.
+ The third parameter is a boolean flag that can be set to false to
+ force the parse to fail. Both `Context` and the boolean flag are
+ optional.]]
+ [[`first`] [An iterator pointing to the start of input]]
+ [[`last`] [An iterator pointing to the end of input]]
+ [[`Ch`] [Character-class specific character type (See __char_class_types__)]]
+ [[`ch`] [Character-class specific character (See __char_class_types__)]]
+ [[`ch2`] [Character-class specific character (See __char_class_types__)]]
+ [[`chset`] [Character-set specifier string (example: "a-z0-9")]]
+ [[`str`] [Character-class specific string (See __char_class_types__)]]
+ [[`Str`] [Attribute of `str`: `std::basic_string<T>` where `T` is the underlying character type of `str`]]
+ [[`tuple<>`] [Used as a placeholder for a fusion sequence]]
+ [[`vector<>`] [Used as a placeholder for an STL container]]
+ [[`variant<>`] [Used as a placeholder for a boost::variant]]
+ [[`optional<>`] [Used as a placeholder for a boost::optional]]
+]
+
+
+[table Predefined /Spirit.Qi/ primitive parsers
+ [[Expression] [Attribute] [Description]]
+ [[`eol`] [`Unused`] [Matches the end of line (`\r` or `\n` or `\r\n`)]]
+ [[`eoi`] [`Unused`] [Matches the end of input (first == last)]]
+ [[`eps`] [`Unused`] [Match an empty string]]
+ [[`eps(b)`] [`Unused`] [If `b` is true, match an empty string]]
+ [[`lazy(fp)`] [Attribute of `P` where `P`
+ is the return type of `fp`] [Invoke `fp` at parse time, returning a parser
+ `p` which is then called to parse.]]
+ [[`fp`] [see `lazy(fp)` above] [Equivalent to `lazy[fp]`]]
+ [[`p[fa]`] [Attribute of `p`] [Call semantic action, `fa` if p succeeds.]]
+
+ [[`byte_`] [8 bits native endian] [Matches an 8 bit binary]]
+ [[`word`] [16 bits native endian] [Matches a 16 bit binary]]
+ [[`big_word`] [16 bits big endian] [Matches a 16 bit binary]]
+ [[`little_word`] [16 bits little endian] [Matches a 16 bit binary]]
+ [[`dword`] [32 bits native endian] [Matches a 32 bit binary]]
+ [[`big_dword`] [32 bits big endian] [Matches a 32 bit binary]]
+ [[`little_dword`] [32 bits little endian] [Matches a 32 bit binary]]
+ [[`qword`] [64 bits native endian] [Matches a 64 bit binary]]
+ [[`big_qword`] [64 bits big endian] [Matches a 64 bit binary]]
+ [[`little_qword`] [64 bits little endian] [Matches a 64 bit binary]]
+
+ [[`char_`] [`Ch`] [Matches any character]]
+ [[`char_(ch)`] [`Ch`] [Matches `ch`]]
+ [[`char_("c")`] [`Ch`] [Matches a single char string literal, `c`]]
+ [[`char_(ch, ch2)`] [`Ch`] [Matches a range of chars from `ch` to `ch2` (inclusive)]]
+ [[`char_(chset)`] [`Ch`] [Matches a character set `chset`]]
+
+ [[`ch`] [`Unused`] [Matches `ch`]]
+ [[`str`] [`Unused`] [Matches `str`]]
+ [[`lit(ch)`] [`Unused`] [Matches `ch`]]
+ [[`lit(str)`] [`Unused`] [Matches `str`]]
+ [[`string(str)`] [`Str`] [Matches `str`]]
+
+ [[`symbols<Ch, T> sym;`][N/A] [Declare a symbol table, `sym`. `Ch` is the
+ underlying char type of the symbol table keys.
+ `T` is the data type associated with each key.]]
+ [[
+``
+ sym.add
+ (str1, val1)
+ (str2, val2)
+ /*...more...*/
+ ;
+``
+ ]
+ [N/A] [Add symbols into a symbol table, `sym`.
+ val1 and val2 are optional data of type `T`,
+ the data type associated with each key.]]
+ [[`sym`] [`T`] [Matches entries in the symbol table, `sym`. If
+ successful, returns the data associated with
+ the key]]
+
+
+ [[`lexeme[a]`] [`A`] [Disable skip parsing for `a`]]
+ [[`nocase[a]`] [`A`] [Inhibits case-sensitivity for `a`]]
+ [[`omit[a]`] [`Unused`] [Ignores the attribute type of `a`]]
+ [[`raw[a]`] [`boost::iterator_range<I>`][Presents the transduction of `a` as an iterator range]]
+
+ [[`repeat[a]`] [`vector<A>`] [Repeat `a` zero or more times]]
+ [[`repeat(N)[a]`] [`vector<A>`] [Repeat `a` `N` times]]
+ [[`repeat(N, M)[a]`] [`vector<A>`] [Repeat `a` `N` to `M` times]]
+ [[`repeat(N, inf)[a]`] [`vector<A>`] [Repeat `a` `N` or more times]]
+
+ [[`skip[a]`] [`A`] [Reestablish the skipper that got inhibited by lexeme]]
+ [[`skip(p)[a]`] [`A`] [Use `p` as a skipper for parsing `a`]]
+
+ [[`float_`] [`float`] [Parse a floating point number into a `float`]]
+ [[`double_`] [`double`] [Parse a floating point number into a `double`]]
+ [[`long_double`] [`long double`] [Parse a floating point number into a `long double`]]
+
+ [[`bin`] [`unsigned`] [Parse a binary integer into an `unsigned`]]
+ [[`oct`] [`unsigned`] [Parse an octal integer into an `unsigned`]]
+ [[`hex`] [`unsigned`] [Parse a hexadecimal integer into an `unsigned`]]
+ [[`ushort_`] [`unsigned short`] [Parse an unsigned short integer]]
+ [[`ulong_`] [`unsigned long`] [Parse an unsigned long integer]]
+ [[`uint_`] [`unsigned int`] [Parse an unsigned int]]
+ [[`ulong_long`] [`unsigned long long`] [Parse an unsigned long long]]
+ [[`short_`] [`short`] [Parse a short integer]]
+ [[`long_`] [`long`] [Parse a long integer]]
+ [[`int_`] [`int`] [Parse an int]]
+ [[`long_long`] [`long long`] [Parse a long long]]
+
+ [[`!a`] [`Unused`] [Not predicate. Ensure that `a` does not match
+ but don't move the iterator position]]
+ [[`&a`] [`Unused`] [And predicate. Ensure that `a` matches
+ but don't move the iterator position]]
+ [[`-a`] [`optional<A>`] [Optional. Parse `a` zero or one time]]
+ [[`*a`] [`vector<A>`] [Kleene. Parse `a` zero or more times]]
+ [[`+a`] [`vector<A>`] [Plus. Parse `a` one or more times]]
+ [[`a | b`] [`variant<A, B>`] [Alternative. Parse `a` or `b`]]
+ [[`a >> b`] [`tuple<A, B>`] [Sequence. Parse `a` followed by `b`]]
+ [[`a > b`] [`tuple<A, B>`] [Expect. Parse `a` followed by `b`. `b` is
+ expected to match when `a` matches, otherwise,
+ an `expectation_failure` is thrown.]]
+ [[`a - b`] [`A`] [Difference. Parse `a` but not `b`]]
+ [[`a || b`] [`tuple<A, B>`] [Sequential Or. Parse `a` or `b` or `a` followed by `b`]]
+ [[`a % b`] [`vector<A>`] [List. Parse `a` delimited `b` one or more times]]
+ [[`a ^ b`] [`tuple<`
+ `optional<A>,`
+ `optional<B> >`
+ ] [Permutation. Parse `a` and `b` in any order]]
+]
+
+[table Predefined /Spirit.Karma/ primitive generators
+ [[Expression] [Attribute] [Description]]
+ [[`eol`] [`Unused`] [Generates the end of line (`\n`)]]
+ [[`eps`] [`Unused`] [Generate an empty string]]
+ [[`eps(b)`] [`Unused`] [If `b` is true, generate an empty string]]
+ [[`lazy(fg)`] [Attribute of `G` where `G`
+ is the return type of `fg`] [Invoke `fg` at generation time, returning a generator
+ `g` which is then called to generate.]]
+ [[`fg`] [see `lazy(fg)` above] [Equivalent to `lazy[fp]`]]
+ [[`g[fa]`] [Attribute of `g`] [Call semantic action `fa` (before executing `g`).]]
+
+ [[`byte_`] [8 bits native endian] [Generates an 8 bit binary]]
+ [[`word`] [16 bits native endian] [Generates a 16 bit binary]]
+ [[`big_word`] [16 bits big endian] [Generates a 16 bit binary]]
+ [[`little_word`] [16 bits little endian] [Generates a 16 bit binary]]
+ [[`dword`] [32 bits native endian] [Generates a 32 bit binary]]
+ [[`big_dword`] [32 bits big endian] [Generates a 32 bit binary]]
+ [[`little_dword`] [32 bits little endian] [Generates a 32 bit binary]]
+ [[`qword`] [64 bits native endian] [Generates a 64 bit binary]]
+ [[`big_qword`] [64 bits big endian] [Generates a 64 bit binary]]
+ [[`little_qword`] [64 bits little endian] [Generates a 64 bit binary]]
+
+ [[`char_(ch)`] [`Ch`] [Generates `ch`]]
+ [[`char_("c")`] [`Ch`] [Generates a single char string literal, `c`]]
+
+ [[`ch`] [`Unused`] [Generates `ch`]]
+ [[`str`] [`Unused`] [Generates `str`]]
+ [[`lit(ch)`] [`Unused`] [Generates `ch`]]
+ [[`lit(str)`] [`Unused`] [Generates `str`]]
+ [[`string(str)`] [`Str`] [Generates `str`]]
+
+ [[`lower[a]`] [`A`] [Generate `a` as lower case]]
+ [[`upper[a]`] [`A`] [Generate `a` as upper case]]
+
+ [[`left_align[a]`] [`A`] [Generate `a` left aligned in column of width
+ BOOST_KARMA_DEFAULT_FIELD_LENGTH]]
+ [[`left_align(N)[a]`] [`A`] [Generate `a` left aligned in column of width `N`]]
+ [[`left_align(N, g)[a]`][`A`] [Generate `a` left aligned in column of width `N`
+ while using `g` to generate the necesssary
+ padding]]
+ [[`right_align[a]`] [`A`] [Generate `a` right aligned in column of width
+ BOOST_KARMA_DEFAULT_FIELD_LENGTH]]
+ [[`right_align(N)[a]`] [`A`] [Generate `a` right aligned in column of width `N`]]
+ [[`right_align(N, g)[a]`][`A`] [Generate `a` right aligned in column of width `N`
+ while using `g` to generate the necesssary
+ padding]]
+ [[`center[a]`] [`A`] [Generate `a` centered in column of width
+ BOOST_KARMA_DEFAULT_FIELD_LENGTH]]
+ [[`center(N)[a]`] [`A`] [Generate `a` centered in column of width `N`]]
+ [[`center(N, g)[a]`] [`A`] [Generate `a` centered in column of width `N`
+ while using `g` to generate the necesssary
+ padding]]
+
+ [[`maxwidth[a]`] [`A`] [Generate `a` truncated to column of width
+ BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH]]
+ [[`maxwidth(N)[a]`] [`A`] [Generate `a` truncated to column of width `N`]]
+
+ [[`repeat[a]`] [`vector<A>`] [Repeat `a` zero or more times]]
+ [[`repeat(N)[a]`] [`vector<A>`] [Repeat `a` `N` times]]
+ [[`repeat(N, M)[a]`] [`vector<A>`] [Repeat `a` `N` to `M` times]]
+ [[`repeat(N, inf)[a]`] [`vector<A>`] [Repeat `a` `N` or more times]]
+
+ [[`verbatim[a]`] [`A`] [Disable delimited generation for `a`]]
+ [[`delimit[a]`] [`A`] [Reestablish the delimiter that got inhibited by verbatim]]
+ [[`delimit(g)[a]`] [`A`] [Use `g` as a skipper for generating `a`]]
+
+ [[`float_`] [`float`] [Generate a floating point number from a `float`]]
+ [[`double_`] [`double`] [Generate a floating point number from a `double`]]
+ [[`long_double`] [`long double`] [Generate a floating point number from a `long double`]]
+
+ [[`bin`] [`unsigned`] [Generate a binary integer from an `unsigned`]]
+ [[`oct`] [`unsigned`] [Generate an octal integer from an `unsigned`]]
+ [[`hex`] [`unsigned`] [Generate a hexadecimal integer from an `unsigned`]]
+ [[`ushort_`] [`unsigned short`] [Generate an unsigned short integer]]
+ [[`ulong_`] [`unsigned long`] [Generate an unsigned long integer]]
+ [[`uint_`] [`unsigned int`] [Generate an unsigned int]]
+ [[`ulong_long`] [`unsigned long long`] [Generate an unsigned long long]]
+ [[`short_`] [`short`] [Generate a short integer]]
+ [[`long_`] [`long`] [Generate a long integer]]
+ [[`int_`] [`int`] [Generate an int]]
+ [[`long_long`] [`long long`] [Generate a long long]]
+
+ [[`!a`] [`Unused`] [Not predicate. Ensure that `a` does not succeed
+ generating but don't create any output]]
+ [[`&a`] [`Unused`] [And predicate. Ensure that `a` does succeed
+ generating but don't create any output]]
+ [[`-a`] [`optional<A>`] [Optional. Generate `a` zero or one time]]
+ [[`*a`] [`vector<A>`] [Kleene. Generate `a` zero or more times]]
+ [[`+a`] [`vector<A>`] [Plus. Generate `a` one or more times]]
+ [[`a | b`] [`variant<A, B>`] [Alternative. Generate `a` or `b`]]
+ [[`a << b`] [`tuple<A, B>`] [Sequence. Generate `a` followed by `b`]]
+ [[`a % b`] [`vector<A>`] [List. Generate `a` delimited `b` one or more times]]
+]
+
+[heading Compound Attribute Rules]
+
+The notation will be for instance:
+
+ a: A, b: B --> (a >> b): tuple<A, B>
+
+which reads as: given, `a` and `b` are parsers/generators, and `A` is the type
+of the attribute of `a`, and `B` is the type of the attribute of `b`, then the
+type of the attribute of `a >> b` will be `tuple<A, B>`.
+
+
+[table /Spirit.Qi/ compound parser attribute types
+ [[Expression] [Attribute]]
+ [[sequence (`>>`)] [`a: A, b: B --> (a >> b): tuple<A, B>`[br]
+ `a: A, b: Unused --> (a >> b): A`[br]
+ `a: Unused, b: B --> (a >> b): B`[br]
+ `a: Unused, b: Unused --> (a >> b): Unused`[br]
+ `a: A, b: A --> (a >> b): vector<A>`]]
+ [[expect (`>`)] [`a: A, b: B --> (a > b): tuple<A, B>`[br]
+ `a: A, b: Unused --> (a > b): A`[br]
+ `a: Unused, b: B --> (a > b): B`[br]
+ `a: Unused, b: Unused --> (a > b): Unused`[br]
+ `a: A, b: A --> (a > b): vector<A>`]]
+ [[alternative (`|`)] [`a: A, b: B --> (a | b): variant<A, B>`[br]
+ `a: A, b: Unused --> (a | b): variant<Unused, A>`[br]
+ `a: Unused, b: B --> (a | b): variant<Unused, B>`[br]
+ `a: Unused, b: Unused --> (a | b): Unused`[br]
+ `a: A, b: A --> (a | b): A`]]
+ [[difference (`-`)] [`a: A, b: B --> (a - b): A`]]
+ [[kleene (`*`)] [`a: A --> *a: vector<A>`[br]
+ `a: Unused --> a: Unused`]]
+ [[plus (`+`)] [`a: A --> +a: vector<A>`[br]
+ `a: Unused --> a: Unused`]]
+ [[list (`%`)] [`a: A, b: B --> (a % b): vector<A>`[br]
+ `a: Unused, b: B --> (a % b): Unused`]]
+ [[repetition] [`a: A --> repeat(...,...)[a]: vector<A>`[br]
+ `a: Unused --> repeat(...,...)[a]: Unused`]]
+ [[sequential or (`||`)] [`a: A, b: B --> (a || b): tuple<optional<A>, optional<B> >`[br]
+ `a: A, b: Unused --> (a || b): optional<A>`[br]
+ `a: Unused, b: B --> (a || b): optional<B>`[br]
+ `a: Unused, b: Unused --> (a || b): Unused`]]
+ [[optional (`-`)] [`a: A --> -a: optional<A>`[br]
+ `a: Unused --> -a: Unused`]]
+ [[and predicate (`&`)] [`a: A --> &a: Unused`]]
+ [[not predicate (`!`)] [`a: A --> !a: Unused`]]
+ [[permutation (`^`)] [`a: A, b: B --> (a ^ b): tuple<optional<A>, optional<B> >`[br]
+ `a: A, b: Unused --> (a ^ b): optional<A>`[br]
+ `a: Unused, b: B --> (a ^ b): optional<B>`[br]
+ `a: Unused, b: Unused --> (a ^ b): Unused`]]
+]
+
+[table /Spirit.Karma/ compound generator attribute types
+ [[Expression] [Attribute]]
+ [[sequence (`<<`)] [`a: A, b: B --> (a << b): tuple<A, B>`[br]
+ `a: A, b: Unused --> (a << b): A`[br]
+ `a: Unused, b: B --> (a << b): B`[br]
+ `a: Unused, b: Unused --> (a << b): Unused`[br]
+ `a: A, b: A --> (a << b): vector<A>`]]
+ [[alternative (`|`)] [`a: A, b: B --> (a | b): variant<A, B>`[br]
+ `a: A, b: Unused --> (a | b): variant<Unused, A>`[br]
+ `a: Unused, b: B --> (a | b): variant<Unused, B>`[br]
+ `a: Unused, b: Unused --> (a | b): Unused`[br]
+ `a: A, b: A --> (a | b): A`]]
+ [[kleene (`*`)] [`a: A --> *a: vector<A>`[br]
+ `a: Unused --> a: Unused`]]
+ [[plus (`+`)] [`a: A --> +a: vector<A>`[br]
+ `a: Unused --> a: Unused`]]
+ [[list (`%`)] [`a: A, b: B --> (a % b): vector<A>`[br]
+ `a: Unused, b: B --> (a % b): Unused`]]
+ [[repetition] [`a: A --> repeat(...,...)[a]: vector<A>`[br]
+ `a: Unused --> repeat(...,...)[a]: Unused`]]
+ [[optional (`-`)] [`a: A --> -a: optional<A>`[br]
+ `a: Unused --> -a: Unused`]]
+ [[and predicate (`&`)] [`a: A --> &a: Unused`]]
+ [[not predicate (`!`)] [`a: A --> !a: Unused`]]
+]
+
+
+[heading Lazy Arguments]
+
+For all expressions of the form:
+
+ p(a1, a2,... aN)
+
+where `p` is a parser, each of the arguments (a1...aN) can either be an
+immediate value, or a lazy function with signature:
+
+ T(Unused, Context)
+
+where `T`, the function's return value, is compatible with the argument
+type expected. For example, this is a valid expression:
+
+ eps(false) // this will always fail
+
+And so is this:
+
+ bool flag = true;
+ eps(phoenix::var(flag)) // success or fail depending on the value
+ // of flag at parse time
+
+since `phoenix::ref(f)` is a function that returns a `bool`.
+
+[heading Non-terminals]
+
+[variablelist Notation
+ [[`RT`] [Synthesized attribute. The rule or grammar's return type.]]
+ [[`Arg1`, `Arg2`, `ArgN`] [Inherited attributes. Zero or more or arguments.]]
+ [[`L1`, `L2`, `LN`] [Zero or more local variables.]]
+ [[`r, r2`] [Rules]]
+ [[`g`] [A grammar]]
+ [[`p`] [A parser expression]]
+ [[`my_grammar]` [A user defined grammar]]
+]
+
+[variablelist Terminology
+ [[Signature] [`RT(Arg1, Arg2 ... ,ArgN)`. The signature specifies
+ the synthesized (return value) and inherited (arguments)
+ attributes.]]
+ [[Locals] [`locals<L1, L2 ..., LN>`. The local variables.]]
+ [[Skipper] [The skip-parser type]]
+]
+
+[variablelist Template Arguments
+ [[`Iterator`] [The iterator type you will use for parsing.]]
+ [[`A1`, `A2`, `A3`] [Can be one of 1)Signature 2)Locals 3)Skipper.]]
+]
+
+[table
+ [[Expression] [Description]]
+ [[`rule<Iterator, A1, A2, A3> r(name);`] [Rule declaration. `Iterator` is required.
+ `A1, A2, A3` are optional and can be specified in any order.
+ `name` is an optional string that gives the rule
+ its name, useful for debugging and error handling.]]
+ [[`rule<Iterator, A1, A2, A3> r(r2);`] [Copy construct rule `r` from rule `r2`. `boost::shared_ptr` semantics.]]
+ [[`r = r2;`] [Assign rule `r2` to `r`. `boost::shared_ptr` semantics.]]
+ [[`r.alias()`] [return an alias of `r`. The alias is a parser that
+ holds a reference to `r`. Reference semantics.]]
+ [[`r.copy()`] [Get a copy of `r`. `boost::shared_ptr` semantics.]]
+ [[`r.name(name)`] [Naming a rule]]
+ [[`r.name()`] [Getting the name of a rule]]
+ [[debug(r)] [Debug rule `r`]]
+ [[`r = p;`] [Rule definition]]
+ [[`r %= p;`] [Auto-rule definition. The attribute of `p` should be
+ compatible with the synthesized attribute of `r`. When `p`
+ is successful, its attribute is automatically propagated
+ to `r`'s synthesized attribute.]]
+
+ [[
+``
+ template <typename Iterator>
+ struct my_grammar : grammar<Iterator, A1, A2, A3>
+ {
+ my_grammar() : my_grammar::base_type(start, name)
+ {
+ // Rule definitions
+ start = /* ... */;
+ }
+
+ rule<Iterator, A1, A2, A3> start;
+ // more rule declarations...
+ };
+``
+ ] [Grammar definition. `name` is an optional string that gives the
+ grammar its name, useful for debugging and error handling.]]
+ [[my_grammar<Iterator> g] [Instantiating a grammar]]
+ [[`g.name(name)`] [Naming a grammar]]
+ [[`g.name()`] [Getting the name of a grammar]]
+]
+
+[heading Semantic Actions]
+
+Has the form:
+
+ p[f]
+
+where `f` is a function with the signatures:
+
+ void f(Attr const&);
+ void f(Attr const&, Context&);
+ void f(Attr const&, Context&, bool&);
+
+You can use `__boost_bind__` to bind member functions. For function
+objects, the allowed signatures are:
+
+ void operator()(Attr const&, unused_type, unused_type) const;
+ void operator()(Attr const&, Context&, unused_type) const;
+ void operator()(Attr const&, Context&, bool&) const;
+
+The `unused_type` is used in the signatures above to signify 'don't
+care'.
+
+[heading Phoenix]
+
+__boost_phoenix__ makes it easier to attach semantic actions. You just
+inline your lambda expressions:
+
+ p[phoenix-lambda-expression]
+
+Spirit.Qi provides some __boost_phoenix__ placeholders to important
+information from the `Attr` and `Context` that are otherwise fiddly to extract.
+
+[variablelist Spirit.Qi specific Phoenix placeholders
+ [[`_1, _2... , _N`] [Nth attribute of `p`]]
+ [[`_val`] [The enclosing rule's synthesized attribute.]]
+ [[`_r1, _r2... , _rN`] [The enclosing rule's Nth inherited attribute.]]
+ [[`_a, _b... , _j`] [The enclosing rule's local variables (`_a` refers to the first).]]
+ [[`_val`] [The enclosing rule's synthesized attribute.]]
+ [[`_pass`] [Assign `false` to `_pass` to force a parser failure.]]
+]
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/roman.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/roman.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,170 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Roman Numerals]
+
+This example demonstrates:
+
+* symbol table
+* rule
+* grammar
+
+[heading Symbol Table]
+
+The symbol table holds a dictionary of symbols where each symbol is a sequence
+of characters (a `char`, `wchar_t`, `int`, enumeration etc.) . The template
+class, parameterized by the character type, can work efficiently with 8, 16, 32
+and even 64 bit characters. Mutable data of type T is associated with each
+symbol.
+
+Traditionally, symbol table management is maintained seperately outside the BNF
+grammar through semantic actions. Contrary to standard practice, the Spirit
+symbol table class symbols is-a parser. An object of which may be used
+anywhere in the EBNF grammar specification. It is an example of a dynamic
+parser. A dynamic parser is characterized by its ability to modify its behavior
+at run time. Initially, an empty symbols object matches nothing. At any time,
+symbols may be added or removed, thus, dynamically altering its behavior.
+
+Each entry in a symbol table has an associated mutable data slot. In this
+regard, one can view the symbol table as an associative container (or map) of
+key-value pairs where the keys are strings.
+
+The symbols class expects two template parameters. The first parameter specifies
+the character type of the symbols. The second specifies the data type associated
+with each symbol: its attribute.
+
+Here's a parser for roman hundreds (100..900) using the symbol table. Keep in
+mind that the data associated with each slot is the parser's attribute (which is
+passed to attached semantic actions).
+
+[import ../../example/qi/roman.cpp]
+
+[tutorial_roman_hundreds]
+
+Here's a parser for roman tens (10..90):
+
+[tutorial_roman_tens]
+
+and, finally, for ones (1..9):
+
+[tutorial_roman_ones]
+
+Now we can use `hundreds`, `tens` and `ones` anywhere in our parser expressions.
+They are all parsers.
+
+[heading Rules]
+
+Up until now, we've been inlining our parser expressions, passing them directly
+to the `phrase_parse` function. The expression evaluates into a temporary,
+unnamed parser which is passed into the `phrase_parse` function, used, and then
+destroyed. This is fine for small parsers. When the expressions get complicated,
+you'd want to break the expressions into smaller easier to understand pieces,
+name them, and refer to them from other parser expressions by name.
+
+A parser expression can be assigned to, what is called, a "rule". There are
+various ways to declare rules. The simplest form is:
+
+ rule<Iterator> r;
+
+At the very least, the rule needs to know the iterator type it will be working
+on. This rule cannot be used with `phrase_parse`. It can only be used with the
+`parse` function -- a version that does not do white space skipping (does not
+have the skipper argument). If you want to have it skip white spaces, you need
+to pass in the type skip parser, as in the next form:
+
+ rule<Iterator, Skipper> r;
+
+Example:
+
+ rule<std::string::iterator, space_type> r;
+
+This type of rule can be used for both `phrase_parse` and `parse`.
+
+For our next example, there's one more rule form you should know about:
+
+ rule<Iterator, Signature> r;
+
+or
+
+ rule<Iterator, Signature, Skipper> r;
+
+[tip All rule template arguments after Iterator can be supplied in any order.]
+
+The Signature specifies the attributes of the rule. You've seen that our parsers
+can have an attribute. Recall that the `double_` parser has an attribute of
+`double`. To be precise, these are /synthesized/ attributes. The parser
+"synthesizes" the attribute value. Think of them as function return values.
+
+There's another type of attribute called "inherited" attribute. We won't need
+them for now, but it's good that you be aware of such attributes. You can think
+of them as function arguments. And, rightly so, the rule signature is a function
+signature of the form:
+
+ result(argN, argN,..., argN)
+
+After having declared a rule, you can now assign any parser expression to it.
+Example:
+
+ r = double_ >> *(',' >> double_);
+
+[heading Grammars]
+
+A grammar encapsulates one or more rules. It has the same template parameters as
+the rule. You declare a grammar by:
+
+# deriving a struct (or class) from the `grammar` class template
+# declare one or more rules as member variables
+# initialize the base grammar class by giving it the start rule (its the first
+ rule that gets called when the grammar starts parsing)
+# initialize your rules in your constructor
+
+The roman numeral grammar is a very nice and simple example of a grammar:
+
+[tutorial_roman_grammar]
+
+Things to take notice of:
+
+* The grammar and start rule signature is `unsigned()`. It has a synthesized
+ attribute (return value) of type `unsigned` with no inherited attributes
+ (arguments).
+
+* We did not specify a skip-parser. We don't want to skip in between the
+ numerals.
+
+* `roman::base_type` is a typedef for `grammar<Iterator, unsigned()>`. If
+ `roman` was not a template, you can simply write: base_type(start)
+
+* But it's best to make your grammar templates, so that they can be reused
+ for different iterator types.
+
+* `_val` is another __phoenix__ placeholder representing the rule's synthesized
+ attribute.
+
+* `eps` is a special spirit parser that consumes no input but is always
+ successful. We use it to initialize `_val`, the rule's synthesized
+ attribute, to zero before anything else. The actual parser starts at
+ `+char_('M')`, parsing roman thousands. Using `eps` this way is good
+ for doing pre and post initializations.
+
+* The expression `a || b` reads: match a or b and in sequence. That is, if both
+ `a` and `b` match, it must be in sequence; this is equivalent to `a >> -b | b`,
+ but more efficient.
+
+[heading Let's Parse!]
+
+[tutorial_roman_grammar_parse]
+
+`roman_parser` is an object of type `roman` -our roman numeral parser. This time
+around, we are using the no-skipping version of the parse functions. We do not
+want to skip any spaces! We are also passing in an attribute, `unsigned result`,
+which will receive the parsed value.
+
+The full cpp file for this example can be found here: [@../../example/qi/roman.cpp]
+
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/rules.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/rules.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Rules]
+[endsect]

Added: trunk/libs/spirit/doc/qi/semantic_actions.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/semantic_actions.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,10 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 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)
+===============================================================================/]
+
+[section Semantic Actions]
+[endsect]

Added: trunk/libs/spirit/doc/qi/sum_tutorial.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/sum_tutorial.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,69 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Sum - adding numbers]
+
+Here's a parser that sums a comma-separated list of numbers.
+
+[import ../../example/qi/sum.cpp]
+
+Ok we've glossed over some details in our previous examples. First, our
+includes:
+
+[tutorial_adder_includes]
+
+Then some using directives:
+
+[tutorial_adder_using]
+
+[table
+ [[Namespace] [Description]]
+ [[boost::phoenix] [All of phoenix]]
+ [[boost::spirit] [All of spirit]]
+ [[boost::spirit::qi] [All of spirit.qi]]
+ [[boost::spirit::ascii] [ASCII version of `char_` and all char related parsers. Other
+ encodings are also provided (e.g. also an ISO8859.1)]]
+ [[boost::spirit::arg_names] [Special phoenix placeholders for spirit]]
+]
+
+[note If you feel uneasy with using whole namespaces, feel free to qualify your
+code, use namespace aliases, etc. For the purpose of this tutorial, we will be
+presenting unqualified names for both Spirit and __phoenix__. No worries, we
+will always present the full working code, so you won't get lost. In fact, all
+examples in this tutorial have a corresponding cpp file that QuickBook (the
+documentation tool we are using) imports in here as code snippets.]
+
+Now the actual parser:
+
+[tutorial_adder]
+
+The full cpp file for this example can be found here: [@../../example/qi/actions.cpp]
+
+This is almost like our original numbers list example. We're incrementally
+building on top of our examples. This time though, like in the complex number
+example, we'll be adding the smarts. There's an accumulator (`double& n) that
+adds the numbers parsed. On a successful parse, this number is the sum of all
+the parsed numbers.
+
+The first `double_` parser attaches this action:
+
+ ref(n) = _1
+
+This assigns the parsed result (actually, the attribute of `double_`) to `n`.
+`ref(n)` tells __phoenix__ that `n` is a mutable reference. `_1` is a
+__phoenix__ placeholder for the parsed result attribute.
+
+The second `double_` parser attaches this action:
+
+ ref(n) += _1
+
+So, subsequent numbers add into `n`.
+
+That wasn't too bad, was it :-) ?
+
+[endsect]

Added: trunk/libs/spirit/doc/qi/tutorial_intro.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/tutorial_intro.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,42 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Quick Start]
+
+[heading Why would you want to use Spirit.Qi?]
+
+Spirit.Qi is designed to be a practical parsing tool. The ability to generate a
+fully-working parser from a formal EBNF specification inlined in C++
+significantly reduces development time. Programmers typically approach parsing
+using ad hoc hacks with primitive tools such as scanf. Even regular-expression
+libraries (such as boost regex) or scanners (such as Boost tokenizer) do not
+scale well when we need to write more elaborate parsers. Attempting to write
+even a moderately-complex parser using these tools leads to code that is hard to
+understand and maintain.
+
+One prime objective is to make the tool easy to use. When one thinks of a
+parser generator, the usual reaction is "it must be big and complex with a
+steep learning curve." Not so. Spirit is designed to be fully scalable. The
+framework is structured in layers. This permits learning on an as-needed basis,
+after only learning the minimal core and basic concepts.
+
+For development simplicity and ease in deployment, the entire framework
+consists of only header files, with no libraries to link against or build.
+Just put the spirit distribution in your include path, compile and run. Code
+size? -very tight -essentially comparable to hand written recursive descent
+code.
+
+Our tutorials will walk you through the simplest Spirit examples, incrementally
+building on top of the earlier examples as we expose more and more features and
+techniques. We will try to be as gentle as possible with the learning curve.
+We will present the tutorials in a cookbook style approach. This style of
+presentation is based on our BoostCon '07 and BoostCon '08 slides.
+
+Have fun!
+
+[endsect] [/ Quickstart]

Added: trunk/libs/spirit/doc/qi/warming_up.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/doc/qi/warming_up.qbk 2009-05-30 06:07:51 EDT (Sat, 30 May 2009)
@@ -0,0 +1,138 @@
+[/==============================================================================
+ Copyright (C) 2001-2008 Joel de Guzman
+ Copyright (C) 2001-2008 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 Warming up]
+
+We'll start by showing examples of parser expressions to give you a feel on how
+to build parsers from the simplest parser, building up as we go.
+
+[heading Trivial Example #1 Parsing a number]
+
+Create a parser that will parse a floating-point number.
+
+ double_
+
+(You've got to admit, that's trivial!) The above code actually generates a
+Spirit floating point parser (a built-in parser). Spirit has many pre-defined
+parsers and consistent naming conventions help you keep from going insane!
+
+[heading Trivial Example #2 Parsing two numbers]
+
+Create a parser that will accept a line consisting of two floating-point numbers.
+
+ double_ >> double_
+
+Here you see the familiar floating-point numeric parser `double_` used twice,
+once for each number. What's that `>>` operator doing in there? Well, they had
+to be separated by something, and this was chosen as the "followed by" sequence
+operator. The above program creates a parser from two simpler parsers, glueing
+them together with the sequence operator. The result is a parser that is a
+composition of smaller parsers. Whitespace between numbers can implicitly be
+consumed depending on how the parser is invoked (see below).
+
+[note When we combine parsers, we end up with a "bigger" parser, but
+ it's still a parser. Parsers can get bigger and bigger, nesting more and more,
+ but whenever you glue two parsers together, you end up with one bigger parser.
+ This is an important concept.
+]
+
+[heading Trivial Example #3 Parsing one or more numbers]
+
+Create a parser that will accept zero or more floating-point numbers.
+
+ *double_
+
+This is like a regular-expression Kleene Star, though the syntax might look a
+bit odd for a C++ programmer not used to seeing the `*` operator overloaded like
+this. Actually, if you know regular expressions it may look odd too since the
+star is before the expression it modifies. C'est la vie. Blame it on the fact
+that we must work with the syntax rules of C++.
+
+Any expression that evaluates to a parser may be used with the Kleene Star.
+Keep in mind, though, that due to C++ operator precedence rules you may need
+to put the expression in parentheses for complex expressions. The Kleene Star
+is also known as a Kleene Closure, but we call it the Star in most places.
+
+[heading Trivial Example #4 Parsing a comma-delimited list of numbers]
+
+This example will create a parser that accepts a comma-delimited list of
+numbers.
+
+ double_ >> *(char_(',') >> double_)
+
+Notice `char_(',')`. It is a literal character parser that can recognize the
+comma `','`. In this case, the Kleene Star is modifying a more complex parser,
+namely, the one generated by the expression:
+
+ (char_(',') >> double_)
+
+Note that this is a case where the parentheses are necessary. The Kleene star
+encloses the complete expression above.
+
+[heading Let's Parse!]
+
+We're done with defining the parser. So the next step is now invoking this
+parser to do its work. There are a couple of ways to do this. For now, we will
+use the `phrase_parse` function. One overload of this function accepts four
+arguments:
+
+# An iterator pointing to the start of the input
+# An iterator pointing to one past the end of the input
+# The parser object
+# Another parser called the skip parser
+
+In our example, we wish to skip spaces and tabs. Another parser named `space`
+is included in Spirit's repertoire of predefined parsers. It is a very simple
+parser that simply recognizes whitespace. We will use `space` as our skip
+parser. The skip parser is the one responsible for skipping characters in
+between parser elements such as the `double_` and `char_`.
+
+Ok, so now let's parse!
+
+[import ../../example/qi/num_list1.cpp]
+[tutorial_numlist1]
+
+The parse function returns `true` or `false` depending on the result of the
+parse. The first iterator is passed by reference. On a successful parse,
+this iterator is repositioned to the rightmost position consumed by the
+parser. If this becomes equal to str.end(), then we have a full match.
+If not, then we have a partial match. A partial match happens when the
+parser is only able to parse a portion of the input.
+
+Note that we inlined the parser directly in the call to parse. Upon calling
+parse, the expression evaluates into a temporary, unnamed parser which is passed
+into the parse() function, used, and then destroyed.
+
+Here, we opted to make the parser generic by making it a template, parameterized
+by the iterator type. By doing so, it can take in data coming from any STL
+conforming sequence as long as the iterators conform to a forward iterator.
+
+You can find the full cpp file here: [@../../example/qi/num_list1.cpp]
+
+[note `char` and `wchar_t` operands
+
+The careful reader may notice that the parser expression has `','` instead of
+`char_(',')` as the previous examples did. This is ok due to C++ syntax rules of
+conversion. There are `>>` operators that are overloaded to accept a `char` or
+`wchar_t` argument on its left or right (but not both). An operator may be
+overloaded if at least one of its parameters is a user-defined type. In this
+case, the `double_` is the 2nd argument to `operator>>`, and so the proper
+overload of `>>` is used, converting `','` into a character literal parser.
+
+The problem with omiting the `char_` should be obvious: `'a' >> 'b'` is not a
+spirit parser, it is a numeric expression, right-shifting the ASCII (or another
+encoding) value of `'a'` by the ASCII value of `'b'`. However, both
+`char_('a') >> 'b'` and `'a' >> char_('b')` are Spirit sequence parsers
+for the letter `'a'` followed by `'b'`. You'll get used to it, sooner or later.
+]
+
+Finally, take note that we test for a full match (i.e. the parser fully parsed
+the input) by checking if the first iterator, after parsing, is equal to the end
+iterator. You may strike out this part if partial matches are to be allowed.
+
+[endsect] [/ Warming up]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk