/*
 * Copyright (c) 2004,2005 UCLA Compilers Group. 
 * 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 UCLA 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.
 */
/*
 * JTB 1.3.x is a derivation of JTB 1.2.1 which has the following 
 * license:
 */
/*
 * All files in the distribution of JTB, The Java Tree Builder are
 * Copyright 1997, 1998, 1999 by the Purdue Research Foundation of Purdue
 * University.  All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this entire copyright notice is duplicated in all
 * such copies, and that any documentation, announcements, and
 * other materials related to such distribution and use acknowledge
 * that the software was developed at Purdue University, West Lafayette,
 * Indiana by Kevin Tao and Jens Palsberg.  No charge may be made
 * for copies, derivations, or distributions of this material
 * without the express written consent of the copyright holder.
 * Neither the name of the University nor the name of the author
 * may be used to endorse or promote products derived from this
 * material without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
 */
//
// Java Tree Builder (JTB) Grammar
//
// Converted from the JavaCC 0.6 grammar in the documentation.
// Appended to the Java1.1.jj grammar provided in JavaCC.
//
// AUTHOR: Kevin Tao, taokr@cs.purdue.edu
//
// This grammar is basically the JavaCC grammar, adapted from the
// documentation.  A few changes have been made to fix possible bugs in the
// grammar.
//
/* ************************************************************************* */
/*
 *
 * Copyright (C) 1996, 1997 Sun Microsystems Inc.
 *
 * Use of this file and the system it is part of is constrained by the
 * file COPYRIGHT in the root directory of this system.  You may, however,
 * make any modifications you wish to this file.
 *
 * Java files generated by running JavaCC on this file (or modified versions
 * of this file) may be used in exactly the same manner as Java files
 * generated from any grammar developed by you.
 *
 * Author: Sriram Sankar
 * Date: 3/5/97
 *
 * This file contains a Java grammar and actions that implement a front-end.
 *
 */

/*
 * JavaCC Grammar used by JTB.
 *
 * @author Marc Mazas
 * @version 1.4.x : 05-11/2009-2010-2011-2012-2013-2014 : MMa
 *  adapted from JavaCC v4.2 grammar (JavaCC.jj)
 *   to fit with JTB.java and 
 *   to use the try-ExpansionChoices-catch-finally syntax through the ExpansionUnitInTCF production
 */
// ModMMa 06/2012 : 1.4.7 : modified AccessModifier(), BlockStatement(), LocalVariableDeclaration()
//                added VariableModifiers()
// ModMMa 07/2012 : 1.4.7 : added assert, enum & strictfp java keywords
//               fixed ForStatement() ; ForInit()
//               renamed RSIGNEDSHIFT in RSignedShift and fixed it
//               renamed RUNSIGNEDSHIFT in RUnsignedShift and fixed it
//               modified RegularExpression (remove LANGLE & RANGLE definitions)
//               renamed ExpansionUnitInTCF into ExpansionUnitTCF
// ModMMa 09/2012 : 1.4.7 : added "!" syntax in BNFProduction and RegExprSpec and ExpansionUnit
//                for not generating the node creation in the callers ;
//                fixed forbidding punctuation between productions
// ModMMa 10/2012 : 1.4.8 : added "%" syntax in JavaCodeProduction
// ModMMa 11/2014 : 1.4.8 : added AnnotationTypeDeclaration() in ClassOrInterfaceBodyDeclaration() ;
//                added ReferenceType() in ExplicitConstructorInvocation() ;
//               removed old invalid comments on missing node descriptors (they are in JJTree but not JTB)
// ModMMa 12/2014 : 1.4.8 : added variables initialization code ;
//                fixed the LOOKAHEAD in and modified ExplicitConstructorInvocation()

options
{
// ModMMa : added (does not exist in JavaCC.jj nor in jtbgram.jj, but needed for Eclipse plugin)
  OUTPUT_DIRECTORY = "parser";

// ModMMa : kept (from JavaCC.jj and jtbgram.jj)
  JAVA_UNICODE_ESCAPE = true;

// ModMMa : kept (from JavaCC.jj, but it does not exist in jtbgram.jj)
  STATIC = false;

// ModMMa : impossible to use it (too long, too big)
//  DEBUG_LOOKAHEAD = true;
  }

// ModMMa : adapted from JavaCC.jj to fit to JTB parser name, package, imports
PARSER_BEGIN(JTBParser)
package EDU.purdue.jtb.parser;

import java.util.List;
import java.util.ArrayList;


/**
 * This file contains the code for JavaCCParser generated
 * by JavaCCParser itself.
 */
// ModMMa : adapted from JavaCC.jj to fit to JTB class name
public class JTBParser extends JavaCCParserInternals
{
  /**
   * The name of the parser class.
   */
  String parser_class_name;
  /**
   * This flag is set to true when the part between PARSER_BEGIN and
   * PARSER_END is being parsed.
   */
  boolean processing_cu = false;
  /**
   * The level of class nesting.
   */
  int class_nesting = 0;
  /**
   * This int variable is incremented while parsing local lookaheads.
   * Hence it keeps track of *syntactic* lookahead nesting.
   * This is used to provide warnings when actions and nested lookaheads
   * are used in syntactic lookahead productions.  This is to prevent
   * typos such as leaving out the comma in LOOKAHEAD( foo(), {check()} ).
   */
  int inLocalLA = 0;
  /**
   * Set to true when the parser is within an action.
   */
  boolean inAction = false;
  /**
   * This flag keeps track of whether or not return and throw
   * statements have been patched during the parsing of a production.
   * The value of this flag is assigned the field with the same
   * name in BNFProduction_.java.
   */
  boolean jumpPatched = false;

  /*
   * Returns true if the next token is not in the FOLLOW list of "expansion".
   * It is used to decide when the end of an "expansion" has been reached.
   */
  private boolean notTailOfExpansionUnit()
  {
    final Token t = getToken(1);
    if (t.kind == BIT_OR || t.kind == COMMA || t.kind == RPAREN || t.kind == RBRACE || t.kind == RBRACKET)
      return false;
    return true;
  }

  /**
   * Class to hold modifiers.
   */
  static public final class ModifierSet
  {
    /* Definitions of the bits in the modifiers field */

    public static final int M_PUBLIC = 0x0001;
    public static final int M_PROTECTED = 0x0002;
    public static final int M_PRIVATE = 0x0004;
    public static final int M_ABSTRACT = 0x0008;
    public static final int M_STATIC = 0x0010;
    public static final int M_FINAL = 0x0020;
    public static final int M_SYNCHRONIZED = 0x0040;
    public static final int M_NATIVE = 0x0080;
    public static final int M_TRANSIENT = 0x0100;
    public static final int M_VOLATILE = 0x0200;
    public static final int M_STRICTFP = 0x1000;

    /* A set of accessors that indicate whether the specified modifier is in the set */

    public boolean isPublic(int modifiers)
    {
      return (modifiers & M_PUBLIC) != 0;
    }

    public boolean isProtected(int modifiers)
    {
      return (modifiers & M_PROTECTED) != 0;
    }

    public boolean isPrivate(int modifiers)
    {
      return (modifiers & M_PRIVATE) != 0;
    }

    public boolean isStatic(int modifiers)
    {
      return (modifiers & M_STATIC) != 0;
    }

    public boolean isAbstract(int modifiers)
    {
      return (modifiers & M_ABSTRACT) != 0;
    }

    public boolean isFinal(int modifiers)
    {
      return (modifiers & M_FINAL) != 0;
    }

    public boolean isNative(int modifiers)
    {
      return (modifiers & M_NATIVE) != 0;
    }

    public boolean isStrictfp(int modifiers)
    {
      return (modifiers & M_STRICTFP) != 0;
    }

    public boolean isSynchronized(int modifiers)
    {
      return (modifiers & M_SYNCHRONIZED) != 0;
    }

    public boolean isTransient(int modifiers)
    {
      return (modifiers & M_TRANSIENT) != 0;
    }

    public boolean isVolatile(int modifiers)
    {
      return (modifiers & M_VOLATILE) != 0;
    }

    /* Removes the given modifier */

    static int removeModifier(int modifiers, int mod)
    {
      return modifiers & ~mod;
    }
  }
}

// ModMMa : adapted from JavaCC.jj to fit to JTB parser name
PARSER_END(JTBParser)

TOKEN_MGR_DECLS :
{
  int size = 20;
  int beginLine[] = new int[size];
  int beginCol[] = new int[size];
  int depth = 0;

  final void saveBeginLineCol(final int l, final int c)
  {
    if (depth == size)
    {
      size += 10;
      final int tmpbeginLine[] = new int[size];
      final int tmpbeginCol [] = new int[size];
      System.arraycopy(beginLine, 0, tmpbeginLine, 0, depth);
      System.arraycopy(beginCol, 0, tmpbeginCol, 0, depth);
      beginLine = tmpbeginLine;
      beginCol = tmpbeginCol;
    }
    beginLine[depth] = l;
    beginCol[depth] = c;
    depth++;
  }

  final void restoreBeginLineCol()
  {
    depth--;
    input_stream.adjustBeginLineColumn(beginLine[depth], beginCol[depth]);
  }
}


/**********************************************
 * THE JAVACC TOKEN SPECIFICATION STARTS HERE *
 **********************************************/
/* JAVACC RESERVED WORDS: These are the only tokens in JavaCC but not in Java */
TOKEN :
{
  // "options" is no longer reserved (see issue 126).
  //  < _OPTIONS: "options" >
  < _LOOKAHEAD : "LOOKAHEAD" >
| < _IGNORE_CASE : "IGNORE_CASE" >
| < _PARSER_BEGIN : "PARSER_BEGIN" >
| < _PARSER_END : "PARSER_END" >
| < _JAVACODE : "JAVACODE" >
| < _TOKEN : "TOKEN" >
| < _SPECIAL_TOKEN : "SPECIAL_TOKEN" >
| < _MORE : "MORE" >
| < _SKIP : "SKIP" >
| < _TOKEN_MGR_DECLS : "TOKEN_MGR_DECLS" >
| < _EOF : "EOF" >
}

/*
 * The remainder of the tokens are exactly (except for the removal of tokens containing ">>" and "<<")
 * as in the Java grammar and must be equivalent (again with the exceptions above) to it
 */
/* WHITE SPACE */
SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
| "\f"
| "/*@egen*/" : AFTER_EGEN
}

< AFTER_EGEN >
SKIP :
{
  < ~[ ] >
  {
    restoreBeginLineCol();
    input_stream.backup(1);
  }
  : DEFAULT
}

/* COMMENTS */
MORE :
{
  "//" : IN_SINGLE_LINE_COMMENT
| < "/**" ~[ "/" ] >
  {
    input_stream.backup(1);
  }
  : IN_FORMAL_COMMENT
| "/*" : IN_MULTI_LINE_COMMENT
| "/*@bgen(jjtree"
  {
    saveBeginLineCol(input_stream.getBeginLine(), input_stream.getBeginColumn());
  }
  : IN_MULTI_LINE_COMMENT
}

< IN_SINGLE_LINE_COMMENT >
SPECIAL_TOKEN :
{
  < SINGLE_LINE_COMMENT :
    "\n"
  | "\r"
  | "\r\n" > : DEFAULT
}

< IN_FORMAL_COMMENT >
SPECIAL_TOKEN :
{
  < FORMAL_COMMENT : "*/" > : DEFAULT
}

< IN_MULTI_LINE_COMMENT >
SPECIAL_TOKEN :
{
  < MULTI_LINE_COMMENT : "*/" > : DEFAULT
}

< IN_SINGLE_LINE_COMMENT, IN_FORMAL_COMMENT, IN_MULTI_LINE_COMMENT >
MORE :
{
  < ~[ ] >
}

/* JAVA RESERVED WORDS AND LITERALS */
TOKEN :
{
  < ABSTRACT : "abstract" >
| < ASSERT : "assert" >
| < BOOLEAN : "boolean" >
| < BREAK : "break" >
| < BYTE : "byte" >
| < CASE : "case" >
| < CATCH : "catch" >
| < CHAR : "char" >
| < CLASS : "class" >
| < CONST : "const" >
| < CONTINUE : "continue" >
| < _DEFAULT : "default" >
| < DO : "do" >
| < DOUBLE : "double" >
| < ELSE : "else" >
| < ENUM : "enum" >
| < EXTENDS : "extends" >
| < FALSE : "false" > // boolean literal
| < FINAL : "final" >
| < FINALLY : "finally" >
| < FLOAT : "float" >
| < FOR : "for" >
| < GOTO : "goto" >
| < IF : "if" >
| < IMPLEMENTS : "implements" >
| < IMPORT : "import" >
| < INSTANCEOF : "instanceof" >
| < INT : "int" >
| < INTERFACE : "interface" >
| < LONG : "long" >
| < NATIVE : "native" >
| < NEW : "new" >
| < NULL : "null" > // null literal
| < PACKAGE : "package" >
| < PRIVATE : "private" >
| < PROTECTED : "protected" >
| < PUBLIC : "public" >
| < RETURN : "return" >
| < SHORT : "short" >
| < STATIC : "static" >
| < STRICTFP : "strictfp" >
| < SUPER : "super" >
| < SWITCH : "switch" >
| < SYNCHRONIZED : "synchronized" >
| < THIS : "this" >
| < THROW : "throw" >
| < THROWS : "throws" >
| < TRANSIENT : "transient" >
| < TRUE : "true" > // boolean literal
| < TRY : "try" >
| < VOID : "void" >
| < VOLATILE : "volatile" >
| < WHILE : "while" >
}

/* JAVA LITERALS */
TOKEN :
{
  < INTEGER_LITERAL :
    < DECIMAL_LITERAL > (< LONG_LETTER >)?
  | < HEX_LITERAL > (< LONG_LETTER >)?
  | < OCTAL_LITERAL > (< LONG_LETTER >)? >
| < FLOATING_POINT_LITERAL :
    < DECIMAL_FLOATING_POINT_LITERAL >
  | < HEXADECIMAL_FLOATING_POINT_LITERAL > >
| < CHARACTER_LITERAL :
    "'"
    (
      (~[ "'", "\\", "\n", "\r" ])
    | < ESCAPED_CHARACTER >
    )
    "'" >
| < STRING_LITERAL :
    "\""
    (
      (~[ "\"", "\\", "\n", "\r" ])
    | < ESCAPED_CHARACTER >
    )*
    "\"" >
| < #DEC_DIGIT : [ "0"-"9" ] >
| < #HEX_DIGIT : [ "0"-"9", "a"-"f", "A"-"F" ] >
| < #OCTAL_DIGIT : [ "0"-"7" ] >
| < #OCTAL_FIRST_DIGIT : [ "0"-"3" ] >
| < #DECIMAL_LITERAL : [ "1"-"9" ] (< DEC_DIGIT >)* >
| < #HEX_LITERAL : "0" [ "x", "X" ] (< HEX_DIGIT >)+ >
| < #OCTAL_LITERAL : "0" (< OCTAL_DIGIT >)* >
| < #DECIMAL_EXPONENT : [ "e", "E" ] ([ "+", "-" ])? (< DEC_DIGIT >)+ >
| < #HEXADECIMAL_EXPONENT : [ "p", "P" ] ([ "+", "-" ])? (< DEC_DIGIT >)+ >
| < #FLOATING_POINT_LETTER : [ "f", "F", "d", "D" ] >
| < #LONG_LETTER : [ "l", "L" ] >
| < #DECIMAL_FLOATING_POINT_LITERAL :
    (< DEC_DIGIT >)+ "." (< DEC_DIGIT >)* (< DECIMAL_EXPONENT >)? (< FLOATING_POINT_LETTER >)?
  | "." (< DEC_DIGIT >)+ (< DECIMAL_EXPONENT >)? (< FLOATING_POINT_LETTER >)?
  | (< DEC_DIGIT >)+ < DECIMAL_EXPONENT > (< FLOATING_POINT_LETTER >)?
  | (< DEC_DIGIT >)+ (< DECIMAL_EXPONENT >)? < FLOATING_POINT_LETTER > >
| < #HEXADECIMAL_FLOATING_POINT_LITERAL :
    "0" [ "x", "X" ] (< HEX_DIGIT >)+ (".")? < HEXADECIMAL_EXPONENT > (< FLOATING_POINT_LETTER >)?
  | "0" [ "x", "X" ] (< HEX_DIGIT >)* "." (< HEX_DIGIT >)+ < HEXADECIMAL_EXPONENT > (< FLOATING_POINT_LETTER >)? >
| < #ESCAPED_CHARACTER :
      "\\"
      (
        [ "n", "t", "b", "r", "f", "\\", "'", "\"" ]
      | < OCTAL_DIGIT > (< OCTAL_DIGIT >)?
      | < OCTAL_FIRST_DIGIT > < OCTAL_DIGIT > < OCTAL_DIGIT >
      ) >
}

/* SEPARATORS */
TOKEN :
{
  < LPAREN : "(" >
| < RPAREN : ")" >
| < LBRACE : "{" >
| < RBRACE : "}" >
| < LBRACKET : "[" >
| < RBRACKET : "]" >
| < SEMICOLON : ";" >
| < COMMA : "," >
| < DOT : "." >
}

/* OPERATORS */
TOKEN :
{
  < ASSIGN : "=" >
  // (moved to next TOKEN declaration)
  //| < GT: ">" >
| < LT : "<" >
| < BANG : "!" >
| < TILDE : "~" >
| < HOOK : "?" >
| < COLON : ":" >
| < EQ : "==" >
| < LE : "<=" >
| < GE : ">=" >
| < NE : "!=" >
| < SC_OR : "||" >
| < SC_AND : "&&" >
| < INCR : "++" >
| < DECR : "--" >
| < PLUS : "+" >
| < MINUS : "-" >
| < STAR : "*" >
| < SLASH : "/" >
| < BIT_AND : "&" >
| < BIT_OR : "|" >
| < XOR : "^" >
| < REM : "%" >
  //	| < LSHIFT: "<<" >
  //	| < RSIGNEDSHIFT: ">>" >
  //	| < RUNSIGNEDSHIFT: ">>>" >
| < PLUSASSIGN : "+=" >
| < MINUSASSIGN : "-=" >
| < STARASSIGN : "*=" >
| < SLASHASSIGN : "/=" >
| < ANDASSIGN : "&=" >
| < ORASSIGN : "|=" >
| < XORASSIGN : "^=" >
| < REMASSIGN : "%=" >
  //	| < LSHIFTASSIGN: "<<=" >
  //	| < RSIGNEDSHIFTASSIGN: ">>=" >
  //	| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
}

/* >'s need special attention due to generics syntax */
// (see also RUnsignedShift() and RSignedShift())
TOKEN :
{
  < RUNSIGNEDSHIFT : ">>>" >
  {
    matchedToken.kind = GT;
    ((Token.GTToken) matchedToken).realKind = RUNSIGNEDSHIFT;
    input_stream.backup(2);
    matchedToken.image = ">";
  }
| < RSIGNEDSHIFT : ">>" >
  {
    matchedToken.kind = GT;
    ((Token.GTToken) matchedToken).realKind = RSIGNEDSHIFT;
    input_stream.backup(1);
    matchedToken.image = ">";
  }
| < GT : ">" >
}

/************************************************
 * THE JAVACC GRAMMAR SPECIFICATION STARTS HERE *
 ************************************************/

// ModMMa : changed all javacc_input into JavaCCInput to conform to class name convention
void JavaCCInput() :
{
  String id1 = null;
  String id2 = null;
  initialize();
// ModMMa : added to JavaCC as called in parser.Main in Javacc 4.2
  Options.init();
}
{
  JavaCCOptions()
  "PARSER_BEGIN" "(" id1 = IdentifierAsString() { addcuname(id1); } ")"
  { processing_cu = true; parser_class_name = id1; }
  CompilationUnit()
  { processing_cu = false; }
  "PARSER_END" "(" id2 = IdentifierAsString() { compare(getToken(0), id1, id2); } ")"
  ( Production() )+
  // ModMMa 09/2012 : added to forbid punctuation between productions
  < EOF >
}

// ModMMa : changed all javacc_options into JavaCCOptions to conform to class name convention
void JavaCCOptions() :
{}
{
  [
    LOOKAHEAD({ getToken(1).image.equals("options") })
    "options" "{"
    (
      OptionBinding()
    )*
    "}"
  ]
  {
    Options.normalize();
  }
}

// ModMMa : changed all option_binding into OptionBinding to conform to class name convention
void OptionBinding() :
{
  String option_name = null;
  int int_val = 0;
  boolean bool_val = false;
  String string_val = null;
  Token t = getToken(1);
}
{
  (
    < IDENTIFIER >
  | "LOOKAHEAD"
  | "IGNORE_CASE"
  | "static"
  )
  {
    option_name = t.image;
  }
  "="
  (
    int_val = IntegerLiteral()
    {
      Options.setInputFileOption(t, getToken(0), option_name, new Integer(int_val));
    }
  | bool_val = BooleanLiteral()
    {
      Options.setInputFileOption(t, getToken(0), option_name, new Boolean(bool_val));
    }
  | string_val = StringLiteral()
    {
      Options.setInputFileOption(t, getToken(0), option_name, string_val);
    }
  )
  ";"
}

// ModMMa : changed all production into Production to conform to class name convention
void Production() :
{}
{
  LOOKAHEAD(1)
  /*
   * Since JAVACODE is both a JavaCC reserved word and a Java identifier,
   * we need to give preference to "JavaCodeProduction" over "BNFProduction"
   */
  JavaCodeProduction()
| LOOKAHEAD(1)
  /*
   * Since SKIP, TOKEN, etc. are both JavaCC reserved words and Java identifiers,
   * we need to give preference to "RegularExprProduction" over "BNFProduction"
   */
  RegularExprProduction()
| LOOKAHEAD(1)
  /*
   * Since TOKEN_MGR_DECLS is both a JavaCC reserved word and a Java identifier,
   * we need to give preference to "TokenManagerDecls" over "BNFProduction"
   */
  TokenManagerDecls()
| BNFProduction()
}

// ModMMa : changed all JavaCodeProduction into JavaCodeProduction_ (JavaCC specific class)
// ModMMa : changed all javacode_production into JavaCodeProduction to conform to class name convention
void JavaCodeProduction() :
{
  JavaCodeProduction_ p = new JavaCodeProduction_();
  String lhs = null;
  Token t = getToken(1);
  p.setFirstToken(t);
  List<Token> excName = null;
  p.setThrowsList(new ArrayList<List<Token>>());
  p.setLine(t.beginLine);
  p.setColumn(t.beginColumn);
}
{
  "JAVACODE" AccessModifier(p)
  ResultType(p.getReturnTypeTokens())
  lhs = IdentifierAsString() { p.setLhs(lhs); }
  FormalParameters(p.getParameterListTokens())
  [
    "throws"
    {
      excName = new ArrayList<Token>();
    }
    Name(excName)
    {
      p.getThrowsList().add(excName);
    }
    (
      {
      excName = new ArrayList<Token>();
      }
      "," Name(excName)
      {
        p.getThrowsList().add(excName);
      }
    )*
  ]
  // ModMMa 10/2012 : added for not generating the node creation within the callers (in JavaCodeProduction)
  [ "%" ]
  Block(p.getCodeTokens())
  {
    p.setLastToken(getToken(0));
    addproduction(p);
  }
}

// ModMMa : changed all BNFProduction into BNFProduction_ (JavaCC specific class)
// ModMMa : changed all bnf_production into BNFProduction to conform to class name convention
void BNFProduction() :
{
  BNFProduction_ p = new BNFProduction_();
  Container c = new Container();
  Token t = getToken(1);
  p.setFirstToken(t);
  List<Token> excName = null;
  String lhs = null;
  p.setThrowsList(new ArrayList<List<Token> >());
  p.setLine(t.beginLine);
  p.setColumn(t.beginColumn);
  jumpPatched = false;
}
{
  AccessModifier(p) ResultType(p.getReturnTypeTokens())
  lhs = IdentifierAsString() { p.setLhs(lhs); }
  FormalParameters(p.getParameterListTokens())
  [
    "throws"
    {
      excName = new ArrayList<Token>();
    }
    Name(excName)
    {
      p.getThrowsList().add(excName);
    }
    (
      {
      excName = new ArrayList<Token>();
      }
      "," Name(excName)
      {
        p.getThrowsList().add(excName);
      }
    )*
  ]
  // ModMMa 09/2012 : added for not generating the node creation within the callers (in BNFProduction)
  [ "!" ]
  ":" Block
  (
    p.getDeclarationTokens()
  )
  "{" ExpansionChoices(c) t = "}"
  {
    p.setLastToken(t);
    p.setJumpPatched(jumpPatched);
    production_addexpansion(p, (Expansion_) (c.member));
    addproduction(p);
  }
}

void AccessModifier(NormalProduction p) :
{
  Token t = null;
}
{
  (
    t = "public"
  | t = "protected"
  | t = "private"
  // added MMa 07/2012
  |  "final"
  // modified MMa 07/2012
  // )?
  )*
  {
    if (t != null)
    {
      p.setAccessMod(t.image);
    }
  }
}

// ModMMa : changed all regular_expr_production into RegularExprProduction to conform to class name convention
void RegularExprProduction() :
{
  TokenProduction p = new TokenProduction();
  List<String> states = null;
  Token t = p.firstToken = getToken(1);
  p.setLine(t.beginLine);
  p.setColumn(t.beginColumn);
}
{
  {
    /* Set p.lexStates assuming there is no lexical state specified, and then override if necessary */
    p.lexStates = new String [ ] { "DEFAULT" };
  }
  [
    LOOKAHEAD(2)
    "<" "*" ">"
    {
      p.lexStates = null;
    }
  | "<"
    {
      states = new ArrayList<String>();
    }
    t = < IDENTIFIER > { states.add(t.image); }
    (
      ","
      t = < IDENTIFIER > { states.add(t.image); }
    )*
    ">"
    {
      p.lexStates = new String [ states.size() ];
      for (int i = 0;
      // modified MMa : workaround for Eclipse plugin color syntax problem
      //      i < states.size();
      i != states.size();
      i++)
        {
          p.lexStates [ i ] = states.get(i);
        }
      }
    ]
    RegExprKind(p)
    {
      if (p.kind != TokenProduction.TOKEN && Options.getUserTokenManager())

      {
        JavaCCErrors.warning(getToken(0), "Regular expression is being treated as if it were a TOKEN since option USER_TOKEN_MANAGER has been set to true.");
      }
    }
    [
      "[" t = "IGNORE_CASE" "]"
      {
        p.ignoreCase = true;
        if (Options.getUserTokenManager())
        {
          JavaCCErrors.warning(t, "Ignoring \"IGNORE_CASE\" specification since option USER_TOKEN_MANAGER has been set to true.");
        }
      }
    ]
    ":" "{" RegExprSpec(p)
    (
      "|" RegExprSpec(p)
    )*
    t = "}"
    {
      p.lastToken = t;
      addregexpr(p);
    }
  }

// ModMMa : changed all token_manager_decls into TokenManagerDecls to conform to class name convention
void TokenManagerDecls() :
  {
    List<Token> decls = new ArrayList<Token>();
    Token t = null;
  }
  {
    t = "TOKEN_MGR_DECLS" ":" ClassOrInterfaceBody(false, decls)
    {
      add_token_manager_decls(t, decls);
    }
  }

// ModMMa : changed all regexpr_kind into RegExprKind to conform to class name convention
void RegExprKind(TokenProduction p) :
{}
  {
    "TOKEN"
    {
      p.kind = TokenProduction.TOKEN;
    }
  | "SPECIAL_TOKEN"
    {
      p.kind = TokenProduction.SPECIAL;
    }
  | "SKIP"
    {
      p.kind = TokenProduction.SKIP;
    }
  | "MORE"
    {
      p.kind = TokenProduction.MORE;
    }
  }

// ModMMa : changed all RegExprSpec into RegExprSpec_ (JavaCC specific class)
// ModMMa : changed all regexpr_spec into RegExprSpec to conform to class name convention
void RegExprSpec(TokenProduction p) :
  {
    Container c = new Container();
    Action act = new Action();
    Token t = null;
    RegExprSpec_ res = new RegExprSpec_();
  }
  {
    RegularExpression(c)
    // ModMMa 09/2012 : added for not generating the node creation within the callers (in RegExprSpec)
    [ "!" ]
    {
      res.rexp = (RegularExpression_) c.member;
      res.rexp.tpContext = p;
    }
    [
      {
        t = getToken(1);
      }
      Block
      (
        act.getActionTokens()
      )
      {
        if (Options.getUserTokenManager())
        {
          JavaCCErrors.warning(t, "Ignoring action in regular expression specification since option USER_TOKEN_MANAGER has been set to true.");
        }
        if (res.rexp.private_rexp)
        {
          JavaCCErrors.parse_error(t, "Actions are not permitted on private (#) regular expressions.");
        }
      }
    ]
    [
      ":" t = < IDENTIFIER >
      {
        res.nextState = t.image;
        if (res.rexp.private_rexp)
        {
          JavaCCErrors.parse_error(t, "Lexical state changes are not permitted after private (#) regular expressions.");
        }
      }
    ]
    {
      res.act = act;
      res.nsTok = t;
      p.respecs.add(res);
    }
  }

// ModMMa : changed all expansion_choices into ExpansionChoices to conform to class name convention
void ExpansionChoices(Container c1) :
  {
    boolean morethanone = false;
    Choice ch = new Choice();
    Container c2 = new Container();
  }
  {
    Expansion(c1)
    (
      "|" Expansion(c2)
      {
        if (morethanone)
        {
          ch.getChoices().add((Expansion_) c2.member);
          ((Expansion_) c2.member).parent = ch;
        }
        else
        {
          morethanone = true;
          ch = new Choice((Expansion_) c1.member);
          ((Expansion_) c1.member).parent = ch;
          ch.getChoices().add((Expansion_) c2.member);
          ((Expansion_) c2.member).parent = ch;
        }
      }
    )*
    {
      if (morethanone)
      {
        c1.member = ch;
      }
    }
  }

// ModMMa : changed all Expansion into Expansion_ (JavaCC specific class)
// ModMMa : changed all expansion into Expansion to conform to class name convention
void Expansion(Container c1) :
  {
    Sequence seq = new Sequence();
    Container c2 = new Container();
    Lookahead la = new Lookahead();
    Token t = getToken(1);
    seq.setLine(t.beginLine);
    seq.setColumn(t.beginColumn);
    la.setLine(t.beginLine);
    la.setColumn(t.beginColumn);
  }
  {
    {
      la.setAmount(Options.getLookahead());
      la.setLaExpansion(null);
      la.setExplicit(false);
    }
    (
      LOOKAHEAD(1)
      t = "LOOKAHEAD" "(" la = LocalLookahead() ")"
      {
        if (inLocalLA != 0 && la.getAmount() != 0)
        {
          JavaCCErrors.warning(t, "Only semantic lookahead specifications within other lookahead specifications is considered.  Syntactic lookahead is ignored.");
        }
      }
    )?
    {
      seq.units.add(la);
    }
    (
      LOOKAHEAD(0, { notTailOfExpansionUnit() })
      ExpansionUnit(c2)
      {
        seq.units.add((Expansion_)c2.member);
        ((Expansion_) c2.member).parent = seq;
        ((Expansion_) c2.member).ordinal = seq.units.size() - 1;
      }
    )+
    {
      if (la.getLaExpansion() == null)
      {
        la.setLaExpansion(seq);
      }
      c1.member = seq;
    }
  }

// ModMMa : changed all local_lookahead into LocalLookahead to conform to class name convention
Lookahead LocalLookahead() :
  {
    Lookahead la = new Lookahead();
    la.setExplicit(true);
    Token t = getToken(1);
    la.setLine(t.beginLine);
    la.setColumn(t.beginColumn);
    la.setLaExpansion(null);
    Container c = new Container();
    boolean commaAtEnd = false, emptyLA = true;
    int laAmount = 0;
    inLocalLA++;
  }
  {
    [
      /*
       * The lookahead of 1 is to turn off the warning message that lets us know that an expansion choice
       * can also start with an integer literal because a primary expression can do the same.
       * But we know that this is what we want.
       */
      LOOKAHEAD(1)
      laAmount = IntegerLiteral()
      {
        emptyLA = false;
        la.setAmount(laAmount);
      }
    ]
    [
      LOOKAHEAD(0, { !emptyLA && (getToken(1).kind != RPAREN) })
      ","
      {
        commaAtEnd = true;
      }
    ]
    [
      LOOKAHEAD(0, { getToken(1).kind != RPAREN && getToken(1).kind != LBRACE })
      ExpansionChoices(c)
      {
        emptyLA = false;
        commaAtEnd = false;
        la.setLaExpansion((Expansion_) c.member);
      }
    ]
    [
      LOOKAHEAD(0, { !emptyLA && !commaAtEnd && (getToken(1).kind != RPAREN) })
      ","
      {
        commaAtEnd = true;
      }
    ]
    [
      LOOKAHEAD(0, { emptyLA || commaAtEnd })
      "{" Expression
      (
        la.getActionTokens()
      )
      "}"
      {
        if (emptyLA)
        {
          la.setAmount(0);
        }
      }
    ]
    {
      inLocalLA--;
      return la;
    }
  }

// ModMMa : changed all expansion_unit into ExpansionUnit to conform to class name convention
void ExpansionUnit(Container c) :
  {
    String name = null;
    List<Token> lhsTokens = new ArrayList<Token>();
    NonTerminal nt = null;
    Action act = null;
    Token t = null;
    Lookahead la = null;
  }
  {
    LOOKAHEAD(1)
    /*
     * We give this priority over primary expressions which use LOOKAHEAD as the name of its identifier */
    t = "LOOKAHEAD" "(" la = LocalLookahead() ")"
    {
      // Now set the la_expansion field of la with a dummy expansion (we use EOF)
      la.setLaExpansion(new REndOfFile());
      // Create a singleton choice with an empty action
      Choice ch = new Choice(t);
      Sequence seq = new Sequence(t, la);
      la.parent = seq;
      la.ordinal = 0;
      act = new Action();
      act.setLine(t.beginLine);
      act.setColumn(t.beginColumn);
      seq.units.add(act);
      act.parent = seq;
      act.ordinal = 1;
      ch.getChoices().add(seq);
      seq.parent = ch;
      seq.ordinal = 0;
      if (la.getAmount() != 0)
      {
        if (la.getActionTokens().size() != 0)
        {
          JavaCCErrors.warning(t, "Encountered LOOKAHEAD(...) at a non-choice location.  Only semantic lookahead will be considered here.");
        }
        else
        {
          JavaCCErrors.warning(t, "Encountered LOOKAHEAD(...) at a non-choice location.  This will be ignored.");
        }
      }
      c.member = ch;
    }
  |
    {
      act = new Action();
      t = getToken(1);
      act.setLine(t.beginLine);
      act.setColumn(t.beginColumn);
      inAction = true;
    }
    Block
    (
      act.getActionTokens()
    )
    {
      inAction = false;
      if (inLocalLA != 0)
      {
        JavaCCErrors.warning(t, "Action within lookahead specification will be ignored.");
      }
      c.member = act;
    }
  | t = "[" ExpansionChoices(c) "]"
    {
      c.member = new ZeroOrOne(t, (Expansion_) c.member);
    }
  | ExpansionUnitTCF(c)
  | LOOKAHEAD(IdentifierAsString() | StringLiteral() | "<" | PrimaryExpression() "=")
    [
      LOOKAHEAD(PrimaryExpression() "=")
      {
        Token first = getToken(1);
      }
      PrimaryExpression()
      {
        Token last = getToken(0);
      }
      "="
      {
        t = first;
        while (true)
        {
          lhsTokens.add(t);
          if (t == last) break;
          t = t.next;
        }
      }
    ]
    (
      // ModMMa 07/2012 : here inside we have IAS | RE instead of RE | IAS in JavaCC1.5.jjt
      // and an extra LOOKAHEAD
      LOOKAHEAD(IdentifierAsString() "(")
      {
        nt = new NonTerminal();
        t = getToken(1);
        nt.setLine(t.beginLine);
        nt.setColumn(t.beginColumn);
        nt.setLhsTokens(lhsTokens);
      }
      name = IdentifierAsString() Arguments(nt.getArgumentTokens())
      {
        nt.setName(name);
        c.member = nt;
      }
      // ModMMa 09/2012 : added for not generating the node creation within the callers (in ExpansionUnit IdentifierAsString)
      [ "!" ]
    | RegularExpression(c)
      {
        ((RegularExpression_) (c.member)).lhsTokens = lhsTokens;
        add_inline_regexpr((RegularExpression_) (c.member));
      }
      [
        "." t = < IDENTIFIER >
        {
          ((RegularExpression_) (c.member)).rhsToken = t;
        }
      ]
      // ModMMa 09/2012 : added for not generating the node creation within the callers (in ExpansionUnit RegularExpression)
      [ "!" ]
    )
  | t = "(" ExpansionChoices(c) ")"
    (
      "+"
      {
        c.member = new OneOrMore(t, (Expansion_) c.member);
      }
    | "*"
      {
        c.member = new ZeroOrMore(t, (Expansion_) c.member);
      }
    | "?"
      {
        c.member = new ZeroOrOne(t, (Expansion_) c.member);
      }
    )?
  }

// ModMMa : added to create a node ; renamed from ExpansionUnitInTCF
void ExpansionUnitTCF(Container c) :
  {
    Token t = null;
  }
  {
    {
      Container expch = new Container();
      List<List<Token>> types = new ArrayList<List<Token>>();
      List<Token> ids = new ArrayList<Token>();
      List<List<Token>> catchblks = new ArrayList<List<Token>>();
      List<Token> finallyblk = null;
      List<Token> vec = new ArrayList<Token>();
      Token t0 = null;
    }
    t0 = "try" "{" ExpansionChoices(expch) "}"
    (
      "catch" "(" Name(vec) t = < IDENTIFIER > ")"
      {
        types.add(vec);
        ids.add(t);
        vec = new ArrayList<Token>();
        inAction = true;
      }
      Block(vec)
      {
        inAction = false;
        catchblks.add(vec);
        vec = new ArrayList<Token>();
      }
    )*
    [
      {
        inAction = true;
      }
      "finally" Block(vec)
      {
        inAction = false;
        finallyblk = vec;
      }
    ]
    {
      makeTryBlock(t0, c, expch, types, ids, catchblks, finallyblk);
    }
  }

// ModMMa : changed all RegularExpression into RegularExpression_ (JavaCC specific class)
// ModMMa : changed all regular_expression into RegularExpression to conform to class name convention
void RegularExpression(Container c) :
  {
    REndOfFile ef = null;
    String image = null;
    boolean private_rexp = false;
    Token t = getToken(1);
  }
  {
    image = StringLiteral()
    {
      c.member = new RStringLiteral(t, image);
    }
  | LOOKAHEAD(3)
    {
      image = "";
    }
    // modified MMa 07/2012 : no definition needed (otherwise it supercedes LT)
    //    < LANGLE : "<" >
    "<"
    [
      [
        "#"
        {
          private_rexp = true;
        }
      ]
      image = IdentifierAsString() ":"
    ]
    ComplexRegularExpressionChoices(c)
    // modified MMa 07/2012 : no definition needed (otherwise it supercedes GT)
    //    < RANGLE : ">" >
    ">"
    {
      RegularExpression_ re = null;
      if (c.member instanceof RJustName)
      {
        RSequence seq = new RSequence();
        seq.units.add((RegularExpression_) c.member);
        re = seq;
      }
      else
      {
        re = (RegularExpression_) c.member;
      }
      re.label = image;
      re.private_rexp = private_rexp;
      re.setLine(t.beginLine);
      re.setColumn(t.beginColumn);
      c.member = re;
    }
  | LOOKAHEAD(2)
    "<"
    image = IdentifierAsString()
    ">"
    {
      c.member = new RJustName(t, image);
    }
  | "<" "EOF" ">"
    {
      ef = new REndOfFile();
      ef.setLine(t.beginLine);
      ef.setColumn(t.beginColumn);
      ef.ordinal = 0;
      c.member = ef;
    }
  }

// ModMMa : changed all complex_regular_expression_choices into ComplexRegularExpressionChoices to conform to class name convention
void ComplexRegularExpressionChoices(Container c1) :
  {
    boolean morethanone = false;
    RChoice ch = new RChoice();
    Container c2 = new Container();
  }
  {
    ComplexRegularExpression(c1)
    (
      "|" ComplexRegularExpression(c2)
      {
        if (morethanone)
        {
          ch.getChoices().add((RegularExpression_) c2.member);
        }
        else
        {
          morethanone = true;
          ch = new RChoice();
          ch.setLine(((RegularExpression_) c1.member).getLine());
          ch.setColumn(((RegularExpression_) c1.member).getColumn());
          ch.getChoices().add((RegularExpression_) c1.member);
          ch.getChoices().add((RegularExpression_) c2.member);
        }
      }
    )*
    {
      if (morethanone)
      {
        c1.member = ch;
      }
    }
  }

// ModMMa : changed all complex_regular_expression into ComplexRegularExpression to conform to class name convention
void ComplexRegularExpression(Container c1) :
  {
    int count = 0;
    RSequence seq = new RSequence();
    Container c2 = new Container();
  }
  {
    (
      ComplexRegularExpressionUnit(c2)
      {
        count++;
        if (count == 1)
        {
          c1.member = c2.member; // if count does not go beyond 1, we are done.
        }
        else if (count == 2)
        { // more than 1, so create a sequence.
          seq = new RSequence();
          seq.setLine(((RegularExpression_) c1.member).getLine());
          seq.setColumn(((RegularExpression_) c1.member).getColumn());
          seq.units.add((RegularExpression_) c1.member);
          seq.units.add((RegularExpression_) c2.member);
        }
        else
        {
          seq.units.add((RegularExpression_) c2.member);
        }
      }
    )+
    {
      if (count > 1)
    {
      c1.member = seq;
    }
  }
}

// ModMMa : changed all complex_regular_expression_unit into ComplexRegularExpressionUnit to conform to class name convention
void ComplexRegularExpressionUnit(Container c) :
{
  String image = null;
  Token t = getToken(1);
  int r1 = 0, r2 =-1;
  boolean hasMax = false;
}
{
  image = StringLiteral()
  {
    c.member = new RStringLiteral(t, image);
  }
| "<" image = IdentifierAsString() ">"
  {
    c.member = new RJustName(t, image);
  }
| CharacterList(c)
| "(" ComplexRegularExpressionChoices(c) ")"
  (
    "+"
    {
      c.member = new ROneOrMore(t, (RegularExpression_) c.member);
    }
  | "*"
    {
      c.member = new RZeroOrMore(t, (RegularExpression_) c.member);
    }
  | "?"
    {
      RZeroOrOne zorexp = new RZeroOrOne();
      zorexp.setLine(t.beginLine);
      zorexp.setColumn(t.beginColumn);
      zorexp.regexpr = (RegularExpression_) c.member;
      c.member = zorexp;
    }
  | "{" r1 = IntegerLiteral()
    [
      ","
      {
        hasMax = true;
      }
      [ r2 = IntegerLiteral() ]
    ]
    "}"
    {
      RRepetitionRange rrrexp = new RRepetitionRange();
      rrrexp.setLine(t.beginLine);
      rrrexp.setColumn(t.beginColumn);
      rrrexp.min = r1;
      rrrexp.max = r2;
      rrrexp.hasMax = hasMax;
      rrrexp.regexpr = (RegularExpression_) c.member;
      c.member = rrrexp;
    }
  )?
}

// ModMMa : changed all character_list into CharacterList to conform to class name convention
void CharacterList(Container c1) :
{
  RCharacterList chlist = new RCharacterList();
  Token t = getToken(1);
  chlist.setLine(t.beginLine);
  chlist.setColumn(t.beginColumn);
  Container c2 = new Container();
}
{
  [
    "~"
    {
      chlist.negated_list = true;
    }
  ]
  "["
  [
    CharacterDescriptor(c2)
    {
      chlist.descriptors.add(c2.member);
    }
    (
      "," CharacterDescriptor(c2)
      {
        chlist.descriptors.add(c2.member);
      }
    )*
  ]
  "]"
  {
    c1.member = chlist;
  }
}

// ModMMa : changed all character_descriptor into CharacterDescriptor to conform to class name convention
void CharacterDescriptor(Container c) :
{
  char c1 = ' ';
  char c2 = ' ';
  boolean isrange = false;
  String imageL = null;
  String imageR = null;
  Token t = getToken(1);
}
{
  imageL = StringLiteral()
  {
    c1 = character_descriptor_assign(getToken(0), imageL);
  }
  [
    "-" imageR = StringLiteral()
    {
      isrange = true;
      c2 = character_descriptor_assign(getToken(0), imageR, imageL);
    }
  ]
  {
    if (isrange)
    {
      CharacterRange cr = new CharacterRange();
      cr.setLine(t.beginLine);
      cr.setColumn(t.beginColumn);
      cr.setLeft(c1);
      cr.setRight(c2);
      c.member = cr;
    }
    else
    {
      SingleCharacter sc = new SingleCharacter();
      sc.setLine(t.beginLine);
      sc.setColumn(t.beginColumn);
      sc.ch = c1;
      c.member = sc;
    }
  }
}

// ModMMa : changed all identifier into Identifier to conform to class name convention
// ModMMa 07/2012 : renamed from Identifier to IdentifierAsString
String IdentifierAsString() :
{
  Token t = null;
}
{
  t = < IDENTIFIER >
  {
    return t.image;
  }
}

/**********************************************
 * THE JAVA GRAMMAR SPECIFICATION STARTS HERE *
 **********************************************/
/*
 * The Java grammar is modified to use sequences of tokens for the missing tokens
 * (those that include "<<" and ">>")
 */
/* Java identifiers and JavaCC reserved words */
// ModMMa 07/2012 : is it useful to return a Token ? Seems not in Name() and BlockStatement()
Token JavaIdentifier() :
{}
{
  (
    < IDENTIFIER >
  // | "options"
  | "LOOKAHEAD"
  | "IGNORE_CASE"
  | "PARSER_BEGIN"
  | "PARSER_END"
  | "JAVACODE"
  | "TOKEN"
  | "SPECIAL_TOKEN"
  | "MORE"
  | "SKIP"
  | "TOKEN_MGR_DECLS"
  | "EOF"
  )
  {
    Token retval = getToken(0);
    retval.kind = IDENTIFIER;
    return retval;
  }
}

void CompilationUnit() :
/* The <EOF> is deleted since the compilation unit is embedded within grammar code */
{
  set_initial_cu_token
  (
    getToken(1)
  )
  ;
}
{
  [
    // ModMMa 07/2012 : fixed grammar
    // LOOKAHEAD((Annotation())* "package")
    PackageDeclaration()
  ]
  (
    ImportDeclaration()
  )*
  (
    TypeDeclaration()
  )*
  {
    insertionpointerrors(getToken(1));
  }
}

void PackageDeclaration() :
{}
{
  // ModMMa 07/2012 : fixed grammar : only at most one Annotation is permitted,
  // and must be in package-info.java, so we should not encounter it in the parsed file
  // Modifiers() "package" Name(null) ";"
  "package" Name(null) ";"
}

void ImportDeclaration() :
{}
{
  "import" [ "static" ] Name(null) [ "." "*" ] ";"
}

/*
 * We match all modifiers in a single rule to reduce the chances of syntax errors
 * for simple modifier mistakes. It will also enable us to give better error messages.
 * Used for class, interface, constant, field, method, constructor & abstract method modifiers,
 * but not for variable modifiers (see VariableModifiers()).
 */
int Modifiers() :
{
  int modifiers = 0;
}
{
  (
    LOOKAHEAD(2)
    (
      "public"
      {
        modifiers |= ModifierSet.M_PUBLIC;
      }
    | "static"
      {
        modifiers |= ModifierSet.M_STATIC;
      }
    | "protected"
      {
        modifiers |= ModifierSet.M_PROTECTED;
      }
    | "private"
      {
        modifiers |= ModifierSet.M_PRIVATE;
      }
    | "final"
      {
        modifiers |= ModifierSet.M_FINAL;
      }
    | "abstract"
      {
        modifiers |= ModifierSet.M_ABSTRACT;
      }
    | "synchronized"
      {
        modifiers |= ModifierSet.M_SYNCHRONIZED;
      }
    | "native"
      {
        modifiers |= ModifierSet.M_NATIVE;
      }
    | "transient"
      {
        modifiers |= ModifierSet.M_TRANSIENT;
      }
    | "volatile"
      {
        modifiers |= ModifierSet.M_VOLATILE;
      }
    | "strictfp"
      {
        modifiers |= ModifierSet.M_STRICTFP;
      }
    | Annotation()
    )
  )*
  {
    return modifiers;
  }
}

void TypeDeclaration() :
{}
{
  ";"
// ModMMa 07/2012 : problem ! Modifiers includes Annotation() which prevents from finding AnnotationTypeDeclaration()
| Modifiers()
  (
    ClassOrInterfaceDeclaration()
  | EnumDeclaration()
  | AnnotationTypeDeclaration()
  )
}

void ClassOrInterfaceDeclaration() :
{
  boolean isInterface = false;
  class_nesting++;
  Token t = null;
  boolean is_parser_class = false;
}
{
  (
    "class"
  | "interface"
    {
      isInterface = true;
    }
  )
  t = < IDENTIFIER > [ TypeParameters() ] [ ExtendsList(isInterface) ] [ ImplementsList(isInterface) ]
  {
    if (t.image.equals(parser_class_name) && class_nesting == 1 && processing_cu)
    {
      is_parser_class = true;
      setinsertionpoint(getToken(1), 1);
    }
  }
  ClassOrInterfaceBody(isInterface, null)
  {
    if (is_parser_class)
    {
      setinsertionpoint(getToken(0), 2);
    }
    class_nesting--;
  }
}

void ExtendsList(boolean isInterface) :
{
  boolean extendsMoreThanOne = false;
}
{
  "extends" ClassOrInterfaceType()
  (
    "," ClassOrInterfaceType()
    {
      extendsMoreThanOne = true;
    }
  )*
  {
    if (extendsMoreThanOne && !isInterface) throw new ParseException("A class cannot extend more than one other class");
  }
}

void ImplementsList(boolean isInterface) :
{}
{
  "implements" ClassOrInterfaceType()
  (
    "," ClassOrInterfaceType()
  )*
  {
    if (isInterface) throw new ParseException("An interface cannot implement other interfaces");
  }
}

void EnumDeclaration() :
{}
{
  "enum" < IDENTIFIER > [ ImplementsList(false) ] EnumBody()
}

void EnumBody() :
{}
{
  "{"
  [
    EnumConstant()
    (
      LOOKAHEAD(2)
      "," EnumConstant()
    )*
  ]
  [ "," ]
  [
    ";"
    (
      ClassOrInterfaceBodyDeclaration(false)
    )*
  ]
  "}"
}

void EnumConstant() :
{}
{
  Modifiers() < IDENTIFIER > [ Arguments(null) ] [ ClassOrInterfaceBody(false, null) ]
}

void TypeParameters() :
{}
{
  "<" TypeParameter()
  (
    "," TypeParameter()
  )*
  ">"
}

void TypeParameter() :
{}
{
  < IDENTIFIER > [ TypeBound() ]
}

void TypeBound() :
{}
{
  "extends" ClassOrInterfaceType()
  (
    "&" ClassOrInterfaceType()
  )*
}

void ClassOrInterfaceBody(boolean isInterface, List<Token> tokens) :
/* Parsing this fills "tokens" with all tokens of the block excluding the braces at each end */
{
  Token first = null;
  Token last = null;
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  "{"
  {
    first = getToken(1);
  }
  (
    ClassOrInterfaceBodyDeclaration(isInterface)
  )*
  {
    last = getToken(0);
  }
  "}"
  {
    if (last.next != first)
    { // i.e., this is not an empty sequence
      Token t = first;
      while (true)
      {
        tokens.add(t);
        if (t == last) break;
        t = t.next;
      }
    }
  }
}

void ClassOrInterfaceBodyDeclaration(boolean isInterface) :
{}
{
  LOOKAHEAD(2)
  Initializer()
  {
    if (isInterface) throw new ParseException("An interface cannot have initializers");
  }
| Modifiers()
  // Just get all the modifiers out of the way.
  // If you want to do more checks, pass the modifiers down to the member
  (
    ClassOrInterfaceDeclaration()
  | EnumDeclaration()
  // ModMMa 11/2014 : added
  | AnnotationTypeDeclaration()
  | LOOKAHEAD([ TypeParameters() ] < IDENTIFIER > "(")
    ConstructorDeclaration()
  | LOOKAHEAD(Type() < IDENTIFIER > ("[" "]")* (","
  | "="
  | ";"))
    FieldDeclaration()
  | MethodDeclaration()
  )
| ";"
}

void FieldDeclaration() :
{}
{
  // Modifiers already matched in the caller
  Type() VariableDeclarator()
  (
    "," VariableDeclarator()
  )*
  ";"
}

void VariableDeclarator() :
{}
{
  VariableDeclaratorId() [ "=" VariableInitializer() ]
}

void VariableDeclaratorId() :
{}
{
  < IDENTIFIER > ("[" "]")*
}

void VariableInitializer() :
{}
{
  ArrayInitializer()
| Expression(null)
}

void ArrayInitializer() :
{}
{
  "{"
  [
    VariableInitializer()
    (
      LOOKAHEAD(2)
      "," VariableInitializer()
    )*
  ]
  [ "," ] "}"
}

void MethodDeclaration() :
{}
{
  // Modifiers already matched in the caller
  [ TypeParameters() ] ResultType(null) MethodDeclarator() [ "throws" NameList() ]
  ( Block(null) | ";" )
}

void MethodDeclarator() :
{}
{
  < IDENTIFIER > FormalParameters(null) ("[" "]")*
}

void FormalParameters(List<Token> tokens) :
/* Parsing this fills "tokens" with all tokens of the formal parameters excluding the parentheses at each end */
{
  Token first = null;
  Token last = null;
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  "("
  {
    first = getToken(1);
  }
  [
    FormalParameter()
    (
      "," FormalParameter()
    )*
  ]
  {
    last = getToken(0);
  }
  ")"
  {
    if (last.next != first)
    { // i.e., this is not an empty sequence
      Token t = first;
      while (true)
      {
        tokens.add(t);
        if (t == last) break;
        t = t.next;
      }
    }
  }
}

void FormalParameter() :
{}
{
  Modifiers() Type() [ "..." ] VariableDeclaratorId()
}

void ConstructorDeclaration() :
{}
{
  // Modifiers already matched in the caller
  [ TypeParameters() ]
  < IDENTIFIER > FormalParameters(null) [ "throws" NameList() ] "{"
  [
    LOOKAHEAD(ExplicitConstructorInvocation())
    ExplicitConstructorInvocation()
  ]
  (
    BlockStatement()
  )*
  "}"
}

void ExplicitConstructorInvocation() :
{}
{
//  // ModMMa 11/2014 : added
//  [ "<" ReferenceType() ("," ReferenceType())* ">" ]
//  // ModMMa 12/2014 : to resolve the conflict with "this" alone in PrimaryPrefix()
//  LOOKAHEAD(3)
//  "this" Arguments(null) ";"
//|
//  [
//    LOOKAHEAD(2)
//    PrimaryExpression() "."
//  ]
//  "super" Arguments(null) ";"
  // MMa 12/2014 : modified to resolve the conflict with "this" alone in PrimaryPrefix()
  (
    LOOKAHEAD(3)
    // MMa 11/2014 : added
    [ "<" ReferenceType() ("," ReferenceType())* ">" ]
    (
      "this" Arguments(null) ";"
    |
      "super" Arguments(null) ";"
    )
  | (
      PrimaryExpression() "."
      "super" Arguments(null) ";"
    )
  )
}

void Initializer() :
{}
{
  [ "static" ] Block(null)
}

void Type() :
{}
{
  LOOKAHEAD(2)
  ReferenceType()
| PrimitiveType()
}

void ReferenceType() :
{}
{
  PrimitiveType()
  (
    LOOKAHEAD(2)
    "[" "]"
  )+
|
  ClassOrInterfaceType()
  (
    LOOKAHEAD(2)
    "[" "]"
  )*
}

void ClassOrInterfaceType() :
{}
{
  < IDENTIFIER >
  [
    LOOKAHEAD(2)
    TypeArguments()
  ]
  (
    LOOKAHEAD(2)
    "." < IDENTIFIER >
    [
      LOOKAHEAD(2)
      TypeArguments()
    ]
  )*
}

void TypeArguments() :
{}
{
  "<" TypeArgument()
  (
    "," TypeArgument()
  )*
  ">"
}

void TypeArgument() :
{}
{
  ReferenceType()
| "?" [ WildcardBounds() ]
}

void WildcardBounds() :
{}
{
  "extends" ReferenceType()
| "super" ReferenceType()
}

void PrimitiveType() :
{}
{
  "boolean"
| "char"
| "byte"
| "short"
| "int"
| "long"
| "float"
| "double"
}

void ResultType(List<Token> tokens) :
{
  Token first = getToken(1);
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  (
    "void"
  | Type()
  )
  {
    Token last = getToken(0);
    Token t = first;
    while (true)
    {
      tokens.add(t);
      if (t == last) break;
      t = t.next;
    }
  }
}

void Name(List<Token> tokens) :
/*
 * A lookahead of 2 is required below since "Name" can be followed
 * by a ".*" when used in the context of an "ImportDeclaration".
 */
{
  if (tokens == null) tokens = new ArrayList<Token>();
  Token first = getToken(1);
}
{
  JavaIdentifier()
  (
    LOOKAHEAD(2)
    "." JavaIdentifier()
  )*
  {
    Token last = getToken(0);
    Token t = first;
    while (true)
    {
      tokens.add(t);
      if (t == last) break;
      t = t.next;
    }
  }
}

void NameList() :
{}
{
  Name(null)
  (
    "," Name(null)
  )*
}

void Expression(List<Token> tokens) :
/*
 * This expansion has been written this way for performance reasons instead of:
 *   Assignment() | ConditionalExpression()
 * However, it is a weakening of the grammar for it allows the LHS of assignments to be
 * any conditional expression whereas it can only be a primary expression.
 * Consider adding a semantic predicate to work around this.
 */
{
  Token first = getToken(1);
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  ConditionalExpression()
  [
    LOOKAHEAD(2)
    AssignmentOperator() Expression(null)
  ]
  {
    Token last = getToken(0);
    Token t = first;
    while (true)
    {
      tokens.add(t);
      if (t == last) break;
      t = t.next;
    }
  }
}

void AssignmentOperator() :
{}
{
  "="
| "*="
| "/="
| "%="
| "+="
| "-="
| "<<="
| ">>="
| ">>>="
| "&="
| "^="
| "|="
}

void ConditionalExpression() :
{}
{
  ConditionalOrExpression() [ "?" Expression(null) ":" Expression(null) ]
}

void ConditionalOrExpression() :
{}
{
  ConditionalAndExpression()
  (
    "||" ConditionalAndExpression()
  )*
}

void ConditionalAndExpression() :
{}
{
  InclusiveOrExpression()
  (
    "&&" InclusiveOrExpression()
  )*
}

void InclusiveOrExpression() :
{}
{
  ExclusiveOrExpression()
  (
    "|" ExclusiveOrExpression()
  )*
}

void ExclusiveOrExpression() :
{}
{
  AndExpression()
  (
    "^" AndExpression()
  )*
}

void AndExpression() :
{}
{
  EqualityExpression()
  (
    "&" EqualityExpression()
  )*
}

void EqualityExpression() :
{}
{
  InstanceOfExpression()
  (
    (
      "=="
    | "!="
    )
    InstanceOfExpression()
  )*
}

void InstanceOfExpression() :
{}
{
  RelationalExpression() [ "instanceof" Type() ]
}

void RelationalExpression() :
{}
{
  ShiftExpression()
  (
    (
      "<"
    | ">"
    | "<="
    | ">="
    )
    ShiftExpression()
  )*
}

void ShiftExpression() :
{}
{
  AdditiveExpression()
  (
    (
      "<<"
      // ModMMa 07/2012 : renamed from RUNSIGNEDSHIFT() and put before RSignedShift
    | RUnsignedShift()
      // ModMMa 07/2012 : renamed from RSIGNEDSHIFT()
    | RSignedShift()
    )
    AdditiveExpression()
  )*
}

/* We use productions to match >>>, >> and > so that we can keep the type declaration syntax with generics clean */
// ModMMa 07/2012 : moved from after TryStatement() and renamed from RSIGNEDSHIFT()
void RSignedShift() :
{}
{
  LOOKAHEAD({ getToken(1).kind == GT && ((Token.GTToken) getToken(1)).realKind == RSIGNEDSHIFT })
  // modified MMa 07/2012 : '">" ">"' changed to '">>"' ?
  ">>"
}

// ModMMa 07/2012 : moved from after TryStatement() and renamed from RUNSIGNEDSHIFT()
void RUnsignedShift() :
{}
{
  LOOKAHEAD({ getToken(1).kind == GT && ((Token.GTToken) getToken(1)).realKind == RUNSIGNEDSHIFT })
  // modified MMa 07/2012 : '">" ">" ">"' changed to '"> >>"' ?
  ">>>"
}

void AdditiveExpression() :
{}
{
  MultiplicativeExpression()
  (
    (
      "+"
    | "-"
    )
    MultiplicativeExpression()
  )*
}

void MultiplicativeExpression() :
{}
{
  UnaryExpression()
  (
    (
      "*"
    | "/"
    | "%"
    )
    UnaryExpression()
  )*
}

void UnaryExpression() :
{}
{
  (
    "+"
  | "-"
  )
  UnaryExpression()
| PreIncrementExpression()
| PreDecrementExpression()
| UnaryExpressionNotPlusMinus()
}

void PreIncrementExpression() :
{}
{
  "++" PrimaryExpression()
}

void PreDecrementExpression() :
{}
{
  "--" PrimaryExpression()
}

void UnaryExpressionNotPlusMinus() :
{}
{
  (
    "~"
  | "!"
  )
  UnaryExpression()
| LOOKAHEAD(CastLookahead())
  CastExpression()
| PostfixExpression()
}

/*
 * This production is to determine lookahead only.
 * The LOOKAHEAD specifications below are not used, but they are there just to indicate that we know about this.
 */
void CastLookahead() :
{}
{
  LOOKAHEAD(2)
  "(" PrimitiveType()
| LOOKAHEAD("(" Type() "[")
  "(" Type() "[" "]"
| "(" Type() ")"
  (
    "~"
  | "!"
  | "("
  | < IDENTIFIER >
  | "this"
  | "super"
  | "new"
  | Literal()
  )
}

void PostfixExpression() :
{}
{
  PrimaryExpression()
  [
    "++"
  | "--"
  ]
}

void CastExpression() :
{}
{
  LOOKAHEAD("(" PrimitiveType())
  "(" Type() ")" UnaryExpression()
| "(" Type() ")" UnaryExpressionNotPlusMinus()
}

void PrimaryExpression() :
{}
{
  PrimaryPrefix()
  (
    LOOKAHEAD(2)
    PrimarySuffix()
  )*
}

void MemberSelector() :
{}
{
  "." TypeArguments() < IDENTIFIER >
}

void PrimaryPrefix() :
{}
{
  Literal()
| "this"
| "super" "." < IDENTIFIER >
| "(" Expression(null) ")"
| AllocationExpression()
| LOOKAHEAD(ResultType(null) "." "class")
  ResultType(null) "." "class"
| Name(null)
}

void PrimarySuffix() :
{}
{
  LOOKAHEAD(2)
  "." "this"
| LOOKAHEAD(2)
  "." AllocationExpression()
| LOOKAHEAD(3)
  MemberSelector()
| "[" Expression(null) "]"
| "." < IDENTIFIER >
| Arguments(null)
}

void Literal() :
{}
{
  < INTEGER_LITERAL >
| < FLOATING_POINT_LITERAL >
| < CHARACTER_LITERAL >
| < STRING_LITERAL >
| BooleanLiteral()
| NullLiteral()
}

int IntegerLiteral() :
{}
{
  < INTEGER_LITERAL >
  {
    try
    {
      return Integer.parseInt(token.image);
    }
    catch (NumberFormatException e)
    {
      throw new Error();
    }
  }
}

boolean BooleanLiteral() :
{}
{
  "true"
  {
    return true;
  }
| "false"
  {
    return false;
  }
}

String StringLiteral() :
{
  Token t = null;
  ;
}
{
  t = < STRING_LITERAL >
  {
    return remove_escapes_and_quotes(t, t.image);
  }
}

void NullLiteral() :
{}
{
  "null"
}

void Arguments(List<Token> tokens) :
/* Parsing this fills "tokens" with all tokens of the arguments excluding the parentheses at each end */
{
  Token first = null;
  Token last = null;
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  "("
  {
    first = getToken(1);
  }
  [ ArgumentList() ]
  {
    last = getToken(0);
  }
  ")"
  {
    if (last.next != first)
    { // i.e., this is not an empty sequence
      Token t = first;
      while (true)
      {
        tokens.add(t);
        if (t == last) break;
        t = t.next;
      }
    }
  }
}

void ArgumentList() :
{}
{
  Expression(null)
  (
    "," Expression(null)
  )*
}

void AllocationExpression() :
{}
{
  LOOKAHEAD(2)
  "new" PrimitiveType() ArrayDimsAndInits()
| "new" ClassOrInterfaceType() [ TypeArguments() ]
  (
    ArrayDimsAndInits()
  | Arguments(null) [ ClassOrInterfaceBody(false, null) ]
  )
}

/*
 * The third LOOKAHEAD specification below is to parse to PrimarySuffix
 * if there is an expression between the "[...]"
 */
void ArrayDimsAndInits() :
{}
{
  LOOKAHEAD(2)
  (
    LOOKAHEAD(2)
    "[" Expression(null) "]"
  )+
  (
    LOOKAHEAD(2)
    "[" "]"
  )*
| ("[" "]")+ ArrayInitializer()
}

void Statement() :
{}
{
  LOOKAHEAD(2)
  LabeledStatement()
| AssertStatement()
| Block(null)
| EmptyStatement()
| StatementExpression() ";"
| SwitchStatement()
| IfStatement()
| WhileStatement()
| DoStatement()
| ForStatement()
| BreakStatement()
| ContinueStatement()
| ReturnStatement()
| ThrowStatement()
| SynchronizedStatement()
| TryStatement()
}

void AssertStatement() :
{}
{
  "assert" Expression(null) [ ":" Expression(null) ] ";"
}

void LabeledStatement() :
{}
{
  < IDENTIFIER > ":" Statement()
}

void Block(List<Token> tokens) :
/* Parsing this fills "tokens" with all tokens of the block excluding the braces at each end */
{
  Token first = null;
  Token last = null;
  if (tokens == null) tokens = new ArrayList<Token>();
}
{
  "{"
  {
    first = getToken(1);
  }
  (
    BlockStatement()
  )*
  {
    last = getToken(0);
  }
  "}"
  {
    if (last.next != first)
    { // i.e., this is not an empty sequence
      Token t = first;
      while (true)
      {
        tokens.add(t);
        if (t == last) break;
        t = t.next;
      }
    }
  }
}

void BlockStatement() :
{}
{
  // modified MMa 07/2012
  //  LOOKAHEAD(Modifiers() Type() JavaIdentifier())
  LOOKAHEAD(VariableModifiers() Type() JavaIdentifier())
  LocalVariableDeclaration() ";"
| Statement()
| ClassOrInterfaceDeclaration()
}

void LocalVariableDeclaration() :
{}
{
  // modified MMa 06/2012
  //  Modifiers() Type() VariableDeclarator()
  VariableModifiers() Type() VariableDeclarator()
  (
    "," VariableDeclarator()
  )*
}

// added MMa 06/2012
void VariableModifiers() :
{}
{
  (
    LOOKAHEAD(2)
    (
      "final"
    | Annotation()
    )
  )*
}

void EmptyStatement() :
{}
{
  ";"
}

void StatementExpression() :
/*
 * The last expansion of this production accepts more than the legal Java expansions for StatementExpression.
 * This expansion does not use PostfixExpression for performance reasons.
 */
{}
{
  PreIncrementExpression()
| PreDecrementExpression()
| PrimaryExpression()
  [
    "++"
  | "--"
  | AssignmentOperator() Expression(null)
  ]
}

void SwitchStatement() :
{}
{
  "switch" "(" Expression(null) ")" "{"
  (
    SwitchLabel()
    (
      BlockStatement()
    )*
  )*
  "}"
}

void SwitchLabel() :
{}
{
  "case" Expression(null) ":"
| "default" ":"
}

void IfStatement() :
/*
 * The disambiguating algorithm of JavaCC automatically binds dangling else's to the innermost if statement.
 * The LOOKAHEAD specification is to tell JavaCC that we know what we are doing.
 */
{}
{
  "if" "(" Expression(null) ")" Statement()
  [
    LOOKAHEAD(1)
    "else" Statement()
  ]
}

void WhileStatement() :
{}
{
  "while" "(" Expression(null) ")" Statement()
}

void DoStatement() :
{}
{
  "do" Statement() "while" "(" Expression(null) ")" ";"
}

void ForStatement() :
{}
{
  "for" "("
  (
    // modified MMa : fixed grammar
    // LOOKAHEAD(Modifiers() Type() < IDENTIFIER > ":")
    // Modifiers() Type() < IDENTIFIER > ":" Expression(null)
    LOOKAHEAD(VariableModifiers() Type() < IDENTIFIER > ":")
    VariableModifiers() Type() < IDENTIFIER > ":" Expression(null)
  | [ ForInit() ] ";" [ Expression(null) ] ";" [ ForUpdate() ]
  )
  ")" Statement()
}

void ForInit() :
{}
{
  // modified MMa : fixed grammar
  // LOOKAHEAD(Modifiers() Type() < IDENTIFIER >)
  LOOKAHEAD(VariableModifiers() Type() < IDENTIFIER >)
  LocalVariableDeclaration()
| StatementExpressionList()
}

void StatementExpressionList() :
{}
{
  StatementExpression()
  (
    "," StatementExpression()
  )*
}

void ForUpdate() :
{}
{
  StatementExpressionList()
}

void BreakStatement() :
{}
{
  "break" [ < IDENTIFIER > ] ";"
}

void ContinueStatement() :
{}
{
  "continue" [ < IDENTIFIER > ] ";"
}

void ReturnStatement() :
{
  Token t = null;
}
{
  t = "return"
  {
    // Add if statement to prevent subsequent code generated from being dead code
    if (inAction)
    {
      t.image = "{if (true) return";
      jumpPatched = true;
    }
  }
  [ Expression(null) ] t = ";"
  {
    // Add closing brace for above if statement
    if (inAction)
    {
      t.image = ";}";
    }
  }
}

void ThrowStatement() :
{
  Token t = null;
}
{
  t = "throw"
  {
    // Add if statement to prevent subsequent code generated from being dead code
    if (inAction)
    {
      t.image = "{if (true) throw";
      jumpPatched = true;
    }
  }
  Expression(null) t = ";"
  {
    // Add closing brace for above if statement
    if (inAction)
    {
      t.image = ";}";
    }
  }
}

void SynchronizedStatement() :
{}
{
  "synchronized" "(" Expression(null) ")" Block(null)
}

void TryStatement() :
/* Semantic check required here to make sure that at least one finally/catch is present */
{}
{
  "try" Block(null)
  (
    "catch" "(" FormalParameter() ")" Block(null)
  )*
  [ "finally" Block(null) ]
}

void Annotation() :
{}
{
  // ModMMa 09/2012 : fixed (added parentheses)
  LOOKAHEAD("@" Name(null) "(" (< IDENTIFIER > "=" | ")"))
  NormalAnnotation()
| LOOKAHEAD("@" Name(null) "(")
  SingleMemberAnnotation()
| MarkerAnnotation()
}

void NormalAnnotation() :
{}
{
  "@" Name(null) "(" [ MemberValuePairs() ] ")"
}

void MarkerAnnotation() :
{}
{
  "@" Name(null)
}

void SingleMemberAnnotation() :
{}
{
  "@" Name(null) "(" MemberValue() ")"
}

void MemberValuePairs() :
{}
{
  MemberValuePair()
  (
    "," MemberValuePair()
  )*
}

void MemberValuePair() :
{}
{
  < IDENTIFIER > "=" MemberValue()
}

void MemberValue() :
{}
{
  Annotation()
| MemberValueArrayInitializer()
| ConditionalExpression()
}

void MemberValueArrayInitializer() :
{}
{
  "{" MemberValue()
  (
    LOOKAHEAD(2)
    "," MemberValue()
  )*
  [ "," ] "}"
}

void AnnotationTypeDeclaration() :
{}
{
  "@" "interface" < IDENTIFIER > AnnotationTypeBody()
}

void AnnotationTypeBody() :
{}
{
  "{"
  (
    AnnotationTypeMemberDeclaration()
  )*
  "}"
}

void AnnotationTypeMemberDeclaration() :
{}
{
  Modifiers()
  (
    LOOKAHEAD(Type() < IDENTIFIER > "(")
    Type() < IDENTIFIER > "(" ")" [ DefaultValue() ] ";"
  | ClassOrInterfaceDeclaration()
  | EnumDeclaration()
  | AnnotationTypeDeclaration()
  | FieldDeclaration()
  )
| ";"
}

void DefaultValue() :
{}
{
  "default" MemberValue()
}

/* IDENTIFIERS */
TOKEN :
{
  < IDENTIFIER: <LETTER> (<PART_LETTER>)* >
|
  < #LETTER:
      [  // all chars for which Character.isIdentifierStart is true
         "$",
         "A"-"Z",
         "_",
         "a"-"z",
         "\u00a2"-"\u00a5",
         "\u00aa",
         "\u00b5",
         "\u00ba",
         "\u00c0"-"\u00d6",
         "\u00d8"-"\u00f6",
         "\u00f8"-"\u021f",
         "\u0222"-"\u0233",
         "\u0250"-"\u02ad",
         "\u02b0"-"\u02b8",
         "\u02bb"-"\u02c1",
         "\u02d0"-"\u02d1",
         "\u02e0"-"\u02e4",
         "\u02ee",
         "\u037a",
         "\u0386",
         "\u0388"-"\u038a",
         "\u038c",
         "\u038e"-"\u03a1",
         "\u03a3"-"\u03ce",
         "\u03d0"-"\u03d7",
         "\u03da"-"\u03f3",
         "\u0400"-"\u0481",
         "\u048c"-"\u04c4",
         "\u04c7"-"\u04c8",
         "\u04cb"-"\u04cc",
         "\u04d0"-"\u04f5",
         "\u04f8"-"\u04f9",
         "\u0531"-"\u0556",
         "\u0559",
         "\u0561"-"\u0587",
         "\u05d0"-"\u05ea",
         "\u05f0"-"\u05f2",
         "\u0621"-"\u063a",
         "\u0640"-"\u064a",
         "\u0671"-"\u06d3",
         "\u06d5",
         "\u06e5"-"\u06e6",
         "\u06fa"-"\u06fc",
         "\u0710",
         "\u0712"-"\u072c",
         "\u0780"-"\u07a5",
         "\u0905"-"\u0939",
         "\u093d",
         "\u0950",
         "\u0958"-"\u0961",
         "\u0985"-"\u098c",
         "\u098f"-"\u0990",
         "\u0993"-"\u09a8",
         "\u09aa"-"\u09b0",
         "\u09b2",
         "\u09b6"-"\u09b9",
         "\u09dc"-"\u09dd",
         "\u09df"-"\u09e1",
         "\u09f0"-"\u09f3",
         "\u0a05"-"\u0a0a",
         "\u0a0f"-"\u0a10",
         "\u0a13"-"\u0a28",
         "\u0a2a"-"\u0a30",
         "\u0a32"-"\u0a33",
         "\u0a35"-"\u0a36",
         "\u0a38"-"\u0a39",
         "\u0a59"-"\u0a5c",
         "\u0a5e",
         "\u0a72"-"\u0a74",
         "\u0a85"-"\u0a8b",
         "\u0a8d",
         "\u0a8f"-"\u0a91",
         "\u0a93"-"\u0aa8",
         "\u0aaa"-"\u0ab0",
         "\u0ab2"-"\u0ab3",
         "\u0ab5"-"\u0ab9",
         "\u0abd",
         "\u0ad0",
         "\u0ae0",
         "\u0b05"-"\u0b0c",
         "\u0b0f"-"\u0b10",
         "\u0b13"-"\u0b28",
         "\u0b2a"-"\u0b30",
         "\u0b32"-"\u0b33",
         "\u0b36"-"\u0b39",
         "\u0b3d",
         "\u0b5c"-"\u0b5d",
         "\u0b5f"-"\u0b61",
         "\u0b85"-"\u0b8a",
         "\u0b8e"-"\u0b90",
         "\u0b92"-"\u0b95",
         "\u0b99"-"\u0b9a",
         "\u0b9c",
         "\u0b9e"-"\u0b9f",
         "\u0ba3"-"\u0ba4",
         "\u0ba8"-"\u0baa",
         "\u0bae"-"\u0bb5",
         "\u0bb7"-"\u0bb9",
         "\u0c05"-"\u0c0c",
         "\u0c0e"-"\u0c10",
         "\u0c12"-"\u0c28",
         "\u0c2a"-"\u0c33",
         "\u0c35"-"\u0c39",
         "\u0c60"-"\u0c61",
         "\u0c85"-"\u0c8c",
         "\u0c8e"-"\u0c90",
         "\u0c92"-"\u0ca8",
         "\u0caa"-"\u0cb3",
         "\u0cb5"-"\u0cb9",
         "\u0cde",
         "\u0ce0"-"\u0ce1",
         "\u0d05"-"\u0d0c",
         "\u0d0e"-"\u0d10",
         "\u0d12"-"\u0d28",
         "\u0d2a"-"\u0d39",
         "\u0d60"-"\u0d61",
         "\u0d85"-"\u0d96",
         "\u0d9a"-"\u0db1",
         "\u0db3"-"\u0dbb",
         "\u0dbd",
         "\u0dc0"-"\u0dc6",
         "\u0e01"-"\u0e30",
         "\u0e32"-"\u0e33",
         "\u0e3f"-"\u0e46",
         "\u0e81"-"\u0e82",
         "\u0e84",
         "\u0e87"-"\u0e88",
         "\u0e8a",
         "\u0e8d",
         "\u0e94"-"\u0e97",
         "\u0e99"-"\u0e9f",
         "\u0ea1"-"\u0ea3",
         "\u0ea5",
         "\u0ea7",
         "\u0eaa"-"\u0eab",
         "\u0ead"-"\u0eb0",
         "\u0eb2"-"\u0eb3",
         "\u0ebd",
         "\u0ec0"-"\u0ec4",
         "\u0ec6",
         "\u0edc"-"\u0edd",
         "\u0f00",
         "\u0f40"-"\u0f47",
         "\u0f49"-"\u0f6a",
         "\u0f88"-"\u0f8b",
         "\u1000"-"\u1021",
         "\u1023"-"\u1027",
         "\u1029"-"\u102a",
         "\u1050"-"\u1055",
         "\u10a0"-"\u10c5",
         "\u10d0"-"\u10f6",
         "\u1100"-"\u1159",
         "\u115f"-"\u11a2",
         "\u11a8"-"\u11f9",
         "\u1200"-"\u1206",
         "\u1208"-"\u1246",
         "\u1248",
         "\u124a"-"\u124d",
         "\u1250"-"\u1256",
         "\u1258",
         "\u125a"-"\u125d",
         "\u1260"-"\u1286",
         "\u1288",
         "\u128a"-"\u128d",
         "\u1290"-"\u12ae",
         "\u12b0",
         "\u12b2"-"\u12b5",
         "\u12b8"-"\u12be",
         "\u12c0",
         "\u12c2"-"\u12c5",
         "\u12c8"-"\u12ce",
         "\u12d0"-"\u12d6",
         "\u12d8"-"\u12ee",
         "\u12f0"-"\u130e",
         "\u1310",
         "\u1312"-"\u1315",
         "\u1318"-"\u131e",
         "\u1320"-"\u1346",
         "\u1348"-"\u135a",
         "\u13a0"-"\u13f4",
         "\u1401"-"\u166c",
         "\u166f"-"\u1676",
         "\u1681"-"\u169a",
         "\u16a0"-"\u16ea",
         "\u1780"-"\u17b3",
         "\u17db",
         "\u1820"-"\u1877",
         "\u1880"-"\u18a8",
         "\u1e00"-"\u1e9b",
         "\u1ea0"-"\u1ef9",
         "\u1f00"-"\u1f15",
         "\u1f18"-"\u1f1d",
         "\u1f20"-"\u1f45",
         "\u1f48"-"\u1f4d",
         "\u1f50"-"\u1f57",
         "\u1f59",
         "\u1f5b",
         "\u1f5d",
         "\u1f5f"-"\u1f7d",
         "\u1f80"-"\u1fb4",
         "\u1fb6"-"\u1fbc",
         "\u1fbe",
         "\u1fc2"-"\u1fc4",
         "\u1fc6"-"\u1fcc",
         "\u1fd0"-"\u1fd3",
         "\u1fd6"-"\u1fdb",
         "\u1fe0"-"\u1fec",
         "\u1ff2"-"\u1ff4",
         "\u1ff6"-"\u1ffc",
         "\u203f"-"\u2040",
         "\u207f",
         "\u20a0"-"\u20af",
         "\u2102",
         "\u2107",
         "\u210a"-"\u2113",
         "\u2115",
         "\u2119"-"\u211d",
         "\u2124",
         "\u2126",
         "\u2128",
         "\u212a"-"\u212d",
         "\u212f"-"\u2131",
         "\u2133"-"\u2139",
         "\u2160"-"\u2183",
         "\u3005"-"\u3007",
         "\u3021"-"\u3029",
         "\u3031"-"\u3035",
         "\u3038"-"\u303a",
         "\u3041"-"\u3094",
         "\u309d"-"\u309e",
         "\u30a1"-"\u30fe",
         "\u3105"-"\u312c",
         "\u3131"-"\u318e",
         "\u31a0"-"\u31b7",
         "\u3400"-"\u4db5",
         "\u4e00"-"\u9fa5",
         "\ua000"-"\ua48c",
         "\uac00"-"\ud7a3",
         "\uf900"-"\ufa2d",
         "\ufb00"-"\ufb06",
         "\ufb13"-"\ufb17",
         "\ufb1d",
         "\ufb1f"-"\ufb28",
         "\ufb2a"-"\ufb36",
         "\ufb38"-"\ufb3c",
         "\ufb3e",
         "\ufb40"-"\ufb41",
         "\ufb43"-"\ufb44",
         "\ufb46"-"\ufbb1",
         "\ufbd3"-"\ufd3d",
         "\ufd50"-"\ufd8f",
         "\ufd92"-"\ufdc7",
         "\ufdf0"-"\ufdfb",
         "\ufe33"-"\ufe34",
         "\ufe4d"-"\ufe4f",
         "\ufe69",
         "\ufe70"-"\ufe72",
         "\ufe74",
         "\ufe76"-"\ufefc",
         "\uff04",
         "\uff21"-"\uff3a",
         "\uff3f",
         "\uff41"-"\uff5a",
         "\uff65"-"\uffbe",
         "\uffc2"-"\uffc7",
         "\uffca"-"\uffcf",
         "\uffd2"-"\uffd7",
         "\uffda"-"\uffdc",
         "\uffe0"-"\uffe1",
         "\uffe5"-"\uffe6"
      ]
  >
|
  < #PART_LETTER:
      [  // all chars for which Character.isIdentifierPart is true
         "\u0000"-"\u0008",
         "\u000e"-"\u001b",
         "$",
         "0"-"9",
         "A"-"Z",
         "_",
         "a"-"z",
         "\u007f"-"\u009f",
         "\u00a2"-"\u00a5",
         "\u00aa",
         "\u00b5",
         "\u00ba",
         "\u00c0"-"\u00d6",
         "\u00d8"-"\u00f6",
         "\u00f8"-"\u021f",
         "\u0222"-"\u0233",
         "\u0250"-"\u02ad",
         "\u02b0"-"\u02b8",
         "\u02bb"-"\u02c1",
         "\u02d0"-"\u02d1",
         "\u02e0"-"\u02e4",
         "\u02ee",
         "\u0300"-"\u034e",
         "\u0360"-"\u0362",
         "\u037a",
         "\u0386",
         "\u0388"-"\u038a",
         "\u038c",
         "\u038e"-"\u03a1",
         "\u03a3"-"\u03ce",
         "\u03d0"-"\u03d7",
         "\u03da"-"\u03f3",
         "\u0400"-"\u0481",
         "\u0483"-"\u0486",
         "\u048c"-"\u04c4",
         "\u04c7"-"\u04c8",
         "\u04cb"-"\u04cc",
         "\u04d0"-"\u04f5",
         "\u04f8"-"\u04f9",
         "\u0531"-"\u0556",
         "\u0559",
         "\u0561"-"\u0587",
         "\u0591"-"\u05a1",
         "\u05a3"-"\u05b9",
         "\u05bb"-"\u05bd",
         "\u05bf",
         "\u05c1"-"\u05c2",
         "\u05c4",
         "\u05d0"-"\u05ea",
         "\u05f0"-"\u05f2",
         "\u0621"-"\u063a",
         "\u0640"-"\u0655",
         "\u0660"-"\u0669",
         "\u0670"-"\u06d3",
         "\u06d5"-"\u06dc",
         "\u06df"-"\u06e8",
         "\u06ea"-"\u06ed",
         "\u06f0"-"\u06fc",
         "\u070f"-"\u072c",
         "\u0730"-"\u074a",
         "\u0780"-"\u07b0",
         "\u0901"-"\u0903",
         "\u0905"-"\u0939",
         "\u093c"-"\u094d",
         "\u0950"-"\u0954",
         "\u0958"-"\u0963",
         "\u0966"-"\u096f",
         "\u0981"-"\u0983",
         "\u0985"-"\u098c",
         "\u098f"-"\u0990",
         "\u0993"-"\u09a8",
         "\u09aa"-"\u09b0",
         "\u09b2",
         "\u09b6"-"\u09b9",
         "\u09bc",
         "\u09be"-"\u09c4",
         "\u09c7"-"\u09c8",
         "\u09cb"-"\u09cd",
         "\u09d7",
         "\u09dc"-"\u09dd",
         "\u09df"-"\u09e3",
         "\u09e6"-"\u09f3",
         "\u0a02",
         "\u0a05"-"\u0a0a",
         "\u0a0f"-"\u0a10",
         "\u0a13"-"\u0a28",
         "\u0a2a"-"\u0a30",
         "\u0a32"-"\u0a33",
         "\u0a35"-"\u0a36",
         "\u0a38"-"\u0a39",
         "\u0a3c",
         "\u0a3e"-"\u0a42",
         "\u0a47"-"\u0a48",
         "\u0a4b"-"\u0a4d",
         "\u0a59"-"\u0a5c",
         "\u0a5e",
         "\u0a66"-"\u0a74",
         "\u0a81"-"\u0a83",
         "\u0a85"-"\u0a8b",
         "\u0a8d",
         "\u0a8f"-"\u0a91",
         "\u0a93"-"\u0aa8",
         "\u0aaa"-"\u0ab0",
         "\u0ab2"-"\u0ab3",
         "\u0ab5"-"\u0ab9",
         "\u0abc"-"\u0ac5",
         "\u0ac7"-"\u0ac9",
         "\u0acb"-"\u0acd",
         "\u0ad0",
         "\u0ae0",
         "\u0ae6"-"\u0aef",
         "\u0b01"-"\u0b03",
         "\u0b05"-"\u0b0c",
         "\u0b0f"-"\u0b10",
         "\u0b13"-"\u0b28",
         "\u0b2a"-"\u0b30",
         "\u0b32"-"\u0b33",
         "\u0b36"-"\u0b39",
         "\u0b3c"-"\u0b43",
         "\u0b47"-"\u0b48",
         "\u0b4b"-"\u0b4d",
         "\u0b56"-"\u0b57",
         "\u0b5c"-"\u0b5d",
         "\u0b5f"-"\u0b61",
         "\u0b66"-"\u0b6f",
         "\u0b82"-"\u0b83",
         "\u0b85"-"\u0b8a",
         "\u0b8e"-"\u0b90",
         "\u0b92"-"\u0b95",
         "\u0b99"-"\u0b9a",
         "\u0b9c",
         "\u0b9e"-"\u0b9f",
         "\u0ba3"-"\u0ba4",
         "\u0ba8"-"\u0baa",
         "\u0bae"-"\u0bb5",
         "\u0bb7"-"\u0bb9",
         "\u0bbe"-"\u0bc2",
         "\u0bc6"-"\u0bc8",
         "\u0bca"-"\u0bcd",
         "\u0bd7",
         "\u0be7"-"\u0bef",
         "\u0c01"-"\u0c03",
         "\u0c05"-"\u0c0c",
         "\u0c0e"-"\u0c10",
         "\u0c12"-"\u0c28",
         "\u0c2a"-"\u0c33",
         "\u0c35"-"\u0c39",
         "\u0c3e"-"\u0c44",
         "\u0c46"-"\u0c48",
         "\u0c4a"-"\u0c4d",
         "\u0c55"-"\u0c56",
         "\u0c60"-"\u0c61",
         "\u0c66"-"\u0c6f",
         "\u0c82"-"\u0c83",
         "\u0c85"-"\u0c8c",
         "\u0c8e"-"\u0c90",
         "\u0c92"-"\u0ca8",
         "\u0caa"-"\u0cb3",
         "\u0cb5"-"\u0cb9",
         "\u0cbe"-"\u0cc4",
         "\u0cc6"-"\u0cc8",
         "\u0cca"-"\u0ccd",
         "\u0cd5"-"\u0cd6",
         "\u0cde",
         "\u0ce0"-"\u0ce1",
         "\u0ce6"-"\u0cef",
         "\u0d02"-"\u0d03",
         "\u0d05"-"\u0d0c",
         "\u0d0e"-"\u0d10",
         "\u0d12"-"\u0d28",
         "\u0d2a"-"\u0d39",
         "\u0d3e"-"\u0d43",
         "\u0d46"-"\u0d48",
         "\u0d4a"-"\u0d4d",
         "\u0d57",
         "\u0d60"-"\u0d61",
         "\u0d66"-"\u0d6f",
         "\u0d82"-"\u0d83",
         "\u0d85"-"\u0d96",
         "\u0d9a"-"\u0db1",
         "\u0db3"-"\u0dbb",
         "\u0dbd",
         "\u0dc0"-"\u0dc6",
         "\u0dca",
         "\u0dcf"-"\u0dd4",
         "\u0dd6",
         "\u0dd8"-"\u0ddf",
         "\u0df2"-"\u0df3",
         "\u0e01"-"\u0e3a",
         "\u0e3f"-"\u0e4e",
         "\u0e50"-"\u0e59",
         "\u0e81"-"\u0e82",
         "\u0e84",
         "\u0e87"-"\u0e88",
         "\u0e8a",
         "\u0e8d",
         "\u0e94"-"\u0e97",
         "\u0e99"-"\u0e9f",
         "\u0ea1"-"\u0ea3",
         "\u0ea5",
         "\u0ea7",
         "\u0eaa"-"\u0eab",
         "\u0ead"-"\u0eb9",
         "\u0ebb"-"\u0ebd",
         "\u0ec0"-"\u0ec4",
         "\u0ec6",
         "\u0ec8"-"\u0ecd",
         "\u0ed0"-"\u0ed9",
         "\u0edc"-"\u0edd",
         "\u0f00",
         "\u0f18"-"\u0f19",
         "\u0f20"-"\u0f29",
         "\u0f35",
         "\u0f37",
         "\u0f39",
         "\u0f3e"-"\u0f47",
         "\u0f49"-"\u0f6a",
         "\u0f71"-"\u0f84",
         "\u0f86"-"\u0f8b",
         "\u0f90"-"\u0f97",
         "\u0f99"-"\u0fbc",
         "\u0fc6",
         "\u1000"-"\u1021",
         "\u1023"-"\u1027",
         "\u1029"-"\u102a",
         "\u102c"-"\u1032",
         "\u1036"-"\u1039",
         "\u1040"-"\u1049",
         "\u1050"-"\u1059",
         "\u10a0"-"\u10c5",
         "\u10d0"-"\u10f6",
         "\u1100"-"\u1159",
         "\u115f"-"\u11a2",
         "\u11a8"-"\u11f9",
         "\u1200"-"\u1206",
         "\u1208"-"\u1246",
         "\u1248",
         "\u124a"-"\u124d",
         "\u1250"-"\u1256",
         "\u1258",
         "\u125a"-"\u125d",
         "\u1260"-"\u1286",
         "\u1288",
         "\u128a"-"\u128d",
         "\u1290"-"\u12ae",
         "\u12b0",
         "\u12b2"-"\u12b5",
         "\u12b8"-"\u12be",
         "\u12c0",
         "\u12c2"-"\u12c5",
         "\u12c8"-"\u12ce",
         "\u12d0"-"\u12d6",
         "\u12d8"-"\u12ee",
         "\u12f0"-"\u130e",
         "\u1310",
         "\u1312"-"\u1315",
         "\u1318"-"\u131e",
         "\u1320"-"\u1346",
         "\u1348"-"\u135a",
         "\u1369"-"\u1371",
         "\u13a0"-"\u13f4",
         "\u1401"-"\u166c",
         "\u166f"-"\u1676",
         "\u1681"-"\u169a",
         "\u16a0"-"\u16ea",
         "\u1780"-"\u17d3",
         "\u17db",
         "\u17e0"-"\u17e9",
         "\u180b"-"\u180e",
         "\u1810"-"\u1819",
         "\u1820"-"\u1877",
         "\u1880"-"\u18a9",
         "\u1e00"-"\u1e9b",
         "\u1ea0"-"\u1ef9",
         "\u1f00"-"\u1f15",
         "\u1f18"-"\u1f1d",
         "\u1f20"-"\u1f45",
         "\u1f48"-"\u1f4d",
         "\u1f50"-"\u1f57",
         "\u1f59",
         "\u1f5b",
         "\u1f5d",
         "\u1f5f"-"\u1f7d",
         "\u1f80"-"\u1fb4",
         "\u1fb6"-"\u1fbc",
         "\u1fbe",
         "\u1fc2"-"\u1fc4",
         "\u1fc6"-"\u1fcc",
         "\u1fd0"-"\u1fd3",
         "\u1fd6"-"\u1fdb",
         "\u1fe0"-"\u1fec",
         "\u1ff2"-"\u1ff4",
         "\u1ff6"-"\u1ffc",
         "\u200c"-"\u200f",
         "\u202a"-"\u202e",
         "\u203f"-"\u2040",
         "\u206a"-"\u206f",
         "\u207f",
         "\u20a0"-"\u20af",
         "\u20d0"-"\u20dc",
         "\u20e1",
         "\u2102",
         "\u2107",
         "\u210a"-"\u2113",
         "\u2115",
         "\u2119"-"\u211d",
         "\u2124",
         "\u2126",
         "\u2128",
         "\u212a"-"\u212d",
         "\u212f"-"\u2131",
         "\u2133"-"\u2139",
         "\u2160"-"\u2183",
         "\u3005"-"\u3007",
         "\u3021"-"\u302f",
         "\u3031"-"\u3035",
         "\u3038"-"\u303a",
         "\u3041"-"\u3094",
         "\u3099"-"\u309a",
         "\u309d"-"\u309e",
         "\u30a1"-"\u30fe",
         "\u3105"-"\u312c",
         "\u3131"-"\u318e",
         "\u31a0"-"\u31b7",
         "\u3400"-"\u4db5",
         "\u4e00"-"\u9fa5",
         "\ua000"-"\ua48c",
         "\uac00"-"\ud7a3",
         "\uf900"-"\ufa2d",
         "\ufb00"-"\ufb06",
         "\ufb13"-"\ufb17",
         "\ufb1d"-"\ufb28",
         "\ufb2a"-"\ufb36",
         "\ufb38"-"\ufb3c",
         "\ufb3e",
         "\ufb40"-"\ufb41",
         "\ufb43"-"\ufb44",
         "\ufb46"-"\ufbb1",
         "\ufbd3"-"\ufd3d",
         "\ufd50"-"\ufd8f",
         "\ufd92"-"\ufdc7",
         "\ufdf0"-"\ufdfb",
         "\ufe20"-"\ufe23",
         "\ufe33"-"\ufe34",
         "\ufe4d"-"\ufe4f",
         "\ufe69",
         "\ufe70"-"\ufe72",
         "\ufe74",
         "\ufe76"-"\ufefc",
         "\ufeff",
         "\uff04",
         "\uff10"-"\uff19",
         "\uff21"-"\uff3a",
         "\uff3f",
         "\uff41"-"\uff5a",
         "\uff65"-"\uffbe",
         "\uffc2"-"\uffc7",
         "\uffca"-"\uffcf",
         "\uffd2"-"\uffd7",
         "\uffda"-"\uffdc",
         "\uffe0"-"\uffe1",
         "\uffe5"-"\uffe6",
         "\ufff9"-"\ufffb"
      ]
  >
}
