Skip to content

Commit

Permalink
Add support for empty structs (#167)
Browse files Browse the repository at this point in the history
### Changelog
Add support for empty structs

### Docs
None

### Description
As per the [IDL spec](https://www.omg.org/spec/IDL/4.1/PDF), structs are
allowed to have no members:

>```
>::+ "struct" <identifier> ":" <scoped_name> "{" <member>* "}"
>| "struct" <identifier> "{" "}"
>```

Our parsing grammar however required a struct to have at least one
member. This PR adapts the grammar to allow structs without members.
  • Loading branch information
achim-k authored May 14, 2024
1 parent 8c870c3 commit 368b49b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/omgidl-parser/src/idl.ne
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ enumFieldName -> multiAnnotations fieldName {% d => {
return extend([annotations, name]);
} %}

struct -> "struct" fieldName "{" (member):+ "}" {% d => {
struct -> "struct" fieldName "{" (member):* "}" {% d => {
const name = d[1].name;
const definitions = d[3].flat(2).filter(def => def !== null);
return {
Expand Down
14 changes: 14 additions & 0 deletions packages/omgidl-parser/src/parseIDL.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2619,6 +2619,20 @@ module rosidl_parser {
},
]);
});
it("can parse empty struct", () => {
const msgDef = `
struct a {
};
`;
const ast = parseIDL(msgDef);
expect(ast).toEqual([
{
name: "a",
aggregatedKind: "struct",
definitions: [],
},
]);
});
// **************** Not supported in our implementation yet
it("cannot compose variable size arrays (no serialization support)", () => {
const msgDef = `
Expand Down
21 changes: 14 additions & 7 deletions packages/omgidl-parser/src/parseIDLToAST.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,20 @@ module idl_parser {
},
]);
});
it("can parse empty struct", () => {
const msgDef = `
struct a {
};
`;
const ast = parseIDLToAST(msgDef);
expect(ast).toEqual([
{
name: "a",
declarator: "struct",
definitions: [],
},
]);
});
/**************** Not supported by IDL (as far as I can tell) */
it("cannot parse constants that reference other constants", () => {
const msgDef = `
Expand All @@ -1819,13 +1833,6 @@ module idl_parser {
`;
expect(() => parseIDLToAST(msgDef)).toThrow(/unexpected , token/i);
});
it("cannot parse empty struct", () => {
const msgDef = `
struct a {
};
`;
expect(() => parseIDLToAST(msgDef)).toThrow(/unexpected RCBR token/i);
});
/**************** Syntax Errors */
it("missing bracket at the end will result in end of input error", () => {
const msgDef = `
Expand Down
28 changes: 28 additions & 0 deletions packages/omgidl-serialization/src/MessageReader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1319,4 +1319,32 @@ module builtin_interfaces {

expect(msgout).toEqual(data);
});
it("Reads struct with no members", () => {
const msgDef = `
struct Message {
};
`;
const data = {};
const writer = new CdrWriter({ kind: EncapsulationKind.PL_CDR_LE });

const rootDef = "Message";
const reader = new MessageReader(rootDef, parseIDL(msgDef));
const msgout = reader.readMessage(writer.data);
expect(msgout).toEqual(data);
});
it("Reads mutable struct with no members", () => {
const msgDef = `
@mutable
struct Message {
};
`;
const data = {};
const writer = new CdrWriter({ kind: EncapsulationKind.PL_CDR_LE });
writer.sentinelHeader(); // end of struct

const rootDef = "Message";
const reader = new MessageReader(rootDef, parseIDL(msgDef));
const msgout = reader.readMessage(writer.data);
expect(msgout).toEqual(data);
});
});

0 comments on commit 368b49b

Please sign in to comment.