The Spirit.Qisubrule
is a component allowing to create a named parser, and to refer to it by
name -- much like rules and grammars. It is in fact a fully static version
of the rule.

The strength of subrules is performance. Replacing some rules with subrules
can make a parser slightly faster (see Performance
below for measurements). The reason is that subrules allow aggressive inlining
by the C++ compiler, whereas the implementation of rules is based on a
virtual function call which, depending on the compiler, can have some run-time
overhead and stop inlining.

The weaknesses of subrules are:

subrules can only be defined and used within the same parser expression.
A subrule cannot be defined at one location, and then used in another
location.

subrules put a massive strain on the C++ compiler. They increase compile
times and memory usage during compilation, and also increase the risk
of hitting compiler limits and/or bugs.

As shown in this code snippet (an extract from the calc1_sr example), subrules
can be freely mixed with rules and grammars. Here, a group of 3 subrules
(expression, term, factor)
is assigned to a rule (named entry).
This means that parts of a parser can use subrules (typically the innermost,
most performance-critical parts), whereas the rest can use rules and grammars.

A subrule group (a set of subrule definitions) is a parser, which can be
used anywhere in a parser expression (in assignments to rules, as well
as directly in arguments to functions such as parse).
In a group, parsing proceeds from the start subrule, which is the first
(topmost) subrule defined in that group. In the two groups in the synopsis
above, sr1 and srA are the start subrules respectively
-- for example when the first subrule group is called forth, the sr1 subrule is called.

A subrule can only be used in a group which defines it. Groups can be viewed
as scopes: a definition of a subrule is limited to its enclosing group.

rule<charconst*>r1,r2,r3;subrule<1>sr1;subrule<2>sr2;r1=(sr1='a'>>int_)// First group in r1.>>(sr2=+sr1)// Second group in r1.// ^^^// DOES NOT COMPILE: sr1 is not defined in this// second group, it cannot be used here (its// previous definition is out of scope).;r2=(sr1='a'>>int_)// Only group in r2.>>sr1// ^^^// DOES NOT COMPILE: not in a subrule group,// sr1 cannot be used here (here too, its// previous definition is out of scope).;r3=(sr1='x'>>double_)// Another group. The same subrule `sr1`// can have another, independent// definition in this group.;

Subrules push the C++ compiler hard. A group of subrules is a single C++
expression. Current C++ compilers cannot handle very complex expressions
very well. One restricting factor is the typical compiler's limit on template
recursion depth. Some, but not all, compilers allow this limit to be configured.

g++'s maximum can be set using a compiler flag: -ftemplate-depth. Set this appropriately if you
use relatively complex subrules.