使用多个AND或ANTLR4解析规则?
我是ANTLR4的新手,我尝试使用它来解析从外部规则生成器获得的规则字符串。 规则的形式为[属性运算符值]and和OR多次 我能够分析更简单的问题,例如:-使用多个AND或ANTLR4解析规则?,antlr4,Antlr4,我是ANTLR4的新手,我尝试使用它来解析从外部规则生成器获得的规则字符串。 规则的形式为[属性运算符值]and和OR多次 我能够分析更简单的问题,例如:- [divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrstatus__c == ('Active')] [[divison3__c == ('AH Marketing', 'Asset Protection Solutions')] OR [hrs
[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')]]
然而,一旦我与那些已经混合了and和ORs的因素进行斗争,例如:-
[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')]]
我的语法适用于简单规则,如下所述。我真的很感激任何关于在解析由复合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;
成功结果:
(grouprules (grouprule [ [ hiredate__c (operator >) (values ( (value '2000-01-01')] AND [divison3__c == ('AH Marketing', 'Asset Protection Solutions') )) ]) ] <EOF>)
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>)
不成功的结果:
(grouprules (grouprule [ [ hiredate__c (operator >) (values ( (value '2000-01-01')] AND [divison3__c == ('AH Marketing', 'Asset Protection Solutions') )) ]) ] <EOF>)
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>)
第1行:1个无关输入“[”应为USERATTRIBUTE
第1行:162个无关输入']',应为{和,或}
(grouprules(grouprule[(表达式[division3_uc(operator==)(值((值“AH营销”、“资产保护解决方案”)或[hrstatus_uc==(“活动”)]和[[hiredate_uc>('2000-01-01')]或[custom10_uc==('ABCD'))]))
您的问题不在于有多个and/or运算符(类似于[…]和[…]或[…]
的运算符可以解析),而是有嵌套的括号([[
)。目前,您的语法只允许括号内有用户属性运算符值
,而不允许其他括号或和
/或
要实现这一点,您应该添加grouprules
作为expression
的替代,这样表达式不仅可以具有USERATTRIBUTE操作符值的形式
,还可以是和
和/或或
操作符的嵌套应用程序
为此,您需要首先将
EOF
从grouprules
移动到start
,尽管您不希望它应用于括号内嵌套的grouprules
(因为后面是一个结束括号,而不是文件结尾,显然只出现一次).您的问题不在于有多个and/or运算符(类似于[…]和[…]或[…]
的运算符可以解析),而是有嵌套的括号([[
)。目前,您的语法只允许括号内有用户属性运算符值
,而不允许其他括号或和
/或
要实现这一点,您应该添加grouprules
作为expression
的替代,这样表达式不仅可以具有USERATTRIBUTE操作符值的形式
,还可以是和
和/或或
操作符的嵌套应用程序
为此,您需要首先将
EOF
从grouprules
移动到start
,尽管您不希望它应用于括号内嵌套的grouprules
(因为后面是一个结束括号,而不是文件结尾,显然只出现一次).关于你的语法有几点意见:
- 您的
可能应该包含字符串
而不是~('\'')*
~('''''))*
- 像
这样的输入将不会(部分)与您的'2018-12-31'
日期规则匹配:因为它周围有引号,您的
字符串将与之匹配。
日期规则可能应该被删除
- 由于前面的备注,您的
日期应删除
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;
语法;
开始
:expr EOF
;
expr
:USERATTRIBUTE(EQ | NE | GE | GT | LE | LT)expr
|expr(和|或)expr
|“['expr']”
|名单
;
列表
:'('STRING(','STRING)*')
;
等式:'=';
NE:“!=”;
GT:“>”;
GE:“>=”;
LT:'('2000-01-01')]或[custom10_uc==('ABCD')]
如下:
关于你的语法有几点意见:
- 您的
可能应该包含字符串
而不是~('\'')*
~('''''))*
- 像
这样的输入将不会(部分)与您的'2018-12-31'
日期规则匹配:因为它周围有引号,您的
字符串将与之匹配。
日期规则可能应该被删除
- 由于前面的备注,您的
日期应删除
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;
语法;
开始
:expr EOF
;
expr
:USERATTRIBUTE(EQ | NE | GE | GT | LE | LT)expr
|expr(和|或)expr
|“['expr']”
|名单
;
列表
:'('STRING(','STRING)*')
;
等式:'=';
NE:“!=”;
GT:“>”;
GE:“>=”;
LT:'('2000-01-01')]或[custom10_uc==('ABCD')]
如下:
谢谢你的建议。我做了你提到的改变。现在错误已经消失了,但看起来像是用别名“grun”和-tree进行测试,它只是在解析规则中第一次出现的表达式。在下一条评论中添加了结果。我将继续尝试。[[Division3_uuC==('AH Marketing'、'Asset Protection Solutions')]或[hrstatus_uC==('Active')]和[[hiredate_uC>('2000-01-01')]或[custom10_uC==('ABCD')](grouprule[(表达式(grouprules[(表达式Division3_uC)(运算符=)(值)('AH Marketing'、'Asset Protection Solutions'))或者[hrstatus_uuuc==('Active')]]和[[hiredate_uuc>('2000-01-01')]或者[custom10_uc==('ABCD')))]]@SouvikMajumdar我可能遗漏了一些东西,但是您的输出似乎包含了您输入的所有内容,所以我觉得它是正确的。谢谢您的建议。我做了你提到的改变。现在错误已经消失了,但看起来像是用别名“grun”和-tree进行测试,它只是在解析规则中第一次出现的表达式。在下一条评论中添加了结果。我将继续尝试。[[Division3_uuC==('AH Marketing'、'Asset Protection Solutions')]或[hrstatus_uC==('Active')]和[[hiredate_uC>('2000-01-01')]或[custom10_uC==('ABCD')](grouprule[(表达式)(grouprules[(表达式Division3_uC)(运算符==)(值)(val