BNF for edl.jj

NON-TERMINALS

//****************************************
// EDL Grammar
//****************************************

/**
 * Initiates the parse of an event description language (EDL) file.
 *
 * @return A {@link SemanticEventData} object encapsulating the parsed
 *     event specifications.
 */
edlUnit
edlUnit ::= ( suiteDecl ( observablesSection | importDecl )+ <EOF> )

/**
 * Production for EDL import declarations.
 *
 * The imported EDL fragment is processed as if it textually appeared
 * in the importing file. The lexer is reassigned to a stream attached
 * to the imported file, without modifying any other lexer or parser
 * state. When processing of the imported file is completed, the lexer
 * stream is restored to the importing file and processing resumes.
 */
importDecl
importDecl ::= "@import" <STRING_LITERAL>

/**
 * Entry point for processing an imported EDL fragment. An imported
 * fragment cannot contain an "EDLSuite" declaration.
 *
 * This production is never referenced directly in the grammar -- it
 * is only called from the action associated with the importDecl()
 * production.
 */
importEdlUnit
importEdlUnit ::= ( observablesSection | importDecl )+ <EOF>

/**
 * Production for the "EDLSuite" section of an EDL specification.
 *
 * A <WILD_STRING> is a string that can contain nearly every character
 * in the legal input character set except whitespace (the same character
 * set accepted by Java). If whitespace must appear within the token,
 * a (quoted) <STRING_LITERAL> should be used instead.
 */
suiteDecl
suiteDecl ::= "begin" "EDLSuite" ( <STRING_LITERAL> | <WILD_STRING> ) ( array_element_load_bounds__decl | array_element_store_bounds__decl )* "end"

/**
 * Production for global array element load bounds specifications in the
 * EDLSuite header section.
 *
 * A <UINT> is a positive integer (whole number) value, with no
 * leading zeros.
 */
array_element_load_bounds__decl
array_element_load_bounds__decl ::= ( "array_element_load_bounds" ( "*" | argType ) ( ( "min:" <UINT> ( "max:" <UINT> )? ) | ( "max:" <UINT> ( "min:" <UINT> )? ) ) )

/**
 * Production for global array element store bounds specifications in the
 * EDLSuite header section.
 *
 * A <UINT> is a positive integer (whole number) value, with no
 * leading zeros.
 */
array_element_store_bounds__decl
array_element_store_bounds__decl ::= ( "array_element_store_bounds" ( "*" | argType ) ( ( "min:" <UINT> ( "max:" <UINT> )? ) | ( "max:" <UINT> ( "min:" <UINT> )? ) ) )

/**
 * Production for "Observables" sections of an EDL specification.
 *
 * Refer to the documentation of the suiteDecl() production for a definition
 * of the <WILD_STRING> token.
 */
observablesSection
observablesSection ::= "begin" "Observables" ( <STRING_LITERAL> | <WILD_STRING> ) preambleSection ( observableEvent )* "end"

/**
 * Production for the "Preamble" section of "Observable" sections.
 */
preambleSection
preambleSection ::= "begin" "Preamble" preambleDeclarations "end"

/**
 * Production for the declarations permitted in a "Preamble" section.
 */
preambleDeclarations
preambleDeclarations ::= ( "System-classes:" ( <STRING_LITERAL> | <WILD_STRING> ) ) ( ( "Module-classes:" ( <STRING_LITERAL> | <WILD_STRING> ) ) | ( "No-module:" ( <TRUE> | <FALSE> ) ) )? ( "Database-tag:" ( <STRING_LITERAL> | <WILD_STRING> ) )? ( preambleTypedef )*

/**
 * Production for a type-alias ("Type-name:") declaration in a
 * "Preamble" section.
 *
 * Expansions of type aliases can occur in the following locations:
 *   - array element bounds event requests
 *   - argument types in method selection expressions
 *   - class names in event requests and method selection expressions
 *
 * Type aliases cannot be declared for primitive types, or associated
 * to any reserved EDL keywords.
 */
preambleTypedef
preambleTypedef ::= "Type-name:" javaIdentifier ( jniReferenceType | qualifiedName )

/**
 * Production for EDL event requests.
 */
observableEvent
observableEvent ::= ( "+" | "-" ) eventDecl

/**
 * Production for EDL event type requests.
 */
eventDecl
eventDecl ::= ( new_object__decl | construct_object__decl | construct_finish__decl | get_static__decl | put_static__decl | get_field__decl | put_field__decl | constructor_call__decl | static_call__decl | virtual_call__decl | interface_call__decl | virtual_method_enter__decl | virtual_method_exit__decl | static_method_enter__decl | static_method_exit__decl | monitor_contend__decl | monitor_acquire__decl | monitor_pre_release__decl | monitor_release__decl | throw__decl | catch__decl | static_init_enter__decl | array_element_load__decl | array_element_store__decl )

/**
 * Production for EDL new object allocation event requests.
 */
new_object__decl
new_object__decl ::= "new_object" ( "*" | ( qualifiedName ( ".*" )? ) ) locationBlock

/**
 * Production for EDL constructor entry event requests.
 */
construct_object__decl
construct_object__decl ::= "construct_object" ( "*" | ( qualifiedName argsExpr ) )

/**
 * Production for EDL constructor exit event requests.
 */
construct_finish__decl
construct_finish__decl ::= "construct_finish" ( "*" | ( qualifiedName argsExpr ) )

/**
 * Production for EDL static field read event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the field is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 */
get_static__decl
get_static__decl ::= "get_static" qualifiedName ( ".*" )? locationBlock

/**
 * Production for EDL static field write event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the field is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 */
put_static__decl
put_static__decl ::= "put_static" qualifiedName ( ".*" )? locationBlock

/**
 * Production for EDL instance field read event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the field is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 */
get_field__decl
get_field__decl ::= "get_field" qualifiedName ( ".*" )? locationBlock

/**
 * Production for EDL instance field write event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the field is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 */
put_field__decl
put_field__decl ::= "put_field" qualifiedName ( ".*" )? locationBlock

/**
 * Production for EDL constructor call event requests.
 *
 * Constructor calls correspond to the INVOKESPECIAL instruction in the JVM
 * bytecode instruction set.
 */
constructor_call__decl
constructor_call__decl ::= "constructor_call" ( "*" | ( qualifiedName argsExpr ) ) locationBlock

/**
 * Production for EDL static method call event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * Static calls correspond to the INVOKESTATIC instruction in the JVM
 * bytecode instruction set.
 */
static_call__decl
static_call__decl ::= "static_call" ( "#INT" )? ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) ) locationBlock

/**
 * Production for EDL virtual (non-interface) method call event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * Virtual calls correspond to the INVOKEVIRTUAL instruction in the JVM
 * bytecode instruction set.
 */
virtual_call__decl
virtual_call__decl ::= "virtual_call" ( "#INT" )? ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) ) locationBlock

/**
 * Production for EDL interface method call event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * Interface calls correspond to the INVOKEINTERFACE instruction in the JVM
 * bytecode instruction set.
 */
interface_call__decl
interface_call__decl ::= "interface_call" ( "#INT" )? ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) ) locationBlock

/**
 * Production for EDL virtual method entry event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * A virtual method for the purpose of this event is any non-constructor
 * method declared without the "static" modifier (e.g. methods dispatched
 * by either INVOKEVIRTUAL or INVOKEINTERFACE call instructions).
 */
virtual_method_enter__decl
virtual_method_enter__decl ::= "virtual_method_enter" ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) )

/**
 * Production for EDL virtual method exit event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * A virtual method for the purpose of this event is any non-constructor
 * method declared without the "static" modifier (e.g. methods dispatched
 * by either INVOKEVIRTUAL or INVOKEINTERFACE call instructions).
 */
virtual_method_exit__decl
virtual_method_exit__decl ::= "virtual_method_exit" ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) )

/**
 * Production for EDL static method entry event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * A static method for the purpose of this event is any non-constructor
 * method declared with the "static" modifier (e.g. methods dispatched
 * by the INVOKESTATIC call instruction).
 */
static_method_enter__decl
static_method_enter__decl ::= "static_method_enter" ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) )

/**
 * Production for EDL static method exit event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of the method is given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 *
 * A static method for the purpose of this event is any non-constructor
 * method declared with the "static" modifier (e.g. methods dispatched
 * by the INVOKESTATIC call instruction).
 */
static_method_exit__decl
static_method_exit__decl ::= "static_method_exit" ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) )

/**
 * Production for EDL monitor contend events.
 */
monitor_contend__decl
monitor_contend__decl ::= "monitor_contend" ( "*" | ( qualifiedName ( ".*" )? ) ) locationBlock

/**
 * Production for EDL monitor acquired events.
 */
monitor_acquire__decl
monitor_acquire__decl ::= "monitor_acquire" ( "*" | ( qualifiedName ( ".*" )? ) ) locationBlock

/**
 * Production for EDL monitor pending release events.
 */
monitor_pre_release__decl
monitor_pre_release__decl ::= "monitor_pre_release" ( "*" | ( qualifiedName ( ".*" )? ) ) locationBlock

/**
 * Production for EDL monitor released events.
 */
monitor_release__decl
monitor_release__decl ::= "monitor_release" ( "*" | ( qualifiedName ( ".*" )? ) ) locationBlock

/**
 * Production for EDL exception raised events.
 */
throw__decl
throw__decl ::= "throw" ( "*" | ( qualifiedName ( "+s" )? ) ) locationBlock

/**
 * Production for EDL exception caught events.
 */
catch__decl
catch__decl ::= "catch" ( "*" | ( qualifiedName ( "+s" )? ) ) locationBlock

/**
 * Production for EDL static initializer entry event requests.
 */
static_init_enter__decl
static_init_enter__decl ::= "static_init_enter" ( "*" | ( qualifiedName ( ".*" )? ) )

/**
 * Production for EDL array element read event requests.
 *
 * A <UINT> is a positive integer (whole number) value, with no
 * leading zeros.
 */
array_element_load__decl
array_element_load__decl ::= "array_element_load" ( "*" | argType ) ( "min:" <UINT> )? ( "max:" <UINT> )? locationBlock

/**
 * Production for EDL array element write event requests.
 *
 * A <UINT> is a positive integer (whole number) value, with no
 * leading zeros.
 */
array_element_store__decl
array_element_store__decl ::= "array_element_store" ( "*" | argType ) ( "min:" <UINT> )? ( "max:" <UINT> )? locationBlock

/**
 * Production for EDL location constraint blocks for event requests.
 *
 * Because of greedy token matching in the qualifiedName() subrule,
 * the expectation that the name of a method may be given as the string
 * after the final "." in the qualified name string is not formally
 * encoded by the grammar, except in the case of wildcard requests.
 */
locationBlock
locationBlock ::= "{" ( ( "in" | "not" ) ( "*" | ( qualifiedName ( ( ".*" ) | argsExpr ) ) ) )* "}"

/**
 * Production for method argument expressions used in method selection
 * expressions (e.g. for specifying method signatures for matching
 * methods).
 */
argsExpr
argsExpr ::= ( "*" | voidArg | ( argType ( "," argType )* ) | jniMethodSignature )

/**
 * Production for the "void" argument type.
 *
 * The void argument type is really a placeholder expression to express
 * a specific match only with a method taking no arguments. It cannot
 * be combined with any other argument types, thus a separate production.
 */
voidArg
voidArg ::= ( "void" | "V" )

/**
 * Production for an argument type declaration.
 */
argType
argType ::= ( basicTypeName | jniPrimitiveType | ( jniObjectType | jniArrayType | qualifiedName ) )

/**
 * Production for basic type names, provided by EDL for
 * convenience/readability.
 *
 * Note that "string" corresponds internally to "java.lang.String".
 */
basicTypeName
basicTypeName ::= ( "byte" | "char" | "double" | "float" | "int" | "long" | "boolean" | "short" | "string" )

/**
 * Production for JNI format primitive type codes.
 *
 * The type code for void ("V") is omitted for the reason
 * described in the voidArg() production.
 */
jniPrimitiveType
jniPrimitiveType ::= ( "B" | "C" | "D" | "F" | "I" | "J" | "Z" | "S" )

/**
 * Union production for all reference type declarations in JNI format
 * (object and array types).
 */
jniReferenceType
jniReferenceType ::= ( jniArrayType | jniObjectType )

/**
 * Production for array type declarations in JNI format.
 */
jniArrayType
jniArrayType ::= ( "[" )+ ( jniPrimitiveType | jniObjectType )

/**
 * Production for object type declarations in JNI format.
 *
 * The expected "L" prefix is not explicitly enforced by the grammar
 * because of the difficulty in differentiating it from an
 * identifier in the lexer, due to the "maximal munch" rule.
 */
jniObjectType
jniObjectType ::= javaIdentifier ( "/" javaIdentifier )* ";"

/**
 * Production for a method signature declaration in JNI format.
 *
 * The formal specification for the JNI method signature format is as
 * follows:
 *
 * "(" ( jniObjectType() | jniArrayType() | jniPrimitiveType() )* ")"
 *     ( jniObjectType() | jniArrayType() | jniPrimitiveType() | "V" )
 *
 * Due to the considerable complexity in both lexer and parser of
 * disambiguating the various token types and subrules, particularly
 * in the presence of the additional shorthand notations provided by
 * EDL, this production accepts essentially freeform inputs consisting
 * of the characters that may legally appear in a JNI signature. The
 * task of validating the signature is deferred (normally to BCEL).
 *
 * At the current time, EDL ignores the return type component of the
 * signature. It is accepted, however, to reduce the burden for
 * tools that might mechanically generate EDL and would likely want
 * to generate signatures in their full, standard format.
 */
jniMethodSignature
jniMethodSignature ::= "(" ( javaIdentifier | "[" | "/" | ";" )* ")" ( javaIdentifier | "V" | "[" | "/" | ";" )+

/**
 * Production for a package-qualified Java class (type) name.
 */
qualifiedName
qualifiedName ::= ( javaIdentifier ( "." javaIdentifier )* )

/**
 * Production for a basic (unqualified) Java identifier.
 *
 * To improve the efficiency of the parser, the productions
 * basicTypeName() and jniPrimitiveType() are defined. These productions
 * induce distinct token types that take precedence in the lexer over the
 * Java identifier token matching in some contexts. However, they are
 * (at least theoretically) still legal Java identifiers (or constituents
 * of a package name, for which the production is defined in terms
 * of Java identifiers). To ensure that EDL accepts them as Java
 * identifiers in productions that do not involve basicTypeName() and/or
 * jniPrimitiveType() subrules, this production must be provided and
 * used.
 * 
 * In cases where combinations of the ambiguous productions are
 * permitted, syntactic lookead is used to resolve in favor of the
 * more specialized productions (basicTypeName(), jniPrimitiveType()).
 */
javaIdentifier
javaIdentifier ::= ( "string" | "B" | "C" | "D" | "F" | "I" | "J" | "Z" | "S" | <JAVA_ID> )