我的任务是用Java编写团队DSL的原型,所以我想我会用ANTLR来试试。但是我遇到了'表达'和'条件'规则的问题。
DSL已经定义明确,所以我希望尽可能接近当前的规格。
grammar MyDSL;
// Obviously this is just a snippet of the whole language, but it should give a
// decent view of the issue.
entry
: condition EOF
;
condition
: LPAREN condition RPAREN
| atomic_condition
| NOT condition
| condition AND condition
| condition OR condition
;
atomic_condition
: expression compare_operator expression
| expression (IS NULL | IS NOT NULL)
| identifier
| BOOLEAN
;
compare_operator
: EQUALS
| NEQUALS
| GT | LT
| GTEQUALS | LTEQUALS
;
expression
: LPAREN expression RPAREN
| atomic_expression
| PREFIX expression
| expression (MULTIPLY | DIVIDE) expression
| expression (ADD | SUBTRACT) expression
| expression CONCATENATE expression
;
atomic_expression
: SUBSTR LPAREN expression COMMA expression (COMMA expression)? RPAREN
| identifier
| INTEGER
;
identifier
: WORD
;
// Function Names
SUBSTR: 'SUBSTR';
// Control Chars
LPAREN : '(';
RPAREN : ')';
COMMA : ',';
// Literals and Identifiers
fragment DIGIT : [0-9] ;
INTEGER: DIGIT+;
fragment LETTER : [A-Za-z@$#];
fragment CHARACTER : DIGIT | LETTER | '_';
WORD: LETTER CHARACTER*;
BOOLEAN: 'TRUE' | 'FALSE';
// Arithmetic Operators
MULTIPLY : '*';
DIVIDE : '/';
ADD : '+';
SUBTRACT : '-';
PREFIX: ADD| SUBTRACT ;
// String Operators
CONCATENATE : '||';
// Comparison Operators
EQUALS : '==';
NEQUALS : '<>';
GTEQUALS : '>=';
LTEQUALS : '<=';
GT : '>';
LT : '<';
// Logical Operators
NOT : 'NOT';
AND : 'AND';
OR : 'OR';
// Keywords
IS : 'IS';
NULL: 'NULL';
// Whitespace
BLANK: [ \t\n\r]+ -> channel(HIDDEN) ;
我正在测试的短语是
(FOO == 115 AND (SUBSTR(BAR,2,1) == 1 OR SUBSTR(BAR,4,1) == 1))
然而,它在嵌套的括号上打破,匹配第一个(与第一个)而不是最外层(见下文)。在ANTLR3中,我用语义谓词解决了这个问题,但似乎ANTLR4应该已经修复了对它们的需求。
如果可能的话,我真的希望将condition
和expression
规则分开。当我在一个expression
规则中合并(基于此处和其他地方的示例)时,我能够使它工作,但当前的DSL规范将它们视为不同,我正在尝试减少任何可能的行为差异。
任何人都可以指出我如何能够在保持conditions' and
表达式的单独规则的同时完成所有工作吗?非常感谢!
答案 0 :(得分:4)
语法对我来说似乎很好。
词法分析器中出现了一个问题:WORD
标记在各种关键字/运算符之前被定义,导致它优先于它们。将WORD
规则放在词法规则的最末端(或者至少在WORD
也可以匹配的最后一个关键词之后)。