Refactoring Parsers

| Refactoring Parsers |

There are three types of Refactoring Parsers implemented right now, which help to abstract common parser refactoring tasks. Parser refactoring means, that a concrete parser construct is replaced (refactored) by another very similar parser construct. Two of the Refactoring Parsers described here (`refactor_unary_parser` and `refactor_action_parser`) are introduced to allow a simple and more expressive notation while using Confix Parsers and List Parsers. The third Refactoring Parser (`attach_action_parser`) is implemented to abstract some functionality required for the Grouping Parser. Nevertheless these Refactoring Parsers may help in solving other complex parsing tasks too.

### Refactoring unary parsers

The `refactor_unary_d` parser generator, which should be used to generate a unary refactoring parser, transforms a construct of the following type

        refactor_unary_d[*some_parser - another_parser]

to

        *(some_parser - another_parser)

> where `refactor_unary_d` is a predefined object of the parser generator struct `refactor_unary_gen<>`

The `refactor_unary_d` parser generator generates a new parser as shown above, only if the original construct is an auxiliary binary parser (here the difference parser) and the left operand of this binary parser is an auxiliary unary parser (here the kleene star operator). If the original parser isn't a binary parser the compilation will fail. If the left operand isn't an unary parser, no refactoring will take place.

### Refactoring action parsers

The `refactor_action_d` parser generator, which should be used to generate an action refactoring parser, transforms a construct of the following type

        refactor_action_d[some_parser[some_actor] - another_parser]

to

        (some_parser - another_parser)[some_actor]

> where `refactor_action_d` is a predefined object of the parser generator struct `refactor_action_gen<>`

The `refactor_action_d` parser generator generates a new parser as shown above, only if the original construct is an auxiliary binary parser (here the difference parser) and the left operand of this binary parser is an auxiliary parser generated by an attached semantic action. If the original parser isn't a binary parser the compilation will fail. If the left operand isn't an action parser, no refactoring will take place.

### Attach action refactoring

The `attach_action_d` parser generator, which should be used to generate an attach action refactoring parser, transforms a construct of the following type

        attach_action_d[(some_parser >> another_parser)[some_actor]]

to

        some_parser[some_actor] >> another_parser[some_actor]

> where `attach_action_d` is a predefined object of the parser generator struct `attach_action_gen<>`

The `attach_action_d` parser generator generates a new parser as shown above, only if the original construct is an auxiliary action parser and the parser to it this action is attached is an auxiliary binary parser (here the sequence parser). If the original parser isn't a action parser the compilation will fail. If the parser to which the action is attached isn't an binary parser, no refactoring will take place.

### Nested refactoring

Sometimes it is required to nest different types of refactoring, i.e. to transform constructs like

        (*some_parser)[some_actor] - another_parser

to

        (*(some_parser - another_parser))[some_actor]

To simplify the construction of such nested refactoring parsers the `refactor_unary_gen<>` and `refactor_action_gen<>` both can take another refactoring parser generator type as their respective template parameter. For instance, to construct a refactoring parser generator for the mentioned nested transformation we should write:

        typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
        const refactor_t refactor_nested_d = refactor_t(refactor_unary_d);

Now we could use it as follows to get the required result:

        refactor_nested_d[(*some_parser)[some_actor] - another_parser]

An empty template parameter means not to nest this particular refactoring parser. The default template parameter is `non_nesting_refactoring`, a predefined helper structure for inhibiting nesting. Sometimes it is required to nest a particular refactoring parser with itself. This is achieved by providing the predefined helper structure `self_nested_refactoring` as the template parameter to the corresponding refactoring parser generator template.

See refactoring.cpp for a compilable example. This is part of the Spirit distribution.

Copyright © 2001-2003 Hartmut Kaiser
Use, modification and distribution is subject to 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)