Nonterminal

| Home | Libraries | People | FAQ | More

##### Nonterminal

###### Description

A Nonterminal is a symbol in a Parsing Expression Grammar production that represents a grammar fragment. Nonterminals may self reference to specify recursion. This is one of the most important concepts and the reason behind the word "recursive" in recursive descent generation.

###### Refinement of

> `Generator`

###### Signature

Rules can have both consumed and inherited attributes. The rule's Signature specifies both the consumed and inherited attributes. The specification uses the function declarator syntax:

    RT(A0, A1, A2, ..., AN)

where `RT` is the rule's consumed attribute and `A0` ... `AN` are the rule's inherited attributes.

###### Attributes

The rule models a C++ function. The rule's consumed attribute is analogous to the function return value as it is the type -exposed- by the rule. Its inherited attributes are analogous to function arguments. The inherited attributes (arguments) can be passed in just like any Lazy Argument, e.g.:

    r(expr) // Evaluate expr at parse time and pass the result to the Nonterminal r

###### `_val`

The `boost::spirit::karma::_val` placeholder can be used in Phoenix semantic actions anywhere in the Nonterminal's definition. This Phoenix placeholder refers to the Nonterminal's (consumed) attribute. The `_val` placeholder acts like an immutable reference to the Nonterminal's attribute.

| Note
Starting with Spirit V2.5 (distributed with Boost V1.47) the placeholder `_val` can be used in semantic actions attached to top level generator components as well. See The Generator API for more information.

###### `_r1`...`r10`

The `boost::spirit::_r1`...`boost::spirit::r10` placeholders can be used in Phoenix semantic actions anywhere in the Nonterminal's definition. These Phoenix placeholders refer to the Nonterminal's inherited attributes.

###### Locals

Nonterminals can have local variables that will be created on the stack at runtime. A locals descriptor added to the Nonterminal declaration will give the Nonterminal local variables:

    template <typename T0, typename T1, typename T2, ..., typename TN>
    struct locals;

where `T0` ... `TN` are the types of local variables accessible in your Phoenix semantic actions using the placeholders:

- `boost::spirit::_a`
- `boost::spirit::_b`
- `boost::spirit::_c`
- `boost::spirit::_d`
- `boost::spirit::_e`
- `boost::spirit::_f`
- `boost::spirit::_g`
- `boost::spirit::_h`
- `boost::spirit::_i`
- `boost::spirit::_j`

which correspond to the Nonterminal's local variables `T0` ... `T9`.

Notation

`x`

  A Nonterminal

`X`

  A Nonterminal type

`arg1`, `arg2`, ..., `argN`

  Lazy Arguments that evaluate to each of the Nonterminal's inherited attributes.

###### Valid Expressions

In addition to the requirements defined in `Generator`, for any Nonterminal the following must be met:

Expression | Semantics | Return type
--- | --- | ---
`x` | In a generator expression, invoke Nonterminal `x` | `X`
`x(arg1, arg2, ..., argN)` | In a generator expression, invoke Nonterminal `x` passing in inherited attributes `arg1`...`argN` | `X`
`x.name(name)` | Set the name of a Nonterminal | `void`
`x.name()` | Get the name of a Nonterminal | `std::string`

###### Type Expressions

Expression | Description
--- | ---
`X::sig_type` | The Signature of `X`: An MPL Forward Sequence. The first element is the Nonterminal's consumed attribute type and the rest are the inherited attribute types.
`X::locals_type` | The local variables of `X`: An MPL Forward Sequence.

###### Models

- rule
- grammar