2009-11-04 58 views
1

如果我爲具有一系列語句的類C語言編寫語法,那麼定義語法的最常用方法是什麼?用於語句順序的BNF語法

我的想法是做這樣的事情:

<program> ::= <statement> 
<statement> ::= <statement-head><statement-tail> 
<statement-head> ::= <if-statement> | <var-declaration> | <assignment> | <whatever> 
<statement-tail> ::= ; | ;<statement> 

但感覺有點麻煩給我。我也考慮使

<program> ::= <statement>* 

<statement> ::= <statement-head> ; | <sequence> 
<sequence> ::= <statement> <statement> 

類型作品。

有沒有一個標準或可接受的方式來做到這一點。我希望我的AST儘可能地乾淨。

回答

7

一個非常普遍的方法是:

<block-statement> ::= '{' <statement-list> '}' ;
<statement-list> ::= /* empty */ | <statement-list> <statement> ;
<statement> ::= <whatever> ';' ;

然後你定義的實際語句,而不是打字<whatever>。包含尾隨分號作爲單個語句的一部分似乎更清晰,而不是將它們放在非終端列表的定義中。

+0

我喜歡這個。我唯一的問題是我不確定大多數解析器生成器(我使用TinyPG)是否支持/ *空* /生產。我的印象是它不那麼猶太教。 – captncraig 2009-11-04 18:02:50

+0

沒關係。在看完C語法後,艾登發佈了它可以是: :: = | captncraig 2009-11-04 18:05:44

+0

我一直在使用我的Bison語法:-)實際上,我從O'Reilly的書籍* lex和yacc *中獲得它,作者系統地使用/ * empty * /來強調空的規則真的存在爲了某件事。如果您的解析器生成器不支持這種評論,那麼您當然可以放棄它。 – 2009-11-04 18:13:51

2

您可以找到C here的BNF,我認爲它來自K & R,您可以查看該文件。你也可以看看SQL BNF here,它可以提供更多關於制定好序列的信息。

這將提供一些約定信息。

就AST的產生而言,真正無關緊要的是您的定義是如何爲所有排列正確解析源代碼。然後只需添加行動來建立您的AST。

只要確定您正在爲正確的解析器生成器(如LL或LR解析器)構造您的語法,因爲您可能遇到復位問題,這將意味着需要以新方式重寫一些規則。請參閱eliminating left recursion

您可能還想看看Bison/Yacc的例子,如thesethese。還檢查了Dragon Book和一本書,叫做「現代編譯器實現在C」