blob: 8533805dd6a5b96a89071b235c96bd2e5e1d88cf [file] [log] [blame]
Mark Slee31985722006-05-24 21:45:31 +00001%{
Mark Sleee9ce01c2007-05-16 02:29:53 +00002// Copyright (c) 2006- Facebook
3// Distributed under the Thrift Software License
4//
5// See accompanying file LICENSE or visit the Thrift site at:
6// http://developers.facebook.com/thrift/
Mark Slee31985722006-05-24 21:45:31 +00007
8/**
9 * Thrift parser.
10 *
11 * This parser is used on a thrift definition file.
12 *
13 * @author Mark Slee <mcslee@facebook.com>
14 */
15
16#include <stdio.h>
17#include "main.h"
18#include "globals.h"
19#include "parse/t_program.h"
Mark Sleef0712dc2006-10-25 19:03:57 +000020#include "parse/t_scope.h"
Mark Slee31985722006-05-24 21:45:31 +000021
Mark Sleef5377b32006-10-10 01:42:59 +000022/**
23 * This global variable is used for automatic numbering of field indices etc.
24 * when parsing the members of a struct. Field values are automatically
25 * assigned starting from -1 and working their way down.
26 */
Mark Slee9cb7c612006-09-01 22:17:45 +000027int y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +000028
29%}
30
Mark Sleef5377b32006-10-10 01:42:59 +000031/**
32 * This structure is used by the parser to hold the data types associated with
33 * various parse nodes.
34 */
Mark Slee31985722006-05-24 21:45:31 +000035%union {
Mark Slee30152872006-11-28 01:24:07 +000036 char* id;
37 int iconst;
38 double dconst;
39 bool tbool;
David Reisscdffe262007-08-14 17:12:31 +000040 t_doc* tdoc;
Mark Slee30152872006-11-28 01:24:07 +000041 t_type* ttype;
Mark Slee6a47fed2007-02-07 02:40:59 +000042 t_base_type* tbase;
Mark Slee30152872006-11-28 01:24:07 +000043 t_typedef* ttypedef;
44 t_enum* tenum;
45 t_enum_value* tenumv;
46 t_const* tconst;
47 t_const_value* tconstv;
48 t_struct* tstruct;
49 t_service* tservice;
50 t_function* tfunction;
51 t_field* tfield;
David Reisscdffe262007-08-14 17:12:31 +000052 char* dtext;
David Reiss8320a922007-08-14 19:59:26 +000053 t_field::e_req ereq;
Mark Slee31985722006-05-24 21:45:31 +000054}
55
Mark Sleef5377b32006-10-10 01:42:59 +000056/**
57 * Strings identifier
58 */
Mark Slee31985722006-05-24 21:45:31 +000059%token<id> tok_identifier
Mark Sleef0712dc2006-10-25 19:03:57 +000060%token<id> tok_literal
David Reisscdffe262007-08-14 17:12:31 +000061%token<dtext> tok_doctext
Mark Sleef5377b32006-10-10 01:42:59 +000062
63/**
Mark Slee30152872006-11-28 01:24:07 +000064 * Constant values
Mark Sleef5377b32006-10-10 01:42:59 +000065 */
Mark Slee31985722006-05-24 21:45:31 +000066%token<iconst> tok_int_constant
Mark Slee30152872006-11-28 01:24:07 +000067%token<dconst> tok_dub_constant
Mark Slee31985722006-05-24 21:45:31 +000068
Mark Sleef5377b32006-10-10 01:42:59 +000069/**
Mark Sleef0712dc2006-10-25 19:03:57 +000070 * Header keywoards
Mark Sleef5377b32006-10-10 01:42:59 +000071 */
Mark Sleef0712dc2006-10-25 19:03:57 +000072%token tok_include
Mark Slee9cb7c612006-09-01 22:17:45 +000073%token tok_namespace
Mark Sleef0712dc2006-10-25 19:03:57 +000074%token tok_cpp_namespace
75%token tok_cpp_include
76%token tok_cpp_type
Mark Sleee888b372007-01-12 01:06:24 +000077%token tok_php_namespace
David Reissc6fc3292007-08-30 00:58:43 +000078%token tok_py_module
Mark Slee27ed6ec2007-08-16 01:26:31 +000079%token tok_perl_package
Mark Sleef0712dc2006-10-25 19:03:57 +000080%token tok_java_package
Mark Slee782abbb2007-01-19 00:17:02 +000081%token tok_xsd_all
Mark Slee36bfa2e2007-01-19 20:09:51 +000082%token tok_xsd_optional
Mark Slee7df0e2a2007-02-06 21:03:18 +000083%token tok_xsd_nillable
Mark Slee0d9199e2007-01-31 02:08:30 +000084%token tok_xsd_namespace
Mark Slee21135c32007-02-05 21:52:08 +000085%token tok_xsd_attrs
Mark Slee58dfb4f2007-07-06 02:45:25 +000086%token tok_ruby_namespace
Mark Slee9cb7c612006-09-01 22:17:45 +000087
Mark Sleef5377b32006-10-10 01:42:59 +000088/**
89 * Base datatype keywords
90 */
91%token tok_void
Mark Slee78f58e22006-09-02 04:17:07 +000092%token tok_bool
Mark Slee31985722006-05-24 21:45:31 +000093%token tok_byte
94%token tok_string
Mark Slee8d725a22007-04-13 01:57:12 +000095%token tok_binary
Mark Sleeb6200d82007-01-19 19:14:36 +000096%token tok_slist
Mark Slee6a47fed2007-02-07 02:40:59 +000097%token tok_senum
Mark Slee9cb7c612006-09-01 22:17:45 +000098%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000099%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +0000100%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +0000101%token tok_double
Mark Slee31985722006-05-24 21:45:31 +0000102
Mark Sleef5377b32006-10-10 01:42:59 +0000103/**
104 * Complex type keywords
105 */
Mark Slee31985722006-05-24 21:45:31 +0000106%token tok_map
107%token tok_list
108%token tok_set
109
Mark Sleef5377b32006-10-10 01:42:59 +0000110/**
111 * Function modifiers
Mark Slee27ed6ec2007-08-16 01:26:31 +0000112 */
Mark Slee31985722006-05-24 21:45:31 +0000113%token tok_async
114
Mark Sleef5377b32006-10-10 01:42:59 +0000115/**
116 * Thrift language keywords
117 */
Mark Slee31985722006-05-24 21:45:31 +0000118%token tok_typedef
119%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000120%token tok_xception
121%token tok_throws
Mark Sleef0712dc2006-10-25 19:03:57 +0000122%token tok_extends
Mark Slee31985722006-05-24 21:45:31 +0000123%token tok_service
124%token tok_enum
Mark Slee30152872006-11-28 01:24:07 +0000125%token tok_const
David Reiss8320a922007-08-14 19:59:26 +0000126%token tok_required
127%token tok_optional
Mark Slee31985722006-05-24 21:45:31 +0000128
Mark Sleef5377b32006-10-10 01:42:59 +0000129/**
130 * Grammar nodes
131 */
132
Mark Slee31985722006-05-24 21:45:31 +0000133%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +0000134%type<ttype> ContainerType
135%type<ttype> MapType
136%type<ttype> SetType
137%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +0000138
David Reisscdffe262007-08-14 17:12:31 +0000139%type<tdoc> Definition
Mark Sleef0712dc2006-10-25 19:03:57 +0000140%type<ttype> TypeDefinition
141
Mark Slee31985722006-05-24 21:45:31 +0000142%type<ttypedef> Typedef
143%type<ttype> DefinitionType
144
145%type<tfield> Field
Mark Slee7ff32452007-02-01 05:26:18 +0000146%type<iconst> FieldIdentifier
David Reiss8320a922007-08-14 19:59:26 +0000147%type<ereq> FieldRequiredness
Mark Slee31985722006-05-24 21:45:31 +0000148%type<ttype> FieldType
Mark Slee7ff32452007-02-01 05:26:18 +0000149%type<tconstv> FieldValue
Mark Sleee8540632006-05-30 09:24:40 +0000150%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +0000151
152%type<tenum> Enum
153%type<tenum> EnumDefList
Mark Slee30152872006-11-28 01:24:07 +0000154%type<tenumv> EnumDef
155
Mark Slee6a47fed2007-02-07 02:40:59 +0000156%type<ttypedef> Senum
157%type<tbase> SenumDefList
158%type<id> SenumDef
159
Mark Slee30152872006-11-28 01:24:07 +0000160%type<tconst> Const
161%type<tconstv> ConstValue
162%type<tconstv> ConstList
163%type<tconstv> ConstListContents
164%type<tconstv> ConstMap
165%type<tconstv> ConstMapContents
Mark Slee31985722006-05-24 21:45:31 +0000166
167%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000168%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +0000169%type<tservice> Service
170
171%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +0000172%type<ttype> FunctionType
173%type<tservice> FunctionList
174
Mark Slee36bfa2e2007-01-19 20:09:51 +0000175%type<tstruct> Throws
176%type<tservice> Extends
177%type<tbool> Async
178%type<tbool> XsdAll
179%type<tbool> XsdOptional
Mark Slee7df0e2a2007-02-06 21:03:18 +0000180%type<tbool> XsdNillable
Mark Slee748d83f2007-02-07 01:20:08 +0000181%type<tstruct> XsdAttributes
Mark Slee36bfa2e2007-01-19 20:09:51 +0000182%type<id> CppType
Mark Slee52f643d2006-08-09 00:03:43 +0000183
David Reisscbd4bac2007-08-14 17:12:33 +0000184%type<dtext> CaptureDocText
ccheeverf53b5cf2007-02-05 20:33:11 +0000185
Mark Slee31985722006-05-24 21:45:31 +0000186%%
187
Mark Sleef5377b32006-10-10 01:42:59 +0000188/**
189 * Thrift Grammar Implementation.
190 *
191 * For the most part this source file works its way top down from what you
192 * might expect to find in a typical .thrift file, i.e. type definitions and
193 * namespaces up top followed by service definitions using those types.
194 */
Mark Slee31985722006-05-24 21:45:31 +0000195
196Program:
David Reisscbd4bac2007-08-14 17:12:33 +0000197 HeaderList DefinitionList
Mark Sleef0712dc2006-10-25 19:03:57 +0000198 {
199 pdebug("Program -> Headers DefinitionList");
David Reisscbd4bac2007-08-14 17:12:33 +0000200 /*
201 TODO(dreiss): Decide whether full-program doctext is worth the trouble.
David Reissc2532a92007-07-30 23:46:11 +0000202 if ($1 != NULL) {
203 g_program->set_doc($1);
204 }
David Reisscbd4bac2007-08-14 17:12:33 +0000205 */
206 clear_doctext();
Mark Sleef0712dc2006-10-25 19:03:57 +0000207 }
208
David Reisscbd4bac2007-08-14 17:12:33 +0000209CaptureDocText:
210 {
211 if (g_parse_mode == PROGRAM) {
212 $$ = g_doctext;
213 g_doctext = NULL;
Mark Slee27ed6ec2007-08-16 01:26:31 +0000214 } else {
David Reisscbd4bac2007-08-14 17:12:33 +0000215 $$ = NULL;
216 }
217 }
218
219/* TODO(dreiss): Try to DestroyDocText in all sorts or random places. */
220DestroyDocText:
221 {
222 if (g_parse_mode == PROGRAM) {
223 clear_doctext();
224 }
225 }
226
227/* We have to DestroyDocText here, otherwise it catches the doctext
228 on the first real element. */
Mark Sleef0712dc2006-10-25 19:03:57 +0000229HeaderList:
David Reisscbd4bac2007-08-14 17:12:33 +0000230 HeaderList DestroyDocText Header
Mark Sleef0712dc2006-10-25 19:03:57 +0000231 {
232 pdebug("HeaderList -> HeaderList Header");
233 }
234|
235 {
236 pdebug("HeaderList -> ");
237 }
238
239Header:
240 Include
241 {
242 pdebug("Header -> Include");
243 }
244| tok_namespace tok_identifier
245 {
246 pwarning(1, "'namespace' is deprecated. Use 'cpp_namespace' and/or 'java_package' instead");
247 if (g_parse_mode == PROGRAM) {
248 g_program->set_cpp_namespace($2);
249 g_program->set_java_package($2);
250 }
251 }
252| tok_cpp_namespace tok_identifier
253 {
254 pdebug("Header -> tok_cpp_namespace tok_identifier");
255 if (g_parse_mode == PROGRAM) {
256 g_program->set_cpp_namespace($2);
257 }
258 }
259| tok_cpp_include tok_literal
260 {
261 pdebug("Header -> tok_cpp_include tok_literal");
262 if (g_parse_mode == PROGRAM) {
263 g_program->add_cpp_include($2);
264 }
265 }
Mark Sleee888b372007-01-12 01:06:24 +0000266| tok_php_namespace tok_identifier
267 {
268 pdebug("Header -> tok_php_namespace tok_identifier");
269 if (g_parse_mode == PROGRAM) {
270 g_program->set_php_namespace($2);
271 }
272 }
David Reissc6fc3292007-08-30 00:58:43 +0000273| tok_py_module tok_identifier
274 {
275 pdebug("Header -> tok_py_module tok_identifier");
276 if (g_parse_mode == PROGRAM) {
277 g_program->set_py_module($2);
278 }
279 }
Mark Slee27ed6ec2007-08-16 01:26:31 +0000280| tok_perl_package tok_identifier
281 {
282 pdebug("Header -> tok_perl_namespace tok_identifier");
283 if (g_parse_mode == PROGRAM) {
284 g_program->set_perl_package($2);
285 }
286 }
Mark Slee58dfb4f2007-07-06 02:45:25 +0000287| tok_ruby_namespace tok_identifier
288 {
289 pdebug("Header -> tok_ruby_namespace tok_identifier");
290 if (g_parse_mode == PROGRAM) {
291 g_program->set_ruby_namespace($2);
292 }
293 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000294| tok_java_package tok_identifier
295 {
296 pdebug("Header -> tok_java_package tok_identifier");
297 if (g_parse_mode == PROGRAM) {
298 g_program->set_java_package($2);
299 }
300 }
Mark Slee0d9199e2007-01-31 02:08:30 +0000301| tok_xsd_namespace tok_literal
302 {
303 pdebug("Header -> tok_xsd_namespace tok_literal");
304 if (g_parse_mode == PROGRAM) {
305 g_program->set_xsd_namespace($2);
306 }
307 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000308
309Include:
310 tok_include tok_literal
311 {
Mark Slee27ed6ec2007-08-16 01:26:31 +0000312 pdebug("Include -> tok_include tok_literal");
Mark Sleef0712dc2006-10-25 19:03:57 +0000313 if (g_parse_mode == INCLUDES) {
314 std::string path = include_file(std::string($2));
315 if (!path.empty()) {
316 g_program->add_include(path);
317 }
318 }
319 }
Mark Slee31985722006-05-24 21:45:31 +0000320
321DefinitionList:
David Reisscbd4bac2007-08-14 17:12:33 +0000322 DefinitionList CaptureDocText Definition
Mark Slee31985722006-05-24 21:45:31 +0000323 {
324 pdebug("DefinitionList -> DefinitionList Definition");
David Reisscdffe262007-08-14 17:12:31 +0000325 if ($2 != NULL && $3 != NULL) {
326 $3->set_doc($2);
327 }
Mark Slee31985722006-05-24 21:45:31 +0000328 }
329|
330 {
331 pdebug("DefinitionList -> ");
332 }
333
334Definition:
Mark Slee30152872006-11-28 01:24:07 +0000335 Const
336 {
337 pdebug("Definition -> Const");
338 if (g_parse_mode == PROGRAM) {
339 g_program->add_const($1);
340 }
David Reisscdffe262007-08-14 17:12:31 +0000341 $$ = $1;
Mark Slee30152872006-11-28 01:24:07 +0000342 }
343| TypeDefinition
Mark Slee9cb7c612006-09-01 22:17:45 +0000344 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000345 pdebug("Definition -> TypeDefinition");
346 if (g_parse_mode == PROGRAM) {
347 g_scope->add_type($1->get_name(), $1);
348 if (g_parent_scope != NULL) {
349 g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
350 }
351 }
David Reisscdffe262007-08-14 17:12:31 +0000352 $$ = $1;
Mark Slee9cb7c612006-09-01 22:17:45 +0000353 }
Mark Slee31985722006-05-24 21:45:31 +0000354| Service
355 {
356 pdebug("Definition -> Service");
Mark Sleef0712dc2006-10-25 19:03:57 +0000357 if (g_parse_mode == PROGRAM) {
358 g_scope->add_service($1->get_name(), $1);
359 if (g_parent_scope != NULL) {
360 g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
361 }
362 g_program->add_service($1);
363 }
David Reisscdffe262007-08-14 17:12:31 +0000364 $$ = $1;
Mark Slee9cb7c612006-09-01 22:17:45 +0000365 }
366
Mark Sleef0712dc2006-10-25 19:03:57 +0000367TypeDefinition:
368 Typedef
Mark Slee9cb7c612006-09-01 22:17:45 +0000369 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000370 pdebug("TypeDefinition -> Typedef");
371 if (g_parse_mode == PROGRAM) {
372 g_program->add_typedef($1);
373 }
374 }
375| Enum
376 {
377 pdebug("TypeDefinition -> Enum");
378 if (g_parse_mode == PROGRAM) {
379 g_program->add_enum($1);
380 }
381 }
Mark Slee6a47fed2007-02-07 02:40:59 +0000382| Senum
383 {
384 pdebug("TypeDefinition -> Senum");
385 if (g_parse_mode == PROGRAM) {
386 g_program->add_typedef($1);
387 }
388 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000389| Struct
390 {
391 pdebug("TypeDefinition -> Struct");
392 if (g_parse_mode == PROGRAM) {
393 g_program->add_struct($1);
394 }
395 }
396| Xception
Mark Slee27ed6ec2007-08-16 01:26:31 +0000397 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000398 pdebug("TypeDefinition -> Xception");
399 if (g_parse_mode == PROGRAM) {
400 g_program->add_xception($1);
401 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000402 }
Mark Slee31985722006-05-24 21:45:31 +0000403
404Typedef:
David Reisscdffe262007-08-14 17:12:31 +0000405 tok_typedef DefinitionType tok_identifier
Mark Slee31985722006-05-24 21:45:31 +0000406 {
407 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
David Reisscdffe262007-08-14 17:12:31 +0000408 t_typedef *td = new t_typedef(g_program, $2, $3);
Mark Slee31985722006-05-24 21:45:31 +0000409 $$ = td;
410 }
411
Mark Slee6a47fed2007-02-07 02:40:59 +0000412CommaOrSemicolonOptional:
413 ','
414 {}
415| ';'
416 {}
417|
418 {}
ccheeverf53b5cf2007-02-05 20:33:11 +0000419
Mark Slee31985722006-05-24 21:45:31 +0000420Enum:
David Reisscdffe262007-08-14 17:12:31 +0000421 tok_enum tok_identifier '{' EnumDefList '}'
Mark Slee31985722006-05-24 21:45:31 +0000422 {
423 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
David Reisscdffe262007-08-14 17:12:31 +0000424 $$ = $4;
425 $$->set_name($2);
Mark Slee31985722006-05-24 21:45:31 +0000426 }
427
428EnumDefList:
Mark Slee207cb462006-11-02 18:43:12 +0000429 EnumDefList EnumDef
Mark Slee31985722006-05-24 21:45:31 +0000430 {
431 pdebug("EnumDefList -> EnumDefList EnumDef");
432 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000433 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000434 }
435|
436 {
437 pdebug("EnumDefList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000438 $$ = new t_enum(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000439 }
440
441EnumDef:
David Reisscbd4bac2007-08-14 17:12:33 +0000442 CaptureDocText tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000443 {
Mark Slee30152872006-11-28 01:24:07 +0000444 pdebug("EnumDef -> tok_identifier = tok_int_constant");
ccheeverf53b5cf2007-02-05 20:33:11 +0000445 if ($4 < 0) {
446 pwarning(1, "Negative value supplied for enum %s.\n", $2);
Mark Slee31985722006-05-24 21:45:31 +0000447 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000448 $$ = new t_enum_value($2, $4);
449 if ($1 != NULL) {
450 $$->set_doc($1);
451 }
Mark Sleed0767c52007-07-27 22:14:41 +0000452 if (g_parse_mode == PROGRAM) {
453 g_scope->add_constant($2, new t_const(g_type_i32, $2, new t_const_value($4)));
454 if (g_parent_scope != NULL) {
455 g_parent_scope->add_constant(g_parent_prefix + $2, new t_const(g_type_i32, $2, new t_const_value($4)));
456 }
457 }
Mark Slee31985722006-05-24 21:45:31 +0000458 }
459|
David Reisscbd4bac2007-08-14 17:12:33 +0000460 CaptureDocText tok_identifier CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000461 {
Mark Slee30152872006-11-28 01:24:07 +0000462 pdebug("EnumDef -> tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000463 $$ = new t_enum_value($2);
464 if ($1 != NULL) {
465 $$->set_doc($1);
466 }
Mark Slee30152872006-11-28 01:24:07 +0000467 }
468
Mark Slee6a47fed2007-02-07 02:40:59 +0000469Senum:
David Reisscdffe262007-08-14 17:12:31 +0000470 tok_senum tok_identifier '{' SenumDefList '}'
Mark Slee6a47fed2007-02-07 02:40:59 +0000471 {
472 pdebug("Senum -> tok_senum tok_identifier { SenumDefList }");
David Reisscdffe262007-08-14 17:12:31 +0000473 $$ = new t_typedef(g_program, $4, $2);
Mark Slee6a47fed2007-02-07 02:40:59 +0000474 }
475
476SenumDefList:
477 SenumDefList SenumDef
478 {
479 pdebug("SenumDefList -> SenumDefList SenumDef");
480 $$ = $1;
481 $$->add_string_enum_val($2);
482 }
483|
484 {
485 pdebug("SenumDefList -> ");
486 $$ = new t_base_type("string", t_base_type::TYPE_STRING);
487 $$->set_string_enum(true);
488 }
489
490SenumDef:
491 tok_literal CommaOrSemicolonOptional
492 {
493 pdebug("SenumDef -> tok_literal");
494 $$ = $1;
495 }
496
Mark Slee30152872006-11-28 01:24:07 +0000497Const:
498 tok_const FieldType tok_identifier '=' ConstValue CommaOrSemicolonOptional
499 {
500 pdebug("Const -> tok_const FieldType tok_identifier = ConstValue");
Mark Sleeaa7671d2006-11-29 03:19:31 +0000501 if (g_parse_mode == PROGRAM) {
502 $$ = new t_const($2, $3, $5);
503 validate_const_type($$);
Mark Sleed0767c52007-07-27 22:14:41 +0000504
505 g_scope->add_constant($3, $$);
506 if (g_parent_scope != NULL) {
507 g_parent_scope->add_constant(g_parent_prefix + $3, $$);
508 }
509
Mark Sleeaa7671d2006-11-29 03:19:31 +0000510 } else {
511 $$ = NULL;
512 }
Mark Slee30152872006-11-28 01:24:07 +0000513 }
514
515ConstValue:
516 tok_int_constant
517 {
518 pdebug("ConstValue => tok_int_constant");
519 $$ = new t_const_value();
520 $$->set_integer($1);
521 }
522| tok_dub_constant
523 {
524 pdebug("ConstValue => tok_dub_constant");
525 $$ = new t_const_value();
526 $$->set_double($1);
527 }
528| tok_literal
529 {
530 pdebug("ConstValue => tok_literal");
Mark Sleed0767c52007-07-27 22:14:41 +0000531 $$ = new t_const_value($1);
Mark Slee30152872006-11-28 01:24:07 +0000532 }
Mark Slee67fc6342006-11-29 03:37:04 +0000533| tok_identifier
534 {
535 pdebug("ConstValue => tok_identifier");
Mark Sleed0767c52007-07-27 22:14:41 +0000536 t_const* constant = g_scope->get_constant($1);
537 if (constant != NULL) {
538 $$ = constant->get_value();
539 } else {
540 if (g_parse_mode == PROGRAM) {
541 pwarning(1, "Constant strings should be quoted: %s\n", $1);
542 }
543 $$ = new t_const_value($1);
544 }
Mark Slee67fc6342006-11-29 03:37:04 +0000545 }
Mark Slee30152872006-11-28 01:24:07 +0000546| ConstList
547 {
548 pdebug("ConstValue => ConstList");
549 $$ = $1;
550 }
551| ConstMap
552 {
553 pdebug("ConstValue => ConstMap");
Mark Slee27ed6ec2007-08-16 01:26:31 +0000554 $$ = $1;
Mark Slee30152872006-11-28 01:24:07 +0000555 }
556
557ConstList:
558 '[' ConstListContents ']'
559 {
560 pdebug("ConstList => [ ConstListContents ]");
561 $$ = $2;
562 }
563
564ConstListContents:
565 ConstListContents ConstValue CommaOrSemicolonOptional
566 {
567 pdebug("ConstListContents => ConstListContents ConstValue CommaOrSemicolonOptional");
568 $$ = $1;
569 $$->add_list($2);
570 }
571|
572 {
573 pdebug("ConstListContents =>");
574 $$ = new t_const_value();
575 $$->set_list();
576 }
577
578ConstMap:
579 '{' ConstMapContents '}'
580 {
581 pdebug("ConstMap => { ConstMapContents }");
582 $$ = $2;
583 }
584
585ConstMapContents:
586 ConstMapContents ConstValue ':' ConstValue CommaOrSemicolonOptional
587 {
588 pdebug("ConstMapContents => ConstMapContents ConstValue CommaOrSemicolonOptional");
589 $$ = $1;
590 $$->add_map($2, $4);
591 }
592|
593 {
594 pdebug("ConstMapContents =>");
595 $$ = new t_const_value();
596 $$->set_map();
Mark Slee31985722006-05-24 21:45:31 +0000597 }
598
599Struct:
David Reisscdffe262007-08-14 17:12:31 +0000600 tok_struct tok_identifier XsdAll '{' FieldList '}'
Mark Slee31985722006-05-24 21:45:31 +0000601 {
602 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
David Reisscdffe262007-08-14 17:12:31 +0000603 $5->set_name($2);
604 $5->set_xsd_all($3);
605 $$ = $5;
Mark Slee9cb7c612006-09-01 22:17:45 +0000606 y_field_val = -1;
607 }
608
Mark Slee36bfa2e2007-01-19 20:09:51 +0000609XsdAll:
Mark Slee782abbb2007-01-19 00:17:02 +0000610 tok_xsd_all
611 {
612 $$ = true;
613 }
614|
615 {
616 $$ = false;
617 }
618
Mark Slee36bfa2e2007-01-19 20:09:51 +0000619XsdOptional:
620 tok_xsd_optional
621 {
622 $$ = true;
623 }
624|
625 {
626 $$ = false;
627 }
628
Mark Slee7df0e2a2007-02-06 21:03:18 +0000629XsdNillable:
630 tok_xsd_nillable
631 {
632 $$ = true;
633 }
634|
635 {
636 $$ = false;
637 }
638
Mark Slee21135c32007-02-05 21:52:08 +0000639XsdAttributes:
Mark Slee748d83f2007-02-07 01:20:08 +0000640 tok_xsd_attrs '{' FieldList '}'
Mark Slee21135c32007-02-05 21:52:08 +0000641 {
Mark Slee748d83f2007-02-07 01:20:08 +0000642 $$ = $3;
Mark Slee21135c32007-02-05 21:52:08 +0000643 }
644|
645 {
646 $$ = NULL;
647 }
648
Mark Slee9cb7c612006-09-01 22:17:45 +0000649Xception:
650 tok_xception tok_identifier '{' FieldList '}'
651 {
652 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
653 $4->set_name($2);
654 $4->set_xception(true);
655 $$ = $4;
656 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000657 }
658
659Service:
David Reisscdffe262007-08-14 17:12:31 +0000660 tok_service tok_identifier Extends '{' FunctionList '}'
Mark Slee31985722006-05-24 21:45:31 +0000661 {
662 pdebug("Service -> tok_service tok_identifier { FunctionList }");
David Reisscdffe262007-08-14 17:12:31 +0000663 $$ = $5;
664 $$->set_name($2);
665 $$->set_extends($3);
Mark Sleef0712dc2006-10-25 19:03:57 +0000666 }
667
Mark Slee36bfa2e2007-01-19 20:09:51 +0000668Extends:
Mark Sleef0712dc2006-10-25 19:03:57 +0000669 tok_extends tok_identifier
670 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000671 pdebug("Extends -> tok_extends tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000672 $$ = NULL;
673 if (g_parse_mode == PROGRAM) {
674 $$ = g_scope->get_service($2);
675 if ($$ == NULL) {
676 yyerror("Service \"%s\" has not been defined.", $2);
677 exit(1);
678 }
679 }
680 }
681|
682 {
683 $$ = NULL;
Mark Slee31985722006-05-24 21:45:31 +0000684 }
685
686FunctionList:
Mark Slee207cb462006-11-02 18:43:12 +0000687 FunctionList Function
Mark Slee31985722006-05-24 21:45:31 +0000688 {
689 pdebug("FunctionList -> FunctionList Function");
690 $$ = $1;
691 $1->add_function($2);
692 }
693|
694 {
695 pdebug("FunctionList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000696 $$ = new t_service(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000697 }
698
699Function:
David Reisscbd4bac2007-08-14 17:12:33 +0000700 CaptureDocText Async FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000701 {
ccheeverf53b5cf2007-02-05 20:33:11 +0000702 $6->set_name(std::string($4) + "_args");
703 $$ = new t_function($3, $4, $6, $8, $2);
704 if ($1 != NULL) {
705 $$->set_doc($1);
706 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000707 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000708 }
709
Mark Slee36bfa2e2007-01-19 20:09:51 +0000710Async:
Mark Slee52f643d2006-08-09 00:03:43 +0000711 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000712 {
Mark Slee52f643d2006-08-09 00:03:43 +0000713 $$ = true;
714 }
715|
716 {
717 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000718 }
719
Mark Slee36bfa2e2007-01-19 20:09:51 +0000720Throws:
Mark Slee9cb7c612006-09-01 22:17:45 +0000721 tok_throws '(' FieldList ')'
722 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000723 pdebug("Throws -> tok_throws ( FieldList )");
Mark Slee9cb7c612006-09-01 22:17:45 +0000724 $$ = $3;
725 }
726|
727 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000728 $$ = new t_struct(g_program);
Mark Slee9cb7c612006-09-01 22:17:45 +0000729 }
730
Mark Slee31985722006-05-24 21:45:31 +0000731FieldList:
Mark Slee207cb462006-11-02 18:43:12 +0000732 FieldList Field
Mark Slee31985722006-05-24 21:45:31 +0000733 {
734 pdebug("FieldList -> FieldList , Field");
735 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000736 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000737 }
738|
739 {
740 pdebug("FieldList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000741 $$ = new t_struct(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000742 }
743
744Field:
David Reiss8320a922007-08-14 19:59:26 +0000745 CaptureDocText FieldIdentifier FieldRequiredness FieldType tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000746 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000747 pdebug("tok_int_constant : Field -> FieldType tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000748 if ($2 < 0) {
David Reiss8320a922007-08-14 19:59:26 +0000749 pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $5);
Mark Slee31985722006-05-24 21:45:31 +0000750 }
David Reiss8320a922007-08-14 19:59:26 +0000751 $$ = new t_field($4, $5, $2);
752 $$->set_req($3);
753 if ($6 != NULL) {
754 validate_field_value($$, $6);
755 $$->set_value($6);
Mark Slee7ff32452007-02-01 05:26:18 +0000756 }
David Reiss8320a922007-08-14 19:59:26 +0000757 $$->set_xsd_optional($7);
758 $$->set_xsd_nillable($8);
ccheeverf53b5cf2007-02-05 20:33:11 +0000759 if ($1 != NULL) {
760 $$->set_doc($1);
761 }
David Reiss8320a922007-08-14 19:59:26 +0000762 if ($9 != NULL) {
763 $$->set_xsd_attrs($9);
Mark Slee21135c32007-02-05 21:52:08 +0000764 }
Mark Slee31985722006-05-24 21:45:31 +0000765 }
Mark Slee7ff32452007-02-01 05:26:18 +0000766
767FieldIdentifier:
768 tok_int_constant ':'
Mark Slee31985722006-05-24 21:45:31 +0000769 {
Mark Slee7ff32452007-02-01 05:26:18 +0000770 if ($1 <= 0) {
771 pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n", $1);
772 $1 = y_field_val--;
Mark Sleef0712dc2006-10-25 19:03:57 +0000773 }
Mark Slee7ff32452007-02-01 05:26:18 +0000774 $$ = $1;
775 }
776|
777 {
778 $$ = y_field_val--;
779 }
780
David Reiss8320a922007-08-14 19:59:26 +0000781FieldRequiredness:
782 tok_required
783 {
784 $$ = t_field::REQUIRED;
785 }
786| tok_optional
787 {
788 $$ = t_field::OPTIONAL;
789 }
790|
791 {
792 $$ = t_field::OPT_IN_REQ_OUT;
793 }
794
Mark Slee7ff32452007-02-01 05:26:18 +0000795FieldValue:
796 '=' ConstValue
797 {
Mark Slee27ed6ec2007-08-16 01:26:31 +0000798 if (g_parse_mode == PROGRAM) {
Mark Slee7ff32452007-02-01 05:26:18 +0000799 $$ = $2;
800 } else {
801 $$ = NULL;
802 }
803 }
804|
805 {
806 $$ = NULL;
Mark Sleef0712dc2006-10-25 19:03:57 +0000807 }
Mark Slee31985722006-05-24 21:45:31 +0000808
809DefinitionType:
810 BaseType
811 {
812 pdebug("DefinitionType -> BaseType");
813 $$ = $1;
814 }
Mark Sleee8540632006-05-30 09:24:40 +0000815| ContainerType
816 {
817 pdebug("DefinitionType -> ContainerType");
818 $$ = $1;
819 }
Mark Slee31985722006-05-24 21:45:31 +0000820
821FunctionType:
822 FieldType
823 {
Mark Sleee8540632006-05-30 09:24:40 +0000824 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000825 $$ = $1;
826 }
827| tok_void
828 {
Mark Sleee8540632006-05-30 09:24:40 +0000829 pdebug("FunctionType -> tok_void");
Mark Sleef0712dc2006-10-25 19:03:57 +0000830 $$ = g_type_void;
Mark Slee31985722006-05-24 21:45:31 +0000831 }
832
833FieldType:
834 tok_identifier
835 {
Mark Sleee8540632006-05-30 09:24:40 +0000836 pdebug("FieldType -> tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000837 if (g_parse_mode == INCLUDES) {
838 // Ignore identifiers in include mode
839 $$ = NULL;
840 } else {
841 // Lookup the identifier in the current scope
842 $$ = g_scope->get_type($1);
843 if ($$ == NULL) {
844 yyerror("Type \"%s\" has not been defined.", $1);
845 exit(1);
846 }
Mark Sleee8540632006-05-30 09:24:40 +0000847 }
Mark Slee31985722006-05-24 21:45:31 +0000848 }
849| BaseType
850 {
Mark Sleee8540632006-05-30 09:24:40 +0000851 pdebug("FieldType -> BaseType");
852 $$ = $1;
853 }
854| ContainerType
855 {
856 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000857 $$ = $1;
858 }
859
860BaseType:
861 tok_string
862 {
863 pdebug("BaseType -> tok_string");
Mark Sleef0712dc2006-10-25 19:03:57 +0000864 $$ = g_type_string;
Mark Slee31985722006-05-24 21:45:31 +0000865 }
Mark Slee8d725a22007-04-13 01:57:12 +0000866| tok_binary
867 {
868 pdebug("BaseType -> tok_binary");
869 $$ = g_type_binary;
870 }
Mark Sleeb6200d82007-01-19 19:14:36 +0000871| tok_slist
872 {
873 pdebug("BaseType -> tok_slist");
874 $$ = g_type_slist;
875 }
Mark Slee78f58e22006-09-02 04:17:07 +0000876| tok_bool
877 {
878 pdebug("BaseType -> tok_bool");
Mark Sleef0712dc2006-10-25 19:03:57 +0000879 $$ = g_type_bool;
Mark Slee78f58e22006-09-02 04:17:07 +0000880 }
Mark Slee31985722006-05-24 21:45:31 +0000881| tok_byte
882 {
883 pdebug("BaseType -> tok_byte");
Mark Sleef0712dc2006-10-25 19:03:57 +0000884 $$ = g_type_byte;
Mark Slee31985722006-05-24 21:45:31 +0000885 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000886| tok_i16
887 {
888 pdebug("BaseType -> tok_i16");
Mark Sleef0712dc2006-10-25 19:03:57 +0000889 $$ = g_type_i16;
Mark Slee9cb7c612006-09-01 22:17:45 +0000890 }
Mark Slee31985722006-05-24 21:45:31 +0000891| tok_i32
892 {
893 pdebug("BaseType -> tok_i32");
Mark Sleef0712dc2006-10-25 19:03:57 +0000894 $$ = g_type_i32;
Mark Slee31985722006-05-24 21:45:31 +0000895 }
Mark Slee31985722006-05-24 21:45:31 +0000896| tok_i64
897 {
898 pdebug("BaseType -> tok_i64");
Mark Sleef0712dc2006-10-25 19:03:57 +0000899 $$ = g_type_i64;
Mark Slee31985722006-05-24 21:45:31 +0000900 }
Mark Sleec98d0502006-09-06 02:42:25 +0000901| tok_double
902 {
903 pdebug("BaseType -> tok_double");
Mark Sleef0712dc2006-10-25 19:03:57 +0000904 $$ = g_type_double;
Mark Sleec98d0502006-09-06 02:42:25 +0000905 }
Mark Slee31985722006-05-24 21:45:31 +0000906
Mark Sleee8540632006-05-30 09:24:40 +0000907ContainerType:
908 MapType
909 {
910 pdebug("ContainerType -> MapType");
911 $$ = $1;
912 }
913| SetType
914 {
915 pdebug("ContainerType -> SetType");
916 $$ = $1;
917 }
918| ListType
919 {
920 pdebug("ContainerType -> ListType");
921 $$ = $1;
922 }
923
924MapType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000925 tok_map CppType '<' FieldType ',' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000926 {
927 pdebug("MapType -> tok_map <FieldType, FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000928 $$ = new t_map($4, $6);
929 if ($2 != NULL) {
930 ((t_container*)$$)->set_cpp_name(std::string($2));
931 }
Mark Sleee8540632006-05-30 09:24:40 +0000932 }
933
934SetType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000935 tok_set CppType '<' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000936 {
937 pdebug("SetType -> tok_set<FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000938 $$ = new t_set($4);
939 if ($2 != NULL) {
940 ((t_container*)$$)->set_cpp_name(std::string($2));
941 }
Mark Sleee8540632006-05-30 09:24:40 +0000942 }
943
944ListType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000945 tok_list '<' FieldType '>' CppType
Mark Sleee8540632006-05-30 09:24:40 +0000946 {
947 pdebug("ListType -> tok_list<FieldType>");
Mark Sleef0712dc2006-10-25 19:03:57 +0000948 $$ = new t_list($3);
949 if ($5 != NULL) {
950 ((t_container*)$$)->set_cpp_name(std::string($5));
Mark Slee4f8da1d2006-10-12 02:47:27 +0000951 }
952 }
953
Mark Slee36bfa2e2007-01-19 20:09:51 +0000954CppType:
Mark Sleeafc76542007-02-09 21:55:44 +0000955 tok_cpp_type tok_literal
Mark Slee4f8da1d2006-10-12 02:47:27 +0000956 {
Mark Sleeafc76542007-02-09 21:55:44 +0000957 $$ = $2;
Mark Slee4f8da1d2006-10-12 02:47:27 +0000958 }
959|
960 {
961 $$ = NULL;
Mark Sleee8540632006-05-30 09:24:40 +0000962 }
963
Mark Slee31985722006-05-24 21:45:31 +0000964%%