// $ANTLR 2.7.5 (20050128): "JAMParser.g" -> "JAMParser.java"$

package at.oefai.aaa.agent.jam;

// StefanRank: rewrite of JAMParser.jj (the JavaCC grammar for JAM) for ANTLR
// (because ANTLR also allows the generation of a Parser using Python/C++)

import antlr.TokenBuffer;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import antlr.ANTLRException;
import antlr.LLkParser;
import antlr.Token;
import antlr.TokenStream;
import antlr.RecognitionException;
import antlr.NoViableAltException;
import antlr.MismatchedTokenException;
import antlr.SemanticException;
import antlr.ParserSharedInputState;
import antlr.collections.impl.BitSet;

import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import at.oefai.aaa.agent.jam.types.DList;
import at.oefai.aaa.agent.jam.types.ExpList;
import at.oefai.aaa.agent.jam.types.Expression;
import at.oefai.aaa.agent.jam.types.Value;
import at.oefai.aaa.agent.jam.types.Variable;

/**
 * JAMParser builds a JAM agent by reading the definition from a file/stream.
 * @author StefanRank
 */
public class JAMParser extends antlr.LLkParser       implements JAMParserTokenTypes
 {

    // a logger for info and debug output, root logger for a start
    private AgentLogger log = AgentLogger.getStaticInstance();
    private static final String version = "0.1 (antlr version by StefanRank 2005-06-05,"
                                          + " based on JAM v.65+76i [November, 2001])";
    //public String filename = null;

    /** disallow public construction */
    //private JAMParser() {
    //    //dont
    //}

    /** Primary JAM interface to parser */
    static public void parse(Reader reader, Interpreter interpreter, String filename)
            throws ParseException {
        interpreter.getLog().config("JAM Parser Version " + JAMParser.version);
        JAMParser parser = new JAMParser(new JAMLexer(reader));
        //parser.filename = filename;
        try {
            parser.parseJamAgentDefinition(interpreter);
        } catch (ANTLRException e) {
            interpreter.getLog().severe("Encountered ANTLRException " + e + " during parse"
                    + "(throwing a ParseException).");
            //e.printStackTrace();
            throw new ParseException(e);
        }
        interpreter.getLog().config("JAM definition parse successful.");
    }

    /** convenience method for parsing strings */
    static public void parse(String sbuf, Interpreter interpreter, String filename)
            throws ParseException {
        JAMParser.parse(new StringReader(sbuf), interpreter, filename);
    }

    /** Command-line interface to parser to facilitate testing. */
    /** @todo move the following commandline parsing facility outward to a special CommandLineInterpreter */
    /*public static void main(String args[]) {
        JAMParser parser;
        IInterpreter interpreter = new Interpreter();
        interpreter.getLog().config("JAM Parser Version " + JAMParser.version);
        if (args.length == 0) {
            log.info("Reading from standard input . . .");
            parser = new JAMParser(new DataInputStream(System.in));
        } else if (args.length == 1) {
            log.info("Reading from file " + args[0] + " . . .");
            try {
                parser = new JAMParser(new DataInputStream(new FileInputStream(args[0])));
            } catch (FileNotFoundException e) {
                log.info("\n\nFile " + args[0] + " not found!\n\n");
                return;
            }
        } else {
            log.info("Usage is one of:");
            log.info("\t java JAMParser < inputfile");
            log.info("OR");
            log.info("\t java JAMParser inputfile");
            return;
        }
        try {
            parser.parseJamAgentDefinition(interpreter);
            log.info("JAM program parsed successfully.");
        } catch (ParseException e) {
            log.severe("Encountered parsing exception " + e + " during parse.");
            e.printStackTrace();
        } catch (Exception e) {
            log.severe("Encountered other exception " + e + " during parse.");
            e.printStackTrace();
        }
    }*/

protected JAMParser(TokenBuffer tokenBuf, int k) {
  super(tokenBuf,k);
  tokenNames = _tokenNames;
}

public JAMParser(TokenBuffer tokenBuf) {
  this(tokenBuf,4);
}

protected JAMParser(TokenStream lexer, int k) {
  super(lexer,k);
  tokenNames = _tokenNames;
}

public JAMParser(TokenStream lexer) {
  this(lexer,4);
}

public JAMParser(ParserSharedInputState state) {
  super(state,4);
  tokenNames = _tokenNames;
}

/** A jam definition: goals - facts - an observer plan - plans.
 * Stefan Rank: I added the EOF to ensure full parsing of the input
 * otherwise it just stops parsing if an agent_component is followed
 * by an unrecognised construct !!!
 */
    public final Interpreter  parseJamAgentDefinition(
        Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Interpreter retval;


        assert (interpreter != null);
        log = interpreter.getLog();
        retval = interpreter;


        agent_components(interpreter);
        match(Token.EOF_TYPE);
        retval = interpreter;
        return retval;
    }

/** JAM allowed arbitrary interleaving of Goals, Plans, Facts, and Observer.
 * Stefan Rank: removed arbitrary ordering, force goals-facts-observer-plans
 * only one observer allowed now (as only the latest one counted anyway)
 */
    public final void agent_components(
        Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        {
        switch ( LA(1)) {
        case GOALS:
        {
            match(GOALS);
            match(COLON);
            {
            _loop5:
            do {
                if (((LA(1) >= ACHIEVE && LA(1) <= QUERY))) {
                    goal(interpreter);
                }
                else {
                    break _loop5;
                }

            } while (true);
            }
            break;
        }
        case EOF:
        case FACTS:
        case OBSERVER:
        case PLAN:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case FACTS:
        {
            match(FACTS);
            match(COLON);
            {
            _loop8:
            do {
                if ((LA(1)==FACT)) {
                    fact(interpreter);
                }
                else {
                    break _loop8;
                }

            } while (true);
            }
            break;
        }
        case EOF:
        case OBSERVER:
        case PLAN:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case OBSERVER:
        {
            match(OBSERVER);
            match(COLON);

            Plan currentPlan = new Plan();
            PlanSequenceConstruct body_elements = null;

            match(LEFT_BRACE);
            body_elements=plan_body_elements(currentPlan, interpreter);
            match(RIGHT_BRACE);

            currentPlan.setBody(body_elements);
            interpreter.getPlanLibrary().setObserver(currentPlan);

            break;
        }
        case EOF:
        case PLAN:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        _loop11:
        do {
            if ((LA(1)==PLAN)) {
                match(PLAN);
                match(COLON);
                plan(interpreter);
            }
            else {
                break _loop11;
            }

        } while (true);
        }
    }

    public final void goal(
        Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {



        GoalAction goal = null;

        goal=goal_action(null, interpreter);
        match(SEMICOLON);

        interpreter.getIntentionStructure().addUnique(goal);

    }

    public final void fact(
        Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        ExpList el;
        String id;


        match(FACT);
        id=identifier();
        el=explist(null, interpreter);
        match(SEMICOLON);

        Relation rel = new Relation(id, el);
        interpreter.getWorldModel().assertRelation(rel, null);

    }

    public final PlanSequenceConstruct  plan_body_elements(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        PlanSequenceConstruct s;


        s = new PlanSequenceConstruct();
        PlanConstruct ct;


        {
        int _cnt54=0;
        _loop54:
        do {
            if ((_tokenSet_0.member(LA(1)))) {
                ct=plan_body_element(currentPlan, interpreter);
                s.insertConstruct(ct);
            }
            else {
                if ( _cnt54>=1 ) { break _loop54; } else {throw new NoViableAltException(LT(1), getFilename());}
            }

            _cnt54++;
        } while (true);
        }
        return s;
    }

/** A plan is just a list of statements. */
    public final void plan(
        Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {



        Plan currentPlan = new Plan();

        match(LEFT_BRACE);
        plan_components(currentPlan, interpreter);
        match(RIGHT_BRACE);

        interpreter.getPlanLibrary().add(currentPlan);

    }

    public final GoalAction  goal_action(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        GoalAction gab;


        gab = null;
        Expression e_utility;
        ExpList e_by;
        ExpList e_not_by;


        {
        gab=goal_action_basic(currentPlan, interpreter);
        {
        switch ( LA(1)) {
        case KEYWORD_UTILITY:
        {
            match(KEYWORD_UTILITY);
            e_utility=expression(currentPlan, interpreter);
            gab.setUtility(e_utility);
            break;
        }
        case LEFT_BRACE:
        case SEMICOLON:
        case KEYWORD_BY:
        case KEYWORD_NOT_BY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case KEYWORD_BY:
        {
            match(KEYWORD_BY);
            e_by=explist(currentPlan, interpreter);
            gab.setBy(e_by);
            break;
        }
        case LEFT_BRACE:
        case SEMICOLON:
        case KEYWORD_NOT_BY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case KEYWORD_NOT_BY:
        {
            match(KEYWORD_NOT_BY);
            e_not_by=explist(currentPlan, interpreter);
            gab.setNotBy(e_not_by);
            break;
        }
        case LEFT_BRACE:
        case SEMICOLON:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        }
        return gab;
    }

    public final String  identifier() throws RecognitionException, TokenStreamException {
        String returnid;

        Token  id = null;

        id = LT(1);
        match(IDENTIFIER);
        returnid = id.getText();
        return returnid;
    }

    public final ExpList  explist(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        ExpList returnel;


        returnel = new ExpList();
        Expression e;


        {
        switch ( LA(1)) {
        case LEFT_PAREN:
        case INTEGER:
        case FLOAT:
        case VARIABLE:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            e=expression(currentPlan, interpreter);
            returnel.addLast(e);
            {
            _loop98:
            do {
                if ((_tokenSet_1.member(LA(1)))) {
                    e=expression(currentPlan, interpreter);
                    returnel.addLast(e);
                }
                else {
                    break _loop98;
                }

            } while (true);
            }
            break;
        }
        case LEFT_BRACE:
        case SEMICOLON:
        case RIGHT_PAREN:
        case KEYWORD_UTILITY:
        case KEYWORD_BY:
        case KEYWORD_NOT_BY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returnel;
    }

    public final void plan_components(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        plan_preamble(currentPlan);
        {
        switch ( LA(1)) {
        case GOAL:
        case CONCLUDE:
        {
            plan_goalorconcludecomponents(currentPlan, interpreter);
            break;
        }
        case PERCEIVE:
        {
            plan_perceivecomponents(currentPlan, interpreter);
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
    }

    public final void plan_preamble(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {


        {
        switch ( LA(1)) {
        case NAME:
        {
            plan_name(currentPlan);
            break;
        }
        case DOCUMENTATION:
        case ATTRIBUTES:
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case DOCUMENTATION:
        {
            plan_doc(currentPlan);
            break;
        }
        case ATTRIBUTES:
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case ATTRIBUTES:
        {
            plan_attributes(currentPlan);
            break;
        }
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
    }

    public final void plan_goalorconcludecomponents(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        {
        switch ( LA(1)) {
        case GOAL:
        {
            plan_goalspec(currentPlan, interpreter);
            break;
        }
        case CONCLUDE:
        {
            plan_concludespec(currentPlan, interpreter);
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case PRECONDITION:
        {
            plan_precondition(currentPlan, interpreter);
            break;
        }
        case CONTEXT:
        case UTILITY:
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case CONTEXT:
        {
            plan_context(currentPlan, interpreter);
            break;
        }
        case UTILITY:
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case UTILITY:
        {
            plan_utility(currentPlan, interpreter);
            break;
        }
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        plan_body(currentPlan, interpreter);
        {
        switch ( LA(1)) {
        case EFFECTS:
        {
            plan_effects(currentPlan, interpreter);
            break;
        }
        case RIGHT_BRACE:
        case FAILURE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        {
        switch ( LA(1)) {
        case FAILURE:
        {
            plan_failure(currentPlan, interpreter);
            break;
        }
        case RIGHT_BRACE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
    }

    public final void plan_perceivecomponents(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        plan_perceivespec(currentPlan, interpreter);
        {
        switch ( LA(1)) {
        case PRECONDITION:
        {
            plan_precondition(currentPlan, interpreter);
            break;
        }
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        plan_body(currentPlan, interpreter);
    }

/** Part of plan documentation: the name. */
    public final void plan_name(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {


        String s = null;
        match(NAME);
        match(COLON);
        {
        switch ( LA(1)) {
        case STRING:
        {
            s=string();
            break;
        }
        case DOCUMENTATION:
        case ATTRIBUTES:
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (s != null) {
        currentPlan.setName(s);
        }

    }

/** Part of plan documentation: a documentation string */
    public final void plan_doc(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {


        String s = null;
        match(DOCUMENTATION);
        match(COLON);
        {
        switch ( LA(1)) {
        case STRING:
        {
            s=string();
            break;
        }
        case ATTRIBUTES:
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (s != null) {
        currentPlan.setDocumentation(s);
        }

    }

/** Arbitrary plan attributes. */
    public final void plan_attributes(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {


        String s = null;
        match(ATTRIBUTES);
        match(COLON);
        {
        switch ( LA(1)) {
        case STRING:
        {
            s=string();
            break;
        }
        case GOAL:
        case CONCLUDE:
        case PERCEIVE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (s != null) {
        currentPlan.setAttributes(s);
        }

    }

/** Goal Specification. */
    public final void plan_goalspec(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        GoalAction ga = null;


        match(GOAL);
        match(COLON);
        ga=goal_action(currentPlan, interpreter);
        match(SEMICOLON);

        currentPlan.setGoalSpecification(ga);

    }

/** Plan Conclude Specification. */
    public final void plan_concludespec(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        Relation rel = null;


        match(CONCLUDE);
        match(COLON);
        rel=relation(currentPlan, interpreter);
        match(SEMICOLON);

        currentPlan.setConcludeSpecification(rel);

    }

/** Precondition. */
    public final void plan_precondition(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        DList c = null;


        match(PRECONDITION);
        match(COLON);
        {
        switch ( LA(1)) {
        case FACT:
        case RETRIEVE:
        case LEFT_PAREN:
        case INTEGER:
        case FLOAT:
        case VARIABLE:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            c=condition_list(currentPlan, interpreter);
            break;
        }
        case CONTEXT:
        case UTILITY:
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (c != null) {
        PlanContext precondition = new PlanContext(c);
        currentPlan.setPrecondition(precondition);
        }

    }

/** Context. */
    public final void plan_context(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        DList c = null;


        match(CONTEXT);
        match(COLON);
        {
        switch ( LA(1)) {
        case FACT:
        case RETRIEVE:
        case LEFT_PAREN:
        case INTEGER:
        case FLOAT:
        case VARIABLE:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            c=condition_list(currentPlan, interpreter);
            break;
        }
        case UTILITY:
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (c != null) {
        PlanContext context = new PlanContext(c);
        currentPlan.setContext(context);
        }

    }

/** Utility. */
    public final void plan_utility(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        Expression e = null;


        match(UTILITY);
        match(COLON);
        {
        switch ( LA(1)) {
        case LEFT_PAREN:
        case INTEGER:
        case FLOAT:
        case VARIABLE:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            e=expression(currentPlan, interpreter);
            match(SEMICOLON);
            break;
        }
        case BODY:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (e != null) {
        currentPlan.setUtility(e);
        }

    }

/** Body */
    public final void plan_body(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        PlanSequenceConstruct body_elements = null;


        match(BODY);
        match(COLON);
        body_elements=plan_body_elements(currentPlan, interpreter);

        if (body_elements != null) {
        currentPlan.setBody(body_elements);
        }

    }

/** Effects. */
    public final void plan_effects(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        PlanSequenceConstruct body_elements = null;
        PlanAtomicConstruct atomic_element = null;


        match(EFFECTS);
        match(COLON);
        {
        switch ( LA(1)) {
        case FACT:
        case ASSERT:
        case RETRACT:
        case PLAN_BODY_AND:
        case PLAN_BODY_OR:
        case PLAN_BODY_PARALLEL:
        case PLAN_BODY_DO_ALL:
        case PLAN_BODY_DO_ANY:
        case PLAN_BODY_WHEN:
        case PLAN_BODY_WHILE:
        case PLAN_BODY_DO:
        case PLAN_BODY_ATOMIC:
        case PLAN_BODY_WAIT:
        case RETRIEVE:
        case EXECUTE:
        case LOAD:
        case RETRIEVEALL:
        case NEXTFACT:
        case TEST:
        case UPDATE:
        case ASSIGN:
        case SUCCEED:
        case FAIL:
        case POST:
        case UNPOST:
        case ACHIEVE:
        case PERFORM:
        case MAINTAIN:
        case QUERY:
        {
            body_elements=plan_body_elements(currentPlan, interpreter);
            break;
        }
        case RIGHT_BRACE:
        case FAILURE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (body_elements != null) {
        atomic_element = new PlanAtomicConstruct(body_elements);
        currentPlan.setEffects(atomic_element);
        }

    }

/** Failure. */
    public final void plan_failure(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        PlanSequenceConstruct body_elements = null;
        PlanAtomicConstruct atomic_element = null;


        match(FAILURE);
        match(COLON);
        {
        switch ( LA(1)) {
        case FACT:
        case ASSERT:
        case RETRACT:
        case PLAN_BODY_AND:
        case PLAN_BODY_OR:
        case PLAN_BODY_PARALLEL:
        case PLAN_BODY_DO_ALL:
        case PLAN_BODY_DO_ANY:
        case PLAN_BODY_WHEN:
        case PLAN_BODY_WHILE:
        case PLAN_BODY_DO:
        case PLAN_BODY_ATOMIC:
        case PLAN_BODY_WAIT:
        case RETRIEVE:
        case EXECUTE:
        case LOAD:
        case RETRIEVEALL:
        case NEXTFACT:
        case TEST:
        case UPDATE:
        case ASSIGN:
        case SUCCEED:
        case FAIL:
        case POST:
        case UNPOST:
        case ACHIEVE:
        case PERFORM:
        case MAINTAIN:
        case QUERY:
        {
            body_elements=plan_body_elements(currentPlan, interpreter);
            break;
        }
        case RIGHT_BRACE:
        {
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }

        if (body_elements != null) {
        atomic_element = new PlanAtomicConstruct(body_elements);
        currentPlan.setFailure(atomic_element);
        }

    }

/** Plan Perceive Specification. */
    public final void plan_perceivespec(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {


        Relation rel = null;


        {
        if ((LA(1)==PERCEIVE) && (LA(2)==COLON) && (LA(3)==ASSERT)) {
            match(PERCEIVE);
            match(COLON);
            match(ASSERT);
            rel=relation(currentPlan, interpreter);
            match(SEMICOLON);

            currentPlan.setPerceiveAssertSpecification(rel);

        }
        else if ((LA(1)==PERCEIVE) && (LA(2)==COLON) && (LA(3)==RETRACT)) {
            match(PERCEIVE);
            match(COLON);
            match(RETRACT);
            rel=relation(currentPlan, interpreter);
            match(SEMICOLON);

            currentPlan.setPerceiveRetractSpecification(rel);

        }
        else {
            throw new NoViableAltException(LT(1), getFilename());
        }

        }
    }

    public final String  string() throws RecognitionException, TokenStreamException {
        String returns;

        Token  str = null;

        str = LT(1);
        match(STRING);
        returns = str.getText();
        return returns;
    }

/** Relation */
    public final Relation  relation(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Relation returnr;


        returnr = null;
        String id;
        ExpList el;


        id=identifier();
        el=explist(currentPlan, interpreter);

        returnr = new Relation(id, el);

        return returnr;
    }

/** Condition */
    public final DList  condition_list(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        DList cl;


        cl = new DList();
        Condition c;


        c=condition(currentPlan, interpreter);
        cl.addLast(c);
        {
        _loop71:
        do {
            if ((_tokenSet_2.member(LA(1)))) {
                c=condition(currentPlan, interpreter);
                cl.addLast(c);
            }
            else {
                break _loop71;
            }

        } while (true);
        }
        return cl;
    }

/** Expression */
    public final Expression  expression(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Expression returnval;


        {
        switch ( LA(1)) {
        case INTEGER:
        case FLOAT:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            returnval=value(currentPlan);
            break;
        }
        case VARIABLE:
        {
            returnval=variable(currentPlan);
            break;
        }
        default:
            if ((LA(1)==LEFT_PAREN) && (LA(2)==IDENTIFIER||LA(2)==CLASS_IDENTIFIER||LA(2)==SPECIAL_FUNCTION_NAME)) {
                returnval=funcall(currentPlan, interpreter);
            }
            else if ((LA(1)==LEFT_PAREN) && (LA(2)==FACT||LA(2)==RETRIEVE||LA(2)==ACHIEVE)) {
                returnval=predicate(currentPlan, interpreter);
            }
        else {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returnval;
    }

    public final PlanSequenceConstruct  plan_branch(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        PlanSequenceConstruct returnsc;


        match(LEFT_BRACE);
        returnsc=plan_body_elements(currentPlan, interpreter);
        match(RIGHT_BRACE);
        return returnsc;
    }

    public final PlanConstruct  plan_body_element(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        PlanConstruct ct;


        Action a;
        PlanSequenceConstruct s;


        {
        switch ( LA(1)) {
        case FACT:
        case ASSERT:
        case RETRACT:
        case RETRIEVE:
        case EXECUTE:
        case LOAD:
        case RETRIEVEALL:
        case NEXTFACT:
        case TEST:
        case UPDATE:
        case ASSIGN:
        case SUCCEED:
        case FAIL:
        case POST:
        case UNPOST:
        case ACHIEVE:
        case PERFORM:
        case MAINTAIN:
        case QUERY:
        {
            a=action(currentPlan, interpreter);
            match(SEMICOLON);
            ct = new PlanSimpleConstruct(a);
            break;
        }
        case PLAN_BODY_AND:
        {
            match(PLAN_BODY_AND);
            ct = new PlanBranchConstruct(null, PlanBranchConstruct.BranchType.AND_BRANCH);
            {
            int _cnt58=0;
            _loop58:
            do {
                if ((LA(1)==LEFT_BRACE)) {
                    s=plan_branch(currentPlan, interpreter);
                    ((PlanBranchConstruct) ct).addBranch(s);
                }
                else {
                    if ( _cnt58>=1 ) { break _loop58; } else {throw new NoViableAltException(LT(1), getFilename());}
                }

                _cnt58++;
            } while (true);
            }
            match(SEMICOLON);
            break;
        }
        case PLAN_BODY_OR:
        {
            match(PLAN_BODY_OR);
            ct = new PlanBranchConstruct(null, PlanBranchConstruct.BranchType.OR_BRANCH);
            {
            int _cnt60=0;
            _loop60:
            do {
                if ((LA(1)==LEFT_BRACE)) {
                    s=plan_branch(currentPlan, interpreter);
                    ((PlanBranchConstruct) ct).addBranch(s);
                }
                else {
                    if ( _cnt60>=1 ) { break _loop60; } else {throw new NoViableAltException(LT(1), getFilename());}
                }

                _cnt60++;
            } while (true);
            }
            match(SEMICOLON);
            break;
        }
        case PLAN_BODY_PARALLEL:
        {
            match(PLAN_BODY_PARALLEL);
            ct = new PlanParallelConstruct();
            {
            int _cnt62=0;
            _loop62:
            do {
                if ((LA(1)==LEFT_BRACE)) {
                    s=plan_branch(currentPlan, interpreter);
                    ((PlanParallelConstruct) ct).insertConstruct(s);
                }
                else {
                    if ( _cnt62>=1 ) { break _loop62; } else {throw new NoViableAltException(LT(1), getFilename());}
                }

                _cnt62++;
            } while (true);
            }
            match(SEMICOLON);
            break;
        }
        case PLAN_BODY_DO_ALL:
        {
            match(PLAN_BODY_DO_ALL);
            ct = new PlanDoAllConstruct();
            {
            int _cnt64=0;
            _loop64:
            do {
                if ((LA(1)==LEFT_BRACE)) {
                    s=plan_branch(currentPlan, interpreter);
                    ((PlanDoAllConstruct) ct).addBranch(s);
                }
                else {
                    if ( _cnt64>=1 ) { break _loop64; } else {throw new NoViableAltException(LT(1), getFilename());}
                }

                _cnt64++;
            } while (true);
            }
            match(SEMICOLON);
            break;
        }
        case PLAN_BODY_DO_ANY:
        {
            match(PLAN_BODY_DO_ANY);
            ct = new PlanDoAnyConstruct();
            {
            int _cnt66=0;
            _loop66:
            do {
                if ((LA(1)==LEFT_BRACE)) {
                    s=plan_branch(currentPlan, interpreter);
                    ((PlanDoAnyConstruct) ct).addBranch(s);
                }
                else {
                    if ( _cnt66>=1 ) { break _loop66; } else {throw new NoViableAltException(LT(1), getFilename());}
                }

                _cnt66++;
            } while (true);
            }
            match(SEMICOLON);
            break;
        }
        case PLAN_BODY_WAIT:
        {
            ct=wait_construct(currentPlan, interpreter);
            break;
        }
        case PLAN_BODY_WHEN:
        {
            match(PLAN_BODY_WHEN);
            match(COLON);
            a=action(currentPlan, interpreter);
            s=plan_branch(currentPlan, interpreter);
            match(SEMICOLON);
            ct = new PlanWhenConstruct(a, s);
            break;
        }
        case PLAN_BODY_WHILE:
        {
            match(PLAN_BODY_WHILE);
            match(COLON);
            a=action(currentPlan, interpreter);
            s=plan_branch(currentPlan, interpreter);
            match(SEMICOLON);
            ct = new PlanWhileConstruct(a, s);
            break;
        }
        case PLAN_BODY_DO:
        {
            match(PLAN_BODY_DO);
            s=plan_branch(currentPlan, interpreter);
            match(PLAN_BODY_WHILE);
            match(COLON);
            a=action(currentPlan, interpreter);
            match(SEMICOLON);
            ct = new PlanDoConstruct(a, s);
            break;
        }
        case PLAN_BODY_ATOMIC:
        {
            match(PLAN_BODY_ATOMIC);
            s=plan_branch(currentPlan, interpreter);
            match(SEMICOLON);
            ct = new PlanAtomicConstruct(s);
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return ct;
    }

/** Action */
    public final Action  action(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Action returna;


        {
        switch ( LA(1)) {
        case ASSERT:
        case RETRACT:
        case RETRIEVE:
        case EXECUTE:
        case LOAD:
        case RETRIEVEALL:
        case NEXTFACT:
        case TEST:
        case UPDATE:
        {
            returna=exec_action(currentPlan, interpreter);
            break;
        }
        case FACT:
        case ASSIGN:
        case SUCCEED:
        case FAIL:
        case POST:
        case UNPOST:
        {
            returna=misc_action(currentPlan, interpreter);
            break;
        }
        case ACHIEVE:
        case PERFORM:
        case MAINTAIN:
        case QUERY:
        {
            returna=goal_action(currentPlan, interpreter);
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returna;
    }

    public final PlanConstruct  wait_construct(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        PlanConstruct c;


        Action a = null;
        Relation rel = null;


        {
        if ((LA(1)==PLAN_BODY_WAIT) && (LA(2)==COLON)) {
            match(PLAN_BODY_WAIT);
            match(COLON);
            a=action(currentPlan, interpreter);
            match(SEMICOLON);

            c = new PlanWaitConstruct(a);

        }
        else if ((LA(1)==PLAN_BODY_WAIT) && (LA(2)==IDENTIFIER)) {
            match(PLAN_BODY_WAIT);
            rel=relation(currentPlan, interpreter);
            match(SEMICOLON);

            c = new PlanWaitConstruct(rel);

        }
        else {
            throw new NoViableAltException(LT(1), getFilename());
        }

        }
        return c;
    }

    public final Condition  condition(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Condition returnc;


        Expression e;
        ExpList el;
        String id;


        {
        switch ( LA(1)) {
        case LEFT_PAREN:
        case INTEGER:
        case FLOAT:
        case VARIABLE:
        case CLASS_IDENTIFIER:
        case STRING:
        {
            e=expression(currentPlan, interpreter);
            match(SEMICOLON);

            returnc = new ExpressionCondition(e);

            break;
        }
        case FACT:
        {
            match(FACT);
            id=identifier();
            el=explist(currentPlan, interpreter);
            match(SEMICOLON);

            returnc = new FactCondition(new Relation(id, el), interpreter.getWorldModel());

            break;
        }
        case RETRIEVE:
        {
            match(RETRIEVE);
            id=identifier();
            el=explist(currentPlan, interpreter);
            match(SEMICOLON);

            returnc = new RetrieveCondition(new Relation(id, el), interpreter.getWorldModel());

            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returnc;
    }

/** Object-oriented form of EXECUTE that invokes static functions.
 * (i.e., doesn't require an object reference)
 */
    public final Action  exec_action(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Action returna;


        Variable var = null;
        String fn = null;
        String id = null;
        String id1 = null;
        String id2 = null;
        String cls = null;
        Expression e = null;
        ExpList el = null;
        ExpList el1 = null;
        ExpList el2 = null;


        {
        switch ( LA(1)) {
        case EXECUTE:
        {
            match(EXECUTE);
            {
            switch ( LA(1)) {
            case CLASS_IDENTIFIER:
            {
                {
                cls=classidentifier();
                {
                switch ( LA(1)) {
                case LEFT_BRACKET:
                {
                    match(LEFT_BRACKET);
                    var=variable(currentPlan);
                    match(RIGHT_BRACKET);
                    break;
                }
                case LEFT_BRACE:
                case SEMICOLON:
                case LEFT_PAREN:
                case INTEGER:
                case FLOAT:
                case VARIABLE:
                case CLASS_IDENTIFIER:
                case STRING:
                {
                    break;
                }
                default:
                {
                    throw new NoViableAltException(LT(1), getFilename());
                }
                }
                }
                el=explist(currentPlan, interpreter);
                }
                break;
            }
            case IDENTIFIER:
            {
                {
                fn=identifier();
                {
                switch ( LA(1)) {
                case LEFT_BRACKET:
                {
                    match(LEFT_BRACKET);
                    var=variable(currentPlan);
                    match(RIGHT_BRACKET);
                    break;
                }
                case LEFT_BRACE:
                case SEMICOLON:
                case LEFT_PAREN:
                case INTEGER:
                case FLOAT:
                case VARIABLE:
                case CLASS_IDENTIFIER:
                case STRING:
                {
                    break;
                }
                default:
                {
                    throw new NoViableAltException(LT(1), getFilename());
                }
                }
                }
                el=explist(currentPlan, interpreter);
                }
                break;
            }
            default:
            {
                throw new NoViableAltException(LT(1), getFilename());
            }
            }
            }

            if (cls != null || var != null) {
            // Break down the class identifier into the class path and the
            // function.
            String fullIdentifier;
            if (cls != null) {
            fullIdentifier = cls;
            } else {
            fullIdentifier = fn;
            }
            //    log.info("fullIdentifier = " + fullIdentifier);
            int lastDotIndex = fullIdentifier.lastIndexOf(".");
            //    log.info("lastDotIndex = " + lastDotIndex);
            String funcName = fullIdentifier.substring(lastDotIndex+1);
            //    log.info("funcName = " + funcName);
            String className;
            if (lastDotIndex != -1) {
            className = fullIdentifier.substring(0, lastDotIndex);
            } else {
            className = new String("");
            }
            //    log.info("className = " + className);
            //    log.info("arg list = " + el + ", #args = " + el.getCount());
            if (var != null) {
            returna = new ObjectAction(className, funcName, var, el);
            returna.setTrace(this.getFilename(), LT(1).getLine());
            } else {
            returna = new ObjectAction(className, funcName, el);
            returna.setTrace(this.getFilename(), LT(1).getLine());
            }
            } else {
            returna = new SimpleAction(fn, el, interpreter);
            returna.setTrace(this.getFilename(), LT(1).getLine());
            }

            break;
        }
        case LOAD:
        {
            match(LOAD);
            el=explist(currentPlan, interpreter);

            returna = new LoadAction(el, interpreter);
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case RETRIEVE:
        {
            match(RETRIEVE);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new RetrieveAction(new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case RETRIEVEALL:
        {
            match(RETRIEVEALL);
            var=variable(currentPlan);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new RetrieveAllAction(var, new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case NEXTFACT:
        {
            match(NEXTFACT);
            var=variable(currentPlan);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new NextFactAction(var, new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case TEST:
        {
            match(TEST);
            e=expression(currentPlan, interpreter);

            returna = new TestAction(e);
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case ASSERT:
        {
            match(ASSERT);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new AssertAction(new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case RETRACT:
        {
            match(RETRACT);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new RetractAction(new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case UPDATE:
        {
            match(UPDATE);
            match(LEFT_PAREN);
            id1=identifier();
            el1=explist(currentPlan, interpreter);
            match(RIGHT_PAREN);
            match(LEFT_PAREN);
            id2=identifier();
            el2=explist(currentPlan, interpreter);
            match(RIGHT_PAREN);

            returna = new UpdateAction(new Relation(id1, el1),
            new Relation(id2, el2), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returna;
    }

    public final Action  misc_action(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Action returna;


        String id;
        Expression e;
        Variable var;
        ExpList el;
        GoalAction ga;


        {
        switch ( LA(1)) {
        case ASSIGN:
        {
            match(ASSIGN);
            var=variable(currentPlan);
            e=expression(currentPlan, interpreter);

            returna = new AssignAction(var, e);
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case FACT:
        {
            match(FACT);
            id=identifier();
            el=explist(currentPlan, interpreter);

            returna = new FactAction(new Relation(id, el), interpreter.getWorldModel());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case SUCCEED:
        {
            match(SUCCEED);

            returna = new SucceedAction();
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case FAIL:
        {
            match(FAIL);

            returna = new FailAction();
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case POST:
        {
            match(POST);
            ga=goal_action(currentPlan, interpreter);

            returna = new PostAction(ga, interpreter.getIntentionStructure());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        case UNPOST:
        {
            match(UNPOST);
            ga=goal_action(currentPlan, interpreter);

            returna = new UnpostAction(ga, interpreter.getIntentionStructure());
            returna.setTrace(this.getFilename(), LT(1).getLine());

            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returna;
    }

    public final String  classidentifier() throws RecognitionException, TokenStreamException {
        String returnclsid;

        Token  clsid = null;

        clsid = LT(1);
        match(CLASS_IDENTIFIER);
        returnclsid = clsid.getText();
        return returnclsid;
    }

    public final Variable  variable(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {
        Variable returnvar;

        Token  v = null;

        v = LT(1);
        match(VARIABLE);
        returnvar = currentPlan.getSymbolMap().getVariable(v.getText());
        return returnvar;
    }

    public final GoalAction  goal_action_basic(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        GoalAction returna;


        returna = null;
        Relation rel;


        {
        switch ( LA(1)) {
        case ACHIEVE:
        {
            match(ACHIEVE);
            rel=relation(currentPlan, interpreter);

            returna = new AchieveGoalAction(rel, (Expression)null, (ExpList)null, (ExpList)null);

            break;
        }
        case PERFORM:
        {
            match(PERFORM);
            rel=relation(currentPlan, interpreter);

            returna = new PerformGoalAction(rel, (Expression)null, (ExpList)null, (ExpList)null);

            break;
        }
        case MAINTAIN:
        {
            match(MAINTAIN);
            rel=relation(currentPlan, interpreter);

            returna = new MaintainGoalAction(rel, (Expression)null);

            break;
        }
        case QUERY:
        {
            match(QUERY);
            rel=relation(currentPlan, interpreter);

            returna = new QueryGoalAction(rel, (Expression)null);

            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returna;
    }

    public final Value  value(
        Plan currentPlan
    ) throws RecognitionException, TokenStreamException {
        Value returnval;

        Token  val1 = null;
        Token  val2 = null;

        returnval = null;
        Variable var = null;
        String cls = null;
        String s;


        {
        switch ( LA(1)) {
        case INTEGER:
        {
            val1 = LT(1);
            match(INTEGER);
            returnval = Value.newValue(Integer.valueOf(val1.getText()).intValue());
            break;
        }
        case FLOAT:
        {
            val2 = LT(1);
            match(FLOAT);
            returnval = Value.newValue(Double.valueOf(val2.getText()).doubleValue());
            break;
        }
        case STRING:
        {
            s=string();
            returnval = Value.newValue(s);
            break;
        }
        case CLASS_IDENTIFIER:
        {
            cls=classidentifier();
            {
            switch ( LA(1)) {
            case LEFT_BRACKET:
            {
                match(LEFT_BRACKET);
                var=variable(currentPlan);
                match(RIGHT_BRACKET);
                break;
            }
            case LEFT_BRACE:
            case SEMICOLON:
            case LEFT_PAREN:
            case RIGHT_PAREN:
            case KEYWORD_UTILITY:
            case KEYWORD_BY:
            case KEYWORD_NOT_BY:
            case INTEGER:
            case FLOAT:
            case VARIABLE:
            case CLASS_IDENTIFIER:
            case STRING:
            {
                break;
            }
            default:
            {
                throw new NoViableAltException(LT(1), getFilename());
            }
            }
            }

            if (cls != null) {
            String    fullIdentifier;
            int    lastDotIndex;
            String    memberName;
            String    className;
            Class    c = null;
            Field    f = null;
            Object  o = null;
            Object    memVal = null;
            int    m;
            fullIdentifier = cls;
            lastDotIndex = fullIdentifier.lastIndexOf(".");
            memberName = fullIdentifier.substring(lastDotIndex+1);
            //log.info("fullIdentifier = " + fullIdentifier);
            //log.info("lastDotIndex = " + lastDotIndex);
            //log.info("memberName = " + memberName);
            if (lastDotIndex != -1) {
            className = fullIdentifier.substring(0, lastDotIndex);
            } else {
            className = new String("");
            }
            //log.info("className = " + className);
            try {
            c = Class.forName(className);
            //log.info("c = " + c);
            } catch (Exception e) {
            log.severe("Encountered exception " + e +
            " trying to get class " + c);
            e.printStackTrace();
            }
            try {
            f = c.getDeclaredField(memberName);
            //log.info("f = " + f);
            } catch (Exception e) {
            log.severe("Encountered exception " + e +
            " trying to get field " + memberName);
            e.printStackTrace();
            }
            // check modifiers to see if member is static
            // if static, then don't create an object instance
            m = f.getModifiers();
            if (var == null || Modifier.isStatic(m)) {
            //log.info("Member is static!\n");
            try {
            memVal = f.get(o);
            //log.info("memVal = " + memVal);
            returnval = Value.newValue(memVal);
            } catch (Exception e) {
            log.severe("Encountered exception " + e +
            " trying to create a new object");
            e.printStackTrace();
            }
            } else {
            //log.info("Member is not static!\n");
            try {
            o = c.newInstance();
            //log.info("o = " + o);
            memVal = f.get(o);
            //log.info("memVal = " + memVal);
            returnval = Value.newValue(memVal);
            } catch (Exception e) {
            log.severe("Encountered exception " + e +
            " trying to create a new object");
            e.printStackTrace();
            }
            }
            log.severe("ERROR, ERROR, ERROR\n");
            returnval = Value.newValue("hi");
            }

            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        return returnval;
    }

    public final FunctionCall  funcall(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        FunctionCall returnval;

        Token  fn1 = null;

        returnval = null;
        ExpList el = null;
        Variable var = null;
        String cls = null;
        String fn = null;
        String className;


        {
        match(LEFT_PAREN);
        {
        switch ( LA(1)) {
        case SPECIAL_FUNCTION_NAME:
        {
            fn1 = LT(1);
            match(SPECIAL_FUNCTION_NAME);
            fn = fn1.getText();
            break;
        }
        case CLASS_IDENTIFIER:
        {
            cls=classidentifier();
            {
            switch ( LA(1)) {
            case LEFT_BRACKET:
            {
                match(LEFT_BRACKET);
                var=variable(currentPlan);
                match(RIGHT_BRACKET);
                break;
            }
            case LEFT_PAREN:
            case RIGHT_PAREN:
            case INTEGER:
            case FLOAT:
            case VARIABLE:
            case CLASS_IDENTIFIER:
            case STRING:
            {
                break;
            }
            default:
            {
                throw new NoViableAltException(LT(1), getFilename());
            }
            }
            }
            break;
        }
        case IDENTIFIER:
        {
            fn=identifier();
            {
            if ((LA(1)==CLASS_IDENTIFIER) && (_tokenSet_3.member(LA(2))) && (_tokenSet_4.member(LA(3))) && (_tokenSet_5.member(LA(4)))) {
                cls=classidentifier();
            }
            else if ((_tokenSet_3.member(LA(1))) && (_tokenSet_4.member(LA(2))) && (_tokenSet_5.member(LA(3))) && (_tokenSet_6.member(LA(4)))) {
            }
            else {
                throw new NoViableAltException(LT(1), getFilename());
            }

            }
            break;
        }
        default:
        {
            throw new NoViableAltException(LT(1), getFilename());
        }
        }
        }
        el=explist(currentPlan, interpreter);
        match(RIGHT_PAREN);
        }

        //log.info("Expression list is " + el.getCount() +
        //               " elements long.");
        if (cls != null || var != null) {
        // Break down the class identifier into the class path and the
        // function.
        String fullIdentifier;
        int lastDotIndex;
        String funcName;
        if (cls != null && fn == null) {
        fullIdentifier = cls;
        } else {
        fullIdentifier = fn;
        }
        //log.info("fullIdentifier = " + fullIdentifier);
        lastDotIndex = fullIdentifier.lastIndexOf(".");
        //log.info("lastDotIndex = " + lastDotIndex);
        if (fn != null) {
        funcName = fn;
        } else {
        funcName = fullIdentifier.substring(lastDotIndex+1);
        }
        //log.info("funcName = " + funcName);
        if (lastDotIndex != -1) {
        className = fullIdentifier.substring(0, lastDotIndex);
        } else if (fn != null && cls != null) {
        className = new String("");
        el.addFirst(Value.newValue(cls));
        } else {
        className = new String("");
        }
        //log.info("className = " + className);
        //log.info("arg list = " + el + ", #args = " + el.getCount());
        if (var != null) {
        //log.info("Creating object-instance method function call\n");
        returnval = new FunctionCall(className, funcName, var, el, interpreter);
        } else {
        //log.info("Creating static method function call\n");
        returnval = new FunctionCall(className, funcName, el, interpreter);
        }
        } else {
        //log.info("Creating basic function call for " + fn.getText() + "\n");
        returnval = new FunctionCall(fn, el, interpreter);
        }
        if (returnval == null) {
        log.warning("Creating null function call\n");
        }

        return returnval;
    }

    public final Predicate  predicate(
        Plan currentPlan, Interpreter interpreter
    ) throws RecognitionException, TokenStreamException {
        Predicate returnp;


        String id;
        ExpList el;
        Relation r;


        {
        if ((LA(1)==LEFT_PAREN) && (LA(2)==FACT)) {
            match(LEFT_PAREN);
            match(FACT);
            id=identifier();
            el=explist(currentPlan, interpreter);
            match(RIGHT_PAREN);

            r = new Relation(id, el);
            returnp = new PredicateFact(id, r, interpreter.getWorldModel());

        }
        else if ((LA(1)==LEFT_PAREN) && (LA(2)==RETRIEVE)) {
            match(LEFT_PAREN);
            match(RETRIEVE);
            id=identifier();
            el=explist(currentPlan, interpreter);
            match(RIGHT_PAREN);

            r = new Relation(id, el);
            returnp = new PredicateRetrieve(id, r, interpreter.getWorldModel());

        }
        else if ((LA(1)==LEFT_PAREN) && (LA(2)==ACHIEVE)) {
            match(LEFT_PAREN);
            match(ACHIEVE);
            id=identifier();
            el=explist(currentPlan, interpreter);
            match(RIGHT_PAREN);

            r = new Relation(id, el);
            returnp = new PredicateAchieve(id, r, interpreter.getIntentionStructure());

        }
        else {
            throw new NoViableAltException(LT(1), getFilename());
        }

        }
        return returnp;
    }


    public static final String[] _tokenNames = {
        "<0>",
        "EOF",
        "<2>",
        "NULL_TREE_LOOKAHEAD",
        "\"GOALS\"",
        "COLON",
        "\"FACTS\"",
        "\"OBSERVER\"",
        "LEFT_BRACE",
        "RIGHT_BRACE",
        "\"PLAN\"",
        "SEMICOLON",
        "\"FACT\"",
        "\"NAME\"",
        "\"DOCUMENTATION\"",
        "\"ATTRIBUTES\"",
        "\"GOAL\"",
        "\"CONCLUDE\"",
        "\"PERCEIVE\"",
        "\"ASSERT\"",
        "\"RETRACT\"",
        "\"CONTEXT\"",
        "\"PRECONDITION\"",
        "\"UTILITY\"",
        "\"EFFECTS\"",
        "\"FAILURE\"",
        "\"BODY\"",
        "\"AND\"",
        "\"OR\"",
        "\"PARALLEL\"",
        "\"DO_ALL\"",
        "\"DO_ANY\"",
        "\"WHEN\"",
        "\"WHILE\"",
        "\"DO\"",
        "\"ATOMIC\"",
        "\"WAIT\"",
        "\"RETRIEVE\"",
        "\"EXECUTE\"",
        "LEFT_BRACKET",
        "RIGHT_BRACKET",
        "\"LOAD\"",
        "\"RETRIEVEALL\"",
        "\"NEXTFACT\"",
        "\"TEST\"",
        "\"UPDATE\"",
        "LEFT_PAREN",
        "RIGHT_PAREN",
        "\"ASSIGN\"",
        "\"SUCCEED\"",
        "\"FAIL\"",
        "\"POST\"",
        "\"UNPOST\"",
        "KEYWORD_UTILITY",
        "KEYWORD_BY",
        "KEYWORD_NOT_BY",
        "\"ACHIEVE\"",
        "\"PERFORM\"",
        "\"MAINTAIN\"",
        "\"QUERY\"",
        "INTEGER",
        "FLOAT",
        "VARIABLE",
        "IDENTIFIER",
        "CLASS_IDENTIFIER",
        "STRING",
        "SPECIAL_FUNCTION_NAME",
        "\"PARSE\"",
        "WHITESPACE",
        "DELIMIT_CHAR",
        "SINGLE_LINE_COMMENT",
        "MULTI_LINE_COMMENT",
        "ESCAPE",
        "ID_START_LETTER",
        "LETTER",
        "KEYWORD_TEST",
        "DIGIT",
        "EXPONENT"
    };

    private static final long[] mk_tokenSet_0() {
        long[] data = { 1089658354191044608L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
    private static final long[] mk_tokenSet_1() {
        long[] data = { 8070520900992106496L, 3L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1());
    private static final long[] mk_tokenSet_2() {
        long[] data = { 8070521038431064064L, 3L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_2 = new BitSet(mk_tokenSet_2());
    private static final long[] mk_tokenSet_3() {
        long[] data = { 8070661638480461824L, 3L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_3 = new BitSet(mk_tokenSet_3());
    private static final long[] mk_tokenSet_4() {
        long[] data = { -1017601722358425344L, 7L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_4 = new BitSet(mk_tokenSet_4());
    private static final long[] mk_tokenSet_5() {
        long[] data = { -1099512143934L, 7L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_5 = new BitSet(mk_tokenSet_5());
    private static final long[] mk_tokenSet_6() {
        long[] data = { -516126L, 7L, 0L, 0L};
        return data;
    }
    public static final BitSet _tokenSet_6 = new BitSet(mk_tokenSet_6());

    }
