1# fidl grammar
2
3## Modified BNF rules
4
5This is the grammar for fidl source files. The grammar is expressed in
6a modified BNF format.
7
8A nonterminal symbol matches a sequence of other symbols, delimited by
9commas.
10```
11nonterminal = list , of , symbols ;
12```
13
14Some symbols are terminals, which are either in all caps or are in
15double quotes.
16```
17another-nonterminal = THESE , ARE , TERMINALS , AND , SO , IS , "this" ;
18```
19
20Alternation is expressed with a pipe.
21```
22choice = this | that | the-other ;
23```
24
25An option (zero or one) is expressed with parentheses.
26```
27optional = ( maybe , these ) , but , definitely , these ;
28```
29
30Repetition (zero or more) is expressed with parentheses and a star.
31```
32zero-or-more = ( list-part )* ;
33```
34
35Repetition (one or more) is expressed with parentheses and a plus.
36```
37one-or-more = ( list-part )+ ;
38
39```
40
41## Tokens
42
43Whitespace and comments are ignored during lexing, and thus not
44present in the following grammar. Comments are C++-style `//` until
45the end of the line.
46
47TODO(US-238): Eventually comments will be read as part of a
48documentation generation system.
49
50## The grammar
51
52`file` is the starting symbol.
53
54```
55file = library-header , ( using-list ) , declaration-list ;
56
57library-header = ( attribute-list ) , "library" , compound-identifier , ";" ;
58
59using-list = ( using | using-declaration )* ;
60
61using-declaration = "using" , IDENTIFIER ,  "=" , primitive-type , ";" ;
62
63declaration-list = ( declaration , ";" )* ;
64
65compound-identifier = IDENTIFIER ( "." , IDENTIFIER )* ;
66
67using = "using" , compound-identifier , ( "as" , IDENTIFIER ) , ";" ;
68
69declaration = const-declaration | enum-declaration | interface-declaration |
70              struct-declaration | union-declaration ;
71
72const-declaration = ( attribute-list ) , "const" , type , IDENTIFIER , "=" , constant ;
73
74enum-declaration = ( attribute-list ) , "enum" , IDENTIFIER , ( ":" , integer-type ) ,
75                   "{" , ( enum-member , ";" )+ , "}" ;
76
77enum-member = IDENTIFIER , ( "=" , enum-member-value ) ;
78
79enum-member-value = IDENTIFIER | NUMERIC-LITERAL ;
80
81interface-declaration = ( attribute-list ) , "interface" , IDENTIFIER ,
82                        ( ":" , super-interface-list ) , "{" , ( interface-method , ";" )*  , "}" ;
83
84super-interface-list = compound-identifier
85                     | compound-identifier , "," , super-interface-list
86
87interface-method = ordinal , ":" , interface-parameters
88
89interface-parameters = IDENTIFIER , parameter-list , ( "->" , parameter-list )
90                     | "->" , IDENTIFIER , parameter-list
91
92parameter-list = "(" , ( parameters ) , ")" ;
93
94parameters = parameter | parameter , "," , parameters ;
95
96parameter = type , IDENTIFIER ;
97
98struct-declaration = ( attribute-list ) , "struct" , IDENTIFIER , "{" , ( struct-field , ";" )* , "}" ;
99
100struct-field = type , IDENTIFIER , ( "=" , constant ) ;
101
102union-declaration = ( attribute-list ) , "union" , IDENTIFIER , "{" , ( union-field , ";" )+ , "}" ;
103
104union-field = type , IDENTIFIER ;
105
106attribute-list = "[" , attributes, "]" ;
107
108attributes = attribute | attribute , "," , attributes ;
109
110attribute = IDENTIFIER , ( "=", STRING-LITERAL ) ;
111
112type = identifier-type | array-type | vector-type | string-type | handle-type
113                       | request-type | primitive-type ;
114
115identifier-type = compound-identifier , ( "?" ) ;
116
117array-type = "array" , "<" , type , ">" , ":" , constant ;
118
119vector-type = "vector" , "<" , type , ">" , ( ":" , constant ) , ( "?" ) ;
120
121string-type = "string" , ( ":" , constant ) , ( "?" ) ;
122
123handle-type = "handle" , ( "<" , handle-subtype , ">" ) , ( "?" ) ;
124
125handle-subtype = "process" | "thread" | "vmo" | "channel" | "event" | "port" |
126                 "interrupt" | "log" | "socket" | "resource" | "eventpair" |
127                 "job" | "vmar" | "fifo" | "guest" | "timer" ;
128
129request-type = "request" , "<" , compound-identifier , ">" , ( "?" ) ;
130
131primitive-type = integer-type | "bool" | "float32" | "float64" ;
132
133integer-type = "int8" | "int16" | "int32" | "int64" |
134               "uint8" | "uint16" | "uint32" | "uint64" ;
135
136constant = compound-identifier | literal ;
137
138ordinal = NUMERIC-LITERAL ;
139
140literal = STRING-LITERAL | NUMERIC-LITERAL | TRUE | FALSE ;
141```
142