LCOV - code coverage report
Current view: top level - compiler - sandeshy.yy (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 273 466 58.6 %
Date: 2026-06-03 15:43:17 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : %{
       2             : /*
       3             :  * Licensed to the Apache Software Foundation (ASF) under one
       4             :  * or more contributor license agreements. See the NOTICE file
       5             :  * distributed with this work for additional information
       6             :  * regarding copyright ownership. The ASF licenses this file
       7             :  * to you under the Apache License, Version 2.0 (the
       8             :  * "License"); you may not use this file except in compliance
       9             :  * with the License. You may obtain a copy of the License at
      10             :  *
      11             :  *   http://www.apache.org/licenses/LICENSE-2.0
      12             :  *
      13             :  * Unless required by applicable law or agreed to in writing,
      14             :  * software distributed under the License is distributed on an
      15             :  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      16             :  * KIND, either express or implied. See the License for the
      17             :  * specific language governing permissions and limitations
      18             :  * under the License.
      19             :  */
      20             : 
      21             : /**
      22             :  * Thrift parser.
      23             :  *
      24             :  * This parser is used on a thrift definition file.
      25             :  */
      26             : 
      27             : #ifdef SANDESH
      28             : /**
      29             :  * Sandesh parser.
      30             :  *
      31             :  * This parser is used on a sandesh definition file.
      32             :  *
      33             :  * sandesh domain specific langauge is derived from apache thrift and
      34             :  * much of thrift code is reused.
      35             :  */
      36             : #endif
      37             : 
      38             : #define __STDC_LIMIT_MACROS
      39             : #define __STDC_FORMAT_MACROS
      40             : #include <stdio.h>
      41             : #include <inttypes.h>
      42             : #include <limits.h>
      43             : #include "main.h"
      44             : #include "globals.h"
      45             : #include "parse/t_program.h"
      46             : #include "parse/t_scope.h"
      47             : 
      48             : /**
      49             :  * This global variable is used for automatic numbering of field indices etc.
      50             :  * when parsing the members of a struct. Field values are automatically
      51             :  * assigned starting from -1 and working their way down.
      52             :  */
      53             : int y_field_val = -1;
      54             : int g_arglist = 0;
      55             : const int struct_is_struct = 0;
      56             : const int struct_is_union = 1;
      57             : 
      58             : %}
      59             : 
      60             : /**
      61             :  * This structure is used by the parser to hold the data types associated with
      62             :  * various parse nodes.
      63             :  */
      64             : %union {
      65             :   char*          id;
      66             :   int64_t        iconst;
      67             :   double         dconst;
      68             :   bool           tbool;
      69             :   t_doc*         tdoc;
      70             :   t_type*        ttype;
      71             :   t_base_type*   tbase;
      72             :   t_typedef*     ttypedef;
      73             :   t_enum*        tenum;
      74             :   t_enum_value*  tenumv;
      75             :   t_const*       tconst;
      76             :   t_const_value* tconstv;
      77             :   t_struct*      tstruct;
      78             :   t_service*     tservice;
      79             :   t_function*    tfunction;
      80             :   t_field*       tfield;
      81             :   char*          dtext;
      82             :   t_field::e_req ereq;
      83             :   t_annotation*  tannot;
      84             :   t_field_id     tfieldid;
      85             :   t_sandesh*     tsandesh;
      86             : }
      87             : 
      88             : /**
      89             :  * Strings identifier
      90             :  */
      91             : %token<id>     tok_identifier
      92             : %token<id>     tok_literal
      93             : %token<dtext>  tok_doctext
      94             : %token<id>     tok_st_identifier
      95             : %token<id>     tok_format
      96             : 
      97             : /**
      98             :  * Constant values
      99             :  */
     100             : %token<iconst> tok_int_constant
     101             : %token<dconst> tok_dub_constant
     102             : 
     103             : /**
     104             :  * Header keywords
     105             :  */
     106             : %token tok_include
     107             : %token tok_namespace
     108             : %token tok_cpp_namespace
     109             : %token tok_cpp_include
     110             : %token tok_cpp_type
     111             : %token tok_php_namespace
     112             : %token tok_py_module
     113             : %token tok_perl_package
     114             : %token tok_java_package
     115             : %token tok_xsd_all
     116             : %token tok_xsd_optional
     117             : %token tok_xsd_nillable
     118             : %token tok_xsd_namespace
     119             : %token tok_xsd_attrs
     120             : %token tok_ruby_namespace
     121             : %token tok_smalltalk_category
     122             : %token tok_smalltalk_prefix
     123             : %token tok_cocoa_prefix
     124             : %token tok_csharp_namespace
     125             : %token tok_delphi_namespace
     126             : 
     127             : /**
     128             :  * Base datatype keywords
     129             :  */
     130             : %token tok_void
     131             : %token tok_bool
     132             : %token tok_byte
     133             : %token tok_string
     134             : %token tok_binary
     135             : %token tok_slist
     136             : %token tok_senum
     137             : %token tok_i16
     138             : %token tok_i32
     139             : %token tok_i64
     140             : %token tok_double
     141             : %token tok_u16
     142             : %token tok_u32
     143             : %token tok_u64
     144             : %token tok_ipv4
     145             : %token tok_ipaddr
     146             : %token tok_xml
     147             : %token tok_uuid_t
     148             : 
     149             : /**
     150             :  * Complex type keywords
     151             :  */
     152             : %token tok_map
     153             : %token tok_list
     154             : %token tok_set
     155             : 
     156             : /**
     157             :  * Function modifiers
     158             :  */
     159             : %token tok_oneway
     160             : %token tok_staticfunction
     161             : %token tok_abcfunction
     162             : 
     163             : /**
     164             :  * Sandesh modifiers
     165             :  */
     166             :  %token tok_system
     167             :  %token tok_request
     168             :  %token tok_response
     169             :  %token tok_trace
     170             :  %token tok_object
     171             :  %token tok_flow
     172             :  %token tok_buffer
     173             :  %token tok_uve
     174             :  %token tok_dynamic_uve
     175             :  %token tok_trace_object
     176             :  %token tok_alarm
     177             :  %token tok_session
     178             : 
     179             : /**
     180             :  * Thrift language keywords
     181             :  */
     182             : %token tok_typedef
     183             : %token tok_struct
     184             : %token tok_xception
     185             : %token tok_throws
     186             : %token tok_extends
     187             : %token tok_service
     188             : %token tok_sandesh
     189             : %token tok_enum
     190             : %token tok_const
     191             : %token tok_required
     192             : %token tok_optional
     193             : %token tok_union
     194             : 
     195             : /**
     196             :  * Grammar nodes
     197             :  */
     198             : 
     199             : %type<ttype>     BaseType
     200             : %type<ttype>     SimpleBaseType
     201             : %type<ttype>     ContainerType
     202             : %type<ttype>     SimpleContainerType
     203             : %type<ttype>     MapType
     204             : %type<ttype>     SetType
     205             : %type<ttype>     ListType
     206             : 
     207             : %type<tdoc>      Definition
     208             : %type<ttype>     TypeDefinition
     209             : 
     210             : %type<ttypedef>  Typedef
     211             : 
     212             : %type<ttype>     TypeAnnotations
     213             : %type<ttype>     TypeAnnotationList
     214             : %type<tannot>    TypeAnnotation
     215             : 
     216             : %type<tfield>    Field
     217             : %type<tfieldid>  FieldIdentifier
     218             : %type<ereq>      FieldRequiredness
     219             : %type<ttype>     FieldType
     220             : %type<tconstv>   FieldValue
     221             : %type<tstruct>   FieldList
     222             : %type<tsandesh>  SFieldList
     223             : 
     224             : %type<tenum>     Enum
     225             : %type<tenum>     EnumDefList
     226             : %type<tenumv>    EnumDef
     227             : 
     228             : %type<ttypedef>  Senum
     229             : %type<tbase>     SenumDefList
     230             : %type<id>        SenumDef
     231             : 
     232             : %type<tconst>    Const
     233             : %type<tconstv>   ConstValue
     234             : %type<tconstv>   ConstList
     235             : %type<tconstv>   ConstListContents
     236             : %type<tconstv>   ConstMap
     237             : %type<tconstv>   ConstMapContents
     238             : 
     239             : %type<iconst>    StructHead
     240             : %type<tstruct>   Struct
     241             : %type<tstruct>   Xception
     242             : %type<tservice>  Service
     243             : %type<tsandesh>  Sandesh
     244             : %type<ttype>     SandeshType
     245             : 
     246             : %type<tfunction> Function
     247             : %type<ttype>     FunctionType
     248             : %type<tservice>  FunctionList
     249             : 
     250             : %type<tstruct>   Throws
     251             : %type<tservice>  Extends
     252             : %type<tbool>     Oneway
     253             : %type<tbool>     StaticFunction
     254             : %type<tbool>     AbcFunction
     255             : %type<tbool>     XsdAll
     256             : %type<tbool>     XsdOptional
     257             : %type<tbool>     XsdNillable
     258             : %type<tstruct>   XsdAttributes
     259             : %type<id>        CppType
     260             : 
     261             : %type<dtext>     CaptureDocText
     262             : 
     263             : %%
     264             : 
     265             : /**
     266             :  * Thrift Grammar Implementation.
     267             :  *
     268             :  * For the most part this source file works its way top down from what you
     269             :  * might expect to find in a typical .thrift file, i.e. type definitions and
     270             :  * namespaces up top followed by service definitions using those types.
     271             :  */
     272             : 
     273             : Program:
     274             :   HeaderList DefinitionList
     275             :     {
     276         584 :       pdebug("Program -> Headers DefinitionList");
     277         584 :       if((g_program_doctext_candidate != NULL) && (g_program_doctext_status != ALREADY_PROCESSED))
     278             :       {
     279         164 :         g_program->set_doc(g_program_doctext_candidate);
     280         164 :         g_program_doctext_status = ALREADY_PROCESSED;
     281             :       }
     282         584 :       clear_doctext();
     283             :     }
     284             : 
     285             : CaptureDocText:
     286             :     {
     287       26044 :       if (g_parse_mode == PROGRAM) {
     288       13022 :         $$ = g_doctext;
     289       13022 :         g_doctext = NULL;
     290             :       } else {
     291       13022 :         $$ = NULL;
     292             :       }
     293             :     }
     294             : 
     295             : /* TODO(dreiss): Try to DestroyDocText in all sorts or random places. */
     296             : DestroyDocText:
     297             :     {
     298         132 :       if (g_parse_mode == PROGRAM) {
     299          66 :         clear_doctext();
     300             :       }
     301             :     }
     302             : 
     303             : /* We have to DestroyDocText here, otherwise it catches the doctext
     304             :    on the first real element. */
     305             : HeaderList:
     306             :   HeaderList DestroyDocText Header
     307             :     {
     308         132 :       pdebug("HeaderList -> HeaderList Header");
     309             :     }
     310             : |
     311             :     {
     312         584 :       pdebug("HeaderList -> ");
     313             :     }
     314             : 
     315             : Header:
     316             :   Include
     317             :     {
     318          72 :       pdebug("Header -> Include");
     319             :     }
     320             : | tok_namespace tok_identifier tok_identifier
     321             :     {
     322          60 :       pdebug("Header -> tok_namespace tok_identifier tok_identifier");
     323          60 :       if (g_parse_mode == PROGRAM) {
     324          30 :         g_program->set_namespace($2, $3);
     325             :       }
     326             :     }
     327             : | tok_namespace '*' tok_identifier
     328             :     {
     329           0 :       pdebug("Header -> tok_namespace * tok_identifier");
     330           0 :       if (g_parse_mode == PROGRAM) {
     331           0 :         g_program->set_namespace("*", $3);
     332             :       }
     333             :     }
     334             : 
     335             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     336             : | tok_cpp_namespace tok_identifier
     337             :     {
     338           0 :       pwarning(1, "'cpp_namespace' is deprecated. Use 'namespace cpp' instead");
     339           0 :       pdebug("Header -> tok_cpp_namespace tok_identifier");
     340           0 :       if (g_parse_mode == PROGRAM) {
     341           0 :         g_program->set_namespace("cpp", $2);
     342             :       }
     343             :     }
     344             : | tok_cpp_include tok_literal
     345             :     {
     346           0 :       pdebug("Header -> tok_cpp_include tok_literal");
     347           0 :       if (g_parse_mode == PROGRAM) {
     348           0 :         g_program->add_cpp_include($2);
     349             :       }
     350             :     }
     351             : | tok_php_namespace tok_identifier
     352             :     {
     353           0 :       pwarning(1, "'php_namespace' is deprecated. Use 'namespace php' instead");
     354           0 :       pdebug("Header -> tok_php_namespace tok_identifier");
     355           0 :       if (g_parse_mode == PROGRAM) {
     356           0 :         g_program->set_namespace("php", $2);
     357             :       }
     358             :     }
     359             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     360             : | tok_py_module tok_identifier
     361             :     {
     362           0 :       pwarning(1, "'py_module' is deprecated. Use 'namespace py' instead");
     363           0 :       pdebug("Header -> tok_py_module tok_identifier");
     364           0 :       if (g_parse_mode == PROGRAM) {
     365           0 :         g_program->set_namespace("py", $2);
     366             :       }
     367             :     }
     368             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     369             : | tok_perl_package tok_identifier
     370             :     {
     371           0 :       pwarning(1, "'perl_package' is deprecated. Use 'namespace perl' instead");
     372           0 :       pdebug("Header -> tok_perl_namespace tok_identifier");
     373           0 :       if (g_parse_mode == PROGRAM) {
     374           0 :         g_program->set_namespace("perl", $2);
     375             :       }
     376             :     }
     377             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     378             : | tok_ruby_namespace tok_identifier
     379             :     {
     380           0 :       pwarning(1, "'ruby_namespace' is deprecated. Use 'namespace rb' instead");
     381           0 :       pdebug("Header -> tok_ruby_namespace tok_identifier");
     382           0 :       if (g_parse_mode == PROGRAM) {
     383           0 :         g_program->set_namespace("rb", $2);
     384             :       }
     385             :     }
     386             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     387             : | tok_smalltalk_category tok_st_identifier
     388             :     {
     389           0 :       pwarning(1, "'smalltalk_category' is deprecated. Use 'namespace smalltalk.category' instead");
     390           0 :       pdebug("Header -> tok_smalltalk_category tok_st_identifier");
     391           0 :       if (g_parse_mode == PROGRAM) {
     392           0 :         g_program->set_namespace("smalltalk.category", $2);
     393             :       }
     394             :     }
     395             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     396             : | tok_smalltalk_prefix tok_identifier
     397             :     {
     398           0 :       pwarning(1, "'smalltalk_prefix' is deprecated. Use 'namespace smalltalk.prefix' instead");
     399           0 :       pdebug("Header -> tok_smalltalk_prefix tok_identifier");
     400           0 :       if (g_parse_mode == PROGRAM) {
     401           0 :         g_program->set_namespace("smalltalk.prefix", $2);
     402             :       }
     403             :     }
     404             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     405             : | tok_java_package tok_identifier
     406             :     {
     407           0 :       pwarning(1, "'java_package' is deprecated. Use 'namespace java' instead");
     408           0 :       pdebug("Header -> tok_java_package tok_identifier");
     409           0 :       if (g_parse_mode == PROGRAM) {
     410           0 :         g_program->set_namespace("java", $2);
     411             :       }
     412             :     }
     413             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     414             : | tok_cocoa_prefix tok_identifier
     415             :     {
     416           0 :       pwarning(1, "'cocoa_prefix' is deprecated. Use 'namespace cocoa' instead");
     417           0 :       pdebug("Header -> tok_cocoa_prefix tok_identifier");
     418           0 :       if (g_parse_mode == PROGRAM) {
     419           0 :         g_program->set_namespace("cocoa", $2);
     420             :       }
     421             :     }
     422             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     423             : | tok_xsd_namespace tok_literal
     424             :     {
     425           0 :       pwarning(1, "'xsd_namespace' is deprecated. Use 'namespace xsd' instead");
     426           0 :       pdebug("Header -> tok_xsd_namespace tok_literal");
     427           0 :       if (g_parse_mode == PROGRAM) {
     428           0 :         g_program->set_namespace("cocoa", $2);
     429             :       }
     430             :     }
     431             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     432             : | tok_csharp_namespace tok_identifier
     433             :    {
     434           0 :      pwarning(1, "'csharp_namespace' is deprecated. Use 'namespace csharp' instead");
     435           0 :      pdebug("Header -> tok_csharp_namespace tok_identifier");
     436           0 :      if (g_parse_mode == PROGRAM) {
     437           0 :        g_program->set_namespace("csharp", $2);
     438             :      }
     439             :    }
     440             : /* TODO(dreiss): Get rid of this once everyone is using the new hotness. */
     441             : | tok_delphi_namespace tok_identifier
     442             :    {
     443           0 :      pwarning(1, "'delphi_namespace' is deprecated. Use 'namespace delphi' instead");
     444           0 :      pdebug("Header -> tok_delphi_namespace tok_identifier");
     445           0 :      if (g_parse_mode == PROGRAM) {
     446           0 :        g_program->set_namespace("delphi", $2);
     447             :      }
     448             :    }
     449             : 
     450             : Include:
     451             :   tok_include tok_literal
     452             :     {
     453          72 :       pdebug("Include -> tok_include tok_literal");
     454          72 :       if (g_parse_mode == INCLUDES) {
     455          72 :         std::string path = include_file(std::string($2));
     456          36 :         if (!path.empty()) {
     457          36 :           g_program->add_include(path, std::string($2));
     458             :         }
     459          36 :       }
     460             :     }
     461             : 
     462             : DefinitionList:
     463             :   DefinitionList CaptureDocText Definition
     464             :     {
     465        7240 :       pdebug("DefinitionList -> DefinitionList Definition");
     466        7240 :       if ($2 != NULL && $3 != NULL) {
     467         800 :         $3->set_doc($2);
     468             :       }
     469             :     }
     470             : |
     471             :     {
     472         584 :       pdebug("DefinitionList -> ");
     473             :     }
     474             : 
     475             : Definition:
     476             :   Const
     477             :     {
     478        2544 :       pdebug("Definition -> Const");
     479        2544 :       if (g_parse_mode == PROGRAM) {
     480        1272 :         g_program->add_const($1);
     481             :       }
     482        2544 :       $$ = $1;
     483             :     }
     484             : | TypeDefinition
     485             :     {
     486        2536 :       pdebug("Definition -> TypeDefinition");
     487        2536 :       if (g_parse_mode == PROGRAM) {
     488        1268 :         g_scope->add_type($1->get_name(), $1);
     489        1268 :         if (g_parent_scope != NULL) {
     490         246 :           g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
     491             :         }
     492             :       }
     493        2536 :       $$ = $1;
     494             :     }
     495             : | Service
     496             :     {
     497           0 :       pdebug("Definition -> Service");
     498           0 :       if (g_parse_mode == PROGRAM) {
     499           0 :         g_scope->add_service($1->get_name(), $1);
     500           0 :         if (g_parent_scope != NULL) {
     501           0 :           g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
     502             :         }
     503           0 :         g_program->add_service($1);
     504             :       }
     505           0 :       $$ = $1;
     506             :     }
     507             : | Sandesh
     508             :     {
     509        2160 :       pdebug("Definition -> Sandesh");
     510        2160 :       if (g_parse_mode == PROGRAM) {
     511        1080 :         if (g_scope->get_sandesh($1->get_name())) {
     512           0 :           yyerror("Duplicate definition of sandesh: %s ", $1->get_name().c_str());
     513           0 :           exit(1);
     514             :         }
     515        1080 :         g_scope->add_sandesh($1->get_name(), $1);
     516        1080 :         if (g_parent_scope != NULL) {
     517         108 :           g_parent_scope->add_sandesh(g_parent_prefix + $1->get_name(), $1);
     518             :         }
     519        1080 :         g_program->add_sandesh($1);
     520             :       }
     521        2160 :       $$ = $1;
     522             :     }
     523             : 
     524             : 
     525             : TypeDefinition:
     526             :   Typedef
     527             :     {
     528           0 :       pdebug("TypeDefinition -> Typedef");
     529           0 :       if (g_parse_mode == PROGRAM) {
     530           0 :         g_program->add_typedef($1);
     531             :       }
     532             :     }
     533             : | Enum
     534             :     {
     535         396 :       pdebug("TypeDefinition -> Enum");
     536         396 :       if (g_parse_mode == PROGRAM) {
     537         198 :         g_program->add_enum($1);
     538             :       }
     539             :     }
     540             : | Senum
     541             :     {
     542           0 :       pdebug("TypeDefinition -> Senum");
     543           0 :       if (g_parse_mode == PROGRAM) {
     544           0 :         g_program->add_typedef($1);
     545             :       }
     546             :     }
     547             : | Struct
     548             :     {
     549        2140 :       pdebug("TypeDefinition -> Struct");
     550        2140 :       if (g_parse_mode == PROGRAM) {
     551        1070 :         g_program->add_struct($1);
     552             :       }
     553             :     }
     554             : | Xception
     555             :     {
     556           0 :       pdebug("TypeDefinition -> Xception");
     557           0 :       if (g_parse_mode == PROGRAM) {
     558           0 :         g_program->add_xception($1);
     559             :       }
     560             :     }
     561             : 
     562             : Typedef:
     563             :   tok_typedef FieldType tok_identifier
     564             :     {
     565           0 :       pdebug("TypeDef -> tok_typedef FieldType tok_identifier");
     566           0 :       t_typedef *td = new t_typedef(g_program, $2, $3);
     567           0 :       $$ = td;
     568             :     }
     569             : 
     570             : CommaOrSemicolonOptional:
     571             :   ','
     572             :     {}
     573             : | ';'
     574             :     {}
     575             : |
     576             :     {}
     577             : 
     578             : Enum:
     579             :   tok_enum tok_identifier '{' EnumDefList '}'
     580             :     {
     581         396 :       pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
     582         396 :       $$ = $4;
     583         396 :       $$->set_name($2);
     584         396 :       $$->resolve_values();
     585             :       // make constants for all the enum values
     586         396 :       if (g_parse_mode == PROGRAM) {
     587         198 :         const std::vector<t_enum_value*>& enum_values = $$->get_constants();
     588         198 :         std::vector<t_enum_value*>::const_iterator c_iter;
     589        1800 :         for (c_iter = enum_values.begin(); c_iter != enum_values.end(); ++c_iter) {
     590        1602 :           std::string const_name = $$->get_name() + "." + (*c_iter)->get_name();
     591        1602 :           t_const_value* const_val = new t_const_value((*c_iter)->get_value());
     592        1602 :           const_val->set_enum($$);
     593        1602 :           g_scope->add_constant(const_name, new t_const(g_type_i32, (*c_iter)->get_name(), const_val));
     594        1602 :           if (g_parent_scope != NULL) {
     595         288 :             g_parent_scope->add_constant(g_parent_prefix + const_name, new t_const(g_type_i32, (*c_iter)->get_name(), const_val));
     596             :           }
     597        1602 :         }
     598             :       }
     599             :     }
     600             : 
     601             : EnumDefList:
     602             :   EnumDefList EnumDef
     603             :     {
     604        3204 :       pdebug("EnumDefList -> EnumDefList EnumDef");
     605        3204 :       $$ = $1;
     606        3204 :       $$->append($2);
     607             :     }
     608             : |
     609             :     {
     610         396 :       pdebug("EnumDefList -> ");
     611         396 :       $$ = new t_enum(g_program);
     612             :     }
     613             : 
     614             : EnumDef:
     615             :   CaptureDocText tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
     616             :     {
     617         420 :       pdebug("EnumDef -> tok_identifier = tok_int_constant");
     618         420 :       if ($4 < 0) {
     619          12 :         pwarning(1, "Negative value supplied for enum %s.\n", $2);
     620             :       }
     621         420 :       if ($4 > INT_MAX) {
     622           0 :         pwarning(1, "64-bit value supplied for enum %s.\n", $2);
     623             :       }
     624         420 :       $$ = new t_enum_value($2, $4);
     625         420 :       if ($1 != NULL) {
     626           0 :         $$->set_doc($1);
     627             :       }
     628             :     }
     629             : |
     630             :   CaptureDocText tok_identifier CommaOrSemicolonOptional
     631             :     {
     632        2784 :       pdebug("EnumDef -> tok_identifier");
     633        2784 :       $$ = new t_enum_value($2);
     634        2784 :       if ($1 != NULL) {
     635           0 :         $$->set_doc($1);
     636             :       }
     637             :     }
     638             : 
     639             : Senum:
     640             :   tok_senum tok_identifier '{' SenumDefList '}'
     641             :     {
     642           0 :       pdebug("Senum -> tok_senum tok_identifier { SenumDefList }");
     643           0 :       $$ = new t_typedef(g_program, $4, $2);
     644             :     }
     645             : 
     646             : SenumDefList:
     647             :   SenumDefList SenumDef
     648             :     {
     649           0 :       pdebug("SenumDefList -> SenumDefList SenumDef");
     650           0 :       $$ = $1;
     651           0 :       $$->add_string_enum_val($2);
     652             :     }
     653             : |
     654             :     {
     655           0 :       pdebug("SenumDefList -> ");
     656           0 :       $$ = new t_base_type("string", t_base_type::TYPE_STRING);
     657           0 :       $$->set_string_enum(true);
     658             :     }
     659             : 
     660             : SenumDef:
     661             :   tok_literal CommaOrSemicolonOptional
     662             :     {
     663           0 :       pdebug("SenumDef -> tok_literal");
     664           0 :       $$ = $1;
     665             :     }
     666             : 
     667             : Const:
     668             :   tok_const FieldType tok_identifier '=' ConstValue CommaOrSemicolonOptional
     669             :     {
     670        2544 :       pdebug("Const -> tok_const FieldType tok_identifier = ConstValue");
     671        2544 :       if (g_parse_mode == PROGRAM) {
     672        1272 :         g_scope->resolve_const_value($5, $2);
     673        1272 :         $$ = new t_const($2, $3, $5);
     674        1272 :         validate_const_type($$);
     675             : 
     676        1272 :         g_scope->add_constant($3, $$);
     677        1272 :         if (g_parent_scope != NULL) {
     678          48 :           g_parent_scope->add_constant(g_parent_prefix + $3, $$);
     679             :         }
     680             :       } else {
     681        1272 :         $$ = NULL;
     682             :       }
     683             :     }
     684             : 
     685             : ConstValue:
     686             :   tok_int_constant
     687             :     {
     688        1008 :       pdebug("ConstValue => tok_int_constant");
     689        1008 :       $$ = new t_const_value();
     690        1008 :       $$->set_integer($1);
     691        1008 :       if (!g_allow_64bit_consts && ($1 < INT32_MIN || $1 > INT32_MAX)) {
     692           0 :         pwarning(1, "64-bit constant \"%" PRIi64 "\" may not work in all languages.\n", $1);
     693             :       }
     694             :     }
     695             : | tok_dub_constant
     696             :     {
     697           0 :       pdebug("ConstValue => tok_dub_constant");
     698           0 :       $$ = new t_const_value();
     699           0 :       $$->set_double($1);
     700             :     }
     701             : | tok_literal
     702             :     {
     703        3828 :       pdebug("ConstValue => tok_literal");
     704        3828 :       $$ = new t_const_value($1);
     705             :     }
     706             : | tok_identifier
     707             :     {
     708        7116 :       pdebug("ConstValue => tok_identifier");
     709        7116 :       $$ = new t_const_value();
     710        7116 :       $$->set_identifier($1);
     711             :     }
     712             : | ConstList
     713             :     {
     714         528 :       pdebug("ConstValue => ConstList");
     715         528 :       $$ = $1;
     716             :     }
     717             : | ConstMap
     718             :     {
     719         456 :       pdebug("ConstValue => ConstMap");
     720         456 :       $$ = $1;
     721             :     }
     722             : 
     723             : ConstList:
     724             :   '[' ConstListContents ']'
     725             :     {
     726         528 :       pdebug("ConstList => [ ConstListContents ]");
     727         528 :       $$ = $2;
     728             :     }
     729             : 
     730             : ConstListContents:
     731             :   ConstListContents ConstValue CommaOrSemicolonOptional
     732             :     {
     733        1428 :       pdebug("ConstListContents => ConstListContents ConstValue CommaOrSemicolonOptional");
     734        1428 :       $$ = $1;
     735        1428 :       $$->add_list($2);
     736             :     }
     737             : |
     738             :     {
     739         528 :       pdebug("ConstListContents =>");
     740         528 :       $$ = new t_const_value();
     741         528 :       $$->set_list();
     742             :     }
     743             : 
     744             : ConstMap:
     745             :   '{' ConstMapContents '}'
     746             :     {
     747         456 :       pdebug("ConstMap => { ConstMapContents }");
     748         456 :       $$ = $2;
     749             :     }
     750             : 
     751             : ConstMapContents:
     752             :   ConstMapContents ConstValue ':' ConstValue CommaOrSemicolonOptional
     753             :     {
     754        4476 :       pdebug("ConstMapContents => ConstMapContents ConstValue CommaOrSemicolonOptional");
     755        4476 :       $$ = $1;
     756        4476 :       $$->add_map($2, $4);
     757             :     }
     758             : |
     759             :     {
     760         456 :       pdebug("ConstMapContents =>");
     761         456 :       $$ = new t_const_value();
     762         456 :       $$->set_map();
     763             :     }
     764             : 
     765             : StructHead:
     766             :   tok_struct
     767             :     {
     768        2128 :       $$ = struct_is_struct;
     769             :     }
     770             : | tok_union
     771             :     {
     772          12 :       $$ = struct_is_union;
     773             :     }
     774             : 
     775             : Struct:
     776             :   StructHead tok_identifier XsdAll '{' FieldList '}' TypeAnnotations
     777             :     {
     778        2140 :       pdebug("Struct -> tok_struct tok_identifier { FieldList }");
     779        2140 :       $5->set_xsd_all($3);
     780        2140 :       $5->set_union($1 == struct_is_union);
     781        2140 :       $$ = $5;
     782        2140 :       $$->set_name($2);
     783        2140 :       if ($7 != NULL) {
     784           0 :         $$->annotations_ = $7->annotations_;
     785           0 :         delete $7;
     786             :       }
     787             :     }
     788             : 
     789             : XsdAll:
     790             :   tok_xsd_all
     791             :     {
     792           0 :       $$ = true;
     793             :     }
     794             : |
     795             :     {
     796        2140 :       $$ = false;
     797             :     }
     798             : 
     799             : XsdOptional:
     800             :   tok_xsd_optional
     801             :     {
     802           0 :       $$ = true;
     803             :     }
     804             : |
     805             :     {
     806       15252 :       $$ = false;
     807             :     }
     808             : 
     809             : XsdNillable:
     810             :   tok_xsd_nillable
     811             :     {
     812           0 :       $$ = true;
     813             :     }
     814             : |
     815             :     {
     816       15252 :       $$ = false;
     817             :     }
     818             : 
     819             : XsdAttributes:
     820             :   tok_xsd_attrs '{' FieldList '}'
     821             :     {
     822           0 :       $$ = $3;
     823             :     }
     824             : |
     825             :     {
     826       15252 :       $$ = NULL;
     827             :     }
     828             : 
     829             : Xception:
     830             :   tok_xception tok_identifier '{' FieldList '}'
     831             :     {
     832           0 :       pdebug("Xception -> tok_xception tok_identifier { FieldList }");
     833           0 :       $4->set_name($2);
     834           0 :       $4->set_xception(true);
     835           0 :       $$ = $4;
     836             :     }
     837             : 
     838             : Sandesh:
     839             :   SandeshType tok_sandesh tok_identifier '{' SFieldList '}' TypeAnnotations
     840             :     {
     841        2160 :       pdebug("Sandesh -> tok_sandesh tok_identifier { SFieldList }");
     842        2160 :       $5->set_name($3);
     843        2160 :       $5->set_type($1);
     844             : 
     845        2160 :       if (($1 != g_type_sandesh_request) &&
     846        1608 :           ($1 != g_type_sandesh_response) &&
     847        1152 :           ($1 != g_type_sandesh_object)) {
     848        1028 :           if ($5->exist_opt_field()) {
     849           0 :               yyerror("optional field not supported in sandesh");
     850           0 :               exit(1);
     851             :           }
     852             :       }
     853             : 
     854        2160 :       if ($1 == g_type_sandesh_response) {
     855         456 :           $5->append(new t_field(g_type_bool, "more", 0, true));
     856        1704 :       } else if ($1 == g_type_sandesh_request) {
     857        1152 :       } else if ($1 == g_type_sandesh_system || $1 == g_type_sandesh_object) {
     858         500 :           $5->append(new t_field(g_type_string, "file", SHRT_MIN, true));
     859         500 :           $5->append(new t_field(g_type_i32, "line", SHRT_MIN + 1, true));
     860         652 :       } else if ($1 == g_type_sandesh_trace || $1 == g_type_sandesh_trace_object) {
     861         336 :           $5->append(new t_field(g_type_string, "file", SHRT_MIN, true));
     862         336 :           $5->append(new t_field(g_type_i32, "line", SHRT_MIN + 1, true));
     863             :       }
     864        2160 :       $$ = $5;
     865        2160 :       if ($7 != NULL) {
     866           0 :         $$->annotations_ = $7->annotations_;
     867           0 :         delete $7;
     868             :       }
     869             :     }
     870             : 
     871             : SandeshType:
     872             :   tok_system
     873             :     {
     874         376 :       $$ = g_type_sandesh_system;
     875             :     }
     876             : |
     877             :   tok_request
     878             :     {
     879         552 :       $$ = g_type_sandesh_request;
     880             :     }
     881             : |
     882             :   tok_response
     883             :     {
     884         456 :       $$ = g_type_sandesh_response;
     885             :     }
     886             : |
     887             :   tok_trace
     888             :     {
     889         324 :       $$ = g_type_sandesh_trace;
     890             :     }
     891             : |
     892             :   tok_trace_object
     893             :     {
     894          12 :       $$ = g_type_sandesh_trace_object;
     895             :     }
     896             : |
     897             :   tok_buffer
     898             :     {
     899           0 :       $$ = g_type_sandesh_buffer;
     900             :     }
     901             : |
     902             :   tok_uve
     903             :     {
     904         256 :       $$ = g_type_sandesh_uve;
     905             :     }
     906             : |
     907             :   tok_dynamic_uve
     908             :     {
     909          36 :       $$ = g_type_sandesh_dynamic_uve;
     910             :     }
     911             : |
     912             :   tok_object
     913             :     {
     914         124 :       $$ = g_type_sandesh_object;
     915             :     }
     916             : |
     917             :   tok_flow
     918             :     {
     919           0 :       $$ = g_type_sandesh_flow;
     920             :     }
     921             : |
     922             :   tok_alarm
     923             :     {
     924          12 :       $$ = g_type_sandesh_alarm;
     925             :     }
     926             : |
     927             :   tok_session
     928             :     {
     929          12 :       $$ = g_type_sandesh_session;
     930             :     }
     931             : 
     932             : Service:
     933             :   tok_service tok_identifier Extends '{' FlagArgs FunctionList UnflagArgs '}'
     934             :     {
     935           0 :       pdebug("Service -> tok_service tok_identifier { FunctionList }");
     936           0 :       $$ = $6;
     937           0 :       $$->set_name($2);
     938           0 :       $$->set_extends($3);
     939             :     }
     940             : 
     941             : FlagArgs:
     942             :     {
     943           0 :        g_arglist = 1;
     944             :     }
     945             : 
     946             : UnflagArgs:
     947             :     {
     948           0 :        g_arglist = 0;
     949             :     }
     950             : 
     951             : Extends:
     952             :   tok_extends tok_identifier
     953             :     {
     954           0 :       pdebug("Extends -> tok_extends tok_identifier");
     955           0 :       $$ = NULL;
     956           0 :       if (g_parse_mode == PROGRAM) {
     957           0 :         $$ = g_scope->get_service($2);
     958           0 :         if ($$ == NULL) {
     959           0 :           yyerror("Service \"%s\" has not been defined.", $2);
     960           0 :           exit(1);
     961             :         }
     962             :       }
     963             :     }
     964             : |
     965             :     {
     966           0 :       $$ = NULL;
     967             :     }
     968             : 
     969             : FunctionList:
     970             :   FunctionList Function
     971             :     {
     972           0 :       pdebug("FunctionList -> FunctionList Function");
     973           0 :       $$ = $1;
     974           0 :       $1->add_function($2);
     975             :     }
     976             : |
     977             :     {
     978           0 :       pdebug("FunctionList -> ");
     979           0 :       $$ = new t_service(g_program);
     980             :     }
     981             : 
     982             : Function:
     983             :   CaptureDocText Oneway AbcFunction StaticFunction FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional
     984             :     {
     985           0 :       $8->set_name(std::string($6) + "_args");
     986           0 :       $$ = new t_function($5, $6, $8, $10, $2, $3, $4);
     987           0 :       if ($1 != NULL) {
     988           0 :         $$->set_doc($1);
     989             :       }
     990             :     }
     991             : 
     992             : Oneway:
     993             :   tok_oneway
     994             :     {
     995           0 :       $$ = true;
     996             :     }
     997             : |
     998             :     {
     999           0 :       $$ = false;
    1000             :     }
    1001             : 
    1002             : StaticFunction:
    1003             :   tok_staticfunction
    1004             :     {
    1005           0 :       $$ = true;
    1006             :     }
    1007             : |
    1008             :     {
    1009           0 :       $$ = false;
    1010             :     }
    1011             : 
    1012             : AbcFunction:
    1013             :   tok_abcfunction
    1014             :     {
    1015           0 :       $$ = true;
    1016             :     }
    1017             : |
    1018             :     {
    1019           0 :       $$ = false;
    1020             :     }
    1021             : 
    1022             : Throws:
    1023             :   tok_throws '(' FieldList ')'
    1024             :     {
    1025           0 :       pdebug("Throws -> tok_throws ( FieldList )");
    1026           0 :       $$ = $3;
    1027           0 :       if (g_parse_mode == PROGRAM && !validate_throws($$)) {
    1028           0 :         yyerror("Throws clause may not contain non-exception types");
    1029           0 :         exit(1);
    1030             :       }
    1031             :     }
    1032             : |
    1033             :     {
    1034           0 :       $$ = new t_struct(g_program);
    1035             :     }
    1036             : 
    1037             : FieldList:
    1038             :   FieldList Field
    1039             :     {
    1040       11372 :       pdebug("FieldList -> FieldList , Field");
    1041       11372 :       $$ = $1;
    1042       11372 :       if (!($$->append($2))) {
    1043           0 :         yyerror("Field identifier %d for \"%s\" has already been used", $2->get_key(), $2->get_name().c_str());
    1044           0 :         exit(1);
    1045             :       }
    1046             :     }
    1047             : |
    1048             :     {
    1049        2140 :       pdebug("FieldList -> ");
    1050        2140 :       y_field_val = -1;
    1051        2140 :       $$ = new t_struct(g_program);
    1052             :     }
    1053             : 
    1054             : SFieldList:
    1055             :   SFieldList Field
    1056             :     {
    1057        4228 :       pdebug("SFieldList -> SFieldList , Field");
    1058        4228 :       $$ = $1;
    1059             : 
    1060        4228 :       if (!($$->append($2))) {
    1061           0 :         yyerror("Field identifier %d for \"%s\" has already been used", $2->get_key(), $2->get_name().c_str());
    1062           0 :         exit(1);
    1063             :       }
    1064             :     }
    1065             : |
    1066             :     {
    1067        2160 :       pdebug("SFieldList -> ");
    1068        2160 :       y_field_val = -1;
    1069        2160 :       $$ = new t_sandesh(g_program);
    1070             :     }
    1071             : 
    1072             : Field:
    1073             :   CaptureDocText FieldIdentifier FieldRequiredness FieldType tok_identifier FieldValue XsdOptional XsdNillable XsdAttributes TypeAnnotations CommaOrSemicolonOptional
    1074             :     {
    1075       15252 :       pdebug("tok_int_constant : Field -> FieldType tok_identifier");
    1076       15252 :       if ($2.auto_assigned) {
    1077           0 :         pwarning(1, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $5);
    1078           0 :         if (g_strict >= 192) {
    1079           0 :           yyerror("Implicit field keys are deprecated and not allowed with -strict");
    1080           0 :           exit(1);
    1081             :         }
    1082             :       }
    1083       15252 :       $$ = new t_field($4, $5, $2.value);
    1084       15252 :       $$->set_req($3);
    1085       15252 :       if ($6 != NULL) {
    1086           6 :         g_scope->resolve_const_value($6, $4);
    1087           6 :         validate_field_value($$, $6);
    1088           6 :         $$->set_value($6);
    1089             :       }
    1090       15252 :       $$->set_xsd_optional($7);
    1091       15252 :       $$->set_xsd_nillable($8);
    1092       15252 :       if ($1 != NULL) {
    1093         754 :         $$->set_doc($1);
    1094             :       }
    1095       15252 :       if ($9 != NULL) {
    1096           0 :         $$->set_xsd_attrs($9);
    1097             :       }
    1098       15252 :       if ($10 != NULL) {
    1099        1032 :         $$->annotations_ = $10->annotations_;
    1100        1032 :         delete $10;
    1101             :       }
    1102             :     }
    1103             : |
    1104             :  CaptureDocText FieldIdentifier tok_literal CommaOrSemicolonOptional
    1105             :     {
    1106         348 :       pdebug("Field -> static string");
    1107         348 :       if ($2.auto_assigned) {
    1108           0 :         pwarning(1, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $3);
    1109           0 :         if (g_strict >= 192) {
    1110           0 :           yyerror("Implicit field keys are deprecated and not allowed with -strict");
    1111           0 :           exit(1);
    1112             :         }
    1113             :       }
    1114             : 
    1115         348 :       $$ = new t_field(g_type_static_const_string, t_field::auto_string_name($2.value), $2.value);
    1116             : 
    1117         348 :       $$->set_req(t_field::T_REQUIRED);
    1118         348 :       $$->set_value(new t_const_value($3));
    1119         348 :       if ($1 != NULL) {
    1120           0 :         $$->set_doc($1);
    1121             :       }
    1122             :     }
    1123             : 
    1124             : FieldIdentifier:
    1125             :   tok_int_constant ':'
    1126             :     {
    1127       15600 :       if ($1 <= 0) {
    1128           0 :         if (g_allow_neg_field_keys) {
    1129             :           /*
    1130             :            * g_allow_neg_field_keys exists to allow users to add explicitly
    1131             :            * specified key values to old .thrift files without breaking
    1132             :            * protocol compatibility.
    1133             :            */
    1134           0 :           if ($1 != y_field_val) {
    1135             :             /*
    1136             :              * warn if the user-specified negative value isn't what
    1137             :              * thrift would have auto-assigned.
    1138             :              */
    1139           0 :             pwarning(1, "Negative field key (%d) differs from what would be "
    1140           0 :                      "auto-assigned by thrift (%d).\n", $1, y_field_val);
    1141             :           }
    1142             :           /*
    1143             :            * Leave $1 as-is, and update y_field_val to be one less than $1.
    1144             :            * The FieldList parsing will catch any duplicate key values.
    1145             :            */
    1146           0 :           y_field_val = $1 - 1;
    1147           0 :           $$.value = $1;
    1148           0 :           $$.auto_assigned = false;
    1149             :         } else {
    1150           0 :           pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n",
    1151           0 :                    $1);
    1152           0 :           $$.value = y_field_val--;
    1153           0 :           $$.auto_assigned = true;
    1154             :         }
    1155             :       } else {
    1156       15600 :         $$.value = $1;
    1157       15600 :         $$.auto_assigned = false;
    1158             :       }
    1159             :     }
    1160             : |
    1161             :     {
    1162           0 :       $$.value = y_field_val--;
    1163           0 :       $$.auto_assigned = true;
    1164             :     }
    1165             : 
    1166             : FieldRequiredness:
    1167             :   tok_required
    1168             :     {
    1169           0 :       $$ = t_field::T_REQUIRED;
    1170             :     }
    1171             : | tok_optional
    1172             :     {
    1173        4028 :       if (g_arglist) {
    1174           0 :         if (g_parse_mode == PROGRAM) {
    1175           0 :           pwarning(1, "optional keyword is ignored in argument lists.\n");
    1176             :         }
    1177           0 :         $$ = t_field::T_OPT_IN_REQ_OUT;
    1178             :       } else {
    1179        4028 :         $$ = t_field::T_OPTIONAL;
    1180             :       }
    1181             :     }
    1182             : |
    1183             :     {
    1184       11224 :       $$ = t_field::T_OPT_IN_REQ_OUT;
    1185             :     }
    1186             : 
    1187             : FieldValue:
    1188             :   '=' ConstValue
    1189             :     {
    1190          12 :       if (g_parse_mode == PROGRAM) {
    1191           6 :         $$ = $2;
    1192             :       } else {
    1193           6 :         $$ = NULL;
    1194             :       }
    1195             :     }
    1196             : |
    1197             :     {
    1198       15240 :       $$ = NULL;
    1199             :     }
    1200             : 
    1201             : FunctionType:
    1202             :   FieldType
    1203             :     {
    1204           0 :       pdebug("FunctionType -> FieldType");
    1205           0 :       $$ = $1;
    1206             :     }
    1207             : | tok_void
    1208             :     {
    1209           0 :       pdebug("FunctionType -> tok_void");
    1210           0 :       $$ = g_type_void;
    1211             :     }
    1212             : 
    1213             : FieldType:
    1214             :   tok_identifier
    1215             :     {
    1216        2360 :       pdebug("FieldType -> tok_identifier");
    1217        2360 :       if (g_parse_mode == INCLUDES) {
    1218             :         // Ignore identifiers in include mode
    1219        1180 :         $$ = NULL;
    1220             :       } else {
    1221             :         // Lookup the identifier in the current scope
    1222        1180 :         $$ = g_scope->get_type($1);
    1223        1180 :         if ($$ == NULL) {
    1224           0 :           yyerror("Type \"%s\" has not been defined.", $1);
    1225           0 :           exit(1);
    1226             :         }
    1227             :       }
    1228             :     }
    1229             : | BaseType
    1230             :     {
    1231       16412 :       pdebug("FieldType -> BaseType");
    1232       16412 :       $$ = $1;
    1233             :     }
    1234             : | ContainerType
    1235             :     {
    1236        2672 :       pdebug("FieldType -> ContainerType");
    1237        2672 :       $$ = $1;
    1238             :     }
    1239             : 
    1240             : BaseType: SimpleBaseType TypeAnnotations
    1241             :     {
    1242       16412 :       pdebug("BaseType -> SimpleBaseType TypeAnnotations");
    1243       16412 :       if ($2 != NULL) {
    1244           0 :         $$ = new t_base_type(*static_cast<t_base_type*>($1));
    1245           0 :         $$->annotations_ = $2->annotations_;
    1246           0 :         delete $2;
    1247             :       } else {
    1248       16412 :         $$ = $1;
    1249             :       }
    1250             :     }
    1251             : 
    1252             : SimpleBaseType:
    1253             : tok_string
    1254             :     {
    1255        9936 :       pdebug("BaseType -> tok_string");
    1256        9936 :       $$ = g_type_string;
    1257             :     }
    1258             : | tok_binary
    1259             :     {
    1260           0 :       pdebug("BaseType -> tok_binary");
    1261           0 :       $$ = g_type_binary;
    1262             :     }
    1263             : | tok_slist
    1264             :     {
    1265           0 :       pdebug("BaseType -> tok_slist");
    1266           0 :       $$ = g_type_slist;
    1267             :     }
    1268             : | tok_bool
    1269             :     {
    1270         880 :       pdebug("BaseType -> tok_bool");
    1271         880 :       $$ = g_type_bool;
    1272             :     }
    1273             : | tok_byte
    1274             :     {
    1275         108 :       pdebug("BaseType -> tok_byte");
    1276         108 :       $$ = g_type_byte;
    1277             :     }
    1278             : | tok_i16
    1279             :     {
    1280          48 :       pdebug("BaseType -> tok_i16");
    1281          48 :       $$ = g_type_i16;
    1282             :     }
    1283             : | tok_i32
    1284             :     {
    1285         380 :       pdebug("BaseType -> tok_i32");
    1286         380 :       $$ = g_type_i32;
    1287             :     }
    1288             : | tok_i64
    1289             :     {
    1290         276 :       pdebug("BaseType -> tok_i64");
    1291         276 :       $$ = g_type_i64;
    1292             :     }
    1293             : | tok_double
    1294             :     {
    1295         716 :       pdebug("BaseType -> tok_double");
    1296         716 :       $$ = g_type_double;
    1297             :     }
    1298             : | tok_u16
    1299             :     {
    1300         948 :       pdebug("BaseType -> tok_u16");
    1301         948 :       $$ = g_type_u16;
    1302             :     }
    1303             : | tok_u32
    1304             :     {
    1305        1152 :       pdebug("BaseType -> tok_u32");
    1306        1152 :       $$ = g_type_u32;
    1307             :     }
    1308             : | tok_u64
    1309             :     {
    1310        1632 :       pdebug("BaseType -> tok_u64");
    1311        1632 :       $$ = g_type_u64;
    1312             :     }
    1313             : | tok_ipv4
    1314             :     {
    1315          24 :       pdebug("BaseType -> tok_ipv4");
    1316          24 :       $$ = g_type_ipv4;
    1317             :     }
    1318             : | tok_ipaddr
    1319             :     {
    1320          96 :       pdebug("BaseType -> tok_ipaddr");
    1321          96 :       $$ = g_type_ipaddr;
    1322             :     }
    1323             : | tok_xml
    1324             :     {
    1325         108 :       pdebug("BaseType -> tok_xml");
    1326         108 :       $$ = g_type_xml;
    1327             :     }
    1328             : | tok_uuid_t
    1329             :     {
    1330         108 :       pdebug("BaseType -> tok_uuid_t");
    1331         108 :       $$ = g_type_uuid_t;
    1332             :     }
    1333             : 
    1334             : ContainerType: SimpleContainerType TypeAnnotations
    1335             :     {
    1336        2672 :       pdebug("ContainerType -> SimpleContainerType TypeAnnotations");
    1337        2672 :       $$ = $1;
    1338        2672 :       if ($2 != NULL) {
    1339           0 :         $$->annotations_ = $2->annotations_;
    1340           0 :         delete $2;
    1341             :       }
    1342             :     }
    1343             : 
    1344             : SimpleContainerType:
    1345             :   MapType
    1346             :     {
    1347         976 :       pdebug("SimpleContainerType -> MapType");
    1348         976 :       $$ = $1;
    1349             :     }
    1350             : | SetType
    1351             :     {
    1352          48 :       pdebug("SimpleContainerType -> SetType");
    1353          48 :       $$ = $1;
    1354             :     }
    1355             : | ListType
    1356             :     {
    1357        1648 :       pdebug("SimpleContainerType -> ListType");
    1358        1648 :       $$ = $1;
    1359             :     }
    1360             : 
    1361             : MapType:
    1362             :   tok_map CppType '<' FieldType ',' FieldType '>'
    1363             :     {
    1364         976 :       pdebug("MapType -> tok_map <FieldType, FieldType>");
    1365         976 :       $$ = new t_map($4, $6);
    1366         976 :       if ($2 != NULL) {
    1367           0 :         ((t_container*)$$)->set_cpp_name(std::string($2));
    1368             :       }
    1369             :     }
    1370             : 
    1371             : SetType:
    1372             :   tok_set CppType '<' FieldType '>'
    1373             :     {
    1374          48 :       pdebug("SetType -> tok_set<FieldType>");
    1375          48 :       $$ = new t_set($4);
    1376          48 :       if ($2 != NULL) {
    1377           0 :         ((t_container*)$$)->set_cpp_name(std::string($2));
    1378             :       }
    1379             :     }
    1380             : 
    1381             : ListType:
    1382             :   tok_list '<' FieldType '>' CppType
    1383             :     {
    1384        1648 :       pdebug("ListType -> tok_list<FieldType>");
    1385        1648 :       $$ = new t_list($3);
    1386        1648 :       if ($5 != NULL) {
    1387           0 :         ((t_container*)$$)->set_cpp_name(std::string($5));
    1388             :       }
    1389             :     }
    1390             : 
    1391             : CppType:
    1392             :   tok_cpp_type tok_literal
    1393             :     {
    1394           0 :       $$ = $2;
    1395             :     }
    1396             : |
    1397             :     {
    1398        2672 :       $$ = NULL;
    1399             :     }
    1400             : 
    1401             : TypeAnnotations:
    1402             :   '(' TypeAnnotationList ')'
    1403             :     {
    1404        1032 :       pdebug("TypeAnnotations -> ( TypeAnnotationList )");
    1405        1032 :       $$ = $2;
    1406             :     }
    1407             : |
    1408             :     {
    1409       37604 :       $$ = NULL;
    1410             :     }
    1411             : 
    1412             : TypeAnnotationList:
    1413             :   TypeAnnotationList TypeAnnotation
    1414             :     {
    1415        1068 :       pdebug("TypeAnnotationList -> TypeAnnotationList , TypeAnnotation");
    1416        1068 :       $$ = $1;
    1417        1068 :       $$->annotations_[$2->key] = $2->val;
    1418        1068 :       delete $2;
    1419             :     }
    1420             : |
    1421             :     {
    1422             :       /* Just use a dummy structure to hold the annotations. */
    1423        1032 :       $$ = new t_struct(g_program);
    1424             :     }
    1425             : 
    1426             : TypeAnnotation:
    1427             :   tok_identifier '=' tok_literal CommaOrSemicolonOptional
    1428             :     {
    1429        1068 :       pdebug("TypeAnnotation -> tok_identifier = tok_literal");
    1430        1068 :       $$ = new t_annotation;
    1431        1068 :       $$->key = $1;
    1432        1068 :       $$->val = $3;
    1433             :     }
    1434             : 
    1435             : %%

Generated by: LCOV version 1.14