Jordi
Jordi

Reputation: 23277

ANTLR single grammar input mismatch

So far I've been testing with ANTLR4, I've tested with this single grammar:

grammar LivingDSLParser;

options{
    language = Java;
    //tokenVocab = LivingDSLLexer;
}

living
 : query                            #QUERY
 ;

query
 : K_QUERY entity K_WITH expr
 ;


entity
 : STAR         #ALL
 | D_FUAS       #FUAS
 | D_RESOURCES  #RESOURCES
 ;

field
 : ((D_FIELD | D_PROPERTY | D_METAINFO) DOT)? IDENTIFIER
 | STAR
 ;

expr
 : field
 | expr ( '*' | '/' | '%' ) expr
 | expr ( '+' | '-' ) expr
 | expr ( '<<' | '>>' | '&' | '|' ) expr
 | expr ( '<' | '<=' | '>' | '>=' ) expr
 | expr ( '=' | '==' | '!=' | '<>' ) expr
 | expr K_AND expr
 | expr K_OR expr
 ;

IDENTIFIER
 : [a-zA-Z_] [a-zA-Z_0-9]* // TODO check: needs more chars in set
 ;

NUMERIC_LITERAL
 : DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )?
 | '.' DIGIT+ ( E [-+]? DIGIT+ )?
 ;

STRING_LITERAL
 : '\'' ( ~'\'' | '\'\'' )* '\''
 ;

K_QUERY : Q U E R Y;
K_WITH: W I T H;
K_OR: O R;
K_AND: A N D;

D_FUAS : F U A S;
D_RESOURCES : R E S O U R C E S;
D_METAINFO: M E T A I N F O;
D_PROPERTY: P R O P E R T Y;
D_FIELD: F I E L D;

STAR : '*';
PLUS : '+';
MINUS : '-';
PIPE2 : '||';
DIV : '/';
MOD : '%';
LT2 : '<<';
GT2 : '>>';
AMP : '&';
PIPE : '|';
LT : '<';
LT_EQ : '<=';
GT : '>';
GT_EQ : '>=';
EQ : '==';
NOT_EQ1 : '!=';
NOT_EQ2 : '<>';

OPEN_PAR : '(';
CLOSE_PAR : ')';
SCOL : ';';
DOT : '.';

SPACES
 : [ \u000B\t\r\n] -> channel(HIDDEN)
 ;

fragment DIGIT : [0-9];

fragment A : [aA];
fragment B : [bB];
fragment C : [cC];
fragment D : [dD];
//so on...

As far I've been able to figure out, when I write some input like this:

query fuas with field.xxx == property.yyy

, it should match.

However I recive this message:

LivingDSLParser::living:1:0: mismatched input 'query' expecting K_QUERY

I have no idea where's the problem and neither what this message means.

Upvotes: 0

Views: 63

Answers (1)

Bart Kiers
Bart Kiers

Reputation: 170308

Whenever ANTLR can match 2 or more rules to some input, it chooses the first rule. Since both IDENTIFIER and K_QUERY match the input "query" , and IDENTIFIER is defined before K_QUERY, IDENTIFIER is matched.

Solution: move your IDENTIFIER rule below your keyword definitions.

Upvotes: 1

Related Questions