ANTLR3语法与空格一起工作,但当我省略空格时,会给出NoviableException

ANTLR3语法与空格一起工作,但当我省略空格时,会给出NoviableException,antlr,antlr3,Antlr,Antlr3,我需要解析定义系统查询的用户输入。这类查询的核心是三元组,它们也可以组合起来形成复杂的查询(其思想是将结果集限制为仅显示满足这些查询的条目)。以下是3个示例输入: field1 = simpleValueNoQuotes field2 ~ "valueWithQuotes" (field1 = simpleValueNoQuotes OR field2 ~ "valueWithQuotes") AND field3 = foobar 如果值包含任何保留字符(如双引号或圆括号以及空格),则用户必

我需要解析定义系统查询的用户输入。这类查询的核心是三元组,它们也可以组合起来形成复杂的查询(其思想是将结果集限制为仅显示满足这些查询的条目)。以下是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

您忘了从
简单值中排除
=
,这意味着
field1=simpleValueNoQuotes
是单个
SIMPLE_值
标记。

SIMPLE_值与一个空标记相匹配,这在大多数情况下本身就是一个问题,因此在值规则中可以将其设置为()+或可选。你能给我们举两个例子,一个匹配,一个不匹配吗?谢谢关于空令牌的提示,这很有意义。不幸的是,它没有解决更大的问题。最后我给出了一个匹配和非匹配输入的例子,在我的语法之后,你看到了吗?你完全正确,这确实解决了问题,但我不确定我是否理解为什么。匹配=/~的“比较”规则不应该优先于简单的_值吗?为什么field1不能与SIMPLE_值匹配?最长的匹配总是优先于较短的匹配,因此它需要
field1=simpleValueNoQuotes
超过
field1
,因此
比较
规则定义的标记根本没有机会。