/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. src/java/ognl/ognl.jj */
/*@egen*///--------------------------------------------------------------------------
//	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
//  All rights reserved.
//
//	Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//	Redistributions of source code must retain the above copyright notice,
//  this list of conditions and the following disclaimer.
//	Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the distribution.
//	Neither the name of the Drew Davidson nor the names of its contributors
//  may be used to endorse or promote products derived from this software
//  without specific prior written permission.
//
//	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
//  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
//  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//  DAMAGE.
//--------------------------------------------------------------------------

/*
 * This file defines the syntax of OGNL, the Object-Graph Navigation Language.  This
 * language was devised by Drew Davidson, who called it Key-Value Coding Language.  Luke
 * Blanshard then made up the new name and reimplemented it using ANTLR, refining and
 * polishing the language a bit on the way.  Drew maintained the system for a couple of
 * years; then Luke converted the ANTLR grammar to JavaCC, to eliminate the run-time
 * dependency on ANTLR.
 *
 * See package.html for a description of the language.
 */

options {
      // Parser options
    LOOKAHEAD           = 1;
    STATIC              = false;
    JAVA_UNICODE_ESCAPE = true;
    UNICODE_INPUT       = true;

                     
                             
                             
}

PARSER_BEGIN(OgnlParser)

package ognl;

import java.math.*;

/**
 * OgnlParser is a JavaCC parser class; it translates OGNL expressions into abstract
 * syntax trees (ASTs) that can then be interpreted by the getValue and setValue methods.
 */
public class OgnlParser/*@bgen(jjtree)*/implements OgnlParserTreeConstants/*@egen*/
{/*@bgen(jjtree)*/
  protected JJTOgnlParserState jjtree = new JJTOgnlParserState();

/*@egen*/
}

PARSER_END(OgnlParser)




/**
 * This is the top-level construct of OGNL.
 */
Node topLevelExpression() : {}
{
    expression() <EOF> { return jjtree.rootNode(); }
}

// sequence (level 14)
void expression() : {}
{
    assignmentExpression() ( ","/*@bgen(jjtree) #Sequence( 2) */
                                 {
                                   ASTSequence jjtn001 = new ASTSequence(JJTSEQUENCE);
                                   boolean jjtc001 = true;
                                   jjtree.openNodeScope(jjtn001);
                                 }
                                 try {
/*@egen*/ assignmentExpression()/*@bgen(jjtree)*/
                                 } catch (Throwable jjte001) {
                                   if (jjtc001) {
                                     jjtree.clearNodeScope(jjtn001);
                                     jjtc001 = false;
                                   } else {
                                     jjtree.popNode();
                                   }
                                   if (jjte001 instanceof RuntimeException) {
                                     throw (RuntimeException)jjte001;
                                   }
                                   if (jjte001 instanceof ParseException) {
                                     throw (ParseException)jjte001;
                                   }
                                   throw (Error)jjte001;
                                 } finally {
                                   if (jjtc001) {
                                     jjtree.closeNodeScope(jjtn001,  2);
                                   }
                                 }
/*@egen*/              )*
}

// assignment expression (level 13)
void assignmentExpression() : {}
{
    conditionalTestExpression() [ "="/*@bgen(jjtree) #Assign( 2) */
                                      {
                                        ASTAssign jjtn001 = new ASTAssign(JJTASSIGN);
                                        boolean jjtc001 = true;
                                        jjtree.openNodeScope(jjtn001);
                                      }
                                      try {
/*@egen*/ assignmentExpression()/*@bgen(jjtree)*/
                                      } catch (Throwable jjte001) {
                                        if (jjtc001) {
                                          jjtree.clearNodeScope(jjtn001);
                                          jjtc001 = false;
                                        } else {
                                          jjtree.popNode();
                                        }
                                        if (jjte001 instanceof RuntimeException) {
                                          throw (RuntimeException)jjte001;
                                        }
                                        if (jjte001 instanceof ParseException) {
                                          throw (ParseException)jjte001;
                                        }
                                        throw (Error)jjte001;
                                      } finally {
                                        if (jjtc001) {
                                          jjtree.closeNodeScope(jjtn001,  2);
                                        }
                                      }
/*@egen*/            ]
}

// conditional test (level 12)
void conditionalTestExpression() : {}
{
    logicalOrExpression()
        [ "?" conditionalTestExpression() ":"/*@bgen(jjtree) #Test( 3) */
                                              {
                                                ASTTest jjtn001 = new ASTTest(JJTTEST);
                                                boolean jjtc001 = true;
                                                jjtree.openNodeScope(jjtn001);
                                              }
                                              try {
/*@egen*/ conditionalTestExpression()/*@bgen(jjtree)*/
                                              } catch (Throwable jjte001) {
                                                if (jjtc001) {
                                                  jjtree.clearNodeScope(jjtn001);
                                                  jjtc001 = false;
                                                } else {
                                                  jjtree.popNode();
                                                }
                                                if (jjte001 instanceof RuntimeException) {
                                                  throw (RuntimeException)jjte001;
                                                }
                                                if (jjte001 instanceof ParseException) {
                                                  throw (ParseException)jjte001;
                                                }
                                                throw (Error)jjte001;
                                              } finally {
                                                if (jjtc001) {
                                                  jjtree.closeNodeScope(jjtn001,  3);
                                                }
                                              }
/*@egen*/          ]
}

// logical or (||)  (level 11)
void logicalOrExpression() : {}
{
    logicalAndExpression() (("||" | "or")/*@bgen(jjtree) #Or( 2) */
                                          {
                                            ASTOr jjtn001 = new ASTOr(JJTOR);
                                            boolean jjtc001 = true;
                                            jjtree.openNodeScope(jjtn001);
                                          }
                                          try {
/*@egen*/ logicalAndExpression()/*@bgen(jjtree)*/
                                          } catch (Throwable jjte001) {
                                            if (jjtc001) {
                                              jjtree.clearNodeScope(jjtn001);
                                              jjtc001 = false;
                                            } else {
                                              jjtree.popNode();
                                            }
                                            if (jjte001 instanceof RuntimeException) {
                                              throw (RuntimeException)jjte001;
                                            }
                                            if (jjte001 instanceof ParseException) {
                                              throw (ParseException)jjte001;
                                            }
                                            throw (Error)jjte001;
                                          } finally {
                                            if (jjtc001) {
                                              jjtree.closeNodeScope(jjtn001,  2);
                                            }
                                          }
/*@egen*/        )*
}


// logical and (&&)  (level 10)
void logicalAndExpression() : {}
{
    inclusiveOrExpression() (("&&" | "and")/*@bgen(jjtree) #And( 2) */
                                            {
                                              ASTAnd jjtn001 = new ASTAnd(JJTAND);
                                              boolean jjtc001 = true;
                                              jjtree.openNodeScope(jjtn001);
                                            }
                                            try {
/*@egen*/ inclusiveOrExpression()/*@bgen(jjtree)*/
                                            } catch (Throwable jjte001) {
                                              if (jjtc001) {
                                                jjtree.clearNodeScope(jjtn001);
                                                jjtc001 = false;
                                              } else {
                                                jjtree.popNode();
                                              }
                                              if (jjte001 instanceof RuntimeException) {
                                                throw (RuntimeException)jjte001;
                                              }
                                              if (jjte001 instanceof ParseException) {
                                                throw (ParseException)jjte001;
                                              }
                                              throw (Error)jjte001;
                                            } finally {
                                              if (jjtc001) {
                                                jjtree.closeNodeScope(jjtn001,  2);
                                              }
                                            }
/*@egen*/         )*
}


// bitwise or non-short-circuiting or (|)  (level 9)
void inclusiveOrExpression() : {}
{
    exclusiveOrExpression() (("|" | "bor")/*@bgen(jjtree) #BitOr( 2) */
                                           {
                                             ASTBitOr jjtn001 = new ASTBitOr(JJTBITOR);
                                             boolean jjtc001 = true;
                                             jjtree.openNodeScope(jjtn001);
                                           }
                                           try {
/*@egen*/ exclusiveOrExpression()/*@bgen(jjtree)*/
                                           } catch (Throwable jjte001) {
                                             if (jjtc001) {
                                               jjtree.clearNodeScope(jjtn001);
                                               jjtc001 = false;
                                             } else {
                                               jjtree.popNode();
                                             }
                                             if (jjte001 instanceof RuntimeException) {
                                               throw (RuntimeException)jjte001;
                                             }
                                             if (jjte001 instanceof ParseException) {
                                               throw (ParseException)jjte001;
                                             }
                                             throw (Error)jjte001;
                                           } finally {
                                             if (jjtc001) {
                                               jjtree.closeNodeScope(jjtn001,  2);
                                             }
                                           }
/*@egen*/           )*
}


// exclusive or (^)  (level 8)
void exclusiveOrExpression() : {}
{
    andExpression() (("^" | "xor")/*@bgen(jjtree) #Xor( 2) */
                                   {
                                     ASTXor jjtn001 = new ASTXor(JJTXOR);
                                     boolean jjtc001 = true;
                                     jjtree.openNodeScope(jjtn001);
                                   }
                                   try {
/*@egen*/ andExpression()/*@bgen(jjtree)*/
                                   } catch (Throwable jjte001) {
                                     if (jjtc001) {
                                       jjtree.clearNodeScope(jjtn001);
                                       jjtc001 = false;
                                     } else {
                                       jjtree.popNode();
                                     }
                                     if (jjte001 instanceof RuntimeException) {
                                       throw (RuntimeException)jjte001;
                                     }
                                     if (jjte001 instanceof ParseException) {
                                       throw (ParseException)jjte001;
                                     }
                                     throw (Error)jjte001;
                                   } finally {
                                     if (jjtc001) {
                                       jjtree.closeNodeScope(jjtn001,  2);
                                     }
                                   }
/*@egen*/         )*
}


// bitwise or non-short-circuiting and (&)  (level 7)
void andExpression() : {}
{
    equalityExpression() (("&" | "band")/*@bgen(jjtree) #BitAnd( 2) */
                                         {
                                           ASTBitAnd jjtn001 = new ASTBitAnd(JJTBITAND);
                                           boolean jjtc001 = true;
                                           jjtree.openNodeScope(jjtn001);
                                         }
                                         try {
/*@egen*/ equalityExpression()/*@bgen(jjtree)*/
                                         } catch (Throwable jjte001) {
                                           if (jjtc001) {
                                             jjtree.clearNodeScope(jjtn001);
                                             jjtc001 = false;
                                           } else {
                                             jjtree.popNode();
                                           }
                                           if (jjte001 instanceof RuntimeException) {
                                             throw (RuntimeException)jjte001;
                                           }
                                           if (jjte001 instanceof ParseException) {
                                             throw (ParseException)jjte001;
                                           }
                                           throw (Error)jjte001;
                                         } finally {
                                           if (jjtc001) {
                                             jjtree.closeNodeScope(jjtn001,  2);
                                           }
                                         }
/*@egen*/            )*
}


// equality/inequality (==/!=) (level 6)
void equalityExpression() : {}
{
    relationalExpression()
    (
        ("==" | "eq")/*@bgen(jjtree) #Eq( 2) */
                      {
                        ASTEq jjtn001 = new ASTEq(JJTEQ);
                        boolean jjtc001 = true;
                        jjtree.openNodeScope(jjtn001);
                      }
                      try {
/*@egen*/ relationalExpression()/*@bgen(jjtree)*/
                      } catch (Throwable jjte001) {
                        if (jjtc001) {
                          jjtree.clearNodeScope(jjtn001);
                          jjtc001 = false;
                        } else {
                          jjtree.popNode();
                        }
                        if (jjte001 instanceof RuntimeException) {
                          throw (RuntimeException)jjte001;
                        }
                        if (jjte001 instanceof ParseException) {
                          throw (ParseException)jjte001;
                        }
                        throw (Error)jjte001;
                      } finally {
                        if (jjtc001) {
                          jjtree.closeNodeScope(jjtn001,  2);
                        }
                      }
/*@egen*/       
     |
        ("!=" | "neq")/*@bgen(jjtree) #NotEq( 2) */
                       {
                         ASTNotEq jjtn002 = new ASTNotEq(JJTNOTEQ);
                         boolean jjtc002 = true;
                         jjtree.openNodeScope(jjtn002);
                       }
                       try {
/*@egen*/ relationalExpression()/*@bgen(jjtree)*/
                       } catch (Throwable jjte002) {
                         if (jjtc002) {
                           jjtree.clearNodeScope(jjtn002);
                           jjtc002 = false;
                         } else {
                           jjtree.popNode();
                         }
                         if (jjte002 instanceof RuntimeException) {
                           throw (RuntimeException)jjte002;
                         }
                         if (jjte002 instanceof ParseException) {
                           throw (ParseException)jjte002;
                         }
                         throw (Error)jjte002;
                       } finally {
                         if (jjtc002) {
                           jjtree.closeNodeScope(jjtn002,  2);
                         }
                       }
/*@egen*/          
    )*
}


// boolean relational expressions (level 5)
void relationalExpression() : {}
{
    shiftExpression()
    (
        ("<" | "lt")/*@bgen(jjtree) #Less( 2) */
                     {
                       ASTLess jjtn001 = new ASTLess(JJTLESS);
                       boolean jjtc001 = true;
                       jjtree.openNodeScope(jjtn001);
                     }
                     try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
                     } catch (Throwable jjte001) {
                       if (jjtc001) {
                         jjtree.clearNodeScope(jjtn001);
                         jjtc001 = false;
                       } else {
                         jjtree.popNode();
                       }
                       if (jjte001 instanceof RuntimeException) {
                         throw (RuntimeException)jjte001;
                       }
                       if (jjte001 instanceof ParseException) {
                         throw (ParseException)jjte001;
                       }
                       throw (Error)jjte001;
                     } finally {
                       if (jjtc001) {
                         jjtree.closeNodeScope(jjtn001,  2);
                       }
                     }
/*@egen*/         
     |
        (">" | "gt")/*@bgen(jjtree) #Greater( 2) */
                     {
                       ASTGreater jjtn002 = new ASTGreater(JJTGREATER);
                       boolean jjtc002 = true;
                       jjtree.openNodeScope(jjtn002);
                     }
                     try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
                     } catch (Throwable jjte002) {
                       if (jjtc002) {
                         jjtree.clearNodeScope(jjtn002);
                         jjtc002 = false;
                       } else {
                         jjtree.popNode();
                       }
                       if (jjte002 instanceof RuntimeException) {
                         throw (RuntimeException)jjte002;
                       }
                       if (jjte002 instanceof ParseException) {
                         throw (ParseException)jjte002;
                       }
                       throw (Error)jjte002;
                     } finally {
                       if (jjtc002) {
                         jjtree.closeNodeScope(jjtn002,  2);
                       }
                     }
/*@egen*/            
     |
        ("<=" | "lte")/*@bgen(jjtree) #LessEq( 2) */
                       {
                         ASTLessEq jjtn003 = new ASTLessEq(JJTLESSEQ);
                         boolean jjtc003 = true;
                         jjtree.openNodeScope(jjtn003);
                       }
                       try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
                       } catch (Throwable jjte003) {
                         if (jjtc003) {
                           jjtree.clearNodeScope(jjtn003);
                           jjtc003 = false;
                         } else {
                           jjtree.popNode();
                         }
                         if (jjte003 instanceof RuntimeException) {
                           throw (RuntimeException)jjte003;
                         }
                         if (jjte003 instanceof ParseException) {
                           throw (ParseException)jjte003;
                         }
                         throw (Error)jjte003;
                       } finally {
                         if (jjtc003) {
                           jjtree.closeNodeScope(jjtn003,  2);
                         }
                       }
/*@egen*/           
     |
        (">=" | "gte")/*@bgen(jjtree) #GreaterEq( 2) */
                       {
                         ASTGreaterEq jjtn004 = new ASTGreaterEq(JJTGREATEREQ);
                         boolean jjtc004 = true;
                         jjtree.openNodeScope(jjtn004);
                       }
                       try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
                       } catch (Throwable jjte004) {
                         if (jjtc004) {
                           jjtree.clearNodeScope(jjtn004);
                           jjtc004 = false;
                         } else {
                           jjtree.popNode();
                         }
                         if (jjte004 instanceof RuntimeException) {
                           throw (RuntimeException)jjte004;
                         }
                         if (jjte004 instanceof ParseException) {
                           throw (ParseException)jjte004;
                         }
                         throw (Error)jjte004;
                       } finally {
                         if (jjtc004) {
                           jjtree.closeNodeScope(jjtn004,  2);
                         }
                       }
/*@egen*/              
     |
        "in"/*@bgen(jjtree) #In( 2) */
             {
               ASTIn jjtn005 = new ASTIn(JJTIN);
               boolean jjtc005 = true;
               jjtree.openNodeScope(jjtn005);
             }
             try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
             } catch (Throwable jjte005) {
               if (jjtc005) {
                 jjtree.clearNodeScope(jjtn005);
                 jjtc005 = false;
               } else {
                 jjtree.popNode();
               }
               if (jjte005 instanceof RuntimeException) {
                 throw (RuntimeException)jjte005;
               }
               if (jjte005 instanceof ParseException) {
                 throw (ParseException)jjte005;
               }
               throw (Error)jjte005;
             } finally {
               if (jjtc005) {
                 jjtree.closeNodeScope(jjtn005,  2);
               }
             }
/*@egen*/       
     |
        "not" "in"/*@bgen(jjtree) #NotIn( 2) */
                   {
                     ASTNotIn jjtn006 = new ASTNotIn(JJTNOTIN);
                     boolean jjtc006 = true;
                     jjtree.openNodeScope(jjtn006);
                   }
                   try {
/*@egen*/ shiftExpression()/*@bgen(jjtree)*/
                   } catch (Throwable jjte006) {
                     if (jjtc006) {
                       jjtree.clearNodeScope(jjtn006);
                       jjtc006 = false;
                     } else {
                       jjtree.popNode();
                     }
                     if (jjte006 instanceof RuntimeException) {
                       throw (RuntimeException)jjte006;
                     }
                     if (jjte006 instanceof ParseException) {
                       throw (ParseException)jjte006;
                     }
                     throw (Error)jjte006;
                   } finally {
                     if (jjtc006) {
                       jjtree.closeNodeScope(jjtn006,  2);
                     }
                   }
/*@egen*/          
    )*
}


// bit shift expressions (level 4)
void shiftExpression() : {}
{
    additiveExpression()
    (
        ("<<" | "shl")/*@bgen(jjtree) #ShiftLeft( 2) */
                       {
                         ASTShiftLeft jjtn001 = new ASTShiftLeft(JJTSHIFTLEFT);
                         boolean jjtc001 = true;
                         jjtree.openNodeScope(jjtn001);
                       }
                       try {
/*@egen*/ additiveExpression()/*@bgen(jjtree)*/
                       } catch (Throwable jjte001) {
                         if (jjtc001) {
                           jjtree.clearNodeScope(jjtn001);
                           jjtc001 = false;
                         } else {
                           jjtree.popNode();
                         }
                         if (jjte001 instanceof RuntimeException) {
                           throw (RuntimeException)jjte001;
                         }
                         if (jjte001 instanceof ParseException) {
                           throw (ParseException)jjte001;
                         }
                         throw (Error)jjte001;
                       } finally {
                         if (jjtc001) {
                           jjtree.closeNodeScope(jjtn001,  2);
                         }
                       }
/*@egen*/              
     |
        (">>" | "shr")/*@bgen(jjtree) #ShiftRight( 2) */
                       {
                         ASTShiftRight jjtn002 = new ASTShiftRight(JJTSHIFTRIGHT);
                         boolean jjtc002 = true;
                         jjtree.openNodeScope(jjtn002);
                       }
                       try {
/*@egen*/ additiveExpression()/*@bgen(jjtree)*/
                       } catch (Throwable jjte002) {
                         if (jjtc002) {
                           jjtree.clearNodeScope(jjtn002);
                           jjtc002 = false;
                         } else {
                           jjtree.popNode();
                         }
                         if (jjte002 instanceof RuntimeException) {
                           throw (RuntimeException)jjte002;
                         }
                         if (jjte002 instanceof ParseException) {
                           throw (ParseException)jjte002;
                         }
                         throw (Error)jjte002;
                       } finally {
                         if (jjtc002) {
                           jjtree.closeNodeScope(jjtn002,  2);
                         }
                       }
/*@egen*/               
     |
        (">>>" | "ushr")/*@bgen(jjtree) #UnsignedShiftRight( 2) */
                         {
                           ASTUnsignedShiftRight jjtn003 = new ASTUnsignedShiftRight(JJTUNSIGNEDSHIFTRIGHT);
                           boolean jjtc003 = true;
                           jjtree.openNodeScope(jjtn003);
                         }
                         try {
/*@egen*/ additiveExpression()/*@bgen(jjtree)*/
                         } catch (Throwable jjte003) {
                           if (jjtc003) {
                             jjtree.clearNodeScope(jjtn003);
                             jjtc003 = false;
                           } else {
                             jjtree.popNode();
                           }
                           if (jjte003 instanceof RuntimeException) {
                             throw (RuntimeException)jjte003;
                           }
                           if (jjte003 instanceof ParseException) {
                             throw (ParseException)jjte003;
                           }
                           throw (Error)jjte003;
                         } finally {
                           if (jjtc003) {
                             jjtree.closeNodeScope(jjtn003,  2);
                           }
                         }
/*@egen*/                       
    )*
}


// binary addition/subtraction (level 3)
void additiveExpression() : {}
{
    multiplicativeExpression()
    (
        "+"/*@bgen(jjtree) #Add( 2) */
            {
              ASTAdd jjtn001 = new ASTAdd(JJTADD);
              boolean jjtc001 = true;
              jjtree.openNodeScope(jjtn001);
            }
            try {
/*@egen*/ multiplicativeExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte001) {
              if (jjtc001) {
                jjtree.clearNodeScope(jjtn001);
                jjtc001 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte001 instanceof RuntimeException) {
                throw (RuntimeException)jjte001;
              }
              if (jjte001 instanceof ParseException) {
                throw (ParseException)jjte001;
              }
              throw (Error)jjte001;
            } finally {
              if (jjtc001) {
                jjtree.closeNodeScope(jjtn001,  2);
              }
            }
/*@egen*/        
     |
        "-"/*@bgen(jjtree) #Subtract( 2) */
            {
              ASTSubtract jjtn002 = new ASTSubtract(JJTSUBTRACT);
              boolean jjtc002 = true;
              jjtree.openNodeScope(jjtn002);
            }
            try {
/*@egen*/ multiplicativeExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte002) {
              if (jjtc002) {
                jjtree.clearNodeScope(jjtn002);
                jjtc002 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte002 instanceof RuntimeException) {
                throw (RuntimeException)jjte002;
              }
              if (jjte002 instanceof ParseException) {
                throw (ParseException)jjte002;
              }
              throw (Error)jjte002;
            } finally {
              if (jjtc002) {
                jjtree.closeNodeScope(jjtn002,  2);
              }
            }
/*@egen*/             
    )*
}


// multiplication/division/remainder (level 2)
void multiplicativeExpression() : {}
{
    unaryExpression()
    (
        "*"/*@bgen(jjtree) #Multiply( 2) */
            {
              ASTMultiply jjtn001 = new ASTMultiply(JJTMULTIPLY);
              boolean jjtc001 = true;
              jjtree.openNodeScope(jjtn001);
            }
            try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte001) {
              if (jjtc001) {
                jjtree.clearNodeScope(jjtn001);
                jjtc001 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte001 instanceof RuntimeException) {
                throw (RuntimeException)jjte001;
              }
              if (jjte001 instanceof ParseException) {
                throw (ParseException)jjte001;
              }
              throw (Error)jjte001;
            } finally {
              if (jjtc001) {
                jjtree.closeNodeScope(jjtn001,  2);
              }
            }
/*@egen*/             
     |
        "/"/*@bgen(jjtree) #Divide( 2) */
            {
              ASTDivide jjtn002 = new ASTDivide(JJTDIVIDE);
              boolean jjtc002 = true;
              jjtree.openNodeScope(jjtn002);
            }
            try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte002) {
              if (jjtc002) {
                jjtree.clearNodeScope(jjtn002);
                jjtc002 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte002 instanceof RuntimeException) {
                throw (RuntimeException)jjte002;
              }
              if (jjte002 instanceof ParseException) {
                throw (ParseException)jjte002;
              }
              throw (Error)jjte002;
            } finally {
              if (jjtc002) {
                jjtree.closeNodeScope(jjtn002,  2);
              }
            }
/*@egen*/           
     |
        "%"/*@bgen(jjtree) #Remainder( 2) */
            {
              ASTRemainder jjtn003 = new ASTRemainder(JJTREMAINDER);
              boolean jjtc003 = true;
              jjtree.openNodeScope(jjtn003);
            }
            try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte003) {
              if (jjtc003) {
                jjtree.clearNodeScope(jjtn003);
                jjtc003 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte003 instanceof RuntimeException) {
                throw (RuntimeException)jjte003;
              }
              if (jjte003 instanceof ParseException) {
                throw (ParseException)jjte003;
              }
              throw (Error)jjte003;
            } finally {
              if (jjtc003) {
                jjtree.closeNodeScope(jjtn003,  2);
              }
            }
/*@egen*/              
    )*
}

// unary (level 1)
void unaryExpression() : {
    StringBuffer sb;
    Token t;
    ASTInstanceof ionode;
}
{
    (
        "-"/*@bgen(jjtree) #Negate( 1) */
            {
              ASTNegate jjtn001 = new ASTNegate(JJTNEGATE);
              boolean jjtc001 = true;
              jjtree.openNodeScope(jjtn001);
            }
            try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte001) {
              if (jjtc001) {
                jjtree.clearNodeScope(jjtn001);
                jjtc001 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte001 instanceof RuntimeException) {
                throw (RuntimeException)jjte001;
              }
              if (jjte001 instanceof ParseException) {
                throw (ParseException)jjte001;
              }
              throw (Error)jjte001;
            } finally {
              if (jjtc001) {
                jjtree.closeNodeScope(jjtn001,  1);
              }
            }
/*@egen*/           
     |
        "+" unaryExpression() // Just leave it there
     |
        "~"/*@bgen(jjtree) #BitNegate( 1) */
            {
              ASTBitNegate jjtn002 = new ASTBitNegate(JJTBITNEGATE);
              boolean jjtc002 = true;
              jjtree.openNodeScope(jjtn002);
            }
            try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
            } catch (Throwable jjte002) {
              if (jjtc002) {
                jjtree.clearNodeScope(jjtn002);
                jjtc002 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte002 instanceof RuntimeException) {
                throw (RuntimeException)jjte002;
              }
              if (jjte002 instanceof ParseException) {
                throw (ParseException)jjte002;
              }
              throw (Error)jjte002;
            } finally {
              if (jjtc002) {
                jjtree.closeNodeScope(jjtn002,  1);
              }
            }
/*@egen*/              
     |
        ("!" | "not")/*@bgen(jjtree) #Not( 1) */
                      {
                        ASTNot jjtn003 = new ASTNot(JJTNOT);
                        boolean jjtc003 = true;
                        jjtree.openNodeScope(jjtn003);
                      }
                      try {
/*@egen*/ unaryExpression()/*@bgen(jjtree)*/
                      } catch (Throwable jjte003) {
                        if (jjtc003) {
                          jjtree.clearNodeScope(jjtn003);
                          jjtc003 = false;
                        } else {
                          jjtree.popNode();
                        }
                        if (jjte003 instanceof RuntimeException) {
                          throw (RuntimeException)jjte003;
                        }
                        if (jjte003 instanceof ParseException) {
                          throw (ParseException)jjte003;
                        }
                        throw (Error)jjte003;
                      } finally {
                        if (jjtc003) {
                          jjtree.closeNodeScope(jjtn003,  1);
                        }
                      }
/*@egen*/        
     |
        navigationChain()
        [
            "instanceof"
            t = <IDENT>/*@bgen(jjtree) #Instanceof( 1) */
                         {
                           ASTInstanceof jjtn004 = new ASTInstanceof(JJTINSTANCEOF);
                           boolean jjtc004 = true;
                           jjtree.openNodeScope(jjtn004);
                         }
                         try {
/*@egen*//*@bgen(jjtree)*/
                         {
                           jjtree.closeNodeScope(jjtn004,  1);
                           jjtc004 = false;
                         }
/*@egen*/  { sb = new StringBuffer(t.image); ionode = jjtn004; }/*@bgen(jjtree)*/
                         } finally {
                           if (jjtc004) {
                             jjtree.closeNodeScope(jjtn004,  1);
                           }
                         }
/*@egen*/               
            (   "." t = <IDENT>         { sb.append('.').append( t.image ); }
            )*                          { ionode.setTargetType( new String(sb) ); }
        ]
    )
}


// navigation chain: property references, method calls, projections, selections, etc.
void navigationChain() : {}
{
    primaryExpression()
    (   "."/*@bgen(jjtree) #Chain( 2) */
        {
          ASTChain jjtn001 = new ASTChain(JJTCHAIN);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
        ( /* Prevent the "eval" ambiguity from issuing a warning; see discussion below. */
            ( LOOKAHEAD(2) methodCall() | propertyName() )
              // Also handle "{", which requires a lookahead of 2.
        |   ( LOOKAHEAD(2) projection() | selection() )
        |   "(" expression() ")"
        )/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001,  2);
          }
        }
/*@egen*/          

    |/*@bgen(jjtree) #Chain( 2) */
        {
          ASTChain jjtn002 = new ASTChain(JJTCHAIN);
          boolean jjtc002 = true;
          jjtree.openNodeScope(jjtn002);
        }
        try {
/*@egen*/   index()/*@bgen(jjtree)*/
        } catch (Throwable jjte002) {
          if (jjtc002) {
            jjtree.clearNodeScope(jjtn002);
            jjtc002 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte002 instanceof RuntimeException) {
            throw (RuntimeException)jjte002;
          }
          if (jjte002 instanceof ParseException) {
            throw (ParseException)jjte002;
          }
          throw (Error)jjte002;
        } finally {
          if (jjtc002) {
            jjtree.closeNodeScope(jjtn002,  2);
          }
        }
/*@egen*/          

    |   "(" expression()/*@bgen(jjtree) #Eval( 2) */
                         {
                           ASTEval jjtn003 = new ASTEval(JJTEVAL);
                           boolean jjtc003 = true;
                           jjtree.openNodeScope(jjtn003);
                         }
                         try {
/*@egen*/ ")"/*@bgen(jjtree)*/
                         } finally {
                           if (jjtc003) {
                             jjtree.closeNodeScope(jjtn003,  2);
                           }
                         }
/*@egen*/         

            /* Using parentheses to indicate evaluation of the current
               object makes this language ambiguous, because the
               expression "ident(args)" could be seen as a single
               method call or as a property name followed by an
               evaluation.  We always put the method call first and
               turn off the ambiguity warning; we always want to
               interpret this as a method call. */

    )*
}


void primaryExpression() : {
    Token   t;
    String  className = null;
}
{
    (
        (<CHAR_LITERAL> | <BACK_CHAR_LITERAL> | <STRING_LITERAL> | <INT_LITERAL> | <FLT_LITERAL>)/*@bgen(jjtree) #Const( 0) */
                                                {
                                                  ASTConst jjtn001 = new ASTConst(JJTCONST);
                                                  boolean jjtc001 = true;
                                                  jjtree.openNodeScope(jjtn001);
                                                }
                                                try {
/*@egen*//*@bgen(jjtree)*/
                                                {
                                                  jjtree.closeNodeScope(jjtn001,  0);
                                                  jjtc001 = false;
                                                }
/*@egen*/
                                                { jjtn001.setValue( token_source.literalValue ); }/*@bgen(jjtree)*/
                                                } finally {
                                                  if (jjtc001) {
                                                    jjtree.closeNodeScope(jjtn001,  0);
                                                  }
                                                }
/*@egen*/          
     |
        "true"/*@bgen(jjtree) #Const( 0) */
                                                {
                                                  ASTConst jjtn002 = new ASTConst(JJTCONST);
                                                  boolean jjtc002 = true;
                                                  jjtree.openNodeScope(jjtn002);
                                                }
                                                try {
/*@egen*//*@bgen(jjtree)*/
                                                {
                                                  jjtree.closeNodeScope(jjtn002,  0);
                                                  jjtc002 = false;
                                                }
/*@egen*/                                  { jjtn002.setValue( Boolean.TRUE ); }/*@bgen(jjtree)*/
                                                } finally {
                                                  if (jjtc002) {
                                                    jjtree.closeNodeScope(jjtn002,  0);
                                                  }
                                                }
/*@egen*/           
     |
        "false"/*@bgen(jjtree) #Const( 0) */
                                                {
                                                  ASTConst jjtn003 = new ASTConst(JJTCONST);
                                                  boolean jjtc003 = true;
                                                  jjtree.openNodeScope(jjtn003);
                                                }
                                                try {
/*@egen*//*@bgen(jjtree)*/
                                                {
                                                  jjtree.closeNodeScope(jjtn003,  0);
                                                  jjtc003 = false;
                                                }
/*@egen*/                                 { jjtn003.setValue( Boolean.FALSE ); }/*@bgen(jjtree)*/
                                                } finally {
                                                  if (jjtc003) {
                                                    jjtree.closeNodeScope(jjtn003,  0);
                                                  }
                                                }
/*@egen*/          
     |/*@bgen(jjtree) #Const( 0) */
        {
          ASTConst jjtn004 = new ASTConst(JJTCONST);
          boolean jjtc004 = true;
          jjtree.openNodeScope(jjtn004);
        }
        try {
/*@egen*/
        "null"/*@bgen(jjtree)*/
        } finally {
          if (jjtc004) {
            jjtree.closeNodeScope(jjtn004,  0);
          }
        }
/*@egen*/                                  // Null is the default value in an ASTConst
     |
        LOOKAHEAD(2) "#this"/*@bgen(jjtree) #ThisVarRef( 0) */
                                             {
                                               ASTThisVarRef jjtn005 = new ASTThisVarRef(JJTTHISVARREF);
                                               boolean jjtc005 = true;
                                               jjtree.openNodeScope(jjtn005);
                                             }
                                             try {
/*@egen*//*@bgen(jjtree)*/
                                             {
                                               jjtree.closeNodeScope(jjtn005,  0);
                                               jjtc005 = false;
                                             }
/*@egen*/                 { jjtn005.setName( "this" ); }/*@bgen(jjtree)*/
                                             } finally {
                                               if (jjtc005) {
                                                 jjtree.closeNodeScope(jjtn005,  0);
                                               }
                                             }
/*@egen*/               
     |
        LOOKAHEAD(2) "#root"/*@bgen(jjtree) #RootVarRef( 0) */
                                             {
                                               ASTRootVarRef jjtn006 = new ASTRootVarRef(JJTROOTVARREF);
                                               boolean jjtc006 = true;
                                               jjtree.openNodeScope(jjtn006);
                                             }
                                             try {
/*@egen*//*@bgen(jjtree)*/
                                             {
                                               jjtree.closeNodeScope(jjtn006,  0);
                                               jjtc006 = false;
                                             }
/*@egen*/                 { jjtn006.setName( "root" ); }/*@bgen(jjtree)*/
                                             } finally {
                                               if (jjtc006) {
                                                 jjtree.closeNodeScope(jjtn006,  0);
                                               }
                                             }
/*@egen*/               
     |
        LOOKAHEAD(2) "#" t=<IDENT>/*@bgen(jjtree) #VarRef( 0) */
                                                {
                                                  ASTVarRef jjtn007 = new ASTVarRef(JJTVARREF);
                                                  boolean jjtc007 = true;
                                                  jjtree.openNodeScope(jjtn007);
                                                }
                                                try {
/*@egen*//*@bgen(jjtree)*/
                                                {
                                                  jjtree.closeNodeScope(jjtn007,  0);
                                                  jjtc007 = false;
                                                }
/*@egen*/              { jjtn007.setName( t.image ); }/*@bgen(jjtree)*/
                                                } finally {
                                                  if (jjtc007) {
                                                    jjtree.closeNodeScope(jjtn007,  0);
                                                  }
                                                }
/*@egen*/           
     |
        LOOKAHEAD(2) ":" "[" expression() "]"/*@bgen(jjtree) #Const( 1) */
                                                {
                                                  ASTConst jjtn008 = new ASTConst(JJTCONST);
                                                  boolean jjtc008 = true;
                                                  jjtree.openNodeScope(jjtn008);
                                                }
                                                try {
/*@egen*//*@bgen(jjtree)*/
                                                {
                                                  jjtree.closeNodeScope(jjtn008,  1);
                                                  jjtc008 = false;
                                                }
/*@egen*/   { jjtn008.setValue( jjtn008.jjtGetChild(0) ); }/*@bgen(jjtree)*/
                                                } finally {
                                                  if (jjtc008) {
                                                    jjtree.closeNodeScope(jjtn008,  1);
                                                  }
                                                }
/*@egen*/          
     |
        staticReference()
     |
        LOOKAHEAD(2) constructorCall()
     |
          // Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
        ( LOOKAHEAD(2) methodCall() | propertyName() )
     |
        index()
     |
        "(" expression() ")"
     |
        "{"/*@bgen(jjtree) List */
            {
              ASTList jjtn009 = new ASTList(JJTLIST);
              boolean jjtc009 = true;
              jjtree.openNodeScope(jjtn009);
            }
            try {
/*@egen*/ [assignmentExpression() ("," assignmentExpression())*]/*@bgen(jjtree)*/
            } catch (Throwable jjte009) {
              if (jjtc009) {
                jjtree.clearNodeScope(jjtn009);
                jjtc009 = false;
              } else {
                jjtree.popNode();
              }
              if (jjte009 instanceof RuntimeException) {
                throw (RuntimeException)jjte009;
              }
              if (jjte009 instanceof ParseException) {
                throw (ParseException)jjte009;
              }
              throw (Error)jjte009;
            } finally {
              if (jjtc009) {
                jjtree.closeNodeScope(jjtn009, true);
              }
            }
/*@egen*/       "}"
     |
        LOOKAHEAD(2)/*@bgen(jjtree) Map */
                     {
                       ASTMap jjtn010 = new ASTMap(JJTMAP);
                       boolean jjtc010 = true;
                       jjtree.openNodeScope(jjtn010);
                     }
                     try {
/*@egen*/ ( "#" (className=classReference())? "{" [keyValueExpression() ("," keyValueExpression())*] { jjtn010.setClassName(className); } "}" )/*@bgen(jjtree)*/
                     } catch (Throwable jjte010) {
                       if (jjtc010) {
                         jjtree.clearNodeScope(jjtn010);
                         jjtc010 = false;
                       } else {
                         jjtree.popNode();
                       }
                       if (jjte010 instanceof RuntimeException) {
                         throw (RuntimeException)jjte010;
                       }
                       if (jjte010 instanceof ParseException) {
                         throw (ParseException)jjte010;
                       }
                       throw (Error)jjte010;
                     } finally {
                       if (jjtc010) {
                         jjtree.closeNodeScope(jjtn010, true);
                       }
                     }
/*@egen*/     
    )
}

void keyValueExpression() : {}
{/*@bgen(jjtree) KeyValue */
        {
          ASTKeyValue jjtn001 = new ASTKeyValue(JJTKEYVALUE);
          boolean jjtc001 = true;
          jjtree.openNodeScope(jjtn001);
        }
        try {
/*@egen*/
        ( assignmentExpression() (":" assignmentExpression())? )/*@bgen(jjtree)*/
        } catch (Throwable jjte001) {
          if (jjtc001) {
            jjtree.clearNodeScope(jjtn001);
            jjtc001 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte001 instanceof RuntimeException) {
            throw (RuntimeException)jjte001;
          }
          if (jjte001 instanceof ParseException) {
            throw (ParseException)jjte001;
          }
          throw (Error)jjte001;
        } finally {
          if (jjtc001) {
            jjtree.closeNodeScope(jjtn001, true);
          }
        }
/*@egen*/          
}

void staticReference() : {
    String className = "java.lang.Math";
    Token t;
}
{
    className=classReference()
        ( // Prevent the "eval" ambiguity from issuing a warning; see discussion elsewhere.
            LOOKAHEAD(2)
            staticMethodCall( className )
         |
            t=<IDENT>/*@bgen(jjtree) #StaticField( 0) */
                                    {
                                      ASTStaticField jjtn001 = new ASTStaticField(JJTSTATICFIELD);
                                      boolean jjtc001 = true;
                                      jjtree.openNodeScope(jjtn001);
                                    }
                                    try {
/*@egen*//*@bgen(jjtree)*/
                                    {
                                      jjtree.closeNodeScope(jjtn001,  0);
                                      jjtc001 = false;
                                    }
/*@egen*/               { jjtn001.init( className, t.image ); }/*@bgen(jjtree)*/
                                    } finally {
                                      if (jjtc001) {
                                        jjtree.closeNodeScope(jjtn001,  0);
                                      }
                                    }
/*@egen*/                
        )
}

String classReference(): {
    String      result = "java.lang.Math";
}
{
    "@" ( result=className() )? "@" { return result; }
}

String className(): {
    Token t;
    StringBuffer result;
}
{
    t=<IDENT>               { result = new StringBuffer( t.image ); }
    ( "." t=<IDENT>         { result.append('.').append( t.image ); }
    )*                      { return new String(result); }
}

void constructorCall()       : {/*@bgen(jjtree) Ctor */
    ASTCtor jjtn000 = new ASTCtor(JJTCTOR);
    boolean jjtc000 = true;
    jjtree.openNodeScope(jjtn000);
/*@egen*/
    String className;
    Token t;
    StringBuffer sb;
}
{/*@bgen(jjtree) Ctor */
    try {
/*@egen*/
    "new" className=className()
        (
            LOOKAHEAD(2) (
                "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"/*@bgen(jjtree)*/
                    {
                      jjtree.closeNodeScope(jjtn000, true);
                      jjtc000 = false;
                    }
/*@egen*/
                    {
                        jjtn000.setClassName(className);
                    }
            )
            |
            LOOKAHEAD(2) (
                "[" "]" "{"/*@bgen(jjtree) List */
                            {
                              ASTList jjtn001 = new ASTList(JJTLIST);
                              boolean jjtc001 = true;
                              jjtree.openNodeScope(jjtn001);
                            }
                            try {
/*@egen*/ [assignmentExpression() ("," assignmentExpression())*]/*@bgen(jjtree)*/
                            } catch (Throwable jjte001) {
                              if (jjtc001) {
                                jjtree.clearNodeScope(jjtn001);
                                jjtc001 = false;
                              } else {
                                jjtree.popNode();
                              }
                              if (jjte001 instanceof RuntimeException) {
                                throw (RuntimeException)jjte001;
                              }
                              if (jjte001 instanceof ParseException) {
                                throw (ParseException)jjte001;
                              }
                              throw (Error)jjte001;
                            } finally {
                              if (jjtc001) {
                                jjtree.closeNodeScope(jjtn001, true);
                              }
                            }
/*@egen*/       "}"/*@bgen(jjtree)*/
                    {
                      jjtree.closeNodeScope(jjtn000, true);
                      jjtc000 = false;
                    }
/*@egen*/
                    {
                        jjtn000.setClassName(className);
                        jjtn000.setArray(true);
                    }
            )
            |
            LOOKAHEAD(2) (
                "[" assignmentExpression() "]"/*@bgen(jjtree)*/
                    {
                      jjtree.closeNodeScope(jjtn000, true);
                      jjtc000 = false;
                    }
/*@egen*/
                    {
                        jjtn000.setClassName(className);
                        jjtn000.setArray(true);
                    }
            )
        )/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void propertyName()           : {/*@bgen(jjtree) Property */
    ASTProperty jjtn000 = new ASTProperty(JJTPROPERTY);
    boolean jjtc000 = true;
    jjtree.openNodeScope(jjtn000);
/*@egen*/
    Token t;
}
{/*@bgen(jjtree) Property */
    try {
/*@egen*/
    t=<IDENT>/*@bgen(jjtree) Const */
              {
                ASTConst jjtn001 = new ASTConst(JJTCONST);
                boolean jjtc001 = true;
                jjtree.openNodeScope(jjtn001);
              }
              try {
/*@egen*//*@bgen(jjtree)*/
              {
                jjtree.closeNodeScope(jjtn001, true);
                jjtc001 = false;
              }
/*@egen*/ { jjtn001.setValue( t.image ); }/*@bgen(jjtree)*/
              } finally {
                if (jjtc001) {
                  jjtree.closeNodeScope(jjtn001, true);
                }
              }
/*@egen*/       /*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void staticMethodCall( String className )               : {/*@bgen(jjtree) StaticMethod */
    ASTStaticMethod jjtn000 = new ASTStaticMethod(JJTSTATICMETHOD);
    boolean jjtc000 = true;
    jjtree.openNodeScope(jjtn000);
/*@egen*/
    Token t;
}
{/*@bgen(jjtree) StaticMethod */
    try {
/*@egen*/
    t=<IDENT> "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"/*@bgen(jjtree)*/
                                        {
                                          jjtree.closeNodeScope(jjtn000, true);
                                          jjtc000 = false;
                                        }
/*@egen*/
                                        { jjtn000.init( className, t.image ); }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void methodCall()         : {/*@bgen(jjtree) Method */
    ASTMethod jjtn000 = new ASTMethod(JJTMETHOD);
    boolean jjtc000 = true;
    jjtree.openNodeScope(jjtn000);
/*@egen*/
    Token t;
}
{/*@bgen(jjtree) Method */
    try {
/*@egen*/
    t=<IDENT> "(" [ assignmentExpression() ( "," assignmentExpression() )* ] ")"/*@bgen(jjtree)*/
                                        {
                                          jjtree.closeNodeScope(jjtn000, true);
                                          jjtc000 = false;
                                        }
/*@egen*/
                                        { jjtn000.setMethodName( t.image ); }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 * Apply an expression to all elements of a collection, creating a new collection
 * as the result.
 */
void projection()          : {/*@bgen(jjtree) Project */
  ASTProject jjtn000 = new ASTProject(JJTPROJECT);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Project */
    try {
/*@egen*/
    "{" expression() "}"/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void selection() : {}
{
        LOOKAHEAD(2) selectAll()
    |
        LOOKAHEAD(2) selectFirst()
    |
        LOOKAHEAD(2) selectLast()
}

/**
 * Apply a boolean expression to all elements of a collection, creating a new collection
 * containing those elements for which the expression returned true.
 */
void selectAll()         : {/*@bgen(jjtree) Select */
  ASTSelect jjtn000 = new ASTSelect(JJTSELECT);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Select */
    try {
/*@egen*/
    "{" "?" expression() "}"/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 * Apply a boolean expression to all elements of a collection, creating a new collection
 * containing those elements for the first element for which the expression returned true.
 */
void selectFirst()              : {/*@bgen(jjtree) SelectFirst */
  ASTSelectFirst jjtn000 = new ASTSelectFirst(JJTSELECTFIRST);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) SelectFirst */
    try {
/*@egen*/
    "{" "^" expression() "}"/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 * Apply a boolean expression to all elements of a collection, creating a new collection
 * containing those elements for the first element for which the expression returned true.
 */
void selectLast()             : {/*@bgen(jjtree) SelectLast */
  ASTSelectLast jjtn000 = new ASTSelectLast(JJTSELECTLAST);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) SelectLast */
    try {
/*@egen*/
    "{" "$" expression() "}"/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void index()           : {/*@bgen(jjtree) Property */
  ASTProperty jjtn000 = new ASTProperty(JJTPROPERTY);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Property */
    try {
/*@egen*/
    "[" expression() "]"/*@bgen(jjtree)*/
                         {
                           jjtree.closeNodeScope(jjtn000, true);
                           jjtc000 = false;
                         }
/*@egen*/ { jjtn000.setIndexedAccess(true); }
 |
    <DYNAMIC_SUBSCRIPT>/*@bgen(jjtree) Const */
                        {
                          ASTConst jjtn001 = new ASTConst(JJTCONST);
                          boolean jjtc001 = true;
                          jjtree.openNodeScope(jjtn001);
                        }
                        try {
/*@egen*//*@bgen(jjtree)*/
                        {
                          jjtree.closeNodeScope(jjtn001, true);
                          jjtc001 = false;
                        }
/*@egen*/ { jjtn001.setValue( token_source.literalValue ); }/*@bgen(jjtree)*/
                        } finally {
                          if (jjtc001) {
                            jjtree.closeNodeScope(jjtn001, true);
                          }
                        }
/*@egen*/       /*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    {
        jjtn000.setIndexedAccess(true);
    }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

// LEXER PRODUCTIONS

TOKEN_MGR_DECLS:
{
      /** Holds the last value computed by a constant token. */
    Object literalValue;
      /** Holds the last character escaped or in a character literal. */
    private char charValue;
      /** Holds char literal start token. */
    private char charLiteralStartQuote;
      /** Holds the last string literal parsed. */
    private StringBuffer stringBuffer;

      /** Converts an escape sequence into a character value. */
    private char escapeChar()
    {
        int ofs = image.length() - 1;
        switch ( image.charAt(ofs) ) {
            case 'n':   return '\n';
            case 'r':   return '\r';
            case 't':   return '\t';
            case 'b':   return '\b';
            case 'f':   return '\f';
            case '\\':  return '\\';
            case '\'':  return '\'';
            case '\"':  return '\"';
        }

          // Otherwise, it's an octal number.  Find the backslash and convert.
        while ( image.charAt(--ofs) != '\\' )
          {}
        int value = 0;
        while ( ++ofs < image.length() )
            value = (value << 3) | (image.charAt(ofs) - '0');
        return (char) value;
    }

    private Object makeInt()
    {
        Object  result;
        String  s = image.toString();
        int     base = 10;

        if ( s.charAt(0) == '0' )
            base = (s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X'))? 16 : 8;
        if ( base == 16 )
            s = s.substring(2); // Trim the 0x off the front
        switch ( s.charAt(s.length()-1) ) {
            case 'l': case 'L':
                result = Long.valueOf( s.substring(0,s.length()-1), base );
                break;

            case 'h': case 'H':
                result = new BigInteger( s.substring(0,s.length()-1), base );
                break;

            default:
                result = Integer.valueOf( s, base );
                break;
        }
        return result;
    }

    private Object makeFloat()
    {
        String s = image.toString();
        switch ( s.charAt(s.length()-1) ) {
            case 'f': case 'F':
                return Float.valueOf( s );

            case 'b': case 'B':
                return new BigDecimal( s.substring(0,s.length()-1) );

            case 'd': case 'D':
            default:
                return Double.valueOf( s );
        }
    }
}

// Whitespace -- ignored
SKIP:
{  " " | "\t" | "\f" | "\r" | "\n" }

// An identifier.
TOKEN:
{
    < IDENT: <LETTER> (<LETTER>|<DIGIT>)* >
 |
    < #LETTER: [
       "$",
       "A"-"Z",
       "_",
       "a"-"z",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ] >
 |
    < #DIGIT:
      [
       "0"-"9",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ] >
}

/**
 * Token for "dynamic subscripts", which are one of: [^], [|], [$], and [*].  The
 * appropriate constant from the DynamicSubscript class is stored in the token manager's
 * "value" field.
 */
TOKEN:
{
    < DYNAMIC_SUBSCRIPT: "[" ["^","|","$","*"] "]" >
        {
            switch (image.charAt(1)) {
              case '^': literalValue = DynamicSubscript.first; break;
              case '|': literalValue = DynamicSubscript.mid;   break;
              case '$': literalValue = DynamicSubscript.last;  break;
              case '*': literalValue = DynamicSubscript.all;   break;
          }
        }
}

/**
 * Character and string literals, whose object value is stored in the token manager's
 * "literalValue" field.
 */
MORE:
{
    "`"     : WithinBackCharLiteral
 |
    "'"     { stringBuffer = new StringBuffer(); }: WithinCharLiteral
 |
    "\""    { stringBuffer = new StringBuffer(); }: WithinStringLiteral
}

<WithinCharLiteral> MORE:
{
    < ESC: "\\" ( ["n","r","t","b","f","\\","'","`","\""]
                | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?
                )
    >
        { charValue = escapeChar(); stringBuffer.append(charValue); }
 |
    < (~["'","\\"]) >
        { charValue = image.charAt( image.length()-1 ); stringBuffer.append(charValue); }
}

<WithinCharLiteral> TOKEN:
{
    < CHAR_LITERAL: "'">
        {
            if (stringBuffer.length() == 1) {
                literalValue = new Character( charValue );
            } else {
                literalValue = new String( stringBuffer );
            }
        }
        : DEFAULT
}

<WithinBackCharLiteral> MORE:
{
    < BACK_CHAR_ESC: <ESC> >
        { charValue = escapeChar(); }
 |
    < (~["`","\\"]) >
        { charValue = image.charAt( image.length()-1 ); }
}

<WithinBackCharLiteral> TOKEN:
{
    < BACK_CHAR_LITERAL: "`">
        { literalValue = new Character( charValue ); }: DEFAULT
}

<WithinStringLiteral> MORE:
{
    < STRING_ESC: <ESC> >
        { stringBuffer.append( escapeChar() ); }
 |
    < (~["\"","\\"]) >
        { stringBuffer.append( image.charAt(image.length()-1) ); }
}

<WithinStringLiteral> TOKEN:
{
    <STRING_LITERAL: "\"">
        { literalValue = new String( stringBuffer ); }
        : DEFAULT
}

/**
 * Integer or real Numeric literal, whose object value is stored in the token manager's
 * "literalValue" field.
 */
TOKEN:
{
    < INT_LITERAL:
        ( "0" (["0"-"7"])* | ["1"-"9"] (["0"-"9"])* | "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ )
        (["l","L","h","H"])?
    >
        { literalValue =
        makeInt(); }
 |
    < FLT_LITERAL:
        ( <DEC_FLT> (<EXPONENT>)? (<FLT_SUFF>)?
        | <DEC_DIGITS> <EXPONENT> (<FLT_SUFF>)?
        | <DEC_DIGITS> <FLT_SUFF>
        )
    >
        { literalValue = makeFloat(); }

 |  < #DEC_FLT: (["0"-"9"])+ "." (["0"-"9"])* | "." (["0"-"9"])+ >
 |  < #DEC_DIGITS: (["0"-"9"])+ >
 |  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
 |  < #FLT_SUFF: ["d","D","f","F","b","B"] >
}

