I'm trying to make a small grammar with ANTLR4. I'm currently working with logic operations. One of the requirements is that a boolean can be either 'true | 1' or 'false | 0'.
The problem I'm facing is with arithmetic operations. I use numbers as well, so depending on the precedence my grammar recognizes '1' and '0' as either a number or a boolean.
Is it posible to have '0' and '1' as boolean and using them as a numeric value as well?.
This is my current grammar:
program: statement*;
statement: declaration | assignment | print;
print: PRINT (expression | condition);
declaration: VAR ID;
assignment: ID ASSIGN (expression | condition);
condition: condition lo condition #conditionCondition
| expression lo expression #expressionCondition
| LP condition RP #parenthesisCondition
| boolean #booleanCondition
| ID #idCondition;
expression: SUB expression #subExpression
| expression operator=(MUL | DIV) expression #muldivExpression
| expression operator=(ADD | SUB) expression #addsubExpression
| LP expression RP #parenthesisExpression
| NUMBER #numberExpression
| ID #idExpression;
boolean: TRUE | FALSE;
lo: GREATHER | LESSER | GREATEQUAL | LESSEQUAL | AND | OR | EQUAL | DIFFERENT;
//GROUP CHARATERS
LP: '(';
RP: ')';
//ARITHMETIC OPERATORS
MUL: '*';
DIV: '/';
ADD: ' ';
SUB: '-';
//LOGIC OPERATORS
GREATHER: '>';
LESSER: '<';
GREATEQUAL: '>=';
LESSEQUAL: '<=';
AND: '&&';
OR: '||';
EQUAL: '==';
DIFFERENT: '!=';
//RESERVED WORDS
VAR: 'var';
PRINT: 'print';
ASSIGN: '=';
//VALUES
NUMBER: [0-9] ;
TRUE: '1' | 'true';
FALSE: '0' | 'false';
ID: [a-zA-Z] [a-zA-Z0-9]*;
BLANKS: [ \t\r\n] -> skip;
CodePudding user response:
You cannot have two rules match the same input. If you specify more than one then the first rule in the grammar will always match.
But you could do something like:
ONE: '1';
ZERO: '0';
TRUE: 'true';
FALSE: 'false';
NUMBER: (ONE | ZERO)? [0-9] ;
boolean: TRUE | FALSE | ONE | ZERO;
CodePudding user response:
I solved it adding the NUMBER lexer rule to the condition parser rule.
condition: condition lo condition #conditionCondition
| expression lo expression #expressionCondition
| LP condition RP #parenthesisCondition
| boolean #booleanCondition
| NUMBER #numberCondition
| ID #idCondition;
So, from the method NumberCondition I check the number value and return a boolean as desired.
I don't know if it is the best approach but it solves my problem.