我是ANTLR4的新手,我试图使用它来解析从外部规则生成器获得的规则字符串。 规则的格式为[属性运算符值]多次AND和OR。
我能够解析更简单的代码,例如:-
[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]
但是,一旦我遇到了那些AND和OR混合的问题,例如:-
[[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]] AND [[hiredate__c > ('2000-01-01')] OR [custom10__c == ('ABCD')]]
下面将介绍我的适用于简单规则的语法。我真的很感谢在解析由复合AND和OR组成的规则方面需要做什么的所有提示。
// Our grammar is called Rules.
grammar Rules;
// Rules
start: grouprules;
grouprules: grouprule (andor grouprule)* EOF;
grouprule: L_SB expression R_SB;
expression: USERATTRIBUTE operator values;
operator: EQ | NE | GE | GT | LE | LT;
values: '(' value (',' value )* ')';
value: STRING | date;
date: '\'' DATE '\'';
andor: AND | OR;
// Tokens
EQ: '==';
NE: '!=';
GT: '>';
GE: '>=';
LT: '<';
LE: '<=';
L_SB: '[';
R_SB: ']';
AND: [aA][nN][dD];
OR: [oO][rR];
NUMBER: [0-9]+;
USERATTRIBUTE: [a-zA-Z][a-zA-Z0-9_]*;
STRING: '\'' ~('"')* '\'' ;
// Not perfect
DATE: [0-9][0-9][0-9][0-9][-][0-1][0-9][-][0-3][0-9] ;
// WS represents a whitespace, which is ignored entirely by skip.
WS: [ \t\u000C\r\n]+ -> skip;
规则:
[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]
成功的结果:
(grouprules (grouprule [ [ hiredate__c (operator >) (values ( (value '2000-01-01')] AND [divison3__c == ('AH Marketing', 'Asset Protection Solutions') )) ]) ] <EOF>)
复合规则:
[[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]] AND [[hiredate__c > ('2000-01-01')] OR [custom10__c == ('ABCD')]]
失败的结果:
line 1:1 extraneous input '[' expecting USERATTRIBUTE
line 1:162 extraneous input ']' expecting {<EOF>, AND, OR}
(grouprules (grouprule [ (expression [ divison3__c (operator ==) (values ( (value 'AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]] AND [[hiredate__c > ('2000-01-01')] OR [custom10__c == ('ABCD') ))) ]) ] <EOF>)
答案 0 :(得分:0)
您的问题不是您有多个运算符和/或运算符(像[...] AND [...] OR [...]
这样的语法可以很好地解析),而是有嵌套的括号([[
)。目前,您的语法仅允许USERATTRIBUTE operator values
放在方括号内,而不允许其他括号或AND
/ OR
。
为此,您应该添加grouprules
作为expression
的替代,因此表达式不仅可以具有USERATTRIBUTE operator values
的形式,而且可以是{{1 }}和/或AND
运算符。
要执行此操作,您首先需要将OR
从EOF
移到grouprules
,尽管您不想将其应用于嵌套在括号内的start
(因为这些将在后面加上一个右括号,而不是文件的末尾(显然只出现一次)。
答案 1 :(得分:0)
关于您的语法的几点评论:
STRING
应该包含~('\'')*
而不是~('"')*
'2018-12-31'
这样的DATE
规则匹配:由于它周围带有引号,因此您的STRING
规则将与之匹配。 DATE
应该被删除date
应该被删除这应该可以解决问题:
grammar Grammar;
start
: expr EOF
;
expr
: USERATTRIBUTE ( EQ | NE | GE | GT | LE | LT ) expr
| expr ( AND | OR ) expr
| '[' expr ']'
| list
;
list
: '(' STRING (',' STRING )* ')'
;
EQ : '==';
NE : '!=';
GT : '>';
GE : '>=';
LT : '<';
LE : '<=';
L_SB : '[';
R_SB : ']';
AND : [aA][nN][dD];
OR : [oO][rR];
NUMBER : [0-9]+;
USERATTRIBUTE : [a-zA-Z][a-zA-Z0-9_]*;
STRING : '\'' ~('\'')* '\'' ;
WS : [ \t\u000C\r\n]+ -> skip;
您的输入[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]
的解析如下:
和[[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')]] AND [[hiredate__c > ('2000-01-01')] OR [custom10__c == ('ABCD')]]
这样: