代码之家  ›  专栏  ›  技术社区  ›  James Ko

ANTLR:当用户修改文本时,如何避免重新解析整个文件

  •  3
  • James Ko  · 技术社区  · 7 年前

    编辑: here .


    我正在用C语言开发一个代码编辑器应用程序,它提供语法高亮显示。我目前正在使用 ANTLR for C#

    我希望编辑器对大文件表现良好,因此我不希望每次用户键入字符时都重新解析整个文件。我做了一些研究,看起来我要找的是一个增量解析器。不幸的是,它看起来像ANTLR v4 can't do incremental parsing ,所以我不知道该怎么办。

    我的问题是:我是否可以采取另一种方法,使用ANTLR,在用户键入时不冻结应用程序?我真的很犹豫放弃ANTLR,因为有 a bunch of free grammars 它是可用的,所以添加对一种新语言的支持不需要太多工作。我研究了TextMate语法,VSCode使用了很多语法,但我不理解它们,也没有C库可以操作它们。

    谢谢你的帮助!

    2 回复  |  直到 7 年前
        1
  •  3
  •   TomServo    7 年前

    我不会在每次击键后解析,但会解析整个文件。这对于我创建的特定于域的语言中的中等大小的文件非常有效。我没有尝试只解析文件的一部分,而是使用混合方法,在三个条件中的第一个条件存在时进行解析:

    1. 用户类型 n
    2. 一个计时器说 m 毫秒。

    底线是,你可能会惊讶于人们在输入任何强加语法的东西时花了多少时间停顿和思考。当用户思考时,可以利用这些暂停来做有用的工作,即使是400毫秒。由于语法原因,我在为工作而创建的DSL中使用了#1和#2。

    n n 字符。我发现这样的组合方法在IDE类型的环境中效果很好。

    要记住的一点是,如果这样做,在发现语法错误时不要弄乱文本控件的插入点,因为错误在键入时是不可避免的。我只是在标签中显示一条消息:

        public override void Recover(Parser recognizer, RecognitionException e)
        {
            IToken token = recognizer.CurrentToken;
            string message = string.Format("parse error at line {0}, position {1} right before {2} ", token.Line, token.Column, GetTokenErrorDisplay(token));
            BasicEnvironment.SyntaxError = message;
    

        2
  •  1
  •   James Ko    7 年前

    @JLH基本上也说明了我正在使用的方法,但我想补充一些您可能需要注意的事情:
    首先,我将在不同于编辑器UI线程的线程中进行解析,以防止在用户决定继续编码的同时启动解析器。如果您使用的是不同的线程,那么用户可以继续编码,而不会注意到解析器正在后台运行。当然,您需要使用某种机制,在这种情况下取消解析,或者至少不在编辑器中对生成的解析树执行任何操作,因为它已经被obsolte了。

    SLL LL SLL公司

    您可以在 source code 我的(虽然它是用java编写的,但原理应该是一样的)。