namespace\_decl = `namespace` ident ( `.` ident )* `;`
-attribute\_decl = `attribute` string\_constant `;`
+attribute\_decl = `attribute` ident | `"`ident`"` `;`
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
if (IsIdentifierStart(c)) {
// Collect all chars of an identifier:
const char *start = cursor_ - 1;
- while (isalnum(static_cast<unsigned char>(*cursor_)) ||
- *cursor_ == '_')
+ while (isalnum(static_cast<unsigned char>(*cursor_)) || *cursor_ == '_')
cursor_++;
attribute_.append(start, cursor_);
token_ = kTokenIdentifier;
NEXT();
for (;;) {
auto name = attribute_;
- EXPECT(kTokenIdentifier);
+ if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant)))
+ return Error("attribute name must be either identifier or string: " +
+ name);
if (known_attributes_.find(name) == known_attributes_.end())
return Error("user define attributes must be declared before use: " +
name);
+ NEXT();
auto e = new Value();
attributes->Add(name, e);
if (Is(':')) {
} else if (IsIdent("attribute")) {
NEXT();
auto name = attribute_;
- EXPECT(kTokenStringConstant);
+ if (Is(kTokenIdentifier)) {
+ NEXT();
+ } else {
+ EXPECT(kTokenStringConstant);
+ }
EXPECT(';');
known_attributes_[name] = false;
} else if (IsIdent("rpc_service")) {