blob: 269d163205e7b762dfa8134d95739efce8760f7c [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
Mark Slee31985722006-05-24 21:45:31 +000059%token tok_service
60%token tok_enum
61
62/** Types */
63%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +000064%type<ttype> ContainerType
65%type<ttype> MapType
66%type<ttype> SetType
67%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +000068
69%type<ttypedef> Typedef
70%type<ttype> DefinitionType
71
72%type<tfield> Field
73%type<ttype> FieldType
Mark Sleee8540632006-05-30 09:24:40 +000074%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +000075
76%type<tenum> Enum
77%type<tenum> EnumDefList
78%type<tconstant> EnumDef
79
80%type<tstruct> Struct
81
82%type<tservice> Service
83
84%type<tfunction> Function
85%type<id> FunctionModifiers
86%type<ttype> FunctionType
87%type<tservice> FunctionList
88
89%%
90
91/** Thrift Grammar */
92
93Program:
94 DefinitionList
95 {
96 pdebug("Program -> DefinitionList");
97 }
98
99DefinitionList:
100 DefinitionList Definition
101 {
102 pdebug("DefinitionList -> DefinitionList Definition");
103 }
104|
105 {
106 pdebug("DefinitionList -> ");
107 }
108
109Definition:
110 Typedef
111 {
112 pdebug("Definition -> Typedef");
113 g_program->add_typedef($1);
114 }
115| Enum
116 {
117 pdebug("Definition -> Enum");
118 g_program->add_enum($1);
119 }
120| Struct
121 {
122 pdebug("Definition -> Struct");
123 g_program->add_struct($1);
124 }
125| Service
126 {
127 pdebug("Definition -> Service");
128 g_program->add_service($1);
129 }
130
131Typedef:
132 tok_typedef DefinitionType tok_identifier
133 {
134 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000135 t_typedef *td = new t_typedef($2, $3);
136 $$ = td;
137 }
138
139Enum:
140 tok_enum tok_identifier '{' EnumDefList '}'
141 {
142 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
143 $$ = $4;
144 $$->set_name($2);
145 }
146
147EnumDefList:
148 EnumDefList ',' EnumDef
149 {
150 pdebug("EnumDefList -> EnumDefList EnumDef");
151 $$ = $1;
152 $$->append($3);
153 }
154| EnumDef
155 {
156 pdebug("EnumDefList -> EnumDef");
157 $$ = new t_enum;
158 $$->append($1);
159 }
160|
161 {
162 pdebug("EnumDefList -> ");
163 $$ = new t_enum;
164 }
165
166EnumDef:
167 tok_identifier '=' tok_int_constant
168 {
Mark Sleee8540632006-05-30 09:24:40 +0000169 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000170 if ($3 < 0) {
171 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
172 }
Mark Slee31985722006-05-24 21:45:31 +0000173 $$ = new t_constant($1, $3);
174 }
175|
176 tok_identifier
177 {
178 pdebug("EnumDef => tok_identifier");
179 $$ = new t_constant($1);
180 }
181
182Struct:
183 tok_struct tok_identifier '{' FieldList '}'
184 {
185 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000186 $4->set_name($2);
187 $$ = $4;
Mark Slee31985722006-05-24 21:45:31 +0000188 y_field_val = 0;
189 }
190
191Service:
192 tok_service tok_identifier '{' FunctionList '}'
193 {
194 pdebug("Service -> tok_service tok_identifier { FunctionList }");
195 $$ = $4;
196 $$->set_name($2);
197 }
198
199FunctionList:
200 FunctionList Function
201 {
202 pdebug("FunctionList -> FunctionList Function");
203 $$ = $1;
204 $1->add_function($2);
205 }
206|
207 {
208 pdebug("FunctionList -> ");
209 $$ = new t_service;
210 }
211
212Function:
213 FunctionType FunctionModifiers tok_identifier '(' FieldList ')'
214 {
Mark Sleeb15a68b2006-06-07 06:46:24 +0000215 $5->set_name(std::string($3) + "_args");
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%%