blob: f0fa3c49c09a9a6ca254d94e685452ee24b28099 [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;
30 t_list* tlist;
31 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
60%token tok_function
61%token tok_service
62%token tok_enum
63
64/** Types */
65%type<ttype> BaseType
66
67%type<ttypedef> Typedef
68%type<ttype> DefinitionType
69
70%type<tfield> Field
71%type<ttype> FieldType
72%type<tlist> FieldList
73
74%type<tenum> Enum
75%type<tenum> EnumDefList
76%type<tconstant> EnumDef
77
78%type<tstruct> Struct
79
80%type<tservice> Service
81
82%type<tfunction> Function
83%type<id> FunctionModifiers
84%type<ttype> FunctionType
85%type<tservice> FunctionList
86
87%%
88
89/** Thrift Grammar */
90
91Program:
92 DefinitionList
93 {
94 pdebug("Program -> DefinitionList");
95 }
96
97DefinitionList:
98 DefinitionList Definition
99 {
100 pdebug("DefinitionList -> DefinitionList Definition");
101 }
102|
103 {
104 pdebug("DefinitionList -> ");
105 }
106
107Definition:
108 Typedef
109 {
110 pdebug("Definition -> Typedef");
111 g_program->add_typedef($1);
112 }
113| Enum
114 {
115 pdebug("Definition -> Enum");
116 g_program->add_enum($1);
117 }
118| Struct
119 {
120 pdebug("Definition -> Struct");
121 g_program->add_struct($1);
122 }
123| Service
124 {
125 pdebug("Definition -> Service");
126 g_program->add_service($1);
127 }
128
129Typedef:
130 tok_typedef DefinitionType tok_identifier
131 {
132 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
133
134 t_typedef *td = new t_typedef($2, $3);
135 $$ = td;
136 }
137
138Enum:
139 tok_enum tok_identifier '{' EnumDefList '}'
140 {
141 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
142 $$ = $4;
143 $$->set_name($2);
144 }
145
146EnumDefList:
147 EnumDefList ',' EnumDef
148 {
149 pdebug("EnumDefList -> EnumDefList EnumDef");
150 $$ = $1;
151 $$->append($3);
152 }
153| EnumDef
154 {
155 pdebug("EnumDefList -> EnumDef");
156 $$ = new t_enum;
157 $$->append($1);
158 }
159|
160 {
161 pdebug("EnumDefList -> ");
162 $$ = new t_enum;
163 }
164
165EnumDef:
166 tok_identifier '=' tok_int_constant
167 {
168 if ($3 < 0) {
169 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
170 }
171 pdebug("EnumDef => tok_identifier = tok_int_constant");
172 $$ = new t_constant($1, $3);
173 }
174|
175 tok_identifier
176 {
177 pdebug("EnumDef => tok_identifier");
178 $$ = new t_constant($1);
179 }
180
181Struct:
182 tok_struct tok_identifier '{' FieldList '}'
183 {
184 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
185 $$ = new t_struct($2, $4);
186 y_field_val = 0;
187 }
188
189Service:
190 tok_service tok_identifier '{' FunctionList '}'
191 {
192 pdebug("Service -> tok_service tok_identifier { FunctionList }");
193 $$ = $4;
194 $$->set_name($2);
195 }
196
197FunctionList:
198 FunctionList Function
199 {
200 pdebug("FunctionList -> FunctionList Function");
201 $$ = $1;
202 $1->add_function($2);
203 }
204|
205 {
206 pdebug("FunctionList -> ");
207 $$ = new t_service;
208 }
209
210Function:
211 FunctionType FunctionModifiers tok_identifier '(' FieldList ')'
212 {
213 t_struct* fun_args = new t_struct("__targs", $5);
214 $$ = new t_function($1, $3, fun_args);
215 y_field_val = 0;
216 }
217
218FunctionModifiers:
219 {
220 /** TODO(mcslee): implement async modifier, etc. */
221 $$ = 0;
222 }
223
224FieldList:
225 FieldList ',' Field
226 {
227 pdebug("FieldList -> FieldList , Field");
228 $$ = $1;
229 $$->append($3);
230 }
231| Field
232 {
233 pdebug("FieldList -> Field");
234 $$ = new t_list;
235 $$->append($1);
236 }
237|
238 {
239 pdebug("FieldList -> ");
240 $$ = new t_list;
241 }
242
243Field:
244 FieldType tok_identifier '=' tok_int_constant
245 {
246 if ($4 < 0) {
247 yyerror("Negative value (%d) not allowed as a field key.", $4);
248 }
249 $$ = new t_field($1, $2, (uint32_t)$4);
250 y_field_val = $4+1;
251 }
252| FieldType tok_identifier
253 {
254 printf("WARNING (%d): No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
255 $$ = new t_field($1, $2, y_field_val++);
256 }
257
258DefinitionType:
259 BaseType
260 {
261 pdebug("DefinitionType -> BaseType");
262 $$ = $1;
263 }
264
265FunctionType:
266 FieldType
267 {
268 $$ = $1;
269 }
270| tok_void
271 {
272 $$ = g_program->get_void_type();
273 }
274
275FieldType:
276 tok_identifier
277 {
278 /** TODO(mcslee): Dynamic type lookup */
279 yyerror("No dynamic type lookup yet.");
280 }
281| BaseType
282 {
283 $$ = $1;
284 }
285
286BaseType:
287 tok_string
288 {
289 pdebug("BaseType -> tok_string");
290 $$ = g_program->get_string_type();
291 }
292| tok_byte
293 {
294 pdebug("BaseType -> tok_byte");
295 $$ = g_program->get_byte_type();
296 }
297| tok_i32
298 {
299 pdebug("BaseType -> tok_i32");
300 $$ = g_program->get_i32_type();
301 }
302| tok_u32
303 {
304 pdebug("BaseType -> tok_u32");
305 $$ = g_program->get_u32_type();
306 }
307| tok_i64
308 {
309 pdebug("BaseType -> tok_i64");
310 $$ = g_program->get_i64_type();
311 }
312| tok_u64
313 {
314 pdebug("BaseType -> tok_u64");
315 $$ = g_program->get_u64_type();
316 }
317
318%%