gpt4 book ai didi

c++ - boost spirit 力和气力。集成跳过解析器

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:48:30 26 4
gpt4 key购买 nike

编辑:我删除了词法分析器,因为它没有与 Qi 完全集成,只是混淆了语法(参见 here)。


我正在尝试在 spirit lex 框架之上发展语法。当我尝试将跳过解析器移动到语法中时,我开始遇到错误。

因此,更改 qi::grammar<>qi::rule<> event来自 <Iterator> 的签名至 <Iterator,void(),ascii::space_type> .在语法结构中。我需要做什么?

此外,我还设置了 token_defoptional 省略其属性 token 和其他一些。为什么它仍然为我提供有效的 _val在词法分析器中可选的语义 Action 中?我问的原因是因为我认为问题与 qi 中事件规则的 rhs 上的可选标记的字符串属性有关,不与 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;
*/
}

此语法失败:

template <typename Iterator>
struct grammar : qi::grammar<Iterator,void(),ascii::space_type>
{
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,void(),ascii::space_type> event;
};

最佳答案

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

在这种情况下,当查看 lex 文档时,查看具有 tokenize_and_phrase_parse 函数的 lex 解析器 api 调用会大大误导。当您尝试像 qi::phrase_parse 那样使用它时,它实际上不起作用,文档也没有解释如何使用此函数连接 skipper 。

通过更改词法分析器,然后使用一些未记录的 qi-skipper 构造来初始化语法和规则,从而将 space 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;
*/
}

关于c++ - boost spirit 力和气力。集成跳过解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19184891/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com