/**
 *
 * 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.
 *
 *
 * Changes applied to this grammar are for the JavaNCSS
 * application: http://www.kclee.com/clemens/java/javancss/
 * Author: Chr. Clemens Lee, 2000-01-31
 * Additional counting of javadoc comments done by
 *    Emilio Gongora, <emilio@sms.nl> and
 *    Guillermo Rodriguez, <guille@sms.nl>.
 * Anonymous class count patch by Vesa Karvonnen, <vesa_karvonen@hotmail.com> 2002-10-30.
 */

options {
  JAVA_UNICODE_ESCAPE = true;
  STATIC = false;
  /* // DEBUG MODE
  DEBUG_PARSER = true;
  // */
}

PARSER_BEGIN(JavaParser)

package net.sourceforge.cobertura.javancss.parser;

import java.util.*;

import net.sourceforge.cobertura.javancss.ccl.Util;

import net.sourceforge.cobertura.javancss.FunctionMetric;
import net.sourceforge.cobertura.javancss.ObjectMetric;
import net.sourceforge.cobertura.javancss.PackageMetric;

/**
 * Java source code parser based on a grammar compiled by
 * JavaCC from Java1.1.jj to the JavaParser class.<p>
 *
 * This class is responsible for parsing Java code and counting
 * all metrics during this parsing process.
 * The rest of the application is only responsible for invoking
 * this parser in a convenient way and to present the results
 * to the user.<p>
 *
 * This grammar is based on the Java grammar that comes as an
 * example with JavaCC, but has been extended to collect the
 * metrics data (and adapted to support real life and jdk 1.4
 * Java sources as well).
 *
 * @author    Sriram Sankar (original JavaCC grammar)
 *            , Chr. Clemens Lee <clemens@kclee.com> (JavaNCSS metrics)
 *            , additional counting of javadoc comments done by
 *              Emilio Gongora, <emilio@sms.nl> and
 *              Guillermo Rodriguez, <guille@sms.nl>.
 *            Anonymous class count patch by Vesa Karvonnen, <vesa_karvonen@hotmail.com> 2002-10-30.
 * @version   2000-01-31 $Id: Java1.1.jj 193 2009-06-12 13:35:12Z reynaud_seb $
 */
public class JavaParser implements JavaParserInterface
{
    {
        /* // DEBUG MODE
        Util.setDebug( true );
        // */
    }
    private boolean _bReturn         = false;
    private int     _ncss            = 0;     // general counter
    private int     _loc             = 0;
    private int     _cyc             = 1;
    private int     _localCases      = 0;
    private String  _sName           = "";    // name of last token
    private String  _sParameter      = "";
    private String  _sPackage        = "";
    private String  _sClass          = "";
    private String  _sFunction       = "";
    private int     _functions       = 0;     // number of functions in this class
    //private int     _topLevelClasses = 0;
    private int     _classes         = 0;
    private int     _classLevel      = 0;
    private int     _anonClassCount  = 1;

    private int     _jvdcLines = 0;           // added by SMS
    private int     _jvdc      = 0;
    private boolean _bPrivate  = true;//false;        // added by SMS
    private boolean _bPublic   = true;        // added by SMS

    private int	_nbligne = 0; //Added by REYNAUD Sebastien (LOGICA)

    /**
     * For each class the number of formal
     * comments in toplevel methods, constructors, inner
     * classes, and for the class itself are counted.
     * The top level comment has to be directly before
     * the class definition, not before the package or
     * import statement as it is often seen in source code
     * examples (at the beginning of your source files you
     * should instead put your copyright notice).
     */
    private int    _javadocs   = 0;              // global javadocs
    private List/*<FunctionMetric>*/ _vFunctions = new ArrayList();   // holds the statistics for each method

    /**
     * Metrics for each class/interface are stored in this
     * vector.
     */
    private List/*<ObjectMetric>*/ _vClasses = new ArrayList();
    private List _vImports = new ArrayList();
    private Object[] _aoPackage = null;
    private Map/*<String,PackageMetric>*/ _htPackage = new HashMap();
    private PackageMetric _pPackageMetric;

    private Token _tmpToken = null;
    /** Argh, too much of a state machine. */
    private Token _tmpResultToken = null;

    private String _formatPackage(String sPackage_) {
        if (sPackage_.equals("")) {
            return ".";
        }

        return sPackage_.substring(0, sPackage_.length() - 1);
    }

    public void parse() throws Exception {
      CompilationUnit();
    }

    public void parseImportUnit() throws Exception {
      ImportUnit();
    }

    public int getNcss() {
        return _ncss;
    }

    public int getLOC() {
        return _loc;
    }

    // added by SMS
    public int getJvdc() {
        return _jvdc;
    }

    /*public int getTopLevelClasses() {
      return _topLevelClasses;
      }*/

    public List/*<FunctionMetric>*/ getFunction() {
        return _vFunctions;
    }

    /**
     * @return Top level classes in sorted order
     */
    public List/*<ObjectMetric>*/ getObject() {
        Collections.sort(_vClasses);
        return _vClasses;
    }

    /**
     * @return The empty package consists of the name ".".
     */
    public Map/*<String,PackageMetric>*/ getPackage() {
        return _htPackage;
    }

    public List getImports() {
        return _vImports;
    }

    /**
     * name, beginLine, ...
     */
    public Object[] getPackageObjects() {
        return _aoPackage;
    }

    /**
     * if javancss is used with cat *.java a long
     * input stream might get generated, so line
     * number information in case of an parse exception
     * is not very useful.
     */
    public String getLastFunction() {
        return _sPackage + _sClass + _sFunction;
    }

   /**
    * Class to hold modifiers.
    */
   static public final class ModifierSet
   {
     /* Definitions of the bits in the modifiers field.  */
     public static final int PUBLIC = 0x0001;
     public static final int PROTECTED = 0x0002;
     public static final int PRIVATE = 0x0004;
     public static final int ABSTRACT = 0x0008;
     public static final int STATIC = 0x0010;
     public static final int FINAL = 0x0020;
     public static final int SYNCHRONIZED = 0x0040;
     public static final int NATIVE = 0x0080;
     public static final int TRANSIENT = 0x0100;
     public static final int VOLATILE = 0x0200;
     public static final int STRICTFP = 0x1000;

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

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

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

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

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

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

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

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

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

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

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

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

     /**
      * Removes the given modifier.
      */
     static int removeModifier(int modifiers, int mod)
     {
        return modifiers & ~mod;
     }
   }
}

PARSER_END(JavaParser)

TOKEN_MGR_DECLS :
{
    // added by SMS

    public static int  _iSingleComments = 0;
    public static int  _iMultiComments = 0;
    public static int  _iFormalComments = 0;

    public static int  _iMultiCommentsLast = 0;

    public static int nbligne = 1; //Added by REYNAUD Sebastien (LOGICA)
}

/* WHITE SPACE */

SKIP :
{
  " "
| "\t"
| "\n" /*Added by REYNAUD Sebastien (LOGICA)*/ {nbligne++;} //
| "\r" /*Added by REYNAUD Sebastien (LOGICA)*/ {nbligne++;} //
| "\f"
| "\u001a"
| "\r\n" {nbligne++;} //Added by REYNAUD Sebastien (LOGICA)
}

/* COMMENTS */

MORE :
{
   //   "//" : IN_SINGLE_LINE_COMMENT
   //|
    //  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
    //|
  "/*" { _iMultiCommentsLast = 0; } : IN_MULTI_LINE_COMMENT     // MODIFIED by SMS
}

SPECIAL_TOKEN :
{
   <SINGLE_LINE_COMMENT: "//"> { _iSingleComments++; } : IN_SINGLE_LINE_COMMENT       // MODIFIED by SMS:  the global counter is incremented
}

<IN_SINGLE_LINE_COMMENT>
SPECIAL_TOKEN :
{
    <SINGLE_LINE_COMMENT2: (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> /*Added by REYNAUD Sebastien (LOGICA)*/ {nbligne++;} /* */: DEFAULT
}

//<IN_SINGLE_LINE_COMMENT>
//SPECIAL_TOKEN :
//{
//   <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
   //<SINGLE_LINE_COMMENT: (~["\n", "\r"])* ("\n" | "\r" | "\r\n")? >
   /*"\n" : DEFAULT
      | "\r" : DEFAULT
      | "\r\n" : DEFAULT
      | <~[]>*/
//}

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

<IN_MULTI_LINE_COMMENT>
SPECIAL_TOKEN :
{
  <END_OF_LINE_MULTI: "\n" | "\r" | "\r\n" > {/*Added by REYNAUD Sebastien (LOGICA)*/ nbligne++; /* */ _iMultiComments++; _iMultiCommentsLast++; } : IN_MULTI_LINE_COMMENT      // added by SMS
  | <MULTI_LINE_COMMENT: "*/" > { _iMultiComments++; _iMultiCommentsLast++; } : DEFAULT                                 // the global counter is incremented
}

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

/* 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" >
| < 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" >
| < PACKAGE: "package">
| < PRIVATE: "private" >
| < PROTECTED: "protected" >
| < PUBLIC: "public" >
| < RETURN: "return" >
| < SHORT: "short" >
| < STATIC: "static" >
| < TESTAAAA: "strictfp" > // STRICTFP lets the linux jdk1.1 compiler fail
| < SUPER: "super" >
| < SWITCH: "switch" >
| < SYNCHRONIZED: "synchronized" >
| < THIS: "this" >
| < THROW: "throw" >
| < THROWS: "throws" >
| < TRANSIENT: "transient" >
| < TRUE: "true" >
| < TRY: "try" >
| < VOID: "void" >
| < VOLATILE: "volatile" >
| < WHILE: "while" >
}

/* LITERALS */

TOKEN :
{
  < INTEGER_LITERAL:
        <DECIMAL_LITERAL> (["l","L"])?
      | <HEX_LITERAL> (["l","L"])?
      | <OCTAL_LITERAL> (["l","L"])?
  >
|
  < #DECIMAL_LITERAL: ["1"-"9"] (["_", "0"-"9"])* >
|
  < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
|
  < #OCTAL_LITERAL: "0" (["0"-"7"])* >
|
  < FLOATING_POINT_LITERAL:
        (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
      | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
      | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
      | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
  >
|
  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
  < CHARACTER_LITERAL:
      "'"
                                         // "\r" eigendlich noch dazu, aber wegen bug
                                         // in java/text/TextBoundaryData.java
                                         // in zeile 55 columne 12 und zeile 69
                                         // columne 12 hier entfernt.
                                         // (   (~["'","\\","\n","\r"])
      (   (~["\\","\n"])
        | ("\\"
            ( ["n","t","b","r","f","\\","'","\""]
            | ["0"-"7"] ( ["0"-"7"] )?
            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
            )
          )
      )
      "'"
  >
|
  < STRING_LITERAL:
      "\""
      (   (~["\"","\\","\n","\r"])
        | ("\\"
            ( ["n","t","b","r","f","\\","'","\""]
            | ["0"-"7"] ( ["0"-"7"] )?
            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
            )
          )
      )*
      "\""
  >
}

/* IDENTIFIERS */

TOKEN :
{
  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
|
  < #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"
      ]
  >
|
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\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"
      ]
  >
}

/* SEPARATORS */

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

/* OPERATORS */

TOKEN :
{
  < ASSIGN: "=" >
| < 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: ">>" > //Removed by REYNAUD Sebastien (LOGICA)

// | < RUNSIGNEDSHIFT: ">>>" > //Removed by REYNAUD Sebastien (LOGICA)

| < PLUSASSIGN: "+=" >
| < MINUSASSIGN: "-=" >
| < STARASSIGN: "*=" >
| < SLASHASSIGN: "/=" >
| < ANDASSIGN: "&=" >
| < ORASSIGN: "|=" >
| < XORASSIGN: "^=" >
| < REMASSIGN: "%=" >
| < LSHIFTASSIGN: "<<=" >
| < RSIGNEDSHIFTASSIGN: ">>=" >
| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
| < ELLIPSIS: "..." >
}


/*****************************************
 * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
 *****************************************/

/*
 * Program structuring syntax follows.
 */

void CompilationUnit() :
{
    int oldNcss = 0;

    // added by SMS
    int oldFormal = 0;
    int oldSingle = 0;
    int oldMulti  = 0;

    JavaParserTokenManager._iSingleComments = 0;
    JavaParserTokenManager._iMultiComments = 0;
    JavaParserTokenManager._iFormalComments = 0;

    JavaParserTokenManager._iMultiCommentsLast = 0;

    _bPrivate = true;//false;

	JavaParserTokenManager.nbligne = 1; //Added by REYNAUD Sebastien (LOGICA)
}
{
        {
                _sPackage = "";
                _pPackageMetric = new PackageMetric();      // this object manages the metrics
        }
  [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ]
  ( ImportDeclaration() )*
  ( TypeDeclaration()
    //{ System.out.println( "Token: " + getToken( 0 ) ); }
    )*
         {
             // Package classes and functions are set inside
             // class and interface bodies.
             _pPackageMetric.ncss = _ncss;

             // added by SMS
             _pPackageMetric.javadocsLn = JavaParserTokenManager._iFormalComments;
             _pPackageMetric.singleLn   = JavaParserTokenManager._iSingleComments;
             _pPackageMetric.multiLn    = JavaParserTokenManager._iMultiComments;
             //

             _htPackage.put(_formatPackage(_sPackage),
                            _pPackageMetric);
         }
  (
  {
      oldNcss = _ncss;
      _sPackage = "";
      _pPackageMetric = new PackageMetric();

      // added by SMS
      oldFormal = JavaParserTokenManager._iFormalComments;
      oldSingle = JavaParserTokenManager._iSingleComments;
      oldMulti  = JavaParserTokenManager._iMultiComments;
  }
  (PackageDeclaration()
   |
   ( ImportDeclaration() )
   )
  ( ImportDeclaration() )*
  ( TypeDeclaration() )+
  {
      // Package classes and functions are set inside
      // class and interface bodies.
      _pPackageMetric.ncss = _ncss - oldNcss;

      // added by SMS
      _pPackageMetric.javadocsLn = JavaParserTokenManager._iFormalComments - oldFormal;
      _pPackageMetric.singleLn   = JavaParserTokenManager._iSingleComments - oldSingle;
      _pPackageMetric.multiLn    = JavaParserTokenManager._iMultiComments  - oldMulti;
      //

      PackageMetric pckmPrevious = (PackageMetric)_htPackage.
             get(_formatPackage(_sPackage));
      _pPackageMetric.add(pckmPrevious);
      _htPackage.put(_formatPackage(_sPackage),
                     _pPackageMetric);
  }
  )*
  <EOF>
         {
             Token pToken = getToken(1);
             _loc = pToken.endLine;
	     _nbligne = JavaParserTokenManager.nbligne; //Added by REYNAUD Sebastien (LOGICA)
         }
}

void ImportUnit() :
{
}
{
  [ PackageDeclaration() ]
  ( ImportDeclaration() )*
  ( "abstract" | "final" | "public" | "synchronized" | "strictfp" )*
  ( "class" | "interface" )
}

void PackageDeclaration() :
{
    int beginLine = 1;
    int beginColumn = 1;
}
{
    (Annotation())*
  "package"
  {
      _anonClassCount = 1;

      Token pToken = getToken( 0 );
      beginLine = pToken.beginLine ;
      beginColumn = pToken.beginColumn;
      _aoPackage = new Object[ 5 ];
  }
  Name()
  {
      _aoPackage[ 0 ] = _sName;
      _aoPackage[ 1 ] = new Integer( beginLine );
      _aoPackage[ 2 ] = new Integer( beginColumn );
  }
  ";"
  {
      _aoPackage[ 3 ] = new Integer( getToken( 0 ).endLine );
      _aoPackage[ 4 ] = new Integer( getToken( 0 ).endColumn );
      _ncss++;
      Util.debug( "_ncss++" );
      _sPackage = _sName + ".";
  }
}

void ImportDeclaration() :
{
    int beginLine = 1;
    int beginColumn = 1;
    Object[] aoImport = null;
}
{
  "import"
  {
      Token pToken = getToken( 0 );
      beginLine = pToken.beginLine ;
      beginColumn = pToken.beginColumn;
  }
[ "static" ]
  Name()
  {
      aoImport = new Object[ 5 ];
      aoImport[ 0 ] = _sName;
      aoImport[ 1 ] = new Integer( beginLine );
      aoImport[ 2 ] = new Integer( beginColumn );
  }
  [ "." "*" { aoImport[ 0 ] = aoImport[ 0 ].toString() + ".*"; } ] ";"
  {
      aoImport[ 3 ] = new Integer( getToken( 0 ).endLine );
      aoImport[ 4 ] = new Integer( getToken( 0 ).endColumn );
      _vImports.add( aoImport );
      _ncss++;
      Util.debug( "_ncss++" );
  }
}

void TypeDeclaration() :
{
   int modifiers;
}
{
  LOOKAHEAD( (Annotation())* ( "abstract" | "final" | "public" | "synchronized" | "strictfp" )* "class" )

	//(Annotation())*	//Removed by REYNAUD Sebastien (LOGICA)

  ClassDeclaration()
|
  LOOKAHEAD( modifiers = Modifiers()
                 "enum" <IDENTIFIER>
             //EnumDeclaration(modifiers)
             )
  modifiers = Modifiers()
  EnumDeclaration(modifiers)
|
         LOOKAHEAD( Modifiers() "interface" )

	//(Annotation())*	//Removed by REYNAUD Sebastien (LOGICA)

  InterfaceDeclaration()
   |
  modifiers = Modifiers()
     AnnotationTypeDeclaration(modifiers)
|
  ";"
}


/*
 * Declaration syntax follows.
 */

void ClassDeclaration() :
{
    Token tmpToken = null;
    _javadocs = 0;
    ObjectMetric metric = null;

    // added by SMS
    int oldSingle = 0;
    int oldMulti  = 0;

    _jvdcLines    = 0;
    boolean bTemp = _bPublic;
    _bPublic      = false;
    //

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken = null;
	//
}
{
	//Added by REYNAUD Sebastien (LOGICA)
	(
	{myToken = getToken(1);}
	Annotation()
	{tmpToken = myToken;}
	)?

	(Annotation())*
	//

  ( "abstract"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "final"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "public"
  {
      _bPublic = true;         // added by SMS
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "synchronized"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "strictfp"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 )*
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 1 );
      }
  }

  // added by SMS
  {
      while( tmpToken.specialToken != null ) {
          if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
              _javadocs++;
              Util.debug( "ClassDeclaration()._javadocs++" );
              if (_bPublic || _bPrivate) {
                  Util.debug( "_jvdc++" );
                  _jvdc++;
                  _jvdcLines += JavaParserTokenManager._iMultiCommentsLast;
                  JavaParserTokenManager._iFormalComments += JavaParserTokenManager._iMultiCommentsLast;
              }
              JavaParserTokenManager._iMultiComments -= JavaParserTokenManager._iMultiCommentsLast;
              break;
          }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
              break;
          }

          //System.out.println("\n"+tmpToken.specialToken.image);

          tmpToken = tmpToken.specialToken;
      }

      oldSingle = JavaParserTokenManager._iSingleComments;
      oldMulti = JavaParserTokenManager._iMultiComments;
  }

  UnmodifiedClassDeclaration()
         {
             /* removed by SMS
             while( tmpToken.specialToken != null ) {
                 if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                     _javadocs++;
                 }
                 tmpToken = tmpToken.specialToken;
             }
             */
             metric = (ObjectMetric)_vClasses.get( _vClasses.size() - 1);
             metric.javadocs = _javadocs;

             // added by SMS
             metric.javadocsLn = _jvdcLines;
             metric.singleLn = JavaParserTokenManager._iSingleComments - oldSingle;
             metric.multiLn = JavaParserTokenManager._iMultiComments - oldMulti;
             //

            // added by SMS
            _bPublic = bTemp;
         }
}

void UnmodifiedClassDeclaration() :
{
        String sOldClass = _sClass;
        int oldNcss = _ncss;
        int oldFunctions = _functions;
        int oldClasses = _classes;
	
	//Added by REYNAUD Sebastien (LOGICA)
	ObjectMetric metric = new ObjectMetric();
	if (_classLevel == 0) {
		//metric.firstLine = JavaParserTokenManager.nbligne;
	}
	//
}
{
        {
                if (!_sClass.equals("")) {
                        _sClass += ".";
                }
                _sClass += getToken(2).image;
                _classLevel ++;
        }
        Modifiers()
  "class" Identifier() [TypeParameters()] [ "extends" Name() [TypeArguments()] /*Added by REYNAUD Sebastien (LOGICA)*/ ("." Name() [TypeArguments()] )* /**/ ] [ "implements" NameList() ]
  ClassBody()
        {
                _ncss++;
                Util.debug( "_ncss++" );
                _classLevel--;
                if (_classLevel == 0) {
                        //_topLevelClasses++;

                        //ObjectMetric metric = new ObjectMetric(); //Removed by REYNAUD Sebastien (LOGICA)

                        metric.name = _sPackage + _sClass;
                        metric.ncss = _ncss - oldNcss;
                        metric.functions = _functions - oldFunctions;
                        metric.classes = _classes - oldClasses;
                        Token lastToken = getToken( 0 );
                        //metric.add( new Integer( lastToken.endLine ) );
                        //metric.add( new Integer( lastToken.endColumn ) );
                        //metric.add( new Integer( _javadocs ) );
                        _vClasses.add( metric );
                        _pPackageMetric.functions += _functions - oldFunctions;
                        _pPackageMetric.classes++;

                        // added by SMS
                        _pPackageMetric.javadocs += _javadocs;
                        //_pPackageMetric.javadocsLn += JavaParserTokenManager._iFormalComments - oldFormal;
                        //_pPackageMetric.singleLn += JavaParserTokenManager._iSingleComments - oldSingle;
                        //_pPackageMetric.multiLn += JavaParserTokenManager._iMultiComments - oldMulti;
                        //
                }

                _functions = oldFunctions;
                _classes = oldClasses + 1;
                _sClass = sOldClass;
        }
}

void ClassBody() :
{}
{
  "{" ( ClassBodyDeclaration() )* "}"
}

void NestedClassDeclaration() :

{
    // added by SMS
    Token tmpToken = null;

    boolean bTemp = _bPublic;
    _bPublic = false;
    boolean bPublic = false;

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken = null;
	//
}
{
	//Added by REYNAUD Sebastien (LOGICA)
	(
	{myToken = getToken(1);}
	Annotation()
	{tmpToken = myToken;}
	)?

	(Annotation())*

	{
	if(tmpToken==null)
	{
		tmpToken = getToken( 1 );
	}
	}
	//

  ( "static" | "abstract" | "final"
  | "public" { bPublic = true; }        // added by SMS
  | "protected" { bPublic = true; }     // added by SMS
  | "private" | "strictfp" )*


  // added by SMS
  {

			//tmpToken = getToken( 0 );//Removed by REYNAUD Sebastien (LOGICA)

                while( tmpToken.specialToken != null ) {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                        _javadocs++;
                        Util.debug( "NestedClassDeclaration()._javadocs++" );
                        if ((_bPublic && bPublic) || _bPrivate) {
                            Util.debug( "_jvdc++" );
                            _jvdc++;
                            _jvdcLines += JavaParserTokenManager._iMultiCommentsLast;
                            JavaParserTokenManager._iFormalComments += JavaParserTokenManager._iMultiCommentsLast;
                        }
                        JavaParserTokenManager._iMultiComments -= JavaParserTokenManager._iMultiCommentsLast;
                        break;
                    }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
                        break;
                    }

                    //System.out.println("\n"+tmpToken.specialToken.image);

                    tmpToken = tmpToken.specialToken;
                }
    }

  UnmodifiedClassDeclaration()
  {
       //added by SMS
      _bPublic = bTemp;
  }
}

void ClassBodyDeclaration() :
{
    int modifiers;
}
{
  EmptyStatement()
|
  LOOKAHEAD(2)
  Initializer()

//Added by REYNAUD Sebastien (LOGICA)
|
  LOOKAHEAD((Annotation())* ( "static" | "abstract" | "final" | "public" | "protected" | "private" | "strictfp" )*  "@" "interface")
  modifiers = Modifiers()
  AnnotationTypeDeclaration(modifiers)
|
  LOOKAHEAD((Annotation())* "@" "interface")
  CreationAnnotation()
//

|
  LOOKAHEAD( (Annotation())* ( "static" | "abstract" | "final" | "public" | "protected" | "private" | "strictfp" )* "class" )

	//(Annotation())*	//Removed by REYNAUD Sebastien (LOGICA)

  NestedClassDeclaration()
|
  LOOKAHEAD( Modifiers() "interface" )
  //LOOKAHEAD( ( "static" | "abstract" | "final" | "public" | "protected" | "private" | "strictfp" )* "interface" )
  modifiers = Modifiers()
  NestedInterfaceDeclaration()
  |
   LOOKAHEAD( Modifiers() "enum" )
   modifiers = Modifiers()
   EnumDeclaration(modifiers)
|
         //LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" )
         LOOKAHEAD( (Annotation())* [ "public" | "protected" | "private" ] [ TypeParameters() ] Name() "(" )
         //{ System.out.println( "\n\nClassDeclaration\n" ); }

	//(Annotation())* //Removed by REYNAUD Sebastien (LOGICA)

  ConstructorDeclaration()
|
  LOOKAHEAD( MethodDeclarationLookahead() )
         //{ System.out.println( "\n\nMethodDeclaration\n" ); }
  MethodDeclaration()
|
  (Annotation())* FieldDeclaration()
}

// This production is to determine lookahead only.
void MethodDeclarationLookahead() :
{}
{
    ( Annotation() )*
    ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" | "strictfp" )*
    ( Annotation() )*
  [ TypeParameters() ]
  ResultType() Identifier() "("
}

void InterfaceDeclaration() :
{
        Token tmpToken = null;
        _javadocs = 0;
        //boolean bClassComment = false;
        ObjectMetric metric = null;

        // added by SMS
        int oldSingle;
        int oldMulti;

        _jvdcLines = 0;
        boolean bTemp = _bPublic;
        _bPublic = false;
        //

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken=null;
	//
}
{
	//Added by REYNAUD Sebastien (LOGICA)
	(
	{myToken = getToken(1);}
	Annotation()
	{tmpToken = myToken;}
	)?

	(Annotation())*
	//

  ( "strictfp" | "abstract"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "public"
  {
      _bPublic = true;         // added by SMS
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 )*
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 1 );
      }
  }


  // added by SMS
  // added by SMS
  {
                while( tmpToken.specialToken != null ) {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                        _javadocs++;
                        Util.debug( "InterfaceDeclaration()._javadocs++" );
                        if (_bPublic || _bPrivate) {
                            Util.debug( "_jvdc++" );
                            _jvdc++;
                            _jvdcLines += JavaParserTokenManager._iMultiCommentsLast;
                            JavaParserTokenManager._iFormalComments += JavaParserTokenManager._iMultiCommentsLast;
                        }
                        JavaParserTokenManager._iMultiComments -= JavaParserTokenManager._iMultiCommentsLast;
                        break;
                    }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
                        break;
                    }

                    //System.out.println("\n"+tmpToken.specialToken.image);

                    tmpToken = tmpToken.specialToken;
                }

                oldSingle = JavaParserTokenManager._iSingleComments;
                oldMulti = JavaParserTokenManager._iMultiComments;
    }

  UnmodifiedInterfaceDeclaration()
         {
             /* removed by SMS
             while( tmpToken.specialToken != null ) {
                 if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                     _javadocs++;
                     bClassComment = true;
                 }
                 tmpToken = tmpToken.specialToken;
                 }*/
             metric = (ObjectMetric)_vClasses.get( _vClasses.size() - 1 );
             metric.javadocs = _javadocs;

             // added by SMS
             metric.javadocsLn = _jvdcLines;
             metric.singleLn = JavaParserTokenManager._iSingleComments - oldSingle;
             metric.multiLn = JavaParserTokenManager._iMultiComments - oldMulti;
             //

            // added by SMS
            _bPublic = bTemp;
         }
}

void NestedInterfaceDeclaration() :

{
    // added by SMS
    Token tmpToken = null;

    boolean bTemp = _bPublic;
    _bPublic = false;
    boolean bPublic = false;

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken=null;
	//

}
{
	//Added by REYNAUD Sebastien (LOGICA)
	(
	{myToken = getToken(1);}
	Annotation()
	{tmpToken = myToken;}
	)?

	(Annotation())*
	{
	if(tmpToken==null)
	{
		tmpToken = getToken( 1 );
	}
	}
	//


  ( "static" | "abstract" | "final"
  | "public" { bPublic = true; }        // added by SMS
  | "protected" { bPublic = true; }     // added by SMS
  | "private" | "strictfp" )*

  // added by SMS
  {

			//tmpToken = getToken( 0 );	//Removed by REYNAUD Sebastien (LOGICA)

                while( tmpToken.specialToken != null ) {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                        _javadocs++;
                        if ((_bPublic && bPublic) || _bPrivate) {
                            Util.debug( "_jvdc++" );
                            _jvdc++;
                            _jvdcLines += JavaParserTokenManager._iMultiCommentsLast;
                            JavaParserTokenManager._iFormalComments += JavaParserTokenManager._iMultiCommentsLast;
                        }
                        JavaParserTokenManager._iMultiComments -= JavaParserTokenManager._iMultiCommentsLast;
                        break;
                    }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
                        break;
                    }

                    //System.out.println("\n"+tmpToken.specialToken.image);

                    tmpToken = tmpToken.specialToken;
                }

    }

  UnmodifiedInterfaceDeclaration()

  {
      // added by SMS
      _bPublic = bTemp;
  }
}

void UnmodifiedInterfaceDeclaration() :
{
        String sOldClass = _sClass;
        int oldNcss = _ncss;
        int oldFunctions = _functions;
        int oldClasses = _classes;


		//Added by REYNAUD Sebastien (LOGICA)
	 	ObjectMetric metric = new ObjectMetric();
	 	//metric.firstLine = JavaParserTokenManager.nbligne;
		//
}
{
        {
                if (!_sClass.equals("")) {
                        _sClass += ".";
                }
                _sClass += getToken(2).image;
                _classLevel ++;
        }
  "interface" Identifier() [TypeParameters()] [ "extends" NameList() ]
  "{" ( InterfaceMemberDeclaration() )* "}"
        {
                _ncss++;
                Util.debug( "_ncss++" );
                _classLevel--;
                if (_classLevel == 0)
                {
                        //_topLevelClasses++;

                        //ObjectMetric metric = new ObjectMetric(); //Removed by REYNAUD Sebastien (LOGICA)

                        metric.name = _sPackage + _sClass;
                        metric.ncss = _ncss - oldNcss;
                        metric.functions = _functions - oldFunctions;
                        metric.classes = _classes - oldClasses;
                        //metric.add( Util.getConstantObject() );
                        //metric.add( Util.getConstantObject() );
                        _vClasses.add( metric );
                        _pPackageMetric.functions += _functions - oldFunctions;
                        _pPackageMetric.classes++;

                        // added by SMS
                        _pPackageMetric.javadocs += _javadocs;
                        //_pPackageMetric.javadocsLn += JavaParserTokenManager._iFormalComments - oldFormal;
                        //_pPackageMetric.singleLn += JavaParserTokenManager._iSingleComments - oldSingle;
                        //_pPackageMetric.multiLn += JavaParserTokenManager._iMultiComments - oldMulti;
                        //
                }

                _functions = oldFunctions;
                _classes = oldClasses + 1;
                _sClass = sOldClass;
        }
}

void InterfaceMemberDeclaration() :
{
   int modifiers;
}
{
  EmptyStatement()
|
  LOOKAHEAD( /* Added by REYNAUD Sebastien (LOGICA) */ (Annotation())* /**/ ( "static" | "abstract" | "final" | "public" | "protected" | "private" | "strictfp" )* "class" )
  NestedClassDeclaration()
|
  LOOKAHEAD( /* Added by REYNAUD Sebastien (LOGICA) */ (Annotation())* /**/ ( "static" | "abstract" | "final" | "public" | "protected" | "private" | "strictfp" )* "interface" )
  NestedInterfaceDeclaration()
  |
  LOOKAHEAD( modifiers = Modifiers()
                 "enum" <IDENTIFIER>
             //EnumDeclaration(modifiers)
             )
   modifiers = Modifiers()
   EnumDeclaration(modifiers)
|
  LOOKAHEAD( MethodDeclarationLookahead() )
  MethodDeclaration()
|
  modifiers = Modifiers()
  FieldDeclaration()
}

void FieldDeclaration() :
{
    // added by SMS
    Token tmpToken = null;
    boolean bPublic = false;
}
{
  ( "public" { bPublic = true; }        // added by SMS
  | "protected" { bPublic = true; }     // added by SMS
  | "private" | "static" | "final" | "transient" | "volatile" )*

  // added by SMS
  {             tmpToken = getToken( 0 );

                while( tmpToken.specialToken != null )
                {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) )
                    {
                        if ((bPublic && _bPublic) || _bPrivate)
                        {
                            //_javadocs++;
                            Util.debug( "_jvdc++" );
                            _jvdc++;
                            _jvdcLines += JavaParserTokenManager._iMultiCommentsLast;
                            JavaParserTokenManager._iFormalComments += JavaParserTokenManager._iMultiCommentsLast;
                        }
                        JavaParserTokenManager._iMultiComments -= JavaParserTokenManager._iMultiCommentsLast;
                        break;
                    }
                    else if ( tmpToken.specialToken.image.startsWith( "/*" ) )
                    {
                        break;
                    }

                    //System.out.println("\n"+tmpToken.specialToken.image);

                    tmpToken = tmpToken.specialToken;
                }
  }
  (Annotation())* Type() VariableDeclarator() ( "," VariableDeclarator() )* ";"
  { _ncss++; Util.debug( "_ncss++" ); }
}

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

void VariableDeclaratorId() :
{}
{
        ("enum"|Identifier()) ( "[" "]" { _sName += "[]"; })*
}

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

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

void MethodDeclaration() :
{
    int oldNcss = _ncss;
    int oldFunctions = _functions;
    String sOldFunction = _sFunction;
    int oldcyc = _cyc;
    boolean bOldReturn = _bReturn;
    Token tmpToken = null;
    int jvdc = 0;

    // added by SMS
    int jvdcLines = 0;
    int oldSingle;
    int oldMulti;
    boolean bPublic = false;
    //

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken = null;
	_tmpToken=null;
	//

	//Added by REYNAUD Sebastien (LOGICA)
	FunctionMetric functionMetrics = new FunctionMetric();
	//functionMetrics.firstLine = JavaParserTokenManager.nbligne;
	//
}
{
    {
    if ( _tmpToken != null )
    {
        tmpToken = _tmpToken;
    }
    }
    (
	//Added by REYNAUD Sebastien (LOGICA)
	{myToken = getToken(1);}
	//
     Annotation()
  {
      if ( tmpToken == null ) {

          //tmpToken = getToken( 0 ); //Removed by REYNAUD Sebastien (LOGICA)

		//Added by REYNAUD Sebastien (LOGICA)
		tmpToken = myToken;
		//
      }
  }
     )*

    // we want to count javadoc comments, so we need first token
  ( "public" { bPublic = true; }        // added by SMS
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
    | "protected" { bPublic = true; }        // added by SMS
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
    | "private"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "static"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "abstract"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "final"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "native"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "synchronized"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
| "strictfp"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
  )*

    ( Annotation() )*

         /*{
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
      }*/


  [ TypeParameters() ]

           {
               _tmpResultToken = null;
           }
  ResultType()
        {
            if ( tmpToken == null )
            {
                tmpToken = _tmpResultToken;
                if ( tmpToken == null )
                {
                    tmpToken = getToken( 0 );
                }
                Util.debug( "result type tmpToken: " + tmpToken );
            }
        }
  MethodDeclarator() [ "throws" NameList() ]
        {
                _cyc = 1;
                _bReturn = false;
        }
  ( Block() | ";" )
         // note: the second ";" is just for a bug in java/sql/Connection.java
         // at line 182 column 38 as of sun jdk 1.1.5. The same
         // applies to java/text/DecimalFormat.java at line 629
         // column 6.
         //[ ";" ]
         {
  // added by SMS
  {
      Util.debug( "Token: " + String.valueOf( tmpToken.image ) );
      while( tmpToken.specialToken != null )
      {
          Util.debug( "Token comment: " + String.valueOf( tmpToken.specialToken.image ) );
          if ( tmpToken.specialToken.image.startsWith( "/**" ) )
          {
              _javadocs++;
              Util.debug( "MethodDeclaration()._javadocs++" );
              jvdc++;
              if ((bPublic && _bPublic) || _bPrivate) {
                  Util.debug( "_jvdc++" );
                  _jvdc++;
                  jvdcLines = JavaParserTokenManager._iMultiCommentsLast;
                  _jvdcLines += jvdcLines;
                  JavaParserTokenManager._iFormalComments += jvdcLines;
              }
              JavaParserTokenManager._iMultiComments -= jvdcLines;
              break;
          }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
              jvdcLines = 0;
              break;
          }

          //System.out.println("\n"+tmpToken.specialToken.image);

          tmpToken = tmpToken.specialToken;
      }

      oldSingle = JavaParserTokenManager._iSingleComments;
      oldMulti = JavaParserTokenManager._iMultiComments;
  }


             // removed by ccl
             /*
             while( tmpToken.specialToken != null ) {
                 if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                     jvdc++;
                     _javadocs++;
                 }
                 tmpToken = tmpToken.specialToken;
             }
             */
             // removed by SMS
             /*
               while( tmpToken.specialToken != null ) {
               if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
               jvdc++;
               _javadocs++;
               _bJavadoc = true;
               }

               tmpToken = tmpToken.specialToken;
               }
             */

             if (_bReturn)
             {
                 _cyc--;
             }
             _ncss++;
             Util.debug( "MethodDeclaration()._ncss++" );

             //FunctionMetric functionMetrics = new FunctionMetric(); //Removed by REYNAUD Sebastien (LOGICA)

             functionMetrics.name = _sPackage + _sClass + _sFunction;
             functionMetrics.ncss = _ncss - oldNcss;
             functionMetrics.ccn = _cyc;
             functionMetrics.javadocs = jvdc;

             // added by SMS
             functionMetrics.javadocsLn = 0; //jvdcLines;
             functionMetrics.singleLn = 0; //JavaParserTokenManager._iSingleComments - oldSingle;
             functionMetrics.multiLn = 0; //JavaParserTokenManager._iMultiComments - oldMulti;
             //

             // specially added for Cobertura
             // Commenting out for now until the rest of patch 2353196 is applied.
             //functionMetrics.beginLine = (new Integer(beginLine));
             //functionMetrics.endLine = (new Integer(endLine));

             _vFunctions.add(functionMetrics);
             _sFunction = sOldFunction;
             _functions = oldFunctions + 1;
             _cyc = oldcyc;
             _bReturn = bOldReturn;

		//Added by REYNAUD Sebastien (LOGICA)
		_tmpToken = null;
		//
         }
}

void MethodDeclarator() :
{}
{
        {
                _sFunction = "." + getToken(1).image;
        }
  Identifier() FormalParameters()
        {
                _sFunction += _sParameter;
        }
  ( "[" "]" { _sFunction += "[]"; } )*
}

void FormalParameters() :
{}
{
        {
                _sParameter = "(";
        }
  "(" [ FormalParameter() { _sParameter += _sName; }
  ( "," FormalParameter() { _sParameter += "," + _sName; } )* ] ")"
        {
                _sParameter += ")";
        }
}

void FormalParameter() :
{}
{
    //[ "final" ]
           Modifiers()
    Type() [ "..." { _sName += "[]"; } ] VariableDeclaratorId()
}

void ConstructorDeclaration() :
{
        int oldNcss = _ncss;
        int oldFunctions = _functions;
        String sOldFunction = _sFunction;
        int oldcyc = _cyc;
        boolean bOldReturn = _bReturn;
        Token tmpToken = null;
        int jvdc = 0;

        // added by SMS
        int oldSingle;
        int oldMulti;
        int jvdcLines = 0;
        boolean bPublic = false;
        //

	//Added by REYNAUD Sebastien (LOGICA)
	Token myToken = null;
	//

	//Added by REYNAUD Sebastien (LOGICA)
	FunctionMetric functionMetrics = new FunctionMetric();
	//functionMetrics.firstLine = JavaParserTokenManager.nbligne;
	//

}
{

//Added by REYNAUD Sebastien (LOGICA)
	(

	{myToken = getToken(1);}

     	Annotation()
  	{
      	if ( tmpToken == null )
		{
			tmpToken = myToken;
      	}
  	}
  	)*
//

  [ "public" { bPublic = true; }        // added by SMS
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "protected" { bPublic = true; }      // added by SMS
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 | "private"
  {
      if ( tmpToken == null ) {
          tmpToken = getToken( 0 );
      }
  }
 ]
  [ TypeParameters() ]
  Identifier()
        {
            if ( tmpToken == null ) {
                tmpToken = getToken( 0 );
            }
                _cyc = 1;
                _sFunction = _sPackage + _sClass + "." + getToken(0).image;
        }
  FormalParameters()
        {
                _sFunction += _sParameter;
                _bReturn = false;
        }
  [ "throws" NameList() ]
         //{ System.out.println( "\n\nInside ContructorDeclaration\n" ); }
  "{"
         //{ System.out.println( "\n\nContructorDeclaration\n" ); }
//  [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
//  [ LOOKAHEAD(("this" "(") | ([PrimaryExpression() "."]"super" "(")) ExplicitConstructorInvocation() ]
    [ LOOKAHEAD("this" "(") ExplicitConstructorInvocation() ]
    [ LOOKAHEAD([PrimaryExpression() "."]"super" "(") ExplicitConstructorInvocation() ]
//         [ LOOKAHEAD(2) ExplicitConstructorInvocation() ]
//         { System.out.println( "\n\nBefore BlockStatement\n" ); }


         // added by SMS
  {
                while( tmpToken.specialToken != null ) {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                        _javadocs++;
                        jvdc++;
                        if ((bPublic && _bPublic) || _bPrivate) {
                            Util.debug( "_jvdc++" );
                            _jvdc++;
                            jvdcLines = JavaParserTokenManager._iMultiCommentsLast;
                            _jvdcLines += jvdcLines;
                            JavaParserTokenManager._iFormalComments += jvdcLines;
                        }
                        JavaParserTokenManager._iMultiComments -= jvdcLines;
                        break;
                    }  else if ( tmpToken.specialToken.image.startsWith( "/*" ) ) {
                        jvdcLines = 0;
                        break;
                    }

                    //System.out.println("\n"+tmpToken.specialToken.image);

                    tmpToken = tmpToken.specialToken;
                }


                oldSingle = JavaParserTokenManager._iSingleComments;
                oldMulti = JavaParserTokenManager._iMultiComments;
                }

    ( BlockStatement() )*
         //{ System.out.println( "\n\nAfter BlockStatement\n" ); }
  "}"
                        // this is just because of a nonconformance to the JLS
                        // in java/net/Socket.java at line 148 column 6 as of
                        // sun jdk 1.1.5
                        //[ ";" ]
        {

            /*
                while( tmpToken.specialToken != null ) {
                    if ( tmpToken.specialToken.image.startsWith( "/**" ) ) {
                        jvdc++;
                        _javadocs++;
                    }
                    tmpToken = tmpToken.specialToken;
                }
            */
                if (_bReturn) {
                        _cyc--;
                }
                _ncss++;
                Util.debug( "_ncss++" );

                //FunctionMetric functionMetrics = new FunctionMetric(); //Removed by REYNAUD Sebastien (LOGICA)

                functionMetrics.name = _sFunction;
                functionMetrics.ncss = _ncss - oldNcss;
                functionMetrics.ccn = _cyc;
                functionMetrics.javadocs = jvdc;

                // added by SMS
                functionMetrics.javadocsLn = jvdcLines;
                functionMetrics.singleLn = JavaParserTokenManager._iSingleComments - oldSingle;
                functionMetrics.multiLn = JavaParserTokenManager._iMultiComments - oldMulti;
                //
                // specially added for Cobertura
                // Commenting out for now until the rest of patch 2353196 is applied.
                //functionMetrics.endLine = beginLine;
                //functionMetrics.endLine = endLine;

                _vFunctions.add(functionMetrics);
                _sFunction = sOldFunction;
                _functions = oldFunctions + 1;
                _cyc = oldcyc;
                _bReturn = bOldReturn;

		//Added by REYNAUD Sebastien (LOGICA)
		_tmpToken = null;
		//
        }
}

void ExplicitConstructorInvocation() :
{
  //System.out.println( "\n\nBefore ExplicitConstructorInvocation 1" );
}
{
  //LOOKAHEAD("this" Arguments() ";")
  LOOKAHEAD("this" "(" )
  "this" Arguments() ";"
         { _ncss++;       Util.debug( "_ncss++" );}
|
  [ LOOKAHEAD(PrimaryExpression() ".") PrimaryExpression()
  //{ System.out.println( "ExplicitConstructorInvocation before ." ); }
"." ]
  //{ System.out.println( "ExplicitConstructorInvocation before super" ); }
  "super" Arguments() ";"
  { _ncss++;       Util.debug( "_ncss++" );
//System.out.println( "\n\nAfter ExplicitConstructorInvocation\n" );
  }
}

void Initializer() :
{}
{
  [ "static" ] Block()
        { _ncss++;       Util.debug( "_ncss++" );}
}

/*
 * Type, name and expression syntax follows.
 */

void Type() :
{ _sName = ""; }
{
   LOOKAHEAD(2) ReferenceType()
 |
   PrimitiveType()
          {
                  _sName = getToken(0).image;
          }
}
/*
ccl 2008-01-24
{
  ( PrimitiveType()
          {
                  _sName = getToken(0).image;
          }
    | Name()
    [TypeArguments() ["." Identifier()] ]
) ( "[" "]" { _sName += "[]"; } )*
}
*/

/*
 * Takes special consideration for assert.
 */

void FieldTypeLookahead() :
{}
{
  ( PrimitiveType()
    | FieldTypeNameLookahead()
 ) ( "[" "]"  )*
}

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

void ResultType() :
{}
{
  "void"
|
  Type()
}

void Name() :
/*
 * A lookahead of 2 is required below since "Name" can be followed
 * by a ".*" when used in the context of an "ImportDeclaration".
 */
{}
{
    ("enum"|Identifier()) //<IDENTIFIER> // no Identifier() because of assert type for field declaration
        {
                _sName = getToken(0).image;
                _tmpResultToken = getToken( 0 );
                Util.debug( "Name._tmpResultToken: " + _tmpResultToken );
        }
    ( LOOKAHEAD(2) "." ("enum"|Identifier())
        {
                _sName += "." + getToken(0).image;
        }
  )*
}

/**
 * Takes special consideration for assert.
 */
void FieldTypeNameLookahead() :
/*
 * A lookahead of 2 is required below since "Name" can be followed
 * by a ".*" when used in the context of an "ImportDeclaration".
 */
{}
{
    <IDENTIFIER> // no Identifier() because of assert type for field declaration
  ( LOOKAHEAD(2) "." Identifier()
  )*
}

void NameList() :
{}
{
    Name() [TypeArguments()]
   ( "," Name() [TypeArguments()]
  )*
}

/*
 * Expression syntax follows.
 */

void Expression() :
{
    //System.out.println( "Expression start" );
}
{

/*Removed by REYNAUD Sebastien (LOGICA)

  LOOKAHEAD( PrimaryExpression() AssignmentOperator() )
  //{ System.out.println( "Expression" ); }
  Assignment()
|
*/

  ConditionalExpression()
}

/*Removed by REYNAUD Sebastien (LOGICA)
void Assignment() :
{}
{
  PrimaryExpression() AssignmentOperator() Expression()
}
*/

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

void ConditionalExpression() :
{}
{
  ConditionalOrExpression() [ "?" Expression() ":" ConditionalExpression() { _cyc++; } ]
}

void ConditionalOrExpression() :
{}
{
  ConditionalAndExpression() ( "||" { _cyc++; } ConditionalAndExpression() )*
}

void ConditionalAndExpression() :
{}
{
  InclusiveOrExpression() ( "&&" { _cyc++; } InclusiveOrExpression() )*
}

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

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

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

/* Removed by REYNAUD Sebastien (LOGICA)
void EqualityExpression() :
{}
{
  InstanceOfExpression() ( ( "==" | "!=" ) InstanceOfExpression() )*
}
*/

//Added by REYNAUD Sebastien (LOGICA)
void EqualityExpression() :
{}
{
  AssigmentExpression() ( ( "==" | "!=" | "+=" | "-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=") AssigmentExpression() )*
}

void AssigmentExpression() :
{}
{
  InstanceOfExpression() (  "="  InstanceOfExpression() )*
}
//

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

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

void ShiftExpression() :
{}
{

//  AdditiveExpression() ( ( "<<" | ">>" | ">>>" ) AdditiveExpression() )* //Removed by REYNAUD Sebastien (LOGICA)

//Added by REYNAUD Sebastien (LOGICA)
  AdditiveExpression() ( LOOKAHEAD(3) ( "<<" | (">" ">") (">")? ) AdditiveExpression() )*
//

}

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

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

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

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

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

void UnaryExpressionNotPlusMinus() :
{}
{
  ( "~" | "!" ) UnaryExpression()
|
         //  LOOKAHEAD( PostfixLookahead() )
         //  PostfixExpression()
         //|
  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("(" Name() "[")
         //  "(" Name() "[" "]"
         //|
         // LOOKAHEAD(3)
         //  "(" Name() ")" ( "~" | "!" | "(" | Identifier() | "this" | "super" | "new" | Literal() )
  LOOKAHEAD("(" Type() "[")
  "(" Type() "[" "]"
|
  "(" Type() ")" ( "~" | "!" | "(" | Identifier() | "this" | "super" | "new" | Literal() )
         //|
         // LOOKAHEAD(3)
         // "(" Type() ")"  UnaryExpressionNotPlusMinus()
}

// To fix bug Test48.java. Clemens [2000-10-03]
void PostfixLookahead() :
{}
{
  "(" Name() ( LOOKAHEAD(2) "[" "]" )* "."
}

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

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

void PrimaryExpression() :
{
//    { System.out.println( "Before PrimaryExpression" ); }
}
{
  PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )*
}

void PrimaryPrefix() :
{}
{
  Literal()
|
//    { System.out.println( "PrimaryPrefix: this" ); }
  "this" 

   //Added by REYNAUD Sebastien (LOGICA)
   (".")? ("new")? (Identifier())?
   //

         //|
         //LOOKAHEAD( 2 )
         //"super" "(" Expression() ")"
         //{ System.out.println( "\n\nAfter PrimaryPrefix super(Expression)\n" ); }
|
  LOOKAHEAD(2)
//  { System.out.println( "Before PrimaryPrefix super." ); }

  //"super" "." Identifier() //removed by REYNAUD Sebastien (LOGICA)


//Added by REYNAUD Sebastien (LOGICA)
"super" (".")? (Identifier())?
//

|
         //{ System.out.println( "\n\nBefore PrimaryPrefix (Expression)\n" ); }
  "(" Expression() ")"
|
  AllocationExpression()
//  { System.out.println( "PrimaryPrefix After AllocationExpression" ); }
|
  LOOKAHEAD( ResultType() "." "class" )
//  { System.out.println( "PrimaryPrefix ResultType" ); }
  ResultType() "." "class"
|
         Name() [ LOOKAHEAD(3) "." "super" "." Identifier() ]

         /* The [ "." "super" "." Identifier() ]
            has been added to fix a bug reported by
            Chris Williamson. It might cause other problems,
            maybe. 2002-05-11 */
//  { System.out.println( "PrimaryPrefix after Name" ); }
}

void PrimarySuffix() :
{}
{
  LOOKAHEAD(2)
  "." "this"
|
  LOOKAHEAD(2)
  "." AllocationExpression()
|
  LOOKAHEAD(3)
  MemberSelector()
|
  "[" Expression() "]"
|
//  { System.out.println( "PrimarySuffix . Identifier()" ); }
  "." Identifier()
|
  Arguments()

 [ "{" MethodDeclaration() "}"]
   
}

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

void BooleanLiteral() :
{}
{
  "true"
|
  "false"
}

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

void Arguments() :
{
// System.out.println( "Arguments start" );
}
{
  "(" [ ArgumentList() ] ")"
}

void ArgumentList() :
{
// System.out.println( "ArgumentList start" );
}
{
  Expression() ( "," Expression() )*
}

void AllocationExpression() :
{
        String sOldClass = _sClass;
        //int oldNcss = _ncss;
        int oldFunctions = _functions;
        int oldClasses = _classes;
        String sName;

}
{
  LOOKAHEAD(2)
  "new" PrimitiveType() ArrayDimsAndInits()
|
         "new" Name()
                        // this is all for anonymous classes
                        { sName = _sName; }
  [TypeArguments()]
      (
      ArrayDimsAndInits()
    |
      Arguments()
                [
                 {
                         if (!_sClass.equals("")) {
                                 _sClass += ".";
                         }
                         /*_sClass += sName;*/
                         _sClass += sName + "$" + _anonClassCount ;

                         _classLevel ++;
                 }
                        ClassBody()
                        {
                                _classLevel--;
                                _functions = oldFunctions;
                                _classes = oldClasses + 1;
                                _sClass = sOldClass;
                        }
                ]
    )
}

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


/*
 * Statement syntax follows.
 */

void Statement() :
{
        _bReturn = false;
        //{ System.out.println( "\n\nBefore Statement\n" ); }
}
{
  LOOKAHEAD(2)
  LabeledStatement()
|
  LOOKAHEAD(AssertStatementLookahead())
  AssertStatement()
|
  Block()
|
  EmptyStatement()
|
         //{ System.out.println( "\n\nBefore Statement Expression\n" ); }
  StatementExpression() ";"
        { _ncss++;       Util.debug( "_ncss++" );}
  //{ System.out.println( "\n\nHit Statement Expression\n" ); }
|
  SwitchStatement()
|
  IfStatement()
        { _cyc++; }
|
  WhileStatement()
        { _cyc++; }
|
  DoStatement()
        { _cyc++; }
|
  ForStatement()
        { _cyc++; }
|
  BreakStatement()
|
  ContinueStatement()
|
  ReturnStatement()
|
  ThrowStatement()
|
  SynchronizedStatement()
|
  TryStatement()
}

void LabeledStatement() :
{}
{
  Identifier() ":" Statement()
        { _ncss++;       Util.debug( "_ncss++" );}
}

void AssertStatementLookahead() :
{

}
{
  <ASSERT>
  Expression()
}

void AssertStatement() :
{
}
{
  <ASSERT>
  Expression()
  [ ":" Expression() ]
  ";"
  { _ncss++;       Util.debug( "_ncss++" );}
}

void Block() :
{}
{
  "{"
         //{_ncss++; Util.debug( "Block()._ncss++" );
         //}
   ( BlockStatement() )* "}"
}

void BlockStatement() :
{}
{
    //LOOKAHEAD([ "final" ] FieldTypeLookahead() Identifier())
  LOOKAHEAD( Modifiers() Type() ("enum"|<IDENTIFIER>) (";"|"="|","|"[""]") )
  LocalVariableDeclaration() ";"
        {
                _ncss++;       Util.debug( "_ncss++" );
        }
|
  Statement()
|
  UnmodifiedClassDeclaration()
|
  UnmodifiedInterfaceDeclaration()
}

/*void LocalVariableDeclaration() :
{}
{
  [ "final" ] Type() VariableDeclarator() ( "," VariableDeclarator() )*
}*/
void LocalVariableDeclaration():
{}
{
  Modifiers() Type() VariableDeclarator() ( "," VariableDeclarator() )*
}


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.
 */
{
    //{ System.out.println( "\n\nBefore StatementExpression\n" ); }
}
{
  PreIncrementExpression()
|
  PreDecrementExpression()
|
  PrimaryExpression()
  [
    "++"
  |
    "--"
  |
    AssignmentOperator() Expression()
  ]
}

void SwitchStatement() :
{}
{
        {
                _localCases = 0;
        }
  "switch" "(" Expression() ")" "{"
    ( SwitchLabel() ( BlockStatement() )* )*
  "}"
        { _ncss++;       Util.debug( "_ncss++" );}
}

void SwitchLabel() :
{}
{
  "case" Expression() ":"
        {
                _ncss++;
                Util.debug( "_ncss++" );
                _localCases++;
                _cyc++;
        }
|
  "default" ":"
        {
                _ncss++;       Util.debug( "_ncss++" );
        }
}

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() ")" Statement() [ LOOKAHEAD(1) "else" { _ncss++;       Util.debug( "_ncss++" );} Statement() ]
        { _ncss++;       Util.debug( "_ncss++" );}
}

void WhileStatement() :
{}
{
  "while" "(" Expression() ")" Statement()
        { _ncss++;       Util.debug( "_ncss++" ); }
}

void DoStatement() :
{}
{
  "do" Statement() "while" "(" Expression() ")" ";"
        { _ncss++;       Util.debug( "_ncss++" );}
}

void ForStatement() :
{}
{
  "for" "("
  (
      LOOKAHEAD(Modifiers() Type() <IDENTIFIER> ":")
      Modifiers() Type() <IDENTIFIER> ":" Expression()
    |
 [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ]
      )
")" Statement()
        { _ncss++;       Util.debug( "_ncss++" );}
}

void ForInit() :
{}
{
  LOOKAHEAD( [ "final" ] Type() ("enum"|Identifier()) )
  LocalVariableDeclaration()
|
  StatementExpressionList()
}

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

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

void BreakStatement() :
{}
{
  "break" [ Identifier() ] ";"
        { _ncss++;       Util.debug( "_ncss++" );}
}

void ContinueStatement() :
{}
{
  "continue" [ Identifier() ] ";"
        { _ncss++;       Util.debug( "_ncss++" );}
}

void ReturnStatement() :
{}
{
  "return" [ Expression() ] ";"
        {
                _ncss++;
                Util.debug( "_ncss++" );
                _cyc++;
                _bReturn = true;
        }
}

void ThrowStatement() :
{}
{
  "throw" Expression() ";"
        {
                _ncss++;
                Util.debug( "_ncss++" );
                _cyc++;
        }
}

void SynchronizedStatement() :
{}
{
  "synchronized" "(" Expression() ")" Block()
        { _ncss++;       Util.debug( "_ncss++" ); }
}

void TryStatement() :
/*
 * Semantic check required here to make sure that at least one
 * finally/catch is present.
 */
{}
{
  "try" TryWithResources() Block()
  ( "catch" "(" CatchParameter() ")" Block() { _ncss++;       Util.debug( "_ncss++" ); _cyc++; } )*
  [ "finally" Block() { _ncss++;       Util.debug( "_ncss++" );} ]
}

/** Try-with-resource parameter with jdk 7**/
void TryWithResources() :
{}
{
 ["(" ( "final" )* (Expression() [";"] )* ")"]
}

/** Multi-catch parameter with jdk 7 **/
void CatchParameter() :
{}
{
  Modifiers() ReferenceType() ("|" ReferenceType())* VariableDeclaratorId()
}

void Identifier() :
{}
{
    <IDENTIFIER>
|
    <ASSERT>
}

/* Annotation syntax follows. */

void Annotation():
{}
{
   LOOKAHEAD( "@" Name() "(" ( <IDENTIFIER> "=" | ")" ))
   NormalAnnotation()
 |
   LOOKAHEAD( "@" Name() "(" )
   SingleMemberAnnotation()
 |
   MarkerAnnotation()
}

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

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

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

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

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

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

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


/*
 =================================================
 Java 1.5 stuff starts here
 =================================================
*/

/* Annotation Types. */

//Added by REYNAUD Sebastien (LOGICA)
void CreationAnnotation():
{}
{
   "@" "interface" <IDENTIFIER> "{" (AnnotationTypeMemberDeclaration())*"}"
}
//

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

void AnnotationTypeBody():
{}
{
  "{" {_ncss++;       Util.debug( "_ncss++" );} ( AnnotationTypeMemberDeclaration() )* "}"
}

void AnnotationTypeMemberDeclaration():
{
   int modifiers;
}
{
 modifiers = Modifiers()
 (
   LOOKAHEAD(Type() <IDENTIFIER> "(")
   Type() <IDENTIFIER> "(" ")" [ DefaultValue() ] ";"
        {
            _ncss++;
            Util.debug( "_ncss++" );
        }

  |
   ClassOrInterfaceDeclaration(modifiers)
  |
   EnumDeclaration(modifiers)
  |
   AnnotationTypeDeclaration(modifiers)
  |
   FieldDeclaration15(modifiers)
 )
 |
        ( ";" )
        {
            _ncss++;
            Util.debug( "_ncss++" );
        }

}

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

/*
 * Modifiers. 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.
 */

int Modifiers():
{
   int modifiers = 0;
   _tmpToken = null;
}
{
 (
  LOOKAHEAD(2)
  (
   "public" { modifiers |= ModifierSet.PUBLIC;
      if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "static" { modifiers |= ModifierSet.STATIC;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "protected" { modifiers |= ModifierSet.PROTECTED;       if ( _tmpToken == null ) {
       _tmpToken = getToken( 0 );
      }
}
  |
   "private" { modifiers |= ModifierSet.PRIVATE;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "final" { modifiers |= ModifierSet.FINAL;       if ( _tmpToken == null ) {
       _tmpToken = getToken( 0 );
      }
}
  |
   "abstract" { modifiers |= ModifierSet.ABSTRACT;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "native" { modifiers |= ModifierSet.NATIVE;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "transient" { modifiers |= ModifierSet.TRANSIENT;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "volatile" { modifiers |= ModifierSet.VOLATILE;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   "strictfp" { modifiers |= ModifierSet.STRICTFP;       if ( _tmpToken == null ) {
          _tmpToken = getToken( 0 );
      }
}
  |
   Annotation()
  )
 )*

 {
    return modifiers;
 }
}

void ClassOrInterfaceDeclaration(int modifiers):
{
   boolean isInterface = false;
}
{
  ( "class" | "interface" { isInterface = true; } )
  <IDENTIFIER>
  [ TypeParameters() ]
  [ ExtendsList(isInterface) ]
  [ ImplementsList(isInterface) ]
  ClassOrInterfaceBody(isInterface)
}

void EnumDeclaration(int modifiers):
{
        String sOldClass = _sClass;
        int oldClasses = _classes;
        int oldNcss = _ncss;
        int oldFunctions = _functions;

        // Chris Povirk
        int oldSingle;
        int oldMulti;
}
{
    { Util.debug( "EnumDeclaration().START" ); }
    "enum" <IDENTIFIER>
         {
                if (!_sClass.equals("")) {
                        _sClass += ".";
                }
                _sClass += getToken(0).image;
                _classLevel ++;
         }
  [ ImplementsList(false) ]
{
        // Chris Povirk
      oldSingle = JavaParserTokenManager._iSingleComments;
      oldMulti = JavaParserTokenManager._iMultiComments;
}
  EnumBody()
         {
             _classLevel--;
             if (_classLevel == 0) {
                 //_topLevelClasses++;
                 ObjectMetric metric = new ObjectMetric();
                 metric.name = _sPackage + _sClass;
                 metric.ncss = _ncss - oldNcss;
                 metric.functions = _functions - oldFunctions;
                 metric.classes = _classes - oldClasses;
                 Token lastToken = getToken( 0 );
                 //metric.add( new Integer( lastToken.endLine ) );
                 //metric.add( new Integer( lastToken.endColumn ) );
                 metric.javadocs = _javadocs;

                 // Chris Povirk
                 metric.javadocsLn = _jvdcLines;
                 metric.singleLn = JavaParserTokenManager._iSingleComments - oldSingle;
                 metric.multiLn = JavaParserTokenManager._iMultiComments - oldMulti;

                 _vClasses.add(metric);
                 _pPackageMetric.functions += _functions - oldFunctions;
                 _pPackageMetric.classes++;

                 // added by SMS
                 _pPackageMetric.javadocs += _javadocs;
                 //_pPackageMetric.javadocsLn += JavaParserTokenManager._iFormalComments - oldFormal;
                 //_pPackageMetric.singleLn += JavaParserTokenManager._iSingleComments - oldSingle;
                 //_pPackageMetric.multiLn += Manager._iMultiComments - oldMulti;
                 //
             }
             _functions = oldFunctions;
             _classes = oldClasses + 1;
             _sClass = sOldClass;
         }
}

void TypeParameters():
{}
{
//    "<" TypeParameter() ( "," TypeParameter() )* [">>>"|">>"|">"]// [LOOKAHEAD(2)">"] [LOOKAHEAD(2)">>"] //Removed by REYNAUD Sebastien (LOGICA)

//Added by REYNAUD Sebastien (LOGICA)
"<" TypeParameter() ( "," TypeParameter() )* ">"
//

}

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 ClassOrInterfaceBody(boolean isInterface):
{}
{
  "{"
         { _ncss++; Util.debug( "ClassOrInterfaceBody()._ncss++" ); }
 ( ClassOrInterfaceBodyDeclaration(isInterface) )* "}"
}

void EnumBody():
{}
{
    "{"
           {
               _ncss++;
               Util.debug( "_ncss++" );
           }

   [ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
        [ "," ]
   [ ";" ( ClassOrInterfaceBodyDeclaration(false) )* ]
   "}"
}

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

void ClassOrInterfaceType():
{}
{
  <IDENTIFIER>
{
                _sName += getToken(0).image;
                if ( _tmpResultToken == null )
                {
                  _tmpResultToken = getToken( 0 );
                  Util.debug( "ClassOrInterfaceType._tmpResultToken: " + _tmpResultToken );
                }
}
[ LOOKAHEAD(4) TypeArguments() ]
  ( LOOKAHEAD(2) "." <IDENTIFIER>
        {
                _sName += "." + getToken(0).image;
        }
 [ LOOKAHEAD(2) TypeArguments() ] )*
}

void ClassOrInterfaceBodyDeclaration(boolean isInterface):
{
   //boolean isNestedInterface = false;
   int modifiers;
}
{
  LOOKAHEAD(2)
  Initializer()
  {
     if (isInterface)
        throw new ParseException("An interface cannot have initializers");
  }
|
  modifiers = 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(modifiers)
    |
      EnumDeclaration(modifiers)
    |
      LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" )
      ConstructorDeclaration()
    |
      LOOKAHEAD( Type() <IDENTIFIER> ( "[" "]" )* ( "," | "=" | ";" ) )
      FieldDeclaration15(modifiers)
    |
      MethodDeclaration15(modifiers)
  )
|
  ";"
}

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

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

void TypeArguments():
{}
{
//    "<" TypeArgument() ( LOOKAHEAD(2) "," TypeArgument() )* [LOOKAHEAD(3)">"] [LOOKAHEAD(3)">>"] [LOOKAHEAD(3)">>>"] //Removed by REYNAUD Sebastien (LOGICA)

//Added by REYNAUD Sebastien (LOGICA)
	"<" { _sName += "<"; } (TypeArgument() ( LOOKAHEAD(2) "," { _sName += ","; } TypeArgument() )* )* ">" { _sName += ">"; }
//

}

void TypeArgument():
{}
{
/* ccl 2008-01-24
    LOOKAHEAD(2)
    <IDENTIFIER> TypeArguments()
 |*/
   ReferenceType()
 |
   "?" [ WildcardBounds() ]

}

void ReferenceType():
{}
{
/* ccl 2008-01-23 */
   PrimitiveType()  { _sName = getToken(0).image; } ( LOOKAHEAD(2) "[" "]" { _sName += "[]"; } )+
  |
   ( ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" { _sName += "[]"; } )*
}

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

void FieldDeclaration15(int modifiers):
{}
{
  // Modifiers are already matched in the caller
  Type() VariableDeclarator() ( "," VariableDeclarator() )* ";"
}

void MethodDeclaration15(int modifiers):
{}
{
    MethodDeclaration()
    /*
  // Modifiers already matched in the caller!
  [ TypeParameters() ]
  ResultType()
  MethodDeclarator15() [ "throws" NameList() ]
         ( Block() | ";" ) { _ncss++; Util.debug( "MethodDeclaration15()._ncss++" ); }
    */
}

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

void FormalParameters15():
{}
{
  "(" [ FormalParameter15() ( "," FormalParameter15() )* ] ")"
}

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

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

