在Antlr4中重用规则总是比用令牌重新定义慢吗?



我正在分析JavaScript中生成的Antlr4解析器。我有一些与ID | STRING匹配的规则。

词法分析程序

ID
: [a-zA-Z_] [a-zA-Z_0-9]*
;
STRING
: '"' (~["rn] | '""')* ('"'|[rn])?
;
解析器

name: ID | STRING ;
rule1: some other rules;
rule2: different rules
some: ID | STRING ;
different: ID | STRING ;

如果我将some改为some: name;,将different改为different: name;,性能下降约30%。(要解析给定代码100次,时间从1.5秒增加到大约2s)。

在本例中,name是解析器中的终端节点。所以我不会假设它本身有很多开销。我们还有8个地方使用ID | STRING。那30%是在我用name代替它们之后。

测试代码为:
x = B."method. {a, b} 1"(1,2)

在上面的代码中,以下内容将由"ID | STRING"匹配:

  1. x
  2. B
  3. "利用。{a, b} 1">
  4. 1
  5. 2

标题中的假设是否正确?

30%似乎很多(但在一个非常简单的例子中可能是人为的)

使用递归下降解析器,在调用name规则而不是识别两个标记中的任何一个时,会有一些开销是有意义的。

我认为在更大的比赛中,整体影响可以忽略不计,除非这是语法中非常基本的一部分,并且使用得很多。

如果您在它周围感到性能痛苦,那么请"展开"。这可能是有道理的。当然,你会失去"名字"。上下文中的结果解析树。这可能是一件好事,也可能是一件坏事,这取决于你想如何处理事情。(有时那些额外的解析树节点只是你的噪音,可能会让你感到恼火,而其他时候,它们是重要的信息片段)。

最新更新