使用多个AND或ANTLR4解析规则?

使用多个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

我是ANTLR4的新手,我尝试使用它来解析从外部规则生成器获得的规则字符串。 规则的形式为[属性运算符值]and和OR多次

我能够分析更简单的问题,例如:-

[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