import java.util.*;
import java.util.regex.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
// All rules never end with WhiteSpace. This allows us to check for error easier.
final static String Identifier
= "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*+"; // Heuristic to exclude any position where adding space would split an Identifier or a keyword apart
final static String TokenBoundary
= "(?:(?<!\\p{javaJavaIdentifierPart})|(?!\\p{javaJavaIdentifierPart}))";
// Optional whitespace
final static String WhiteSpaceOpt
= "[ \\t\\f\\r\\n]*+"; // Compulsory whitespace
final static String WhiteSpaceCom
= "[ \\t\\f\\r\\n]++";
final static String MarkerAnnotation
= "@" + WhiteSpaceOpt
+ Identifier
; // Skipped: SingleElementAnnotation, NormalAnnotation
// Can't be included due to middle recursion
final static String ClassModifier
= "(?:public|protected|private|abstract|static|final|strictfp|" + Annotation + ")"; // Since the declaration
// public@Deprecated ...
// is allowed, the space between modifiers is optional.
// Since allowing the space to be optional recognizes this invalid declaration
// publicstatic ...
// we need to assert boundary between 2 class modifiers
final static String ClassModifiers
= ClassModifier
+ "(?:" + WhiteSpaceOpt
+ TokenBoundary
+ ClassModifier
+ ")*+";
final static String TypeVariable
= Identifier
;
// Skipped: ArrayType, ClassOrInterfaceType
// Can't be included, since the grammar is context-free, and this is where middle recursion occurs
final static String ReferenceType
= TypeVariable
; final static String WildcardBounds
= "(?:extends|super)" + WhiteSpaceCom
+ ReferenceType
; final static String Wildcard
= "[?]" + WhiteSpaceOpt
+ "(?:" + WildcardBounds
+ ")?+"; final static String TypeArgument
= "(?:" + ReferenceType
+ "|" + Wildcard
+ ")"; final static String TypeArgumentList
= TypeArgument
+ "(?:" + WhiteSpaceOpt
+ "," + WhiteSpaceOpt
+ TypeArgument
+ ")*+"; final static String TypeArguments
= "<" + WhiteSpaceOpt
+ TypeArgumentList
+ WhiteSpaceOpt
+ ">";
final static String TypeName
= Identifier
+ "(?:" + WhiteSpaceOpt
+ "[.]" + WhiteSpaceOpt
+ Identifier
+ ")*+"; // Expanded definition of ClassOrInterfaceType = ClassType = InterfaceType
// ClassOrInterfaceType -> TypeName TypeArguments<opt>
// ClassOrInterfaceType -> ClassOrInterfaceType . Identifier TypeArguments<opt>
final static String ClassType
= TypeName
+ "(?:" + WhiteSpaceOpt
+ TypeArguments
+ ")?+" + "(?:" + WhiteSpaceOpt + "[.]" + WhiteSpaceOpt + Identifier + "(?:" + WhiteSpaceOpt + TypeArguments + ")?+" + ")*+";
// Definition of ClassType and InterfaceType are identical
final static String InterfaceType
= ClassType
; final static String ClassOrInterfaceType
= ClassType
;
final static String TypeBound
= "extends" + WhiteSpaceCom
+ "(?:" + ClassOrInterfaceType
+ "|" + TypeVariable
+ ")"; final static String TypeParameter
= TypeVariable
+ "(?:" + WhiteSpaceCom
+ TypeBound
+ ")?+"; final static String TypeParameterList
= TypeParameter
+ "(?:" + WhiteSpaceOpt
+ "," + WhiteSpaceOpt
+ TypeParameter
+ ")*+"; final static String TypeParameters
= "<" + WhiteSpaceOpt
+ TypeParameterList
+ WhiteSpaceOpt
+ ">";
final static String Super = "extends" + WhiteSpaceCom
+ ClassType
;
final static String InterfaceTypeList
= InterfaceType
+ "(?:" + WhiteSpaceOpt
+ "," + WhiteSpaceOpt
+ InterfaceType
+ ")*+"; final static String Interfaces
= "implements" + WhiteSpaceCom
+ InterfaceTypeList
;
final static String NormalClassDeclaration
= // Annotation in its fullest form can end in ), so WhiteSpaceOpt is used here for pedantic
// It can be changed to WhiteSpaceCom to save the TokenBoundary check, since current definition always end with Identifier character
"(?:" + "(" + ClassModifiers + ")" + WhiteSpaceOpt + ")?+" +
TokenBoundary + "class" + WhiteSpaceCom +
// WhiteSpaceOpt is used here, since TypeParameters starts with < and no whitespace is needed to delimit
"(" + Identifier + ")" + WhiteSpaceOpt +
"(?:" + "(" + TypeParameters + ")" + WhiteSpaceOpt + ")?+" +
// As the result, we need to check for boundary before "extends" and "implements"
TokenBoundary + "(?:" + "(" + Super + ")"+ WhiteSpaceOpt + ")?+" +
TokenBoundary + "(?:" + "(" + Interfaces + WhiteSpaceOpt + ")" + ")?+[{]";
// ClassBody is skipped, and only opening bracket { is matched
final static String InterfaceModifier
= "(?:public|protected|private|abstract|static|strictfp|" + Annotation + ")"; // Same as ClassModifiers, except that "final" is no longer a valid modifier
final static String InterfaceModifiers
= InterfaceModifier
+ "(?:" + WhiteSpaceOpt
+ TokenBoundary
+ InterfaceModifier
+ ")*+";
final static String ExtendsInterfaces
= "extends" + WhiteSpaceCom
+ InterfaceTypeList
;
final static String NormalInterfaceDeclaration
= "(?:" + "(" + InterfaceModifiers + ")" + WhiteSpaceOpt + ")?+" +
TokenBoundary + "interface" + WhiteSpaceCom +
// WhiteSpaceOpt is used here, since TypeParameters starts with < and no whitespace is needed to delimit
"(" + Identifier + ")" + WhiteSpaceOpt +
"(?:" + "(" + TypeParameters + ")" + WhiteSpaceOpt + ")?+" +
// As the result, we need to check for boundary before "extends" here
TokenBoundary + "(?:" + "(" + ExtendsInterfaces + ")" + WhiteSpaceOpt + ")?+[{]";
{
"class SetupMouseListener extends MouseAdapter {}",
"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{}"
};
Pattern re = Pattern.compile(NormalClassDeclaration);
Matcher m;
for (String source
: sources
) { m = re.matcher(source);
if (m.find()) {
for (int i = 1; i <= m.groupCount(); i++) {
System.
out.
println(m.
group(i
)); }
}
}
}
}