Java 解释过程中的Antlr不匹配异常
我是Antlr新手,我使用Antlr 3定义了一个基本语法。语法编译和ANTLRWorks生成解析器和Lexer代码,没有任何问题 语法如下所示:Java 解释过程中的Antlr不匹配异常,java,antlr,Java,Antlr,我是Antlr新手,我使用Antlr 3定义了一个基本语法。语法编译和ANTLRWorks生成解析器和Lexer代码,没有任何问题 语法如下所示: grammar i; @header { package i; } module : 'Module1'| 'Module2'; object : 'I'; objectType : 'Name'; filters : EMPTY | 'WHERE' module; table : module
grammar i;
@header {
package i;
}
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : EMPTY | 'WHERE' module;
table : module object objectType;
STRING : ('a'..'z'|'A'..'Z')+;
EMPTY : ' ';
问题是,当我解释表解析器时,我得到了一个不匹配的DsetException。这是因为有空的。一旦我把空的从语法中去掉,解释就开始了。我查看了Antlr网站和其他一些示例,其中的空白是“”。我不知道该怎么办。我需要这个空的
当它解释时,我得到以下异常:
Interpreting...
[11:02:14] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
[11:02:14] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
Interpreting...
[10:57:23] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
[10:57:23] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
一旦我将空的更改为以下内容:
EMPTY : '';
而不是:
EMPTY : ' ';
它实际上解释了它。但是,我得到以下例外情况:
Interpreting...
[11:02:14] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
[11:02:14] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 );])
Interpreting...
[10:57:23] problem matching token at 1:4 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
[10:57:23] problem matching token at 1:9 NoViableAltException(' '@[1:1: Tokens : ( T__4 | T__5 | T__6 | T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 );])
但是,ANLTWorks仍然生成Lexer和解析器代码
我希望你能帮忙
编辑:
我仍然有点不确定用法,但我认为我们说“空输入”是在谈论同一件事。这里有一个解决办法,从修改语法开始
grammar i;
@header {
package i;
}
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : | 'WHERE' module;
table : module object objectType filters;
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; //ignore whitespace
请注意,我在表
规则的末尾添加了过滤器
,以解释我所说的内容
此语法与以前一样接受以下输入(从规则表开始):
模1 I名称
它之所以有效,是因为过滤器
匹配,即使文本名称
后面没有任何内容:它使用第一个选项匹配空输入
语法也接受这一点:
模块1 I名称,其中模块2
过滤器
规则满足文本WHERE Module2
匹配第二个备选方案(在语法中定义为“WHERE”模块
)
一个更干净的方法是将过滤器
和表格
更改为以下规则(当然,首先要认识到我更改了表格
)
语法与之前的输入匹配,但术语更加清晰:我们现在说“过滤器在表中是必需的,过滤器在空时匹配,过滤器在表中是可选的,过滤器在空时不匹配”
在这种情况下,它相当于同一件事。在空(foo:|等;
)上进行匹配是完全有效的,但使用它时遇到的问题比匹配可选(foo?
)规则时遇到的问题要多
在更新之后更新
我要退一步,让我们走出理论,进入实践。这是一个更新的语法、调用它的Java测试代码、测试输入和测试输出。请试一试
语法
为测试而修改,但遵循与以前相同的想法
grammar i;
@header {
package i;
}
selects : ( //test rule to allow processing multiple select calls. Don't worry about the details.
{System.out.println(">>select");}
select
{System.out.println("<<select");}
)+
;
select : 'SELECT *' 'FROM' table filters? ';'
{System.out.println("\tFinished select.");} //test output
;
module : 'Module1'| 'Module2';
object : 'I';
objectType : 'Name';
filters : 'WHERE' conditions
{System.out.println("\tFinished filters.");} //test output
;
table : module object objectType
{System.out.println("\tFinished table.");} //test output
;
conditions : STRING operator value
{System.out.println("\tCondition test on " + $STRING.text);}
;
operator : '=' | '!=';
true_ : 'true'; //changed so that Java code could be generated
value : true_;
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; //ignore whitespace
itest.txt测试输入文件
SELECT * FROM Module2 I Name;
SELECT * FROM Module2 I Name WHERE foobar = true;
SELECT * FROM Module2 I Name WHERE dingdong != true;
测试输出
>>select
Finished table.
Finished select.
<<select
>>select
Finished table.
Condition test on foobar
Finished filters.
Finished select.
<<select
>>select
Finished table.
Condition test on dingdong
Finished filters.
Finished select.
<<select
>选择
完成的桌子。
完成选择。
选择
完成的桌子。
foobar的状态测试
成品过滤器。
完成选择。
选择
完成的桌子。
定东的条件试验
成品过滤器。
完成选择。
我怀疑您是否需要显式捕获空白,但如果不更好地理解其用法,我就不能确定。您能否举例说明您计划如何使用过滤器
规则?例如,如果您想使用WHERE
关键字,输入看起来会是什么样子?现在它还没有连接到另一个规则,所以举个例子会有所帮助。好吧,我无法给出完整的细节。以上只是一个例子。我正在为我的公司开发语法,要求很高。我无法提供任何信息。你能帮忙吗?综上所述,需要空格。如上所述,此NoViableAltException在没有空格的情况下仍会发生。当我想到名为EMPTY
的规则时,我想到过滤器:|“WHERE”模块代码>(第一个备选方案中的“空”输入满足规则过滤器
),而不是过滤器:“|”WHERE“module;”代码>(第一个alt的单个空格)。一旦你明确地匹配了空格(也就是说,你没有跳过它),它就必须在关键字和其他任何地方进行解释,所以我对这个空规则怒目而视空的只是一个空的空间。所以我想做的是:当用户不输入任何内容时,语法会接受它,“|”实际上是指一个空白吗?所以基本上,我不知道你是否懂Java。但我试图实现的是这样的:私有字符串名;名称=新字符串(“”)@用户1646481过滤器:|“WHERE”模块中的:
和|
之间的间隙
表示“如果不读取任何内容,则认为满足此规则。”(新规则WS
确保跳过空格,因此实际空格完全不在图片中:它们现在实际上是“空输入”或“非输入”)<代码>过滤器
可以写成过滤器:“WHERE”模块|
,将空的替代项放在末尾。@user1646481 Re:新字符串(“”
):我对Java很熟悉,但我需要一个适用于您的语法的示例来确定您的要求。如果没有这些,我们最终会互相扯淡/好的,我已经编辑了上面的内容。请看编辑,让我知道你的想法。这会让您了解为什么需要空字符串。@user1646481这很有帮助,谢谢。是SELECT*FROM Foo代码>(分号前无空格,未提供筛选器)有效输入?如何从Foo中选择*代码>这里和那里都有额外的空格?
>>select
Finished table.
Finished select.
<<select
>>select
Finished table.
Condition test on foobar
Finished filters.
Finished select.
<<select
>>select
Finished table.
Condition test on dingdong
Finished filters.
Finished select.
<<select