编写语法高亮器

34

我希望在暑假的项目中编写自己的语法高亮器,但我不确定如何编写自己的语法高亮器。

我知道有很多实现方式,但我想学习正则表达式以及语法高亮的工作原理。

语法高亮是如何工作的?开发一个好的语法高亮器需要哪些参考资料?语法高亮器是逐个字符扫描还是在每个字符输入后扫描整个文档/文本区域?

非常感谢您提供的任何见解。

谢谢。

PS:我打算用ActionScript编写它。

7个回答

30
语法高亮器可以通过两种非常一般的方式工作。第一种实现了用于高亮显示的语言的完整词法分析器和语法分析器,精确地识别每个标记的类型(关键字、类名、实例名、变量类型、预处理器指令...)。这提供了所有需要根据某些规范准确突出显示代码的信息(关键字为红色,类名为蓝色等)。
第二种方法类似于Google Code Prettify所使用的方法,其中不是为每种语言实现一个词法分析器/语法分析器,而是使用了几个非常通用的解析器,可以在大多数语法上做出合理的效果。例如,此高亮器将能够合理地解析和突出显示任何类C语言,因为其词法分析器/语法分析器可以识别这些类型语言的一般组件。
这也具有优点,即作为结果,您不需要明确指定语言,因为引擎将自行确定哪个通用解析器可以做出最佳效果。当然,缺点是突出显示不如使用特定于语言的解析器那样完美。

3
你开始说荧光笔有两种一般的使用方式,但是除非我误解了,你没有解释第二种方式。 - Marplesoft
10
据我理解,第一种方法是为每种语言编写一个词法分析器和语法分析器,而第二种方法是编写通用的词法分析器和语法分析器。 - yasar
使用Trie数据结构可能会有帮助。 - S.A.Parkhid

17

构建语法高亮器的关键在于在代码中查找特定的关键词并给它们指定一个特定的样式(字体、字体风格、颜色等)。为了实现这一点,您需要定义一个特定于编程语言的关键词列表,并解析文本(例如使用正则表达式),找到特定的标记,并用正确样式的HTML标记替换它们。

一个非常基本的JavaScript高亮器将如下所示:

var keywords = [ "public", "class", "private", "static", "return", "void" ];
for (var i = 0; i < keywords.length; i++)
{
        var regex = new RegExp("([^A-z0-9])(" + keywords[i] + ")([^A-z0-9])(?![^<]*>|[^<>]*</)", "g");
        code = code.replace(regex, "$1<span class='rm-code-keyword'>$2</span>$3");
}

4
一个好的开始是参加Udacity课程CS262。虽然标题是“构建一个Web浏览器”,但实际上课程重点关注您正在寻找的问题——如何解析和分析一组文本。在您的情况下,您将使用这些信息进行突出显示。我刚刚学完这门课程,感觉非常好。该课程现在已经“结束”,但视频、练习题和作业仍可供查看。

1
链接已失效。 - BarbaraKwarc
@BarbaraKwarc,链接对我来说没有失效,但是课程已经失效了:? - blueberry_chopsticks

4
StackOverflow第50期播客中,Steve Yegge谈到了他创建一些通用的高亮机制的项目。虽然这不是一个成品,可能比您想要的更为复杂,但其中可能有一些有趣的东西。

这个播客在链接页面上真的可以听吗? - Orestis Kapar
2
@OrestesKappa 看起来不是这样。我只需在Google的播客应用程序中搜索“Stack Overflow Podcast”,然后向下滚动到第50集,就能找到它。它应该可以从任何播客播放器中获取。 - Yoshi Askharoun

3

很遗憾,我从未使用过Actionscript,所以无法帮助您解决此问题。

但是除此之外,编写语法高亮器的好方法是查看现有的高亮器。例如,vim具有普通文本文件形式的语法文件,因此您可以从中开始查看。那里有一堆正则表达式(正则表达式有几种不同的风格,但它们并没有太大的区别...),因此对于这部分,您可以参考一些书籍。

就个人而言,我发现Beginning regular expressions是一本不错的书。对于更高级的主题,Mastering regular expressions也很不错。另一方面,Regular expressions pocket reference适合确定上述风格的差异,因为它还包括关于vim的正则表达式的章节。


2
如果您能解释一下这个语法高亮器的作用,可能会有所帮助。如果您是使用ActionScript编写它,您的想法是在Flash动画中有一个文本框,在提交按钮被按下后突出显示语法?还是您想从某个Web服务中读取文本,然后显示突出显示的语法?... 对我来说很难提供帮助,因为我很难想象您正在做什么。
然而,语法高亮器会读取文本,然后将代码行与一些正则表达式进行比较,以帮助语法高亮器确定单词的含义。例如,它可能将“function”或“int”等单词读作保留字,并将它们替换为html文本:
<span class="reserved">function</span>, <span class="reserved"></span>

假设您已经有了CSS,并且想将保留字标记为红色,
.reserved{
  color: #ff0000;
}

这是基本概念,您可能希望从geshi获取灵感,因为您可以查看源代码。


抱歉我没有说明得更清楚。我计划在Adobe Flex中实现一个协作式文本编辑器。我想要的是一个TextArea或类似的文本输入组件……然后当用户打字时,例如Java代码,他们正在输入的代码将变为语法高亮显示。就像任何具有语法高亮显示功能的IDE一样。 - Ian Dallas

1

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