Is Boost Spirit X3 production ready?
Asked Answered
B

1

8

I'm migrating a hand-written parser to Boost.Spirit (2.5.4). First impressions are positive, but since I'm using C++17, X3 seems like a very attractive option.

Fortunately, there are many resources available about X3:

However:

  • there is nothing on Boost.Org, which gives the impression that, although Spirit X3 is part of Boost, it's more like a stowaway than a first class passenger
  • as of today, it seems that the development stoped in June 2014

So I'm worried: is X3 a good bet? Not only of maintenance, but does it hold its promesses compared to its predecessor?

EDIT

I did my homework badly, similar questions were asked elsewhere:

Booty answered 13/1, 2018 at 7:18 Comment(0)
M
5

Spirit X3 is being used in production (the developers state this on the mailing list).

It's strictly still "beta": interfaces and implementation may be subject to change.

All in all, I think it does deliver. There are some quirks/wrinkles that may bite if you heavily require things like Qi's qi::locals<> or switching skippers in recursive rules.

As long as you keep these in mind you'll find that X3 is a breeze to use compared to Qi, mostly due to core language integration (composability is the biggest win IMO).

You can have a scan through (my) answers on this site. (Not all answers are on questions tagged as such, so consider also searching for the text 'x3').

Development did not stop:

$ git log --all --oneline --decorate --date-order \
      --after=2014-7-1 --graph -- include/boost/spirit/home/x3
* ea57c257f Prevent parse_nan() from dereferencing out of range iterator
* 1433de2fe X3: Remove unused function_types includes
* 5bd4d1061 X3: Dereference a single item view instead of unwrapping sequence
* 6cd3d3a08 fix sequence partitioning problem (reverted from commit a8e391bd99dddb3f9ece84bdb1bb9236b0a37cf7)
* 9bdbf6bd2 X3: Fixed iterator move_to to single item sequence
* c5411ad23 X3: Reenable fusion::map support
* 60031eb77 Fix container traits for msvc (#318)
*   b10e4a477 Merge pull request #320 from think-cell/thinkcell_iterator_check
|\  
* | 6de179282 If there's ambiguity in attribute_category on container_attribute or tuple_attribute (e.g. array and std::array), choose tuple_attribute. We probably should define is_container better.
| * 766cc4c9b ForwardIterator -> ReadableIteratorConcept & ForwardTraversalConcept
|/  
* 52de6d17b Fix for trac ticket 12928 "x3 cannot synthesize attribute of type boost::iterator_range in a sequence parser"
* cb946ba08 X3: Fixed include guard names collision
*   5ec71cfd3 Merge pull request #307 from octopus-prime/optional_attribute
|\  
* \   1265ee169 Merge pull request #120 from mlang/x3/implicit
|\ \  
* \ \   deab0a261 Merge pull request #109 from mlang/x3/repeat-kleene-auto
|\ \ \  
* | | | 6d6f40c3e X3: Workaround VS2015 rvalue ref in template of noexcept expression bug
* | | | a30e517b1 X3: Workaround VS2015 decltype in function arguments bug
| | | * c3a83ce08 optional_attribute
| |_|/  
|/| |   
* | | b8b82630a fix x3::uint_parser<T(signed)> overflow problem
* | | 690830713 Replaced tab by spaces.
* | | 74f67517c Bugfix and tests for issue #287 "x3 cannot parse into associative containers anymore".
* | | ee4943d58 X3: Fix `unused_type` attribute case in `parse_into_container`
* | | 79995f7e8 x3::error_handler::position() CR+LF lines wrongly counted.
* | | b4e4762b6 Add noexcept specs to x3::variant and forward_ast
* | | 19972887f Context& -> Context const&
* | | 30dfb6230 simplify with directive (3): make rvalue injection mutable
* | | 361b12eee simplify with directive
* | | 1f513cb40 Revert "Crash when print attribute in debug mode."
* | | e7962ea67 Update simple_trace.hpp
* | | 8c7f9c071 Update and_predicate.hpp
* | | ca335f30f Fix dangling refs in debug of call_rule_defintion`
* | | cfa7446a8 silence unused parameter warning
* | | 16320a556 Check for unitialized rules in parser composition
* | | 6c1cab48f Avoid logic_error if rule was unitialized
* | | 29dc7ec6e Added BOOST_SPIRIT_NO_REAL_NUMBERS to not include float parsers
* | | 30c1d59d3 Make standard_wide and wchar_t optional for platforms that do not support
* | | 1d5620fef Update rule.hpp
* | | 379413a50 Fixed bug where string("string1") >> attr(std::string("string2")) produces the wrong attribute result
* | | 124fda502 fix wrong out commented parameter in x3::detail::make_rule_context(...)
* | | 8357037e8 use ignore_unused instead of C-cast to void
* | | a1a30d431 Suppress 'unused parameter' warnings in x3::parse_rule(...)
* | | 5c782ee5e Suppress 'unused parameter' warnings in x3::detail::make_unique_context(...)
* | | 672391030 Suppress 'unused parameter' warnings in x3::detail::move_if_not_alternative::call(...)
* | | 5b1a433d2 Suppress 'unused parameter' warnings in x3::detail::parse_into_container_base_impl::call(...)
* | | 10286fafa Suppress 'unused parameter' warnings in x3::detail::call(...)
* | | 96272e324 Suppress 'unused parameter' warnings in x3::get_info::operator()(...)
* | | 3063a043c Suppress 'unused parameter' warnings in x3::lazy_semantic_predicate::parse(...)
* | | ce02014df Suppress 'unused parameter' warnings in x3::attr_parser::parse(...)
* | | c3f97a461 Suppress 'unused parameter' warnings in rule.hpp
* | | 277cdf777 Suppress 'unused parameter' warnings in container_traits.hpp
* | | a19bcb5b7 Suppress an "unused parameter" warning of rule_
| | | * 8616d3ff3 Update exposed attribute for alternative parser
| |_|/  
|/| |   
* | | de81dc44d Using boost TTI library to replace hand-written TTI code.
* | | b818ca5c8 - added x3 variant test - added x3 variant, extended variant swap member function
* | | 76c57b600 call c.insert(iter, f, l) or c.inser(f, l) as appropriate depending on container type.
* | | 2085a9f50 dangling reference to attribute when BOOST_SPIRIT_X3_DEBUG is defined
* | | 9e488859d Fixes for ticket https://svn.boost.org/trac/boost/ticket/12094
* | | c447315c1 Use forward<T> as appropriate
* | | a077a4cae fixes problem with move_to
* | | 7690022b9 Bigfix: with_context should not return const context. doing so will introduce type conflicts and linker errors
* | | 82bd5b2cc fixes problem with BOOST_SPIRIT_X3_DEBUG.
* | |   d98a7dc9f Merge pull request #175 from octopus-prime/develop
|\ \ \  
| * | | a39923104 Use std::basic_string<Char> instead of Char*
* | | | 035fc0fd9 - added static assert on phrase_parse to make sure user does not pass in unused_type skipper - fixed symbols parser bug (fixes ticket 12016)
* | | |   3cee512a4 Merge pull request #170 from octopus-prime/develop
|\ \ \ \  
| |/ / /  
| * | | 8602d2b8e Replaced cend() by end().
| * | | 0037392a7 Changed push_back(unused_type, T const&) to push_back(unused_type, T&&).
* | | | a8e391bd9 fix sequence partitioning problem
* | | | d91cf7410 Fixes Ticket #11952
| * | | 9c2bc9f34 size calculation in has_reserve_method case only.
| * | | 1fbe050ef Replaced c.end() by c.cend(). Replaced std::integral_constant<bool, detail::has_reserve_method<Container>::value>() by typename detail::has_reserve_method<Container>::type{}.
| * | | 045216a5c Add and use has_reserve_method construct to determine whether container has reserve() method.
| * | | 27d3352ec Added reserve optimization for std::vector and std::basic_string
| * | | c014a081b Cleaned up container_traits.
|/ / /  
* | | c31e79efa Using insert() method of containers in push_back().
* | | cec9817bc Added support for std::multimap, std::unordered_map and std::unordered_multimap.
* | | a362319f3 X3: fix char_range boundaries
* | |   2df3b8885 Merge pull request #110 from mlang/x3/error_handler.position_of
|\ \ \  
* \ \ \   949e49979 Merge pull request #132 from bebuch/develop
|\ \ \ \  
* | | | | b42df6fe5 X3: Fix parse_sequence with variant_attribute.
| * | | | 5dadb838c return type via decltype(auto)
|/ / / /  
* | | | 509029d24 remove include duplicate
* | | | 9b0daf9cc X3: Less is more.
* | | | d109f01de X3: We do not need integer_sequence.hpp.
* | | | 090e7a056 X3: Simplify operator>.
* | | | 391cbb2f2 X3: Use decltype instead of result_of.
* | | |   c6aba10d5 Merge pull request #124 from mlang/x3/context/decltype-auto
|\ \ \ \  
| * | | | d6b5f0d92 X3: Eliminate two more hidden cases of get_result.
* | | | | d87aa6846 X3: Add another missing const&.
|/ / / /  
* | | | 20658b2b2 X3: Remove useless using-directives.
* | | | 6ede5f7c8 X3: [context] decltype(auto) makes get_result unnecessary.
| | | * 2f20512a3 X3: Make use of implicit constructibility.
| |_|/  
|/| |   
* | | 53352198f X3: Use inheritance instead of typedef typename ...::type type;
* | | af73c1c20 X3: Simplify alternative::parse.
* | | 1d7159ce0 X3: Avoid copying the arguments to {unary,binary}_parser, sequence and alternative.
* | | bc20650d9 X3: Remove unused include mpl/joint_view.hpp and add mpl/insert_range.hpp where appropriate.
* | | 2a94b18e9 X3: Fix push_back to mpl::view in x3::sequence.
| * | 2995de5fa Allow retrieval of the iterator_range of a position_tagged.
|/ /  
| * c5b9823ae auto makes this simpler.
|/  
*   0a7fadd83 Merge pull request #104 from teajay-fr/feature/x3_binary
|\  
* | bec338319 Remove leftover pragma once
| * e1210dff4 Clean up and finalized the binary parser
* | 55e87419c c++11 coding style tweaks
* | 1c8d9b6e2 removing #pragma once clutter
| * d5f119779 Add support for the binary parsers
* | ad507e4da Fix include paths.
* | cea20165b - removing extensions - promoting stuff from extensions to directive
* | 10c13779b Rename {directive => extensions}/matches.hpp.
* | dc4c7f824 x3::matches.
|/  
* 8bd4d7078 Add one space after 'for'.
* c13b91ac6 X3: No need for BOOST_FOREACH.
* 033e52c03 Make annotation.hpp generic and move to support/utility/annotate_on_success.hpp.
* 7404981b0 Use utf_to_utf in x3::error_handler.
* ac70d6f65 Allow rule.hpp to be included independently.
* 0debda097 Allow string/string_literal.hpp be able to be independently included.
* 20170960d bug fix x3: where we try to push_back to an mpl::view.
* c60d93fff bug fix for x3 where container attribute is substitute for the container value type. happens with recursive data structures such as vector<v> where v is a variant that also contains vector<v>.
* 0e17b6d05 reorganizing files into cleaner directory structures
* a3d667002 Making testing a full-fledged X3 suppoty utility
* c45fdad1b Bug fix: rule IDs must have accessible on_error and on_sucess
* 3627a4690 more test updates and cleanup
* 0adee06b2 cleaning up the tests
* 63e779a2e added version type
* 21dd555af Updated the check-for-self in x3::variant
* 14c87d616 specific support for puch_back and append to std::map
* c5fe8848c added explicit force_attribute bool template parameter to rule
* 5e4b0a7c8 X3 now works with g++4.9
* 2baddc5f2 fixed new symbols usage
*   729ffd680 Merge pull request #70 from mlang/error_reporting/without/line_pos_iterator
|\  
* | c0ea389a1 Fix misplaced inline keyword.
| * 5d6dd28e8 Decouple error_reporting.hpp from line_pos_iterator.
* | 19ca8017b Add missing inline to avoid linker errors about duplicate definitions.
|/  
*   fec70d409 Merge branch 'x3-devel' into feature/x3_devlop_merge
|\  
* | 9113f02e5 Macro to remove filesystem dependency
| * 6c0b5da3a Improved the formating
| *   e4d195ef2 Merge branch 'x3-devel' of https://github.com/boostorg/spirit into feature/x3_no_case
| |\  
| | * 92bd34bd7 Corrected the seperation of the literal string from their sizes in the any_char operator() Reactivated all the char set tests
| | * 7bde4c42f Add as_parser templates to handle on char strings as char_ instead of literal_string
| | * 134e30e75 Add support for char sets and char ranges
| | * a4e043101 Add the char_set and char_range parser
| | * eec3ff531 Fix the char encoding specific generators for all the string literal parsers
| * 1d6267610 Simplified the case sensitive/insensitive helpers
| * 60cca1161 Implement the no case directive for the symbols parser
| * ad9d0429a Use a less invasive case_compare type extraction from the context
| * 3f089ad13 Create a fresh no_case context for the skipper
| * 430cd5fee Add missing template keyword for clang
| * ea72c747a Make the char class parser no_case compatible. Make all no_case tests pass.
| * 1f01e9056 Use the same logic as the skipper to swap between case sensitive and case insensitive parsing.
| * c0dfd1416 Move the no case tag and the context extraction template to the support folder
| * 4b1fab071 Make no case directive compilable
| * 5a7495205 Add no case directive
* bcd6f561a Merge branch 'develop'

The last commit is in 2018.

Maneuver answered 13/1, 2018 at 12:14 Comment(9)
“mailing list” Ohhh. Where do I subscribe?Brodie
@HenriMenke I don't really know these days, but the list name is spirit-general (boost.org/community/groups.html looks like a starting point)Maneuver
So how come the documentation, and the last post on boost-spirit.com, are from 2015? That does seem slightly fishy.Vivyan
@Vivyan I don't know. The blog looks like it just went out of use. It should probably still get major news-flashes, so it's useful. The docs (both linked from that page and here) say "Last revised: May 15, 2015 at 16:45:18 GMT" - were you referring to the copyright notification? Lastly, is there a point you'd like to make?Maneuver
@sehe: I was hoping you'd reconcile the continuing development per se and the apparentl relevant neglect of the "facade", so to speak.Vivyan
@Vivyan I'm not seeing that neglect. I'm continuing to see evidence of instable interfaces though. Caveat emptor. To me the benefits of modern and the compilation times mostly outweigh the missing/volatile features, but YMMV.Maneuver
I often choose Qi for tasks. For dynamically composing parsers or leveraging custom parsers (e.g. or this), I love x3Maneuver
@sehe, it's almost two years later and what is the update on X3? Is it out of beta yet?Teasley
@Teasley officially nothing changed. I use X3 in lightweight situations (mainly in a single TU) and surround with all the tests. Also running with sanitizers. For many tasks I think Qi is more mature/convenient.Maneuver

© 2022 - 2024 — McMap. All rights reserved.