我在 Java 中为 Android 开发了一个语法荧光笔,它运行良好,但问题是大文件可能会很慢。
所以我想知道 Eclipse 和 Gedit (Ubuntu) 之类的源代码编辑器如何快速突出显示您刚刚编写的内容。例如,如果您在编写 HTML 标记时输入结尾大于符号,它会立即突出显示该标记。
怎么这么快,即使是大文件?他们有没有一种特定的方式来做这件事,或者他们只是为你所在的行执行语法突出显示?
谢谢,亚历克斯
我在 Java 中为 Android 开发了一个语法荧光笔,它运行良好,但问题是大文件可能会很慢。
所以我想知道 Eclipse 和 Gedit (Ubuntu) 之类的源代码编辑器如何快速突出显示您刚刚编写的内容。例如,如果您在编写 HTML 标记时输入结尾大于符号,它会立即突出显示该标记。
怎么这么快,即使是大文件?他们有没有一种特定的方式来做这件事,或者他们只是为你所在的行执行语法突出显示?
谢谢,亚历克斯
我不能为 Gedit 说话,但在 Eclipse 中,我们作弊 :-)
如果您仔细观察,您实际上可以看到像 Java 这样的结构化语言的语法着色是一个两阶段的过程。
首先,运行演示协调器来进行非常基本的语法着色。这是在编辑器的文档发生更改时立即触发的,并且预计会非常快。它实际上不是基于语法的着色,而是基于词法的着色。因此,重点是字符串、关键字、单词、数字、评论等标记——所有可以基于简单字符表或类似字符轻松识别的标记。因此,类名、变量名或静态方法名之间没有区别,即使它们最终的颜色可能不同。对于许多语言,这是唯一完成的着色。
接下来,运行语法协调器来为文档构建抽象语法树 (AST) - 或者尽可能接近语法错误或语义错误。这是由计时器触发的,对于某些语言,尝试仅对AST 进行部分更新(不容易)。然后使用完成的 AST 更新大纲视图,然后根据附加信息(例如静态方法名称)进行附加语法着色。(AST 通常用于许多其他事情,例如悬停信息、折叠、超链接等。
对于最初的表示协调器和后来的基于语法的协调器,一些相当复杂的逻辑决定了必须解析的文档区域的大小。对于表示协调器,该决定可以基于任何现有的着色,而对于基于语法的着色,运行中的单独损坏/修复阶段以确定区域的大小。
一些总是使事情复杂化的极端示例是添加或删除块评论时
a = b /* c + 1 /* remember the offset! */;
如果删除或添加第一个斜线,则演示协调器必须处理比天真的预期更大的区域......