所以,我得到了这段代码:
calclist: /* nothing */ matches at beginning of input
| calclist exp EOL { printf("= %d\n", $1); } EOL is end of an expression
;
解释说:
定义符号calcset的前两个规则实现了一个循环 读取由换行符终止的表达式并打印其值。 calclist的定义使用常见的双规则递归惯用法 实现序列或列表:第一个规则是空的并匹配 没有;第二个将一个项添加到列表中。第二个动作 rule以$ 2打印exp的值。
来自“Flex and Bison”一书。有人可以告诉我这样的语法是如何暗示循环的吗?我可以理解exp
中的递归(稍后会写,但我不包含因为它在这里无关紧要)。但是,看看这样的语法,我只能想到第一条规则不匹配任何东西,以保持解析器不处理任何东西,从而具有无限循环,直到从标准输入流给出第一个符号并启动第二个规则。但是,我不明白第二条规则。怎么能到达exp
部分?遇到calclist
会不会继续递归?
答案 0 :(得分:4)
第二条规则意味着一个循环,好像你有一行如:
exp EOL exp EOL exp EOL exp EOL
这些“exp EOL”中的每一个都是一个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
这就是创建循环的意思。就像你引用的部分一样,这是定义语法时常见的“习语”,以便创建任意长度的表达式列表。
我希望能回答你的问题。
谢谢!
答案 1 :(得分:1)
如果这是一个递归下降解析器,但我想重点是它不是。