GLR解析与C++解析器的深入探究
1. GLR解析概述
1.1 GLR解析的优缺点
传统的解析器生成器(如yacc和bison)创建的解析器比手写解析器更可靠。若将无冲突的语法输入到bison,生成的解析器接受的语言与语法描述完全一致。而GLR解析允许将任何语法交给bison,它会在解析时解决冲突。但冲突越多,解析的语言越可能不是你想要的,解析器也越难按预期解决冲突。
1.2 GLR解析的性能
理论上,GLR解析器可能非常慢,因为并行运行N个解析大约比单个解析慢N倍,特别是在语法高度模糊时,每个标记都可能分支。不过,有用的GLR语法通常只有少量模糊性,且能在几个标记内解决,所以性能通常是足够的。
1.3 GLR解析处理冲突的方式
正常的bison LALR解析器在构建时已解决所有冲突,无需处理移进/归约或归约/归约冲突。而GLR解析器遇到冲突时,会概念性地分支并继续两种可能的解析,并行消耗输入标记。若有多个冲突,会创建部分解析的树。
若语法实际上是明确的,只是需要比LALR(1)提供的单个标记更多的前瞻,大多数解析最终会因无法匹配下一个输入标记而失败。bison会默默丢弃失败的解析,只要还有至少一个解析仍在活动就会继续。若所有可能的解析都失败,bison会按常规方式报告错误。对于这类语法,GLR解析器的工作方式与常规LALR解析器非常相似,只需添加几行代码告诉它使用GLR解析器并告知预期的冲突数量。
若语法确实模糊,解析器会遇到有两个或更多使用相同左部符号的规则可能归约的状态。此时有两种解决方法:
- 使用% dprec N标签
超级会员免费看
订阅专栏 解锁全文
6

被折叠的 条评论
为什么被折叠?



