如何使用boost spirit x3 kleene star?
How to use boost spirit x3 kleene star?
我是 boost::spirit
的新手,正在尝试使用 x3 编写一个简单的解析器。
我收到一个无法解释的错误。
出于某种原因,我收到有关 boost::spirit::x3::unused_type
的错误消息。
当我删除下面标记的行中的 kleene star 时,错误消失了。
其他 kleene 星似乎还好(出于某种原因)。
这是我的代码:
#include <string>
#include <iostream>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
int main()
{
std::string str = "qqq::qqq::qqq";
auto begin = str.begin(), end = str.end();
bool r = x3::parse(begin, end,
( (x3::alpha | '_') >> *(x3::alnum | '_')) >>
* //this line is the problem
("::" >> (x3::alpha | '_') >> *(x3::alnum | '_'))
); // is supposed to match str
if (r && std::distance(begin,end) < 1)
{
std::cout << "Parsing succeeded\n";
}
else
{
std::cout << "Parsing FAILED\n";
std::cout << "r " << r << " d " << std::distance(begin,end) << "\n";
}
return 0;
}
这是错误:
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:254:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘empty’
254 | if (attr.empty())
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘insert’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:34: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:46: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘begin’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:60: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~
我在 Ubuntu 18.04 使用 boost 1.65.1。
我阅读了这篇文章 () post,其中描述了类似的问题。
有没有办法在不更改系统包的情况下解决或规避这个问题?
不,这只是一个已修复的错误。
- 1.65.1 https://wandbox.org/permlink/uUeqVJOsnSxk9aD1 损坏
- 1.66.0 https://wandbox.org/permlink/AhQ9G8Ubm9v0DeYj 损坏
- 1.67.0 https://wandbox.org/permlink/nh4wDJdhO8lSfBZo 还行
无论如何,像 x3::alpha | '_'
这样的语法结构不会公开您需要的内容,因为 literal '_'
不公开任何属性。
因此,在实践中您可能只想使用 raw[]
:
来简化
auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ]
接下来,您可以匹配多个符合::
的标识符:
x3::raw [ ident >> * ("::" >> ident) ]
顺便说一下,这完全等同于
x3::raw [ ident % "::") ]
见
- 1.65.1 https://wandbox.org/permlink/Jorllem5U7u3L04e 还行
- 1.67.0 https://wandbox.org/permlink/EXMjDTPhcZfu05Ot 也可以
奖金:
分配给属性
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip>
#include <string>
namespace x3 = boost::spirit::x3;
int main() {
std::string str = "foo::_bar::qux_1";
auto begin = str.begin(), end = str.end();
auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ] ];
std::vector<std::string> qualified;
bool r = x3::parse(begin, end, ident % "::", qualified);
if (r && begin==end) {
std::cout << "Parsing succeeded\n";
for (auto& el : qualified) {
std::cout << " element " << std::quoted(el) << "\n";
}
} else {
std::cout << "Parsing FAILED\n";
}
std::cout << std::boolalpha << r << " " << std::quoted(std::string(begin, end)) << "\n";
}
打印:
Parsing succeeded
element "foo"
element "_bar"
element "qux_1"
true ""
并且语法被简化为
std::vector<std::string> qualified;
bool r = x3::parse(begin, end, ident % "::", qualified);
这通常是个好兆头。
我是 boost::spirit
的新手,正在尝试使用 x3 编写一个简单的解析器。
我收到一个无法解释的错误。
出于某种原因,我收到有关 boost::spirit::x3::unused_type
的错误消息。
当我删除下面标记的行中的 kleene star 时,错误消失了。
其他 kleene 星似乎还好(出于某种原因)。
这是我的代码:
#include <string>
#include <iostream>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
int main()
{
std::string str = "qqq::qqq::qqq";
auto begin = str.begin(), end = str.end();
bool r = x3::parse(begin, end,
( (x3::alpha | '_') >> *(x3::alnum | '_')) >>
* //this line is the problem
("::" >> (x3::alpha | '_') >> *(x3::alnum | '_'))
); // is supposed to match str
if (r && std::distance(begin,end) < 1)
{
std::cout << "Parsing succeeded\n";
}
else
{
std::cout << "Parsing FAILED\n";
std::cout << "r " << r << " d " << std::distance(begin,end) << "\n";
}
return 0;
}
这是错误:
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:254:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘empty’
254 | if (attr.empty())
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘insert’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:34: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:46: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘begin’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:60: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~
我在 Ubuntu 18.04 使用 boost 1.65.1。
我阅读了这篇文章 (
有没有办法在不更改系统包的情况下解决或规避这个问题?
不,这只是一个已修复的错误。
- 1.65.1 https://wandbox.org/permlink/uUeqVJOsnSxk9aD1 损坏
- 1.66.0 https://wandbox.org/permlink/AhQ9G8Ubm9v0DeYj 损坏
- 1.67.0 https://wandbox.org/permlink/nh4wDJdhO8lSfBZo 还行
无论如何,像 x3::alpha | '_'
这样的语法结构不会公开您需要的内容,因为 literal '_'
不公开任何属性。
因此,在实践中您可能只想使用 raw[]
:
auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ]
接下来,您可以匹配多个符合::
的标识符:
x3::raw [ ident >> * ("::" >> ident) ]
顺便说一下,这完全等同于
x3::raw [ ident % "::") ]
见
- 1.65.1 https://wandbox.org/permlink/Jorllem5U7u3L04e 还行
- 1.67.0 https://wandbox.org/permlink/EXMjDTPhcZfu05Ot 也可以
奖金:
分配给属性
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip>
#include <string>
namespace x3 = boost::spirit::x3;
int main() {
std::string str = "foo::_bar::qux_1";
auto begin = str.begin(), end = str.end();
auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ] ];
std::vector<std::string> qualified;
bool r = x3::parse(begin, end, ident % "::", qualified);
if (r && begin==end) {
std::cout << "Parsing succeeded\n";
for (auto& el : qualified) {
std::cout << " element " << std::quoted(el) << "\n";
}
} else {
std::cout << "Parsing FAILED\n";
}
std::cout << std::boolalpha << r << " " << std::quoted(std::string(begin, end)) << "\n";
}
打印:
Parsing succeeded
element "foo"
element "_bar"
element "qux_1"
true ""
并且语法被简化为
std::vector<std::string> qualified;
bool r = x3::parse(begin, end, ident % "::", qualified);
这通常是个好兆头。