野牛解析无法区分变量声明和赋值

时间:2014-02-02 00:02:56

标签: parsing bison

所以我的语法有规则,

Method     : METHODNAME Params ')' ':' Types '{' VarsDecs Statements RETURN Returns '}' ';'
           ;
           ;
VarsDecs   : VarDec VarsDecs 
           | 
           ;
VarDec     : VARNAME ':' Types ';'
           ;
Statements : Statement Statements
           |
           ;
Statement  : Assignment
           | Print
           | If
           ;                            
Assignment : VARNAME '=' Expression ';'
           ;

我的解析器无法判断变量声明何时停止,并且当赋值是找到的第一个语句时语句开始,因为赋值也以VARNAME开头。

我将如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

基本问题是它需要在开始解析语句之前减少一个空规则,但是当它看到VARNAME作为前瞻时,它无法判断它是否在变量的末尾进行了演示,因为它需要更多的前瞻来区分VarDecStatement

你可以通过使其递归而不是右递归来改善一些事情,但这并不能完全解决问题。要真正解决问题,你需要摆脱空语句规则:

Statements : Statements Statement
           | Statement

然后将Method规则更改为两个版本,一个带语句,另一个没有:

Method     : METHODNAME Params ')' ':' Types '{' VarsDecs Statements RETURN Returns '}' ';'
           | METHODNAME Params ')' ':' Types '{' VarsDecs RETURN Returns '}' ';'

答案 1 :(得分:0)

语法不是全部,所以很难直接测试,但使用正确的递归代替normal left recursion可能是其中的一部分。

Statements : Statement Statements
VarsDecs   : VarDec VarsDecs 

尝试让它保持递归

Statements : Statements Statement
VarsDecs   : VarsDecs VarDec