我正在分析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"匹配:
- x B
- "利用。{a, b} 1"> 12
标题中的假设是否正确?
30%似乎很多(但在一个非常简单的例子中可能是人为的)
使用递归下降解析器,在调用name规则而不是识别两个标记中的任何一个时,会有一些开销是有意义的。
我认为在更大的比赛中,整体影响可以忽略不计,除非这是语法中非常基本的一部分,并且使用得很多。
如果您在它周围感到性能痛苦,那么请"展开"。这可能是有道理的。当然,你会失去"名字"。上下文中的结果解析树。这可能是一件好事,也可能是一件坏事,这取决于你想如何处理事情。(有时那些额外的解析树节点只是你的噪音,可能会让你感到恼火,而其他时候,它们是重要的信息片段)。