Parser will allow a table or vector to have a trailing comma.

Unless in --strict-json mode.
Also added strict_json option to the parser, which in
addition controls if field names without quotes are allowed.

Change-Id: Id56fe5c780bdb9170958050ffa8fa23cf2babe95
Tested: on Linux.
parent e568f170
......@@ -67,7 +67,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');});
<li><code>-t</code> : If data is contained in this file, generate a <code>filename.json</code> representing the data in the flatbuffer.</li>
<li><code>-o PATH</code> : Output all generated files to PATH (either absolute, or relative to the current directory). If omitted, PATH will be the current directory. PATH should end in your systems path separator, e.g. <code>/</code> or <code>\</code>.</li>
<li><code>-I PATH</code> : when encountering <code>include</code> statements, attempt to load the files from this path. Paths will be tried in the order given, and if all fail (or none are specified) it will try to load relative to the path of the schema file being parsed.</li>
<li><code>--strict-json</code> : Generate strict JSON (field names are enclosed in quotes). By default, no quotes are generated.</li>
<li><code>--strict-json</code> : Require &amp; generate strict JSON (field names are enclosed in quotes, no trailing commas in tables/vectors). By default, no quotes are required/generated, and trailing commas are allowed.</li>
<li><code>--no-prefix</code> : Don't prefix enum values in generated C++ by their enum type.</li>
<li><code>--gen-includes</code> : Generate include statements for included schemas the generated file depends on (C++).</li>
<li><code>--proto</code>: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: <code>package</code>, <code>message</code>, <code>enum</code>. Does not support, but will skip without error: <code>import</code>, <code>option</code>. Does not support, will generate error: <code>service</code>, <code>extend</code>, <code>extensions</code>, <code>oneof</code>, <code>group</code>, custom options, nested declarations. </li>
......
......@@ -41,8 +41,9 @@ be generated for each file processed:
fail (or none are specified) it will try to load relative to the path of
the schema file being parsed.
- `--strict-json` : Generate strict JSON (field names are enclosed in quotes).
By default, no quotes are generated.
- `--strict-json` : Require & generate strict JSON (field names are enclosed
in quotes, no trailing commas in tables/vectors). By default, no quotes are
required/generated, and trailing commas are allowed.
- `--no-prefix` : Don't prefix enum values in generated C++ by their enum
type.
......
......@@ -266,12 +266,13 @@ struct EnumDef : public Definition {
class Parser {
public:
Parser(bool proto_mode = false)
Parser(bool strict_json = false, bool proto_mode = false)
: root_struct_def(nullptr),
source_(nullptr),
cursor_(nullptr),
line_(1),
proto_mode_(proto_mode) {
proto_mode_(proto_mode),
strict_json_(strict_json) {
// Just in case none are declared:
namespaces_.push_back(new Namespace());
known_attributes_.insert("deprecated");
......@@ -354,6 +355,7 @@ class Parser {
int line_; // the current line being parsed
int token_;
bool proto_mode_;
bool strict_json_;
std::string attribute_;
std::vector<std::string> doc_comment_;
......
......@@ -102,7 +102,8 @@ static void Error(const char *err, const char *obj, bool usage,
printf(
" -o PATH Prefix PATH to all generated files.\n"
" -I PATH Search for includes in the specified path.\n"
" --strict-json Strict JSON: add quotes to field names.\n"
" --strict-json Strict JSON: field names must be / will be quoted,\n"
" no trailing commas in tables/vectors.\n"
" --no-prefix Don\'t prefix enum values with the enum type in C++.\n"
" --gen-includes Generate include statements for included schemas the\n"
" generated file depends on (C++).\n"
......@@ -174,7 +175,7 @@ int main(int argc, const char *argv[]) {
"specify one of -c -g -j -t -b etc.", true);
// Now process the files:
flatbuffers::Parser parser(proto_mode);
flatbuffers::Parser parser(opts.strict_json, proto_mode);
for (auto file_it = filenames.begin();
file_it != filenames.end();
++file_it) {
......
......@@ -480,9 +480,11 @@ void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
uoffset_t Parser::ParseTable(const StructDef &struct_def) {
Expect('{');
size_t fieldn = 0;
if (!IsNext('}')) for (;;) {
for (;;) {
if ((!strict_json_ || !fieldn) && IsNext('}')) break;
std::string name = attribute_;
if (!IsNext(kTokenStringConstant)) Expect(kTokenIdentifier);
if (!IsNext(kTokenStringConstant))
Expect(strict_json_ ? kTokenStringConstant : kTokenIdentifier);
auto field = struct_def.fields.Lookup(name);
if (!field) Error("unknown field: " + name);
if (struct_def.fixed && (fieldn >= struct_def.fields.vec.size()
......@@ -574,16 +576,16 @@ uoffset_t Parser::ParseTable(const StructDef &struct_def) {
uoffset_t Parser::ParseVector(const Type &type) {
int count = 0;
if (token_ != ']') for (;;) {
for (;;) {
if ((!strict_json_ || !count) && IsNext(']')) break;
Value val;
val.type = type;
ParseAnyValue(val, NULL);
field_stack_.push_back(std::make_pair(val, nullptr));
count++;
if (token_ == ']') break;
if (IsNext(']')) break;
Expect(',');
}
Next();
builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
InlineAlignment(type));
......
......@@ -249,7 +249,7 @@ void ParseProtoTest() {
"tests/prototest/test.golden", false, &goldenfile), true);
// Parse proto.
flatbuffers::Parser parser(true);
flatbuffers::Parser parser(false, true);
TEST_EQ(parser.Parse(protofile.c_str(), nullptr), true);
// Generate fbs.
......@@ -493,8 +493,9 @@ void FuzzTest2() {
}
// Test that parser errors are actually generated.
void TestError(const char *src, const char *error_substr) {
flatbuffers::Parser parser;
void TestError(const char *src, const char *error_substr,
bool strict_json = false) {
flatbuffers::Parser parser(strict_json);
TEST_EQ(parser.Parse(src), false); // Must signal error
// Must be the error we're expecting
TEST_NOTNULL(strstr(parser.error_.c_str(), error_substr));
......@@ -522,6 +523,9 @@ void ErrorTest() {
TestError("union Z { X } table X { Y:Z; } root_type X; { Y_type: 99, Y: {",
"type id");
TestError("table X { Y:int; } root_type X; { Z:", "unknown field");
TestError("table X { Y:int; } root_type X; { Y:", "string constant", true);
TestError("table X { Y:int; } root_type X; { \"Y\":1, }", "string constant",
true);
TestError("struct X { Y:int; Z:int; } table W { V:X; } root_type W; "
"{ V:{ Y:1 } }", "incomplete");
TestError("enum E:byte { A } table X { Y:E; } root_type X; { Y:U }",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment