C++ 提神益气。集成跳过解析器

C++ 提神益气。集成跳过解析器,c++,parsing,boost,boost-spirit,lexical-analysis,C++,Parsing,Boost,Boost Spirit,Lexical Analysis,编辑:我已经删除了lexer,因为它没有与Qi完全集成,只是混淆了语法(请参阅) 我试图在spirit lex框架的基础上发展语法。当我尝试将跳过解析器移动到语法中时,我开始出错 因此,将qi::grammar和qi::rule事件签名从更改为。在语法结构中。我需要做什么 此外,我还设置了token_def,以省略可选的标记和其他一些标记的属性。为什么它仍然在lexer的可选语义操作中为我提供有效的\u val?我之所以问这个问题,是因为我认为问题与qi中事件规则rhs上可选标记的string

编辑:我已经删除了lexer,因为它没有与Qi完全集成,只是混淆了语法(请参阅)


我试图在spirit lex框架的基础上发展语法。当我尝试将跳过解析器移动到语法中时,我开始出错

因此,将
qi::grammar
qi::rule事件
签名从
更改为
。在语法结构中。我需要做什么

此外,我还设置了
token_def
,以省略
可选的
标记和其他一些标记的属性。为什么它仍然在lexer的可选语义操作中为我提供有效的
\u val
?我之所以问这个问题,是因为我认为问题与qi中事件规则rhs上可选标记的string属性有关,而不是与规则的
void()
属性签名一致

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>

namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
    tokens()
        : left_paranthesis("\"{\""),
        right_paranthesis("\"}\""),
        colon(":"),
        namespace_("(?i:namespace)"),
        event("(?i:event)"),
        optional("(?i:optional)"),
        required("(?i:required)"),
        ordinal("\\d+"),
        identifier("\\w+")

    {
        using boost::spirit::lex::_val;

        this->self
            = " "
            | left_paranthesis    [ std::cout << px::val("lpar") << std::endl]
            | right_paranthesis   [ std::cout << px::val("rpar") << std::endl]
            | colon               [ std::cout << px::val("colon") << std::endl]
            | namespace_          [ std::cout << px::val("kw namesapce") << std::endl]
            | event               [ std::cout << px::val("kw event") << std::endl]
            | optional            [ std::cout << px::val("optional ")  << "-->" << _val << "<--" << std::endl]
            | required            [ std::cout << px::val("required") << std::endl]
            | ordinal             [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
            | identifier          [std::cout << px::val("val identifier(") << _val << ")" << std::endl];
    }

    lex::token_def<> left_paranthesis, right_paranthesis, colon;
    lex::token_def<lex::omit> namespace_, event, optional, required;
    lex::token_def<boost::uint32_t> ordinal;
    lex::token_def<> identifier;
};

template <typename Iterator>
struct grammar : qi::grammar<Iterator>
{
    template <typename TokenDef>
    grammar(TokenDef const& tok)
      : grammar::base_type(event)
    {
      //start = event;
      event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
    }

    qi::rule<Iterator> start;
    qi::rule<Iterator> event;
};

// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";

std::string test = "OPTIONAL";

int main()
{
    typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
    typedef lex::lexertl::actor_lexer<token_type> lexer_type;
    typedef tokens<lexer_type>::iterator_type iterator_type;

    tokens<lexer_type> token_lexer;
    grammar<iterator_type> grammar(token_lexer);

    std::string::iterator first = test.begin();
    std::string::iterator last = test.end(); 
    bool r; 

    r = lex::tokenize_and_parse(first, last, token_lexer, grammar);

    if(r)
        ;
    else
    {
        std::cout << "parsing failed" << std::endl;
    }
   /* 
    lexer_type::iterator_type iter; 

    try
    {
        iter = token_lexer.begin(first,last);
    }
    catch(std::exception & e)
    {
        std::cout << e.what() << std::endl;
    }

    lexer_type::iterator_type end = token_lexer.end();

    while (iter != end && token_is_valid(*iter))
        ++iter;
   */ 
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间lex=boost::spirit::lex;
名称空间px=boost::phoenix;
名称空间qi=boost::spirit::qi;
名称空间ascii=boost::spirit::ascii;
模板
结构令牌:lex::lexer
{
代币()
:左(“{\”),
右图(“\”}\”),
冒号(“:”,
名称空间(“(?i:名称空间)”),
事件(“(?i:事件)”),
可选((?i:可选)”,
必需((?i:必需)”,
序数(\\d+),
标识符(\\w+)
{
使用boost::spirit::lex::\u val;
这个->自我
= " "

|左思右想[std::cout与大多数spirit一样。如果你想做一些现实的事情,你必须花几个小时寻找一个没有记录但隐藏在示例和邮件列表中的解决方案。认真考虑转向ragel或flex/bison。问题不在于机器不可用,而在于它没有记录

在本例中,当查看lex文档时,我们会发现lex parser api调用有一个
标记化_和_短语_parse
函数,这在您尝试像
qi::短语_parse
那样使用它时并不真正起作用。文档也没有解释如何使用此函数连接跳过程序不客气

将空格跳跃器连接到解析器中的方法是更改lexer,然后使用一些未记录的qi skipper构造初始化语法和规则。您可以在lex示例目录(示例5)中看到这一点。编译并运行的代码:

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>

namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
    tokens()
        : left_paranthesis("\"{\""),
        right_paranthesis("\"}\""),
        colon(":"),
        namespace_("(?i:namespace)"),
        event("(?i:event)"),
        optional("(?i:optional)"),
        required("(?i:required)"),
        ordinal("\\d+"),
        identifier("\\w+")

    {
        using boost::spirit::lex::_val;

        this->self
            = 
              left_paranthesis    [ std::cout << px::val("lpar") << std::endl]
            | right_paranthesis   [ std::cout << px::val("rpar") << std::endl]
            | colon               [ std::cout << px::val("colon") << std::endl]
            | namespace_          [ std::cout << px::val("kw namesapce") << std::endl]
            | event               [ std::cout << px::val("kw event") << std::endl]
            | optional            [ std::cout << px::val("optional ")  << "-->" << _val << "<--" << std::endl]
            | required            [ std::cout << px::val("required") << std::endl]
            | ordinal             [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
            | identifier          [std::cout << px::val("val identifier(") << _val << ")" << std::endl];


        this->self("WS") =   lex::token_def<>("[ \\t\\n]+");
    }


    lex::token_def<> left_paranthesis, right_paranthesis, colon;
    lex::token_def<lex::omit> namespace_, event, optional, required;
    lex::token_def<boost::uint32_t> ordinal;
    lex::token_def<> identifier;
};

template <typename Iterator, typename Lexer>
struct grammar : qi::grammar<Iterator,qi::in_state_skipper<Lexer> >
{
    template <typename TokenDef>
    grammar(TokenDef const& tok)
      : grammar::base_type(event)
    {
      //start = event;
      event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
    }

    qi::rule<Iterator> start;
    qi::rule<Iterator, qi::in_state_skipper<Lexer> > event;
};

// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";

std::string test = " OPTIONAL ";

int main()
{
    typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
    typedef lex::lexertl::actor_lexer<token_type> lexer_type;
    typedef tokens<lexer_type>::iterator_type iterator_type;

    tokens<lexer_type> token_lexer;
    grammar<iterator_type,tokens<lexer_type>::lexer_def> grammar(token_lexer);

    std::string::iterator it = test.begin();
    iterator_type first = token_lexer.begin(it, test.end());
    iterator_type last = token_lexer.end();

    bool r; 

    r = qi::phrase_parse(first, last, grammar, qi::in_state("WS")[token_lexer.self]);

    if(r)
        ;
    else
    {
        std::cout << "parsing failed" << std::endl;
    }
   /* 
    lexer_type::iterator_type iter; 

    try
    {
        iter = token_lexer.begin(first,last);
    }
    catch(std::exception & e)
    {
        std::cout << e.what() << std::endl;
    }

    lexer_type::iterator_type end = token_lexer.end();

    while (iter != end && token_is_valid(*iter))
        ++iter;
   */ 
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间lex=boost::spirit::lex;
名称空间px=boost::phoenix;
名称空间qi=boost::spirit::qi;
名称空间ascii=boost::spirit::ascii;
模板
结构令牌:lex::lexer
{
代币()
:左(“{\”),
右图(“\”}\”),
冒号(“:”,
名称空间(“(?i:名称空间)”),
事件(“(?i:事件)”),
可选((?i:可选)”,
必需((?i:必需)”,
序数(\\d+),
标识符(\\w+)
{
使用boost::spirit::lex::\u val;
这个->自我
= 

左脑偏执[std::cout然而,
lex::pass\u flags::pass\u ignore
os完美地记录了一个符合要求的操作系统。关键是,你不需要传统的跳过程序。是的,老实说,这种方法使语法比以前更干净。如果我使用
pass\u ignore
我想我甚至不必跳过
qi::in\u state\kipper
在我的语法中,lexer会悄悄跳过WS-tokens?在这个网站上搜索总是一个好主意。似乎是合适的。hehe=D巧合的是,我现在正在看另一个问题,sehe在邮件列表中出现了:。
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>

namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
    tokens()
        : left_paranthesis("\"{\""),
        right_paranthesis("\"}\""),
        colon(":"),
        namespace_("(?i:namespace)"),
        event("(?i:event)"),
        optional("(?i:optional)"),
        required("(?i:required)"),
        ordinal("\\d+"),
        identifier("\\w+")

    {
        using boost::spirit::lex::_val;

        this->self
            = 
              left_paranthesis    [ std::cout << px::val("lpar") << std::endl]
            | right_paranthesis   [ std::cout << px::val("rpar") << std::endl]
            | colon               [ std::cout << px::val("colon") << std::endl]
            | namespace_          [ std::cout << px::val("kw namesapce") << std::endl]
            | event               [ std::cout << px::val("kw event") << std::endl]
            | optional            [ std::cout << px::val("optional ")  << "-->" << _val << "<--" << std::endl]
            | required            [ std::cout << px::val("required") << std::endl]
            | ordinal             [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
            | identifier          [std::cout << px::val("val identifier(") << _val << ")" << std::endl];


        this->self("WS") =   lex::token_def<>("[ \\t\\n]+");
    }


    lex::token_def<> left_paranthesis, right_paranthesis, colon;
    lex::token_def<lex::omit> namespace_, event, optional, required;
    lex::token_def<boost::uint32_t> ordinal;
    lex::token_def<> identifier;
};

template <typename Iterator, typename Lexer>
struct grammar : qi::grammar<Iterator,qi::in_state_skipper<Lexer> >
{
    template <typename TokenDef>
    grammar(TokenDef const& tok)
      : grammar::base_type(event)
    {
      //start = event;
      event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
    }

    qi::rule<Iterator> start;
    qi::rule<Iterator, qi::in_state_skipper<Lexer> > event;
};

// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";

std::string test = " OPTIONAL ";

int main()
{
    typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
    typedef lex::lexertl::actor_lexer<token_type> lexer_type;
    typedef tokens<lexer_type>::iterator_type iterator_type;

    tokens<lexer_type> token_lexer;
    grammar<iterator_type,tokens<lexer_type>::lexer_def> grammar(token_lexer);

    std::string::iterator it = test.begin();
    iterator_type first = token_lexer.begin(it, test.end());
    iterator_type last = token_lexer.end();

    bool r; 

    r = qi::phrase_parse(first, last, grammar, qi::in_state("WS")[token_lexer.self]);

    if(r)
        ;
    else
    {
        std::cout << "parsing failed" << std::endl;
    }
   /* 
    lexer_type::iterator_type iter; 

    try
    {
        iter = token_lexer.begin(first,last);
    }
    catch(std::exception & e)
    {
        std::cout << e.what() << std::endl;
    }

    lexer_type::iterator_type end = token_lexer.end();

    while (iter != end && token_is_valid(*iter))
        ++iter;
   */ 
}