创建shift-reduce / reduce-reduce自由语法

时间:2011-04-11 23:17:44

标签: parsing compiler-construction grammar shift-reduce-conflict reduce-reduce-conflict

我正在尝试在sablecc中实现一个简单的Java语言解析器,尽管在实现shift-reducereduce-reduce时我经常遇到if / while个问题和block陈述。

例如,我考虑过以下几点:

stmts = stmt*;

stmt = if_stmt | block_stmt | while_stmt;

block_stmt = { stmts } | ;;

while_stmt = while ( predicate ) { stmts } | while ( predicate ) ;

例如,这种语法会导致问题,即当你有某种形式时

while (true) ;

解析器无法知道是仅减少;(来自block_stmt)还是完整while (true);(来自while_stmt)。

我一直在阅读shift-reduce / reduce-reduce问题的原因,我想我理解它们。但有一件事是要知道是什么导致了它们,而另一件完全不同的是知道如何构造语法以避免它们。我尝试以非常不同的方式实现语法,但我最终还是遇到了问题。

我想这不是仅仅尝试从特定的ss / rr问题中运行,而是必须采用一种范式来避免这类问题吗?我相信我处理这个问题的方式一定是完全错误的:(

关于如何从头开始构建语法而不会陷入所有这些陷阱的任何资源?关于这个问题的资源往往要么很容易(说明明显的if then else问题),要么是完全标记的语法,这些语法是不可穿透的。

1 个答案:

答案 0 :(得分:2)

问题在于你的语法是如此指定的,例如分号可以解释为while_stmt的分号或block_stmt的分号......不好意思不是,但不知何故语法是多余的,因为{stmt}在RHS上出现两次。通常你会这样做

 stmts ::= stmt | stmts stmt
 block_stmt ::= { stmts }
 stmt ::= ... | block_stmt | ;     // empty
 while_stmt ::= while ... stmt