blob: a406c8e0bffbfda293ec0c4ed793c8fa19795959 [file] [log] [blame]
Mark Slee31985722006-05-24 21:45:31 +00001%{
2
3/**
4 * Thrift parser.
5 *
6 * This parser is used on a thrift definition file.
7 *
8 * @author Mark Slee <mcslee@facebook.com>
9 */
10
11#include <stdio.h>
12#include "main.h"
13#include "globals.h"
14#include "parse/t_program.h"
15
16int y_field_val = 0;
17
18%}
19
20%union {
21 char* id;
22 int iconst;
23 t_type* ttype;
24 t_typedef* ttypedef;
25 t_enum* tenum;
26 t_struct* tstruct;
27 t_service* tservice;
28 t_function* tfunction;
29 t_field* tfield;
Mark Slee31985722006-05-24 21:45:31 +000030 t_constant* tconstant;
31}
32
33/** Strings and constants */
34%token<id> tok_identifier
35%token<iconst> tok_int_constant
36
37/** Base datatypes */
38%token tok_byte
39%token tok_string
40%token tok_i32
41%token tok_u32
42%token tok_i64
43%token tok_u64
44
45/** Complex Types */
46%token tok_map
47%token tok_list
48%token tok_set
49
50/** Function types */
51%token tok_void
52
53/** Modifiers */
54%token tok_async
55
56/** Thrift actions */
57%token tok_typedef
58%token tok_struct
59%token tok_function
60%token tok_service
61%token tok_enum
62
63/** Types */
64%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +000065%type<ttype> ContainerType
66%type<ttype> MapType
67%type<ttype> SetType
68%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +000069
70%type<ttypedef> Typedef
71%type<ttype> DefinitionType
72
73%type<tfield> Field
74%type<ttype> FieldType
Mark Sleee8540632006-05-30 09:24:40 +000075%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +000076
77%type<tenum> Enum
78%type<tenum> EnumDefList
79%type<tconstant> EnumDef
80
81%type<tstruct> Struct
82
83%type<tservice> Service
84
85%type<tfunction> Function
86%type<id> FunctionModifiers
87%type<ttype> FunctionType
88%type<tservice> FunctionList
89
90%%
91
92/** Thrift Grammar */
93
94Program:
95 DefinitionList
96 {
97 pdebug("Program -> DefinitionList");
98 }
99
100DefinitionList:
101 DefinitionList Definition
102 {
103 pdebug("DefinitionList -> DefinitionList Definition");
104 }
105|
106 {
107 pdebug("DefinitionList -> ");
108 }
109
110Definition:
111 Typedef
112 {
113 pdebug("Definition -> Typedef");
114 g_program->add_typedef($1);
115 }
116| Enum
117 {
118 pdebug("Definition -> Enum");
119 g_program->add_enum($1);
120 }
121| Struct
122 {
123 pdebug("Definition -> Struct");
124 g_program->add_struct($1);
125 }
126| Service
127 {
128 pdebug("Definition -> Service");
129 g_program->add_service($1);
130 }
131
132Typedef:
133 tok_typedef DefinitionType tok_identifier
134 {
135 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000136 t_typedef *td = new t_typedef($2, $3);
137 $$ = td;
138 }
139
140Enum:
141 tok_enum tok_identifier '{' EnumDefList '}'
142 {
143 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
144 $$ = $4;
145 $$->set_name($2);
146 }
147
148EnumDefList:
149 EnumDefList ',' EnumDef
150 {
151 pdebug("EnumDefList -> EnumDefList EnumDef");
152 $$ = $1;
153 $$->append($3);
154 }
155| EnumDef
156 {
157 pdebug("EnumDefList -> EnumDef");
158 $$ = new t_enum;
159 $$->append($1);
160 }
161|
162 {
163 pdebug("EnumDefList -> ");
164 $$ = new t_enum;
165 }
166
167EnumDef:
168 tok_identifier '=' tok_int_constant
169 {
Mark Sleee8540632006-05-30 09:24:40 +0000170 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000171 if ($3 < 0) {
172 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
173 }
Mark Slee31985722006-05-24 21:45:31 +0000174 $$ = new t_constant($1, $3);
175 }
176|
177 tok_identifier
178 {
179 pdebug("EnumDef => tok_identifier");
180 $$ = new t_constant($1);
181 }
182
183Struct:
184 tok_struct tok_identifier '{' FieldList '}'
185 {
186 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000187 $4->set_name($2);
188 $$ = $4;
Mark Slee31985722006-05-24 21:45:31 +0000189 y_field_val = 0;
190 }
191
192Service:
193 tok_service tok_identifier '{' FunctionList '}'
194 {
195 pdebug("Service -> tok_service tok_identifier { FunctionList }");
196 $$ = $4;
197 $$->set_name($2);
198 }
199
200FunctionList:
201 FunctionList Function
202 {
203 pdebug("FunctionList -> FunctionList Function");
204 $$ = $1;
205 $1->add_function($2);
206 }
207|
208 {
209 pdebug("FunctionList -> ");
210 $$ = new t_service;
211 }
212
213Function:
214 FunctionType FunctionModifiers tok_identifier '(' FieldList ')'
215 {
Mark Sleee8540632006-05-30 09:24:40 +0000216 $$ = new t_function($1, $3, $5);
Mark Slee31985722006-05-24 21:45:31 +0000217 y_field_val = 0;
218 }
219
220FunctionModifiers:
221 {
222 /** TODO(mcslee): implement async modifier, etc. */
223 $$ = 0;
224 }
225
226FieldList:
227 FieldList ',' Field
228 {
229 pdebug("FieldList -> FieldList , Field");
230 $$ = $1;
231 $$->append($3);
232 }
233| Field
234 {
235 pdebug("FieldList -> Field");
Mark Sleee8540632006-05-30 09:24:40 +0000236 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000237 $$->append($1);
238 }
239|
240 {
241 pdebug("FieldList -> ");
Mark Sleee8540632006-05-30 09:24:40 +0000242 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000243 }
244
245Field:
246 FieldType tok_identifier '=' tok_int_constant
247 {
Mark Sleee8540632006-05-30 09:24:40 +0000248 pdebug("Field -> FieldType tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000249 if ($4 < 0) {
250 yyerror("Negative value (%d) not allowed as a field key.", $4);
Mark Sleee8540632006-05-30 09:24:40 +0000251 exit(1);
Mark Slee31985722006-05-24 21:45:31 +0000252 }
253 $$ = new t_field($1, $2, (uint32_t)$4);
254 y_field_val = $4+1;
255 }
256| FieldType tok_identifier
257 {
Mark Sleee8540632006-05-30 09:24:40 +0000258 pdebug("Field -> FieldType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000259 printf("WARNING (%d): No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
260 $$ = new t_field($1, $2, y_field_val++);
261 }
262
263DefinitionType:
264 BaseType
265 {
266 pdebug("DefinitionType -> BaseType");
267 $$ = $1;
268 }
Mark Sleee8540632006-05-30 09:24:40 +0000269| ContainerType
270 {
271 pdebug("DefinitionType -> ContainerType");
272 $$ = $1;
273 }
Mark Slee31985722006-05-24 21:45:31 +0000274
275FunctionType:
276 FieldType
277 {
Mark Sleee8540632006-05-30 09:24:40 +0000278 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000279 $$ = $1;
280 }
281| tok_void
282 {
Mark Sleee8540632006-05-30 09:24:40 +0000283 pdebug("FunctionType -> tok_void");
Mark Slee31985722006-05-24 21:45:31 +0000284 $$ = g_program->get_void_type();
285 }
286
287FieldType:
288 tok_identifier
289 {
Mark Sleee8540632006-05-30 09:24:40 +0000290 pdebug("FieldType -> tok_identifier");
291 $$ = g_program->get_custom_type($1);
292 if ($$ == NULL) {
293 yyerror("Type \"%s\" has not been defined.", $1);
294 exit(1);
295 }
Mark Slee31985722006-05-24 21:45:31 +0000296 }
297| BaseType
298 {
Mark Sleee8540632006-05-30 09:24:40 +0000299 pdebug("FieldType -> BaseType");
300 $$ = $1;
301 }
302| ContainerType
303 {
304 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000305 $$ = $1;
306 }
307
308BaseType:
309 tok_string
310 {
311 pdebug("BaseType -> tok_string");
312 $$ = g_program->get_string_type();
313 }
314| tok_byte
315 {
316 pdebug("BaseType -> tok_byte");
317 $$ = g_program->get_byte_type();
318 }
319| tok_i32
320 {
321 pdebug("BaseType -> tok_i32");
322 $$ = g_program->get_i32_type();
323 }
324| tok_u32
325 {
326 pdebug("BaseType -> tok_u32");
327 $$ = g_program->get_u32_type();
328 }
329| tok_i64
330 {
331 pdebug("BaseType -> tok_i64");
332 $$ = g_program->get_i64_type();
333 }
334| tok_u64
335 {
336 pdebug("BaseType -> tok_u64");
337 $$ = g_program->get_u64_type();
338 }
339
Mark Sleee8540632006-05-30 09:24:40 +0000340ContainerType:
341 MapType
342 {
343 pdebug("ContainerType -> MapType");
344 $$ = $1;
345 }
346| SetType
347 {
348 pdebug("ContainerType -> SetType");
349 $$ = $1;
350 }
351| ListType
352 {
353 pdebug("ContainerType -> ListType");
354 $$ = $1;
355 }
356
357MapType:
358 tok_map '<' FieldType ',' FieldType '>'
359 {
360 pdebug("MapType -> tok_map <FieldType, FieldType>");
361 $$ = new t_map($3, $5);
362 }
363
364SetType:
365 tok_set '<' FieldType '>'
366 {
367 pdebug("SetType -> tok_set<FieldType>");
368 $$ = new t_set($3);
369 }
370
371ListType:
372 tok_list '<' FieldType '>'
373 {
374 pdebug("ListType -> tok_list<FieldType>");
375 $$ = new t_list($3);
376 }
377
Mark Slee31985722006-05-24 21:45:31 +0000378%%