2012-01-11 86 views
1

野牛一个循环,这样,我得到这个代码:实现使用BNF

calclist: /* nothing */ matches at beginning of input 
| calclist exp EOL { printf("= %d\n", $1); } EOL is end of an expression 
; 

据解释说:

前两个规则,定义符号calcset,实现循环 读取由换行符终止的表达式并打印其值。 calclist的定义使用了一个共同的两规则递归惯用法来实现一个序列或列表:第一个规则是空的,并且与 没有任何关系;第二个将项目添加到列表中。第二个 规则中的操作在$ 2中打印exp的值。

从书“Flex和野牛”。有人可以告诉我这样的语法意味着一个循环吗?我可以理解exp中的递归(稍后写,但我不包括,因为它在这里不相关)。然而,看看这样的语法,我只能想到第一条规则没有匹配任何东西来保持解析器不处理任何东西,因此,直到从标准输入流中提供第一个符号并启动第二个规则,才会有无限循环。但是,我不明白第二条规则。它怎么能达到exp部分?当它遇到calclist时,它会保持递归吗?

回答

4

第二条规则意味着一个循环,如果你有一条线,如:

exp EOL exp EOL exp EOL exp EOL 

每个那些“EXP EOL” S是一个calclist,这是包括另一calclist内。 因此,规则将减少该行这样:

exp EOL exp EOL exp EOL exp EOL 
calclist1 exp EOL exp EOL exp EOL exp EOL < - Rule 1. calclist1 is [ ], the empty string. 
calclist2 exp EOL exp EOL exp EOL < - Rule 2. calclist2 is calclist1 exp EOL 
calclist3 exp EOL exp EOL < - Rule 2. calclist3 is calclist2 exp EOL 
calclist4 exp EOL < - Rule 2. calclist4 is calclist3 exp EOL 
calclist5 < - Rule 2. calclist5 is calclist4 exp EOL 

这是什么意思由它创建一个循环。就像您所引用的部分一样,在定义语法以创建任意长度的表达式列表时,这是一个常见的“成语”。

我希望能回答你的问题。

谢谢!

+0

啊我明白了。 calclist1 exp EOL => calclist2。我认为Bison会从左向右处理输入流,这意味着它会一直进入'calclist - > calclist - > calclist',并且永远不会到达'exp'段。现在我认为,右边的规则是让Bison匹配来自输入流的模式,但不是从左到右的处理,不是吗?因为我们可以定义:'exp:exp exp'+'',这显然是匹配的模式,但不是实际的代码。通常,'exp'的例子是这样写的:'exp:exp + exp',因此我认为这是实际的实现。 – Amumu 2012-01-11 02:58:51

1

如果这是一个递归下降解析器,但我想重点是它不是。