Go! AOP Pointcuts

Below is an example of a Go! AOP pointcuts grammar.

Grammar

/**
 * This file is a set of rules for parsing (syntax analysis) of pointcut syntax.
 *
 * @see https://github.com/goaop/idea-plugin/blob/1.2.1/src/com/aopphp/go/parser/pointcut.bnf
 */

%pragma root Expression

/**
 * This file is a set of rules for lexical analysis of pointcut syntax.
 *
 * @see https://github.com/goaop/idea-plugin/blob/master/src/com/aopphp/go/parser/PointcutLexer.flex
 */

%token  T_THIS              \$this\b

%token  T_ACCESS            (?<=\b)(?i)access\b
%token  T_EXECUTION         (?<=\b)(?i)execution\b
%token  T_WITHIN            (?<=\b)(?i)within\b
%token  T_INIT              (?<=\b)(?i)initialization\b
%token  T_INIT_STATIC       (?<=\b)(?i)staticInitialization\b
%token  T_CFLOW             (?<=\b)(?i)cFlowBelow\b
%token  T_DYNAMIC           (?<=\b)(?i)dynamic\b
%token  T_MATCH             (?<=\b)(?i)matchInherited\b

%token  T_MOD_PUBLIC        (?<=\b)public\b
%token  T_MOD_PRIVATE       (?<=\b)private\b
%token  T_MOD_PROTECTED     (?<=\b)protected\b
%token  T_MOD_FINAL         (?<=\b)final\b


// Note: Keyword "abstract" does not make sense, because
// because pointcuts cannot be applied on abstract methods
//
// %token  T_MOD_ABSTRACT      (?<=\b)abstract\b

// Note: Keyword "static" does not make sense, because
// access method is controlled through tokens "->" and "::"
//
// %token  T_MOD_STATIC        (?<=\b)static\b

%token  T_NS_SEPARATOR      \\
%token  T_ANNOTATION        @
%token  T_LEFT_PAREN        \(
%token  T_RIGHT_PAREN       \)

%token  T_OBJECT_ACCESS     \->
%token  T_STATIC_ACCESS     ::

%token  T_DOUBLE_ASTERISK   \*\*
%token  T_ASTERISK          \*
%token  T_SUBNAMESPACE_SIGN \+

%token  T_ALTERNATION       \|
%token  T_NEGATION          !
%token  T_LOGICAL_OR        \|\|
%token  T_LOGICAL_AND       &&
%token  T_RETURN_HINT       :

%token  T_NAME              \w+

%skip   T_COMMENT           //[^\n]+
%skip   T_WHITESPACE        \s+

NamespacePattern
  : NamespacePatternPart() (
      ::T_NS_SEPARATOR:: NamespacePatternPart()
    )*
  ;

NamePattern
  : NamePatternPart() (
      ::T_ALTERNATION:: NamePatternPart()
    )*
  ;

// -----------------------------------------------------------------------------

NamespacePatternPart
  : NamePatternPart()
  | AnyNamespacedWord()
  ;

NamePatternPart
  : NamePatternItem()+
  ;

NamePatternItem
  : AnyWord()
  | Name()
  ;

AnyNamespacedWord
  : <T_DOUBLE_ASTERISK>
  ;

AnyWord
  : <T_ASTERISK>
  ;

Name
  : <T_ACCESS>
  | <T_EXECUTION>
  | <T_WITHIN>
  | <T_INIT>
  | <T_INIT_STATIC>
  | <T_CFLOW>
  | <T_DYNAMIC>
  | <T_MATCH>
  | <T_MOD_PUBLIC>
  | <T_MOD_PRIVATE>
  | <T_MOD_PROTECTED>
  | <T_MOD_FINAL>
  | <T_NAME>
  ;

MethodModifiers
  : AccessModifierExpression() BehaviourModifierExpression()?
  | BehaviourModifierExpression() AccessModifierExpression()?
  ;

PropertyModifiers
  : AccessModifierExpression()
  ;

//
// -----------------------------------------------------------------------------
//  final
// -----------------------------------------------------------------------------
//

BehaviourModifierExpression
  : BehaviourModifierNegation()
  | BehaviourModifier()
  ;

BehaviourModifierNegation
  : ::T_NEGATION:: BehaviourModifier()
  ;

BehaviourModifier
  : <T_MOD_FINAL>
  ;

//
// -----------------------------------------------------------------------------
//  private|public|protected
// -----------------------------------------------------------------------------
//

AccessModifierExpression
  : AccessModifier() (
      ::T_ALTERNATION:: AccessModifier()
    )*
  ;

AccessModifier
  : <T_MOD_PUBLIC>
  | <T_MOD_PRIVATE>
  | <T_MOD_PROTECTED>
  ;

Pointcut
  : AccessPointcut()
  | AnnotatedAccessPointcut()
  | ExecutionPointcut()
  | AnnotatedExecutionPointcut()
  | WithinPointcut()
  | AnnotatedWithinPointcut()
  | InitializationPointcut()
  | StaticInitializationPointcut()
  | ControlFlowBelowPointcut()
  | DynamicExecutionPointcut()
  | MatchInheritedPointcut()
  | PointcutReference()
  ;

AccessPointcut
  : ::T_ACCESS:: ::T_LEFT_PAREN::
      PropertyDefinition()
    ::T_RIGHT_PAREN::
  ;

AnnotatedAccessPointcut
  : ::T_ANNOTATION:: ::T_ACCESS:: ::T_LEFT_PAREN::
      ClassDefinition()
    ::T_RIGHT_PAREN::
  ;

ExecutionPointcut
  : ::T_EXECUTION:: ::T_LEFT_PAREN:: (
      FunctionDefinition() |
      MethodDefinition()
    ) ::T_RIGHT_PAREN::
  ;

AnnotatedExecutionPointcut
  : ::T_ANNOTATION:: ::T_EXECUTION:: ::T_LEFT_PAREN::
      ClassDefinition()
    ::T_RIGHT_PAREN::
  ;

WithinPointcut
  : ::T_WITHIN:: ::T_LEFT_PAREN::
      ClassFilter()
    ::T_RIGHT_PAREN::
  ;

AnnotatedWithinPointcut
  : ::T_ANNOTATION:: ::T_WITHIN:: ::T_LEFT_PAREN::
      ClassDefinition()
    ::T_RIGHT_PAREN::
  ;

InitializationPointcut
  : ::T_INIT:: ::T_LEFT_PAREN::
      ClassFilter()
    ::T_RIGHT_PAREN::
  ;

StaticInitializationPointcut
  : ::T_INIT_STATIC:: ::T_LEFT_PAREN::
      ClassFilter()
    ::T_RIGHT_PAREN::
  ;

ControlFlowBelowPointcut
  : ::T_CFLOW:: ::T_LEFT_PAREN::
      ExecutionPointcut()
    ::T_RIGHT_PAREN::
  ;

DynamicExecutionPointcut
  : ::T_DYNAMIC:: ::T_LEFT_PAREN::
      MethodDefinition()
    ::T_RIGHT_PAREN::
  ;

MatchInheritedPointcut
  : ::T_MATCH:: ::T_LEFT_PAREN:: ::T_RIGHT_PAREN::
  ;

PointcutReference
  : PointcutReferenceContext() ::T_OBJECT_ACCESS:: PropertyDefinitionBody()
  ;

PointcutReferenceContext
  : NamespacePattern()
  | <T_THIS>
  ;

//
// -----------------------------------------------------------------------------
//  Access Modifiers
// -----------------------------------------------------------------------------
//

AccessType
  : ObjectAccess()
  | StaticAccess()
  ;

ObjectAccess
  : <T_OBJECT_ACCESS>
  ;

StaticAccess
  : <T_STATIC_ACCESS>
  ;

//
// -----------------------------------------------------------------------------
//  Function Reference
// -----------------------------------------------------------------------------
//

FunctionDefinition
  : NamePattern() FunctionDefinitionArguments()
  ;

FunctionDefinitionArguments
  : FunctionAnyArguments()
  | FunctionNoArguments()
  ;

FunctionNoArguments
  : ::T_LEFT_PAREN:: ::T_RIGHT_PAREN::
  ;

FunctionAnyArguments
  : ::T_LEFT_PAREN:: ::T_ASTERISK:: ::T_RIGHT_PAREN::
  ;

//
// -----------------------------------------------------------------------------
//  Property Reference
// -----------------------------------------------------------------------------
//

PropertyDefinition
  : PropertyModifiers()?
    ClassFilter() AccessType() PropertyDefinitionBody()
  ;

PropertyDefinitionBody
  : NamePattern()
  ;

//
// -----------------------------------------------------------------------------
//  Method Reference
// -----------------------------------------------------------------------------
//

MethodDefinition
  : MethodModifiers()?
    ClassFilter() AccessType() FunctionDefinition()
  ;

//
// -----------------------------------------------------------------------------
//  Class Reference
// -----------------------------------------------------------------------------
//

ClassDefinition
  : NamespacePattern()
  ;

ClassInstanceOfDefinition
  : NamespacePattern() ::T_SUBNAMESPACE_SIGN::
  ;

ClassFilter
  : ClassInstanceOfDefinition()
  | ClassDefinition()
  ;

Expression
  : AlternatedExpression()?
  ;

AlternatedExpression
  : ConjugatedExpression() (::T_LOGICAL_OR:: ConjugatedExpression())+
  | ConjugatedExpression()
  ;

ConjugatedExpression
  : NegatedExpression() (::T_LOGICAL_AND:: NegatedExpression())+
  | NegatedExpression()
  ;

NegatedExpression
  : ::T_NEGATION:: GroupExpression()
  | GroupExpression()
  ;

GroupExpression
  : ::T_LEFT_PAREN:: Expression() ::T_RIGHT_PAREN::
  | SinglePointcut()
  ;

SinglePointcut
  : Pointcut()
  ;