基於EBNF語法的描述

基於JavaCC的語法描述

使用JavaCC從token序列中識別出"語句" “表達式” “函數調用” 等語法單位的方法。

只要爲JavaCC描述“語句” “表達式” “函數調用” 這樣的語法單位各自是由怎樣的token序列構成的,就能夠對該語法進行分析(parse)。

例如:最簡單的賦值表達式可以描述爲“符號” “ “=” ” ”表達式“ 的排列。 換言之, 如果存在”符號“ ” ”=“ “ ”表達式“ 這樣的排列 那就是賦值表達式。這個規則在JavaCC中表示成下面這樣:

assign():
{}
{
  <IDENTIFIER> "=" expr()
}

  assign()對應賦值表達式,<IDENTIFIER>對應token標示符,"="對應"="token。
像<IDENTIFIER>這樣已經在掃描器中定義的token,在描述解析器時可以直接使用。其他的如"="這樣的固定字符串也因爲可以表示token,所以也能在規則中使用。 另外,表達式expr()自身也是多個token構成的,這樣的情況下需要進一步對expr()的規則進行描述,以下是僞描述:

expr():
{}
{
     expr() "+" expr()
   或expr() "-" expr()
   或expr() "*" expr()
   ..
   .
}

終端符與非終端符

JavaCC中將"語句" "函數調用" "表達式" 等非token的語法單位稱爲非終端符,並將非終端符像java的函數調用一樣在後面加上括號寫成stmt()或expr()。
終端符可以歸納爲token。使用在掃描器中定義的名稱,可以寫成<INDENTIFIER>或<LONG>。並且JavaCC中除了掃描器中定義的token以外, "="、"+"、"==" 這樣的字符串字面量也可以作爲終端符來使用

種類含義
終端符 token <IDENTIFIER>、<LONG>、"="、"=="
非終端符 由終端符排列組成的語法單位 stmt()、expr()、assign()

在畫語法時,終端符位於樹的枝幹的末端(終端),非終端符由於是由其他符號的列組成的,所以位於分叉處。

JavaCC的EBNF表示法

JavaCC使用EBNF(Extended Backus-Naur-Form)的表示法來描述語法規則。下表中羅列了JavaCC的解析器生成所使用的EBNF表示法。

種類例子
終端符 <IDENTIFIER>或","
非終端符 name()
連接 <UNISGNED><LONG>
重複0次或多次 (","expr())*
重複1次或多次 (stmt())+
選擇 <CHAR>丨<SHORT>丨<INT>丨<LONG>
可以省略 [<ELSE>stmt()]

1. 連接

連接是指特定符號相連續的模式。例如C語言continue語句是保留字continue和分號的排列。JavaCC中將該規則寫成如下形式:

<CONTINUE> ";"

<CONTINUE>是表示保留字continue的終端符,“:”是表示字符自身的終端符。

2. 重複0次或多次

下面的寫法表示0個或多個語句排列:

(stmt())*

下面的例子,函數的參數是由逗號分隔的表達式排列組成的,即expr之後排列着0個或多個逗號和expr的組合:

expr() ("," expt())*

3. 重複1次或多次

(stmt())+

上面的代碼描述了非終端符stmt()重複1次或多次。

4. 選擇

選擇即爲從多個選項中選擇1個的規則。例如cflat的類型由void、char、unsigned、char等:

<VOID> | <CHAR> | <UNSIGNED> | <CHAR> | ...

5. 可以省略

定義變量時可以設置初始值也可以不設置,這種在JavaCC中可以寫成:

storage() typeref() name() ["=" expr()] ";"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章