blob: d0882ff7c8861ff10534fd3bf96ac3f74df90b6b [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;
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
38/** Base datatypes */
39%token tok_byte
40%token tok_string
41%token tok_i32
42%token tok_u32
43%token tok_i64
44%token tok_u64
45
46/** Complex Types */
47%token tok_map
48%token tok_list
49%token tok_set
50
51/** Function types */
52%token tok_void
53
54/** Modifiers */
55%token tok_async
56
57/** Thrift actions */
58%token tok_typedef
59%token tok_struct
Mark Slee31985722006-05-24 21:45:31 +000060%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
Mark Slee31985722006-05-24 21:45:31 +000086%type<ttype> FunctionType
87%type<tservice> FunctionList
88
Mark Slee52f643d2006-08-09 00:03:43 +000089%type<tbool> AsyncOptional
90
Mark Slee31985722006-05-24 21:45:31 +000091%%
92
93/** Thrift Grammar */
94
95Program:
96 DefinitionList
97 {
98 pdebug("Program -> DefinitionList");
99 }
100
101DefinitionList:
102 DefinitionList Definition
103 {
104 pdebug("DefinitionList -> DefinitionList Definition");
105 }
106|
107 {
108 pdebug("DefinitionList -> ");
109 }
110
111Definition:
112 Typedef
113 {
114 pdebug("Definition -> Typedef");
115 g_program->add_typedef($1);
116 }
117| Enum
118 {
119 pdebug("Definition -> Enum");
120 g_program->add_enum($1);
121 }
122| Struct
123 {
124 pdebug("Definition -> Struct");
125 g_program->add_struct($1);
126 }
127| Service
128 {
129 pdebug("Definition -> Service");
130 g_program->add_service($1);
131 }
132
133Typedef:
134 tok_typedef DefinitionType tok_identifier
135 {
136 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000137 t_typedef *td = new t_typedef($2, $3);
138 $$ = td;
139 }
140
141Enum:
142 tok_enum tok_identifier '{' EnumDefList '}'
143 {
144 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
145 $$ = $4;
146 $$->set_name($2);
147 }
148
149EnumDefList:
150 EnumDefList ',' EnumDef
151 {
152 pdebug("EnumDefList -> EnumDefList EnumDef");
153 $$ = $1;
154 $$->append($3);
155 }
156| EnumDef
157 {
158 pdebug("EnumDefList -> EnumDef");
159 $$ = new t_enum;
160 $$->append($1);
161 }
162|
163 {
164 pdebug("EnumDefList -> ");
165 $$ = new t_enum;
166 }
167
168EnumDef:
169 tok_identifier '=' tok_int_constant
170 {
Mark Sleee8540632006-05-30 09:24:40 +0000171 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000172 if ($3 < 0) {
173 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
174 }
Mark Slee31985722006-05-24 21:45:31 +0000175 $$ = new t_constant($1, $3);
176 }
177|
178 tok_identifier
179 {
180 pdebug("EnumDef => tok_identifier");
181 $$ = new t_constant($1);
182 }
183
184Struct:
185 tok_struct tok_identifier '{' FieldList '}'
186 {
187 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000188 $4->set_name($2);
189 $$ = $4;
Mark Slee31985722006-05-24 21:45:31 +0000190 y_field_val = 0;
191 }
192
193Service:
194 tok_service tok_identifier '{' FunctionList '}'
195 {
196 pdebug("Service -> tok_service tok_identifier { FunctionList }");
197 $$ = $4;
198 $$->set_name($2);
199 }
200
201FunctionList:
202 FunctionList Function
203 {
204 pdebug("FunctionList -> FunctionList Function");
205 $$ = $1;
206 $1->add_function($2);
207 }
208|
209 {
210 pdebug("FunctionList -> ");
211 $$ = new t_service;
212 }
213
214Function:
Mark Slee52f643d2006-08-09 00:03:43 +0000215 FunctionType AsyncOptional tok_identifier '(' FieldList ')'
Mark Slee31985722006-05-24 21:45:31 +0000216 {
Mark Sleeb15a68b2006-06-07 06:46:24 +0000217 $5->set_name(std::string($3) + "_args");
Mark Slee52f643d2006-08-09 00:03:43 +0000218 $$ = new t_function($1, $3, $5, $2);
Mark Slee31985722006-05-24 21:45:31 +0000219 y_field_val = 0;
220 }
221
Mark Slee52f643d2006-08-09 00:03:43 +0000222AsyncOptional:
223 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000224 {
Mark Slee52f643d2006-08-09 00:03:43 +0000225 $$ = true;
226 }
227|
228 {
229 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000230 }
231
232FieldList:
233 FieldList ',' Field
234 {
235 pdebug("FieldList -> FieldList , Field");
236 $$ = $1;
237 $$->append($3);
238 }
239| Field
240 {
241 pdebug("FieldList -> Field");
Mark Sleee8540632006-05-30 09:24:40 +0000242 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000243 $$->append($1);
244 }
245|
246 {
247 pdebug("FieldList -> ");
Mark Sleee8540632006-05-30 09:24:40 +0000248 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000249 }
250
251Field:
252 FieldType tok_identifier '=' tok_int_constant
253 {
Mark Sleee8540632006-05-30 09:24:40 +0000254 pdebug("Field -> FieldType tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000255 if ($4 < 0) {
256 yyerror("Negative value (%d) not allowed as a field key.", $4);
Mark Sleee8540632006-05-30 09:24:40 +0000257 exit(1);
Mark Slee31985722006-05-24 21:45:31 +0000258 }
259 $$ = new t_field($1, $2, (uint32_t)$4);
260 y_field_val = $4+1;
261 }
262| FieldType tok_identifier
263 {
Mark Sleee8540632006-05-30 09:24:40 +0000264 pdebug("Field -> FieldType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000265 printf("WARNING (%d): No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
266 $$ = new t_field($1, $2, y_field_val++);
267 }
268
269DefinitionType:
270 BaseType
271 {
272 pdebug("DefinitionType -> BaseType");
273 $$ = $1;
274 }
Mark Sleee8540632006-05-30 09:24:40 +0000275| ContainerType
276 {
277 pdebug("DefinitionType -> ContainerType");
278 $$ = $1;
279 }
Mark Slee31985722006-05-24 21:45:31 +0000280
281FunctionType:
282 FieldType
283 {
Mark Sleee8540632006-05-30 09:24:40 +0000284 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000285 $$ = $1;
286 }
287| tok_void
288 {
Mark Sleee8540632006-05-30 09:24:40 +0000289 pdebug("FunctionType -> tok_void");
Mark Slee31985722006-05-24 21:45:31 +0000290 $$ = g_program->get_void_type();
291 }
292
293FieldType:
294 tok_identifier
295 {
Mark Sleee8540632006-05-30 09:24:40 +0000296 pdebug("FieldType -> tok_identifier");
297 $$ = g_program->get_custom_type($1);
298 if ($$ == NULL) {
299 yyerror("Type \"%s\" has not been defined.", $1);
300 exit(1);
301 }
Mark Slee31985722006-05-24 21:45:31 +0000302 }
303| BaseType
304 {
Mark Sleee8540632006-05-30 09:24:40 +0000305 pdebug("FieldType -> BaseType");
306 $$ = $1;
307 }
308| ContainerType
309 {
310 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000311 $$ = $1;
312 }
313
314BaseType:
315 tok_string
316 {
317 pdebug("BaseType -> tok_string");
318 $$ = g_program->get_string_type();
319 }
320| tok_byte
321 {
322 pdebug("BaseType -> tok_byte");
323 $$ = g_program->get_byte_type();
324 }
325| tok_i32
326 {
327 pdebug("BaseType -> tok_i32");
328 $$ = g_program->get_i32_type();
329 }
330| tok_u32
331 {
332 pdebug("BaseType -> tok_u32");
333 $$ = g_program->get_u32_type();
334 }
335| tok_i64
336 {
337 pdebug("BaseType -> tok_i64");
338 $$ = g_program->get_i64_type();
339 }
340| tok_u64
341 {
342 pdebug("BaseType -> tok_u64");
343 $$ = g_program->get_u64_type();
344 }
345
Mark Sleee8540632006-05-30 09:24:40 +0000346ContainerType:
347 MapType
348 {
349 pdebug("ContainerType -> MapType");
350 $$ = $1;
351 }
352| SetType
353 {
354 pdebug("ContainerType -> SetType");
355 $$ = $1;
356 }
357| ListType
358 {
359 pdebug("ContainerType -> ListType");
360 $$ = $1;
361 }
362
363MapType:
364 tok_map '<' FieldType ',' FieldType '>'
365 {
366 pdebug("MapType -> tok_map <FieldType, FieldType>");
367 $$ = new t_map($3, $5);
368 }
369
370SetType:
371 tok_set '<' FieldType '>'
372 {
373 pdebug("SetType -> tok_set<FieldType>");
374 $$ = new t_set($3);
375 }
376
377ListType:
378 tok_list '<' FieldType '>'
379 {
380 pdebug("ListType -> tok_list<FieldType>");
381 $$ = new t_list($3);
382 }
383
Mark Slee31985722006-05-24 21:45:31 +0000384%%