Search code examples
javac#antlrantlr4grammar

Antlr4 is not recognizing Keywords and classifying them as ID


I have been searching the internet for almost 3 days now i cant find solution, please Help

Here is the problem

I Have this grammar

grammar EasyBite;
IF                :   'if';
THEN              :   'then';
ELSE              :   'else';
ELSE_IF           :   'else if';
END_IF            :   'end if';
DECLARE : 'declare';
SET : 'set';
TO : 'to';
SHOW : 'show';
ID : [a-zA-Z] [a-zA-Z0-9_]*;
NUMBER : ('+' | '-')? [0-9]+ ('.' [0-9]+)?;
STRING : '"' ( '\\' . | ~[\\"] )* '"' | '\'' ( '\\' . | ~[\\'] )* '\'' ;
INPUT  : 'input';
MUL : '*';
DIV : '/';
MODULO : 'remind';
POW    : '^';
PLUS : '+';
MINUS : '-';
SEMICOLON : ';';
LPAREN : '(';
RPAREN : ')';
AND : 'and';
OR : 'or';
NOT : 'not';
LESS_THAN         :   '<';
LESS_THAN_EQUAL   :   '<=';
GREATER_THAN      :   '>';
GREATER_THAN_EQUAL:   '>=';
EQUAL             :   '==';
NOT_EQUAL         :   '!=';
NEWLINE : '\r'? '\n';
WS : [ \t\n\r]+ -> skip;


// Parser rule
program : statement_list* | EOF;

statement_list : statement (NEWLINE|SEMICOLON)*;

statement : if_statement
            |declare_statement 
            |set_statement
            |input_statement
            |print_statement
            ;

// Declaration statement
if_statement : IF expression THEN statement_list (elseif_statement)* (ELSE statement_list)? END_IF;
elseif_statement : ELSE_IF expression THEN statement_list;

declare_statement : DECLARE ID;
set_statement : (SET ID  | ID) TO expression | value | comparison;

input_statement : (SET ID | ID) TO INPUT LPAREN expression RPAREN;
print_statement : SHOW (LPAREN expression RPAREN | STRING);

expression: logicalOr;

logicalOr: logicalAnd (OR logicalAnd)*;

logicalAnd: equality (AND equality)*;

comparison: equality ((GREATER_THAN | LESS_THAN |  GREATER_THAN_EQUAL | LESS_THAN_EQUAL) equality)*;

equality: term ((EQUAL | NOT_EQUAL) term)*;

term: factor ((PLUS | MINUS) factor)*;

factor: power ((MUL | DIV | MODULO) power)*;
power: value ('^' value)*;
value: NUMBER | STRING | ID;

I am using Intellij Idea to verify the parse tree, it now indicating 'then' keyword is expecting, and when i went through the parse tree, it classifying AND and OR as ID also else part of if is not in the tree. Indicating LESS_THAN is expected.

Here is source i tried the grammar with

declare x
set x to 10
declare y
set y to 20
declare z
set z to x + y * 2
if x < y and y >= z or x == y then
  show("x is less than y and y is greater than or equal to z, or x is not equal to y")
else
  show("none of the above")
end if

Below is the Tree output The tree output I dont know how add it inline.

Thank you.

If possible, i need a grammar that will do what intended and cause of the problem and solution. Please help.


Solution

  • The order of your lexer rule matter. Given these rules:

    ID : [a-zA-Z] [a-zA-Z0-9_]*;
    INPUT  : 'input';
    

    ANTLR will never create an INPUT because the source "input" wil always become an ID token. The solution: place INPUT (and all other keywords!) above the ID rule:

    INPUT  : 'input';
    ID : [a-zA-Z] [a-zA-Z0-9_]*;
    

    Of course, this will cause "input" to never become an ID token. If you want keywords to become identifiers as well, have a look at this Q&A: Antlr4 how to build a grammar allowed keywords as identifier