C ++ Spirit专家,我正在寻找以下用例的通用解析器。任何帮助将不胜感激
KEY = alphanumeric value
Value = alphanumeric value
Array of values alphanumeric separated by ()
List of Array – 2D
例如:
Key1 = “my name” key2= 10 key3=(1 2 3) key4=((1 2 3) (4 5 6))
我希望将键和值存储在std :: map中。
答案 0 :(得分:1)
因为从我写解析器以来已经很久了,所以我跑了它:
// #define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iomanip> // std::quoted
#include <map>
namespace qi = boost::spirit::qi;
using Value = boost::make_recursive_variant<std::string, double, std::vector<boost::recursive_variant_> >::type;
using Map = std::map<std::string, Value>;
template <typename It>
struct Parser : qi::grammar<It, Map()> {
Parser() : Parser::base_type(start) {
using namespace qi;
start = skip(space) [*key_value];
key_value = key >> '=' >> value;
value = v_string | v_array | v_num;
// lexemes
key = alpha >> *alnum;
v_string = "“" >> *('\\' >> char_ | ~char_("”")) >> "”";
v_array = '(' >> *value >> ')';
v_num = double_;
BOOST_SPIRIT_DEBUG_NODES((start)(key_value)(value)(key)(v_string)(v_array)(v_num))
}
private:
qi::rule<It, Map()> start;
qi::rule<It, std::pair<std::string, Value>(), qi::space_type> key_value;
qi::rule<It, Value(), qi::space_type> value;
qi::rule<It, std::vector<Value>(), qi::space_type> v_array;
qi::rule<It, std::string()> key, v_string;
qi::rule<It, double()> v_num;
// lexemes
};
static inline std::ostream& operator<<(std::ostream& os, Value const& v) {
struct {
std::ostream& _os;
void operator()(Value const& v) const { boost::apply_visitor(*this, v); }
void operator()(std::string const& v) const { _os << std::quoted(v); }
void operator()(double v) const { _os << v; }
void operator()(std::vector<Value> const& v) const {
_os << "( ";
for (auto& el:v) {
operator()(el);
_os << " ";
}
_os << ")";
}
} vis{os};
vis(v);
return os;
}
int main() {
using It = std::string::const_iterator;
Parser<It> const p;
for (std::string const& input : {
"Key1 = “my name” key2= 10 key3=(1 2 3) key4=((1 2 3) (4 5 6))"
})
{
It f = input.begin(), l = input.end();
Map data;
bool ok = parse(f, l, p, data);
if (ok) {
std::cout << "Parsed " << data.size() << " unique keys\n";
for (auto& entry : data) {
std::cout << entry.first << " = " << entry.second << "\n";
}
} else {
std::cout << "Parse failed\n";
}
if (f != l)
std::cout << "Remaining unparsed: " << std::quoted(std::string(f,l)) << "\n";
}
}
打印:
Parsed 4 unique keys
Key1 = "my name"
key2 = 10
key3 = ( 1 2 3 )
key4 = ( ( 1 2 3 ) ( 4 5 6 ) )
注意:我希望有技巧的Unicode引号是故意的
启用BOOST_SPIRIT_DEBUG
:
<start>
<try>Key1 = “my name”</try>
<key_value>
<try>Key1 = “my name”</try>
<key>
<try>Key1 = “my name”</try>
<success> = “my name” ke</success>
<attributes>[[K, e, y, 1]]</attributes>
</key>
<value>
<try> “my name” key2</try>
<v_string>
<try>“my name” key2=</try>
<success> key2= 10 key3=(1 2</success>
<attributes>[[m, y, , n, a, m, e]]</attributes>
</v_string>
<success> key2= 10 key3=(1 2</success>
<attributes>[[m, y, , n, a, m, e]]</attributes>
</value>
<success> key2= 10 key3=(1 2</success>
<attributes>[[[K, e, y, 1], [m, y, , n, a, m, e]]]</attributes>
</key_value>
<key_value>
<try> key2= 10 key3=(1 2</try>
<key>
<try>key2= 10 key3=(1 2 3</try>
<success>= 10 key3=(1 2 3) ke</success>
<attributes>[[k, e, y, 2]]</attributes>
</key>
<value>
<try> 10 key3=(1 2 3) key</try>
<v_string>
<try>10 key3=(1 2 3) key4</try>
<fail/>
</v_string>
<v_array>
<try>10 key3=(1 2 3) key4</try>
<fail/>
</v_array>
<v_num>
<try>10 key3=(1 2 3) key4</try>
<success> key3=(1 2 3) key4=(</success>
<attributes>[10]</attributes>
</v_num>
<success> key3=(1 2 3) key4=(</success>
<attributes>[10]</attributes>
</value>
<success> key3=(1 2 3) key4=(</success>
<attributes>[[[k, e, y, 2], 10]]</attributes>
</key_value>
<key_value>
<try> key3=(1 2 3) key4=(</try>
<key>
<try>key3=(1 2 3) key4=((</try>
<success>=(1 2 3) key4=((1 2 </success>
<attributes>[[k, e, y, 3]]</attributes>
</key>
<value>
<try>(1 2 3) key4=((1 2 3</try>
<v_string>
<try>(1 2 3) key4=((1 2 3</try>
<fail/>
</v_string>
<v_array>
<try>(1 2 3) key4=((1 2 3</try>
<value>
<try>1 2 3) key4=((1 2 3)</try>
<v_string>
<try>1 2 3) key4=((1 2 3)</try>
<fail/>
</v_string>
<v_array>
<try>1 2 3) key4=((1 2 3)</try>
<fail/>
</v_array>
<v_num>
<try>1 2 3) key4=((1 2 3)</try>
<success> 2 3) key4=((1 2 3) </success>
<attributes>[1]</attributes>
</v_num>
<success> 2 3) key4=((1 2 3) </success>
<attributes>[1]</attributes>
</value>
<value>
<try> 2 3) key4=((1 2 3) </try>
<v_string>
<try>2 3) key4=((1 2 3) (</try>
<fail/>
</v_string>
<v_array>
<try>2 3) key4=((1 2 3) (</try>
<fail/>
</v_array>
<v_num>
<try>2 3) key4=((1 2 3) (</try>
<success> 3) key4=((1 2 3) (4</success>
<attributes>[2]</attributes>
</v_num>
<success> 3) key4=((1 2 3) (4</success>
<attributes>[2]</attributes>
</value>
<value>
<try> 3) key4=((1 2 3) (4</try>
<v_string>
<try>3) key4=((1 2 3) (4 </try>
<fail/>
</v_string>
<v_array>
<try>3) key4=((1 2 3) (4 </try>
<fail/>
</v_array>
<v_num>
<try>3) key4=((1 2 3) (4 </try>
<success>) key4=((1 2 3) (4 5</success>
<attributes>[3]</attributes>
</v_num>
<success>) key4=((1 2 3) (4 5</success>
<attributes>[3]</attributes>
</value>
<value>
<try>) key4=((1 2 3) (4 5</try>
<v_string>
<try>) key4=((1 2 3) (4 5</try>
<fail/>
</v_string>
<v_array>
<try>) key4=((1 2 3) (4 5</try>
<fail/>
</v_array>
<v_num>
<try>) key4=((1 2 3) (4 5</try>
<fail/>
</v_num>
<fail/>
</value>
<success> key4=((1 2 3) (4 5 </success>
<attributes>[[1, 2, 3]]</attributes>
</v_array>
<success> key4=((1 2 3) (4 5 </success>
<attributes>[[1, 2, 3]]</attributes>
</value>
<success> key4=((1 2 3) (4 5 </success>
<attributes>[[[k, e, y, 3], [1, 2, 3]]]</attributes>
</key_value>
<key_value>
<try> key4=((1 2 3) (4 5 </try>
<key>
<try>key4=((1 2 3) (4 5 6</try>
<success>=((1 2 3) (4 5 6))</success>
<attributes>[[k, e, y, 4]]</attributes>
</key>
<value>
<try>((1 2 3) (4 5 6))</try>
<v_string>
<try>((1 2 3) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>((1 2 3) (4 5 6))</try>
<value>
<try>(1 2 3) (4 5 6))</try>
<v_string>
<try>(1 2 3) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>(1 2 3) (4 5 6))</try>
<value>
<try>1 2 3) (4 5 6))</try>
<v_string>
<try>1 2 3) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>1 2 3) (4 5 6))</try>
<fail/>
</v_array>
<v_num>
<try>1 2 3) (4 5 6))</try>
<success> 2 3) (4 5 6))</success>
<attributes>[1]</attributes>
</v_num>
<success> 2 3) (4 5 6))</success>
<attributes>[1]</attributes>
</value>
<value>
<try> 2 3) (4 5 6))</try>
<v_string>
<try>2 3) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>2 3) (4 5 6))</try>
<fail/>
</v_array>
<v_num>
<try>2 3) (4 5 6))</try>
<success> 3) (4 5 6))</success>
<attributes>[2]</attributes>
</v_num>
<success> 3) (4 5 6))</success>
<attributes>[2]</attributes>
</value>
<value>
<try> 3) (4 5 6))</try>
<v_string>
<try>3) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>3) (4 5 6))</try>
<fail/>
</v_array>
<v_num>
<try>3) (4 5 6))</try>
<success>) (4 5 6))</success>
<attributes>[3]</attributes>
</v_num>
<success>) (4 5 6))</success>
<attributes>[3]</attributes>
</value>
<value>
<try>) (4 5 6))</try>
<v_string>
<try>) (4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>) (4 5 6))</try>
<fail/>
</v_array>
<v_num>
<try>) (4 5 6))</try>
<fail/>
</v_num>
<fail/>
</value>
<success> (4 5 6))</success>
<attributes>[[1, 2, 3]]</attributes>
</v_array>
<success> (4 5 6))</success>
<attributes>[[1, 2, 3]]</attributes>
</value>
<value>
<try> (4 5 6))</try>
<v_string>
<try>(4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>(4 5 6))</try>
<value>
<try>4 5 6))</try>
<v_string>
<try>4 5 6))</try>
<fail/>
</v_string>
<v_array>
<try>4 5 6))</try>
<fail/>
</v_array>
<v_num>
<try>4 5 6))</try>
<success> 5 6))</success>
<attributes>[4]</attributes>
</v_num>
<success> 5 6))</success>
<attributes>[4]</attributes>
</value>
<value>
<try> 5 6))</try>
<v_string>
<try>5 6))</try>
<fail/>
</v_string>
<v_array>
<try>5 6))</try>
<fail/>
</v_array>
<v_num>
<try>5 6))</try>
<success> 6))</success>
<attributes>[5]</attributes>
</v_num>
<success> 6))</success>
<attributes>[5]</attributes>
</value>
<value>
<try> 6))</try>
<v_string>
<try>6))</try>
<fail/>
</v_string>
<v_array>
<try>6))</try>
<fail/>
</v_array>
<v_num>
<try>6))</try>
<success>))</success>
<attributes>[6]</attributes>
</v_num>
<success>))</success>
<attributes>[6]</attributes>
</value>
<value>
<try>))</try>
<v_string>
<try>))</try>
<fail/>
</v_string>
<v_array>
<try>))</try>
<fail/>
</v_array>
<v_num>
<try>))</try>
<fail/>
</v_num>
<fail/>
</value>
<success>)</success>
<attributes>[[4, 5, 6]]</attributes>
</v_array>
<success>)</success>
<attributes>[[4, 5, 6]]</attributes>
</value>
<value>
<try>)</try>
<v_string>
<try>)</try>
<fail/>
</v_string>
<v_array>
<try>)</try>
<fail/>
</v_array>
<v_num>
<try>)</try>
<fail/>
</v_num>
<fail/>
</value>
<success></success>
<attributes>[[[1, 2, 3], [4, 5, 6]]]</attributes>
</v_array>
<success></success>
<attributes>[[[1, 2, 3], [4, 5, 6]]]</attributes>
</value>
<success></success>
<attributes>[[[k, e, y, 4], [[1, 2, 3], [4, 5, 6]]]]</attributes>
</key_value>
<key_value>
<try></try>
<key>
<try></try>
<fail/>
</key>
<fail/>
</key_value>
<success></success>
<attributes>[[[[K, e, y, 1], [m, y, , n, a, m, e]], [[k, e, y, 2], 10], [[k, e, y, 3], [1, 2, 3]], [[k, e, y, 4], [[1, 2, 3], [4, 5, 6]]]]]</attributes>
</start>