请考虑以下代码:(Boost.Spirit 2.5.1)
qi::parse(str.begin(), str.end(), (+qi::alpha)[[](const string& s){cout << s<< '\n';}]
>> (*(qi::char_(',') | qi::char_('\'')))
>> qi::uint_[[](int integer){cout << integer << '\n';}]);
Run Code Online (Sandbox Code Playgroud)
该[[](int integer){cout << integer << '\n';}]作品,但类似的代码+qi::alpha没有.
我该如何更正代码?
我很难得到一个小的boost :: spirit语法来编译.这是一个较大的语法的一小部分,我遇到了麻烦,我正在尝试测试较小的部分来发现我的问题.基本上这个语法应该做的是解析一个double值,它有任意数量的前导/尾随空格.但是当我尝试编译时,我得到了一些我不理解的问题清单.欢迎任何帮助!代码:grammar.h
#ifndef GRAMMAR_H
#define GRAMMAR_H
#include <boost/spirit/include/qi.hpp>
template <typename Iterator>
struct point_double_grammar : boost::spirit::qi::grammar<Iterator, double()>
{
/**
* Constructor used to create the grammar.
* @param is_point boolean indicating if the point is used as decimal.
* @author Luc Kleeven
**/
point_double_grammar() : point_double_grammar::base_type(d)
{
d = *boost::spirit::qi::lit(' ') >> boost::spirit::qi::double_ >> *boost::spirit::qi::lit(' ');
}
boost::spirit::qi::rule<Iterator, double()> d;
};
#endif // GRAMMAR_H
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "grammar.h"
int main(int argc, char *argv[])
{
point_double_grammar<std::string::iterator> point_grammar();
bool result = false;
double …Run Code Online (Sandbox Code Playgroud) 我希望有人可以通过我在精神解析中使用>和>>操作符的无知来发光.
我有一个工作语法,顶级规则看起来像
test = identifier >> operationRule >> repeat(1,3)[any_string] >> arrow >> any_string >> conditionRule;
Run Code Online (Sandbox Code Playgroud)
它依赖于属性来自动将解析后的值分配给融合自适应结构(即boost元组).
但是,我知道一旦我们匹配operationRule,我们必须继续或失败(即我们不希望允许回溯尝试以其他规则开头identifier).
test = identifier >>
operationRule > repeat(1,3)[any_string] > arrow > any_string > conditionRule;
Run Code Online (Sandbox Code Playgroud)
这会导致一个神秘的编译器错误('boost::Container' : use of class template requires template argument list).Futz一点点以下编译:
test = identifier >>
(operationRule > repeat(1,3)[any_string] > arrow > any_string > conditionRule);
Run Code Online (Sandbox Code Playgroud)
但属性设置不再有效 - 我的数据结构在解析后包含垃圾.这可以通过添加类似的操作来修复[at_c<0>(_val) = _1],但这似乎有点笨拙 - 以及根据boost文档使事情变慢.
所以,我的问题是
()operationRule匹配之后是否真的停止了回溯(我怀疑不是,似乎如果(...)允许整个解析器内部失败回溯)?当我尝试从iterator_range转换令牌的值时,词法分析器在尝试读取下一个令牌时失败.
这是包含令牌定义的Tokens结构:(我不认为这是相关的,但我包括以防万一.)
template <typename Lexer>
struct Tokens : boost::spirit::lex::lexer<Lexer>
{
Tokens();
boost::spirit::lex::token_def<std::string> identifier;
boost::spirit::lex::token_def<std::string> string;
boost::spirit::lex::token_def<bool> boolean;
boost::spirit::lex::token_def<double> real;
boost::spirit::lex::token_def<> comment;
boost::spirit::lex::token_def<> whitespace;
};
template <typename Lexer>
Tokens<Lexer>::Tokens()
{
// Define regex macros
this->self.add_pattern
("LETTER", "[a-zA-Z_]")
("DIGIT", "[0-9]")
("INTEGER", "-?{DIGIT}+")
("FLOAT", "-?{DIGIT}*\\.{DIGIT}+");
// Define the tokens' regular expressions
identifier = "{LETTER}({LETTER}|{DIGIT})*";
string = "\"[a-zA-Z_0-9]*\"";
boolean = "true|false";
real = "{INTEGER}|{FLOAT}";
comment = "#[^\n\r\f\v]*$";
whitespace = "\x20\n\r\f\v\t+";
// Define tokens
this->self
= identifier
| string
| boolean
| real
| '{' …Run Code Online (Sandbox Code Playgroud) 假设我有一个std::string属性,但为了易于解析,我想使用qi::int_或qi::double_.
有一种简单的方法可以将转换作为语义操作吗?
我试过这样的事情:
std::stringstream ss;
my_int_as_str = qi::int_ [ ref(ss)<<_1; _val=ss.str() ];
Run Code Online (Sandbox Code Playgroud)
但这甚至不会编译.
编辑 - 尝试下面的回答
#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi=boost::spirit::qi;
namespace phx=boost::phoenix;
int main(int argc, char* argv[])
{
std::string test="123";
std::string result;
// 1. qi::raw[ qi::int_ ] works
// 2. qi::lexeme[ qi::int_ ] doesn't
// 3. qi::as_string[ qi::int_ ] doesn't
qi::rule<std::string::const_iterator, std::string()> my_int_as_str =
qi::raw[ qi::int_ ];
parse( test.cbegin(), test.cend(), my_int_as_str, result );
std::cout << result << …Run Code Online (Sandbox Code Playgroud) 例如,假设我有以下结构/子结构定义:
struct address_rec
{
std::string m_street;
std::string m_state;
unsigned m_zip;
};
struct employee_rec
{
std::string m_name;
address_rec m_address;
};
Run Code Online (Sandbox Code Playgroud)
我应该如何使用BOOST_FUSION_ADAPT_STRUCT的employee_rec?
我正在尝试扩展计算器示例,以便解析器将确定代数语句是否为真,而不是解析和评估代数表达式.我的意思是1 + 5 * 5 - 10 = 19 - 3(期望的解析器结果是true)和3 - 1 = 9(期望的解析器结果false).
我必须承认我是新手,boost::spirit而且现在这一切都是压倒性的.但是,我觉得我理解计算器示例足够好,至少可以取得一些进展.
使用提供的示例作为起点,语法如下所示:
calculator() : calculator::base_type(expression)
{
using qi::uint_;
using qi::_val;
using qi::_1;
expression =
term [_val = _1]
>> *( ('+' >> term [_val = _val + _1])
| ('-' >> term [_val = _val - _1])
);
term =
factor [_val = _1]
>> *( ('*' >> factor [_val = _val * …Run Code Online (Sandbox Code Playgroud) 我的解析器语法底部有以下错误处理程序:
qi::on_error<qi::fail>(
launch,
std::cerr << phoenix::val("Paring error in ") << spirit::_4 << std::endl
<< phoenix::construct<std::string>(spirit::_3, spirit::_2)
<< std::endl
);
Run Code Online (Sandbox Code Playgroud)
问题是解析器的输入事先没有被新行分解,因此产生的错误语句将是源代码中从错误点到结束的所有行.有没有直接替代
phoenix::construct<std::string>(spirit::_3, spirit::_2)
Run Code Online (Sandbox Code Playgroud)
只打印发生错误的一行?如果我试图搜索,凤凰语义将给我带来麻烦'\n'.
我希望能够解析一个数字,以存储其原始来源并跟踪其在源中的位置,并将其保留在结构本身中.
这是我到目前为止:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/home/support/iterators/line_pos_iterator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <iostream>
#include <iomanip>
#include <ios>
#include <string>
#include <complex>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
struct Position
{
Position()
: line(-1)
{
}
size_t line;
};
struct Number : public Position
{
Number()
: Position()
, value(-1)
, source()
{
}
unsigned value;
std::string source;
};
using namespace boost::spirit;
BOOST_FUSION_ADAPT_STRUCT(Number,
(unsigned, value)
(std::string, source)
(size_t, line)
);
template <typename Iterator>
struct source_hex : …Run Code Online (Sandbox Code Playgroud) 我用boost :: spirit :: qi :: rule写了一些语法来解析互联网数据包.语法是这样的:
qi::rule<Iterator> start, request, response, status, query ;
start = (request | response | status | query) >> lit("\r\n");
Run Code Online (Sandbox Code Playgroud)
为了提高性能,用户可能希望跳过运行时中的一些规则,例如忽略"响应","状态","查询"并且只尝试匹配请求,因此规则将更改为:
start = (request ) >> lit("\r\n");
Run Code Online (Sandbox Code Playgroud)
有可能这样做吗?例如,是否有一个像"禁用()"这样的功能来禁用规则"响应","状态"和"查询"?