自定义ANTLR语法不适用于每个输入

时间:2012-02-21 17:56:47

标签: parsing antlr business-rules

我正在尝试为我们的自定义规则引擎编写语法,该引擎使用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值。

任何人都可以指导我出错的地方吗?

1 个答案:

答案 0 :(得分:3)

BATMAN被标记为LHSOPERAND令牌。您必须意识到词法分析器没有考虑解析器在特定时间“需要”的内容。词法分析器只是尝试尽可能匹配,如果2(或更多)规则匹配相同数量的字符(在您的情况下为LHSOPERANDRHSOPERAND),则首先定义的规则将“赢” “,这是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();};

(请注意EQNEQ不是真正的关系运算符...)

解析输入,如:

PERSON_NAME = BATMAN OR age <> 42

现在将导致以下解析:

enter image description here