Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Rules have to be formatted as follows (same rules apply for lexer rules and lexer fragments. Yet, the naming is different - see naming below):

Code Block
ruleName 
    :    //instructions
    ;

More formatting rules apply to the instructions itself (wrapping lines below). Also consider the next section how the indentation has to be written.

...

Code Block
ruleName
@init{
    //Java Code which has to follow the Java Code conventions
}
@after{
    //more instructions
}
    :    //notice that : is still intended
    |    //an alternative
    ;

Indentation

Four spaces should be used as the unit of indentation. Use only spaces and not tabs (replace tabs by spaces if necessary).

Rule of thumb, everything should be lined on vertical lines with a gap of four spaces (most text editors will behave like this when the user is pressing "tab" and tabs are replaces by four spaces). 

Consider the following:

Code Block
rule
    //after one tab I am here
    :
        //after two tabs I am here
        alternative1
    |   alternative2
        -> ^(BLOCK 
            //after three tabs I am here
            alternative2
        )
    ;

Be aware that the gap between | and alternative2 is only 3 spaces

Line length

Lines should not be longer than 120 characters

...

Code Block
compilationUnit	
	:    namespaceSemicolon+ EOF!
	|    namespaceBracket+ EOF!
	|    withoutNamespace EOF!
	;

In addition, if you need to break an alternative, then try to group it logically. Following a good and a bad example

Code Block
titlegood example
withoutNamespace 
    :    (statement*) 
         -> ^(Namespace[$statement.start,"namespace"]
             DEFAULT_NAMESPACE[$statement.start, BACKSLASH] 
             ^(NAMESPACE_BODY[$statement.start,"nBody"] statement*)
         )
    ;
Code Block
titlebad example
withoutNamespace :    
        (statement*) -> 
        ^(Namespace[$statement.start,"namespace"] DEFAULT_NAMESPACE[$statement.start, BACKSLASH] 
        ^(NAMESPACE_BODY[$statement.start,"nBody"] 
        statement*)) 
;

...

Code Block
titlegood example
unaryPrimitiveAtom
	:    uplus = '+' primitiveAtomWithConstant -> ^(UNARY_PLUS[$uplus, "uPlus"] primitiveAtomWithConstant)
	|    uminus = '-' primitiveAtomWithConstant -> ^(UNARY_MINUS[$uminus,"uMinus"] primitiveAtomWithConstant)
	|    primitiveAtomWithConstant
	;
Code Block
titlebad example
unaryPrimitiveAtom
	:    uplus = '+' primitiveAtomWithConstant 
    -> ^(UNARY_PLUS[$uplus, "uPlus"] primitiveAtomWithConstant)
	|    uminus = '-' primitiveAtomWithConstant -> ^(UNARY_MINUS[$uminus,"uMinus"] primitiveAtomWithConstant)
	|    primitiveAtomWithConstant;

...

Code Block
titlegood example
unaryPrimitiveAtom
	:    uplus = '+' primitiveAtomWithConstant 
         -> ^(UNARY_PLUS[$uplus, "uPlus"] primitiveAtomWithConstant)
	|    uminus = '-' primitiveAtomWithConstant 
         -> ^(UNARY_MINUS[$uminus,"uMinus"] primitiveAtomWithConstant)
	|    primitiveAtomWithConstant
    ;

Please notice that -> has to be intended with 9 spaces. 2x 4 for a "tab" and one for the missing : 

If you think this is too crowded then you are allowed to place an empty line between the alternatives as follows:

Code Block
titlegood example
unaryPrimitiveAtom
	:    uplus = '+' primitiveAtomWithConstant 
         -> ^(UNARY_PLUS[$uplus, "uPlus"] primitiveAtomWithConstant)
 
	|    uminus = '-' primitiveAtomWithConstant 
         -> ^(UNARY_MINUS[$uminus,"uMinus"] primitiveAtomWithConstant)

	|    primitiveAtomWithConstant
    ;

...

  • Before a left parenthesis

    Code Block
    paramList
    	:	    :   paramDeclarationOptional (','! paramDeclarationOptional)* //good example
    	|	    |   paramDeclarationNormal(','! paramDeclarationNormal)*(','! paramDeclarationOptional)* //bad example
    	;
  • before a ->
  • before a ^
  • after a token as text (see code example below, 'final' is a token as text)
  • after a , in a token declaration. Following an example:

    Code Block
    finalModifier
        :    fin='final' -> 'final' Public[$fin, "public"]
        ; 

...

Code Block
titlebad example
linenumberstrue
interfaceDefinition
    :    inter = 'interface'Identifier(ext='extends' identifierList) ? block= '{' interfaceBody* '}'
         -> ^ ('interface' 
             ^(CLASS_MODIFIER[$inter,"iMod"] modifiers +)
             Identifier 
             ^(Extends [$ext,"extends"] identifierList?) 
             ^(INTERFACE_BODY[$block,"iBody"] interfaceBody *)
         )
    ;

The following deficiencies can pointed out:

...

what?Naming rulesExample
tokenToken names should reflect what they stand for and needs to be in PascalCase.
In the simplest case it is just the name for the corresponding sign.
BitwiseAnd = '&';
BitwiseAndAssign = '&=';
imaginary tokenImaginary token names should also reflect what the stand for and should be in UPPER_CASE with underscore to separate words.
BLOCK;
METHOD_CALL; 
virtual tokenVirtual token should also reflect what they stand for but need to be in UPPER_CASE with underscore to separate words
ACTUAL_PARAMETERS;
CLASS_BODY; 
ruleRule names should reflect what they represent (hence often nouns are used) and they should be in camelCase
interfaceDefinition
: //instruction
lexer ruleRules names should also reflect what they represent but are in PascalCase
Int 
: DECIMAL
| HEXADECIMAL
| OCTAL
| BINARY
;
lexer fragementsFragment names should refelect what they represent and need to be in UPPER_CASE with underscore to separate words
fragment
HEXADECIMAL
: '0' ('x'|'X') ('0'..'9'|'a'..'f'|'A'..'F')+
;

fragment
STRING_SINGLE_QUOTED
: '\''
( ('\\\\')=>'\\\\'
| ('\\\'')=>'\\\''
| ~ ('\'' )
)*
'\''
;
emptyAn empty alternative has to be denoted by /* empty */
namespaceIdOrEmpty
: namespaceId | /* empty */
;

...