http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_field.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_field.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_field.h new file mode 100644 index 0000000..eece7bb --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_field.h @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_FIELD_H +#define T_FIELD_H + +#include <string> +#include <sstream> + +#include "t_doc.h" + +// Forward declare for xsd_attrs +class t_struct; + +/** + * Class to represent a field in a thrift structure. A field has a data type, + * a symbolic name, and a numeric identifier. + * + */ +class t_field : public t_doc { +public: + t_field(t_type* type, std::string name) + : type_(type), + name_(name), + key_(0), + value_(NULL), + xsd_optional_(false), + xsd_nillable_(false), + xsd_attrs_(NULL), + reference_(false) {} + + t_field(t_type* type, std::string name, int32_t key) + : type_(type), + name_(name), + key_(key), + req_(T_OPT_IN_REQ_OUT), + value_(NULL), + xsd_optional_(false), + xsd_nillable_(false), + xsd_attrs_(NULL), + reference_(false) {} + + ~t_field() {} + + t_type* get_type() const { return type_; } + + const std::string& get_name() const { return name_; } + + int32_t get_key() const { return key_; } + + enum e_req { T_REQUIRED, T_OPTIONAL, T_OPT_IN_REQ_OUT }; + + void set_req(e_req req) { req_ = req; } + + e_req get_req() const { return req_; } + + void set_value(t_const_value* value) { value_ = value; } + + t_const_value* get_value() { return value_; } + + void set_xsd_optional(bool xsd_optional) { xsd_optional_ = xsd_optional; } + + bool get_xsd_optional() const { return xsd_optional_; } + + void set_xsd_nillable(bool xsd_nillable) { xsd_nillable_ = xsd_nillable; } + + bool get_xsd_nillable() const { return xsd_nillable_; } + + void set_xsd_attrs(t_struct* xsd_attrs) { xsd_attrs_ = xsd_attrs; } + + t_struct* get_xsd_attrs() { return xsd_attrs_; } + + /** + * Comparator to sort fields in ascending order by key. + * Make this a functor instead of a function to help GCC inline it. + * The arguments are (const) references to const pointers to const t_fields. + */ + struct key_compare { + bool operator()(t_field const* const& a, t_field const* const& b) { + return a->get_key() < b->get_key(); + } + }; + + std::map<std::string, std::string> annotations_; + + bool get_reference() { return reference_; } + + void set_reference(bool reference) { reference_ = reference; } + +private: + t_type* type_; + std::string name_; + int32_t key_; + e_req req_; + t_const_value* value_; + + bool xsd_optional_; + bool xsd_nillable_; + t_struct* xsd_attrs_; + bool reference_; +}; + +/** + * A simple struct for the parser to use to store a field ID, and whether or + * not it was specified by the user or automatically chosen. + */ +struct t_field_id { + int32_t value; + bool auto_assigned; +}; + +#endif
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_function.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_function.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_function.h new file mode 100644 index 0000000..96886f3 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_function.h @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_FUNCTION_H +#define T_FUNCTION_H + +#include <string> +#include "t_type.h" +#include "t_struct.h" +#include "t_doc.h" + +/** + * Representation of a function. Key parts are return type, function name, + * optional modifiers, and an argument list, which is implemented as a thrift + * struct. + * + */ +class t_function : public t_doc { +public: + t_function(t_type* returntype, std::string name, t_struct* arglist, bool oneway = false) + : returntype_(returntype), name_(name), arglist_(arglist), oneway_(oneway) { + xceptions_ = new t_struct(NULL); + if (oneway_ && (!returntype_->is_void())) { + pwarning(1, "Oneway methods should return void.\n"); + } + } + + t_function(t_type* returntype, + std::string name, + t_struct* arglist, + t_struct* xceptions, + bool oneway = false) + : returntype_(returntype), + name_(name), + arglist_(arglist), + xceptions_(xceptions), + oneway_(oneway) { + if (oneway_ && !xceptions_->get_members().empty()) { + throw std::string("Oneway methods can't throw exceptions."); + } + if (oneway_ && (!returntype_->is_void())) { + pwarning(1, "Oneway methods should return void.\n"); + } + } + + ~t_function() {} + + t_type* get_returntype() const { return returntype_; } + + const std::string& get_name() const { return name_; } + + t_struct* get_arglist() const { return arglist_; } + + t_struct* get_xceptions() const { return xceptions_; } + + bool is_oneway() const { return oneway_; } + + std::map<std::string, std::string> annotations_; + +private: + t_type* returntype_; + std::string name_; + t_struct* arglist_; + t_struct* xceptions_; + bool oneway_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_list.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_list.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_list.h new file mode 100644 index 0000000..ac0d981 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_list.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_LIST_H +#define T_LIST_H + +#include "t_container.h" + +/** + * A list is a lightweight container type that just wraps another data type. + * + */ +class t_list : public t_container { +public: + t_list(t_type* elem_type) : elem_type_(elem_type) {} + + t_type* get_elem_type() const { return elem_type_; } + + bool is_list() const { return true; } + +private: + t_type* elem_type_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_map.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_map.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_map.h new file mode 100644 index 0000000..269aeab --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_map.h @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_MAP_H +#define T_MAP_H + +#include "t_container.h" + +/** + * A map is a lightweight container type that just wraps another two data + * types. + * + */ +class t_map : public t_container { +public: + t_map(t_type* key_type, t_type* val_type) : key_type_(key_type), val_type_(val_type) {} + + t_type* get_key_type() const { return key_type_; } + + t_type* get_val_type() const { return val_type_; } + + bool is_map() const { return true; } + +private: + t_type* key_type_; + t_type* val_type_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_program.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_program.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_program.h new file mode 100644 index 0000000..556ee6c --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_program.h @@ -0,0 +1,381 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_PROGRAM_H +#define T_PROGRAM_H + +#include <map> +#include <string> +#include <vector> + +// For program_name() +#include "main.h" + +#include "t_doc.h" +#include "t_scope.h" +#include "t_base_type.h" +#include "t_typedef.h" +#include "t_enum.h" +#include "t_const.h" +#include "t_struct.h" +#include "t_service.h" +#include "t_list.h" +#include "t_map.h" +#include "t_set.h" +#include "generate/t_generator_registry.h" +//#include "t_doc.h" + +/** + * Top level class representing an entire thrift program. A program consists + * fundamentally of the following: + * + * Typedefs + * Enumerations + * Constants + * Structs + * Exceptions + * Services + * + * The program module also contains the definitions of the base types. + * + */ +class t_program : public t_doc { +public: + t_program(std::string path, std::string name) + : path_(path), name_(name), out_path_("./"), out_path_is_absolute_(false) { + scope_ = new t_scope(); + } + + t_program(std::string path) : path_(path), out_path_("./"), out_path_is_absolute_(false) { + name_ = program_name(path); + scope_ = new t_scope(); + } + + ~t_program() { + if (scope_) { + delete scope_; + scope_ = NULL; + } + } + + // Path accessor + const std::string& get_path() const { return path_; } + + // Output path accessor + const std::string& get_out_path() const { return out_path_; } + + // Create gen-* dir accessor + bool is_out_path_absolute() const { return out_path_is_absolute_; } + + // Name accessor + const std::string& get_name() const { return name_; } + + // Namespace + const std::string& get_namespace() const { return namespace_; } + + // Include prefix accessor + const std::string& get_include_prefix() const { return include_prefix_; } + + // Accessors for program elements + const std::vector<t_typedef*>& get_typedefs() const { return typedefs_; } + const std::vector<t_enum*>& get_enums() const { return enums_; } + const std::vector<t_const*>& get_consts() const { return consts_; } + const std::vector<t_struct*>& get_structs() const { return structs_; } + const std::vector<t_struct*>& get_xceptions() const { return xceptions_; } + const std::vector<t_struct*>& get_objects() const { return objects_; } + const std::vector<t_service*>& get_services() const { return services_; } + const std::map<std::string, std::string>& get_namespaces() const { return namespaces_; } + + // Program elements + void add_typedef(t_typedef* td) { typedefs_.push_back(td); } + void add_enum(t_enum* te) { enums_.push_back(te); } + void add_const(t_const* tc) { consts_.push_back(tc); } + void add_struct(t_struct* ts) { + objects_.push_back(ts); + structs_.push_back(ts); + } + void add_xception(t_struct* tx) { + objects_.push_back(tx); + xceptions_.push_back(tx); + } + void add_service(t_service* ts) { services_.push_back(ts); } + + // Programs to include + const std::vector<t_program*>& get_includes() const { return includes_; } + + void set_out_path(std::string out_path, bool out_path_is_absolute) { + out_path_ = out_path; + out_path_is_absolute_ = out_path_is_absolute; + // Ensure that it ends with a trailing '/' (or '\' for windows machines) + char c = out_path_.at(out_path_.size() - 1); + if (!(c == '/' || c == '\\')) { + out_path_.push_back('/'); + } + } + + // Typename collision detection + /** + * Search for typename collisions + * @param t the type to test for collisions + * @return true if a certain collision was found, otherwise false + */ + bool is_unique_typename(t_type* t) { + int occurrences = program_typename_count(this, t); + for (std::vector<t_program*>::iterator it = includes_.begin(); it != includes_.end(); ++it) { + occurrences += program_typename_count(*it, t); + } + return 0 == occurrences; + } + + /** + * Search all type collections for duplicate typenames + * @param prog the program to search + * @param t the type to test for collisions + * @return the number of certain typename collisions + */ + int program_typename_count(t_program* prog, t_type* t) { + int occurrences = 0; + occurrences += collection_typename_count(prog, prog->typedefs_, t); + occurrences += collection_typename_count(prog, prog->enums_, t); + occurrences += collection_typename_count(prog, prog->objects_, t); + occurrences += collection_typename_count(prog, prog->services_, t); + return occurrences; + } + + /** + * Search a type collection for duplicate typenames + * @param prog the program to search + * @param type_collection the type collection to search + * @param t the type to test for collisions + * @return the number of certain typename collisions + */ + template <class T> + int collection_typename_count(t_program* prog, T type_collection, t_type* t) { + int occurrences = 0; + for (typename T::iterator it = type_collection.begin(); it != type_collection.end(); ++it) + if (t != *it && 0 == t->get_name().compare((*it)->get_name()) && is_common_namespace(prog, t)) + ++occurrences; + return occurrences; + } + + /** + * Determine whether identical typenames will collide based on namespaces. + * + * Because we do not know which languages the user will generate code for, + * collisions within programs (IDL files) having namespace declarations can be + * difficult to determine. Only guaranteed collisions return true (cause an error). + * Possible collisions involving explicit namespace declarations produce a warning. + * Other possible collisions go unreported. + * @param prog the program containing the preexisting typename + * @param t the type containing the typename match + * @return true if a collision within namespaces is found, otherwise false + */ + bool is_common_namespace(t_program* prog, t_type* t) { + // Case 1: Typenames are in the same program [collision] + if (prog == t->get_program()) { + pwarning(1, + "Duplicate typename %s found in %s", + t->get_name().c_str(), + t->get_program()->get_name().c_str()); + return true; + } + + // Case 2: Both programs have identical namespace scope/name declarations [collision] + bool match = true; + for (std::map<std::string, std::string>::iterator it = prog->namespaces_.begin(); + it != prog->namespaces_.end(); + ++it) { + if (0 == it->second.compare(t->get_program()->get_namespace(it->first))) { + pwarning(1, + "Duplicate typename %s found in %s,%s,%s and %s,%s,%s [file,scope,ns]", + t->get_name().c_str(), + t->get_program()->get_name().c_str(), + it->first.c_str(), + it->second.c_str(), + prog->get_name().c_str(), + it->first.c_str(), + it->second.c_str()); + } else { + match = false; + } + } + for (std::map<std::string, std::string>::iterator it = t->get_program()->namespaces_.begin(); + it != t->get_program()->namespaces_.end(); + ++it) { + if (0 == it->second.compare(prog->get_namespace(it->first))) { + pwarning(1, + "Duplicate typename %s found in %s,%s,%s and %s,%s,%s [file,scope,ns]", + t->get_name().c_str(), + t->get_program()->get_name().c_str(), + it->first.c_str(), + it->second.c_str(), + prog->get_name().c_str(), + it->first.c_str(), + it->second.c_str()); + } else { + match = false; + } + } + if (0 == prog->namespaces_.size() && 0 == t->get_program()->namespaces_.size()) { + pwarning(1, + "Duplicate typename %s found in %s and %s", + t->get_name().c_str(), + t->get_program()->get_name().c_str(), + prog->get_name().c_str()); + } + return match; + } + + // Scoping and namespacing + void set_namespace(std::string name) { namespace_ = name; } + + // Scope accessor + t_scope* scope() const { return scope_; } + + // Includes + + void add_include(std::string path, std::string include_site) { + t_program* program = new t_program(path); + + // include prefix for this program is the site at which it was included + // (minus the filename) + std::string include_prefix; + std::string::size_type last_slash = std::string::npos; + if ((last_slash = include_site.rfind("/")) != std::string::npos) { + include_prefix = include_site.substr(0, last_slash); + } + + program->set_include_prefix(include_prefix); + includes_.push_back(program); + } + + std::vector<t_program*>& get_includes() { return includes_; } + + void set_include_prefix(std::string include_prefix) { + include_prefix_ = include_prefix; + + // this is intended to be a directory; add a trailing slash if necessary + std::string::size_type len = include_prefix_.size(); + if (len > 0 && include_prefix_[len - 1] != '/') { + include_prefix_ += '/'; + } + } + + // Language neutral namespace / packaging + void set_namespace(std::string language, std::string name_space) { + if (language != "*") { + size_t sub_index = language.find('.'); + std::string base_language = language.substr(0, sub_index); + std::string sub_namespace; + + if (base_language == "smalltalk") { + pwarning(1, "Namespace 'smalltalk' is deprecated. Use 'st' instead"); + base_language = "st"; + } + + t_generator_registry::gen_map_t my_copy = t_generator_registry::get_generator_map(); + + t_generator_registry::gen_map_t::iterator it; + it = my_copy.find(base_language); + + if (it == my_copy.end()) { + std::string warning = "No generator named '" + base_language + "' could be found!"; + pwarning(1, warning.c_str()); + } else { + if (sub_index != std::string::npos) { + std::string sub_namespace = language.substr(sub_index + 1); + if (!it->second->is_valid_namespace(sub_namespace)) { + std::string warning = base_language + " generator does not accept '" + sub_namespace + + "' as sub-namespace!"; + pwarning(1, warning.c_str()); + } + } + } + } + + namespaces_[language] = name_space; + } + + std::string get_namespace(std::string language) const { + std::map<std::string, std::string>::const_iterator iter; + if ((iter = namespaces_.find(language)) != namespaces_.end() + || (iter = namespaces_.find("*")) != namespaces_.end()) { + return iter->second; + } + return std::string(); + } + + const std::map<std::string, std::string>& get_all_namespaces(){ + return namespaces_; + } + // Language specific namespace / packaging + + void add_cpp_include(std::string path) { cpp_includes_.push_back(path); } + + const std::vector<std::string>& get_cpp_includes() { return cpp_includes_; } + + void add_c_include(std::string path) { c_includes_.push_back(path); } + + const std::vector<std::string>& get_c_includes() { return c_includes_; } + +private: + // File path + std::string path_; + + // Name + std::string name_; + + // Output directory + std::string out_path_; + + // Output directory is absolute location for generated source (no gen-*) + bool out_path_is_absolute_; + + // Namespace + std::string namespace_; + + // Included programs + std::vector<t_program*> includes_; + + // Include prefix for this program, if any + std::string include_prefix_; + + // Identifier lookup scope + t_scope* scope_; + + // Components to generate code for + std::vector<t_typedef*> typedefs_; + std::vector<t_enum*> enums_; + std::vector<t_const*> consts_; + std::vector<t_struct*> objects_; + std::vector<t_struct*> structs_; + std::vector<t_struct*> xceptions_; + std::vector<t_service*> services_; + + // Dynamic namespaces + std::map<std::string, std::string> namespaces_; + + // C++ extra includes + std::vector<std::string> cpp_includes_; + + // C extra includes + std::vector<std::string> c_includes_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_scope.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_scope.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_scope.h new file mode 100644 index 0000000..c108fdd --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_scope.h @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_SCOPE_H +#define T_SCOPE_H + +#include <map> +#include <string> +#include <sstream> + +#include "t_type.h" +#include "t_service.h" +#include "t_const.h" +#include "t_const_value.h" +#include "t_base_type.h" +#include "t_map.h" +#include "t_list.h" + +/** + * This represents a variable scope used for looking up predefined types and + * services. Typically, a scope is associated with a t_program. Scopes are not + * used to determine code generation, but rather to resolve identifiers at + * parse time. + * + */ +class t_scope { +public: + t_scope() {} + + void add_type(std::string name, t_type* type) { types_[name] = type; } + + t_type* get_type(std::string name) { return types_[name]; } + + void add_service(std::string name, t_service* service) { services_[name] = service; } + + t_service* get_service(std::string name) { return services_[name]; } + + void add_constant(std::string name, t_const* constant) { + if (constants_.find(name) != constants_.end()) { + throw "Enum " + name + " is already defined!"; + } else { + constants_[name] = constant; + } + } + + t_const* get_constant(std::string name) { return constants_[name]; } + + void print() { + std::map<std::string, t_type*>::iterator iter; + for (iter = types_.begin(); iter != types_.end(); ++iter) { + printf("%s => %s\n", iter->first.c_str(), iter->second->get_name().c_str()); + } + } + + void resolve_const_value(t_const_value* const_val, t_type* ttype) { + if (ttype->is_map()) { + const std::map<t_const_value*, t_const_value*>& map = const_val->get_map(); + std::map<t_const_value*, t_const_value*>::const_iterator v_iter; + for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) { + resolve_const_value(v_iter->first, ((t_map*)ttype)->get_key_type()); + resolve_const_value(v_iter->second, ((t_map*)ttype)->get_val_type()); + } + } else if (ttype->is_list() || ttype->is_set()) { + const std::vector<t_const_value*>& val = const_val->get_list(); + std::vector<t_const_value*>::const_iterator v_iter; + for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { + resolve_const_value((*v_iter), ((t_list*)ttype)->get_elem_type()); + } + } else if (ttype->is_struct()) { + t_struct* tstruct = (t_struct*)ttype; + const std::map<t_const_value*, t_const_value*>& map = const_val->get_map(); + std::map<t_const_value*, t_const_value*>::const_iterator v_iter; + for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) { + t_field* field = tstruct->get_field_by_name(v_iter->first->get_string()); + if (field == NULL) { + throw "No field named \"" + v_iter->first->get_string() + + "\" was found in struct of type \"" + tstruct->get_name() + "\""; + } + resolve_const_value(v_iter->second, field->get_type()); + } + } else if (const_val->get_type() == t_const_value::CV_IDENTIFIER) { + if (ttype->is_enum()) { + const_val->set_enum((t_enum*)ttype); + } else { + t_const* constant = get_constant(const_val->get_identifier()); + if (constant == NULL) { + throw "No enum value or constant found named \"" + const_val->get_identifier() + "\"!"; + } + + // Resolve typedefs to the underlying type + t_type* const_type = constant->get_type()->get_true_type(); + + if (const_type->is_base_type()) { + switch (((t_base_type*)const_type)->get_base()) { + case t_base_type::TYPE_I16: + case t_base_type::TYPE_I32: + case t_base_type::TYPE_I64: + case t_base_type::TYPE_BOOL: + case t_base_type::TYPE_BYTE: + const_val->set_integer(constant->get_value()->get_integer()); + break; + case t_base_type::TYPE_STRING: + const_val->set_string(constant->get_value()->get_string()); + break; + case t_base_type::TYPE_DOUBLE: + const_val->set_double(constant->get_value()->get_double()); + break; + case t_base_type::TYPE_VOID: + throw "Constants cannot be of type VOID"; + } + } else if (const_type->is_map()) { + const std::map<t_const_value*, t_const_value*>& map = constant->get_value()->get_map(); + std::map<t_const_value*, t_const_value*>::const_iterator v_iter; + + const_val->set_map(); + for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) { + const_val->add_map(v_iter->first, v_iter->second); + } + } else if (const_type->is_list()) { + const std::vector<t_const_value*>& val = constant->get_value()->get_list(); + std::vector<t_const_value*>::const_iterator v_iter; + + const_val->set_list(); + for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { + const_val->add_list(*v_iter); + } + } + } + } else if (ttype->is_enum()) { + // enum constant with non-identifier value. set the enum and find the + // value's name. + t_enum* tenum = (t_enum*)ttype; + t_enum_value* enum_value = tenum->get_constant_by_value(const_val->get_integer()); + if (enum_value == NULL) { + std::ostringstream valstm; + valstm << const_val->get_integer(); + throw "Couldn't find a named value in enum " + tenum->get_name() + " for value " + + valstm.str(); + } + const_val->set_identifier(tenum->get_name() + "." + enum_value->get_name()); + const_val->set_enum(tenum); + } + } + +private: + // Map of names to types + std::map<std::string, t_type*> types_; + + // Map of names to constants + std::map<std::string, t_const*> constants_; + + // Map of names to services + std::map<std::string, t_service*> services_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_service.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_service.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_service.h new file mode 100644 index 0000000..2b01f9c --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_service.h @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_SERVICE_H +#define T_SERVICE_H + +#include "t_function.h" +#include <vector> + +class t_program; + +/** + * A service consists of a set of functions. + * + */ +class t_service : public t_type { +public: + t_service(t_program* program) : t_type(program), extends_(NULL) {} + + bool is_service() const { return true; } + + void set_extends(t_service* extends) { extends_ = extends; } + + void add_function(t_function* func) { + std::vector<t_function*>::const_iterator iter; + for (iter = functions_.begin(); iter != functions_.end(); ++iter) { + if (func->get_name() == (*iter)->get_name()) { + throw "Function " + func->get_name() + " is already defined"; + } + } + functions_.push_back(func); + } + + const std::vector<t_function*>& get_functions() const { return functions_; } + + t_service* get_extends() { return extends_; } + +private: + std::vector<t_function*> functions_; + t_service* extends_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_set.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_set.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_set.h new file mode 100644 index 0000000..8a46480 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_set.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_SET_H +#define T_SET_H + +#include "t_container.h" + +/** + * A set is a lightweight container type that just wraps another data type. + * + */ +class t_set : public t_container { +public: + t_set(t_type* elem_type) : elem_type_(elem_type) {} + + t_type* get_elem_type() const { return elem_type_; } + + bool is_set() const { return true; } + +private: + t_type* elem_type_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_struct.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_struct.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_struct.h new file mode 100644 index 0000000..93cb089 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_struct.h @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_STRUCT_H +#define T_STRUCT_H + +#include <algorithm> +#include <vector> +#include <utility> +#include <string> + +#include "t_type.h" +#include "t_field.h" + +// Forward declare that puppy +class t_program; + +/** + * A struct is a container for a set of member fields that has a name. Structs + * are also used to implement exception types. + * + */ +class t_struct : public t_type { +public: + typedef std::vector<t_field*> members_type; + + t_struct(t_program* program) + : t_type(program), + is_xception_(false), + is_union_(false), + members_validated(false), + members_with_value(0), + xsd_all_(false) {} + + t_struct(t_program* program, const std::string& name) + : t_type(program, name), + is_xception_(false), + is_union_(false), + members_validated(false), + members_with_value(0), + xsd_all_(false) {} + + void set_name(const std::string& name) { + name_ = name; + validate_union_members(); + } + + void set_xception(bool is_xception) { is_xception_ = is_xception; } + + void validate_union_member(t_field* field) { + if (is_union_ && (!name_.empty())) { + + // unions can't have required fields + if (field->get_req() == t_field::T_REQUIRED) { + pwarning(1, + "Required field %s of union %s set to optional.\n", + field->get_name().c_str(), + name_.c_str()); + field->set_req(t_field::T_OPTIONAL); + } + + // unions may have up to one member defaulted, but not more + if (field->get_value() != NULL) { + if (1 < ++members_with_value) { + throw "Error: Field " + field->get_name() + " provides another default value for union " + + name_; + } + } + } + } + + void validate_union_members() { + if (is_union_ && (!name_.empty()) && (!members_validated)) { + members_type::const_iterator m_iter; + for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) { + validate_union_member(*m_iter); + } + members_validated = true; + } + } + + void set_union(bool is_union) { + is_union_ = is_union; + validate_union_members(); + } + + void set_xsd_all(bool xsd_all) { xsd_all_ = xsd_all; } + + bool get_xsd_all() const { return xsd_all_; } + + bool append(t_field* elem) { + typedef members_type::iterator iter_type; + std::pair<iter_type, iter_type> bounds = std::equal_range(members_in_id_order_.begin(), + members_in_id_order_.end(), + elem, + t_field::key_compare()); + if (bounds.first != bounds.second) { + return false; + } + // returns false when there is a conflict of field names + if (get_field_by_name(elem->get_name()) != NULL) { + return false; + } + members_.push_back(elem); + members_in_id_order_.insert(bounds.second, elem); + validate_union_member(elem); + return true; + } + + const members_type& get_members() { return members_; } + + const members_type& get_sorted_members() { return members_in_id_order_; } + + bool is_struct() const { return !is_xception_; } + + bool is_xception() const { return is_xception_; } + + bool is_union() const { return is_union_; } + + t_field* get_field_by_name(std::string field_name) { + members_type::const_iterator m_iter; + for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) { + if ((*m_iter)->get_name() == field_name) { + return *m_iter; + } + } + return NULL; + } + +private: + members_type members_; + members_type members_in_id_order_; + bool is_xception_; + bool is_union_; + bool members_validated; + int members_with_value; + + bool xsd_all_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_type.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_type.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_type.h new file mode 100644 index 0000000..416cc6f --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_type.h @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_TYPE_H +#define T_TYPE_H + +#include <string> +#include <map> +#include <cstring> +#include <stdint.h> +#include "t_doc.h" + +class t_program; + +/** + * Generic representation of a thrift type. These objects are used by the + * parser module to build up a tree of object that are all explicitly typed. + * The generic t_type class exports a variety of useful methods that are + * used by the code generator to branch based upon different handling for the + * various types. + * + */ +class t_type : public t_doc { +public: + virtual ~t_type() {} + + virtual void set_name(const std::string& name) { name_ = name; } + + virtual const std::string& get_name() const { return name_; } + + virtual bool is_void() const { return false; } + virtual bool is_base_type() const { return false; } + virtual bool is_string() const { return false; } + virtual bool is_bool() const { return false; } + virtual bool is_typedef() const { return false; } + virtual bool is_enum() const { return false; } + virtual bool is_struct() const { return false; } + virtual bool is_xception() const { return false; } + virtual bool is_container() const { return false; } + virtual bool is_list() const { return false; } + virtual bool is_set() const { return false; } + virtual bool is_map() const { return false; } + virtual bool is_service() const { return false; } + + t_program* get_program() { return program_; } + + const t_program* get_program() const { return program_; } + + t_type* get_true_type(); + + // This function will break (maybe badly) unless 0 <= num <= 16. + static char nybble_to_xdigit(int num) { + if (num < 10) { + return '0' + num; + } else { + return 'A' + num - 10; + } + } + + static std::string byte_to_hex(uint8_t byte) { + std::string rv; + rv += nybble_to_xdigit(byte >> 4); + rv += nybble_to_xdigit(byte & 0x0f); + return rv; + } + + std::map<std::string, std::string> annotations_; + +protected: + t_type() : program_(NULL) { ; } + + t_type(t_program* program) : program_(program) { ; } + + t_type(t_program* program, std::string name) : program_(program), name_(name) { ; } + + t_type(std::string name) : program_(NULL), name_(name) { ; } + + t_program* program_; + std::string name_; +}; + +/** + * Placeholder struct for returning the key and value of an annotation + * during parsing. + */ +struct t_annotation { + std::string key; + std::string val; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.cc ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.cc b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.cc new file mode 100644 index 0000000..ddbe749 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.cc @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <cstdio> + +#include "t_typedef.h" +#include "t_program.h" + +t_type* t_typedef::get_type() const { + if (type_ == NULL) { + t_type* type = get_program()->scope()->get_type(symbolic_); + if (type == NULL) { + printf("Type \"%s\" not defined\n", symbolic_.c_str()); + exit(1); + } + return type; + } + return type_; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.h b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.h new file mode 100644 index 0000000..a39a246 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/parse/t_typedef.h @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef T_TYPEDEF_H +#define T_TYPEDEF_H + +#include <string> +#include "t_type.h" + +/** + * A typedef is a mapping from a symbolic name to another type. In dymanically + * typed languages (i.e. php/python) the code generator can actually usually + * ignore typedefs and just use the underlying type directly, though in C++ + * the symbolic naming can be quite useful for code clarity. + * + */ +class t_typedef : public t_type { +public: + t_typedef(t_program* program, t_type* type, const std::string& symbolic) + : t_type(program, symbolic), type_(type), symbolic_(symbolic), forward_(false), seen_(false) {} + + /** + * This constructor is used to refer to a type that is lazily + * resolved at a later time, like for forward declarations or + * recursive types. + */ + t_typedef(t_program* program, const std::string& symbolic, bool forward) + : t_type(program, symbolic), + type_(NULL), + symbolic_(symbolic), + forward_(forward), + seen_(false) {} + + ~t_typedef() {} + + t_type* get_type() const; + + const std::string& get_symbolic() const { return symbolic_; } + + bool is_forward_typedef() const { return forward_; } + + bool is_typedef() const { return true; } + +private: + t_type* type_; + std::string symbolic_; + bool forward_; + mutable bool seen_; +}; + +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/platform.h ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/platform.h b/depends/thirdparty/thrift/compiler/cpp/src/platform.h new file mode 100644 index 0000000..8cbe9db --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/platform.h @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * define for mkdir,since the method signature + * is different for the non-POSIX MinGW + */ + +#ifdef _MSC_VER +#include "windows/config.h" +#endif + +#ifdef _WIN32 +#include <direct.h> +#include <io.h> +#else +#include <sys/types.h> +#include <sys/stat.h> +#endif + +#ifdef _WIN32 +#define MKDIR(x) mkdir(x) +#else +#define MKDIR(x) mkdir(x, S_IRWXU | S_IRWXG | S_IRWXO) +#endif + +#ifdef PATH_MAX +#define THRIFT_PATH_MAX PATH_MAX +#else +#define THRIFT_PATH_MAX MAX_PATH +#endif http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/thriftl.ll ---------------------------------------------------------------------- diff --git a/depends/thirdparty/thrift/compiler/cpp/src/thriftl.ll b/depends/thirdparty/thrift/compiler/cpp/src/thriftl.ll new file mode 100644 index 0000000..a771269 --- /dev/null +++ b/depends/thirdparty/thrift/compiler/cpp/src/thriftl.ll @@ -0,0 +1,423 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Thrift scanner. + * + * Tokenizes a thrift definition file. + */ + +%{ + +/* This is redundant with some of the flags in Makefile.am, but it works + * when people override CXXFLAGS without being careful. The pragmas are + * the 'right' way to do it, but don't work on old-enough GCC (in particular + * the GCC that ship on Mac OS X 10.6.5, *counter* to what the GNU docs say) + * + * We should revert the Makefile.am changes once Apple ships a reasonable + * GCC. + */ +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-label" +#endif + +#ifdef _MSC_VER +//warning C4102: 'find_rule' : unreferenced label +#pragma warning(disable:4102) +//avoid isatty redefinition +#define YY_NEVER_INTERACTIVE 1 + +#define YY_NO_UNISTD_H 1 +#endif + +#include <cassert> +#include <string> +#include <errno.h> +#include <stdlib.h> + +#ifdef _MSC_VER +#include "windows/config.h" +#endif +#include "main.h" +#include "globals.h" +#include "parse/t_program.h" + +/** + * Must be included AFTER parse/t_program.h, but I can't remember why anymore + * because I wrote this a while ago. + */ +#if defined(BISON_USE_PARSER_H_EXTENSION) +#include "thrifty.h" +#else +#include "thrifty.hh" +#endif + +void thrift_reserved_keyword(char* keyword) { + yyerror("Cannot use reserved language keyword: \"%s\"\n", keyword); + exit(1); +} + +void integer_overflow(char* text) { + yyerror("This integer is too big: \"%s\"\n", text); + exit(1); +} + +void unexpected_token(char* text) { + yyerror("Unexpected token in input: \"%s\"\n", text); + exit(1); +} + +%} + +/** + * Provides the yylineno global, useful for debugging output + */ +%option lex-compat + +/** + * Our inputs are all single files, so no need for yywrap + */ +%option noyywrap + +/** + * We don't use it, and it fires up warnings at -Wall + */ +%option nounput + +/** + * Helper definitions, comments, constants, and whatnot + */ + +intconstant ([+-]?[0-9]+) +hexconstant ([+-]?"0x"[0-9A-Fa-f]+) +dubconstant ([+-]?[0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?) +identifier ([a-zA-Z_](\.[a-zA-Z_0-9]|[a-zA-Z_0-9])*) +whitespace ([ \t\r\n]*) +sillycomm ("/*""*"*"*/") +multicomm ("/*"[^*]"/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/") +doctext ("/**"([^*/]|[^*]"/"|"*"[^/])*"*"*"*/") +comment ("//"[^\n]*) +unixcomment ("#"[^\n]*) +symbol ([:;\,\{\}\(\)\=<>\[\]]) +st_identifier ([a-zA-Z-](\.[a-zA-Z_0-9-]|[a-zA-Z_0-9-])*) +literal_begin (['\"]) + +%% + +{whitespace} { /* do nothing */ } +{sillycomm} { /* do nothing */ } +{multicomm} { /* do nothing */ } +{comment} { /* do nothing */ } +{unixcomment} { /* do nothing */ } + +{symbol} { return yytext[0]; } +"*" { return yytext[0]; } + +"false" { yylval.iconst=0; return tok_int_constant; } +"true" { yylval.iconst=1; return tok_int_constant; } + +"namespace" { return tok_namespace; } +"cpp_namespace" { return tok_cpp_namespace; } +"cpp_include" { return tok_cpp_include; } +"cpp_type" { return tok_cpp_type; } +"java_package" { return tok_java_package; } +"cocoa_prefix" { return tok_cocoa_prefix; } +"csharp_namespace" { return tok_csharp_namespace; } +"delphi_namespace" { return tok_delphi_namespace; } +"php_namespace" { return tok_php_namespace; } +"py_module" { return tok_py_module; } +"perl_package" { return tok_perl_package; } +"ruby_namespace" { return tok_ruby_namespace; } +"smalltalk_category" { return tok_smalltalk_category; } +"smalltalk_prefix" { return tok_smalltalk_prefix; } +"xsd_all" { return tok_xsd_all; } +"xsd_optional" { return tok_xsd_optional; } +"xsd_nillable" { return tok_xsd_nillable; } +"xsd_namespace" { return tok_xsd_namespace; } +"xsd_attrs" { return tok_xsd_attrs; } +"include" { return tok_include; } +"void" { return tok_void; } +"bool" { return tok_bool; } +"byte" { return tok_byte; } +"i16" { return tok_i16; } +"i32" { return tok_i32; } +"i64" { return tok_i64; } +"double" { return tok_double; } +"string" { return tok_string; } +"binary" { return tok_binary; } +"slist" { + pwarning(0, "\"slist\" is deprecated and will be removed in a future compiler version. This type should be replaced with \"string\".\n"); + return tok_slist; +} +"senum" { + pwarning(0, "\"senum\" is deprecated and will be removed in a future compiler version. This type should be replaced with \"string\".\n"); + return tok_senum; +} +"map" { return tok_map; } +"list" { return tok_list; } +"set" { return tok_set; } +"oneway" { return tok_oneway; } +"typedef" { return tok_typedef; } +"struct" { return tok_struct; } +"union" { return tok_union; } +"exception" { return tok_xception; } +"extends" { return tok_extends; } +"throws" { return tok_throws; } +"service" { return tok_service; } +"enum" { return tok_enum; } +"const" { return tok_const; } +"required" { return tok_required; } +"optional" { return tok_optional; } +"async" { + pwarning(0, "\"async\" is deprecated. It is called \"oneway\" now.\n"); + return tok_oneway; +} +"&" { return tok_reference; } + + +"BEGIN" { thrift_reserved_keyword(yytext); } +"END" { thrift_reserved_keyword(yytext); } +"__CLASS__" { thrift_reserved_keyword(yytext); } +"__DIR__" { thrift_reserved_keyword(yytext); } +"__FILE__" { thrift_reserved_keyword(yytext); } +"__FUNCTION__" { thrift_reserved_keyword(yytext); } +"__LINE__" { thrift_reserved_keyword(yytext); } +"__METHOD__" { thrift_reserved_keyword(yytext); } +"__NAMESPACE__" { thrift_reserved_keyword(yytext); } +"abstract" { thrift_reserved_keyword(yytext); } +"alias" { thrift_reserved_keyword(yytext); } +"and" { thrift_reserved_keyword(yytext); } +"args" { thrift_reserved_keyword(yytext); } +"as" { thrift_reserved_keyword(yytext); } +"assert" { thrift_reserved_keyword(yytext); } +"begin" { thrift_reserved_keyword(yytext); } +"break" { thrift_reserved_keyword(yytext); } +"case" { thrift_reserved_keyword(yytext); } +"catch" { thrift_reserved_keyword(yytext); } +"class" { thrift_reserved_keyword(yytext); } +"clone" { thrift_reserved_keyword(yytext); } +"continue" { thrift_reserved_keyword(yytext); } +"declare" { thrift_reserved_keyword(yytext); } +"def" { thrift_reserved_keyword(yytext); } +"default" { thrift_reserved_keyword(yytext); } +"del" { thrift_reserved_keyword(yytext); } +"delete" { thrift_reserved_keyword(yytext); } +"do" { thrift_reserved_keyword(yytext); } +"dynamic" { thrift_reserved_keyword(yytext); } +"elif" { thrift_reserved_keyword(yytext); } +"else" { thrift_reserved_keyword(yytext); } +"elseif" { thrift_reserved_keyword(yytext); } +"elsif" { thrift_reserved_keyword(yytext); } +"end" { thrift_reserved_keyword(yytext); } +"enddeclare" { thrift_reserved_keyword(yytext); } +"endfor" { thrift_reserved_keyword(yytext); } +"endforeach" { thrift_reserved_keyword(yytext); } +"endif" { thrift_reserved_keyword(yytext); } +"endswitch" { thrift_reserved_keyword(yytext); } +"endwhile" { thrift_reserved_keyword(yytext); } +"ensure" { thrift_reserved_keyword(yytext); } +"except" { thrift_reserved_keyword(yytext); } +"exec" { thrift_reserved_keyword(yytext); } +"finally" { thrift_reserved_keyword(yytext); } +"float" { thrift_reserved_keyword(yytext); } +"for" { thrift_reserved_keyword(yytext); } +"foreach" { thrift_reserved_keyword(yytext); } +"from" { thrift_reserved_keyword(yytext); } +"function" { thrift_reserved_keyword(yytext); } +"global" { thrift_reserved_keyword(yytext); } +"goto" { thrift_reserved_keyword(yytext); } +"if" { thrift_reserved_keyword(yytext); } +"implements" { thrift_reserved_keyword(yytext); } +"import" { thrift_reserved_keyword(yytext); } +"in" { thrift_reserved_keyword(yytext); } +"inline" { thrift_reserved_keyword(yytext); } +"instanceof" { thrift_reserved_keyword(yytext); } +"interface" { thrift_reserved_keyword(yytext); } +"is" { thrift_reserved_keyword(yytext); } +"lambda" { thrift_reserved_keyword(yytext); } +"module" { thrift_reserved_keyword(yytext); } +"native" { thrift_reserved_keyword(yytext); } +"new" { thrift_reserved_keyword(yytext); } +"next" { thrift_reserved_keyword(yytext); } +"nil" { thrift_reserved_keyword(yytext); } +"not" { thrift_reserved_keyword(yytext); } +"or" { thrift_reserved_keyword(yytext); } +"package" { thrift_reserved_keyword(yytext); } +"pass" { thrift_reserved_keyword(yytext); } +"public" { thrift_reserved_keyword(yytext); } +"print" { thrift_reserved_keyword(yytext); } +"private" { thrift_reserved_keyword(yytext); } +"protected" { thrift_reserved_keyword(yytext); } +"public" { thrift_reserved_keyword(yytext); } +"raise" { thrift_reserved_keyword(yytext); } +"redo" { thrift_reserved_keyword(yytext); } +"rescue" { thrift_reserved_keyword(yytext); } +"retry" { thrift_reserved_keyword(yytext); } +"register" { thrift_reserved_keyword(yytext); } +"return" { thrift_reserved_keyword(yytext); } +"self" { thrift_reserved_keyword(yytext); } +"sizeof" { thrift_reserved_keyword(yytext); } +"static" { thrift_reserved_keyword(yytext); } +"super" { thrift_reserved_keyword(yytext); } +"switch" { thrift_reserved_keyword(yytext); } +"synchronized" { thrift_reserved_keyword(yytext); } +"then" { thrift_reserved_keyword(yytext); } +"this" { thrift_reserved_keyword(yytext); } +"throw" { thrift_reserved_keyword(yytext); } +"transient" { thrift_reserved_keyword(yytext); } +"try" { thrift_reserved_keyword(yytext); } +"undef" { thrift_reserved_keyword(yytext); } +"union" { thrift_reserved_keyword(yytext); } +"unless" { thrift_reserved_keyword(yytext); } +"unsigned" { thrift_reserved_keyword(yytext); } +"until" { thrift_reserved_keyword(yytext); } +"use" { thrift_reserved_keyword(yytext); } +"var" { thrift_reserved_keyword(yytext); } +"virtual" { thrift_reserved_keyword(yytext); } +"volatile" { thrift_reserved_keyword(yytext); } +"when" { thrift_reserved_keyword(yytext); } +"while" { thrift_reserved_keyword(yytext); } +"with" { thrift_reserved_keyword(yytext); } +"xor" { thrift_reserved_keyword(yytext); } +"yield" { thrift_reserved_keyword(yytext); } + +{intconstant} { + errno = 0; + yylval.iconst = strtoll(yytext, NULL, 10); + if (errno == ERANGE) { + integer_overflow(yytext); + } + return tok_int_constant; +} + +{hexconstant} { + errno = 0; + char sign = yytext[0]; + int shift = sign == '0' ? 2 : 3; + yylval.iconst = strtoll(yytext+shift, NULL, 16); + if (sign == '-') { + yylval.iconst = -yylval.iconst; + } + if (errno == ERANGE) { + integer_overflow(yytext); + } + return tok_int_constant; +} + +{dubconstant} { + yylval.dconst = atof(yytext); + return tok_dub_constant; +} + +{identifier} { + yylval.id = strdup(yytext); + return tok_identifier; +} + +{st_identifier} { + yylval.id = strdup(yytext); + return tok_st_identifier; +} + +{literal_begin} { + char mark = yytext[0]; + std::string result; + for(;;) + { + int ch = yyinput(); + switch (ch) { + case EOF: + yyerror("End of file while read string at %d\n", yylineno); + exit(1); + case '\n': + yyerror("End of line while read string at %d\n", yylineno - 1); + exit(1); + case '\\': + ch = yyinput(); + switch (ch) { + case 'r': + result.push_back('\r'); + continue; + case 'n': + result.push_back('\n'); + continue; + case 't': + result.push_back('\t'); + continue; + case '"': + result.push_back('"'); + continue; + case '\'': + result.push_back('\''); + continue; + case '\\': + result.push_back('\\'); + continue; + default: + yyerror("Bad escape character\n"); + return -1; + } + break; + default: + if (ch == mark) { + yylval.id = strdup(result.c_str()); + return tok_literal; + } else { + result.push_back(ch); + } + } + } +} + + +{doctext} { + /* This does not show up in the parse tree. */ + /* Rather, the parser will grab it out of the global. */ + if (g_parse_mode == PROGRAM) { + clear_doctext(); + g_doctext = strdup(yytext + 3); + assert(strlen(g_doctext) >= 2); + g_doctext[strlen(g_doctext) - 2] = ' '; + g_doctext[strlen(g_doctext) - 1] = '\0'; + g_doctext = clean_up_doctext(g_doctext); + g_doctext_lineno = yylineno; + if( (g_program_doctext_candidate == NULL) && (g_program_doctext_status == INVALID)){ + g_program_doctext_candidate = strdup(g_doctext); + g_program_doctext_lineno = g_doctext_lineno; + g_program_doctext_status = STILL_CANDIDATE; + pdebug("%s","program doctext set to STILL_CANDIDATE"); + } + } +} + +. { + unexpected_token(yytext); +} + + +. { + /* Catch-all to let us catch "*" in the parser. */ + return (int) yytext[0]; +} + +%% + +/* vim: filetype=lex +*/
