javascript - 在 Antlr4 中重用规则总是比使用令牌重新定义慢吗?
问题描述
我正在用 JavaScript 分析我的 Antlr4 生成的解析器。我有一些匹配的规则ID | STRING
。
词法分析器
ID
: [a-zA-Z_] [a-zA-Z_0-9]*
;
STRING
: '"' (~["\r\n] | '""')* ('"'|[\r\n])?
;
解析器
name: ID | STRING ;
rule1: some other rules;
rule2: different rules
some: ID | STRING ;
different: ID | STRING ;
如果我更改为some
,some: name;
性能下降约 30%。(要解析给定代码 100 次,时间从 1.5 秒增加到大约 2 秒)。different
different: name;
在这种情况下,name
是解析器中的终端节点。所以我不会假设很多开销本身。我们还有 8 个其他地方使用ID | STRING
. 那 30% 是在我将它们全部替换为name
.
测试代码为:
x = B."method. {a, b} 1"(1,2)
在上面的代码中,以下内容将被“ID | STRING”匹配:
- X
- 乙
- “方法。{a, b} 1”
- 1
- 2
我在标题中的假设是否正确?
解决方案
30% 似乎很多(但在一个非常简单的例子中这可能是人为的)
使用递归下降解析器,调用名称规则而不是识别两个标记中的任何一个都会有一些开销是有道理的。
我认为在更大的比赛中整体影响可以忽略不计,除非这是你语法中非常基本的部分,并且经常使用。
如果您在它周围感到性能痛苦,那么“展开”它可能是有道理的。当然,您会在生成的解析树中丢失“名称”上下文。这可能是好事也可能是坏事,这取决于你想如何处理事情。(有时,那些额外的解析树节点只是您拥有的噪音,可能会让人感到恼火,而其他时候,它们是重要的信息)。
推荐阅读
- python-3.x - python代码返回不在S3中的文件的数据时间戳?
- java - spring boot webflux如何同时保存更新和删除多个Monos
- typescript - 添加自定义类型打字稿3
- java - H2内存数据库测试找不到表TAB
- sql - 每个月的新 ID
- vb.net - 在网络浏览器的文本框中输入文本
- ssl - sssd (2.0.0, CentOS 8) 与旧 tls 1.0 仅 ldap
- azure - Azure Powershell 错误 - 未找到资源组
- mysql - 当我有一组值来检查任何匹配就足够的值时,如何使用 IN SQL 运算符?
- python - 海龟图形(python):NameError:未定义名称'_name_'