如何在YACC(/RACC)中编码系列可选标记及产生式最简性验证
结论
你当前的产生式功能可以正确匹配a[b]?[c]?[d]?对应的所有token序列,但不是最简形式,存在更简洁、可维护性更高的实现方案。
现有写法的问题
你把三个可选后缀(B、C、D)的匹配逻辑耦合在了b、c两个非终结符中,分支逻辑不够直观,后续如果需要调整单个可选段的规则(比如要求B出现时C必须出现),修改成本会更高。
更优实现方案
方案1:逻辑对齐正则的最简可维护写法
完全和正则的可选段一一对应,每个可选逻辑单独拆分非终结符,可读性最强:
expr : A optional_B optional_C optional_D ; optional_B : /* 空,匹配B不出现的情况 */ | B ; optional_C : /* 空,匹配C不出现的情况 */ | C ; optional_D : /* 空,匹配D不出现的情况 */ | D ;
这个方案仅比你原来的写法多1个非终结符,但逻辑完全清晰,每个非终结符职责单一,后续调整成本极低。
方案2:最少非终结符的极简写法
如果追求最少非终结符数量,且后续不会新增可选后缀,可以直接把所有合法分支列在expr下,不需要额外非终结符,执行效率最高:
expr : A | A B | A C | A D | A B C | A B D | A C D | A B C D ;
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

