$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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]