Allow data path to end with a list for get and ls
Change-Id: I3facc8315fa6192da4318012a85121de37e7314b
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 7f76ac7..7caa45c 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -28,6 +28,9 @@
x3::rule<schemaNode_class, schemaNode_> const schemaNode = "schemaNode";
x3::rule<absoluteStart_class, Scope> const absoluteStart = "absoluteStart";
x3::rule<schemaPath_class, schemaPath_> const schemaPath = "schemaPath";
+x3::rule<dataNodeList_class, decltype(dataPath_::m_nodes)::value_type> const dataNodeList = "dataNodeList";
+x3::rule<dataNodesListEnd_class, decltype(dataPath_::m_nodes)> const dataNodesListEnd = "dataNodesListEnd";
+x3::rule<dataPathListEnd_class, dataPath_> const dataPathListEnd = "dataPathListEnd";
x3::rule<dataPath_class, dataPath_> const dataPath = "dataPath";
x3::rule<leaf_path_class, dataPath_> const leafPath = "leafPath";
@@ -49,6 +52,8 @@
x3::rule<commit_class, commit_> const commit = "commit";
x3::rule<command_class, command_> const command = "command";
+x3::rule<initializeContext_class, x3::unused_type> const initializeContext = "initializeContext";
+
#if __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-shift-op-parentheses"
@@ -90,7 +95,7 @@
listPrefix > listSuffix;
auto const list_def =
- node_identifier;
+ node_identifier >> !char_('[');
auto const nodeup_def =
lit("..") > x3::attr(nodeup_());
@@ -109,7 +114,7 @@
-(module) >> x3::expect[container | list | nodeup | leaf];
auto const dataNode_def =
- -(module) >> x3::expect[container | listElement | nodeup | leaf];
+ -(module) >> (container | listElement | nodeup | leaf);
auto const absoluteStart_def =
x3::omit['/'] >> x3::attr(Scope::Absolute);
@@ -119,6 +124,21 @@
absoluteStart >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::eoi |
-(absoluteStart) >> dataNode % '/';
+auto const dataNodeList_def =
+ -(module) >> list;
+
+// This intermediate rule is mandatory, because we need the first alternative
+// to be collapsed to a vector. If we didn't use the intermediate rule,
+// Spirit wouldn't know we want it to collapse.
+// https://github.com/boostorg/spirit/issues/408
+auto const dataNodesListEnd_def =
+ dataNode % '/' >> '/' >> dataNodeList |
+ initializeContext >> x3::attr(decltype(dataPath_::m_nodes)()) >> dataNodeList;
+
+auto const dataPathListEnd_def =
+ absoluteStart >> x3::attr(decltype(dataPath_::m_nodes)()) >> x3::eoi |
+ -(absoluteStart) >> dataNodesListEnd;
+
auto const schemaPath_def =
absoluteStart >> x3::attr(decltype(schemaPath_::m_nodes)()) >> x3::eoi |
-(absoluteStart) >> schemaNode % '/';
@@ -169,8 +189,12 @@
}
} const ls_options;
+// A "nothing" parser, which is used to reset the context (when trying to parse different types of paths)
+auto const initializeContext_def =
+ x3::eps;
+
auto const ls_def =
- lit("ls") >> *(space_separator >> ls_options) >> -(space_separator >> dataPath);
+ lit("ls") >> *(space_separator >> ls_options) >> -(space_separator >> (dataPathListEnd | initializeContext >> dataPath));
auto const cd_def =
lit("cd") >> space_separator > dataPath;
@@ -182,7 +206,7 @@
lit("delete") >> space_separator > dataPath;
auto const get_def =
- lit("get") >> -dataPath;
+ lit("get") >> -(space_separator >> (dataPathListEnd | initializeContext >> dataPath));
auto const set_def =
lit("set") >> space_separator > leafPath > leaf_data;
@@ -216,6 +240,9 @@
BOOST_SPIRIT_DEFINE(leafPath)
BOOST_SPIRIT_DEFINE(schemaPath)
BOOST_SPIRIT_DEFINE(dataPath)
+BOOST_SPIRIT_DEFINE(dataNodeList)
+BOOST_SPIRIT_DEFINE(dataNodesListEnd)
+BOOST_SPIRIT_DEFINE(dataPathListEnd)
BOOST_SPIRIT_DEFINE(absoluteStart)
BOOST_SPIRIT_DEFINE(module)
BOOST_SPIRIT_DEFINE(leaf_data)
@@ -225,6 +252,7 @@
BOOST_SPIRIT_DEFINE(leaf_data_int)
BOOST_SPIRIT_DEFINE(leaf_data_uint)
BOOST_SPIRIT_DEFINE(leaf_data_string)
+BOOST_SPIRIT_DEFINE(initializeContext)
BOOST_SPIRIT_DEFINE(set)
BOOST_SPIRIT_DEFINE(commit)
BOOST_SPIRIT_DEFINE(get)