什麼是BNF範式,什麼又是EBNF範式

什麼是BNF範式,什麼又是EBNF範式?

巴科斯範式及其擴展
BNF & Augmented BNF   
     
     什麼是巴科斯範式?
  
  巴科斯範式(BNF: Backus-Naur Form 的縮寫)是由 John Backus 和 Peter Naur 首先引入的用來描述計算機語言語法的符號集。
  現在,幾乎每一位新編程語言書籍的作者都使用巴科斯範式來定義編程語言的語法規則。   
     
     巴科斯範式的內容  

在雙引號中的字("word")代表着這些字符本身。而double_quote用來代表雙引號。
在雙引號外的字(有可能有下劃線)代表着語法部分。
尖括號( < > )內包含的爲必選項。
方括號( [ ] )內包含的爲可選項。
大括號( { } )內包含的爲可重複0至無數次的項。
豎線( | )表示在其左右兩邊任選一項,相當於"OR"的意思。
::= 是“被定義爲”的意思。 
   
     巴科斯範式示例  

         這是用BNF來定義的Java語言中的For語句的實例:

FOR_STATEMENT ::=
      "for" "(" ( variable_declaration |
  ( expression ";" ) | ";" )
      [ expression ] ";"
      [ expression ] ";"
      ")" statement

         這是Oracle packages的BNF定義:

package_body ::= "package" package_name "is"
package_obj_body { package_obj_body }
[ "begin" seq_of_statements ]
"end" [ package_name ] ";"

package_obj_body ::= variable_declaration
| subtype_declaration
| cursor_declaration
| cursor_body
| exception_declaration
| record_declaration
| plsql_table_declaration
| procedure_body
| function_body

procedure_body ::= "procedure" procedure_name
[ "(" argument { "," argument } ")" ]
"return" return_type
"is"
[ "declare" declare_spec ";" { declare_spec ";" } ]
"begin"
seq_of_statements
[ "exception" exception_handler { exception_handler } ]
"end" [ procedure_name ] ";"

statement ::= comment
| assignment_statement
| exit_statement
| goto_statement
| if_statement
| loop_statement
| null_statement
| raise_statement
| return_statement
| sql_statement
| plsql_block

    這是用BNF來定義的BNF本身的例子:

syntax     ::=  { rule }
rule       ::=  identifier  "::="  expression
expression ::=  term { "|" term }
term       ::=  factor { factor }
factor     ::=  identifier |
                quoted_symbol |
                "("  expression  ")" |
                "["  expression  "]" |
                "{"  expression  "}"
identifier ::=  letter { letter | digit }
quoted_symbol ::= """ { any_character } """

     
     擴展的巴科斯範式 Augmented BNF 
 
  RFC2234 定義了擴展的巴科斯範式(ABNF)。近年來在Internet的定義中ABNF被廣泛使用。ABNF做了更多的改進,比如說,在ABNF中,尖括號不再需要。 

 
 
什麼是EBNF?
基本 (EBNF) 定義有關 EBNF 協定的詳細情況,可以參看 Computing Dictionary.
這裏是要點一覽:
  "..." : 
 
http://estone.nease.net/sgf/sgf4.html#2 裏會給出一個EBNF在棋牌類的應用.
 
--------------------------------------------------------------------------------------------
 
<BNF>::=     <非終結符>::=<或項列表>  
  <或項列表>::=     <項>     |     <或項列表>|<項>  
  <項>::=     <非終結符>     |     <終結符>   |   <項><非終結符>   |   <項><終結符>  
  <非終結符>::=       <非終結符名>  
   
  (   但願能有人看得懂:-)   )  
   
  BNF就是巴科特·瑙爾式的縮寫,  
  在計算機的史前時代(1950s),曾有一位大師,他奠定了現代計算機的基礎  
  在他老人家的諸多成就之中,包括了對形式語言的研究,和發明了高級語言:  
  FORTRAN。  
  爲了紀念他老人家,我們把他提出的一套描述語言的方法叫做BNF  
   
  其實BNF很簡單::=表示定義   |表示或   尖括號(<>)括起來的是非終結符  
  所謂非終結符就是語言中某些抽象的概念,終結符就是可以直接出現在  
  語言中的符號  
   
  比如:C語言的聲明語句可以用BNF這樣描述:  
  <聲明語句>   ::=   <類型><標識符>;   |   <類型><標識符>[<數字>];  
  這一句中<聲明語句>這個非終結符被定義成了兩種形式(上面用|隔開的兩部分)  
  在這裏引入了三個終結符:   分號;     左右方括號[   ]  
   
  <類型>   ::=   <簡單類型>   |   <指針類型>   |   <自定義類型>  
  <指針類型>   ::=   <簡單類型>   *   |   <自定義類型>   *  
  <簡單類型>   ::=   int|char|double|float|long|short|void  
  <自定義類型>   ::=   enum<標識符>|struct<標識符>|union<標識符>|<標識符>  
  到這裏就基本上把<類型>定義清楚了  
   
  <數字>   ::=   0X<十六進制數字串>   |   0<八進制數字串>   |   <十進制數字串>  
  <十六進制數字串>   ::=   <十六進制數字>   |   <十六進制數字串><十六進制數字>    
  <八進制數字串>   ::=   <八進制數字>   |   <八進制數字串><八進制數字>    
  <十進制數字串>   ::=   <十進制數字>   |   <十進制數字串><十進制數字>    
  <十六進制數字>   ::=   <十進制數字>   |   A   |   B   |   C   |   D   |   E   |   F  
  <十進制數字>     ::=   <八進制數字>   |   8   |   9    
  <八進制數字>   ::=   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7  
  到這裏就把<數字>定義清楚了  
   
  <標識符>   ::=   <字母>   |   <標識符>   <字母數字串>  
  <字母數字串>   ::=   <字母>|<十進制數字>|<字母數字串><字母>|<字母數字串><十進制數字>    
  <字母>   ::=   _   |   <大寫字母>   |   <小寫字母>  
  <小寫字母>   ::=   a|b|c|d|e|f|g|h|i|j   ……   (偷個懶)  
  <大寫字母>   ::=   A|B|C|D|E|F|G|H|I|J   ……  
   
  到此爲止整個聲明語句就定義完了(就是說已經沒有非終結符了),雖然看起來很  
  繁,但前面定義的各種非終結符都可以很容易的在別的地方重用比如,函數聲明  
  可以定義成下面的樣子:  
  <函數聲明語句>   ::=   <類型><標識符>(<形參表>);  
  <形參表>   ::=   <類型><標識符>   |   <形參表>,<形參表>  
  只用兩句就描述完了,所以BNF實際上比用自然語言要簡練得多  
  (整個C語言只用一二百句就可以描述清楚)  
  而且相當的精確,不會有自然語言中那種模棱兩可的表達  
  如果你對BNF比較敏感的話,會發現C裏面的標識符不能由數字開頭  
  而且在C裏面下劃線是被當做字母看待的(也就是說能用字母的地方  
  都可以用下劃線)比如:(最好用老一點的編譯器比如PDP11上的cc)  
  #define   ____   main  
  #define   ___   for  
  typedef   char*   _____;  
  int   (*______)(char   *,   ...)   =   printf;   //如果這一句不靈,就用下面這句  
  //#define   ______   printf                         //如果你用的是C++可以試一下下面這個  
  //int   (*______)(const   char   *,   ...)   =   printf;    
   
  ____(_,char*   __[])   //要是你編譯器不吃,可以改成int   ____(int   _,char*__[])  
  {  
      ___(   ;   _   ;   _   --)  
      {  
            ______("%s/n",   __[_]);  
      }  
  }  
   
  另外,還有一種EBNF就沒有正宗的BNF這麼爽了,也有很多人在用,前面的  
  那些遞歸的定義被寫成了{}  
   
  有一段時間PASCAL愛好者們喜歡用一個叫語法圖的東西,畫出來很難看,但  
  功能和BNF差不多,現在好象已經沒多少人用了  
   
  近幾年流行另一種東西:  
  digit   =   one   of  
                  0   1   2   3   4   5   6   7   8   9  
  這裏非終結符digit用斜體表示,one   of是這種方法裏定義的一個量詞(常用斜黑體)  
  我不喜歡這個,因爲我眼神不好,常常分不清那個是斜體,那個是正體  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章