blob: 1ad0c35fc4d139c59c61e1ccac9e9cad8fbc70a5 [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;
40 t_type* ttype;
Mark Slee6a47fed2007-02-07 02:40:59 +000041 t_base_type* tbase;
Mark Slee30152872006-11-28 01:24:07 +000042 t_typedef* ttypedef;
43 t_enum* tenum;
44 t_enum_value* tenumv;
45 t_const* tconst;
46 t_const_value* tconstv;
47 t_struct* tstruct;
48 t_service* tservice;
49 t_function* tfunction;
50 t_field* tfield;
ccheeverf53b5cf2007-02-05 20:33:11 +000051 char* tdoc;
Mark Slee31985722006-05-24 21:45:31 +000052}
53
Mark Sleef5377b32006-10-10 01:42:59 +000054/**
55 * Strings identifier
56 */
Mark Slee31985722006-05-24 21:45:31 +000057%token<id> tok_identifier
Mark Sleef0712dc2006-10-25 19:03:57 +000058%token<id> tok_literal
ccheeverf53b5cf2007-02-05 20:33:11 +000059%token<tdoc> tok_doctext
Mark Sleef5377b32006-10-10 01:42:59 +000060
61/**
Mark Slee30152872006-11-28 01:24:07 +000062 * Constant values
Mark Sleef5377b32006-10-10 01:42:59 +000063 */
Mark Slee31985722006-05-24 21:45:31 +000064%token<iconst> tok_int_constant
Mark Slee30152872006-11-28 01:24:07 +000065%token<dconst> tok_dub_constant
Mark Slee31985722006-05-24 21:45:31 +000066
Mark Sleef5377b32006-10-10 01:42:59 +000067/**
Mark Sleef0712dc2006-10-25 19:03:57 +000068 * Header keywoards
Mark Sleef5377b32006-10-10 01:42:59 +000069 */
Mark Sleef0712dc2006-10-25 19:03:57 +000070%token tok_include
Mark Slee9cb7c612006-09-01 22:17:45 +000071%token tok_namespace
Mark Sleef0712dc2006-10-25 19:03:57 +000072%token tok_cpp_namespace
73%token tok_cpp_include
74%token tok_cpp_type
Mark Sleee888b372007-01-12 01:06:24 +000075%token tok_php_namespace
Mark Sleef0712dc2006-10-25 19:03:57 +000076%token tok_java_package
Mark Slee782abbb2007-01-19 00:17:02 +000077%token tok_xsd_all
Mark Slee36bfa2e2007-01-19 20:09:51 +000078%token tok_xsd_optional
Mark Slee7df0e2a2007-02-06 21:03:18 +000079%token tok_xsd_nillable
Mark Slee0d9199e2007-01-31 02:08:30 +000080%token tok_xsd_namespace
Mark Slee21135c32007-02-05 21:52:08 +000081%token tok_xsd_attrs
Mark Slee58dfb4f2007-07-06 02:45:25 +000082%token tok_ruby_namespace
Mark Slee9cb7c612006-09-01 22:17:45 +000083
Mark Sleef5377b32006-10-10 01:42:59 +000084/**
85 * Base datatype keywords
86 */
87%token tok_void
Mark Slee78f58e22006-09-02 04:17:07 +000088%token tok_bool
Mark Slee31985722006-05-24 21:45:31 +000089%token tok_byte
90%token tok_string
Mark Slee8d725a22007-04-13 01:57:12 +000091%token tok_binary
Mark Sleeb6200d82007-01-19 19:14:36 +000092%token tok_slist
Mark Slee6a47fed2007-02-07 02:40:59 +000093%token tok_senum
Mark Slee9cb7c612006-09-01 22:17:45 +000094%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000095%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +000096%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +000097%token tok_double
Mark Slee31985722006-05-24 21:45:31 +000098
Mark Sleef5377b32006-10-10 01:42:59 +000099/**
100 * Complex type keywords
101 */
Mark Slee31985722006-05-24 21:45:31 +0000102%token tok_map
103%token tok_list
104%token tok_set
105
Mark Sleef5377b32006-10-10 01:42:59 +0000106/**
107 * Function modifiers
108 */
Mark Slee31985722006-05-24 21:45:31 +0000109%token tok_async
110
Mark Sleef5377b32006-10-10 01:42:59 +0000111/**
112 * Thrift language keywords
113 */
Mark Slee31985722006-05-24 21:45:31 +0000114%token tok_typedef
115%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000116%token tok_xception
117%token tok_throws
Mark Sleef0712dc2006-10-25 19:03:57 +0000118%token tok_extends
Mark Slee31985722006-05-24 21:45:31 +0000119%token tok_service
120%token tok_enum
Mark Slee30152872006-11-28 01:24:07 +0000121%token tok_const
Mark Slee31985722006-05-24 21:45:31 +0000122
Mark Sleef5377b32006-10-10 01:42:59 +0000123/**
124 * Grammar nodes
125 */
126
Mark Slee31985722006-05-24 21:45:31 +0000127%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +0000128%type<ttype> ContainerType
129%type<ttype> MapType
130%type<ttype> SetType
131%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +0000132
Mark Sleef0712dc2006-10-25 19:03:57 +0000133%type<ttype> TypeDefinition
134
Mark Slee31985722006-05-24 21:45:31 +0000135%type<ttypedef> Typedef
136%type<ttype> DefinitionType
137
138%type<tfield> Field
Mark Slee7ff32452007-02-01 05:26:18 +0000139%type<iconst> FieldIdentifier
Mark Slee31985722006-05-24 21:45:31 +0000140%type<ttype> FieldType
Mark Slee7ff32452007-02-01 05:26:18 +0000141%type<tconstv> FieldValue
Mark Sleee8540632006-05-30 09:24:40 +0000142%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +0000143
144%type<tenum> Enum
145%type<tenum> EnumDefList
Mark Slee30152872006-11-28 01:24:07 +0000146%type<tenumv> EnumDef
147
Mark Slee6a47fed2007-02-07 02:40:59 +0000148%type<ttypedef> Senum
149%type<tbase> SenumDefList
150%type<id> SenumDef
151
Mark Slee30152872006-11-28 01:24:07 +0000152%type<tconst> Const
153%type<tconstv> ConstValue
154%type<tconstv> ConstList
155%type<tconstv> ConstListContents
156%type<tconstv> ConstMap
157%type<tconstv> ConstMapContents
Mark Slee31985722006-05-24 21:45:31 +0000158
159%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000160%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +0000161%type<tservice> Service
162
163%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +0000164%type<ttype> FunctionType
165%type<tservice> FunctionList
166
Mark Slee36bfa2e2007-01-19 20:09:51 +0000167%type<tstruct> Throws
168%type<tservice> Extends
169%type<tbool> Async
170%type<tbool> XsdAll
171%type<tbool> XsdOptional
Mark Slee7df0e2a2007-02-06 21:03:18 +0000172%type<tbool> XsdNillable
Mark Slee748d83f2007-02-07 01:20:08 +0000173%type<tstruct> XsdAttributes
Mark Slee36bfa2e2007-01-19 20:09:51 +0000174%type<id> CppType
Mark Slee52f643d2006-08-09 00:03:43 +0000175
ccheeverf53b5cf2007-02-05 20:33:11 +0000176%type<tdoc> DocTextOptional
177
Mark Slee31985722006-05-24 21:45:31 +0000178%%
179
Mark Sleef5377b32006-10-10 01:42:59 +0000180/**
181 * Thrift Grammar Implementation.
182 *
183 * For the most part this source file works its way top down from what you
184 * might expect to find in a typical .thrift file, i.e. type definitions and
185 * namespaces up top followed by service definitions using those types.
186 */
Mark Slee31985722006-05-24 21:45:31 +0000187
188Program:
David Reissc2532a92007-07-30 23:46:11 +0000189 DocTextOptional HeaderList DefinitionList
Mark Sleef0712dc2006-10-25 19:03:57 +0000190 {
191 pdebug("Program -> Headers DefinitionList");
David Reissc2532a92007-07-30 23:46:11 +0000192 if ($1 != NULL) {
193 g_program->set_doc($1);
194 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000195 }
196
197HeaderList:
198 HeaderList Header
199 {
200 pdebug("HeaderList -> HeaderList Header");
201 }
202|
203 {
204 pdebug("HeaderList -> ");
205 }
206
207Header:
208 Include
209 {
210 pdebug("Header -> Include");
211 }
212| tok_namespace tok_identifier
213 {
214 pwarning(1, "'namespace' is deprecated. Use 'cpp_namespace' and/or 'java_package' instead");
215 if (g_parse_mode == PROGRAM) {
216 g_program->set_cpp_namespace($2);
217 g_program->set_java_package($2);
218 }
219 }
220| tok_cpp_namespace tok_identifier
221 {
222 pdebug("Header -> tok_cpp_namespace tok_identifier");
223 if (g_parse_mode == PROGRAM) {
224 g_program->set_cpp_namespace($2);
225 }
226 }
227| tok_cpp_include tok_literal
228 {
229 pdebug("Header -> tok_cpp_include tok_literal");
230 if (g_parse_mode == PROGRAM) {
231 g_program->add_cpp_include($2);
232 }
233 }
Mark Sleee888b372007-01-12 01:06:24 +0000234| tok_php_namespace tok_identifier
235 {
236 pdebug("Header -> tok_php_namespace tok_identifier");
237 if (g_parse_mode == PROGRAM) {
238 g_program->set_php_namespace($2);
239 }
240 }
Mark Slee58dfb4f2007-07-06 02:45:25 +0000241| tok_ruby_namespace tok_identifier
242 {
243 pdebug("Header -> tok_ruby_namespace tok_identifier");
244 if (g_parse_mode == PROGRAM) {
245 g_program->set_ruby_namespace($2);
246 }
247 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000248| tok_java_package tok_identifier
249 {
250 pdebug("Header -> tok_java_package tok_identifier");
251 if (g_parse_mode == PROGRAM) {
252 g_program->set_java_package($2);
253 }
254 }
Mark Slee0d9199e2007-01-31 02:08:30 +0000255| tok_xsd_namespace tok_literal
256 {
257 pdebug("Header -> tok_xsd_namespace tok_literal");
258 if (g_parse_mode == PROGRAM) {
259 g_program->set_xsd_namespace($2);
260 }
261 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000262
263Include:
264 tok_include tok_literal
265 {
266 pdebug("Include -> tok_include tok_literal");
267 if (g_parse_mode == INCLUDES) {
268 std::string path = include_file(std::string($2));
269 if (!path.empty()) {
270 g_program->add_include(path);
271 }
272 }
273 }
Mark Slee31985722006-05-24 21:45:31 +0000274
275DefinitionList:
276 DefinitionList Definition
277 {
278 pdebug("DefinitionList -> DefinitionList Definition");
279 }
280|
281 {
282 pdebug("DefinitionList -> ");
283 }
284
285Definition:
Mark Slee30152872006-11-28 01:24:07 +0000286 Const
287 {
288 pdebug("Definition -> Const");
289 if (g_parse_mode == PROGRAM) {
290 g_program->add_const($1);
291 }
292 }
293| TypeDefinition
Mark Slee9cb7c612006-09-01 22:17:45 +0000294 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000295 pdebug("Definition -> TypeDefinition");
296 if (g_parse_mode == PROGRAM) {
297 g_scope->add_type($1->get_name(), $1);
298 if (g_parent_scope != NULL) {
299 g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
300 }
301 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000302 }
Mark Slee31985722006-05-24 21:45:31 +0000303| Service
304 {
305 pdebug("Definition -> Service");
Mark Sleef0712dc2006-10-25 19:03:57 +0000306 if (g_parse_mode == PROGRAM) {
307 g_scope->add_service($1->get_name(), $1);
308 if (g_parent_scope != NULL) {
309 g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
310 }
311 g_program->add_service($1);
312 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000313 }
314
Mark Sleef0712dc2006-10-25 19:03:57 +0000315TypeDefinition:
316 Typedef
Mark Slee9cb7c612006-09-01 22:17:45 +0000317 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000318 pdebug("TypeDefinition -> Typedef");
319 if (g_parse_mode == PROGRAM) {
320 g_program->add_typedef($1);
321 }
322 }
323| Enum
324 {
325 pdebug("TypeDefinition -> Enum");
326 if (g_parse_mode == PROGRAM) {
327 g_program->add_enum($1);
328 }
329 }
Mark Slee6a47fed2007-02-07 02:40:59 +0000330| Senum
331 {
332 pdebug("TypeDefinition -> Senum");
333 if (g_parse_mode == PROGRAM) {
334 g_program->add_typedef($1);
335 }
336 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000337| Struct
338 {
339 pdebug("TypeDefinition -> Struct");
340 if (g_parse_mode == PROGRAM) {
341 g_program->add_struct($1);
342 }
343 }
344| Xception
345 {
346 pdebug("TypeDefinition -> Xception");
347 if (g_parse_mode == PROGRAM) {
348 g_program->add_xception($1);
349 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000350 }
Mark Slee31985722006-05-24 21:45:31 +0000351
352Typedef:
ccheeverf53b5cf2007-02-05 20:33:11 +0000353 DocTextOptional tok_typedef DefinitionType tok_identifier
Mark Slee31985722006-05-24 21:45:31 +0000354 {
355 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000356 t_typedef *td = new t_typedef(g_program, $3, $4);
Mark Slee31985722006-05-24 21:45:31 +0000357 $$ = td;
ccheeverf53b5cf2007-02-05 20:33:11 +0000358 if ($1 != NULL) {
359 td->set_doc($1);
360 }
Mark Slee31985722006-05-24 21:45:31 +0000361 }
362
ccheeverf53b5cf2007-02-05 20:33:11 +0000363DocTextOptional:
364 tok_doctext
365 {
366 pdebug("DocTextOptional -> tok_doctext");
David Reiss1ac05802007-07-30 22:00:27 +0000367 $$ = clean_up_doctext($1);
ccheeverf53b5cf2007-02-05 20:33:11 +0000368 }
369|
370 {
371 $$ = NULL;
372 }
373
Mark Slee6a47fed2007-02-07 02:40:59 +0000374CommaOrSemicolonOptional:
375 ','
376 {}
377| ';'
378 {}
379|
380 {}
ccheeverf53b5cf2007-02-05 20:33:11 +0000381
Mark Slee31985722006-05-24 21:45:31 +0000382Enum:
ccheeverf53b5cf2007-02-05 20:33:11 +0000383 DocTextOptional tok_enum tok_identifier '{' EnumDefList '}'
Mark Slee31985722006-05-24 21:45:31 +0000384 {
385 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
ccheeverf53b5cf2007-02-05 20:33:11 +0000386 $$ = $5;
387 $$->set_name($3);
388 if ($1 != NULL) {
389 $$->set_doc($1);
390 }
Mark Slee31985722006-05-24 21:45:31 +0000391 }
392
393EnumDefList:
Mark Slee207cb462006-11-02 18:43:12 +0000394 EnumDefList EnumDef
Mark Slee31985722006-05-24 21:45:31 +0000395 {
396 pdebug("EnumDefList -> EnumDefList EnumDef");
397 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000398 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000399 }
400|
401 {
402 pdebug("EnumDefList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000403 $$ = new t_enum(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000404 }
405
406EnumDef:
ccheeverf53b5cf2007-02-05 20:33:11 +0000407 DocTextOptional tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000408 {
Mark Slee30152872006-11-28 01:24:07 +0000409 pdebug("EnumDef -> tok_identifier = tok_int_constant");
ccheeverf53b5cf2007-02-05 20:33:11 +0000410 if ($4 < 0) {
411 pwarning(1, "Negative value supplied for enum %s.\n", $2);
Mark Slee31985722006-05-24 21:45:31 +0000412 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000413 $$ = new t_enum_value($2, $4);
414 if ($1 != NULL) {
415 $$->set_doc($1);
416 }
Mark Sleed0767c52007-07-27 22:14:41 +0000417 if (g_parse_mode == PROGRAM) {
418 g_scope->add_constant($2, new t_const(g_type_i32, $2, new t_const_value($4)));
419 if (g_parent_scope != NULL) {
420 g_parent_scope->add_constant(g_parent_prefix + $2, new t_const(g_type_i32, $2, new t_const_value($4)));
421 }
422 }
Mark Slee31985722006-05-24 21:45:31 +0000423 }
424|
ccheeverf53b5cf2007-02-05 20:33:11 +0000425 DocTextOptional tok_identifier CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000426 {
Mark Slee30152872006-11-28 01:24:07 +0000427 pdebug("EnumDef -> tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000428 $$ = new t_enum_value($2);
429 if ($1 != NULL) {
430 $$->set_doc($1);
431 }
Mark Slee30152872006-11-28 01:24:07 +0000432 }
433
Mark Slee6a47fed2007-02-07 02:40:59 +0000434Senum:
435 DocTextOptional tok_senum tok_identifier '{' SenumDefList '}'
436 {
437 pdebug("Senum -> tok_senum tok_identifier { SenumDefList }");
438 $$ = new t_typedef(g_program, $5, $3);
439 if ($1 != NULL) {
440 $$->set_doc($1);
441 }
442 }
443
444SenumDefList:
445 SenumDefList SenumDef
446 {
447 pdebug("SenumDefList -> SenumDefList SenumDef");
448 $$ = $1;
449 $$->add_string_enum_val($2);
450 }
451|
452 {
453 pdebug("SenumDefList -> ");
454 $$ = new t_base_type("string", t_base_type::TYPE_STRING);
455 $$->set_string_enum(true);
456 }
457
458SenumDef:
459 tok_literal CommaOrSemicolonOptional
460 {
461 pdebug("SenumDef -> tok_literal");
462 $$ = $1;
463 }
464
Mark Slee30152872006-11-28 01:24:07 +0000465Const:
466 tok_const FieldType tok_identifier '=' ConstValue CommaOrSemicolonOptional
467 {
468 pdebug("Const -> tok_const FieldType tok_identifier = ConstValue");
Mark Sleeaa7671d2006-11-29 03:19:31 +0000469 if (g_parse_mode == PROGRAM) {
470 $$ = new t_const($2, $3, $5);
471 validate_const_type($$);
Mark Sleed0767c52007-07-27 22:14:41 +0000472
473 g_scope->add_constant($3, $$);
474 if (g_parent_scope != NULL) {
475 g_parent_scope->add_constant(g_parent_prefix + $3, $$);
476 }
477
Mark Sleeaa7671d2006-11-29 03:19:31 +0000478 } else {
479 $$ = NULL;
480 }
Mark Slee30152872006-11-28 01:24:07 +0000481 }
482
483ConstValue:
484 tok_int_constant
485 {
486 pdebug("ConstValue => tok_int_constant");
487 $$ = new t_const_value();
488 $$->set_integer($1);
489 }
490| tok_dub_constant
491 {
492 pdebug("ConstValue => tok_dub_constant");
493 $$ = new t_const_value();
494 $$->set_double($1);
495 }
496| tok_literal
497 {
498 pdebug("ConstValue => tok_literal");
Mark Sleed0767c52007-07-27 22:14:41 +0000499 $$ = new t_const_value($1);
Mark Slee30152872006-11-28 01:24:07 +0000500 }
Mark Slee67fc6342006-11-29 03:37:04 +0000501| tok_identifier
502 {
503 pdebug("ConstValue => tok_identifier");
Mark Sleed0767c52007-07-27 22:14:41 +0000504 t_const* constant = g_scope->get_constant($1);
505 if (constant != NULL) {
506 $$ = constant->get_value();
507 } else {
508 if (g_parse_mode == PROGRAM) {
509 pwarning(1, "Constant strings should be quoted: %s\n", $1);
510 }
511 $$ = new t_const_value($1);
512 }
Mark Slee67fc6342006-11-29 03:37:04 +0000513 }
Mark Slee30152872006-11-28 01:24:07 +0000514| ConstList
515 {
516 pdebug("ConstValue => ConstList");
517 $$ = $1;
518 }
519| ConstMap
520 {
521 pdebug("ConstValue => ConstMap");
522 $$ = $1;
523 }
524
525ConstList:
526 '[' ConstListContents ']'
527 {
528 pdebug("ConstList => [ ConstListContents ]");
529 $$ = $2;
530 }
531
532ConstListContents:
533 ConstListContents ConstValue CommaOrSemicolonOptional
534 {
535 pdebug("ConstListContents => ConstListContents ConstValue CommaOrSemicolonOptional");
536 $$ = $1;
537 $$->add_list($2);
538 }
539|
540 {
541 pdebug("ConstListContents =>");
542 $$ = new t_const_value();
543 $$->set_list();
544 }
545
546ConstMap:
547 '{' ConstMapContents '}'
548 {
549 pdebug("ConstMap => { ConstMapContents }");
550 $$ = $2;
551 }
552
553ConstMapContents:
554 ConstMapContents ConstValue ':' ConstValue CommaOrSemicolonOptional
555 {
556 pdebug("ConstMapContents => ConstMapContents ConstValue CommaOrSemicolonOptional");
557 $$ = $1;
558 $$->add_map($2, $4);
559 }
560|
561 {
562 pdebug("ConstMapContents =>");
563 $$ = new t_const_value();
564 $$->set_map();
Mark Slee31985722006-05-24 21:45:31 +0000565 }
566
567Struct:
ccheeverf53b5cf2007-02-05 20:33:11 +0000568 DocTextOptional tok_struct tok_identifier XsdAll '{' FieldList '}'
Mark Slee31985722006-05-24 21:45:31 +0000569 {
570 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
ccheeverf53b5cf2007-02-05 20:33:11 +0000571 $6->set_name($3);
572 if ($1 != NULL) {
573 $6->set_doc($1);
574 }
575 $6->set_xsd_all($4);
576 $$ = $6;
Mark Slee9cb7c612006-09-01 22:17:45 +0000577 y_field_val = -1;
578 }
579
Mark Slee36bfa2e2007-01-19 20:09:51 +0000580XsdAll:
Mark Slee782abbb2007-01-19 00:17:02 +0000581 tok_xsd_all
582 {
583 $$ = true;
584 }
585|
586 {
587 $$ = false;
588 }
589
Mark Slee36bfa2e2007-01-19 20:09:51 +0000590XsdOptional:
591 tok_xsd_optional
592 {
593 $$ = true;
594 }
595|
596 {
597 $$ = false;
598 }
599
Mark Slee7df0e2a2007-02-06 21:03:18 +0000600XsdNillable:
601 tok_xsd_nillable
602 {
603 $$ = true;
604 }
605|
606 {
607 $$ = false;
608 }
609
Mark Slee21135c32007-02-05 21:52:08 +0000610XsdAttributes:
Mark Slee748d83f2007-02-07 01:20:08 +0000611 tok_xsd_attrs '{' FieldList '}'
Mark Slee21135c32007-02-05 21:52:08 +0000612 {
Mark Slee748d83f2007-02-07 01:20:08 +0000613 $$ = $3;
Mark Slee21135c32007-02-05 21:52:08 +0000614 }
615|
616 {
617 $$ = NULL;
618 }
619
Mark Slee9cb7c612006-09-01 22:17:45 +0000620Xception:
621 tok_xception tok_identifier '{' FieldList '}'
622 {
623 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
624 $4->set_name($2);
625 $4->set_xception(true);
626 $$ = $4;
627 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000628 }
629
630Service:
ccheeverf53b5cf2007-02-05 20:33:11 +0000631 DocTextOptional tok_service tok_identifier Extends '{' FunctionList '}'
Mark Slee31985722006-05-24 21:45:31 +0000632 {
633 pdebug("Service -> tok_service tok_identifier { FunctionList }");
ccheeverf53b5cf2007-02-05 20:33:11 +0000634 $$ = $6;
635 $$->set_name($3);
636 $$->set_extends($4);
637 if ($1 != NULL) {
638 $$->set_doc($1);
639 }
Mark Sleef0712dc2006-10-25 19:03:57 +0000640 }
641
Mark Slee36bfa2e2007-01-19 20:09:51 +0000642Extends:
Mark Sleef0712dc2006-10-25 19:03:57 +0000643 tok_extends tok_identifier
644 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000645 pdebug("Extends -> tok_extends tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000646 $$ = NULL;
647 if (g_parse_mode == PROGRAM) {
648 $$ = g_scope->get_service($2);
649 if ($$ == NULL) {
650 yyerror("Service \"%s\" has not been defined.", $2);
651 exit(1);
652 }
653 }
654 }
655|
656 {
657 $$ = NULL;
Mark Slee31985722006-05-24 21:45:31 +0000658 }
659
660FunctionList:
Mark Slee207cb462006-11-02 18:43:12 +0000661 FunctionList Function
Mark Slee31985722006-05-24 21:45:31 +0000662 {
663 pdebug("FunctionList -> FunctionList Function");
664 $$ = $1;
665 $1->add_function($2);
666 }
667|
668 {
669 pdebug("FunctionList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000670 $$ = new t_service(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000671 }
672
673Function:
ccheeverf53b5cf2007-02-05 20:33:11 +0000674 DocTextOptional Async FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000675 {
ccheeverf53b5cf2007-02-05 20:33:11 +0000676 $6->set_name(std::string($4) + "_args");
677 $$ = new t_function($3, $4, $6, $8, $2);
678 if ($1 != NULL) {
679 $$->set_doc($1);
680 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000681 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000682 }
683
Mark Slee36bfa2e2007-01-19 20:09:51 +0000684Async:
Mark Slee52f643d2006-08-09 00:03:43 +0000685 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000686 {
Mark Slee52f643d2006-08-09 00:03:43 +0000687 $$ = true;
688 }
689|
690 {
691 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000692 }
693
Mark Slee36bfa2e2007-01-19 20:09:51 +0000694Throws:
Mark Slee9cb7c612006-09-01 22:17:45 +0000695 tok_throws '(' FieldList ')'
696 {
Mark Slee36bfa2e2007-01-19 20:09:51 +0000697 pdebug("Throws -> tok_throws ( FieldList )");
Mark Slee9cb7c612006-09-01 22:17:45 +0000698 $$ = $3;
699 }
700|
701 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000702 $$ = new t_struct(g_program);
Mark Slee9cb7c612006-09-01 22:17:45 +0000703 }
704
Mark Slee31985722006-05-24 21:45:31 +0000705FieldList:
Mark Slee207cb462006-11-02 18:43:12 +0000706 FieldList Field
Mark Slee31985722006-05-24 21:45:31 +0000707 {
708 pdebug("FieldList -> FieldList , Field");
709 $$ = $1;
Mark Slee207cb462006-11-02 18:43:12 +0000710 $$->append($2);
Mark Slee31985722006-05-24 21:45:31 +0000711 }
712|
713 {
714 pdebug("FieldList -> ");
Mark Sleef0712dc2006-10-25 19:03:57 +0000715 $$ = new t_struct(g_program);
Mark Slee31985722006-05-24 21:45:31 +0000716 }
717
718Field:
Mark Slee7df0e2a2007-02-06 21:03:18 +0000719 DocTextOptional FieldIdentifier FieldType tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes CommaOrSemicolonOptional
Mark Slee31985722006-05-24 21:45:31 +0000720 {
Mark Sleef0712dc2006-10-25 19:03:57 +0000721 pdebug("tok_int_constant : Field -> FieldType tok_identifier");
ccheeverf53b5cf2007-02-05 20:33:11 +0000722 if ($2 < 0) {
Mark Slee21135c32007-02-05 21:52:08 +0000723 pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $4);
Mark Slee31985722006-05-24 21:45:31 +0000724 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000725 $$ = new t_field($3, $4, $2);
726 if ($5 != NULL) {
727 validate_field_value($$, $5);
728 $$->set_value($5);
Mark Slee7ff32452007-02-01 05:26:18 +0000729 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000730 $$->set_xsd_optional($6);
Mark Slee7df0e2a2007-02-06 21:03:18 +0000731 $$->set_xsd_nillable($7);
ccheeverf53b5cf2007-02-05 20:33:11 +0000732 if ($1 != NULL) {
733 $$->set_doc($1);
734 }
Mark Slee7df0e2a2007-02-06 21:03:18 +0000735 if ($8 != NULL) {
Mark Slee748d83f2007-02-07 01:20:08 +0000736 $$->set_xsd_attrs($8);
Mark Slee21135c32007-02-05 21:52:08 +0000737 }
Mark Slee31985722006-05-24 21:45:31 +0000738 }
Mark Slee7ff32452007-02-01 05:26:18 +0000739
740FieldIdentifier:
741 tok_int_constant ':'
Mark Slee31985722006-05-24 21:45:31 +0000742 {
Mark Slee7ff32452007-02-01 05:26:18 +0000743 if ($1 <= 0) {
744 pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n", $1);
745 $1 = y_field_val--;
Mark Sleef0712dc2006-10-25 19:03:57 +0000746 }
Mark Slee7ff32452007-02-01 05:26:18 +0000747 $$ = $1;
748 }
749|
750 {
751 $$ = y_field_val--;
752 }
753
754FieldValue:
755 '=' ConstValue
756 {
757 if (g_parse_mode == PROGRAM) {
758 $$ = $2;
759 } else {
760 $$ = NULL;
761 }
762 }
763|
764 {
765 $$ = NULL;
Mark Sleef0712dc2006-10-25 19:03:57 +0000766 }
Mark Slee31985722006-05-24 21:45:31 +0000767
768DefinitionType:
769 BaseType
770 {
771 pdebug("DefinitionType -> BaseType");
772 $$ = $1;
773 }
Mark Sleee8540632006-05-30 09:24:40 +0000774| ContainerType
775 {
776 pdebug("DefinitionType -> ContainerType");
777 $$ = $1;
778 }
Mark Slee31985722006-05-24 21:45:31 +0000779
780FunctionType:
781 FieldType
782 {
Mark Sleee8540632006-05-30 09:24:40 +0000783 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000784 $$ = $1;
785 }
786| tok_void
787 {
Mark Sleee8540632006-05-30 09:24:40 +0000788 pdebug("FunctionType -> tok_void");
Mark Sleef0712dc2006-10-25 19:03:57 +0000789 $$ = g_type_void;
Mark Slee31985722006-05-24 21:45:31 +0000790 }
791
792FieldType:
793 tok_identifier
794 {
Mark Sleee8540632006-05-30 09:24:40 +0000795 pdebug("FieldType -> tok_identifier");
Mark Sleef0712dc2006-10-25 19:03:57 +0000796 if (g_parse_mode == INCLUDES) {
797 // Ignore identifiers in include mode
798 $$ = NULL;
799 } else {
800 // Lookup the identifier in the current scope
801 $$ = g_scope->get_type($1);
802 if ($$ == NULL) {
803 yyerror("Type \"%s\" has not been defined.", $1);
804 exit(1);
805 }
Mark Sleee8540632006-05-30 09:24:40 +0000806 }
Mark Slee31985722006-05-24 21:45:31 +0000807 }
808| BaseType
809 {
Mark Sleee8540632006-05-30 09:24:40 +0000810 pdebug("FieldType -> BaseType");
811 $$ = $1;
812 }
813| ContainerType
814 {
815 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000816 $$ = $1;
817 }
818
819BaseType:
820 tok_string
821 {
822 pdebug("BaseType -> tok_string");
Mark Sleef0712dc2006-10-25 19:03:57 +0000823 $$ = g_type_string;
Mark Slee31985722006-05-24 21:45:31 +0000824 }
Mark Slee8d725a22007-04-13 01:57:12 +0000825| tok_binary
826 {
827 pdebug("BaseType -> tok_binary");
828 $$ = g_type_binary;
829 }
Mark Sleeb6200d82007-01-19 19:14:36 +0000830| tok_slist
831 {
832 pdebug("BaseType -> tok_slist");
833 $$ = g_type_slist;
834 }
Mark Slee78f58e22006-09-02 04:17:07 +0000835| tok_bool
836 {
837 pdebug("BaseType -> tok_bool");
Mark Sleef0712dc2006-10-25 19:03:57 +0000838 $$ = g_type_bool;
Mark Slee78f58e22006-09-02 04:17:07 +0000839 }
Mark Slee31985722006-05-24 21:45:31 +0000840| tok_byte
841 {
842 pdebug("BaseType -> tok_byte");
Mark Sleef0712dc2006-10-25 19:03:57 +0000843 $$ = g_type_byte;
Mark Slee31985722006-05-24 21:45:31 +0000844 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000845| tok_i16
846 {
847 pdebug("BaseType -> tok_i16");
Mark Sleef0712dc2006-10-25 19:03:57 +0000848 $$ = g_type_i16;
Mark Slee9cb7c612006-09-01 22:17:45 +0000849 }
Mark Slee31985722006-05-24 21:45:31 +0000850| tok_i32
851 {
852 pdebug("BaseType -> tok_i32");
Mark Sleef0712dc2006-10-25 19:03:57 +0000853 $$ = g_type_i32;
Mark Slee31985722006-05-24 21:45:31 +0000854 }
Mark Slee31985722006-05-24 21:45:31 +0000855| tok_i64
856 {
857 pdebug("BaseType -> tok_i64");
Mark Sleef0712dc2006-10-25 19:03:57 +0000858 $$ = g_type_i64;
Mark Slee31985722006-05-24 21:45:31 +0000859 }
Mark Sleec98d0502006-09-06 02:42:25 +0000860| tok_double
861 {
862 pdebug("BaseType -> tok_double");
Mark Sleef0712dc2006-10-25 19:03:57 +0000863 $$ = g_type_double;
Mark Sleec98d0502006-09-06 02:42:25 +0000864 }
Mark Slee31985722006-05-24 21:45:31 +0000865
Mark Sleee8540632006-05-30 09:24:40 +0000866ContainerType:
867 MapType
868 {
869 pdebug("ContainerType -> MapType");
870 $$ = $1;
871 }
872| SetType
873 {
874 pdebug("ContainerType -> SetType");
875 $$ = $1;
876 }
877| ListType
878 {
879 pdebug("ContainerType -> ListType");
880 $$ = $1;
881 }
882
883MapType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000884 tok_map CppType '<' FieldType ',' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000885 {
886 pdebug("MapType -> tok_map <FieldType, FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000887 $$ = new t_map($4, $6);
888 if ($2 != NULL) {
889 ((t_container*)$$)->set_cpp_name(std::string($2));
890 }
Mark Sleee8540632006-05-30 09:24:40 +0000891 }
892
893SetType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000894 tok_set CppType '<' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000895 {
896 pdebug("SetType -> tok_set<FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000897 $$ = new t_set($4);
898 if ($2 != NULL) {
899 ((t_container*)$$)->set_cpp_name(std::string($2));
900 }
Mark Sleee8540632006-05-30 09:24:40 +0000901 }
902
903ListType:
Mark Slee36bfa2e2007-01-19 20:09:51 +0000904 tok_list '<' FieldType '>' CppType
Mark Sleee8540632006-05-30 09:24:40 +0000905 {
906 pdebug("ListType -> tok_list<FieldType>");
Mark Sleef0712dc2006-10-25 19:03:57 +0000907 $$ = new t_list($3);
908 if ($5 != NULL) {
909 ((t_container*)$$)->set_cpp_name(std::string($5));
Mark Slee4f8da1d2006-10-12 02:47:27 +0000910 }
911 }
912
Mark Slee36bfa2e2007-01-19 20:09:51 +0000913CppType:
Mark Sleeafc76542007-02-09 21:55:44 +0000914 tok_cpp_type tok_literal
Mark Slee4f8da1d2006-10-12 02:47:27 +0000915 {
Mark Sleeafc76542007-02-09 21:55:44 +0000916 $$ = $2;
Mark Slee4f8da1d2006-10-12 02:47:27 +0000917 }
918|
919 {
920 $$ = NULL;
Mark Sleee8540632006-05-30 09:24:40 +0000921 }
922
Mark Slee31985722006-05-24 21:45:31 +0000923%%