fork download
  1. import java.util.*;
  2. import java.util.regex.*;
  3. import java.lang.*;
  4. import java.io.*;
  5.  
  6. /* Name of the class has to be "Main" only if the class is public. */
  7. class Ideone
  8. {
  9. // All rules never end with WhiteSpace. This allows us to check for error easier.
  10.  
  11. final static String Identifier = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*+";
  12. // Heuristic to exclude any position where adding space would split an Identifier or a keyword apart
  13. final static String TokenBoundary = "(?:(?<!\\p{javaJavaIdentifierPart})|(?!\\p{javaJavaIdentifierPart}))";
  14.  
  15. // Optional whitespace
  16. final static String WhiteSpaceOpt = "[ \\t\\f\\r\\n]*+";
  17. // Compulsory whitespace
  18. final static String WhiteSpaceCom = "[ \\t\\f\\r\\n]++";
  19.  
  20. final static String MarkerAnnotation = "@" + WhiteSpaceOpt + Identifier;
  21. // Skipped: SingleElementAnnotation, NormalAnnotation
  22. // Can't be included due to middle recursion
  23. final static String Annotation = MarkerAnnotation;
  24.  
  25. final static String ClassModifier = "(?:public|protected|private|abstract|static|final|strictfp|" + Annotation + ")";
  26. // Since the declaration
  27. // public@Deprecated ...
  28. // is allowed, the space between modifiers is optional.
  29. // Since allowing the space to be optional recognizes this invalid declaration
  30. // publicstatic ...
  31. // we need to assert boundary between 2 class modifiers
  32. final static String ClassModifiers = ClassModifier + "(?:" + WhiteSpaceOpt + TokenBoundary + ClassModifier + ")*+";
  33.  
  34. final static String TypeVariable = Identifier;
  35.  
  36. // Skipped: ArrayType, ClassOrInterfaceType
  37. // Can't be included, since the grammar is context-free, and this is where middle recursion occurs
  38. final static String ReferenceType = TypeVariable;
  39. final static String WildcardBounds = "(?:extends|super)" + WhiteSpaceCom + ReferenceType;
  40. final static String Wildcard = "[?]" + WhiteSpaceOpt + "(?:" + WildcardBounds + ")?+";
  41. final static String TypeArgument = "(?:" + ReferenceType + "|" + Wildcard + ")";
  42. final static String TypeArgumentList = TypeArgument + "(?:" + WhiteSpaceOpt + "," + WhiteSpaceOpt + TypeArgument + ")*+";
  43. final static String TypeArguments = "<" + WhiteSpaceOpt + TypeArgumentList + WhiteSpaceOpt + ">";
  44.  
  45. final static String TypeName = Identifier + "(?:" + WhiteSpaceOpt + "[.]" + WhiteSpaceOpt + Identifier + ")*+";
  46. // Expanded definition of ClassOrInterfaceType = ClassType = InterfaceType
  47. // ClassOrInterfaceType -> TypeName TypeArguments<opt>
  48. // ClassOrInterfaceType -> ClassOrInterfaceType . Identifier TypeArguments<opt>
  49. final static String ClassType = TypeName + "(?:" + WhiteSpaceOpt + TypeArguments + ")?+" +
  50. "(?:" + WhiteSpaceOpt + "[.]" + WhiteSpaceOpt + Identifier + "(?:" + WhiteSpaceOpt + TypeArguments + ")?+" + ")*+";
  51. // Definition of ClassType and InterfaceType are identical
  52. final static String InterfaceType = ClassType;
  53. final static String ClassOrInterfaceType = ClassType;
  54.  
  55. final static String TypeBound = "extends" + WhiteSpaceCom + "(?:" + ClassOrInterfaceType + "|" + TypeVariable + ")";
  56. final static String TypeParameter = TypeVariable + "(?:" + WhiteSpaceCom + TypeBound + ")?+";
  57. final static String TypeParameterList = TypeParameter + "(?:" + WhiteSpaceOpt + "," + WhiteSpaceOpt + TypeParameter + ")*+";
  58. final static String TypeParameters = "<" + WhiteSpaceOpt + TypeParameterList + WhiteSpaceOpt + ">";
  59.  
  60. final static String Super = "extends" + WhiteSpaceCom + ClassType;
  61.  
  62. final static String InterfaceTypeList = InterfaceType + "(?:" + WhiteSpaceOpt + "," + WhiteSpaceOpt + InterfaceType + ")*+";
  63. final static String Interfaces = "implements" + WhiteSpaceCom + InterfaceTypeList;
  64.  
  65. final static String NormalClassDeclaration =
  66. // Annotation in its fullest form can end in ), so WhiteSpaceOpt is used here for pedantic
  67. // It can be changed to WhiteSpaceCom to save the TokenBoundary check, since current definition always end with Identifier character
  68. "(?:" + "(" + ClassModifiers + ")" + WhiteSpaceOpt + ")?+" +
  69. TokenBoundary + "class" + WhiteSpaceCom +
  70. // WhiteSpaceOpt is used here, since TypeParameters starts with < and no whitespace is needed to delimit
  71. "(" + Identifier + ")" + WhiteSpaceOpt +
  72. "(?:" + "(" + TypeParameters + ")" + WhiteSpaceOpt + ")?+" +
  73. // As the result, we need to check for boundary before "extends" and "implements"
  74. TokenBoundary + "(?:" + "(" + Super + ")"+ WhiteSpaceOpt + ")?+" +
  75. TokenBoundary + "(?:" + "(" + Interfaces + WhiteSpaceOpt + ")" + ")?+[{]";
  76. // ClassBody is skipped, and only opening bracket { is matched
  77.  
  78. final static String InterfaceModifier = "(?:public|protected|private|abstract|static|strictfp|" + Annotation + ")";
  79. // Same as ClassModifiers, except that "final" is no longer a valid modifier
  80. final static String InterfaceModifiers = InterfaceModifier + "(?:" + WhiteSpaceOpt + TokenBoundary + InterfaceModifier + ")*+";
  81.  
  82. final static String ExtendsInterfaces = "extends" + WhiteSpaceCom + InterfaceTypeList;
  83.  
  84. final static String NormalInterfaceDeclaration =
  85. "(?:" + "(" + InterfaceModifiers + ")" + WhiteSpaceOpt + ")?+" +
  86. TokenBoundary + "interface" + WhiteSpaceCom +
  87. // WhiteSpaceOpt is used here, since TypeParameters starts with < and no whitespace is needed to delimit
  88. "(" + Identifier + ")" + WhiteSpaceOpt +
  89. "(?:" + "(" + TypeParameters + ")" + WhiteSpaceOpt + ")?+" +
  90. // As the result, we need to check for boundary before "extends" here
  91. TokenBoundary + "(?:" + "(" + ExtendsInterfaces + ")" + WhiteSpaceOpt + ")?+[{]";
  92.  
  93.  
  94. public static void main (String[] args) throws java.lang.Exception
  95. {
  96. String sources[] = {
  97. "class SetupMouseListener extends MouseAdapter {}",
  98. "abstract class X<B extends Integer,D extends java.io.InputStream,R extends Comparator<?super D>>extends java.util.ArrayList<Integer>implements java.util.Queue<Integer>,Serializable{}"
  99. };
  100.  
  101. Pattern re = Pattern.compile(NormalClassDeclaration);
  102.  
  103. Matcher m;
  104.  
  105. for (String source: sources) {
  106. m = re.matcher(source);
  107.  
  108. if (m.find()) {
  109. for (int i = 1; i <= m.groupCount(); i++) {
  110. System.out.println(m.group(i));
  111. }
  112. }
  113. }
  114. }
  115. }
Success #stdin #stdout 0.09s 380480KB
stdin
Standard input is empty
stdout
null
SetupMouseListener
null
extends MouseAdapter
null
abstract
X
<B extends Integer,D extends java.io.InputStream,R extends Comparator<?super D>>
extends java.util.ArrayList<Integer>
implements java.util.Queue<Integer>,Serializable