summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWouter van Oortmerssen <aardappel@gmail.com>2017-09-22 14:32:07 -0700
committerWouter van Oortmerssen <aardappel@gmail.com>2017-09-22 16:30:26 -0700
commit03e2899985849dbffa3178ae76c00288f7aca79b (patch)
tree98f4e5692a825881e43194d53845667e0c71d381 /src
parent72a99abfb7db64dc49720b28b41f382b5ec7cde0 (diff)
downloadflatbuffers-03e2899985849dbffa3178ae76c00288f7aca79b.tar.gz
flatbuffers-03e2899985849dbffa3178ae76c00288f7aca79b.tar.bz2
flatbuffers-03e2899985849dbffa3178ae76c00288f7aca79b.zip
Made the parser not have any hard-coded keywords.
This prevented any keywords showing up as JSON field names, for example. Change-Id: Ie9d0cada96778e06016ca02ca96d052410a37038 Tested: on Linux.
Diffstat (limited to 'src')
-rw-r--r--src/idl_gen_cpp.cpp2
-rw-r--r--src/idl_gen_general.cpp4
-rw-r--r--src/idl_gen_go.cpp2
-rw-r--r--src/idl_gen_php.cpp2
-rw-r--r--src/idl_gen_python.cpp2
-rw-r--r--src/idl_gen_text.cpp6
-rw-r--r--src/idl_parser.cpp311
7 files changed, 133 insertions, 196 deletions
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 93941b80..729580a3 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -333,7 +333,7 @@ class CppGenerator : public BaseGenerator {
// Return a C++ type from the table in idl.h
std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
static const char *ctypename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#CTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
index 8e799194..0a7b3b82 100644
--- a/src/idl_gen_general.cpp
+++ b/src/idl_gen_general.cpp
@@ -241,7 +241,7 @@ static bool IsEnum(const Type& type) {
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
static const char *java_typename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#JTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -249,7 +249,7 @@ std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
};
static const char *csharp_typename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#NTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp
index 8d4a7a59..0cc2e934 100644
--- a/src/idl_gen_go.cpp
+++ b/src/idl_gen_go.cpp
@@ -694,7 +694,7 @@ static std::string GenMethod(const FieldDef &field) {
static std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#GTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp
index 893f16f2..b2610892 100644
--- a/src/idl_gen_php.cpp
+++ b/src/idl_gen_php.cpp
@@ -909,7 +909,7 @@ namespace php {
static std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
-#define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#NTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp
index 7958b91e..fd2e1c3f 100644
--- a/src/idl_gen_python.cpp
+++ b/src/idl_gen_python.cpp
@@ -580,7 +580,7 @@ static std::string GenMethod(const FieldDef &field) {
static std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
#PTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp
index b7c58756..50d54c5f 100644
--- a/src/idl_gen_text.cpp
+++ b/src/idl_gen_text.cpp
@@ -135,7 +135,7 @@ template<> bool Print<const void *>(const void *val,
type = type.VectorType();
// Call PrintVector above specifically for each element type:
switch (type.base_type) {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM: \
if (!PrintVector<CTYPE>( \
@@ -226,7 +226,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
text += " ";
if (is_present) {
switch (fd.value.type.base_type) {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM: \
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
@@ -237,7 +237,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
// Generate drop-thru case statements for all pointer types:
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM:
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 99513b8c..b919c3c5 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -32,7 +32,7 @@
namespace flatbuffers {
const char *const kTypeNames[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -41,7 +41,7 @@ const char *const kTypeNames[] = {
};
const char kTypeSizes[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
sizeof(CTYPE),
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -165,8 +165,6 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
return stream.str();
}
-
-
// Declare tokens we'll use. Single character tokens are represented by their
// ascii character code (e.g. '{'), others above 256.
#define FLATBUFFERS_GEN_TOKENS(TD) \
@@ -174,21 +172,7 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
TD(StringConstant, 257, "string constant") \
TD(IntegerConstant, 258, "integer constant") \
TD(FloatConstant, 259, "float constant") \
- TD(Identifier, 260, "identifier") \
- TD(Table, 261, "table") \
- TD(Struct, 262, "struct") \
- TD(Enum, 263, "enum") \
- TD(Union, 264, "union") \
- TD(NameSpace, 265, "namespace") \
- TD(RootType, 266, "root_type") \
- TD(FileIdentifier, 267, "file_identifier") \
- TD(FileExtension, 268, "file_extension") \
- TD(Include, 269, "include") \
- TD(Attribute, 270, "attribute") \
- TD(Null, 271, "null") \
- TD(Service, 272, "rpc_service") \
- TD(NativeInclude, 273, "native_include") \
- TD(BooleanConstant, 274, "boolean constant")
+ TD(Identifier, 260, "identifier")
#ifdef __GNUC__
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
@@ -196,11 +180,6 @@ enum {
#define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE,
FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
#undef FLATBUFFERS_TOKEN
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
- kToken ## ENUM,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
};
static std::string TokenToString(int t) {
@@ -208,7 +187,7 @@ static std::string TokenToString(int t) {
#define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING,
FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
#undef FLATBUFFERS_TOKEN
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -224,7 +203,7 @@ static std::string TokenToString(int t) {
}
std::string Parser::TokenToStringId(int t) {
- return TokenToString(t) + (t == kTokenIdentifier ? ": " + attribute_ : "");
+ return t == kTokenIdentifier ? attribute_ : TokenToString(t);
}
// Parses exactly nibbles worth of hex digits into a number, or error.
@@ -240,11 +219,14 @@ CheckedError Parser::ParseHexNum(int nibbles, uint64_t *val) {
}
CheckedError Parser::SkipByteOrderMark() {
- if (static_cast<unsigned char>(*cursor_) != 0xef) return NoError();
+ if (static_cast<unsigned char>(*cursor_) != 0xef)
+ return NoError();
cursor_++;
- if (static_cast<unsigned char>(*cursor_) != 0xbb) return Error("invalid utf-8 byte order mark");
+ if (static_cast<unsigned char>(*cursor_) != 0xbb)
+ return Error("invalid utf-8 byte order mark");
cursor_++;
- if (static_cast<unsigned char>(*cursor_) != 0xbf) return Error("invalid utf-8 byte order mark");
+ if (static_cast<unsigned char>(*cursor_) != 0xbf)
+ return Error("invalid utf-8 byte order mark");
cursor_++;
return NoError();
}
@@ -383,76 +365,6 @@ CheckedError Parser::Next() {
*cursor_ == '_')
cursor_++;
attribute_.append(start, cursor_);
- // First, see if it is a type keyword from the table of types:
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
- if (attribute_ == IDLTYPE || attribute_ == ALIASTYPE) { \
- token_ = kToken ## ENUM; \
- return NoError(); \
- }
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
- // If it's a boolean constant keyword, turn those into integers,
- // which simplifies our logic downstream.
- if (attribute_ == "true" || attribute_ == "false") {
- attribute_ = NumToString(attribute_ == "true");
- token_ = kTokenBooleanConstant;
- return NoError();
- }
- // Check for declaration keywords:
- if (attribute_ == "table") {
- token_ = kTokenTable;
- return NoError();
- }
- if (attribute_ == "struct") {
- token_ = kTokenStruct;
- return NoError();
- }
- if (attribute_ == "enum") {
- token_ = kTokenEnum;
- return NoError();
- }
- if (attribute_ == "union") {
- token_ = kTokenUnion;
- return NoError();
- }
- if (attribute_ == "namespace") {
- token_ = kTokenNameSpace;
- return NoError();
- }
- if (attribute_ == "root_type") {
- token_ = kTokenRootType;
- return NoError();
- }
- if (attribute_ == "include") {
- token_ = kTokenInclude;
- return NoError();
- }
- if (attribute_ == "attribute") {
- token_ = kTokenAttribute;
- return NoError();
- }
- if (attribute_ == "file_identifier") {
- token_ = kTokenFileIdentifier;
- return NoError();
- }
- if (attribute_ == "file_extension") {
- token_ = kTokenFileExtension;
- return NoError();
- }
- if (attribute_ == "null") {
- token_ = kTokenNull;
- return NoError();
- }
- if (attribute_ == "rpc_service") {
- token_ = kTokenService;
- return NoError();
- }
- if (attribute_ == "native_include") {
- token_ = kTokenNativeInclude;
- return NoError();
- }
- // If not, it is a user-defined identifier:
token_ = kTokenIdentifier;
return NoError();
} else if (isdigit(static_cast<unsigned char>(c)) || c == '-') {
@@ -506,6 +418,10 @@ bool Parser::Is(int t) {
return t == token_;
}
+bool Parser::IsIdent(const char *id) {
+ return token_ == kTokenIdentifier && attribute_ == id;
+}
+
// Expect a given token to be next, consume it, or error if not present.
CheckedError Parser::Expect(int t) {
if (t != token_) {
@@ -555,28 +471,61 @@ CheckedError Parser::ParseTypeIdent(Type &type) {
// Parse any IDL type.
CheckedError Parser::ParseType(Type &type) {
- if (token_ >= kTokenBOOL && token_ <= kTokenSTRING) {
- type.base_type = static_cast<BaseType>(token_ - kTokenNONE);
- NEXT();
- } else {
- if (token_ == kTokenIdentifier) {
- ECHECK(ParseTypeIdent(type));
- } else if (token_ == '[') {
+ if (token_ == kTokenIdentifier) {
+ if (IsIdent("bool")) {
+ type.base_type = BASE_TYPE_BOOL;
+ NEXT();
+ } else if (IsIdent("byte") || IsIdent("int8")) {
+ type.base_type = BASE_TYPE_CHAR;
+ NEXT();
+ } else if (IsIdent("ubyte") || IsIdent("uint8")) {
+ type.base_type = BASE_TYPE_UCHAR;
+ NEXT();
+ } else if (IsIdent("short") || IsIdent("int16")) {
+ type.base_type = BASE_TYPE_SHORT;
+ NEXT();
+ } else if (IsIdent("ushort") || IsIdent("uint16")) {
+ type.base_type = BASE_TYPE_USHORT;
+ NEXT();
+ } else if (IsIdent("int") || IsIdent("int32")) {
+ type.base_type = BASE_TYPE_INT;
+ NEXT();
+ } else if (IsIdent("uint") || IsIdent("uint32")) {
+ type.base_type = BASE_TYPE_UINT;
+ NEXT();
+ } else if (IsIdent("long") || IsIdent("int64")) {
+ type.base_type = BASE_TYPE_LONG;
+ NEXT();
+ } else if (IsIdent("ulong") || IsIdent("uint64")) {
+ type.base_type = BASE_TYPE_ULONG;
+ NEXT();
+ } else if (IsIdent("float") || IsIdent("float32")) {
+ type.base_type = BASE_TYPE_FLOAT;
+ NEXT();
+ } else if (IsIdent("double") || IsIdent("float64")) {
+ type.base_type = BASE_TYPE_DOUBLE;
+ NEXT();
+ } else if (IsIdent("string")) {
+ type.base_type = BASE_TYPE_STRING;
NEXT();
- Type subtype;
- ECHECK(ParseType(subtype));
- if (subtype.base_type == BASE_TYPE_VECTOR) {
- // We could support this, but it will complicate things, and it's
- // easier to work around with a struct around the inner vector.
- return Error(
- "nested vector types not supported (wrap in table first).");
- }
- type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
- type.element = subtype.base_type;
- EXPECT(']');
} else {
- return Error("illegal type syntax");
+ ECHECK(ParseTypeIdent(type));
+ }
+ } else if (token_ == '[') {
+ NEXT();
+ Type subtype;
+ ECHECK(ParseType(subtype));
+ if (subtype.base_type == BASE_TYPE_VECTOR) {
+ // We could support this, but it will complicate things, and it's
+ // easier to work around with a struct around the inner vector.
+ return Error(
+ "nested vector types not supported (wrap in table first).");
}
+ type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
+ type.element = subtype.base_type;
+ EXPECT(']');
+ } else {
+ return Error("illegal type syntax");
}
return NoError();
}
@@ -945,7 +894,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
ECHECK(parser->SkipAnyJsonValue());
}
} else {
- if (parser->Is(kTokenNull)) {
+ if (parser->IsIdent("null")) {
ECHECK(parser->Next()); // Ignore this field.
} else {
Value val = field->value;
@@ -1023,7 +972,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
if (!struct_def.sortbysize ||
size == SizeOf(field_value.type.base_type)) {
switch (field_value.type.base_type) {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \
@@ -1040,7 +989,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
break;
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
#undef FLATBUFFERS_TD
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \
@@ -1116,7 +1065,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue) {
// start at the back, since we're building the data backwards.
auto &val = field_stack_.back().first;
switch (val.type.base_type) {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, ALIASTYPE, \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
case BASE_TYPE_ ## ENUM: \
if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
@@ -1317,6 +1266,7 @@ CheckedError Parser::ParseSingleValue(Value &e) {
#undef FLATBUFFERS_FN_DOUBLE
// Then check if this could be a string/identifier enum value:
} else if (e.type.base_type != BASE_TYPE_STRING &&
+ e.type.base_type != BASE_TYPE_BOOL &&
e.type.base_type != BASE_TYPE_NONE &&
(token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
if (IsIdentifierStart(attribute_[0])) { // Enum value.
@@ -1348,11 +1298,6 @@ CheckedError Parser::ParseSingleValue(Value &e) {
e,
BASE_TYPE_INT,
&match));
- ECHECK(TryTypedValue(kTokenBooleanConstant,
- IsBool(e.type.base_type),
- e,
- BASE_TYPE_BOOL,
- &match));
ECHECK(TryTypedValue(kTokenFloatConstant,
IsFloat(e.type.base_type),
e,
@@ -1363,6 +1308,15 @@ CheckedError Parser::ParseSingleValue(Value &e) {
e,
BASE_TYPE_STRING,
&match));
+ auto istrue = IsIdent("true");
+ if (istrue || IsIdent("false")) {
+ attribute_ = NumToString(istrue);
+ ECHECK(TryTypedValue(kTokenIdentifier,
+ IsBool(e.type.base_type),
+ e,
+ BASE_TYPE_BOOL,
+ &match));
+ }
if (!match) return TokenError();
}
return NoError();
@@ -1594,8 +1548,9 @@ static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) {
CheckedError Parser::ParseDecl() {
std::vector<std::string> dc = doc_comment_;
- bool fixed = Is(kTokenStruct);
- if (fixed) NEXT() else EXPECT(kTokenTable);
+ bool fixed = IsIdent("struct");
+ if (!fixed && !IsIdent("table")) return Error("declaration expected");
+ NEXT();
std::string name = attribute_;
EXPECT(kTokenIdentifier);
StructDef *struct_def;
@@ -1753,11 +1708,11 @@ static bool compareEnumVals(const EnumVal *a, const EnumVal* b) {
// We parse everything as identifiers instead of keywords, since we don't
// want protobuf keywords to become invalid identifiers in FlatBuffers.
CheckedError Parser::ParseProtoDecl() {
- bool isextend = attribute_ == "extend";
- if (attribute_ == "package") {
+ bool isextend = IsIdent("extend");
+ if (IsIdent("package")) {
// These are identical in syntax to FlatBuffer's namespace decl.
ECHECK(ParseNamespace());
- } else if (attribute_ == "message" || isextend) {
+ } else if (IsIdent("message") || isextend) {
std::vector<std::string> struct_comment = doc_comment_;
NEXT();
StructDef *struct_def = nullptr;
@@ -1789,7 +1744,7 @@ CheckedError Parser::ParseProtoDecl() {
current_namespace_ = parent_namespace;
}
if (Is(';')) NEXT();
- } else if (attribute_ == "enum") {
+ } else if (IsIdent("enum")) {
// These are almost the same, just with different terminator:
EnumDef *enum_def;
ECHECK(ParseEnum(false, &enum_def));
@@ -1803,15 +1758,15 @@ CheckedError Parser::ParseProtoDecl() {
if (it != v.begin() && it[0]->value == it[-1]->value) it = v.erase(it);
else ++it;
}
- } else if (attribute_ == "syntax") { // Skip these.
+ } else if (IsIdent("syntax")) { // Skip these.
NEXT();
EXPECT('=');
EXPECT(kTokenStringConstant);
EXPECT(';');
- } else if (attribute_ == "option") { // Skip these.
+ } else if (IsIdent("option")) { // Skip these.
ECHECK(ParseProtoOption());
EXPECT(';');
- } else if (attribute_ == "service") { // Skip these.
+ } else if (IsIdent("service")) { // Skip these.
NEXT();
EXPECT(kTokenIdentifier);
ECHECK(ParseProtoCurliesOrIdent());
@@ -1826,11 +1781,10 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
bool inside_oneof) {
EXPECT('{');
while (token_ != '}') {
- if (attribute_ == "message" || attribute_ == "extend" ||
- attribute_ == "enum") {
+ if (IsIdent("message") || IsIdent("extend") || IsIdent("enum")) {
// Nested declarations.
ECHECK(ParseProtoDecl());
- } else if (attribute_ == "extensions") { // Skip these.
+ } else if (IsIdent("extensions")) { // Skip these.
NEXT();
EXPECT(kTokenIntegerConstant);
if (Is(kTokenIdentifier)) {
@@ -1838,10 +1792,10 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
NEXT(); // num
}
EXPECT(';');
- } else if (attribute_ == "option") { // Skip these.
+ } else if (IsIdent("option")) { // Skip these.
ECHECK(ParseProtoOption());
EXPECT(';');
- } else if (attribute_ == "reserved") { // Skip these.
+ } else if (IsIdent("reserved")) { // Skip these.
NEXT();
EXPECT(kTokenIntegerConstant);
while (Is(',')) { NEXT(); EXPECT(kTokenIntegerConstant); }
@@ -1853,26 +1807,26 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
bool repeated = false;
bool oneof = false;
if (!inside_oneof) {
- if (attribute_ == "optional") {
+ if (IsIdent("optional")) {
// This is the default.
- EXPECT(kTokenIdentifier);
- } else if (attribute_ == "required") {
+ NEXT();
+ } else if (IsIdent("required")) {
required = true;
- EXPECT(kTokenIdentifier);
- } else if (attribute_ == "repeated") {
+ NEXT();
+ } else if (IsIdent("repeated")) {
repeated = true;
- EXPECT(kTokenIdentifier);
- } else if (attribute_ == "oneof") {
+ NEXT();
+ } else if (IsIdent("oneof")) {
oneof = true;
- EXPECT(kTokenIdentifier);
+ NEXT();
} else {
// can't error, proto3 allows decls without any of the above.
}
}
StructDef *anonymous_struct = nullptr;
Type type;
- if (attribute_ == "group" || oneof) {
- if (!oneof) EXPECT(kTokenIdentifier);
+ if (IsIdent("group") || oneof) {
+ if (!oneof) NEXT();
auto name = "Anonymous" + NumToString(anonymous_counter++);
ECHECK(StartStruct(name, &anonymous_struct));
type = Type(BASE_TYPE_STRUCT, anonymous_struct);
@@ -1885,14 +1839,7 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
type.base_type = BASE_TYPE_VECTOR;
}
std::string name = attribute_;
- // Protos may use our keywords "attribute" & "namespace" as an identifier.
- if (Is(kTokenAttribute) || Is(kTokenNameSpace)) {
- NEXT();
- // TODO: simpler to just not make these keywords?
- name += "_"; // Have to make it not a keyword.
- } else {
- EXPECT(kTokenIdentifier);
- }
+ EXPECT(kTokenIdentifier);
if (!oneof) {
// Parse the field id. Since we're just translating schemas, not
// any kind of binary compatibility, we can safely ignore these, and
@@ -2036,19 +1983,13 @@ CheckedError Parser::SkipAnyJsonValue() {
this);
}
case kTokenStringConstant:
- EXPECT(kTokenStringConstant);
- break;
case kTokenIntegerConstant:
- EXPECT(kTokenIntegerConstant);
- break;
case kTokenFloatConstant:
- EXPECT(kTokenFloatConstant);
- break;
- case kTokenBooleanConstant:
- EXPECT(kTokenBooleanConstant);
+ NEXT();
break;
default:
- return TokenError();
+ if (IsIdent("true") || IsIdent("false") || IsIdent("null")) { NEXT(); }
+ else return TokenError();
}
return NoError();
}
@@ -2104,16 +2045,15 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
builder->Int(StringToInt(attribute_.c_str()));
EXPECT(kTokenIntegerConstant);
break;
- case kTokenBooleanConstant:
- builder->Bool(StringToInt(attribute_.c_str()) != 0);
- EXPECT(kTokenBooleanConstant);
- break;
case kTokenFloatConstant:
builder->Double(strtod(attribute_.c_str(), nullptr));
EXPECT(kTokenFloatConstant);
break;
default:
- return TokenError();
+ if (IsIdent("true")) { builder->Bool(true); NEXT(); }
+ else if (IsIdent("false")) { builder->Bool(false); NEXT(); }
+ else if (IsIdent("null")) { builder->Null(); NEXT(); }
+ else return TokenError();
}
return NoError();
}
@@ -2202,14 +2142,11 @@ CheckedError Parser::DoParse(const char *source,
(attribute_ == "option" || attribute_ == "syntax" ||
attribute_ == "package")) {
ECHECK(ParseProtoDecl());
- } else if (Is(kTokenNativeInclude)) {
+ } else if (IsIdent("native_include")) {
NEXT();
vector_emplace_back(&native_included_files_, attribute_);
EXPECT(kTokenStringConstant);
- } else if (Is(kTokenInclude) ||
- (opts.proto_mode &&
- attribute_ == "import" &&
- Is(kTokenIdentifier))) {
+ } else if (IsIdent("include") || (opts.proto_mode && IsIdent("import"))) {
NEXT();
if (opts.proto_mode && attribute_ == "public") NEXT();
auto name = flatbuffers::PosixPath(attribute_.c_str());
@@ -2257,7 +2194,7 @@ CheckedError Parser::DoParse(const char *source,
while (token_ != kTokenEof) {
if (opts.proto_mode) {
ECHECK(ParseProtoDecl());
- } else if (token_ == kTokenNameSpace) {
+ } else if (IsIdent("namespace")) {
ECHECK(ParseNamespace());
} else if (token_ == '{') {
if (!root_struct_def_)
@@ -2269,11 +2206,11 @@ CheckedError Parser::DoParse(const char *source,
ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
builder_.Finish(Offset<Table>(toff),
file_identifier_.length() ? file_identifier_.c_str() : nullptr);
- } else if (token_ == kTokenEnum) {
+ } else if (IsIdent("enum")) {
ECHECK(ParseEnum(false, nullptr));
- } else if (token_ == kTokenUnion) {
+ } else if (IsIdent("union")) {
ECHECK(ParseEnum(true, nullptr));
- } else if (token_ == kTokenRootType) {
+ } else if (IsIdent("root_type")) {
NEXT();
auto root_type = attribute_;
EXPECT(kTokenIdentifier);
@@ -2283,7 +2220,7 @@ CheckedError Parser::DoParse(const char *source,
if (root_struct_def_->fixed)
return Error("root type must be a table");
EXPECT(';');
- } else if (token_ == kTokenFileIdentifier) {
+ } else if (IsIdent("file_identifier")) {
NEXT();
file_identifier_ = attribute_;
EXPECT(kTokenStringConstant);
@@ -2293,20 +2230,20 @@ CheckedError Parser::DoParse(const char *source,
NumToString(FlatBufferBuilder::kFileIdentifierLength) +
" characters");
EXPECT(';');
- } else if (token_ == kTokenFileExtension) {
+ } else if (IsIdent("file_extension")) {
NEXT();
file_extension_ = attribute_;
EXPECT(kTokenStringConstant);
EXPECT(';');
- } else if(token_ == kTokenInclude) {
+ } else if(IsIdent("include")) {
return Error("includes must come before declarations");
- } else if(token_ == kTokenAttribute) {
+ } else if(IsIdent("attribute")) {
NEXT();
auto name = attribute_;
EXPECT(kTokenStringConstant);
EXPECT(';');
known_attributes_[name] = false;
- } else if (token_ == kTokenService) {
+ } else if (IsIdent("rpc_service")) {
ECHECK(ParseService());
} else {
ECHECK(ParseDecl());