I am trying to write a grammar for our custom rule engine which uses ANTLR (for parsing) and Pentaho Kettle (for executing the rules)
Valid inputs for the parser would be of the type:
(<Attribute_name> <Relational_Operator> <Value>) AND/OR (<Attribute_name> <Relational_Operator> <Value>)
i.e. PERSON_PHONE = 123456789
Here is my grammar:
grammar RuleGrammar;
options{
language=Java;
}
prog : condition;
condition
: LHSOPERAND RELATIONOPERATOR RHSOPERAND
;
LHSOPERAND
: STRINGVALUE
;
RHSOPERAND
: NUMBERVALUE |
STRINGVALUE
;
RELATIONOPERATOR
: '>' |
'=>' |
'<' |
'<=' |
'=' |
'<>'
;
fragment NUMBERVALUE
: '0'..'9'+
;
fragment STRINGVALUE
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_')*
;
fragment LOGICALOPERATOR
: 'AND' |
'OR' |
'NOT'
;
The issue I am facing is comparing against string value i.e. PERSON_NAME=1 would pass the grammar, but the value PERSON_NAME=BATMAN
does not work. I am using ANTLRWorks and on debugging for PERSON_NAME=BATMAN
, I get a MismatchTokenException
for the RHS value.
Can anyone please guide me where I am going wrong?
BATMAN
is being tokenized as aLHSOPERAND
token. You must realize that the lexer does not take into account what the parser "needs" at a particular time. The lexer simply tries to match as much as possible, and in case 2 (or more) rules match the same amount of characters (LHSOPERAND
andRHSOPERAND
in your case), the rule defined first will "win", which is theLHSOPERAND
rule.A quick demo of how you could do it:
(note that
EQ
andNEQ
aren't really relational operators...)Parsing input like:
would now result in the following parse: