基於EBNF語法的描述

基於JavaCC的語法描述

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

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

例如:最簡單的賦值表達式能夠描述爲「符號」 「 「=」 」 」表達式「 的排列。 換言之, 若是存在」符號「 」 」=「 「 」表達式「 這樣的排列 那就是賦值表達式。這個規則在JavaCC中表示成下面這樣:spa

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

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

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

終端符與非終端符

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

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

在畫語法時,終端符位於樹的枝幹的末端(終端),非終端符因爲是由其餘符號的列組成的,因此位於分叉處。token

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中將該規則寫成以下形式:string

<CONTINUE> ";" 

<CONTINUE>是表示保留字continue的終端符,「:」是表示字符自身的終端符。it

2. 重複0次或屢次

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

(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()] ";"
相關文章
相關標籤/搜索