Refactoring Parsers

There are two 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. The Refactoring Parsers described here are introduced to allow a simple and more expressive notation while using Confix Parsers and List Parsers.

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_action_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 auxilliary binary parser (here the difference parser) and the left operand of this binary parser is an auxilliary 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 a 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 auxilliary binary parser (here the difference parser) and the left operand of this binary parser is an auxilliary 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.

Nested refactoring

Sometimes it is required to nest both 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.