我需要解析定义系统查询的用户输入。此类查询的核心是三元组,它们也可以组合成复杂的查询(想法是将结果集限制为仅显示满足这些查询的条目)。以下是 3 个示例输入:
field1 = simpleValueNoQuotes
field2 ~ "valueWithQuotes"
(field1 = simpleValueNoQuotes OR field2 ~ "valueWithQuotes") AND field3 = foobar
如果它们的值包含任何保留字符(如双引号或括号以及空格),则用户必须使用带引号的值。
到目前为止,我的语法已经很好地处理了这个问题,但是现在出现了一个新的要求。应该允许用户省略空格,输入类似field1=simpleValueNoQuotes
. 我的语法无法处理这个问题,我似乎无法弄清楚为什么(这是我第一个使用 antlr 的项目)。
这是我稍微简化的语法:
grammar simple;
querytree : query EOF;
query : subquery (operator subquery)* ;
subquery : leaf | composite;
operator : 'and' | 'or';
leaf : fieldname comparison value;
value : DOUBLEQUOTE_DELIMITED_VALUE | SIMPLE_VALUE;
composite : leftParenthesis query rightParenthesis;
fieldname : 'field1' | 'field2'; //this has many keywords in reality
comparison : '=' | '~';
leftParenthesis : '(';
rightParenthesis : ')';
fragment
ESCAPE : '\\' ( '"' | '\\') ;
DOUBLEQUOTE_DELIMITED_VALUE
: '"' ( ~( '"' | '\\' ) | ESCAPE )* '"'
;
SIMPLE_VALUE
: ('\u0021'|'\u0023'..'\u0027'|'\u002A'..'\u007E'|'\u00A1'..'\uFFFF')*; /*all unicode characters except control characters, doublequotes, parentheses and whitespace defined below*/
WHITESPACE
: ('\u0009'|'\u000A'|'\u000C'|'\u000D'|'\u0020'|'\u00A0')+ {$channel = HIDDEN;} /*\t, \n, \f, \r, space, nonbreaking space*/
;
关于为什么这能够解析field1 = simpleValueNoQuotes
但无法解析的任何想法field1=simpleValueNoQuotes
?