blob: e159ef05316aec93515c9790c0d0457d61d4c48d [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
Mark Sleef0712dc2006-10-25 19:03:57 +000078%token tok_java_package
Mark Slee782abbb2007-01-19 00:17:02 +000079%token tok_xsd_all
Mark Slee36bfa2e2007-01-19 20:09:51 +000080%token tok_xsd_optional
Mark Slee7df0e2a2007-02-06 21:03:18 +000081%token tok_xsd_nillable
Mark Slee0d9199e2007-01-31 02:08:30 +000082%token tok_xsd_namespace
Mark Slee21135c32007-02-05 21:52:08 +000083%token tok_xsd_attrs
Mark Slee58dfb4f2007-07-06 02:45:25 +000084%token tok_ruby_namespace
Mark Slee9cb7c612006-09-01 22:17:45 +000085
Mark Sleef5377b32006-10-10 01:42:59 +000086/**
87 * Base datatype keywords
88 */
89%token tok_void
Mark Slee78f58e22006-09-02 04:17:07 +000090%token tok_bool
Mark Slee31985722006-05-24 21:45:31 +000091%token tok_byte
92%token tok_string
Mark Slee8d725a22007-04-13 01:57:12 +000093%token tok_binary
Mark Sleeb6200d82007-01-19 19:14:36 +000094%token tok_slist
Mark Slee6a47fed2007-02-07 02:40:59 +000095%token tok_senum
Mark Slee9cb7c612006-09-01 22:17:45 +000096%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000097%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +000098%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +000099%token tok_double
Mark Slee31985722006-05-24 21:45:31 +0000100
Mark Sleef5377b32006-10-10 01:42:59 +0000101/**
102 * Complex type keywords
103 */
Mark Slee31985722006-05-24 21:45:31 +0000104%token tok_map
105%token tok_list
106%token tok_set
107
Mark Sleef5377b32006-10-10 01:42:59 +0000108/**
109 * Function modifiers
110 */
Mark Slee31985722006-05-24 21:45:31 +0000111%token tok_async
112
Mark Sleef5377b32006-10-10 01:42:59 +0000113/**
114 * Thrift language keywords
115 */
Mark Slee31985722006-05-24 21:45:31 +0000116%token tok_typedef
117%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000118%token tok_xception
119%token tok_throws
Mark Sleef0712dc2006-10-25 19:03:57 +0000120%token tok_extends
Mark Slee31985722006-05-24 21:45:31 +0000121%token tok_service
122%token tok_enum
Mark Slee30152872006-11-28 01:24:07 +0000123%token tok_const
David Reiss8320a922007-08-14 19:59:26 +0000124%token tok_required
125%token tok_optional
Mark Slee31985722006-05-24 21:45:31 +0000126
Mark Sleef5377b32006-10-10 01:42:59 +0000127/**
128 * Grammar nodes
129 */
130
Mark Slee31985722006-05-24 21:45:31 +0000131%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +0000132%type<ttype> ContainerType
133%type<ttype> MapType
134%type<ttype> SetType
135%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +0000136
David Reisscdffe262007-08-14 17:12:31 +0000137%type<tdoc> Definition
Mark Sleef0712dc2006-10-25 19:03:57 +0000138%type<ttype> TypeDefinition
139
Mark Slee31985722006-05-24 21:45:31 +0000140%type<ttypedef> Typedef
141%type<ttype> DefinitionType
142
143%type<tfield> Field
Mark Slee7ff32452007-02-01 05:26:18 +0000144%type<iconst> FieldIdentifier
David Reiss8320a922007-08-14 19:59:26 +0000145%type<ereq> FieldRequiredness
Mark Slee31985722006-05-24 21:45:31 +0000146%type<ttype> FieldType
Mark Slee7ff32452007-02-01 05:26:18 +0000147%type<tconstv> FieldValue
Mark Sleee8540632006-05-30 09:24:40 +0000148%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +0000149
150%type<tenum> Enum
151%type<tenum> EnumDefList
Mark Slee30152872006-11-28 01:24:07 +0000152%type<tenumv> EnumDef
153
Mark Slee6a47fed2007-02-07 02:40:59 +0000154%type<ttypedef> Senum
155%type<tbase> SenumDefList
156%type<id> SenumDef
157
Mark Slee30152872006-11-28 01:24:07 +0000158%type<tconst> Const
159%type<tconstv> ConstValue
160%type<tconstv> ConstList
161%type<tconstv> ConstListContents
162%type<tconstv> ConstMap
163%type<tconstv> ConstMapContents
Mark Slee31985722006-05-24 21:45:31 +0000164
165%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000166%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +0000167%type<tservice> Service
168
169%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +0000170%type<ttype> FunctionType
171%type<tservice> FunctionList
172
Mark Slee36bfa2e2007-01-19 20:09:51 +0000173%type<tstruct> Throws
174%type<tservice> Extends
175%type<tbool> Async
176%type<tbool> XsdAll
177%type<tbool> XsdOptional
Mark Slee7df0e2a2007-02-06 21:03:18 +0000178%type<tbool> XsdNillable
Mark Slee748d83f2007-02-07 01:20:08 +0000179%type<tstruct> XsdAttributes
Mark Slee36bfa2e2007-01-19 20:09:51 +0000180%type<id> CppType
Mark Slee52f643d2006-08-09 00:03:43 +0000181
David Reisscbd4bac2007-08-14 17:12:33 +0000182%type<dtext> CaptureDocText
ccheeverf53b5cf2007-02-05 20:33:11 +0000183
Mark Slee31985722006-05-24 21:45:31 +0000184%%
185
Mark Sleef5377b32006-10-10 01:42:59 +0000186/**
187 * Thrift Grammar Implementation.
188 *
189 * For the most part this source file works its way top down from what you
190 * might expect to find in a typical .thrift file, i.e. type definitions and
191 * namespaces up top followed by service definitions using those types.
192 */
Mark Slee31985722006-05-24 21:45:31 +0000193
194Program:
David Reisscbd4bac2007-08-14 17:12:33 +0000195 HeaderList DefinitionList
Mark Sleef0712dc2006-10-25 19:03:57 +0000196 {
197 pdebug("Program -> Headers DefinitionList");
David Reisscbd4bac2007-08-14 17:12:33 +0000198 /*
199 TODO(dreiss): Decide whether full-program doctext is worth the trouble.
David Reissc2532a92007-07-30 23:46:11 +0000200 if ($1 != NULL) {
201 g_program->set_doc($1);
202 }
David Reisscbd4bac2007-08-14 17:12:33 +0000203 */
204 clear_doctext();
Mark Sleef0712dc2006-10-25 19:03:57 +0000205 }
206
David Reisscbd4bac2007-08-14 17:12:33 +0000207CaptureDocText:
208 {
209 if (g_parse_mode == PROGRAM) {
210 $$ = g_doctext;
211 g_doctext = NULL;
212 }
213 else {
214 $$ = NULL;
215 }
216 }
217
218/* TODO(dreiss): Try to DestroyDocText in all sorts or random places. */
219DestroyDocText:
220 {
221 if (g_parse_mode == PROGRAM) {
222 clear_doctext();
223 }
224 }
225
226/* We have to DestroyDocText here, otherwise it catches the doctext
227 on the first real element. */
Mark Sleef0712dc2006-10-25 19:03:57 +0000228HeaderList:
David Reisscbd4bac2007-08-14 17:12:33 +0000229 HeaderList DestroyDocText Header
Mark Sleef0712dc2006-10-25 19:03:57 +0000230 {
231 pdebug("HeaderList -> HeaderList Header");
232 }
233|
234 {
235 pdebug("HeaderList -> ");
236 }
237
238Header:
239 Include
240 {
241 pdebug("Header -> Include");
242 }
243| tok_namespace tok_identifier
244 {
245 pwarning(1, "'namespace' is deprecated. Use 'cpp_namespace' and/or 'java_package' instead");
246 if (g_parse_mode == PROGRAM) {
247 g_program->set_cpp_namespace($2);
248 g_program->set_java_package($2);
249 }
250 }
251| tok_cpp_namespace tok_identifier
252 {
253 pdebug("Header -> tok_cpp_namespace tok_identifier");
254 if (g_parse_mode == PROGRAM) {
255 g_program->set_cpp_namespace($2);
256 }
257 }
258| tok_cpp_include tok_literal
259 {
260 pdebug("Header -> tok_cpp_include tok_literal");
261 if (g_parse_mode == PROGRAM) {
262 g_program->add_cpp_include($2);
263 }
264 }
Mark Sleee888b372007-01-12 01:06:24 +0000265| tok_php_namespace tok_identifier
266 {
267 pdebug("Header -> tok_php_namespace tok_identifier");
268 if (g_parse_mode == PROGRAM) {
269 g_program->set_php_namespace($2);
270 }
271 }
Mark Slee58dfb4f2007-07-06 02:45:25 +0000272| tok_ruby_namespace tok_identifier
273 {
274 pdebug("Header -> tok_ruby_namespace tok_identifier");
275 if (g_parse_mode == PROGRAM) {
276 g_program->set_ruby_namespace($2);
277 }
278 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000279| tok_java_package tok_identifier
280 {
281 pdebug("Header -> tok_java_package tok_identifier");
282 if (g_parse_mode == PROGRAM) {
283 g_program->set_java_package($2);
284 }
285 }
Mark Slee0d9199e2007-01-31 02:08:30 +0000286| tok_xsd_namespace tok_literal
287 {
288 pdebug("Header -> tok_xsd_namespace tok_literal");
289 if (g_parse_mode == PROGRAM) {
290 g_program->set_xsd_namespace($2);
291 }
292 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000293
294Include:
295 tok_include tok_literal
296 {
297 pdebug("Include -> tok_include tok_literal");
298 if (g_parse_mode == INCLUDES) {
299 std::string path = include_file(std::string($2));
300 if (!path.empty()) {
301 g_program->add_include(path);
302 }
303 }
304 }
Mark Slee31985722006-05-24 21:45:31 +0000305
306DefinitionList:
David Reisscbd4bac2007-08-14 17:12:33 +0000307 DefinitionList CaptureDocText Definition
Mark Slee31985722006-05-24 21:45:31 +0000308 {
309 pdebug("DefinitionList -> DefinitionList Definition");
David Reisscdffe262007-08-14 17:12:31 +0000310 if ($2 != NULL && $3 != NULL) {
311 $3->set_doc($2);
312 }
Mark Slee31985722006-05-24 21:45:31 +0000313 }
314|
315 {
316 pdebug("DefinitionList -> ");
317 }
318
319Definition:
Mark Slee30152872006-11-28 01:24:07 +0000320 Const
321 {
322 pdebug("Definition -> Const");
323 if (g_parse_mode == PROGRAM) {
324 g_program->add_const($1);
325 }
David Reisscdffe262007-08-14 17:12:31 +0000326 $$ = $1;
Mark Slee30152872006-11-28 01:24:07 +0000327 }
328| TypeDefinition
Mark Slee9cb7c612006-09-01 22:17:45 +0000329 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000330 pdebug("Definition -> TypeDefinition");
331 if (g_parse_mode == PROGRAM) {
332 g_scope->add_type($1->get_name(), $1);
333 if (g_parent_scope != NULL) {
334 g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
335 }
336 }
David Reisscdffe262007-08-14 17:12:31 +0000337 $$ = $1;
Mark Slee9cb7c612006-09-01 22:17:45 +0000338 }
Mark Slee31985722006-05-24 21:45:31 +0000339| Service
340 {
341 pdebug("Definition -> Service");
Mark Sleef0712dc2006-10-25 19:03:57 +0000342 if (g_parse_mode == PROGRAM) {
343 g_scope->add_service($1->get_name(), $1);
344 if (g_parent_scope != NULL) {
345 g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
346 }
347 g_program->add_service($1);
348 }
David Reisscdffe262007-08-14 17:12:31 +0000349 $$ = $1;
Mark Slee9cb7c612006-09-01 22:17:45 +0000350 }
351
Mark Sleef0712dc2006-10-25 19:03:57 +0000352TypeDefinition:
353 Typedef
Mark Slee9cb7c612006-09-01 22:17:45 +0000354 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000355 pdebug("TypeDefinition -> Typedef");
356 if (g_parse_mode == PROGRAM) {
357 g_program->add_typedef($1);
358 }
359 }
360| Enum
361 {
362 pdebug("TypeDefinition -> Enum");
363 if (g_parse_mode == PROGRAM) {
364 g_program->add_enum($1);
365 }
366 }
Mark Slee6a47fed2007-02-07 02:40:59 +0000367| Senum
368 {
369 pdebug("TypeDefinition -> Senum");
370 if (g_parse_mode == PROGRAM) {
371 g_program->add_typedef($1);
372 }
373 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000374| Struct
375 {
376 pdebug("TypeDefinition -> Struct");
377 if (g_parse_mode == PROGRAM) {
378 g_program->add_struct($1);
379 }
380 }
381| Xception
382 {
383 pdebug("TypeDefinition -> Xception");
384 if (g_parse_mode == PROGRAM) {
385 g_program->add_xception($1);
386 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000387 }
Mark Slee31985722006-05-24 21:45:31 +0000388
389Typedef:
David Reisscdffe262007-08-14 17:12:31 +0000390 tok_typedef DefinitionType tok_identifier
Mark Slee31985722006-05-24 21:45:31 +0000391 {
392 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
David Reisscdffe262007-08-14 17:12:31 +0000393 t_typedef *td = new t_typedef(g_program, $2, $3);
Mark Slee31985722006-05-24 21:45:31 +0000394 $$ = td;
395 }
396
Mark Slee6a47fed2007-02-07 02:40:59 +0000397CommaOrSemicolonOptional:
398 ','
399 {}
400| ';'
401 {}
402|
403 {}
ccheeverf53b5cf2007-02-05 20:33:11 +0000404
Mark Slee31985722006-05-24 21:45:31 +0000405Enum:
David Reisscdffe262007-08-14 17:12:31 +0000406 tok_enum tok_identifier '{' EnumDefList '}'
Mark Slee31985722006-05-24 21:45:31 +0000407 {
408 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
David Reisscdffe262007-08-14 17:12:31 +0000409 $$ = $4;
410 $$->set_name($2);
Mark Slee31985722006-05-24 21:45:31 +0000411 }
412
413EnumDefList:
Mark Slee207cb462006-11-02 18:43:12 +0000414 EnumDefList EnumDef
Mark Slee31985722006-05-24 21:45:31 +0000415 {
416 pdebug("EnumDefList -> EnumDefList EnumDef");
417 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000418 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000419 }
420|
421 {
422 pdebug("EnumDefList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000423 $$ = new t_enum(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000424 }
425
426EnumDef:
David Reisscbd4bac2007-08-14 17:12:33 +0000427 CaptureDocText tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000428 {
Mark Slee30152872006-11-28 01:24:07 +0000429 pdebug("EnumDef -> tok_identifier = tok_int_constant");
ccheeverf53b5cf2007-02-05 20:33:11 +0000430 if ($4 < 0) {
431 pwarning(1, "Negative value supplied for enum %s.\n", $2);
Mark Slee31985722006-05-24 21:45:31 +0000432 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000433 $$ = new t_enum_value($2, $4);
434 if ($1 != NULL) {
435 $$->set_doc($1);
436 }
Mark Sleed0767c52007-07-27 22:14:41 +0000437 if (g_parse_mode == PROGRAM) {
438 g_scope->add_constant($2, new t_const(g_type_i32, $2, new t_const_value($4)));
439 if (g_parent_scope != NULL) {
440 g_parent_scope->add_constant(g_parent_prefix + $2, new t_const(g_type_i32, $2, new t_const_value($4)));
441 }
442 }
Mark Slee31985722006-05-24 21:45:31 +0000443 }
444|
David Reisscbd4bac2007-08-14 17:12:33 +0000445 CaptureDocText tok_identifier CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000446 {
Mark Slee30152872006-11-28 01:24:07 +0000447 pdebug("EnumDef -> tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000448 $$ = new t_enum_value($2);
449 if ($1 != NULL) {
450 $$->set_doc($1);
451 }
Mark Slee30152872006-11-28 01:24:07 +0000452 }
453
Mark Slee6a47fed2007-02-07 02:40:59 +0000454Senum:
David Reisscdffe262007-08-14 17:12:31 +0000455 tok_senum tok_identifier '{' SenumDefList '}'
Mark Slee6a47fed2007-02-07 02:40:59 +0000456 {
457 pdebug("Senum -> tok_senum tok_identifier { SenumDefList }");
David Reisscdffe262007-08-14 17:12:31 +0000458 $$ = new t_typedef(g_program, $4, $2);
Mark Slee6a47fed2007-02-07 02:40:59 +0000459 }
460
461SenumDefList:
462 SenumDefList SenumDef
463 {
464 pdebug("SenumDefList -> SenumDefList SenumDef");
465 $$ = $1;
466 $$->add_string_enum_val($2);
467 }
468|
469 {
470 pdebug("SenumDefList -> ");
471 $$ = new t_base_type("string", t_base_type::TYPE_STRING);
472 $$->set_string_enum(true);
473 }
474
475SenumDef:
476 tok_literal CommaOrSemicolonOptional
477 {
478 pdebug("SenumDef -> tok_literal");
479 $$ = $1;
480 }
481
Mark Slee30152872006-11-28 01:24:07 +0000482Const:
483 tok_const FieldType tok_identifier '=' ConstValue CommaOrSemicolonOptional
484 {
485 pdebug("Const -> tok_const FieldType tok_identifier = ConstValue");
Mark Sleeaa7671d2006-11-29 03:19:31 +0000486 if (g_parse_mode == PROGRAM) {
487 $$ = new t_const($2, $3, $5);
488 validate_const_type($$);
Mark Sleed0767c52007-07-27 22:14:41 +0000489
490 g_scope->add_constant($3, $$);
491 if (g_parent_scope != NULL) {
492 g_parent_scope->add_constant(g_parent_prefix + $3, $$);
493 }
494
Mark Sleeaa7671d2006-11-29 03:19:31 +0000495 } else {
496 $$ = NULL;
497 }
Mark Slee30152872006-11-28 01:24:07 +0000498 }
499
500ConstValue:
501 tok_int_constant
502 {
503 pdebug("ConstValue => tok_int_constant");
504 $$ = new t_const_value();
505 $$->set_integer($1);
506 }
507| tok_dub_constant
508 {
509 pdebug("ConstValue => tok_dub_constant");
510 $$ = new t_const_value();
511 $$->set_double($1);
512 }
513| tok_literal
514 {
515 pdebug("ConstValue => tok_literal");
Mark Sleed0767c52007-07-27 22:14:41 +0000516 $$ = new t_const_value($1);
Mark Slee30152872006-11-28 01:24:07 +0000517 }
Mark Slee67fc6342006-11-29 03:37:04 +0000518| tok_identifier
519 {
520 pdebug("ConstValue => tok_identifier");
Mark Sleed0767c52007-07-27 22:14:41 +0000521 t_const* constant = g_scope->get_constant($1);
522 if (constant != NULL) {
523 $$ = constant->get_value();
524 } else {
525 if (g_parse_mode == PROGRAM) {
526 pwarning(1, "Constant strings should be quoted: %s\n", $1);
527 }
528 $$ = new t_const_value($1);
529 }
Mark Slee67fc6342006-11-29 03:37:04 +0000530 }
Mark Slee30152872006-11-28 01:24:07 +0000531| ConstList
532 {
533 pdebug("ConstValue => ConstList");
534 $$ = $1;
535 }
536| ConstMap
537 {
538 pdebug("ConstValue => ConstMap");
539 $$ = $1;
540 }
541
542ConstList:
543 '[' ConstListContents ']'
544 {
545 pdebug("ConstList => [ ConstListContents ]");
546 $$ = $2;
547 }
548
549ConstListContents:
550 ConstListContents ConstValue CommaOrSemicolonOptional
551 {
552 pdebug("ConstListContents => ConstListContents ConstValue CommaOrSemicolonOptional");
553 $$ = $1;
554 $$->add_list($2);
555 }
556|
557 {
558 pdebug("ConstListContents =>");
559 $$ = new t_const_value();
560 $$->set_list();
561 }
562
563ConstMap:
564 '{' ConstMapContents '}'
565 {
566 pdebug("ConstMap => { ConstMapContents }");
567 $$ = $2;
568 }
569
570ConstMapContents:
571 ConstMapContents ConstValue ':' ConstValue CommaOrSemicolonOptional
572 {
573 pdebug("ConstMapContents => ConstMapContents ConstValue CommaOrSemicolonOptional");
574 $$ = $1;
575 $$->add_map($2, $4);
576 }
577|
578 {
579 pdebug("ConstMapContents =>");
580 $$ = new t_const_value();
581 $$->set_map();
Mark Slee31985722006-05-24 21:45:31 +0000582 }
583
584Struct:
David Reisscdffe262007-08-14 17:12:31 +0000585 tok_struct tok_identifier XsdAll '{' FieldList '}'
Mark Slee31985722006-05-24 21:45:31 +0000586 {
587 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
David Reisscdffe262007-08-14 17:12:31 +0000588 $5->set_name($2);
589 $5->set_xsd_all($3);
590 $$ = $5;
Mark Slee9cb7c612006-09-01 22:17:45 +0000591 y_field_val = -1;
592 }
593
Mark Slee36bfa2e2007-01-19 20:09:51 +0000594XsdAll:
Mark Slee782abbb2007-01-19 00:17:02 +0000595 tok_xsd_all
596 {
597 $$ = true;
598 }
599|
600 {
601 $$ = false;
602 }
603
Mark Slee36bfa2e2007-01-19 20:09:51 +0000604XsdOptional:
605 tok_xsd_optional
606 {
607 $$ = true;
608 }
609|
610 {
611 $$ = false;
612 }
613
Mark Slee7df0e2a2007-02-06 21:03:18 +0000614XsdNillable:
615 tok_xsd_nillable
616 {
617 $$ = true;
618 }
619|
620 {
621 $$ = false;
622 }
623
Mark Slee21135c32007-02-05 21:52:08 +0000624XsdAttributes:
Mark Slee748d83f2007-02-07 01:20:08 +0000625 tok_xsd_attrs '{' FieldList '}'
Mark Slee21135c32007-02-05 21:52:08 +0000626 {
Mark Slee748d83f2007-02-07 01:20:08 +0000627 $$ = $3;
Mark Slee21135c32007-02-05 21:52:08 +0000628 }
629|
630 {
631 $$ = NULL;
632 }
633
Mark Slee9cb7c612006-09-01 22:17:45 +0000634Xception:
635 tok_xception tok_identifier '{' FieldList '}'
636 {
637 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
638 $4->set_name($2);
639 $4->set_xception(true);
640 $$ = $4;
641 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000642 }
643
644Service:
David Reisscdffe262007-08-14 17:12:31 +0000645 tok_service tok_identifier Extends '{' FunctionList '}'
Mark Slee31985722006-05-24 21:45:31 +0000646 {
647 pdebug("Service -> tok_service tok_identifier { FunctionList }");
David Reisscdffe262007-08-14 17:12:31 +0000648 $$ = $5;
649 $$->set_name($2);
650 $$->set_extends($3);
Mark Sleef0712dc2006-10-25 19:03:57 +0000651 }
652
Mark Slee36bfa2e2007-01-19 20:09:51 +0000653Extends:
Mark Sleef0712dc2006-10-25 19:03:57 +0000654 tok_extends tok_identifier
655 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000656 pdebug("Extends -> tok_extends tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000657 $$ = NULL;
658 if (g_parse_mode == PROGRAM) {
659 $$ = g_scope->get_service($2);
660 if ($$ == NULL) {
661 yyerror("Service \"%s\" has not been defined.", $2);
662 exit(1);
663 }
664 }
665 }
666|
667 {
668 $$ = NULL;
Mark Slee31985722006-05-24 21:45:31 +0000669 }
670
671FunctionList:
Mark Slee207cb462006-11-02 18:43:12 +0000672 FunctionList Function
Mark Slee31985722006-05-24 21:45:31 +0000673 {
674 pdebug("FunctionList -> FunctionList Function");
675 $$ = $1;
676 $1->add_function($2);
677 }
678|
679 {
680 pdebug("FunctionList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000681 $$ = new t_service(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000682 }
683
684Function:
David Reisscbd4bac2007-08-14 17:12:33 +0000685 CaptureDocText Async FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000686 {
ccheeverf53b5cf2007-02-05 20:33:11 +0000687 $6->set_name(std::string($4) + "_args");
688 $$ = new t_function($3, $4, $6, $8, $2);
689 if ($1 != NULL) {
690 $$->set_doc($1);
691 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000692 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000693 }
694
Mark Slee36bfa2e2007-01-19 20:09:51 +0000695Async:
Mark Slee52f643d2006-08-09 00:03:43 +0000696 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000697 {
Mark Slee52f643d2006-08-09 00:03:43 +0000698 $$ = true;
699 }
700|
701 {
702 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000703 }
704
Mark Slee36bfa2e2007-01-19 20:09:51 +0000705Throws:
Mark Slee9cb7c612006-09-01 22:17:45 +0000706 tok_throws '(' FieldList ')'
707 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000708 pdebug("Throws -> tok_throws ( FieldList )");
Mark Slee9cb7c612006-09-01 22:17:45 +0000709 $$ = $3;
710 }
711|
712 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000713 $$ = new t_struct(g_program);
Mark Slee9cb7c612006-09-01 22:17:45 +0000714 }
715
Mark Slee31985722006-05-24 21:45:31 +0000716FieldList:
Mark Slee207cb462006-11-02 18:43:12 +0000717 FieldList Field
Mark Slee31985722006-05-24 21:45:31 +0000718 {
719 pdebug("FieldList -> FieldList , Field");
720 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000721 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000722 }
723|
724 {
725 pdebug("FieldList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000726 $$ = new t_struct(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000727 }
728
729Field:
David Reiss8320a922007-08-14 19:59:26 +0000730 CaptureDocText FieldIdentifier FieldRequiredness FieldType tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000731 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000732 pdebug("tok_int_constant : Field -> FieldType tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000733 if ($2 < 0) {
David Reiss8320a922007-08-14 19:59:26 +0000734 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 +0000735 }
David Reiss8320a922007-08-14 19:59:26 +0000736 $$ = new t_field($4, $5, $2);
737 $$->set_req($3);
738 if ($6 != NULL) {
739 validate_field_value($$, $6);
740 $$->set_value($6);
Mark Slee7ff32452007-02-01 05:26:18 +0000741 }
David Reiss8320a922007-08-14 19:59:26 +0000742 $$->set_xsd_optional($7);
743 $$->set_xsd_nillable($8);
ccheeverf53b5cf2007-02-05 20:33:11 +0000744 if ($1 != NULL) {
745 $$->set_doc($1);
746 }
David Reiss8320a922007-08-14 19:59:26 +0000747 if ($9 != NULL) {
748 $$->set_xsd_attrs($9);
Mark Slee21135c32007-02-05 21:52:08 +0000749 }
Mark Slee31985722006-05-24 21:45:31 +0000750 }
Mark Slee7ff32452007-02-01 05:26:18 +0000751
752FieldIdentifier:
753 tok_int_constant ':'
Mark Slee31985722006-05-24 21:45:31 +0000754 {
Mark Slee7ff32452007-02-01 05:26:18 +0000755 if ($1 <= 0) {
756 pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n", $1);
757 $1 = y_field_val--;
Mark Sleef0712dc2006-10-25 19:03:57 +0000758 }
Mark Slee7ff32452007-02-01 05:26:18 +0000759 $$ = $1;
760 }
761|
762 {
763 $$ = y_field_val--;
764 }
765
David Reiss8320a922007-08-14 19:59:26 +0000766FieldRequiredness:
767 tok_required
768 {
769 $$ = t_field::REQUIRED;
770 }
771| tok_optional
772 {
773 $$ = t_field::OPTIONAL;
774 }
775|
776 {
777 $$ = t_field::OPT_IN_REQ_OUT;
778 }
779
Mark Slee7ff32452007-02-01 05:26:18 +0000780FieldValue:
781 '=' ConstValue
782 {
783 if (g_parse_mode == PROGRAM) {
784 $$ = $2;
785 } else {
786 $$ = NULL;
787 }
788 }
789|
790 {
791 $$ = NULL;
Mark Sleef0712dc2006-10-25 19:03:57 +0000792 }
Mark Slee31985722006-05-24 21:45:31 +0000793
794DefinitionType:
795 BaseType
796 {
797 pdebug("DefinitionType -> BaseType");
798 $$ = $1;
799 }
Mark Sleee8540632006-05-30 09:24:40 +0000800| ContainerType
801 {
802 pdebug("DefinitionType -> ContainerType");
803 $$ = $1;
804 }
Mark Slee31985722006-05-24 21:45:31 +0000805
806FunctionType:
807 FieldType
808 {
Mark Sleee8540632006-05-30 09:24:40 +0000809 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000810 $$ = $1;
811 }
812| tok_void
813 {
Mark Sleee8540632006-05-30 09:24:40 +0000814 pdebug("FunctionType -> tok_void");
Mark Sleef0712dc2006-10-25 19:03:57 +0000815 $$ = g_type_void;
Mark Slee31985722006-05-24 21:45:31 +0000816 }
817
818FieldType:
819 tok_identifier
820 {
Mark Sleee8540632006-05-30 09:24:40 +0000821 pdebug("FieldType -> tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000822 if (g_parse_mode == INCLUDES) {
823 // Ignore identifiers in include mode
824 $$ = NULL;
825 } else {
826 // Lookup the identifier in the current scope
827 $$ = g_scope->get_type($1);
828 if ($$ == NULL) {
829 yyerror("Type \"%s\" has not been defined.", $1);
830 exit(1);
831 }
Mark Sleee8540632006-05-30 09:24:40 +0000832 }
Mark Slee31985722006-05-24 21:45:31 +0000833 }
834| BaseType
835 {
Mark Sleee8540632006-05-30 09:24:40 +0000836 pdebug("FieldType -> BaseType");
837 $$ = $1;
838 }
839| ContainerType
840 {
841 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000842 $$ = $1;
843 }
844
845BaseType:
846 tok_string
847 {
848 pdebug("BaseType -> tok_string");
Mark Sleef0712dc2006-10-25 19:03:57 +0000849 $$ = g_type_string;
Mark Slee31985722006-05-24 21:45:31 +0000850 }
Mark Slee8d725a22007-04-13 01:57:12 +0000851| tok_binary
852 {
853 pdebug("BaseType -> tok_binary");
854 $$ = g_type_binary;
855 }
Mark Sleeb6200d82007-01-19 19:14:36 +0000856| tok_slist
857 {
858 pdebug("BaseType -> tok_slist");
859 $$ = g_type_slist;
860 }
Mark Slee78f58e22006-09-02 04:17:07 +0000861| tok_bool
862 {
863 pdebug("BaseType -> tok_bool");
Mark Sleef0712dc2006-10-25 19:03:57 +0000864 $$ = g_type_bool;
Mark Slee78f58e22006-09-02 04:17:07 +0000865 }
Mark Slee31985722006-05-24 21:45:31 +0000866| tok_byte
867 {
868 pdebug("BaseType -> tok_byte");
Mark Sleef0712dc2006-10-25 19:03:57 +0000869 $$ = g_type_byte;
Mark Slee31985722006-05-24 21:45:31 +0000870 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000871| tok_i16
872 {
873 pdebug("BaseType -> tok_i16");
Mark Sleef0712dc2006-10-25 19:03:57 +0000874 $$ = g_type_i16;
Mark Slee9cb7c612006-09-01 22:17:45 +0000875 }
Mark Slee31985722006-05-24 21:45:31 +0000876| tok_i32
877 {
878 pdebug("BaseType -> tok_i32");
Mark Sleef0712dc2006-10-25 19:03:57 +0000879 $$ = g_type_i32;
Mark Slee31985722006-05-24 21:45:31 +0000880 }
Mark Slee31985722006-05-24 21:45:31 +0000881| tok_i64
882 {
883 pdebug("BaseType -> tok_i64");
Mark Sleef0712dc2006-10-25 19:03:57 +0000884 $$ = g_type_i64;
Mark Slee31985722006-05-24 21:45:31 +0000885 }
Mark Sleec98d0502006-09-06 02:42:25 +0000886| tok_double
887 {
888 pdebug("BaseType -> tok_double");
Mark Sleef0712dc2006-10-25 19:03:57 +0000889 $$ = g_type_double;
Mark Sleec98d0502006-09-06 02:42:25 +0000890 }
Mark Slee31985722006-05-24 21:45:31 +0000891
Mark Sleee8540632006-05-30 09:24:40 +0000892ContainerType:
893 MapType
894 {
895 pdebug("ContainerType -> MapType");
896 $$ = $1;
897 }
898| SetType
899 {
900 pdebug("ContainerType -> SetType");
901 $$ = $1;
902 }
903| ListType
904 {
905 pdebug("ContainerType -> ListType");
906 $$ = $1;
907 }
908
909MapType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000910 tok_map CppType '<' FieldType ',' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000911 {
912 pdebug("MapType -> tok_map <FieldType, FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000913 $$ = new t_map($4, $6);
914 if ($2 != NULL) {
915 ((t_container*)$$)->set_cpp_name(std::string($2));
916 }
Mark Sleee8540632006-05-30 09:24:40 +0000917 }
918
919SetType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000920 tok_set CppType '<' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000921 {
922 pdebug("SetType -> tok_set<FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000923 $$ = new t_set($4);
924 if ($2 != NULL) {
925 ((t_container*)$$)->set_cpp_name(std::string($2));
926 }
Mark Sleee8540632006-05-30 09:24:40 +0000927 }
928
929ListType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000930 tok_list '<' FieldType '>' CppType
Mark Sleee8540632006-05-30 09:24:40 +0000931 {
932 pdebug("ListType -> tok_list<FieldType>");
Mark Sleef0712dc2006-10-25 19:03:57 +0000933 $$ = new t_list($3);
934 if ($5 != NULL) {
935 ((t_container*)$$)->set_cpp_name(std::string($5));
Mark Slee4f8da1d2006-10-12 02:47:27 +0000936 }
937 }
938
Mark Slee36bfa2e2007-01-19 20:09:51 +0000939CppType:
Mark Sleeafc76542007-02-09 21:55:44 +0000940 tok_cpp_type tok_literal
Mark Slee4f8da1d2006-10-12 02:47:27 +0000941 {
Mark Sleeafc76542007-02-09 21:55:44 +0000942 $$ = $2;
Mark Slee4f8da1d2006-10-12 02:47:27 +0000943 }
944|
945 {
946 $$ = NULL;
Mark Sleee8540632006-05-30 09:24:40 +0000947 }
948
Mark Slee31985722006-05-24 21:45:31 +0000949%%