/*
* xtc - The eXTensible Compiler
* Copyright (C) 2004-2007 Robert Grimm
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package xtc.util;
/**
* The interface to all actions. An action implements a computation
* that takes a single argument and produces a single result. Both
* argument and result have the same type so that actions can be
* trivially composed with each other.
*
* <p />Actions help in producing a left-recursive AST, even though
* the productions generating the individual AST nodes are
* right-recursive (as left-recursion is generally illegal for
* <i>Rats!</i>' grammars). The basic idea is to create a {@link Pair
* list} of actions during the right-recursion and then apply the
* actions onto the semantic value of the base case.
*
* <p />To illustrate this use of actions, consider the grammar rule
* for logical and expressions in C:<pre>
* <i>logical-and-expression</i> :
* <i>bitwise-or-expression</i>
* <i>logical-and-expression</i> <b>&&</b> <i>bitwise-or-expression</i>
* </pre>
* Since this grammar rule is left-recursive, it cannot directly be
* converted into the corresponding <i>Rats!</i> production and must
* be rewritten as a right-recursion. At the same time, the
* corresponding AST should still be left-recursive, as the logical
* and operator is left-associative.
*
* <p />Using actions and {@link xtc.tree.GNode generic nodes} as
* semantic values, the corresponding right-recursive productions can
* be written as follows:<pre>
* Node LogicalAndExpression =
* base:BitwiseOrExpression list:LogicalAndExpressionTail*
* { yyValue = apply(list, base); }
* ;
*
* Action<Node> LogicalAndExpressionTail =
* "&&":Symbol right:BitwiseOrExpression
* { yyValue = new Action<Node>() {
* public Node run(Node left) {
* return GNode.create("LogicalAndExpression", left, right);
* }};
* }
* ;
* </pre>
* The semantic action for the <code>LogicalAndExpression</code>
* production relies on an <code>apply()</code> helper method, which
* can be written as following:<pre>
* <T> T apply(Pair<Action<T>> actions, T seed) {
* while (! actions.isEmpty()) {
* seed = actions.head().run(seed);
* actions = actions.tail();
* }
* return seed;
* }
* </pre>
* In detail, the <code>LogicalAndExpressionTail</code> production
* recognizes logical and operators followed by the right operands.
* By using an action as its semantic value, the production delays the
* actual construction of the corresponding generic node. Once all
* logical and operators and the corresponding bitwise or expressions
* have been parsed, the semantic action for the
* <code>LogicalAndExpression</code> production applies the actions
* and creates a left-recursive AST. Note that this example assumes
* that the production for bitwise or expressions also has a generic
* node as its semantic value. Further note that, if there is no
* logical and operator in the input, this example simply passes the
* semantic value of the single bitwise or expression through, which
* is the desired behavior as it leaves the AST unmodified. Finally,
* note that direct left recursions may appear in generic productions,
* as <i>Rats!</i> automatically transforms them into the
* corresponding right-recursions while also creating left-recursive
* semantic values with the help of actions.
*
* @author Robert Grimm
* @version $Revision: 1.10 $
*/
public interface Action<T> {
/**
* Perform this action.
*
* @param arg The argument.
* @return The result.
*/
T run(T arg);
}