Update thrift compiler for new syntax, generate new form of C++ code
Reviewed By: wayne, he loves less warnings
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664840 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y
index 3bf8b53..7d1ba1e 100644
--- a/compiler/cpp/src/thrift.y
+++ b/compiler/cpp/src/thrift.y
@@ -12,6 +12,7 @@
#include "main.h"
#include "globals.h"
#include "parse/t_program.h"
+#include "parse/t_scope.h"
/**
* This global variable is used for automatic numbering of field indices etc.
@@ -44,7 +45,7 @@
* Strings identifier
*/
%token<id> tok_identifier
-%token<id> tok_cpptype
+%token<id> tok_literal
/**
* Integer constant value
@@ -52,9 +53,14 @@
%token<iconst> tok_int_constant
/**
- * Namespace keyword
+ * Header keywoards
*/
+%token tok_include
%token tok_namespace
+%token tok_cpp_namespace
+%token tok_cpp_include
+%token tok_cpp_type
+%token tok_java_package
/**
* Base datatype keywords
@@ -87,6 +93,7 @@
%token tok_struct
%token tok_xception
%token tok_throws
+%token tok_extends
%token tok_service
%token tok_enum
@@ -94,14 +101,14 @@
* Grammar nodes
*/
-%type<id> Namespace
-
%type<ttype> BaseType
%type<ttype> ContainerType
%type<ttype> MapType
%type<ttype> SetType
%type<ttype> ListType
+%type<ttype> TypeDefinition
+
%type<ttypedef> Typedef
%type<ttype> DefinitionType
@@ -122,6 +129,7 @@
%type<tservice> FunctionList
%type<tstruct> ThrowsOptional
+%type<tservice> ExtendsOptional
%type<tbool> AsyncOptional
%type<id> CppTypeOptional
@@ -136,10 +144,67 @@
*/
Program:
- DefinitionList
- {
- pdebug("Program -> DefinitionList");
- }
+ HeaderList DefinitionList
+ {
+ pdebug("Program -> Headers DefinitionList");
+ }
+
+HeaderList:
+ HeaderList Header
+ {
+ pdebug("HeaderList -> HeaderList Header");
+ }
+|
+ {
+ pdebug("HeaderList -> ");
+ }
+
+Header:
+ Include
+ {
+ pdebug("Header -> Include");
+ }
+| tok_namespace tok_identifier
+ {
+ pwarning(1, "'namespace' is deprecated. Use 'cpp_namespace' and/or 'java_package' instead");
+ if (g_parse_mode == PROGRAM) {
+ g_program->set_cpp_namespace($2);
+ g_program->set_java_package($2);
+ }
+ }
+| tok_cpp_namespace tok_identifier
+ {
+ pdebug("Header -> tok_cpp_namespace tok_identifier");
+ if (g_parse_mode == PROGRAM) {
+ g_program->set_cpp_namespace($2);
+ }
+ }
+| tok_cpp_include tok_literal
+ {
+ pdebug("Header -> tok_cpp_include tok_literal");
+ if (g_parse_mode == PROGRAM) {
+ g_program->add_cpp_include($2);
+ }
+ }
+| tok_java_package tok_identifier
+ {
+ pdebug("Header -> tok_java_package tok_identifier");
+ if (g_parse_mode == PROGRAM) {
+ g_program->set_java_package($2);
+ }
+ }
+
+Include:
+ tok_include tok_literal
+ {
+ pdebug("Include -> tok_include tok_literal");
+ if (g_parse_mode == INCLUDES) {
+ std::string path = include_file(std::string($2));
+ if (!path.empty()) {
+ g_program->add_include(path);
+ }
+ }
+ }
DefinitionList:
DefinitionList Definition
@@ -152,49 +217,63 @@
}
Definition:
- Namespace
+ TypeDefinition
{
- pdebug("Definition -> Namespace");
- g_program->set_namespace($1);
- }
-| Typedef
- {
- pdebug("Definition -> Typedef");
- g_program->add_typedef($1);
- }
-| Enum
- {
- pdebug("Definition -> Enum");
- g_program->add_enum($1);
- }
-| Struct
- {
- pdebug("Definition -> Struct");
- g_program->add_struct($1);
- }
-| Xception
- {
- pdebug("Definition -> Xception");
- g_program->add_xception($1);
+ pdebug("Definition -> TypeDefinition");
+ if (g_parse_mode == PROGRAM) {
+ g_scope->add_type($1->get_name(), $1);
+ if (g_parent_scope != NULL) {
+ g_parent_scope->add_type(g_parent_prefix + $1->get_name(), $1);
+ }
+ }
}
| Service
{
pdebug("Definition -> Service");
- g_program->add_service($1);
+ if (g_parse_mode == PROGRAM) {
+ g_scope->add_service($1->get_name(), $1);
+ if (g_parent_scope != NULL) {
+ g_parent_scope->add_service(g_parent_prefix + $1->get_name(), $1);
+ }
+ g_program->add_service($1);
+ }
}
-Namespace:
- tok_namespace tok_identifier
+TypeDefinition:
+ Typedef
{
- pdebug("Namespace -> tok_namespace tok_identifier");
- $$ = $2;
+ pdebug("TypeDefinition -> Typedef");
+ if (g_parse_mode == PROGRAM) {
+ g_program->add_typedef($1);
+ }
+ }
+| Enum
+ {
+ pdebug("TypeDefinition -> Enum");
+ if (g_parse_mode == PROGRAM) {
+ g_program->add_enum($1);
+ }
+ }
+| Struct
+ {
+ pdebug("TypeDefinition -> Struct");
+ if (g_parse_mode == PROGRAM) {
+ g_program->add_struct($1);
+ }
+ }
+| Xception
+ {
+ pdebug("TypeDefinition -> Xception");
+ if (g_parse_mode == PROGRAM) {
+ g_program->add_xception($1);
+ }
}
Typedef:
tok_typedef DefinitionType tok_identifier
{
pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
- t_typedef *td = new t_typedef($2, $3);
+ t_typedef *td = new t_typedef(g_program, $2, $3);
$$ = td;
}
@@ -216,13 +295,13 @@
| EnumDef
{
pdebug("EnumDefList -> EnumDef");
- $$ = new t_enum;
+ $$ = new t_enum(g_program);
$$->append($1);
}
|
{
pdebug("EnumDefList -> ");
- $$ = new t_enum;
+ $$ = new t_enum(g_program);
}
EnumDef:
@@ -230,7 +309,7 @@
{
pdebug("EnumDef => tok_identifier = tok_int_constant");
if ($3 < 0) {
- printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
+ pwarning(1, "Negative value supplied for enum %s.\n", $1);
}
$$ = new t_constant($1, $3);
}
@@ -261,11 +340,30 @@
}
Service:
- tok_service tok_identifier '{' FunctionList '}'
+ tok_service tok_identifier ExtendsOptional '{' FunctionList '}'
{
pdebug("Service -> tok_service tok_identifier { FunctionList }");
- $$ = $4;
+ $$ = $5;
$$->set_name($2);
+ $$->set_extends($3);
+ }
+
+ExtendsOptional:
+ tok_extends tok_identifier
+ {
+ pdebug("ExtendsOptional -> tok_extends tok_identifier");
+ $$ = NULL;
+ if (g_parse_mode == PROGRAM) {
+ $$ = g_scope->get_service($2);
+ if ($$ == NULL) {
+ yyerror("Service \"%s\" has not been defined.", $2);
+ exit(1);
+ }
+ }
+ }
+|
+ {
+ $$ = NULL;
}
FunctionList:
@@ -278,7 +376,7 @@
|
{
pdebug("FunctionList -> ");
- $$ = new t_service;
+ $$ = new t_service(g_program);
}
CommaOptional:
@@ -308,11 +406,12 @@
ThrowsOptional:
tok_throws '(' FieldList ')'
{
+ pdebug("ThrowsOptional -> tok_throws ( FieldList )");
$$ = $3;
}
|
{
- $$ = new t_struct;
+ $$ = new t_struct(g_program);
}
FieldList:
@@ -325,31 +424,41 @@
| Field
{
pdebug("FieldList -> Field");
- $$ = new t_struct;
+ $$ = new t_struct(g_program);
$$->append($1);
}
|
{
pdebug("FieldList -> ");
- $$ = new t_struct;
+ $$ = new t_struct(g_program);
}
Field:
- FieldType tok_identifier '=' tok_int_constant
+ tok_int_constant ':' FieldType tok_identifier
{
- pdebug("Field -> FieldType tok_identifier = tok_int_constant");
- if ($4 <= 0) {
- printf("WARNING (%d): Nonpositive value (%d) not allowed as a field key for '%s'.\n", yylineno, $4, $2);
- $4 = y_field_val--;
+ pdebug("tok_int_constant : Field -> FieldType tok_identifier");
+ if ($1 <= 0) {
+ pwarning(1, "Nonpositive value (%d) not allowed as a field key for '%s'.\n", $1, $4);
+ $1 = y_field_val--;
}
- $$ = new t_field($1, $2, $4);
+ $$ = new t_field($3, $4, $1);
}
| FieldType tok_identifier
{
pdebug("Field -> FieldType tok_identifier");
- printf("WARNING (%d): No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
+ pwarning(2, "No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", $2);
$$ = new t_field($1, $2, y_field_val--);
}
+| FieldType tok_identifier '=' tok_int_constant
+ {
+ pwarning(1, "Trailing = id notation is deprecated. Use 'Id: Type Name' notatio instead");
+ pdebug("Field -> FieldType tok_identifier = tok_int_constant");
+ if ($4 <= 0) {
+ pwarning(1, "Nonpositive value (%d) not allowed as a field key for '%s'.\n", $4, $2);
+ $4 = y_field_val--;
+ }
+ $$ = new t_field($1, $2, $4);
+ }
DefinitionType:
BaseType
@@ -372,17 +481,23 @@
| tok_void
{
pdebug("FunctionType -> tok_void");
- $$ = g_program->get_void_type();
+ $$ = g_type_void;
}
FieldType:
tok_identifier
{
pdebug("FieldType -> tok_identifier");
- $$ = g_program->get_custom_type($1);
- if ($$ == NULL) {
- yyerror("Type \"%s\" has not been defined.", $1);
- exit(1);
+ if (g_parse_mode == INCLUDES) {
+ // Ignore identifiers in include mode
+ $$ = NULL;
+ } else {
+ // Lookup the identifier in the current scope
+ $$ = g_scope->get_type($1);
+ if ($$ == NULL) {
+ yyerror("Type \"%s\" has not been defined.", $1);
+ exit(1);
+ }
}
}
| BaseType
@@ -400,37 +515,37 @@
tok_string
{
pdebug("BaseType -> tok_string");
- $$ = g_program->get_string_type();
+ $$ = g_type_string;
}
| tok_bool
{
pdebug("BaseType -> tok_bool");
- $$ = g_program->get_bool_type();
+ $$ = g_type_bool;
}
| tok_byte
{
pdebug("BaseType -> tok_byte");
- $$ = g_program->get_byte_type();
+ $$ = g_type_byte;
}
| tok_i16
{
pdebug("BaseType -> tok_i16");
- $$ = g_program->get_i16_type();
+ $$ = g_type_i16;
}
| tok_i32
{
pdebug("BaseType -> tok_i32");
- $$ = g_program->get_i32_type();
+ $$ = g_type_i32;
}
| tok_i64
{
pdebug("BaseType -> tok_i64");
- $$ = g_program->get_i64_type();
+ $$ = g_type_i64;
}
| tok_double
{
pdebug("BaseType -> tok_double");
- $$ = g_program->get_double_type();
+ $$ = g_type_double;
}
ContainerType:
@@ -471,19 +586,19 @@
}
ListType:
- tok_list CppTypeOptional '<' FieldType '>'
+ tok_list '<' FieldType '>' CppTypeOptional
{
pdebug("ListType -> tok_list<FieldType>");
- $$ = new t_list($4);
- if ($2 != NULL) {
- ((t_container*)$$)->set_cpp_name(std::string($2));
+ $$ = new t_list($3);
+ if ($5 != NULL) {
+ ((t_container*)$$)->set_cpp_name(std::string($5));
}
}
CppTypeOptional:
- tok_cpptype
+ '[' tok_cpp_type tok_literal ']'
{
- $$ = $1;
+ $$ = $3;
}
|
{