boost-spirit-x3

Spirit X3, Is this error handling approach useful?

限于喜欢 提交于 2019-12-01 01:27:47
After reading the the Spirit X3 tutorial on error handling and some experimentation. I was drawn to a conclusion. I believe there is some room for improvement on the topic of error handing in X3. An important goal from my perspective is to provide a meaningful error message. First and foremost adding a semantic action that will set the _pass(ctx) member to false wouldn’t do it because X3 will try to match something else. Only throwing an x3::expectation_failure will quit the parse function prematurely, i.e. without trying to match anything else. So what is left are the parser directive expect

parsing from std::string into a boost::string_view using boost::spirit::x3

心不动则不痛 提交于 2019-12-01 00:57:43
In my my previous question it was suggested that the performance of my boost::spirit::x3 parser could be improved by parsing into a boost::string_view using the raw directive. However, I have difficulties getting it to compile. This is what I found out: Before x3 , one had to specialize assign_to_attribute_from_iterators (see e.g. this SO answer ) to handle the raw directive. x3 now uses the move_to free function instead (see e.g. this SO answer ). I therefore added a move_to overload which works if I parse from char* : #include <iostream> #include <string> #include <boost/utility/string_view

Stop X3 symbols from matching substrings

心已入冬 提交于 2019-11-29 16:16:25
How does one prevent X3 symbol parsers from matching partial tokens? In the example below, I want to match "foo", but not "foobar". I tried throwing the symbol parser in a lexeme directive as one would for an identifier, but then nothing matches. Thanks for any insights! #include <string> #include <iostream> #include <iomanip> #include <boost/spirit/home/x3.hpp> int main() { boost::spirit::x3::symbols<int> sym; sym.add("foo", 1); for (std::string const input : { "foo", "foobar", "barfoo" }) { using namespace boost::spirit::x3; std::cout << "\nParsing " << std::left << std::setw(20) << ("'" +

Parsing comma-separated list of ranges and numbers with semantic actions

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 11:03:49
Using Boost.Spirit X3 , I want to parse a comma-separated list of ranges and individual numbers (e.g. 1-4, 6, 7, 9-12) into a single std::vector<int> . Here's what I've come up with: namespace ast { struct range { int first_, last_; }; using expr = std::vector<int>; } namespace parser { template<typename T> auto as_rule = [](auto p) { return x3::rule<struct _, T>{} = x3::as_parser(p); }; auto const push = [](auto& ctx) { x3::_val(ctx).push_back(x3::_attr(ctx)); }; auto const expand = [](auto& ctx) { for (auto i = x3::_attr(ctx).first_; i <= x3::_attr(ctx).last_; ++i) x3::_val(ctx).push_back(i)

boost::spirit::x3 attribute compatibility rules, intuition or code?

谁说胖子不能爱 提交于 2019-11-29 08:44:20
Is there a document somewhere which describes how various spirit::x3 rule definition operations affect attribute compatibility? I was surprised when: x3::lexeme[ x3::alpha > *(x3::alnum | x3::char_('_')) ] could not be moved into a fusion-adapted struct: struct Name { std::string value; }; For the time being, I got rid of the first mandatory alphabetical character, but I would still like to express a rule which defines that the name string must begin with a letter. Is this one of those situations where I need to try adding eps around until it works, or is there a stated reason why the above

Boost Spirit x3: parse into structs

六月ゝ 毕业季﹏ 提交于 2019-11-29 02:39:54
From the Boost Spirit X3 tutorial: First, let's create a struct representing an employee: namespace client { namespace ast { struct employee { int age; std::string surname; std::string forename; double salary; }; }} Then, we need to tell Boost.Fusion about our employee struct to make it a first-class fusion citizen that the grammar can utilize. BOOST_FUSION_ADAPT_STRUCT( client::ast::employee, (int, age) (std::string, surname) (std::string, forename) (double, salary) )` [...] In fusion's view, a struct is just a form of a tuple. You can adapt any struct to be a fully conforming fusion tuple. [

Spirit X3: parser with internal state

无人久伴 提交于 2019-11-28 05:54:18
问题 I want to efficiently parse large CSV-like files, whose order of columns I get at runtime. With Spirit Qi, I would parse each field with a lazy auxiliary parser that would select at runtime which column-specific parser to apply to each column. But X3 doesn't seem to have lazy (despite that it's listed in documentation). After reading recommendations here on SO, I've decided to write a custom parser. It ended up being pretty nice, but now I've noticed I don't really need the pos variable be

Boost Spirit x3: parse into structs

梦想的初衷 提交于 2019-11-27 17:00:13
问题 From the Boost Spirit X3 tutorial: First, let's create a struct representing an employee: namespace client { namespace ast { struct employee { int age; std::string surname; std::string forename; double salary; }; }} Then, we need to tell Boost.Fusion about our employee struct to make it a first-class fusion citizen that the grammar can utilize. BOOST_FUSION_ADAPT_STRUCT( client::ast::employee, (int, age) (std::string, surname) (std::string, forename) (double, salary) )` [...] In fusion's view

How to make a recursive rule in boost spirit x3 in VS2017

霸气de小男生 提交于 2019-11-27 16:11:26
I've written the following recursive rule in boost::spirit::x3 but it only seems to compile in g++/clang, not VS2017 (15.5.3): #include <iostream> #include <boost/spirit/home/x3.hpp> namespace lex3 { namespace x3 = boost::spirit::x3; x3::rule<struct foo_class> const foo = "foo"; x3::rule<struct bar_class> const bar = "bar"; auto bar_def = *((x3::char_ - "/*") - "*/") >> *(foo > *((x3::char_ - "/*") - "*/")); auto foo_def = "/*" > bar > "*/"; BOOST_SPIRIT_DEFINE(foo) BOOST_SPIRIT_DEFINE(bar) } int main(int argc, char** argv) { std::string input = "/* a /* nested */ comment */"; auto f = input

Parsing comma-separated list of ranges and numbers with semantic actions

柔情痞子 提交于 2019-11-27 07:10:09
问题 Using Boost.Spirit X3, I want to parse a comma-separated list of ranges and individual numbers (e.g. 1-4, 6, 7, 9-12) into a single std::vector<int> . Here's what I've come up with: namespace ast { struct range { int first_, last_; }; using expr = std::vector<int>; } namespace parser { template<typename T> auto as_rule = [](auto p) { return x3::rule<struct _, T>{} = x3::as_parser(p); }; auto const push = [](auto& ctx) { x3::_val(ctx).push_back(x3::_attr(ctx)); }; auto const expand = [](auto&