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 )+ ;

令牌

在词法分析期间,系统会忽略空格和注释,因此以下语法中不会出现这些内容。

注释可以以两个斜杠 ('//') 或三个斜杠 ('///') 开头,也可以包含在 [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 )*,但编译器会按如下方式限制此功能:

  • 一个修饰符不能在同一声明中出现两次。
  • flexiblestrict 修饰符不能一起使用。
  • 只有当 layout-kindbitsenumunion 时,才能使用 flexiblestrict 修饰符。
  • 只有当 layout-kindstructtableunion 时,才能使用 resource 修饰符。

NOTE 3

语法允许在所有声明中使用 ( layout-subtype ),但编译器将此限制为仅当 layout-kindbitsenum 时才允许使用。

此外,layout-subtype 允许在语法中使用更宽松的 type-constructor,但编译器将此限制为枚举的带符号或无符号整数类型(请参阅基本类型)和位的无符号整数类型。

NOTE 4

value-layout-member 允许语法中出现更宽松的 constant,但编译器会限制 constant 可取的值:

  • enum 的上下文中,符合指定 subtype 的任何值。
  • 任何符合指定 subtype 且是 bits 上下文中的 2 的幂的值。

NOTE 5

ordinal-layout 语法允许任意数量的成员,但严格的并集必须至少有一个成员。

注意 6

protocol-method 错误 stanza 允许语法中存在更宽松的 type-constructor,但编译器将其限制为 int32uint32 或相应枚举。

NOTE 7

parameter-list 允许语法中使用更宽松的 type-constructor,但编译器仅支持结构、表或联合布局。

NOTE 8

service-member 允许语法中使用更宽松的 type-constructor,但编译器将其限制为 client_end 类型。

NOTE 9

modifier-availability 允许语法中出现更宽松的 attribute-args,但编译器将此限制为 addedremoved 实参。

NOTE 10

目前支持结构体字段的默认值,但已弃用。 当所有结构默认值用法都被移除时,将不再支持(请参阅此问题)。