语法高亮 - 最高效和专业的方式

6
问题:
我需要代码实现:对编程语言进行语法高亮
语言: C# 或者汇编 x86 (最好是C#)
平台: Windows
要求: 实现方式最高效/最专业/大公司如微软的实现方式
改写后: 如何以目前已知的最高效方式,在Windows上用C#实现编程语言的语法高亮?


详细说明(可跳过 - 不需要回答问题):
我不想只是采用任何方法 - 我已经看到了几种。
我想知道微软在Visual Studio(任何版本)中是如何做到这么好的。

当涉及到语法高亮时,人们总是试图重新发明轮子。我不明白为什么。
这被认为是一个非常难的问题吗?我已经看到了一些只突出显示当前屏幕内容的实现,我认为这是正确的方式...(它使用了一些聪明的API来知道文本框的哪些行实际上正在显示)。
我也看到了一些使用RichTextBox的实现,我认为那不是正确的方式(也许我在这里是错的) - 我认为像子类化绘制常规文本框的例程并更改其画笔可能更好(也许我在某个地方看到过这样的实现 - 我不认为我自己能想出来)
此外,我听说有些人使用AST来实现,就像编译器一样编码(词法分析部分,我想?) - 我希望那是累赘 - 我不认为那是有效的。(无知的猜测)

如果这确实是一个困难的问题,那么大公司如何总是做对呢?例如,我从未听说过破解Visual Studio中的语法高亮方式。
但任何其他工具实现它都做得很糟糕,或者比大公司做得更差。
什么是官方的“这是最好的方式,任何其他方式都不够高效”的方法?

我真的没有证据表明微软的方式更好,但是考虑到他们可能比其他任何人都更了解Windows API,我猜他们的实现方式是最好的(我希望我错了 - 想象一下能够说我的语法高亮实现比MS的更好!)

抱歉说明有些杂乱无章。
此外,我提前为任何失礼道歉 - 这是我的第一个问题。
4个回答

1

最好的方法也许是重用现有的东西,比如ScintillaNET


1
谢谢。我已经看过那个以及其他几个,但我更想知道它在更商业化的IDE中是如何实现的。 - PeterM

1

我认为没有一种"这是最好的方法,其他任何方法都不如它高效"的方式来做。实际上,我觉得效率并不是主要问题,复杂性才是。 一个好的语法高亮器基于一个好的解析器。只要你能解析代码,你可以以任何你喜欢的方式突出显示它的每个部分。但是,当代码格式不正确时会发生什么呢?很多语法高亮器只是突出显示关键字和一些块结构来解决这个问题。通过这样做,他们可以使用简单的正则表达式,而不是一个完备的、容忍语法错误的解析器(这就是Visual Studio所拥有的)。


是的,但是你看,正则表达式难道不比微软采用的任何方式都要低效吗?所以你说对于微软来说很容易,因为他们已经有了语言解析器(用于编译),因此他们可以只使用它来进行语法高亮,并且自动获得100%的正确性? 如果是这样,您能指出实现该方式的代码吗? - PeterM
@悲观主义者:你可能想看一下这个链接:http://bit.ly/3w5wK3 和这个链接:http://bit.ly/dxDrkx。 - Klaus Byskov Pedersen
@悲观主义者:但请注意,当高亮代码不是格式良好时,仅使用编译器是不够的。此外,正如您可能在维基百科上读到的那样,正则表达式方法并不一定非常高效。 - Klaus Byskov Pedersen
虽然没有提供代码,我真的很想看到一些实现建议解决方案的代码(同时也要涉及到原始问题中概述的更大的背景,例如仅突出显示可见代码等)。但我明白这里在讨论什么,我可以将其与我已知的内容联系起来。我会选择此作为采纳答案。 - PeterM

0

如果您能够嵌入网页,您可以查看Prism.js


0

就像任何代码一样......很少有“最佳”方法。有多种做事的方式,每种方式都有优点和缺点。

话虽如此,某种形式的解释器模式可能是最常见的方法。根据GoF书籍

解释器模式在使用面向对象语言实现的编译器中广泛使用,例如Smalltalk编译器。SPECTalk使用该模式来解释输入文件格式的描述。QOCA约束求解工具包使用它来评估约束条件。

它还继续谈论了它在适用性部分的限制。

  • 语法简单。对于复杂的语法,语法的类层次结构会变得庞大且难以管理。在这种情况下,解析器生成器等工具是更好的选择。
  • 效率不是关键问题。最高效的解释器通常不是通过直接解释解析树来实现,而是先将其转换为另一种形式。例如,正则表达式经常被转换为状态机。但即使如此,翻译器也可以通过解释器模式来实现,因此该模式仍然适用。

了解这一点后,您现在应该知道为什么在执行多个匹配之前最好预编译可重用的RegEx。如果不这样做,它将不得不每次都执行两个步骤(转换、解释),而不是只构建一次状态机,然后有效地多次应用它。

针对您所描述的解释类型,微软公开了Microsoft.VisualStudio命名空间及其强大功能,作为Visual Studio SDK的一部分。您还可以查看System.CodeDOM以进行动态代码生成和编译。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接