最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【整理】antlrworks使用心得,经验总结,注意事项,bug总结

ANTLR crifan 3415浏览 0评论

【背景】

之前用过很多次的antlr的IDE:antlrworks

期间,遇到很多需要总结的bug,经验等内容,

现在整理如下。

 

antlrworksbug总结

 

有时候存在语法错误的时候,仍然可以编译成功

比如:

我在某次,调试时,前面把BINARY_OPERATOR都改为了binary_operator,所以后面的BINARY_OPERATOR,自然就肯定找不到而出错了。

但是此时,竟然可以正常编译的。。。。

如图:

antlrworks binary operator grammar error but can compile ok

所以,不能完全相信antlrworks。。。。

 

antlrworks中,即使语法写对了,但是也还是会报错

用antlrworks当做编辑器,去编辑.g语法文件时,很不好用

其中遇到过:

赋值,粘贴,等等操作了一堆。

然后确定,语法是写对了的

但是估计是antlrworks内部没有及时更新,导致:

虽然语法是对的,但是其还是报错

看起来是:在把语法改正确之前的某次错误的内容,其记住了,但是就一直报错,

即使你后来还是改对了

所以:

作为.g文件的编辑器,语法高亮方面,还是凑合的,可以的

但是作为普通的文本编辑器,以及语法检测等方面,还是不好用,还是有很多bug的。

注:

后来想到了:

貌似是:

当你的(lexer的)token和(parser的)rule,

混写的话,容易出现上述的,有语法错误,但检测不到的问题。

其中:

混写的意思是:

本来是:

.g语法文件中:

要么,前面全是token,后面全是rule

要么,前面全是rule,后面全是token

而混写是:

rule中,混杂着token

(或者是:token中混杂着rule)

之前遇到一次此问题了。

这次又遇到了:

mix use lexer token and parser rule will error but not detect

其中,此处的,之前是READ,但是早就编辑过了,移动到别处了,更新语法了,确保正确了。

但是此处还是,无故的,报错,说是找不到什么READ。

 

 

antlrworks使用心得,经验总结,注意事项

antlrworks的调试功能支持很丰富

调试时,对应的Break On的部分,选择对应的内容,则可以实现对应的情况下,停止,供你调试

比如,我此处,全选了所有的:

select all option for break on

包括:

ALL

Location

Consume

LT

Exception

所以:

每次点击那个单步调试的时候,就可以一点点的看到右边的,events中的输出了:

events stop for view for every step

stop for every step now show ast tree

下图是:后来某次的调试之后的,一堆的events的输出:

for select all for break on show many events stop

然后对于具体含义,后来才大概明白:

首先,从events中,可以看出,

antlr内部执行的每一步,都是如何执行的。

对应的内部涉及到各种算法,目前我也不是很熟悉

其中调用了此处的各种函数,去执行对应的逻辑和判断

这些函数包含:

LT,Location,以及Consume等等

当然,如果出错时,会抛出异常,

比如上面那个MismatchedSetException之类的异常。

其中,唯一稍微清楚点的是:

Consume函数,表示消费了,吃掉了,匹配到了,对应的内容,所以就“消费”,被“吃”掉了。

然后继续后面的匹配。

所以,此处的Break On中的:

Location

Consume

LT

Exception

分别对应上述调用的函数:

Location(xxx)

Consume(xxx)

LT(xxx)

发生的各种异常:根异常都是Recognition Exception,其下包括各种类型的异常。

详见:

【整理】antlr的Exception Handling异常处理中的异常Exception的类型

而对于ALL的意思是:

除了上述那几个类型的输出以为,余下的,各种步骤,是否也中断,是否也停下,供你调试查看。

比如上面那个一堆的events中间就有,除了Location,Consume,LT,Exception之外的Enter xxx等语句,

也都会中断停止,供你调试。

对于,平常我们要的效果:

希望调试时可以实现:

一直运行,知道出现异常再停止

则可以去如下设置和使用:

对于Break On,只选择Exception

表示出现异常时,中断

然后点击那个单步执行(Step Forward)

就可以实现上述的效果了:

一直运行,直到遇到第一个异常,就中断

方便我们发现语法代码匹配所处理的内容,找到第一个出错的位置

效果如图:

when exception happen then double click can jump to error location

 

如果调试输入文件内容太多,则可能会由于绘制Parse Tree太长而导致antlrworks假死

之前,写了语法,在antlrworks中去调试

但是由于测试所用输入文件内容太长:6000+行

导致:

点击调试运行后:

虽然本身.g语法是对的,解析输入的文件内容也没错

但是由于输入文件内容太多,而导致了那个Parse Tree的界面

会内部调用java代码,去一点点绘制出对应的Parse Tree的

而由于生成的树的节点和内容太多

搞得所耗费时间太长:

一共大概需要十几分钟甚至几十分钟的

而对应的,如果点击掉Parse Tree:

click to disable not show parse tree

即,只是去调试,但是不生成Parse Tree

其本身调试完毕此大文件的时间,只有10几秒,很快的。

而由于之前耗费N多分钟,才能显示完毕Parse Tree,

搞得:

期间,调试了多次,

结果都是由于antlrworks中,点击后,死掉了

(其实是假死,只是需要足够的时间,去绘制Parse Tree而已)

以为自己的代码或者是输入文件有问题呢。。。。

另外也导致:

正好此时去测试和验证:

antlr的.g语法文件本身,去解析此大的输入文件时,需要耗时多少

结果实际上只是10多秒

结果以为几十分钟呢。。。

所以:

如果你也遇到了,所要测试的文件(或字符串内容)太长(至少单位为千行算)

而可能会导致:

调试时,看起来是antlrworks假死了

实际上是

内部正在耗时,去绘制Parse Tree呢

反过来说:

如果你和我之前一样,本身只是想要测试代码的正确性,输入文件的正确性

暂时不关心那个Parse Tree,则可以在debug时,点击下面的那个Parse Tree,去掉,不显示Parse Tree。

即可避免由于输入文件内容太多,生成Parse Tree耗时太长而导致antlrworks假死的现象了。

 

如果.g文件无法编译,则很可能是由于原文件是只读文件而导致的

之前就遇到过类似情况:

antlrworks中,无法编辑文件:

即:

鼠标点击文件,结果无法看到希望看到的鼠标变成编辑模式,可以输入文字,可以修改文字的效果:

within antlrworks mouse click not show vertical bar

后来才搞懂根本原因:

原来是当前所用antlrworks载入的文件,本身是只读的:

root cause is file is readonly

去掉只读属性后:

remove readonly for file

antlrworks中,其实还是不能立刻实现编辑文件,需要重新载入后:

need antlrworks file open recent g file

才可以编辑文件:

now can edit g file

另外:好像如果对于更改文件属性,去掉只读,去点击Apply而不是OK的话,貌似无需直接载入,即可编辑文件的。

转载请注明:在路上 » 【整理】antlrworks使用心得,经验总结,注意事项,bug总结

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.166 seconds, using 22.10MB memory