2012-01-11 87 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

如果這是一個遞歸下降解析器,但我想重點是它不是。