r1401@opsdev009 (orig r74315): dreiss | 2007-12-13 23:03:03 -0800
[amiethrift.git] / compiler / cpp / src / thrifty.yy
blobe46d0ef7dcaf6d852a6a1954b62709253d810f41
1 %{
2 // 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/
8 /**
9  * Thrift parser.
10  *
11  * This parser is used on a thrift definition file.
12  *
13  * @author Mark Slee <mcslee@facebook.com>
14  */
16 #include <stdio.h>
17 #include "main.h"
18 #include "globals.h"
19 #include "parse/t_program.h"
20 #include "parse/t_scope.h"
22 /**
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  */
27 int y_field_val = -1;
28 int g_arglist = 0;
32 /**
33  * This structure is used by the parser to hold the data types associated with
34  * various parse nodes.
35  */
36 %union {
37   char*          id;
38   int            iconst;
39   double         dconst;
40   bool           tbool;
41   t_doc*         tdoc;
42   t_type*        ttype;
43   t_base_type*   tbase;
44   t_typedef*     ttypedef;
45   t_enum*        tenum;
46   t_enum_value*  tenumv;
47   t_const*       tconst;
48   t_const_value* tconstv;
49   t_struct*      tstruct;
50   t_service*     tservice;
51   t_function*    tfunction;
52   t_field*       tfield;
53   char*          dtext;
54   t_field::e_req ereq;
57 /**
58  * Strings identifier
59  */
60 %token<id>     tok_identifier
61 %token<id>     tok_literal
62 %token<dtext>  tok_doctext
63 %token<id>     tok_st_identifier
65 /**
66  * Constant values
67  */
68 %token<iconst> tok_int_constant
69 %token<dconst> tok_dub_constant
71 /**
72  * Header keywoards
73  */
74 %token tok_include
75 %token tok_namespace
76 %token tok_cpp_namespace
77 %token tok_cpp_include
78 %token tok_cpp_type
79 %token tok_php_namespace
80 %token tok_py_module
81 %token tok_perl_package
82 %token tok_java_package
83 %token tok_xsd_all
84 %token tok_xsd_optional
85 %token tok_xsd_nillable
86 %token tok_xsd_namespace
87 %token tok_xsd_attrs
88 %token tok_ruby_namespace
89 %token tok_smalltalk_category
90 %token tok_smalltalk_prefix
91 %token tok_cocoa_prefix
93 /**
94  * Base datatype keywords
95  */
96 %token tok_void
97 %token tok_bool
98 %token tok_byte
99 %token tok_string
100 %token tok_binary
101 %token tok_slist
102 %token tok_senum
103 %token tok_i16
104 %token tok_i32
105 %token tok_i64
106 %token tok_double
109  * Complex type keywords
110  */
111 %token tok_map
112 %token tok_list
113 %token tok_set
116  * Function modifiers
117  */
118 %token tok_async
121  * Thrift language keywords
122  */
123 %token tok_typedef
124 %token tok_struct
125 %token tok_xception
126 %token tok_throws
127 %token tok_extends
128 %token tok_service
129 %token tok_enum
130 %token tok_const
131 %token tok_required
132 %token tok_optional
135  * Grammar nodes
136  */
138 %type<ttype>     BaseType
139 %type<ttype>     ContainerType
140 %type<ttype>     MapType
141 %type<ttype>     SetType
142 %type<ttype>     ListType
144 %type<tdoc>      Definition
145 %type<ttype>     TypeDefinition
147 %type<ttypedef>  Typedef
148 %type<ttype>     DefinitionType
150 %type<tfield>    Field
151 %type<iconst>    FieldIdentifier
152 %type<ereq>      FieldRequiredness
153 %type<ttype>     FieldType
154 %type<tconstv>   FieldValue
155 %type<tstruct>   FieldList
157 %type<tenum>     Enum
158 %type<tenum>     EnumDefList
159 %type<tenumv>    EnumDef
161 %type<ttypedef>  Senum
162 %type<tbase>     SenumDefList
163 %type<id>        SenumDef
165 %type<tconst>    Const
166 %type<tconstv>   ConstValue
167 %type<tconstv>   ConstList
168 %type<tconstv>   ConstListContents
169 %type<tconstv>   ConstMap
170 %type<tconstv>   ConstMapContents
172 %type<tstruct>   Struct
173 %type<tstruct>   Xception
174 %type<tservice>  Service
176 %type<tfunction> Function
177 %type<ttype>     FunctionType
178 %type<tservice>  FunctionList
180 %type<tstruct>   Throws
181 %type<tservice>  Extends
182 %type<tbool>     Async
183 %type<tbool>     XsdAll
184 %type<tbool>     XsdOptional
185 %type<tbool>     XsdNillable
186 %type<tstruct>   XsdAttributes
187 %type<id>        CppType
189 %type<dtext>     CaptureDocText
194  * Thrift Grammar Implementation.
196  * For the most part this source file works its way top down from what you
197  * might expect to find in a typical .thrift file, i.e. type definitions and
198  * namespaces up top followed by service definitions using those types.
199  */
201 Program:
202   HeaderList DefinitionList
203     {
204       pdebug("Program -> Headers DefinitionList");
205       /*
206       TODO(dreiss): Decide whether full-program doctext is worth the trouble.
207       if ($1 != NULL) {
208         g_program->set_doc($1);
209       }
210       */
211       clear_doctext();
212     }
214 CaptureDocText:
215     {
216       if (g_parse_mode == PROGRAM) {
217         $$ = g_doctext;
218         g_doctext = NULL;
219       } else {
220         $$ = NULL;
221       }
222     }
224 /* TODO(dreiss): Try to DestroyDocText in all sorts or random places. */
225 DestroyDocText:
226     {
227       if (g_parse_mode == PROGRAM) {
228         clear_doctext();
229       }
230     }
232 /* We have to DestroyDocText here, otherwise it catches the doctext
233    on the first real element. */
234 HeaderList:
235   HeaderList DestroyDocText Header
236     {
237       pdebug("HeaderList -> HeaderList Header");
238     }
240     {
241       pdebug("HeaderList -> ");
242     }
244 Header:
245   Include
246     {
247       pdebug("Header -> Include");
248     }
249 | tok_namespace tok_identifier
250     {
251       pwarning(1, "'namespace' is deprecated. Use 'cpp_namespace' and/or 'java_package' instead");
252       if (g_parse_mode == PROGRAM) {
253         g_program->set_cpp_namespace($2);
254         g_program->set_java_package($2);
255       }
256     }
257 | tok_cpp_namespace tok_identifier
258     {
259       pdebug("Header -> tok_cpp_namespace tok_identifier");
260       if (g_parse_mode == PROGRAM) {
261         g_program->set_cpp_namespace($2);
262       }
263     }
264 | tok_cpp_include tok_literal
265     {
266       pdebug("Header -> tok_cpp_include tok_literal");
267       if (g_parse_mode == PROGRAM) {
268         g_program->add_cpp_include($2);
269       }
270     }
271 | tok_php_namespace tok_identifier
272     {
273       pdebug("Header -> tok_php_namespace tok_identifier");
274       if (g_parse_mode == PROGRAM) {
275         g_program->set_php_namespace($2);
276       }
277     }
278 | tok_py_module tok_identifier
279     {
280       pdebug("Header -> tok_py_module tok_identifier");
281       if (g_parse_mode == PROGRAM) {
282         g_program->set_py_module($2);
283       }
284     }
285 | tok_perl_package tok_identifier
286     {
287       pdebug("Header -> tok_perl_namespace tok_identifier");
288       if (g_parse_mode == PROGRAM) {
289         g_program->set_perl_package($2);
290       }
291     }
292 | tok_ruby_namespace tok_identifier
293     {
294       pdebug("Header -> tok_ruby_namespace tok_identifier");
295       if (g_parse_mode == PROGRAM) {
296         g_program->set_ruby_namespace($2);
297       }
298     }
299 | tok_smalltalk_category tok_st_identifier
300     {
301       pdebug("Header -> tok_smalltalk_category tok_st_identifier");
302       if (g_parse_mode == PROGRAM) {
303         g_program->set_smalltalk_category($2);
304       }
305     }
306 | tok_smalltalk_prefix tok_identifier
307     {
308       pdebug("Header -> tok_smalltalk_prefix tok_identifier");
309       if (g_parse_mode == PROGRAM) {
310         g_program->set_smalltalk_prefix($2);
311       }
312     }
313 | tok_java_package tok_identifier
314     {
315       pdebug("Header -> tok_java_package tok_identifier");
316       if (g_parse_mode == PROGRAM) {
317         g_program->set_java_package($2);
318       }
319     }
320 | tok_cocoa_prefix tok_identifier
321     {
322       pdebug("Header -> tok_cocoa_prefix tok_identifier");
323       if (g_parse_mode == PROGRAM) {
324         g_program->set_cocoa_prefix($2);
325       }
326     }
327 | tok_xsd_namespace tok_literal
328     {
329       pdebug("Header -> tok_xsd_namespace tok_literal");
330       if (g_parse_mode == PROGRAM) {
331         g_program->set_xsd_namespace($2);
332       }
333     }
335 Include:
336   tok_include tok_literal
337     {
338       pdebug("Include -> tok_include tok_literal");
339       if (g_parse_mode == INCLUDES) {
340         std::string path = include_file(std::string($2));
341         if (!path.empty()) {
342           g_program->add_include(path);
343         }
344       }
345     }
347 DefinitionList:
348   DefinitionList CaptureDocText Definition
349     {
350       pdebug("DefinitionList -> DefinitionList Definition");
351       if ($2 != NULL && $3 != NULL) {
352         $3->set_doc($2);
353       }
354     }
356     {
357       pdebug("DefinitionList -> ");
358     }
360 Definition:
361   Const
362     {
363       pdebug("Definition -> Const");
364       if (g_parse_mode == PROGRAM) {
365         g_program->add_const($1);
366       }
367       $$ = $1;
368     }
369 | TypeDefinition
370     {
371       pdebug("Definition -> TypeDefinition");
372       if (g_parse_mode == PROGRAM) {
373         g_scope->add_type($1->get_name(), $1);
374         if (g_parent_scope != NULL) {
375           g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
376         }
377       }
378       $$ = $1;
379     }
380 | Service
381     {
382       pdebug("Definition -> Service");
383       if (g_parse_mode == PROGRAM) {
384         g_scope->add_service($1->get_name(), $1);
385         if (g_parent_scope != NULL) {
386           g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
387         }
388         g_program->add_service($1);
389       }
390       $$ = $1;
391     }
393 TypeDefinition:
394   Typedef
395     {
396       pdebug("TypeDefinition -> Typedef");
397       if (g_parse_mode == PROGRAM) {
398         g_program->add_typedef($1);
399       }
400     }
401 | Enum
402     {
403       pdebug("TypeDefinition -> Enum");
404       if (g_parse_mode == PROGRAM) {
405         g_program->add_enum($1);
406       }
407     }
408 | Senum
409     {
410       pdebug("TypeDefinition -> Senum");
411       if (g_parse_mode == PROGRAM) {
412         g_program->add_typedef($1);
413       }
414     }
415 | Struct
416     {
417       pdebug("TypeDefinition -> Struct");
418       if (g_parse_mode == PROGRAM) {
419         g_program->add_struct($1);
420       }
421     }
422 | Xception
423     {
424       pdebug("TypeDefinition -> Xception");
425       if (g_parse_mode == PROGRAM) {
426         g_program->add_xception($1);
427       }
428     }
430 Typedef:
431   tok_typedef DefinitionType tok_identifier
432     {
433       pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
434       t_typedef *td = new t_typedef(g_program, $2, $3);
435       $$ = td;
436     }
438 CommaOrSemicolonOptional:
439   ','
440     {}
441 | ';'
442     {}
444     {}
446 Enum:
447   tok_enum tok_identifier '{' EnumDefList '}'
448     {
449       pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
450       $$ = $4;
451       $$->set_name($2);
452     }
454 EnumDefList:
455   EnumDefList EnumDef
456     {
457       pdebug("EnumDefList -> EnumDefList EnumDef");
458       $$ = $1;
459       $$->append($2);
460     }
462     {
463       pdebug("EnumDefList -> ");
464       $$ = new t_enum(g_program);
465     }
467 EnumDef:
468   CaptureDocText tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
469     {
470       pdebug("EnumDef -> tok_identifier = tok_int_constant");
471       if ($4 < 0) {
472         pwarning(1, "Negative value supplied for enum %s.\n", $2);
473       }
474       $$ = new t_enum_value($2, $4);
475       if ($1 != NULL) {
476         $$->set_doc($1);
477       }
478       if (g_parse_mode == PROGRAM) {
479         g_scope->add_constant($2, new t_const(g_type_i32, $2, new t_const_value($4)));
480         if (g_parent_scope != NULL) {
481           g_parent_scope->add_constant(g_parent_prefix + $2, new t_const(g_type_i32, $2, new t_const_value($4)));
482         }
483       }
484     }
486   CaptureDocText tok_identifier CommaOrSemicolonOptional
487     {
488       pdebug("EnumDef -> tok_identifier");
489       $$ = new t_enum_value($2);
490       if ($1 != NULL) {
491         $$->set_doc($1);
492       }
493     }
495 Senum:
496   tok_senum tok_identifier '{' SenumDefList '}'
497     {
498       pdebug("Senum -> tok_senum tok_identifier { SenumDefList }");
499       $$ = new t_typedef(g_program, $4, $2);
500     }
502 SenumDefList:
503   SenumDefList SenumDef
504     {
505       pdebug("SenumDefList -> SenumDefList SenumDef");
506       $$ = $1;
507       $$->add_string_enum_val($2);
508     }
510     {
511       pdebug("SenumDefList -> ");
512       $$ = new t_base_type("string", t_base_type::TYPE_STRING);
513       $$->set_string_enum(true);
514     }
516 SenumDef:
517   tok_literal CommaOrSemicolonOptional
518     {
519       pdebug("SenumDef -> tok_literal");
520       $$ = $1;
521     }
523 Const:
524   tok_const FieldType tok_identifier '=' ConstValue CommaOrSemicolonOptional
525     {
526       pdebug("Const -> tok_const FieldType tok_identifier = ConstValue");
527       if (g_parse_mode == PROGRAM) {
528         $$ = new t_const($2, $3, $5);
529         validate_const_type($$);
531         g_scope->add_constant($3, $$);
532         if (g_parent_scope != NULL) {
533           g_parent_scope->add_constant(g_parent_prefix + $3, $$);
534         }
536       } else {
537         $$ = NULL;
538       }
539     }
541 ConstValue:
542   tok_int_constant
543     {
544       pdebug("ConstValue => tok_int_constant");
545       $$ = new t_const_value();
546       $$->set_integer($1);
547     }
548 | tok_dub_constant
549     {
550       pdebug("ConstValue => tok_dub_constant");
551       $$ = new t_const_value();
552       $$->set_double($1);
553     }
554 | tok_literal
555     {
556       pdebug("ConstValue => tok_literal");
557       $$ = new t_const_value($1);
558     }
559 | tok_identifier
560     {
561       pdebug("ConstValue => tok_identifier");
562       t_const* constant = g_scope->get_constant($1);
563       if (constant != NULL) {
564         $$ = constant->get_value();
565       } else {
566         if (g_parse_mode == PROGRAM) {
567           pwarning(1, "Constant strings should be quoted: %s\n", $1);
568         }
569         $$ = new t_const_value($1);
570       }
571     }
572 | ConstList
573     {
574       pdebug("ConstValue => ConstList");
575       $$ = $1;
576     }
577 | ConstMap
578     {
579       pdebug("ConstValue => ConstMap");
580       $$ = $1;
581     }
583 ConstList:
584   '[' ConstListContents ']'
585     {
586       pdebug("ConstList => [ ConstListContents ]");
587       $$ = $2;
588     }
590 ConstListContents:
591   ConstListContents ConstValue CommaOrSemicolonOptional
592     {
593       pdebug("ConstListContents => ConstListContents ConstValue CommaOrSemicolonOptional");
594       $$ = $1;
595       $$->add_list($2);
596     }
598     {
599       pdebug("ConstListContents =>");
600       $$ = new t_const_value();
601       $$->set_list();
602     }
604 ConstMap:
605   '{' ConstMapContents '}'
606     {
607       pdebug("ConstMap => { ConstMapContents }");
608       $$ = $2;
609     }
611 ConstMapContents:
612   ConstMapContents ConstValue ':' ConstValue CommaOrSemicolonOptional
613     {
614       pdebug("ConstMapContents => ConstMapContents ConstValue CommaOrSemicolonOptional");
615       $$ = $1;
616       $$->add_map($2, $4);
617     }
619     {
620       pdebug("ConstMapContents =>");
621       $$ = new t_const_value();
622       $$->set_map();
623     }
625 Struct:
626   tok_struct tok_identifier XsdAll '{' FieldList '}'
627     {
628       pdebug("Struct -> tok_struct tok_identifier { FieldList }");
629       $5->set_name($2);
630       $5->set_xsd_all($3);
631       $$ = $5;
632       y_field_val = -1;
633     }
635 XsdAll:
636   tok_xsd_all
637     {
638       $$ = true;
639     }
641     {
642       $$ = false;
643     }
645 XsdOptional:
646   tok_xsd_optional
647     {
648       $$ = true;
649     }
651     {
652       $$ = false;
653     }
655 XsdNillable:
656   tok_xsd_nillable
657     {
658       $$ = true;
659     }
661     {
662       $$ = false;
663     }
665 XsdAttributes:
666   tok_xsd_attrs '{' FieldList '}'
667     {
668       $$ = $3;
669     }
671     {
672       $$ = NULL;
673     }
675 Xception:
676   tok_xception tok_identifier '{' FieldList '}'
677     {
678       pdebug("Xception -> tok_xception tok_identifier { FieldList }");
679       $4->set_name($2);
680       $4->set_xception(true);
681       $$ = $4;
682       y_field_val = -1;
683     }
685 Service:
686   tok_service tok_identifier Extends '{' FlagArgs FunctionList UnflagArgs '}'
687     {
688       pdebug("Service -> tok_service tok_identifier { FunctionList }");
689       $$ = $6;
690       $$->set_name($2);
691       $$->set_extends($3);
692     }
694 FlagArgs:
695     {
696        g_arglist = 1;
697     }
699 UnflagArgs:
700     {
701        g_arglist = 0;
702     }
704 Extends:
705   tok_extends tok_identifier
706     {
707       pdebug("Extends -> tok_extends tok_identifier");
708       $$ = NULL;
709       if (g_parse_mode == PROGRAM) {
710         $$ = g_scope->get_service($2);
711         if ($$ == NULL) {
712           yyerror("Service \"%s\" has not been defined.", $2);
713           exit(1);
714         }
715       }
716     }
718     {
719       $$ = NULL;
720     }
722 FunctionList:
723   FunctionList Function
724     {
725       pdebug("FunctionList -> FunctionList Function");
726       $$ = $1;
727       $1->add_function($2);
728     }
730     {
731       pdebug("FunctionList -> ");
732       $$ = new t_service(g_program);
733     }
735 Function:
736   CaptureDocText Async FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional
737     {
738       $6->set_name(std::string($4) + "_args");
739       $$ = new t_function($3, $4, $6, $8, $2);
740       if ($1 != NULL) {
741         $$->set_doc($1);
742       }
743       y_field_val = -1;
744     }
746 Async:
747   tok_async
748     {
749       $$ = true;
750     }
752     {
753       $$ = false;
754     }
756 Throws:
757   tok_throws '(' FieldList ')'
758     {
759       pdebug("Throws -> tok_throws ( FieldList )");
760       $$ = $3;
761     }
763     {
764       $$ = new t_struct(g_program);
765     }
767 FieldList:
768   FieldList Field
769     {
770       pdebug("FieldList -> FieldList , Field");
771       $$ = $1;
772       if (!($$->validate_field($2))) {
773         yyerror("Field identifier %d for \"%s\" has already been used", $2->get_key(), $2->get_name().c_str());
774         exit(1);
775       }
776       $$->append($2);
777     }
779     {
780       pdebug("FieldList -> ");
781       $$ = new t_struct(g_program);
782     }
784 Field:
785   CaptureDocText FieldIdentifier FieldRequiredness FieldType tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes CommaOrSemicolonOptional
786     {
787       pdebug("tok_int_constant : Field -> FieldType tok_identifier");
788       if ($2 < 0) {
789         pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $5);
790       }
791       $$ = new t_field($4, $5, $2);
792       $$->set_req($3);
793       if ($6 != NULL) {
794         validate_field_value($$, $6);
795         $$->set_value($6);
796       }
797       $$->set_xsd_optional($7);
798       $$->set_xsd_nillable($8);
799       if ($1 != NULL) {
800         $$->set_doc($1);
801       }
802       if ($9 != NULL) {
803         $$->set_xsd_attrs($9);
804       }
805     }
807 FieldIdentifier:
808   tok_int_constant ':'
809     {
810       if ($1 <= 0) {
811         pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n", $1);
812         $1 = y_field_val--;
813       }
814       $$ = $1;
815     }
817     {
818       $$ = y_field_val--;
819     }
821 FieldRequiredness:
822   tok_required
823     {
824       if (g_arglist) {
825         if (g_parse_mode == PROGRAM) {
826           pwarning(1, "required keyword is ignored in argument lists.\n");
827         }
828         $$ = t_field::OPT_IN_REQ_OUT;
829       } else {
830         $$ = t_field::REQUIRED;
831       }
832     }
833 | tok_optional
834     {
835       if (g_arglist) {
836         if (g_parse_mode == PROGRAM) {
837           pwarning(1, "optional keyword is ignored in argument lists.\n");
838         }
839         $$ = t_field::OPT_IN_REQ_OUT;
840       } else {
841         $$ = t_field::OPTIONAL;
842       }
843     }
845     {
846       $$ = t_field::OPT_IN_REQ_OUT;
847     }
849 FieldValue:
850   '=' ConstValue
851     {
852       if (g_parse_mode == PROGRAM) {
853         $$ = $2;
854       } else {
855         $$ = NULL;
856       }
857     }
859     {
860       $$ = NULL;
861     }
863 DefinitionType:
864   BaseType
865     {
866       pdebug("DefinitionType -> BaseType");
867       $$ = $1;
868     }
869 | ContainerType
870     {
871       pdebug("DefinitionType -> ContainerType");
872       $$ = $1;
873     }
875 FunctionType:
876   FieldType
877     {
878       pdebug("FunctionType -> FieldType");
879       $$ = $1;
880     }
881 | tok_void
882     {
883       pdebug("FunctionType -> tok_void");
884       $$ = g_type_void;
885     }
887 FieldType:
888   tok_identifier
889     {
890       pdebug("FieldType -> tok_identifier");
891       if (g_parse_mode == INCLUDES) {
892         // Ignore identifiers in include mode
893         $$ = NULL;
894       } else {
895         // Lookup the identifier in the current scope
896         $$ = g_scope->get_type($1);
897         if ($$ == NULL) {
898           yyerror("Type \"%s\" has not been defined.", $1);
899           exit(1);
900         }
901       }
902     }
903 | BaseType
904     {
905       pdebug("FieldType -> BaseType");
906       $$ = $1;
907     }
908 | ContainerType
909     {
910       pdebug("FieldType -> ContainerType");
911       $$ = $1;
912     }
914 BaseType:
915   tok_string
916     {
917       pdebug("BaseType -> tok_string");
918       $$ = g_type_string;
919     }
920 | tok_binary
921     {
922       pdebug("BaseType -> tok_binary");
923       $$ = g_type_binary;
924     }
925 | tok_slist
926     {
927       pdebug("BaseType -> tok_slist");
928       $$ = g_type_slist;
929     }
930 | tok_bool
931     {
932       pdebug("BaseType -> tok_bool");
933       $$ = g_type_bool;
934     }
935 | tok_byte
936     {
937       pdebug("BaseType -> tok_byte");
938       $$ = g_type_byte;
939     }
940 | tok_i16
941     {
942       pdebug("BaseType -> tok_i16");
943       $$ = g_type_i16;
944     }
945 | tok_i32
946     {
947       pdebug("BaseType -> tok_i32");
948       $$ = g_type_i32;
949     }
950 | tok_i64
951     {
952       pdebug("BaseType -> tok_i64");
953       $$ = g_type_i64;
954     }
955 | tok_double
956     {
957       pdebug("BaseType -> tok_double");
958       $$ = g_type_double;
959     }
961 ContainerType:
962   MapType
963     {
964       pdebug("ContainerType -> MapType");
965       $$ = $1;
966     }
967 | SetType
968     {
969       pdebug("ContainerType -> SetType");
970       $$ = $1;
971     }
972 | ListType
973     {
974       pdebug("ContainerType -> ListType");
975       $$ = $1;
976     }
978 MapType:
979   tok_map CppType '<' FieldType ',' FieldType '>'
980     {
981       pdebug("MapType -> tok_map <FieldType, FieldType>");
982       $$ = new t_map($4, $6);
983       if ($2 != NULL) {
984         ((t_container*)$$)->set_cpp_name(std::string($2));
985       }
986     }
988 SetType:
989   tok_set CppType '<' FieldType '>'
990     {
991       pdebug("SetType -> tok_set<FieldType>");
992       $$ = new t_set($4);
993       if ($2 != NULL) {
994         ((t_container*)$$)->set_cpp_name(std::string($2));
995       }
996     }
998 ListType:
999   tok_list '<' FieldType '>' CppType
1000     {
1001       pdebug("ListType -> tok_list<FieldType>");
1002       $$ = new t_list($3);
1003       if ($5 != NULL) {
1004         ((t_container*)$$)->set_cpp_name(std::string($5));
1005       }
1006     }
1008 CppType:
1009   tok_cpp_type tok_literal
1010     {
1011       $$ = $2;
1012     }
1014     {
1015       $$ = NULL;
1016     }