修改后的 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" ; [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 )*
,但编译器对此进行了如下限制:
- 一个修饰符不能在同一个声明中出现两次。
flexible
和strict
修饰符不能一起使用。- 仅当
layout-kind
为bits
、enum
或union
时,才能使用flexible
和strict
修饰符。 resource
修饰符只有在layout-kind
为struct
、table
或union
时才可用。
注 3
语法允许所有声明使用 ( layout-subtype )
,但编译器限制,仅当 layout-kind
为 bits
或 enum
时才允许这样操作。
此外,layout-subtype
允许在语法中使用更自由的 type-constructor
,但编译器对枚举和位的无符号整数类型限制为有符号或无符号整数类型(请参阅基元)。
注 4
value-layout-member
允许在语法中使用更为自由的 constant
,但编译器会限制 constant
可采用的值:
- 在
enum
的上下文中,满足指定subtype
的任何值。 bits
上下文中,满足指定subtype
的 2 的幂的任何值。
注 5
ordinal-layout
语法允许任意数量的成员,但严格联合明确必须至少有一个成员。
注 6
此外,虽然序数可以是任何数字字面量,但编译器会强制要求任何联合或表的指定序数涵盖从 1 开始的连续范围。
注 7
protocol-method
错误节允许在语法中使用更自由的 type-constructor
,但编译器会将其限制为 int32
、uint32
或其枚举。
注 8
parameter-list
允许在语法中使用更为自由的 type-constructor
,但编译器仅支持结构体、表或联合的布局。
注 9
service-member
允许在语法中使用更为自由的 type-constructor
,但编译器将限制仅限于协议。