c# - ANTLR:如何避免在用户修改文本时重新解析整个文件

标签 c# parsing compiler-construction antlr antlr4

编辑: 对于那些有兴趣/想看看我到底在做什么的人,可以找到我的应用程序的源代码 here .


我正在使用 C# 构建一个代码编辑器应用程序,它提供语法高亮显示。我目前正在使用 ANTLR for C#解析代码以突出显示它。到目前为止,我的应用程序可以在用户最初打开文件时非常快速地突出显示代码。但是,我没有编写任何代码来在用户开始编辑文本时重新突出显示文本。

我希望编辑器能够很好地处理大文件,所以我不想在用户每次键入一个字符时都重新解析整个文件。我做了一些研究,看起来我正在寻找的是一个增量解析器。不幸的是,它看起来像 ANTLR v4 can't do incremental parsing ,所以我不确定该怎么做。

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

感谢您的帮助!

最佳答案

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

  1. 用户键入 n 个字符
  2. 计时器表示 m 毫秒后没有变化。
  3. 对于某些语法,用户键入行终止符/分隔符;

最重要的是,您可能会惊讶于人们在输入任何强加语法的内容时会花多少时间停下来思考。可以利用这些暂停在用户思考时做有用的工作,即使是 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;

在我的使用环境中,定时器通常控制它何时关闭;使用 800 毫秒和 10 个字符的值,我得到了很好的结果,计时器通常控制解析何时开始。

关于c# - ANTLR:如何避免在用户修改文本时重新解析整个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45153284/

相关文章:

ios - 解析响应 Facebook iOS sdk

linux - 为什么编译后.o文件中的函数名与.cc文件中的函数名不同?

c++ - 关于应用程序速度,最好的 C++ 编译器和 Windows 构建选项?

parsing - 有多少种方法来构建解析器?

c# - 在没有 APNS 的应用程序中显示 Apple 警报角标(Badge)

c# - 如何在控制台应用程序中为连接字符串定义数据目录以使用 Entity Framework 代码优先迁移

c++ - 增强精神解析器: getting around the greedy kleene *

C# - 没有为类型 'System.Int64' 定义二元运算符 Equal

c# - 将我的 DTO 暴露给认为不正确的 View 吗?

c# - 微软的 botframework 是免费的吗?