blob: 069d6c8b52b219a1d7f075402b07504526815ef2 [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
Mark Slee9cb7c612006-09-01 22:17:45 +000016int y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +000017
18%}
19
20%union {
21 char* id;
22 int iconst;
Mark Slee52f643d2006-08-09 00:03:43 +000023 bool tbool;
Mark Slee31985722006-05-24 21:45:31 +000024 t_type* ttype;
25 t_typedef* ttypedef;
26 t_enum* tenum;
27 t_struct* tstruct;
28 t_service* tservice;
29 t_function* tfunction;
30 t_field* tfield;
Mark Slee31985722006-05-24 21:45:31 +000031 t_constant* tconstant;
32}
33
34/** Strings and constants */
35%token<id> tok_identifier
36%token<iconst> tok_int_constant
37
Mark Slee9cb7c612006-09-01 22:17:45 +000038/** Namespace */
39%token tok_namespace
40
Mark Slee31985722006-05-24 21:45:31 +000041/** Base datatypes */
42%token tok_byte
43%token tok_string
Mark Slee9cb7c612006-09-01 22:17:45 +000044%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000045%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +000046%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +000047%token tok_double
Mark Slee31985722006-05-24 21:45:31 +000048
49/** Complex Types */
50%token tok_map
51%token tok_list
52%token tok_set
53
54/** Function types */
55%token tok_void
56
57/** Modifiers */
58%token tok_async
59
60/** Thrift actions */
61%token tok_typedef
62%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +000063%token tok_xception
64%token tok_throws
Mark Slee31985722006-05-24 21:45:31 +000065%token tok_service
66%token tok_enum
67
68/** Types */
69%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +000070%type<ttype> ContainerType
71%type<ttype> MapType
72%type<ttype> SetType
73%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +000074
Mark Slee9cb7c612006-09-01 22:17:45 +000075%type<id> Namespace
76
Mark Slee31985722006-05-24 21:45:31 +000077%type<ttypedef> Typedef
78%type<ttype> DefinitionType
79
80%type<tfield> Field
81%type<ttype> FieldType
Mark Sleee8540632006-05-30 09:24:40 +000082%type<tstruct> FieldList
Mark Slee9cb7c612006-09-01 22:17:45 +000083%type<tstruct> ThrowsOptional
Mark Slee31985722006-05-24 21:45:31 +000084
85%type<tenum> Enum
86%type<tenum> EnumDefList
87%type<tconstant> EnumDef
88
89%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +000090%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +000091
92%type<tservice> Service
93
94%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +000095%type<ttype> FunctionType
96%type<tservice> FunctionList
97
Mark Slee52f643d2006-08-09 00:03:43 +000098%type<tbool> AsyncOptional
99
Mark Slee31985722006-05-24 21:45:31 +0000100%%
101
102/** Thrift Grammar */
103
104Program:
105 DefinitionList
106 {
107 pdebug("Program -> DefinitionList");
108 }
109
110DefinitionList:
111 DefinitionList Definition
112 {
113 pdebug("DefinitionList -> DefinitionList Definition");
114 }
115|
116 {
117 pdebug("DefinitionList -> ");
118 }
119
120Definition:
Mark Slee9cb7c612006-09-01 22:17:45 +0000121 Namespace
122 {
123 pdebug("Definition -> Namespace");
124 g_program->set_namespace($1);
125 }
126| Typedef
Mark Slee31985722006-05-24 21:45:31 +0000127 {
128 pdebug("Definition -> Typedef");
129 g_program->add_typedef($1);
130 }
131| Enum
132 {
133 pdebug("Definition -> Enum");
134 g_program->add_enum($1);
135 }
136| Struct
137 {
138 pdebug("Definition -> Struct");
139 g_program->add_struct($1);
140 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000141| Xception
142 {
143 pdebug("Definition -> Xception");
144 g_program->add_xception($1);
145 }
Mark Slee31985722006-05-24 21:45:31 +0000146| Service
147 {
148 pdebug("Definition -> Service");
149 g_program->add_service($1);
Mark Slee9cb7c612006-09-01 22:17:45 +0000150 }
151
152Namespace:
153 tok_namespace tok_identifier
154 {
155 pdebug("Namespace -> tok_namespace tok_identifier");
156 $$ = $2;
157 }
Mark Slee31985722006-05-24 21:45:31 +0000158
159Typedef:
160 tok_typedef DefinitionType tok_identifier
161 {
162 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000163 t_typedef *td = new t_typedef($2, $3);
164 $$ = td;
165 }
166
167Enum:
168 tok_enum tok_identifier '{' EnumDefList '}'
169 {
170 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
171 $$ = $4;
172 $$->set_name($2);
173 }
174
175EnumDefList:
176 EnumDefList ',' EnumDef
177 {
178 pdebug("EnumDefList -> EnumDefList EnumDef");
179 $$ = $1;
180 $$->append($3);
181 }
182| EnumDef
183 {
184 pdebug("EnumDefList -> EnumDef");
185 $$ = new t_enum;
186 $$->append($1);
187 }
188|
189 {
190 pdebug("EnumDefList -> ");
191 $$ = new t_enum;
192 }
193
194EnumDef:
195 tok_identifier '=' tok_int_constant
196 {
Mark Sleee8540632006-05-30 09:24:40 +0000197 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000198 if ($3 < 0) {
199 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
200 }
Mark Slee31985722006-05-24 21:45:31 +0000201 $$ = new t_constant($1, $3);
202 }
203|
204 tok_identifier
205 {
206 pdebug("EnumDef => tok_identifier");
207 $$ = new t_constant($1);
208 }
209
210Struct:
211 tok_struct tok_identifier '{' FieldList '}'
212 {
213 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000214 $4->set_name($2);
215 $$ = $4;
Mark Slee9cb7c612006-09-01 22:17:45 +0000216 y_field_val = -1;
217 }
218
219Xception:
220 tok_xception tok_identifier '{' FieldList '}'
221 {
222 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
223 $4->set_name($2);
224 $4->set_xception(true);
225 $$ = $4;
226 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000227 }
228
229Service:
230 tok_service tok_identifier '{' FunctionList '}'
231 {
232 pdebug("Service -> tok_service tok_identifier { FunctionList }");
233 $$ = $4;
234 $$->set_name($2);
235 }
236
237FunctionList:
Mark Slee9cb7c612006-09-01 22:17:45 +0000238 FunctionList Function CommaOptional
Mark Slee31985722006-05-24 21:45:31 +0000239 {
240 pdebug("FunctionList -> FunctionList Function");
241 $$ = $1;
242 $1->add_function($2);
243 }
244|
245 {
246 pdebug("FunctionList -> ");
247 $$ = new t_service;
248 }
249
Mark Slee9cb7c612006-09-01 22:17:45 +0000250CommaOptional:
251 ','
252 {}
253|
254 {}
255
Mark Slee31985722006-05-24 21:45:31 +0000256Function:
Mark Slee9cb7c612006-09-01 22:17:45 +0000257 FunctionType AsyncOptional tok_identifier '(' FieldList ')' ThrowsOptional
Mark Slee31985722006-05-24 21:45:31 +0000258 {
Mark Sleeb15a68b2006-06-07 06:46:24 +0000259 $5->set_name(std::string($3) + "_args");
Mark Slee9cb7c612006-09-01 22:17:45 +0000260 $$ = new t_function($1, $3, $5, $7, $2);
261 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000262 }
263
Mark Slee52f643d2006-08-09 00:03:43 +0000264AsyncOptional:
265 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000266 {
Mark Slee52f643d2006-08-09 00:03:43 +0000267 $$ = true;
268 }
269|
270 {
271 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000272 }
273
Mark Slee9cb7c612006-09-01 22:17:45 +0000274ThrowsOptional:
275 tok_throws '(' FieldList ')'
276 {
277 $$ = $3;
278 }
279|
280 {
281 $$ = new t_struct;
282 }
283
Mark Slee31985722006-05-24 21:45:31 +0000284FieldList:
285 FieldList ',' Field
286 {
287 pdebug("FieldList -> FieldList , Field");
288 $$ = $1;
289 $$->append($3);
290 }
291| Field
292 {
293 pdebug("FieldList -> Field");
Mark Sleee8540632006-05-30 09:24:40 +0000294 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000295 $$->append($1);
296 }
297|
298 {
299 pdebug("FieldList -> ");
Mark Sleee8540632006-05-30 09:24:40 +0000300 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000301 }
302
303Field:
304 FieldType tok_identifier '=' tok_int_constant
305 {
Mark Sleee8540632006-05-30 09:24:40 +0000306 pdebug("Field -> FieldType tok_identifier = tok_int_constant");
Mark Slee9cb7c612006-09-01 22:17:45 +0000307 if ($4 <= 0) {
308 printf("WARNING (%d): Nonpositive value (%d) not allowed as a field key for '%s'.\n", yylineno, $4, $2);
309 $4 = y_field_val--;
Mark Slee31985722006-05-24 21:45:31 +0000310 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000311 $$ = new t_field($1, $2, $4);
Mark Slee31985722006-05-24 21:45:31 +0000312 }
313| FieldType tok_identifier
314 {
Mark Sleee8540632006-05-30 09:24:40 +0000315 pdebug("Field -> FieldType tok_identifier");
Mark Slee9cb7c612006-09-01 22:17:45 +0000316 printf("WARNING (%d): No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
317 $$ = new t_field($1, $2, y_field_val--);
Mark Slee31985722006-05-24 21:45:31 +0000318 }
319
320DefinitionType:
321 BaseType
322 {
323 pdebug("DefinitionType -> BaseType");
324 $$ = $1;
325 }
Mark Sleee8540632006-05-30 09:24:40 +0000326| ContainerType
327 {
328 pdebug("DefinitionType -> ContainerType");
329 $$ = $1;
330 }
Mark Slee31985722006-05-24 21:45:31 +0000331
332FunctionType:
333 FieldType
334 {
Mark Sleee8540632006-05-30 09:24:40 +0000335 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000336 $$ = $1;
337 }
338| tok_void
339 {
Mark Sleee8540632006-05-30 09:24:40 +0000340 pdebug("FunctionType -> tok_void");
Mark Slee31985722006-05-24 21:45:31 +0000341 $$ = g_program->get_void_type();
342 }
343
344FieldType:
345 tok_identifier
346 {
Mark Sleee8540632006-05-30 09:24:40 +0000347 pdebug("FieldType -> tok_identifier");
348 $$ = g_program->get_custom_type($1);
349 if ($$ == NULL) {
350 yyerror("Type \"%s\" has not been defined.", $1);
351 exit(1);
352 }
Mark Slee31985722006-05-24 21:45:31 +0000353 }
354| BaseType
355 {
Mark Sleee8540632006-05-30 09:24:40 +0000356 pdebug("FieldType -> BaseType");
357 $$ = $1;
358 }
359| ContainerType
360 {
361 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000362 $$ = $1;
363 }
364
365BaseType:
366 tok_string
367 {
368 pdebug("BaseType -> tok_string");
369 $$ = g_program->get_string_type();
370 }
371| tok_byte
372 {
373 pdebug("BaseType -> tok_byte");
374 $$ = g_program->get_byte_type();
375 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000376| tok_i16
377 {
378 pdebug("BaseType -> tok_i16");
379 $$ = g_program->get_i16_type();
380 }
Mark Slee31985722006-05-24 21:45:31 +0000381| tok_i32
382 {
383 pdebug("BaseType -> tok_i32");
384 $$ = g_program->get_i32_type();
385 }
Mark Slee31985722006-05-24 21:45:31 +0000386| tok_i64
387 {
388 pdebug("BaseType -> tok_i64");
389 $$ = g_program->get_i64_type();
390 }
Mark Slee31985722006-05-24 21:45:31 +0000391
Mark Sleee8540632006-05-30 09:24:40 +0000392ContainerType:
393 MapType
394 {
395 pdebug("ContainerType -> MapType");
396 $$ = $1;
397 }
398| SetType
399 {
400 pdebug("ContainerType -> SetType");
401 $$ = $1;
402 }
403| ListType
404 {
405 pdebug("ContainerType -> ListType");
406 $$ = $1;
407 }
408
409MapType:
410 tok_map '<' FieldType ',' FieldType '>'
411 {
412 pdebug("MapType -> tok_map <FieldType, FieldType>");
413 $$ = new t_map($3, $5);
414 }
415
416SetType:
417 tok_set '<' FieldType '>'
418 {
419 pdebug("SetType -> tok_set<FieldType>");
420 $$ = new t_set($3);
421 }
422
423ListType:
424 tok_list '<' FieldType '>'
425 {
426 pdebug("ListType -> tok_list<FieldType>");
427 $$ = new t_list($3);
428 }
429
Mark Slee31985722006-05-24 21:45:31 +0000430%%