1

Imagine there is a rule to parse some name:

m_sName = qi::lexeme[
    (ascii::alpha | qi::char_('_')) >> *(ascii::alnum | qi::char_('_'))
]

Could one use the same object for parsing two names in series or does one have to instantiate m_sName1 and m_sName2?

m_sName >> m_sName
sehe
  • 374,641
  • 47
  • 450
  • 633
Frank Puck
  • 467
  • 1
  • 11
  • What prompts this question? It seems to me that something else than `m_sName >> m_sName` makes no sense, and you would have your answer in 10s of trying. Well 30s on a slow compiler. Is there a context where this is not working the way you expected it to work? – sehe Jun 13 '23 at 14:37
  • 1
    @sehe I had a grammar in which until now I had used multiple copies of the same grammar because I somehow had the (wrong?) notion that they must be separate. – Frank Puck Jun 13 '23 at 16:07
  • You can see a parser epression as a declarative specification of a `parse()` function. All state goes in via arguments. (Of course your own grammars might add instance state if you want, but then it becomes harder to reason about reuse and even recursion) – sehe Jun 13 '23 at 16:30

1 Answers1

2

I made a sample that might help:

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <iomanip>

int main() {
    namespace qi = boost::spirit::qi;
    using It     = std::string::const_iterator;

    qi::rule<It, std::string()> m_sName = (qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'));

    for (std::string const input : {"foo bar qux_net"}) {
        std::string a, b, c;
        if (phrase_parse(input.begin(), input.end(), m_sName >> m_sName >> m_sName, qi::space, a, b, c)) {
            std::cout << quoted(a) << " " << quoted(b) << " " << quoted(c) << "\n";
        }
    }
}

Prints

"foo" "bar" "qux_net"

NOTES

sehe
  • 374,641
  • 47
  • 450
  • 633