我正计划使用Boost.Spirit 2进行脚本转换实用程序(用于扩展诊断信息).
虽然支持行信息等解析错误,但我如何使用Qi存储成功解析的表达式的行号?
试图调整boost spirit x3 calc示例来解析可以将函数作为参数的函数.但是它没有编译.
namespace client{ namespace ast{
struct ts;
struct fnc;
typedef boost::variant<
ts,
boost::recursive_wrapper<fnc>
> node;
struct ts{
unsigned int id;
};
struct fnc{
std::vector<char> id;
std::vector<node> args;
};
}}
BOOST_FUSION_ADAPT_STRUCT(
client::ast::ts,
(unsigned int, id)
)
BOOST_FUSION_ADAPT_STRUCT(
client::ast::fnc,
(std::vector<char>, id)
(std::vector<client::ast::node>, args)
)
namespace client{
namespace x3 = boost::spirit::x3;
namespace calc_grammar{
using x3::uint_;
using x3::alpha;
using x3::alnum;
using x3::lit;
using x3::char_;
x3::rule<class funct, ast::fnc> const funct("function");
x3::rule<class ts, ast::ts> const ts("timeseries");
x3::rule<class funct_name, std::vector<char>> const funct_name("function_name");
auto const …
Run Code Online (Sandbox Code Playgroud) 不应该简单eol
的伎俩吗?
#include <algorithm>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
using boost::spirit::ascii::space;
using boost::spirit::lit;
using boost::spirit::qi::eol;
using boost::spirit::qi::phrase_parse;
struct fix : std::unary_function<char, void> {
fix(std::string &result) : result(result) {}
void operator() (char c) {
if (c == '\n') result += "\\n";
else if (c == '\r') result += "\\r";
else result += c;
}
std::string &result;
};
template <typename Parser>
void parse(const std::string &s, const Parser &p) {
std::string::const_iterator it = s.begin(), end = s.end();
bool r = phrase_parse(it, …
Run Code Online (Sandbox Code Playgroud) 我试图像下面的树表达式一样解析C函数(使用Spirit Parser Framework):
F( A() , B( GREAT( SOME , NOT ) ) , C( YES ) )
Run Code Online (Sandbox Code Playgroud)
为此,我试图使用以下语法的三个规则:
template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {
InputGrammar() : InputGrammar::base_type( ) {
tag = ( qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9") )[ push_back( at_c<0>(qi::_val) , qi::_1 ) ];
command = tag [ at_c<0>(qi::_val) = at_c<0>(qi::_1) ] >> "(" >> (*instruction >> ",")
[ push_back( at_c<1>(qi::_val) , qi::_1 ) ] >> ")";
instruction = ( command …
Run Code Online (Sandbox Code Playgroud) 我必须使用boost :: spirit进行解析,我想使用phrase_parse函数:
qi::phrase_parse(str.begin(), str.end(), grammar, ascii::space - qi::eol);
Run Code Online (Sandbox Code Playgroud)
但是我的编译器不允许第四个术语(ascii :: space - qi :: eol).我如何使用船长ascii :: space没有跳过eol?
如何使用utf8 unicode字符boost::spirit
?
例如,我想识别此字符串中的所有字符:
$ echo "?? ?????? ????????? ????" | ./a.out
? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ?
Run Code Online (Sandbox Code Playgroud)
当我尝试这个简单的boost::spirit
程序时,它将无法正确匹配unicode字符:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/foreach.hpp>
namespace qi = boost::spirit::qi;
int main() {
std::cin.unsetf(std::ios::skipws);
boost::spirit::istream_iterator begin(std::cin);
boost::spirit::istream_iterator end;
std::vector<char> letters;
bool result = qi::phrase_parse(
begin, end, // input
+qi::char_, // match every character
qi::space, // skip whitespace
letters); // result
BOOST_FOREACH(char letter, letters) { …
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种方法来将字符串解析为int或double,解析器应该尝试两种方法并选择与输入流的最长部分匹配的方法.
有一个不推荐使用的指令(longest_d)正是我正在寻找的:
number = longest_d[ integer | real ];
Run Code Online (Sandbox Code Playgroud)
...因为它已被弃用,还有其他选择吗?如果有必要实现语义动作来实现所需的行为,有没有人有建议?
显然 hold_any
有比...更好的表现boost::any
.它是如何设法做到这一点的?
我有一个关于Spirit Qi的编译问题,它抱怨value_type不是标识符的成员.出于某种原因,Qi的属性系统将标识符视为容器类型,并尝试枚举它的值类型.
这是与此问题类似的问题,但是,我认为原因是单个成员结构,可能与此错误有关.
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
using namespace boost::spirit::qi;
struct identifier
{
std::wstring name;
};
struct problem
{
identifier _1;
identifier _2;
identifier _3;
};
BOOST_FUSION_ADAPT_STRUCT(
identifier,
(std::wstring, name)
)
BOOST_FUSION_ADAPT_STRUCT(
problem,
(identifier, _1)
(identifier, _2)
(identifier, _3)
)
int main(int argc, char* argv[])
{
rule<std::wstring::const_iterator, identifier()> gr_identifier = eps >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]];
// Ok, compiles
/*rule<std::wstring::const_iterator, problem()> gr_problem = gr_identifier
>> …
Run Code Online (Sandbox Code Playgroud) 我正在努力学习Boost.Spirit,但我发现了一个难点.
我试图将字符串解析为以下结构:
struct employee {
std::string name;
std::string location;
};
Run Code Online (Sandbox Code Playgroud)
似乎当两个具有相同类型的属性背靠背时,它们会崩溃(逻辑上)std::vector
为该类型的一个.由于该规则,以下解析器
+x3::ascii::alnum >>
+x3::space >>
+x3::ascii::alnum
Run Code Online (Sandbox Code Playgroud)
会有的属性std::vector<std::string>
.
但我试图将其解析为struct
,这意味着我的理想属性将是一个boost::fusion::tuple<std::string, std::string>
,所以我可以调整我的结构.
不工作代码的完整版本(如上所述):
// Example program
#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct employee {
std::string name;
std::string location;
};
BOOST_FUSION_ADAPT_STRUCT(employee,
(std::string, name),
(std::string, location)
)
namespace x3 = boost::spirit::x3;
x3::rule<struct parse_emp_id, employee> const parse_emp = "Employee Parser";
auto parse_emp_def =
+x3::ascii::alnum >>
+x3::space >>
+x3::ascii::alnum
;
BOOST_SPIRIT_DEFINE(parse_emp);
int main()
{
std::string input …
Run Code Online (Sandbox Code Playgroud)