我正在尝试为我们的自定义规则引擎编写语法,该引擎使用ANTLR(用于解析)和Pentaho Kettle(用于执行规则)
解析器的有效输入类型为:
(<Attribute_name> <Relational_Operator> <Value>) AND/OR (<Attribute_name> <Relational_Operator> <Value>)
即PERSON_PHONE = 123456789
这是我的语法:
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'
;
我面临的问题是与字符串值进行比较,即PERSON_NAME = 1会传递语法,但值PERSON_NAME=BATMAN
不起作用。我正在使用ANTLRWorks并调试PERSON_NAME=BATMAN
,我得到一个MismatchTokenException
的RHS值。
任何人都可以指导我出错的地方吗?
答案 0 :(得分:3)
BATMAN
被标记为LHSOPERAND
令牌。您必须意识到词法分析器没有考虑解析器在特定时间“需要”的内容。词法分析器只是尝试尽可能匹配,如果2(或更多)规则匹配相同数量的字符(在您的情况下为LHSOPERAND
和RHSOPERAND
),则首先定义的规则将“赢” “,这是LHSOPERAND
规则。
修改
这样看:首先,词法分析器接收它在一个标记流中转换的字符流。在创建了所有令牌之后,解析器会收到这些令牌,然后它会尝试理解这些令牌。在解析期间(在解析器规则中),但在它之前,令牌不。
快速演示 可以
做什么:grammar RuleGrammar;
prog
: condition EOF
;
condition
: logical
;
logical
: relational ((AND | OR) relational)*
;
relational
: STRINGVALUE ((GT | GTEQ | LT | LTEQ | EQ | NEQ) term)?
;
term
: STRINGVALUE
| NUMBERVALUE
| '(' condition ')'
;
GT : '>';
GTEQ : '>=';
LT : '<';
LTEQ : '<=';
EQ : '=';
NEQ : '<>';
NUMBERVALUE : '0'..'9'+;
AND : 'AND';
OR : 'OR';
STRINGVALUE : ('a'..'z' | 'A'..'Z' | '_')+;
SPACE : ' ' {skip();};
(请注意EQ
和NEQ
不是真正的关系运算符...)
解析输入,如:
PERSON_NAME = BATMAN OR age <> 42
现在将导致以下解析: