我正在使用 Antlr4 创建解释器、词法分析器和解析器。它将用于的 GUI 包含 QScintilla2。
由于 QScintilla 不需要解析器并且具有 CustomLexer 模块,(Antlr4 构建,Python3 目标)解释器就足够了吗?
我不是在征求意见,而是在寻求事实指导。谢谢。
我正在使用 Antlr4 创建解释器、词法分析器和解析器。它将用于的 GUI 包含 QScintilla2。
由于 QScintilla 不需要解析器并且具有 CustomLexer 模块,(Antlr4 构建,Python3 目标)解释器就足够了吗?
我不是在征求意见,而是在寻求事实指导。谢谢。
口译员包含什么
解释器必须有某种方式来解析代码,然后有某种方式来运行它。通常“解析代码的方式”将由词法分析器+解析器处理,但也可以进行无词法分析。无论哪种方式,解析器都会创建代码的一些中间表示,例如树或字节码。然后,“运行它的方式”将是一个迭代生成的树或字节码并执行它的阶段。JIT 编译(即从树或字节码生成机器代码然后执行)也是可能的,但更高级。您还可以在解析和执行之间运行各种分析(例如,您可以检查是否有任何未定义的变量或在任何地方使用,或者您可以进行静态类型检查——尽管后者在解释语言中并不常见)。
使用 ANTLR 时,ANTLR 将为您生成一个词法分析器和解析器,后者将生成一个解析树作为结果,您可以使用生成的侦听器或访问者对其进行迭代。那时,您可以按照自己的代码进行操作。例如,您可以从解析树生成字节码并执行它,将解析树转换为简化树并执行它或直接在访问者中执行解析树。
QScintilla 是关于显示语言的,与解释器无关。在 IDE 中,控制台是解释器与运行脚本一起发挥作用的地方(例如,从“运行”按钮)。QScintilla 和解释器唯一的共同点是脚本文件——解释器没有连接或链接到 QScintilla。这是否具有基本意义?
是的,这是有道理的,但不必完全如此。也就是说,重用解释器的某些部分以在编辑器/IDE 中实现某些功能是有意义的,但您不必这样做。
您已经特别提到了“运行”按钮,就这一点而言,解释器的实现(以及它是否使用 ANTLR)完全无关紧要。实际上,解释器是用哪种语言编写的甚至都没有关系。如果您的解释器被命名mylangi
并且您当前正在编辑一个名为 的文件foo.mylang
,那么点击“运行”按钮应该简单地执行subprocess.run(["mylangi", "foo.mylang"])
并在某种选项卡中显示结果或窗户。
如果您想拥有一个“控制台”或“REPL”窗口,您可以在其中与解释器交互:您只需将解释器作为子进程调用并将其连接到显示控制台的选项卡或子窗口。同样,解释器的实现与此无关 - 您将其视为任何其他命令行应用程序。
现在 IDE 和代码编辑器的其他功能是语法高亮、自动完成和错误高亮。
对于语法高亮,您需要一些通过源代码并告诉编辑器代码的哪些部分应该具有哪种颜色(或粗体等)的代码。使用 QScintilla,您可以通过提供一个执行此操作的词法分析器类来完成此操作。您可以定义这样一个类,只需编写必要的代码来手动检测标记的类型,但您也可以重用由 ANTLR 生成的词法分析器。因此,这是可以在编辑器/IDE 中重用解释器实现的一种方式。但是,由于语法荧光笔通常很容易手动编写,因此您不必这样做。
对于代码完成,您需要了解文件中定义了哪些变量和函数,它们的范围是什么,以及当前文件中包含哪些其他文件。如今,在所谓的语言服务器中实现此逻辑已变得很普遍,该语言服务器是可以从不同的编辑器和 IDE 中重复使用的独立工具。无论您是在这样的语言服务器中还是直接在编辑器中实现此逻辑,您都需要一个解析器(如果适用,还需要一个类型检查器)来回答这些类型的问题。同样,您可以从解释器中重复使用这些东西,这一次绝对是一个好主意,因为编写第二个解析器将是重要的额外工作(并且很容易与解释器的解析器不同步)。
对于错误突出显示,您可以简单地在“仅验证”模式下调用解释器(即只打印出语法错误和其他可以静态检测到的错误,但实际上并不运行文件——许多解释器都有这样的选项)然后解析输出以找出在哪里绘制波浪线。但是您也可以从您的解释器中重新使用解析器(如果有的话,还可以进行分析)。如果您选择使用语言服务器,错误和警告也将由语言服务器处理。