gpt4 book ai didi

c++ - 跟踪 boost::spirit 的位置

转载 作者:太空宇宙 更新时间:2023-11-04 11:47:06 25 4
gpt4 key购买 nike

如何追踪 spirit 属性的位置?

一个简单的例子

template <typename Iterator>
bool trace_numbers(Iterator first, Iterator last)
{
using boost::spirit::qi::double_;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;

bool r = phrase_parse(first, last,

// Begin grammar
(
double_ % ','
)
,
// End grammar
space);

if (first != last) // fail if we did not get a full match
return false;
return r;
}

我想追踪“double_”的位置(行和列),我找到line_pos_iterator但不知道如何使用它。我还找到了multi-pass , 但不知道它是否可以用来追踪位置(如果可以,怎么做?)。

最佳答案

经过研究,我发现单独使用spirit::lex或者结合spirit::qi是一个解决方案。

#include <boost/config/warning_disable.hpp>
//[wcp_includes
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
//]

#include <iostream>
#include <string>
#include <vector>

namespace spiritParser
{

//[wcp_namespaces
using namespace boost::spirit;
using namespace boost::spirit::ascii;

//[wcp_token_ids
enum tokenids
{
IDANY = lex::min_token_id + 10
};
//]

//[wcp_token_definition
template <typename Lexer>
struct number_position_track_tokens : lex::lexer<Lexer>
{
number_position_track_tokens()
{
// define patterns (lexer macros) to be used during token definition
// below
this->self.add_pattern
("NUM", "[0-9]+")
;

number = "{NUM}"; // reference the pattern 'NUM' as defined above

this->self.add
(number) // no token id is needed here
(".", IDANY) // characters are usable as tokens as well
;
}

lex::token_def<std::string> number;
};
//]

template<typename Iterator>
struct numberGrammar : qi::grammar<Iterator>
{
template <typename TokenDef>
numberGrammar(TokenDef const &tok)
: numberGrammar::base_type(start)
, num(0), position(0)
{
using boost::phoenix::ref;
using boost::phoenix::push_back;
using boost::phoenix::size;
//"34, 44, 55, 66, 77, 88"
start = *( tok.number [++ref(num),
boost::phoenix::push_back(boost::phoenix::ref(numPosition), boost::phoenix::ref(position)),
ref(position) += size(_1)
]
| qi::token(IDANY) [++ref(position)]
)
;
}

std::size_t num, position;
std::vector<size_t> numPosition;
qi::rule<Iterator> start;
};

void lex_word_count_1()
{
using token_type = lex::lexertl::token<char const*, boost::mpl::vector<std::string> >;

number_position_track_tokens<lexer_type> word_count; // Our lexer
numberGrammar<iterator_type> g (word_count); // Our parser

// read in the file int memory
std::string str ("34, 44, 55, 66, 77, 88");
char const* first = str.c_str();
char const* last = &first[str.size()];

if (r) {
std::cout << "nums: " << g.num << ", size: " << g.position <<std::endl;
for(auto data : g.numPosition){
std::cout<<"position : "<<data<<std::endl;
}
}
else {
std::string rest(first, last);
std::cerr << "Parsing failed\n" << "stopped at: \""
<< rest << "\"\n";
}
}

}

这是文档 Quickstart 3 - Counting Words Using a Parser 中的示例有一些交替。在我看来,对于像这样的小任务来说,这远非易事。如果模式对 std::regex 来说不难描述;需要更快的速度或两者兼而有之,选择 spirit::lex 来跟踪简单模式的位置(如我展示的示例)是多余的。

关于c++ - 跟踪 boost::spirit 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19486358/

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