FIDL 文法

修改過的 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 )+ ;

憑證

進行 Lex 時,系統會忽略空白字元和註解,因此不會在下列文法中呈現。

註解開頭可以是兩條斜線 ('//') 或三個斜線 ('///'),也可能在 [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" ; [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 ;

ordinal-layout =  "{" , ( ordinal-layout-member , ";" )* , "}" ; [NOTE 5]

ordinal-layout-member = ( attribute-list ) , ordinal , ":" , member-field ; [NOTE 6]

protocol-declaration = ( attribute-list ) , "protocol" , IDENTIFIER ,
                       "{" , ( protocol-member , ";" )*  , "}" ;

protocol-member = protocol-method | protocol-event | protocol-compose ;

protocol-method = ( attribute-list ) , IDENTIFIER , parameter-list,
                  ( "->" , parameter-list , ( "error" type-constructor ) ) ; [NOTE 7]

protocol-event = ( attribute-list ) , "->" , IDENTIFIER , parameter-list ;

parameter-list = "(" , ( type-constructor ) , ")" ; [NOTE 8]

protocol-compose = "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 9]

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 ;

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 | literal ;

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 )*,但編譯器會限制此做法,如下所示:

  • 同一個宣告中不能出現兩次修飾符。
  • 無法搭配使用 flexiblestrict 修飾符。
  • 只有在 layout-kindbitsenumunion 時,才能使用 flexiblestrict 修飾符。
  • resource 修飾符只能當 layout-kindstructtableunion 時。

附註 3

文法允許所有宣告使用 ( layout-subtype ),但編譯器會限制只有在 layout-kindbitsenum 時才能使用。

此外,layout-subtype 允許文法中更多的 type-constructor,但編譯器會將此限制為帶正負號或無正負號整數類型 (請參閱基元),以瞭解列舉和位元的無正負號整數類型。

注意事項 4

value-layout-member 允許文法中偏離的 constant,但編譯器會限制 constant 可能採用的值:

  • enum 內容中符合指定 subtype 的任何值。
  • 任何符合指定 subtype 且為 bits 的次方的值。

注意事項 5

ordinal-layout 文法可允許任意數量的成員,但嚴格聯集必須至少包含一個成員。

注意 6

此外,雖然序數可以是任何數值常值,但編譯器會強制對任何聯集或資料表指定的序數,涵蓋從 1 開始的連續範圍。

注意 7

protocol-method 錯誤處理器允許文法中更多的 type-constructor,但編譯器會將此限制為 int32uint32 或列舉。

注意 8

parameter-list 允許文法中更加自由的 type-constructor,但編譯器僅支援結構、資料表或聯集的版面配置。

附註 9

service-member 可讓文法中偏離的 type-constructor,但編譯器會將此限制在通訊協定中。