FIDL grammar

Modified BNF rules

This is the grammar for FIDL source files. The grammar is expressed in a modified BNF format.

A nonterminal symbol matches a sequence of other symbols, delimited by commas.

  1. nonterminal = list , of , symbols ;

Some symbols are terminals, which are either in all caps or are in double quotes.

  1. another-nonterminal = THESE , ARE , TERMINALS , AND , SO , IS , "this" ;

Alternation is expressed with a pipe.

  1. choice = this | that | the-other ;

An option (zero or one) is expressed with parentheses.

  1. optional = ( maybe , these ) , but , definitely , these ;

Repetition (zero or more) is expressed with parentheses and a star.

  1. zero-or-more = ( list-part )* ;

Repetition (one or more) is expressed with parentheses and a plus.

  1. one-or-more = ( list-part )+ ;

Tokens

Whitespace and comments are ignored during lexing, and thus not present in the following grammar.

Comments can start with two slashes (‘//‘) or three slashes (‘///‘), or they can be embodied within a [Doc] attribute. The three-slash variant and the [Doc] attribute behave the same way, propagating the comments to the generated target.

The fidldoc tool processes comments propagated into the JSON-based Intermediate Representation (IR) to generate reference documentation pages for FIDL files.

See the FIDL style guide for more details on comments.

Grammar {#grammar}

file is the starting symbol.

  1. file = library-header , ( using-list ) , declaration-list ;
  2. library-header = ( attribute-list ) , "library" , compound-identifier , ";" ;
  3. using-list = ( using , ";" )* ;
  4. using = "using" , compound-identifier , ( "as" , IDENTIFIER ) ;
  5. declaration-list = ( declaration , ";" )* ;
  6. compound-identifier = IDENTIFIER ( "." , IDENTIFIER )* ;
  7. declaration = bits-declaration | const-declaration | enum-declaration | protocol-declaration
  8. | struct-declaration | table-declaration | union-declaration
  9. | type-alias-declaration | resource-declaration | service-declaration ;
  10. declaration-modifiers = "flexible" | "strict" | "resource"; [NOTE 1]
  11. const-declaration = ( attribute-list ) , "const" , type-constructor , IDENTIFIER , "=" , constant ;
  12. enum-declaration = ( attribute-list ) , ( declaration-modifiers )* , "enum" , IDENTIFIER ,
  13. ( ":" , type-constructor ) , "{" , ( bits-or-enum-member , ";" )+ ,
  14. "}" ; [NOTE 2]
  15. bits-declaration = ( attribute-list ) , ( declaration-modifiers )* , "bits" , IDENTIFIER ,
  16. ( ":" , type-constructor ) , "{" , ( bits-or-enum-member , ";" )+ ,
  17. "}" ; [NOTE 3]
  18. bits-or-enum-member = ( attribute-list ) , IDENTIFIER , "=" , bits-or-enum-member-value ;
  19. bits-or-enum-member-value = IDENTIFIER | literal ; [NOTE 4]
  20. protocol-declaration = ( attribute-list ) , "protocol" , IDENTIFIER ,
  21. "{" , ( protocol-member , ";" )* , "}" ;
  22. protocol-member = protocol-method | protocol-event | protocol-compose ;
  23. protocol-method = ( attribute-list ) , IDENTIFIER , parameter-list,
  24. ( "->" , parameter-list , ( "error" type-constructor ) ) ; [NOTE 5]
  25. protocol-event = ( attribute-list ) , "->" , IDENTIFIER , parameter-list ;
  26. parameter-list = "(" , ( parameter ( "," , parameter )+ ) , ")" ;
  27. parameter = ( attribute-list ) , type-constructor , IDENTIFIER ;
  28. protocol-compose = "compose" , compound-identifier ;
  29. struct-declaration = ( attribute-list ) , "struct" , IDENTIFIER , "{" , ( member-field , ";" )* ,
  30. "}" ;
  31. union-declaration = ( attribute-list ) , ( declaration-modifiers )* , "union" , IDENTIFIER , "{" ,
  32. ( ordinal-member-field , ";" )+ , "}" ;
  33. table-declaration = ( attribute-list ) , ( declaration-modifiers )* , "table" , IDENTIFIER , "{" ,
  34. ( ordinal-member-field , ";" )* , "}" ;
  35. member-field = ( attribute-list ) , type-constructor , IDENTIFIER , ( "=" , constant ) ;
  36. ordinal-member-field = ( attribute-list ) , ordinal , ":" , ordinal-member-field-body ; [NOTE 6]
  37. ordinal-member-field-body = member-field | "reserved";
  38. type-alias-declaration = ( attribute-list ) , "alias" , IDENTIFIER , "=" , type-constructor ;
  39. resource-declaration = ( attribute-list ) , "resource_definition" , IDENTIFIER , ":",
  40. "uint32" , "{" , resource-properties , "}" ;
  41. resource-properties = "properties" , "{" , ( type-constructor , IDENTIFIER , ";" )* , "}" , ";"
  42. service-declaration = ( attribute-list ) , "service" , IDENTIFIER , "{" ,
  43. ( service-member , ";" )* , "}" ;
  44. service-member = ( attribute-list ) , type-constructor , IDENTIFIER ; [NOTE 7]
  45. attribute-list = "[" , attributes , "]" ;
  46. attributes = attribute | attribute , "," , attributes ;
  47. attribute = IDENTIFIER , ( "=" , STRING-LITERAL ) ;
  48. type-constructor = compound-identifier ( "<" type-constructor ">" ) , ( type-constraint ) , ( "?" )
  49. | handle-type ;
  50. handle-type = "handle" , ( "<" , handle-subtype , ">" ) , ( "?" ) ;
  51. handle-subtype = "bti" | "channel" | "clock" | "debuglog" | "event" | "eventpair" | "exception"
  52. | "fifo" | "guest" | "interrupt" | "iommu" | "job" | "pager" | "pcidevice"
  53. | "pmt" | "port" | "process" | "profile" | "resource" | "socket" | "suspendtoken"
  54. | "thread" | "timer" | "vcpu" | "vmar" | "vmo" ;
  55. type-constraint = ":" , constant ;
  56. constant = compound-identifier | literal ;
  57. ordinal = NUMERIC-LITERAL ;
  58. literal = STRING-LITERAL | NUMERIC-LITERAL | "true" | "false" ;

NOTE 1

The grammar allows ( declaration-modifiers )* on all declarations, but the compiler limits this as follows:

  • A modifier cannot occur twice on the same declaration.
  • The flexible and strict modifiers cannot be used together.
  • The flexible and strict modifiers can only be used on bits, enum, and union.
  • The resource modifier can only be used on struct, table, and union.

NOTE 2

The enum-declaration allows the more liberal type-constructor in the grammar, but the compiler limits this to signed or unsigned integer types, see primitives.

NOTE 3

The bits-declaration allows the more liberal type-constructor in the grammar, but the compiler limits this to unsigned integer types, see primitives.

NOTE 4

The bits-or-enum-member-value allows the more liberal literal in the grammar, but the compiler limits this to:

  • A NUMERIC-LITERAL in the context of an enum;
  • A NUMERIC-LITERAL, which must be a power of two, in the context of a bits.

NOTE 5

The protocol-method error stanza allows the more liberal type-constructor in the grammar, but the compiler limits this to an int32, uint32, or an enum thereof.

NOTE 6

Attributes cannot be placed on a reserved member.

NOTE 7

The service-member allows the more liberal type-constructor in the grammar, but the compiler limits this to protocols.