Your lexer rule CLASSNAME
currently references parser rule upper_lower_case
(lexer rules start with an uppercase letter; parser rules start with lowercase). Lexer rules can only reference lexer rules.
In addition, it appears that UPPER_CASE
, LOWER_CASE
, and DIGITS
should not create tokens themselves so they should be marked as fragment
rules. In the following example, I changed DIGITS
to DIGIT
since it only ever matches one digit.
CLASSNAME : UPPER_CASE (DIGIT | UPPER_LOWER_CASE)*;
fragment UPPER_LOWER_CASE : LOWER_CASE | UPPER_CASE;
fragment UPPER_CASE : 'A'..'Z';
fragment LOWER_CASE : 'a'..'z';
fragment DIGIT : '0'..'9';
Edit 1 (for the edits in the question):
A piece of text in the input can only have one token type. For example, consider the input text
X3
. Since this text could match aCLASSNAME
or anOBJECTNAME
, the lexer will end up assigning it the type of the first rule appearing in the grammar. In other words, ifCLASSNAME
appears beforeOBJECTNAME
in the grammar, the inputX3
will always be aCLASSNAME
token and will never be aOBJECTNAME
token. IfOBJECTNAME
appears beforeCLASSNAME
in the grammar, the inputX3
will always be anOBJECTNAME
and never be aCLASSNAME
(in fact, in this case no token will ever be aCLASSNAME
).Your
ACCESSOR
rule looks like it should be a parser rule, like the following:accessor : PUBLIC | PROTECTED | PRIVATE;
Edit 2 (for the comment about distinguishing CLASSNAME
and OBJECTNAME
):
To distinguish between CLASSNAME
and OBJECTNAME
, you can create a lexer rule IDENTIFIER
which matches either.
IDENTIFIER : UPPER_LOWER_CASE (DIGIT | UPPER_LOWER_CASE)*;
You can then create a parser rule to handle the distinction:
classname : IDENTIFIER;
objectname : IDENTIFIER;
Obviously this allows x3
to be a classname
, which is not valid in your language. When possible, I always prefer to relax the parser rules a bit and perform further validation later where I can provide a better error message. For example, if you allow x3
to match classname
, then after you parse the input and have an AST (ANTLR 3) or parse tree (ANTLR 4), you can look for all instances of classname
and make sure that the matched IDENTIFIER
starts with the required upper case letter.
Example error message produced by the parser's automatic error reporting:
line 1:15 mismatched input 'variable' expecting CLASSNAME
Example error message produced by separate validation:
line 1:15 class name
variable
must start with an upper case letter