ANTLR是否会自动提取顶层分支?附两种算术表达式文法对比
关于ANTLR两种等价文法结构的疑问
我写了两种算术表达式文法,一种将同优先级的运算符拆分为独立分支,另一种则把同优先级运算符分组到同一分支中:
未分组的文法(NoPrefix)
grammar NoPrefix; root: (expr ';')* EOF; expr : '(' expr ')' | expr '*' expr | expr '/' expr | expr '+' expr | expr '-' expr | Atom ; Atom: [a-z]+ | [0-9]+ | '\'' Atom '\''; WHITESPACE: [ \t\r\n] -> skip;
分组后的文法(YesPrefix)
grammar YesPrefix; root: (expr ';')* EOF; expr : '(' expr ')' | expr ('*'|'/') expr | expr ('+'|'-') expr | Atom ; Atom:[a-z]+ | [0-9]+ | '\'' Atom '\''; WHITESPACE: [ \t\r\n] -> skip;
这两种文法在运行时间、生成的解析器大小等方面几乎完全一致。我想知道ANTLR是否会自动把这两种分支形式转换成完全相同的输出,比如将:
expr: expr '*' expr | expr '/' expr <==> expr: expr ('*'|'/') expr;
这两种写法视为等价,并生成相同的内部结构和解析器?
是的,ANTLR会将这两种写法视为等价,并生成完全相同的解析器结构。
从语法定义的语义来看,expr '*' expr | expr '/' expr 和 expr ('*'|'/') expr 描述的是完全一致的语法规则——都是匹配一个表达式,后跟乘/除运算符,再跟一个表达式。ANTLR在处理文法时,会对这两种形式做等价转换,最终生成的解析器在运行逻辑、性能、结构大小上没有区别。
这种分组写法只是语法层面的简化,本质上和拆分多个分支没有差异,ANTLR的内部处理会将它们归一化为相同的状态机和解析逻辑,所以才会出现你观察到的运行时间、构建大小几乎一致的情况。
内容的提问来源于stack exchange,提问作者samuelbrody1249
相关产品推荐
相关产品推荐

