[C++] better type mismatch error (#4623)

* better parse error

* pass str as a pointer instead of a reference for more efficient performance
This commit is contained in:
Masato Nagai
2018-02-17 01:32:50 +09:00
committed by Wouter van Oortmerssen
parent 36f8564846
commit 19c81b11b3
4 changed files with 26 additions and 24 deletions

View File

@@ -648,7 +648,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (token_ == '=') {
NEXT();
ECHECK(ParseSingleValue(field->value));
ECHECK(ParseSingleValue(&field->name, field->value));
if (!IsScalar(type.base_type) ||
(struct_def.fixed && field->value.constant != "0"))
return Error(
@@ -878,11 +878,11 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
(token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
ECHECK(ParseHash(val, field));
} else {
ECHECK(ParseSingleValue(val));
ECHECK(ParseSingleValue(field ? &field->name : nullptr, val));
}
break;
}
default: ECHECK(ParseSingleValue(val)); break;
default: ECHECK(ParseSingleValue(field ? &field->name : nullptr, val)); break;
}
return NoError();
}
@@ -1201,7 +1201,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
attributes->Add(name, e);
if (Is(':')) {
NEXT();
ECHECK(ParseSingleValue(*e));
ECHECK(ParseSingleValue(&name, *e));
}
if (Is(')')) {
NEXT();
@@ -1213,7 +1213,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
return NoError();
}
CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e,
CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
BaseType req, bool *destmatch) {
bool match = dtoken == token_;
if (match) {
@@ -1225,7 +1225,9 @@ CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e,
} else {
return Error(std::string("type mismatch: expecting: ") +
kTypeNames[e.type.base_type] +
", found: " + kTypeNames[req]);
", found: " + kTypeNames[req] +
", name: " + (name ? *name : "") +
", value: " + e.constant);
}
}
NEXT();
@@ -1310,13 +1312,13 @@ CheckedError Parser::TokenError() {
return Error("cannot parse value starting with: " + TokenToStringId(token_));
}
CheckedError Parser::ParseSingleValue(Value &e) {
CheckedError Parser::ParseSingleValue(const std::string *name, Value &e) {
// First see if this could be a conversion function:
if (token_ == kTokenIdentifier && *cursor_ == '(') {
auto functionname = attribute_;
NEXT();
EXPECT('(');
ECHECK(ParseSingleValue(e));
ECHECK(ParseSingleValue(name, e));
EXPECT(')');
// clang-format off
#define FLATBUFFERS_FN_DOUBLE(name, op) \
@@ -1362,17 +1364,17 @@ CheckedError Parser::ParseSingleValue(Value &e) {
}
} else {
bool match = false;
ECHECK(TryTypedValue(kTokenIntegerConstant, IsScalar(e.type.base_type), e,
ECHECK(TryTypedValue(name, kTokenIntegerConstant, IsScalar(e.type.base_type), e,
BASE_TYPE_INT, &match));
ECHECK(TryTypedValue(kTokenFloatConstant, IsFloat(e.type.base_type), e,
ECHECK(TryTypedValue(name, kTokenFloatConstant, IsFloat(e.type.base_type), e,
BASE_TYPE_FLOAT, &match));
ECHECK(TryTypedValue(kTokenStringConstant,
ECHECK(TryTypedValue(name, kTokenStringConstant,
e.type.base_type == BASE_TYPE_STRING, 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,
ECHECK(TryTypedValue(name, kTokenIdentifier, IsBool(e.type.base_type), e,
BASE_TYPE_BOOL, &match));
}
if (!match) return TokenError();