<commit_before>parser grammar MaslSortParser;

options
{
  tokenVocab=MaslLexer;
  output=AST;
}

@annotations
{
@SuppressWarnings("all")
}

@header
{
import java.util.Collections;
}

@members
{

// buffer for the file
private StringBuilder buf = null;

// public getter for buffer
public String getResult() {
    if ( buf == null ) return "";
    return buf.toString();
}

// private method to add to the buffer
private void appendChunk( StringBuilder block, ArrayList<String> chunk ) {
    if ( chunk == null || block == null ) return;

    // sort the chunk
    Collections.sort( chunk );

    // append each string to the block
    for ( String s : chunk ) {
        block.append( " " );
        block.append( s );
        block.append( "\n" );
    }
}

// private method for adding to the current chunk
private void addToChunk( ArrayList<String> chunk, String value ) {
    chunk.add( value );
}

}

target                        
@init { buf = new StringBuilder(); }
                              : definition+;

definition                    : projectDefinition
                              | domainDefinition { buf.append( $domainDefinition.result ); }
                              | objectServiceDefinition 
                              | objectFunctionDefinition 
                              | stateDefinition
                              | domainServiceDefinition 
                              | domainFunctionDefinition 
                              | terminatorServiceDefinition 
                              | terminatorFunctionDefinition 
                              ;

//---------------------------------------------------------
// Project Definition
//---------------------------------------------------------

projectDefinition             : PROJECT projectName IS
                                 projectItem*
                                END PROJECT? SEMI pragmaList                              
                              ;

projectItem                   : domainPrjDefinition
                              ;

domainPrjDefinition
                              : DOMAIN domainName IS
                                  domainPrjItem* 
                                END DOMAIN? SEMI pragmaList                               
                              ;

domainPrjItem                 : terminatorDefinition
                              ;

projectName                   : identifier                                               
                              ;


//---------------------------------------------------------
// Domain Definition
//---------------------------------------------------------

domainDefinition
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> object_decl = new ArrayList<String>();
  ArrayList<String> type_decl = new ArrayList<String>();
  ArrayList<String> types = new ArrayList<String>();
  ArrayList<String> services = new ArrayList<String>();
  ArrayList<String> terminators = new ArrayList<String>();
  ArrayList<String> relationships = new ArrayList<String>();
  ArrayList<String> objects = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, object_decl );
  appendChunk( block, type_decl );
  appendChunk( block, types );
  appendChunk( block, services );
  appendChunk( block, terminators );
  appendChunk( block, relationships );
  appendChunk( block, objects );
  $result = begin + " " + block.toString() + " " + end;
}
                              : domainDefinitionBegin { begin = $domainDefinitionBegin.text; }
                                (objectDeclaration { addToChunk( object_decl, $objectDeclaration.text ); }
                                | domainServiceDeclaration { addToChunk( services, $domainServiceDeclaration.text ); }        
                                | domainFunctionDeclaration { addToChunk( services, $domainFunctionDeclaration.text ); }       
                                | terminatorDefinition { addToChunk( terminators, $terminatorDefinition.result ); }       
                                | relationshipDefinition { addToChunk( relationships, $relationshipDefinition.result ); }
                                | objectDefinition { addToChunk( objects, $objectDefinition.result ); }
                                | typeForwardDeclaration { addToChunk( type_decl, $typeForwardDeclaration.text ); }
                                | typeDeclaration { addToChunk( types, $typeDeclaration.text ); }
                                | exceptionDeclaration { /*addToChunk( exceptions, $exceptionDeclaration.text );*/ } )*
                                domainDefinitionEnd { end = $domainDefinitionEnd.text; }
                              ; 

domainDefinitionBegin         : DOMAIN domainName IS
                              ;

domainDefinitionEnd           : END DOMAIN? SEMI pragmaList
                              ;

domainName                    : identifier                                                
                              ;


//---------------------------------------------------------
// Exception Declaration
//---------------------------------------------------------
exceptionDeclaration          : exceptionVisibility EXCEPTION exceptionName 
                                SEMI pragmaList                                           
                              ;

exceptionName                 : identifier                                                
                              ;

exceptionVisibility           : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;

//---------------------------------------------------------
// Type Definition
//---------------------------------------------------------

typeForwardDeclaration        : typeVisibility TYPE typeName SEMI pragmaList              
                              ;

typeDeclaration               : typeVisibility TYPE typeName IS
                                typeDef=typeDefinition SEMI pragmaList                          
                                                                                                
                              ;

typeDefinition                : structureTypeDefinition
                              | enumerationTypeDefinition
                              | constrainedTypeDefinition
                              | typeReferenceWithCA
                              | unconstrainedArrayDefinition
                              ;

typeVisibility                : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;



// Constrained Type
constrainedTypeDefinition     : namedTypeRef typeConstraint                               
                              ;

typeConstraint                : rangeConstraint
                              | deltaConstraint
                              | digitsConstraint
                              ;

rangeConstraint               : RANGE expression                                          
                              ;

deltaConstraint               : DELTA constExpression rangeConstraint                     
                              ;

digitsConstraint              : DIGITS constExpression rangeConstraint                    
                              ;

// Structure Type
structureTypeDefinition       : STRUCTURE 
                                  structureComponentDefinition+ 
                                END STRUCTURE?                                            
                              ;

structureComponentDefinition  : componentName COLON typeReference 
                                (ASSIGN defaultValue=constExpression)?
                                SEMI pragmaList                                           
                              ;

componentName                 : identifier                                                
                              ;


// Enumeration Type
enumerationTypeDefinition     : ENUM LPAREN 
                                  enumerator ( COMMA enumerator )*
                                RPAREN                                                    
                              ;

enumerator                    : enumeratorName ( (EQUAL|ASSIGN) constExpression )?        
                              ;

enumeratorName                : identifier                                                
                              ;


// Unconstrained array
unconstrainedArrayDefinition  : ARRAY LPAREN 
                                  indexType=indexTypeReference RANGE LTGT 
                                RPAREN 
                                OF arrayOf=typeReference                                  
                              ;


indexTypeReference            : namedTypeRef
                              ;

//---------------------------------------------------------
// Type Reference
//---------------------------------------------------------

/*
typeReference
                              : namedTypeRef                                              
                              | instanceTypeRef                                           
                              | collectionTypeRef                                         
                              | deprecatedType                                            
                              ;
                              */

typeReference
                              : named=namedTypeRef                                        
                              | inst=instanceTypeRef                                      
                              | col=collectionTypeRef                                     
                              | depr=deprecatedType                                       
                              ;

typeReferenceWithCA           : typeReference                                             
                              | constrainedArrayTypeRef                                   
                              ;

deprecatedType                : INSTANCE                                                  
                              | EVENT                                                     
                              | SERVICE                                                   
                              ;


qualifiedObjectName           : (domainName SCOPE)? objectName                            
                              ;

instanceTypeRef               : ANONYMOUS? INSTANCE OF qualifiedObjectName                
                              ;

namedTypeRef                  : ANONYMOUS? (domainName SCOPE)? typeName                   
                              ;

userDefinedTypeRef            : (domainName SCOPE)? typeName                              
                              ;

constrainedArrayTypeRef       : userDefinedTypeRef arrayBounds                            
                              ;

typeName                      : identifier                                                
                              ;

arrayBounds                   : LPAREN expression RPAREN                                  
                              ;



collectionTypeRef             : ANONYMOUS? SEQUENCE 
                              		(LPAREN expression RPAREN)? OF typeReference            
                              | ANONYMOUS? ARRAY arrayBounds OF typeReference             
                              | ANONYMOUS? SET OF typeReference                           
                              | ANONYMOUS? BAG OF typeReference                           
                              | ANONYMOUS? DICTIONARY 
                                ( dictKeyType? OF dictValueType )?                        
                              ;

dictKeyType                   : namedTypeRef												
			      | instanceTypeRef																					  
			      ;

dictValueType                 : typeReference																							
			      ;

//---------------------------------------------------------
// Terminator Definition
//---------------------------------------------------------

terminatorName                : identifier                                                
                              ;

terminatorDefinition          
returns[String result]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> services = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, services );
  $result = begin + " " + block.toString() + " " + end;
}
                              : terminatorDefinitionBegin { begin = $terminatorDefinitionBegin.text; }
                                (terminatorServiceDeclaration { addToChunk( services, $terminatorServiceDeclaration.text ); }
                                | terminatorFunctionDeclaration { addToChunk( services, $terminatorFunctionDeclaration.text ); } )*
                                terminatorDefinitionEnd { end = $terminatorDefinitionEnd.text; }
                              ;

terminatorDefinitionBegin     : TERMINATOR terminatorName IS
                              ;

terminatorDefinitionEnd       : END TERMINATOR? SEMI pragmaList                           
                              ;

terminatorServiceDeclaration  : serviceVisibility SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

terminatorFunctionDeclaration : serviceVisibility FUNCTION serviceName 
                                  parameterList RETURN returnType 
                                  SEMI pragmaList                                         
                              ;

//---------------------------------------------------------
// Object Definition
//---------------------------------------------------------

objectName                    : identifier                                                
                              ;

attributeName                 : identifier                                                
                              ;

objectDeclaration             : OBJECT objectName SEMI pragmaList                         
                              ;


objectDefinition              
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> attrs = new ArrayList<String>();
  ArrayList<String> ids = new ArrayList<String>();
  ArrayList<String> services = new ArrayList<String>();
  ArrayList<String> states = new ArrayList<String>();
  ArrayList<String> events = new ArrayList<String>();
  ArrayList<String> trans_tables = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, attrs );
  appendChunk( block, ids );
  appendChunk( block, services );
  appendChunk( block, states );
  appendChunk( block, events );
  appendChunk( block, trans_tables );
  $result = begin + " " + block.toString() + " " + end;
}
                              : objectDefinitionBegin { begin = $objectDefinitionBegin.text; }
                                (attributeDefinition { addToChunk( attrs, $attributeDefinition.text ); }
                                | identifierDefinition { addToChunk( ids, $identifierDefinition.text ); }
                                | objectServiceDeclaration { addToChunk( services, $objectServiceDeclaration.text ); }
                                | objectFunctionDeclaration { addToChunk( services, $objectFunctionDeclaration.text ); }
                                | eventDefinition { addToChunk( events, $eventDefinition.text ); }
                                | stateDeclaration { addToChunk( states, $stateDeclaration.text ); }
                                | transitionTable { addToChunk( trans_tables, $transitionTable.result ); })*
                                objectDefinitionEnd { end = $objectDefinitionEnd.text; }
                              ;

objectDefinitionBegin         : startDec=OBJECT objectName IS
                              ;

objectDefinitionEnd          : END OBJECT? SEMI pragmaList                               
                              ;

attributeDefinition           : attributeName COLON 
                                attModifiers attReferentials? typeReference 
                                (ASSIGN defaultValue=constExpression)? 
                                SEMI pragmaList                                           
                              ;

attModifiers                  : PREFERRED? UNIQUE?;

attReferentials               : REFERENTIAL 
                                LPAREN
                                  attReferential ( COMMA attReferential )*
                                RPAREN                                                    
                              ;

attReferential                : relationshipSpec 
                                DOT attributeName                                         
                              ;

relationshipSpec              : relationshipName
                                  ( DOT objOrRole=identifier
                                    (DOT objectName)?
                                  )?                                                      
                              ;


objectServiceDeclaration      : serviceVisibility serviceType SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

objectFunctionDeclaration     : serviceVisibility serviceType FUNCTION serviceName 
                                  parameterList 
                                  RETURN returnType SEMI pragmaList                       
                              ;

serviceType                   : (INSTANCE (DEFERRED LPAREN relationshipName RPAREN)?)?  
                              ;

identifierDefinition          : IDENTIFIER IS
                                LPAREN 
                                attributeName ( COMMA attributeName )*
                                RPAREN SEMI pragmaList                                    
                              ;

eventDefinition               : eventType EVENT eventName parameterList SEMI pragmaList   
                              ; 
eventName                     : identifier                                                
                              ;

eventType                     : ASSIGNER                                                  
                              | CREATION                                                  
                              | /* blank */                                               
                              ;

stateDeclaration              : stateType STATE stateName parameterList SEMI pragmaList  
                              ; 

stateName                     : identifier                                                
                              ;

stateType                     : ASSIGNER                                                  
                              | ASSIGNER START                                            
                              | CREATION                                                  
                              | TERMINAL                                                  
                              | /* blank */                                               
                              ;


transitionTable               
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> rows = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, rows );
  $result = begin + "\n" + block.toString() + " " + end;
}
                              : transitionTableBegin { begin = $transitionTableBegin.text; }
                                  (transitionRow { addToChunk( rows, $transitionRow.result ); } )+ 
                                transitionTableEnd { end = $transitionTableEnd.text; }
                              ;

transitionTableBegin          : transTableType TRANSITION IS 
                              ;

transitionTableEnd            : END TRANSITION SEMI pragmaList                            
                              ;

transTableType                : ASSIGNER                                                  
                              | /* blank */                                               
                              ;

transitionRow
returns[String result]
@init {
  ArrayList<String> tos = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  Collections.sort( tos );
  $result = begin;
  String separator = "";
  for ( String s : tos ) {
    $result += separator + s;
    separator = ",\n";
  }
  $result += end;
}
                              : transitionRowBegin { begin = $transitionRowBegin.text; }
                                  to=transitionOption { addToChunk( tos, $to.text ); } (COMMA next_to=transitionOption { addToChunk( tos, $next_to.text ); } )*
                                transitionRowEnd { end = $transitionRowEnd.text; }
                              ;

transitionRowBegin            : startState LPAREN 
                              ;

transitionRowEnd              : RPAREN SEMI pragmaList                                    
                              ;

transitionOption              : incomingEvent GOES_TO endState                            
                              ;

incomingEvent                 : (objectName DOT)? eventName                               
                              ;

startState                    : NON_EXISTENT                                              
                              | stateName                                                 
                              ;

endState                      : stateName                                                 
                              | IGNORE                                                    
                              | CANNOT_HAPPEN                                             
                              ;

//---------------------------------------------------------
// Service Declaration
//---------------------------------------------------------

domainServiceDeclaration      : serviceVisibility SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

domainFunctionDeclaration     : serviceVisibility FUNCTION serviceName 
                                  parameterList 
                                  RETURN returnType SEMI pragmaList                       
                              ;


parameterList                 : LPAREN
                                  parameterDefinition? ( COMMA parameterDefinition )*                          
                                RPAREN                                                    
                              ;


parameterDefinition           : parameterName COLON parameterMode parameterType           
                              ;


serviceVisibility             : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;
        
parameterMode                 : IN
                              | OUT
                              ;


serviceName                   : identifier                                                
                              ;

parameterName                 : identifier                                                <commit_msg>job #8249 updated masl sort utility to add 'public' where left out to remove ambiguity<commit_after>parser grammar MaslSortParser;

options
{
  tokenVocab=MaslLexer;
  output=AST;
}

@annotations
{
@SuppressWarnings("all")
}

@header
{
import java.util.Collections;
import java.util.regex.*;
}

@members
{

// buffer for the file
private StringBuilder buf = null;

// public getter for buffer
public String getResult() {
    if ( buf == null ) return "";
    return buf.toString();
}

// private method to add to the buffer
private void appendChunk( StringBuilder block, ArrayList<String> chunk ) {
    if ( chunk == null || block == null ) return;

    // sort the chunk
    Collections.sort( chunk );

    // append each string to the block
    for ( String s : chunk ) {
        block.append( " " );
        block.append( s );
        block.append( "\n" );
    }
}

// private method for adding to the current chunk
private void addToChunk( ArrayList<String> chunk, String value ) {
    chunk.add( value );
}

}

target                        
@init { buf = new StringBuilder(); }
                              : definition+;

definition                    : projectDefinition
                              | domainDefinition { buf.append( $domainDefinition.result ); }
                              | objectServiceDefinition 
                              | objectFunctionDefinition 
                              | stateDefinition
                              | domainServiceDefinition 
                              | domainFunctionDefinition 
                              | terminatorServiceDefinition 
                              | terminatorFunctionDefinition 
                              ;

//---------------------------------------------------------
// Project Definition
//---------------------------------------------------------

projectDefinition             : PROJECT projectName IS
                                 projectItem*
                                END PROJECT? SEMI pragmaList                              
                              ;

projectItem                   : domainPrjDefinition
                              ;

domainPrjDefinition
                              : DOMAIN domainName IS
                                  domainPrjItem* 
                                END DOMAIN? SEMI pragmaList                               
                              ;

domainPrjItem                 : terminatorDefinition
                              ;

projectName                   : identifier                                               
                              ;


//---------------------------------------------------------
// Domain Definition
//---------------------------------------------------------

domainDefinition
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> object_decl = new ArrayList<String>();
  ArrayList<String> type_decl = new ArrayList<String>();
  ArrayList<String> types = new ArrayList<String>();
  ArrayList<String> exceptions = new ArrayList<String>();
  ArrayList<String> services = new ArrayList<String>();
  ArrayList<String> terminators = new ArrayList<String>();
  ArrayList<String> relationships = new ArrayList<String>();
  ArrayList<String> objects = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, object_decl );
  appendChunk( block, type_decl );
  appendChunk( block, types );
  appendChunk( block, exceptions );
  appendChunk( block, services );
  appendChunk( block, terminators );
  appendChunk( block, relationships );
  appendChunk( block, objects );
  $result = begin + " " + block.toString() + " " + end;
}
                              : domainDefinitionBegin { begin = $domainDefinitionBegin.text; }
                                (objectDeclaration { addToChunk( object_decl, $objectDeclaration.text ); }
                                | domainServiceDeclaration { addToChunk( services, $domainServiceDeclaration.result ); }        
                                | domainFunctionDeclaration { addToChunk( services, $domainFunctionDeclaration.result ); }       
                                | terminatorDefinition { addToChunk( terminators, $terminatorDefinition.result ); }       
                                | relationshipDefinition { addToChunk( relationships, $relationshipDefinition.result ); }
                                | objectDefinition { addToChunk( objects, $objectDefinition.result ); }
                                | typeForwardDeclaration { addToChunk( type_decl, $typeForwardDeclaration.text ); }
                                | typeDeclaration { addToChunk( types, $typeDeclaration.result ); }
                                | exceptionDeclaration { addToChunk( exceptions, $exceptionDeclaration.result ); } )*
                                domainDefinitionEnd { end = $domainDefinitionEnd.text; }
                              ; 

domainDefinitionBegin         : DOMAIN domainName IS
                              ;

domainDefinitionEnd           : END DOMAIN? SEMI pragmaList
                              ;

domainName                    : identifier                                                
                              ;


//---------------------------------------------------------
// Exception Declaration
//---------------------------------------------------------
exceptionDeclaration          
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : exceptionVisibility EXCEPTION exceptionName 
                                SEMI pragmaList                                           
                              ;

exceptionName                 : identifier                                                
                              ;

exceptionVisibility           : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;

//---------------------------------------------------------
// Type Definition
//---------------------------------------------------------

typeForwardDeclaration        : typeVisibility TYPE typeName SEMI pragmaList              
                              ;

typeDeclaration
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : typeVisibility TYPE typeName IS
                                typeDef=typeDefinition SEMI pragmaList                          
                                                                                                
                              ;

typeDefinition                : structureTypeDefinition
                              | enumerationTypeDefinition
                              | constrainedTypeDefinition
                              | typeReferenceWithCA
                              | unconstrainedArrayDefinition
                              ;

typeVisibility                : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;



// Constrained Type
constrainedTypeDefinition     : namedTypeRef typeConstraint                               
                              ;

typeConstraint                : rangeConstraint
                              | deltaConstraint
                              | digitsConstraint
                              ;

rangeConstraint               : RANGE expression                                          
                              ;

deltaConstraint               : DELTA constExpression rangeConstraint                     
                              ;

digitsConstraint              : DIGITS constExpression rangeConstraint                    
                              ;

// Structure Type
structureTypeDefinition       : STRUCTURE 
                                  structureComponentDefinition+ 
                                END STRUCTURE?                                            
                              ;

structureComponentDefinition  : componentName COLON typeReference 
                                (ASSIGN defaultValue=constExpression)?
                                SEMI pragmaList                                           
                              ;

componentName                 : identifier                                                
                              ;


// Enumeration Type
enumerationTypeDefinition     : ENUM LPAREN 
                                  enumerator ( COMMA enumerator )*
                                RPAREN                                                    
                              ;

enumerator                    : enumeratorName ( (EQUAL|ASSIGN) constExpression )?        
                              ;

enumeratorName                : identifier                                                
                              ;


// Unconstrained array
unconstrainedArrayDefinition  : ARRAY LPAREN 
                                  indexType=indexTypeReference RANGE LTGT 
                                RPAREN 
                                OF arrayOf=typeReference                                  
                              ;


indexTypeReference            : namedTypeRef
                              ;

//---------------------------------------------------------
// Type Reference
//---------------------------------------------------------

/*
typeReference
                              : namedTypeRef                                              
                              | instanceTypeRef                                           
                              | collectionTypeRef                                         
                              | deprecatedType                                            
                              ;
                              */

typeReference
                              : named=namedTypeRef                                        
                              | inst=instanceTypeRef                                      
                              | col=collectionTypeRef                                     
                              | depr=deprecatedType                                       
                              ;

typeReferenceWithCA           : typeReference                                             
                              | constrainedArrayTypeRef                                   
                              ;

deprecatedType                : INSTANCE                                                  
                              | EVENT                                                     
                              | SERVICE                                                   
                              ;


qualifiedObjectName           : (domainName SCOPE)? objectName                            
                              ;

instanceTypeRef               : ANONYMOUS? INSTANCE OF qualifiedObjectName                
                              ;

namedTypeRef                  : ANONYMOUS? (domainName SCOPE)? typeName                   
                              ;

userDefinedTypeRef            : (domainName SCOPE)? typeName                              
                              ;

constrainedArrayTypeRef       : userDefinedTypeRef arrayBounds                            
                              ;

typeName                      : identifier                                                
                              ;

arrayBounds                   : LPAREN expression RPAREN                                  
                              ;



collectionTypeRef             : ANONYMOUS? SEQUENCE 
                              		(LPAREN expression RPAREN)? OF typeReference            
                              | ANONYMOUS? ARRAY arrayBounds OF typeReference             
                              | ANONYMOUS? SET OF typeReference                           
                              | ANONYMOUS? BAG OF typeReference                           
                              | ANONYMOUS? DICTIONARY 
                                ( dictKeyType? OF dictValueType )?                        
                              ;

dictKeyType                   : namedTypeRef												
			      | instanceTypeRef																					  
			      ;

dictValueType                 : typeReference																							
			      ;

//---------------------------------------------------------
// Terminator Definition
//---------------------------------------------------------

terminatorName                : identifier                                                
                              ;

terminatorDefinition          
returns[String result]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> services = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, services );
  $result = begin + " " + block.toString() + " " + end;
}
                              : terminatorDefinitionBegin { begin = $terminatorDefinitionBegin.text; }
                                (terminatorServiceDeclaration { addToChunk( services, $terminatorServiceDeclaration.result ); }
                                | terminatorFunctionDeclaration { addToChunk( services, $terminatorFunctionDeclaration.result ); } )*
                                terminatorDefinitionEnd { end = $terminatorDefinitionEnd.text; }
                              ;

terminatorDefinitionBegin     : TERMINATOR terminatorName IS
                              ;

terminatorDefinitionEnd       : END TERMINATOR? SEMI pragmaList                           
                              ;

terminatorServiceDeclaration  
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

terminatorFunctionDeclaration 
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility FUNCTION serviceName 
                                  parameterList RETURN returnType 
                                  SEMI pragmaList                                         
                              ;

//---------------------------------------------------------
// Object Definition
//---------------------------------------------------------

objectName                    : identifier                                                
                              ;

attributeName                 : identifier                                                
                              ;

objectDeclaration             : OBJECT objectName SEMI pragmaList                         
                              ;


objectDefinition              
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> attrs = new ArrayList<String>();
  ArrayList<String> ids = new ArrayList<String>();
  ArrayList<String> services = new ArrayList<String>();
  ArrayList<String> states = new ArrayList<String>();
  ArrayList<String> events = new ArrayList<String>();
  ArrayList<String> trans_tables = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, attrs );
  appendChunk( block, ids );
  appendChunk( block, services );
  appendChunk( block, states );
  appendChunk( block, events );
  appendChunk( block, trans_tables );
  $result = begin + " " + block.toString() + " " + end;
}
                              : objectDefinitionBegin { begin = $objectDefinitionBegin.text; }
                                (attributeDefinition { addToChunk( attrs, $attributeDefinition.text ); }
                                | identifierDefinition { addToChunk( ids, $identifierDefinition.text ); }
                                | objectServiceDeclaration { addToChunk( services, $objectServiceDeclaration.result ); }
                                | objectFunctionDeclaration { addToChunk( services, $objectFunctionDeclaration.result ); }
                                | eventDefinition { addToChunk( events, $eventDefinition.text ); }
                                | stateDeclaration { addToChunk( states, $stateDeclaration.text ); }
                                | transitionTable { addToChunk( trans_tables, $transitionTable.result ); })*
                                objectDefinitionEnd { end = $objectDefinitionEnd.text; }
                              ;

objectDefinitionBegin         : startDec=OBJECT objectName IS
                              ;

objectDefinitionEnd          : END OBJECT? SEMI pragmaList                               
                              ;

attributeDefinition           : attributeName COLON 
                                attModifiers attReferentials? typeReference 
                                (ASSIGN defaultValue=constExpression)? 
                                SEMI pragmaList                                           
                              ;

attModifiers                  : PREFERRED? UNIQUE?;

attReferentials               : REFERENTIAL 
                                LPAREN
                                  attReferential ( COMMA attReferential )*
                                RPAREN                                                    
                              ;

attReferential                : relationshipSpec 
                                DOT attributeName                                         
                              ;

relationshipSpec              : relationshipName
                                  ( DOT objOrRole=identifier
                                    (DOT objectName)?
                                  )?                                                      
                              ;


objectServiceDeclaration      
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility serviceType SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

objectFunctionDeclaration     
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility serviceType FUNCTION serviceName 
                                  parameterList 
                                  RETURN returnType SEMI pragmaList                       
                              ;

serviceType                   : (INSTANCE (DEFERRED LPAREN relationshipName RPAREN)?)?  
                              ;

identifierDefinition          : IDENTIFIER IS
                                LPAREN 
                                attributeName ( COMMA attributeName )*
                                RPAREN SEMI pragmaList                                    
                              ;

eventDefinition               : eventType EVENT eventName parameterList SEMI pragmaList   
                              ; 
eventName                     : identifier                                                
                              ;

eventType                     : ASSIGNER                                                  
                              | CREATION                                                  
                              | /* blank */                                               
                              ;

stateDeclaration              : stateType STATE stateName parameterList SEMI pragmaList  
                              ; 

stateName                     : identifier                                                
                              ;

stateType                     : ASSIGNER                                                  
                              | ASSIGNER START                                            
                              | CREATION                                                  
                              | TERMINAL                                                  
                              | /* blank */                                               
                              ;


transitionTable               
returns[ String result ]
@init { 
  StringBuilder block = new StringBuilder();
  ArrayList<String> rows = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  appendChunk( block, rows );
  $result = begin + "\n" + block.toString() + " " + end;
}
                              : transitionTableBegin { begin = $transitionTableBegin.text; }
                                  (transitionRow { addToChunk( rows, $transitionRow.result ); } )+ 
                                transitionTableEnd { end = $transitionTableEnd.text; }
                              ;

transitionTableBegin          : transTableType TRANSITION IS 
                              ;

transitionTableEnd            : END TRANSITION SEMI pragmaList                            
                              ;

transTableType                : ASSIGNER                                                  
                              | /* blank */                                               
                              ;

transitionRow
returns[String result]
@init {
  ArrayList<String> tos = new ArrayList<String>();
  String begin = "";
  String end = "";
}
@after {
  Collections.sort( tos );
  $result = begin;
  String separator = "";
  for ( String s : tos ) {
    $result += separator + s;
    separator = ",\n";
  }
  $result += end;
}
                              : transitionRowBegin { begin = $transitionRowBegin.text; }
                                  to=transitionOption { addToChunk( tos, $to.text ); } (COMMA next_to=transitionOption { addToChunk( tos, $next_to.text ); } )*
                                transitionRowEnd { end = $transitionRowEnd.text; }
                              ;

transitionRowBegin            : startState LPAREN 
                              ;

transitionRowEnd              : RPAREN SEMI pragmaList                                    
                              ;

transitionOption              : incomingEvent GOES_TO endState                            
                              ;

incomingEvent                 : (objectName DOT)? eventName                               
                              ;

startState                    : NON_EXISTENT                                              
                              | stateName                                                 
                              ;

endState                      : stateName                                                 
                              | IGNORE                                                    
                              | CANNOT_HAPPEN                                             
                              ;

//---------------------------------------------------------
// Service Declaration
//---------------------------------------------------------

domainServiceDeclaration      
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility SERVICE serviceName 
                                  parameterList SEMI pragmaList                           
                              ;

domainFunctionDeclaration     
returns[String result]
@after {
    Matcher m = Pattern.compile( "public|private" ).matcher( $text );
    if ( !m.find() ) {
        $result = "public " + $text;    // if there is no public or private modifier, it is public
    }
    else {
        $result = $text;
    }
}
                              : serviceVisibility FUNCTION serviceName 
                                  parameterList 
                                  RETURN returnType SEMI pragmaList                       
                              ;


parameterList                 : LPAREN
                                  parameterDefinition? ( COMMA parameterDefinition )*                          
                                RPAREN                                                    
                              ;


parameterDefinition           : parameterName COLON parameterMode parameterType           
                              ;


serviceVisibility             : PRIVATE                                                   
                              | PUBLIC                                                    
                              | /* blank */                                               
                              ;
        
parameterMode                 : IN
                              | OUT
                              ;


serviceName                   : identifier                                                
                              ;

parameterName                 : identifier                                                
{'fraction_non_alphanumeric': 0.08764862327909888, 'fraction_numerical': 7.822277847309137e-05, 'mean_word_length': 0.7364006791171477, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 308, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6119183', 'n_tokens_mistral': 9310, 'n_tokens_neox': 8658, 'n_words': 1981}