| Home | Libraries | People | FAQ | More

##### Rule

###### Description

The rule is a polymorphic parser that acts as a named placeholder capturing the behavior of a Parsing Expression Grammar expression assigned to it. Naming a Parsing Expression Grammar expression allows it to be referenced later and makes it possible for the rule to call itself. This is one of the most important mechanisms and the reason behind the word "recursive" in recursive descent parsing.

###### Header

    // forwards to <boost/spirit/home/qi/nonterminal/rule.hpp>
    #include <boost/spirit/include/qi_rule.hpp>

Also, see Include Structure.

###### Namespace

Name
`boost::spirit::qi::rule`

###### Synopsis

    template <typename Iterator, typename A1, typename A2, typename A3>
    struct rule;

###### Template parameters

Parameter | Description | Default
--- | --- | ---
`Iterator` | The underlying iterator type that the rule is expected to work on. | none
`A1`, `A2`, `A3` | Either `Signature`, `Skipper` or `Locals` in any order. See table below. | See table below.

Here is more information about the template parameters:

Parameter | Description | Default
--- | --- | ---
`Signature` | Specifies the rule's synthesized (return value) and inherited attributes (arguments). More on this here: `Nonterminal`. | `unused_type`. When `Signature` defaults to `unused_type`, the effect is the same as specifying a signature of `void()` which is also equivalent to `unused_type()`
`Skipper` | Specifies the rule's skipper parser. Specify this if you want the rule to skip white spaces. If this is not specified, the rule is an "implicit lexeme" and will not skip spaces. "implicit lexeme" rules can still be called with a skipper. In such a case, the rule does a pre-skip just as all lexemes and primitives do. | `unused_type`
`Locals` | Specifies the rule's local variables. See `Nonterminal`. | `unused_type`

###### Model of

> `Nonterminal`

Notation

`r, r2`

  Rules

`p`

  A parser expression

`Iterator`

  The underlying iterator type that the rule is expected to work on.

`A1`, `A2`, `A3`

  Either `Signature`, `Skipper` or `Locals` in any order.

###### Expression Semantics

Semantics of an expression is defined only where it differs from, or is not defined in `Nonterminal`.

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`.

`r = r2;` | Assign rule `r2` to `r`.
`r.alias()` | return an alias of `r`. The alias is a parser that holds a reference to `r`.
`r.copy()` | Get a copy of `r`.
`r = p;` | Rule definition. This is equivalent to `r %= p` (see below) if there are no semantic actions attached anywhere in `p`.
`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.

###### Attributes

> The parser attribute of the rule is `T`, its synthesized attribute. See `Attribute`

###### Complexity

> The complexity is defined by the complexity of the RHS parser, `p`

###### Example

| Note
The test harness for the example(s) below is presented in the Basics Examples section.

Some using declarations:

    using boost::spirit::qi::rule;
    using boost::spirit::qi::int_;
    using boost::spirit::qi::locals;
    using boost::spirit::qi::_1;
    using boost::spirit::qi::_a;
    using boost::spirit::ascii::alpha;
    using boost::spirit::ascii::char_;
    using boost::spirit::ascii::space_type;

Basic rule:

    rule<char const*> r;
    r = int_;
    test_parser("123", r);

Rule with synthesized attribute:

    rule<char const*, int()> ra;
    ra = int_;
    int i;
    test_parser_attr("123", ra, i);
    assert(i ==  123);

Rule with skipper and synthesized attribute:

    rule<char const*, std::vector<int>(), space_type> rs;
    rs = *int_;
    std::vector<int> v;
    test_phrase_parser_attr("123 456 789", rs, v);
    assert(v[0] ==  123);
    assert(v[1] ==  456);
    assert(v[2] ==  789);

Rule with one local variable:

    rule<char const*, locals<char> > rl;
    rl = alpha[_a = _1] >> char_(_a); // get two identical characters
    test_parser("aa", rl); // pass
    test_parser("ax", rl); // fail