Home > Enterprise >  What is the motivation of a separate config.hpp in boost spirit X3 program structure?
What is the motivation of a separate config.hpp in boost spirit X3 program structure?

Time:11-17

The title itself should be quite clear, but for more context, I was going through the tutorial about x3 program structure in order to re-structure my own baby-parsing-project before adding a recursive AST, and it is not clear to me what level of complexity management I can achieve using the proposed layers.

Particularly, I am confused at what the config.hpp enables. I could find at least one person had similar interrogations.

The content of this file is:

/*=============================================================================
    Copyright (c) 2001-2018 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_MINIMAL_CONFIG_HPP)
#define BOOST_SPIRIT_X3_MINIMAL_CONFIG_HPP

#include <boost/spirit/home/x3.hpp>

namespace client { namespace parser
{
    namespace x3 = boost::spirit::x3;

    using iterator_type = std::string::const_iterator;
    using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
}}

#endif

The motivations as stated in the documentation are: Here, we declare some types for instatntaiting our X3 parser with. Rememeber that Spirit parsers can work with any ForwardIterator. We'll also need to provide the initial context type. This is the context that X3 will use to initiate a parse. For calling phrase_parse, you will need the phrase_parse_context like we do below, passing in the skipper type.

My guess is this module is useful in complex project, but does not bring much for my simplistic application: am I wrong?

On a larger scope and for future reference, what would be is a good rule of thumb/redline not to cross in terms of modularity in the context of x3 parsers? (my lack of experience here is striking!)

CodePudding user response:

Again, you're asking the big, core questions!

You don't need a config.hpp.

However, if you spread definition of rules across translation units, you will need to decide on the concrete template instantiations you need to be part of your object files.

The two variable parameters here are

  • iterator type
  • context type

The X3 examples all assume you will have a single set for your entire grammar. The developers have decided that it would be a good way to emphasize this by putting these "global parameters" in a central header.

There are many documented cases on this site where people have run into linker errors when working from one of the spirit examples, when they switched iterator types (e.g. from std::string::iterator to std::string::const_iterator) or by introducing another skipper.

Keep in mind you might want to facilitate multiple iterator/context combinations. Nothing prevents you from instantiating parse_rule functions for different combinations of parameters: BOOST_SPIRIT_INSTANTIATE.

Finally:

Q. My guess is this module is useful in complex project, but does not bring much for my simplistic application: am I wrong?

You are correct. In fact, I think that X3 shines when you can encapsulate the entire grammar inside a translation unit so that you don't need to deal with explicit instantiations, or even BOOST_SPIRIT_DEFINE - except for recursive rules.

  • Related