2

在代码中查找 RPAREN 的最佳方法是什么?例如,我有这个伪代码:

if(a && (b || "c)"))
  |     ^---------^| CASE A
  ^----------------^ CASE B

例如,如果我考虑第一个 LPAREN,它需要与最后一个 RPAREN 匹配(案例 B)。如果我考虑第二个 LPAREN,它需要与最后一个 RPAREN 匹配(案例 A)。

请注意,有些字符串"C)"具有 RPAREN,但在这种情况下需要忽略它。

嗯......我想到了正则表达式,但我想它会非常复杂(注意需要匹配字符串,正则表达式,然后另一个认为可以包括 RPAREN 或类似的东西)。然后我考虑使用手动扫描(通过代码)来检测每个部分(如手动正则表达式)。

我需要它来解析我正在构建的代码(自己的编程语言)。而且我想忽略阅读一些代码以使其更快。

例如:

function a() { return 1; }
function b() { return 2; }
alert(b());

在这种情况下,只b()需要被解析,因为a()从不使用。所以我将按启动器扫描{并忽略(但存储)直到真正的}. 如果使用该函数,它将被解析。

我的疑惑:

  1. 正则表达式还是手动代码?
  2. 这是好事还是坏事?如果从未使用过代码,请忽略它有助于提高解析器的速度吗?
  3. 题外话:一些加快解析器速度的技巧?也许是一个“预解析”文件,将语言代码与计算机代码(操作码???)一起存储?
4

2 回答 2

3
  1. 正则表达式无法匹配括号 - 这是不可能的。解析这种语言的一种方法是 lex(tokenize)和 yacc(解析器)——你可以在网上找到很多信息。

  2. 向解析器添加优化不太可能使其解析更快,但可以提高生成代码的性能。好与坏是道德判断,我不知道它们在这里是什么意思。

  3. 匹配源代码中的模式并替换预编译的优化代码可以为您提供改进的结果,但它是否加快解析速度取决于模式在代码中出现的频率。

于 2012-02-29T04:32:46.457 回答
2

如果您正在构建自己的语言,您应该真正了解处理语言源代码的标准方法。(欢迎你提出聪明的新想法,但大多数这样的想法都不是那么聪明,如果你知道标准的想法,那么为什么会很明显)。

您真的无法使用纯正则表达式处理您的代码和“匹配”括号。您需要某种下推自动机或计数引擎来匹配嵌套的括号(或任何其他可能匹配的内容,例如大括号、IF 和 ENDIF,...),在此类任务的上下文中通常称为“解析器”。

关于你的3个问题:

1)正则表达式或手动代码?

了解/使用解析器生成器,例如ANTLR

2)这是好事还是坏事?如果从未使用过代码,请忽略它有助于提高解析器的速度吗?

这确实是一个“过早”的优化。最好简单地获得一个快速解析引擎。ANTLR 还不错;我怀疑你是否会注意到差异。如果您坚持快速燃烧,请考虑 使用 LRSTAR;构建它的人在过去十年中对其生成的解析器进行了微优化,而且它们的速度非常快。

鉴于您正在尝试实现一种编程语言,我建议您担心实际清晰定义它、构建工作解析器以及以实际方式执行它(无论这意味着解释还是编译)的更大问题没关系)。鉴于您对解析业务的明显理解水平,我怀疑您真的还没有准备好这样做。您最好花一些时间学习编译器的一般工作方式,以便您有一个参考点。

3) 题外话:一些加快解析器速度的技巧?也许是一个“预解析”文件,将语言代码与计算机代码(操作码???)一起存储?

您可以通过预处理文本并将其存储为一组标记来加速解析器。您还可以通过在假设没有更改的情况下存储先前解析的结果来加速它。(大型代码系统中的大多数源文件不会更改,即使它们可能会被重新编译很多次)。您甚至可以将编译后的代码与源文本一起存储在某种表示形式中,以避免编译它。[我考虑过为这样的单个函数存储编译代码;即使编辑文件,中的大部分功能也不会改变]。这些技巧都有麻烦:你如何通过设置这一切来让程序员和编辑合作?构建一个快速解析器要容易得多,您应该从那里开始,稍后再担心花哨的技巧。

于 2012-02-29T13:33:56.587 回答