修改後的 BNF 規則
這是 FIDL 來源檔案的文法。文法以修改過的 BNF 格式表示。
非終端符號會比對以半形逗號分隔的其他符號序列。
nonterminal = list , of , symbols ;
部分符號是終端,不是全大寫就是以雙引號括住。
another-nonterminal = THESE , ARE , TERMINALS , AND , SO , IS , "this" ;
以直線符號表示交替。
choice = this | that | the-other ;
選項 (零或一) 會以半形括號表示。
optional = ( maybe , these ) , but , definitely , these ;
重複 (零次以上) 會以括號和星號表示。
zero-or-more = ( list-part )* ;
重複 (一或多個) 會以括號和加號表示。
one-or-more = ( list-part )+ ;
憑證
在詞法分析期間,系統會忽略空白字元和註解,因此下列文法中不會出現這些內容。
註解可以從兩條斜線 (「//」) 或三條斜線 (「///」) 開始,也可以包含在 [Doc]
屬性中。三斜線變體和 [Doc]
屬性的行為相同,都會將註解傳播至產生的目標。
fidldoc 工具會處理傳播至 JSON 型中介表示法 (IR) 的註解,為 FIDL 檔案產生參考說明文件頁面。
如要進一步瞭解註解,請參閱 FIDL 樣式指南。
文法
file
是起始符號。
file = library-header , ( using-list ) , declaration-list ;
library-header = ( attribute-list ) , "library" , compound-identifier , ";" ;
using-list = ( using , ";" )* ;
using = "using" , compound-identifier , ( "as" , IDENTIFIER ) ;
compound-identifier = IDENTIFIER ( "." , IDENTIFIER )* ;
declaration-list = ( declaration , ";" )* ;
declaration = const-declaration | layout-declaration | protocol-declaration
| type-alias-declaration | resource-declaration | service-declaration ;
const-declaration = ( attribute-list ) , "const" , IDENTIFIER ,
type-constructor , "=" , constant ;
layout-declaration = ( attribute-list ) , "type" , IDENTIFIER , "=" ,
inline-layout ; [NOTE 1]
inline-layout = ( attribute-list ) , ( declaration-modifiers )* , layout-kind ,
( layout-subtype ) , layout-body ;
declaration-modifiers = "flexible" | "strict" | "resource",
( modifier-availability ) ; [NOTE 2]
layout-subtype = ":" , type-constructor ; [NOTE 3]
layout-kind = "struct" | "bits" | "enum" | "union" | "table" ;
layout-body = value-layout | struct-layout | ordinal-layout ;
value-layout = "{" , ( value-layout-member , ";" )+ , "}" ;
value-layout-member = ( attribute-list ) , IDENTIFIER , "=" ,
constant ; [NOTE 4]
struct-layout = "{" , ( struct-layout-member , ";" )* , "}" ;
struct-layout-member = ( attribute-list ) , member-field , ( '=' , constant ) ; [NOTE 10]
ordinal-layout = "{" , ( ordinal-layout-member , ";" )* , "}" ; [NOTE 5]
ordinal-layout-member = ( attribute-list ) , ordinal , ":" ,
member-field ;
protocol-declaration = ( attribute-list ) , ( protocol-modifiers )* ,
"protocol" , IDENTIFIER , "{" , ( protocol-member , ";" )* , "}" ;
protocol-modifiers = "closed" | "ajar" | "closed" , ( modifier-availability ) ;
protocol-member = protocol-method | protocol-event | protocol-compose ;
protocol-method = ( attribute-list ) , ( method-modifiers )* , IDENTIFIER ,
parameter-list , ( "->" , parameter-list ,
( "error" type-constructor ) ) ; [NOTE 6]
protocol-event = ( attribute-list ) , ( method-modifiers )* , "->" ,
IDENTIFIER , parameter-list ;
method-modifiers = "strict" | "flexible" , ( modifier-availability ) ;
parameter-list = "(" , ( type-constructor ) , ")" ; [NOTE 7]
protocol-compose = ( attribute-list ) , "compose" , compound-identifier ;
type-alias-declaration = ( attribute-list ) , "alias" , IDENTIFIER , "=" ,
type-constructor ;
resource-declaration = ( attribute-list ) , "resource_definition" , IDENTIFIER ,
":" , "uint32" , "{" , resource-properties , "}" ;
resource-properties = "properties" , "{" , ( member-field , ";" )* , "}" , ";"
service-declaration = ( attribute-list ) , "service" , IDENTIFIER , "{" ,
( service-member , ";" )* , "}" ;
service-member = ( attribute-list ) , member-field ; [NOTE 8]
member-field = IDENTIFIER , type-constructor ;
attribute-list = ( attribute )* ;
attribute = "@" , IDENTIFIER , ( "(" , constant | attribute-args , ")" ) ;
attribute-args = attribute-arg | attribute-arg , "," attribute-args ;
attribute-arg = IDENTIFIER , "=" , constant ;
modifier-availability = "(" , attribute-args , ")" ; [NOTE 9]
type-constructor = layout , ( "<" , layout-parameters , ">" ) ,
( ":" type-constraints ) ;
layout = compound-identifier | inline-layout ;
layout-parameters = layout-parameter | layout-parameter , "," ,
layout-parameters ;
layout-parameter = type-constructor | constant ;
type-constraints = type-constraint | "<" type-constraint-list ">" ;
type-constraint-list = type-constraint | type-constraint , "," ,
type-constraint-list ;
type-constraint = constant ;
constant = compound-identifier , ( '|' , constant ) | literal , ( '|' , constant );
ordinal = NUMERIC-LITERAL ;
literal = STRING-LITERAL | NUMERIC-LITERAL | "true" | "false" ;
STRING-LITERAL
STRING-LITERAL
的文法如下:
STRING-LITERAL = "\"" ( unicode-value )* "\"" ;
unicode-value = literal-char | escaped-basic | escaped-unicode ;
literal-char = any unicode character except CR, LF, "\" or "\"" ;
escaped-basic = "\" ( "\" | "\"" | "n" | "r" | "t" ) ;
escaped-unicode = "\u{" ( hex-digit ){1,6} "}" ;
附註 1
匿名版面配置簡介的屬性可放在下列任一位置:
type
關鍵字之前,或- 做為
inline-layout
的一部分。
編譯器不允許在單一版面配置定義中,將屬性放在這兩個位置。
附註 2
文法允許在所有宣告中使用 ( declaration-modifiers )*
,但編譯器會限制這項操作,如下所示:
- 同一個宣告不得出現兩次修飾符。
flexible
和strict
修飾符不得同時使用。- 只有在
layout-kind
為bits
、enum
或union
時,才能使用flexible
和strict
修飾符。 - 只有在
layout-kind
為struct
、table
或union
時,才能使用resource
修飾符。
NOTE 3
文法允許所有宣告使用 ( layout-subtype )
,但編譯器會限制只能在 layout-kind
為 bits
或 enum
時使用。
此外,layout-subtype
允許文法中較寬鬆的 type-constructor
,但編譯器會將此限制為列舉的帶正負號或不帶正負號的整數型別,以及位元的無符號整數型別 (請參閱基本型別)。
NOTE 4
value-layout-member
允許文法中出現較寬鬆的 constant
,但編譯器會限制 constant
可採用的值:
- 符合指定
subtype
的任何值 (在enum
的環境中)。 - 符合指定
subtype
且為 2 的乘方的任何值 (以bits
為背景)。
NOTE 5
ordinal-layout
文法允許任意數量的成員,但嚴格聯集必須至少有一個成員。
NOTE 6
protocol-method
錯誤節可讓文法更寬鬆,但編譯器會將此限制為 int32
、uint32
或其中一個列舉。type-constructor
NOTE 7
parameter-list
允許文法中出現較寬鬆的 type-constructor
,但編譯器只支援結構體、表格或聯集等版面配置。
NOTE 8
service-member
允許語法中較寬鬆的 type-constructor
,但編譯器會將此限制為 client_end
型別。
NOTE 9
modifier-availability
可在文法中提供較寬鬆的 attribute-args
,但編譯器會將此限制為 added
和 removed
引數。
NOTE 10
目前支援結構體欄位的預設值,但已淘汰。移除所有 struct 預設值的使用情形後,系統就會停止支援 (請參閱這個問題)。