// ---
Lexer
-identifier = ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9')*;
+identifier = ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'-'|'$'|'0'..'9')*;
blank = (' '|'\n'|'\t'|'\r')+;
separator = ('.'|'/');
brackets = '[]';
wildcard = '?';
+compiled_from = 'Compiled from "' (Any-'"')* '"';
// ---
Parser
Ignored blank;
-multi_files = compiled_from? class_declaration;
-
-compiled_from = 'Compiled from "' identifier+ '.java"';
+files = file+;
+file = compiled_from? class_declaration;
class_declaration = modifier* class_or_interface full_class_name
extends_declaration? implements_declaration? throws_declaration?
class_or_interface = 'class'|'interface';
modifier
- = 'public'|'private'|'protected'|'static'|'final'|'native'|'synchronized'|'abstract'|'threadsafe'|'transient'|'volatile';
+ = 'public'|'private'|'protected'|'static'|'final'|'native'|'synchronized'|'abstract'|'threadsafe'|'transient'|'volatile'|'strictfp';
type = primitive_type brackets*;
primitive_type
= 'boolean'|'byte'|'char'|'short'|'int'|'float'|'long'|'double'
type_ref
= full_class_name
- | generic_identifier 'extends' full_class_name
- | question_mark;
+ | generic_identifier 'extends' type_bound
+ | wildcard;
+type_bound
+ = {tail:} type_bound '&' full_class_name
+ | {head:} full_class_name;
generic_param = '<' generic_parameter_list '>';
generic_parameter_list
property_declaration
= {method:} modifier* generic_param? type method_id '(' parameter_list? ')' throws_declaration? ';'
- | {constructor:} modifier* full_class_name '(' parameter_list? ')' throws_declaration? ';'
+ | {constructor:} modifier* generic_param? full_class_name '(' parameter_list? ')' throws_declaration? ';'
| {attribute:} modifier* type attribute_id throws_declaration? ';'
| {static:} modifier* '{' '}' ';'
| ';';