Commits

Tim Vernum committed f7da03e

Update grammar to support Java 7

  • Participants
  • Parent commits 8d5e9b9

Comments (0)

Files changed (1)

File parser/java.jjt

 /* Copyright (c) 2006, Sun Microsystems, Inc.
  * All rights reserved.
  *
+ * Copyright (c) 2012, Tim Vernum
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *
 /**
  * Grammar to parse Java version 1.5
  * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5
+ * @author Tim Vernum - Extended for Java 7
  */
 public class JavaParser
 {
    /**
     * 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;
+    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
+        /** 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 isPublic(int modifiers)
+        {
+            return (modifiers & PUBLIC) != 0;
+        }
 
-     public boolean isProtected(int modifiers)
-     {
-       return (modifiers & PROTECTED) != 0;
-     }
+        public boolean isProtected(int modifiers)
+        {
+            return (modifiers & PROTECTED) != 0;
+        }
 
-     public boolean isPrivate(int modifiers)
-     {
-       return (modifiers & PRIVATE) != 0;
-     }
+        public boolean isPrivate(int modifiers)
+        {
+            return (modifiers & PRIVATE) != 0;
+        }
 
-     public boolean isStatic(int modifiers)
-     {
-       return (modifiers & STATIC) != 0;
-     }
+        public boolean isStatic(int modifiers)
+        {
+            return (modifiers & STATIC) != 0;
+        }
 
-     public boolean isAbstract(int modifiers)
-     {
-       return (modifiers & ABSTRACT) != 0;
-     }
+        public boolean isAbstract(int modifiers)
+        {
+            return (modifiers & ABSTRACT) != 0;
+        }
 
-     public boolean isFinal(int modifiers)
-     {
-       return (modifiers & FINAL) != 0;
-     }
+        public boolean isFinal(int modifiers)
+        {
+            return (modifiers & FINAL) != 0;
+        }
 
-     public boolean isNative(int modifiers)
-     {
-       return (modifiers & NATIVE) != 0;
-     }
+        public boolean isNative(int modifiers)
+        {
+            return (modifiers & NATIVE) != 0;
+        }
 
-     public boolean isStrictfp(int modifiers)
-     {
-       return (modifiers & STRICTFP) != 0;
-     }
+        public boolean isStrictfp(int modifiers)
+        {
+            return (modifiers & STRICTFP) != 0;
+        }
 
-     public boolean isSynchronized(int modifiers)
-     {
-       return (modifiers & SYNCHRONIZED) != 0;
-     }
+        public boolean isSynchronized(int modifiers)
+        {
+            return (modifiers & SYNCHRONIZED) != 0;
+        }
 
-     public boolean isTransient(int modifiers)
-      {
-       return (modifiers & TRANSIENT) != 0;
-     }
+        public boolean isTransient(int modifiers)
+        {
+            return (modifiers & TRANSIENT) != 0;
+        }
 
-     public boolean isVolatile(int modifiers)
-     {
-       return (modifiers & VOLATILE) != 0;
-     }
+        public boolean isVolatile(int modifiers)
+        {
+            return (modifiers & VOLATILE) != 0;
+        }
 
-     /**
-      * Removes the given modifier.
-      */
-     static int removeModifier(int modifiers, int mod)
-     {
-        return modifiers & ~mod;
-     }
-   }
+        /**
+        * Removes the given modifier.
+        */
+        static int removeModifier(int modifiers, int mod)
+        {
+            return modifiers & ~mod;
+        }
 
-   public JavaParser(String fileName)
-   {
-      this(System.in);
-      try { ReInit(new FileInputStream(new File(fileName))); }
-      catch(Exception e) { e.printStackTrace(); }
-   }
+        static int withModifier(int modifier, int mod) 
+        {
+            return modifier & mod;
+        }
+    }
 
-  public static void main(String args[]) {
-    JavaParser parser;
-    if (args.length == 0) {
-      System.out.println("Java Parser Version 1.1:  Reading from standard input . . .");
-      parser = new JavaParser(System.in);
-    } else if (args.length == 1) {
-      System.out.println("Java Parser Version 1.1:  Reading from file " + args[0] + " . . .");
-      try {
-        parser = new JavaParser(new java.io.FileInputStream(args[0]));
-      } catch (java.io.FileNotFoundException e) {
-        System.out.println("Java Parser Version 1.1:  File " + args[0] + " not found.");
-        return;
-      }
-    } else {
-      System.out.println("Java Parser Version 1.1:  Usage is one of:");
-      System.out.println("         java JavaParser < inputfile");
-      System.out.println("OR");
-      System.out.println("         java JavaParser inputfile");
-      return;
+    public JavaParser(String fileName)
+    {
+        this(System.in);
+        try { ReInit(new FileInputStream(new File(fileName))); }
+        catch(Exception e) { e.printStackTrace(); }
     }
-    try {
-      parser.CompilationUnit();
-      System.out.println("Java Parser Version 1.1:  Java program parsed successfully.");
-    } catch (ParseException e) {
-      System.out.println(e.getMessage());
-      System.out.println("Java Parser Version 1.1:  Encountered errors during parse.");
+
+    public static void main(String args[]) 
+    {
+        JavaParser parser;
+        if (args.length == 0)
+        {
+            System.out.println("Java Parser Version 1.2:  Reading from standard input . . .");
+            parser = new JavaParser(System.in);
+        }
+        else if (args.length == 1)
+        {
+            System.out.println("Java Parser Version 1.2:  Reading from file " + args[0] + " . . .");
+            try 
+            {
+                parser = new JavaParser(new java.io.FileInputStream(args[0]));
+            }
+            catch (java.io.FileNotFoundException e)
+            {
+                System.out.println("Java Parser Version 1.2:  File " + args[0] + " not found.");
+                return;
+            }
+        }
+        else
+        {
+            System.out.println("Java Parser Version 1.2:  Usage is one of:");
+            System.out.println("         java JavaParser < inputfile");
+            System.out.println("OR");
+            System.out.println("         java JavaParser inputfile");
+            return;
+        }
+
+        try
+        {
+            parser.CompilationUnit();
+            System.out.println("Java Parser Version 1.2:  Java program parsed successfully.");
+        }
+        catch (ParseException e)
+        {
+            System.out.println(e.getMessage());
+            System.out.println("Java Parser Version 1.2:  Encountered errors during parse.");
+        }
     }
-  }
-
 }
 
 PARSER_END(JavaParser)
 
 SKIP :
 {
-  " "
+" "
 | "\t"
 | "\n"
 | "\r"
 
 MORE :
 {
-  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
+<"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
 |
   "/*" : IN_MULTI_LINE_COMMENT
 }
 
 TOKEN :
 {
+  < #NON_ZERO_DIGIT : ["1"-"9"] >
+|
+  < #DIGIT : ["0"-"9"] >
+|
+  < #HEX_DIGIT : ["0"-"9","a"-"f","A"-"F"] >
+|
+  < #DIGIT_SEQ : <DIGIT> ( ("_")* <DIGIT> )* >
+|
+  < #HEX_SEQ : <HEX_DIGIT> ( ("_")* <HEX_DIGIT> )* >
+|
   < INTEGER_LITERAL:
         <DECIMAL_LITERAL> (["l","L"])?
       | <HEX_LITERAL> (["l","L"])?
       | <OCTAL_LITERAL> (["l","L"])?
+      | <BINARY_LITERAL> (["l","L"])?
   >
 |
-  < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
+  < #DECIMAL_LITERAL: "0" | <NON_ZERO_DIGIT> ( ("_")* <DIGIT> )* >
 |
-  < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+  < #HEX_LITERAL: "0" ["x","X"] <HEX_SEQ> >
 |
-  < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+  < #OCTAL_LITERAL: "0" ( ("_")* ["0"-"7"])+ >
+|
+  < #BINARY_LITERAL: "0" ["b","B"] ["0","1"] ( ("_")* ["0","1"] )* >
 |
   < FLOATING_POINT_LITERAL:
         <DECIMAL_FLOATING_POINT_LITERAL>
   >
 |
   < #DECIMAL_FLOATING_POINT_LITERAL:
-        (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
-      | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
-      | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
-      | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]
+        <DIGIT_SEQ> "." <DIGIT_SEQ> (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | <DIGIT_SEQ> "."             (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      |             "." <DIGIT_SEQ> (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | <DIGIT_SEQ>                 (<DECIMAL_EXPONENT>)?  ["f","F","d","D"]
+      | <DIGIT_SEQ> <DECIMAL_EXPONENT> 
   >
 |
-  < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+  < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? <DIGIT_SEQ> >
 |
   < #HEXADECIMAL_FLOATING_POINT_LITERAL:
-        "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
-      | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+        "0" ["x", "X"]  <HEX_SEQ>  (".")?           <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+      | "0" ["x", "X"] (<HEX_SEQ>)? "."   <HEX_SEQ> <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
   >
 |
-  < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
+  < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? <DIGIT_SEQ> >
 |
   < CHARACTER_LITERAL:
       "'"
 | < RSIGNEDSHIFTASSIGN: ">>=" >
 | < RUNSIGNEDSHIFTASSIGN: ">>>=" >
 | < ELLIPSIS: "..." >
+| < DIAMOND: "<>" >
 }
 
 /* >'s need special attention due to generics syntax. */
  * Program structuring syntax follows.
  */
 
-void CompilationUnit():
+ASTCompilationUnit CompilationUnit():
 {}
 {
   [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ]
   ( TypeDeclaration() )+
   ( < "\u001a" > )?
   ( <STUFF_TO_IGNORE: ~[]> )?
-  <EOF>
+  <EOF> { return jjtThis; }
 }
 
 void PackageDeclaration():
   // danson, added
   //          [ "final" | Annotation() ]
   // See Java Language Specification, 3rd Edition, section 8.4.1
-  Modifiers() [ "final" | Annotation() ] Type() [ "..." ] VariableDeclaratorId()
+  Modifiers() ( VariableModifier() )* Type() [ "..." ] VariableDeclaratorId()
+}
+
+void VariableModifier():
+{}
+{
+    "final"
+  |
+    Annotation()
 }
 
 void ConstructorDeclaration():
 {}
 {
    "<" TypeArgument() ( "," TypeArgument() )* ">"
+|  "<>"
 }
 
 void TypeArgument():
 
 void TryStatement():
 /*
- * Semantic check required here to make sure that at least one
- * finally/catch is present.
+ * Semantic check required here to make sure that at least one of
+ * resources/finally/catch is present.
  */
 {}
 {
-  "try" Block()
-  ( "catch" "(" FormalParameter() ")" Block() )*
+  "try" [ ResourcesSpecification() ] Block()
+  ( "catch" "(" CatchParameter() ")" Block() )*
   [ "finally" Block() ]
 }
 
+void ResourcesSpecification():
+{}
+{
+    "(" 
+        Resource() ( LOOKAHEAD(2) ";" Resource() )* [ ";" ]
+    ")"
+}
+
+void Resource() :
+{}
+{
+    ( VariableModifier() )* ReferenceType() VariableDeclaratorId() "=" Expression()
+}
+
+void CatchParameter() :
+{}
+{
+    ( VariableModifier() )* CatchType() <IDENTIFIER>
+}
+
+void CatchType() :
+{}
+{
+    <IDENTIFIER> ( "|" <IDENTIFIER> )*
+}
+
 /* We use productions to match >>>, >> and > so that we can keep the
  * type declaration syntax with generics clean
  */