spirit默认的语义动作和字符串组成
boost::spirit default semantic action and string composition
我有以下代码:
#include <gtest/gtest.h>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_eps.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/include/phoenix_bind.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_chset.hpp>
#include <boost/spirit/include/classic_utility.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/variant.hpp>
namespace spi = boost::spirit;
namespace qi = boost::spirit::qi;
TEST(TestBoost, cpp_comment)
{
using qi::char_;
using qi::omit;
using qi::eoi;
typedef std::string::const_iterator iter;
const std::string example = "/* this should be ignored */";
auto b = std::begin(example);
auto e = std::end(example);
qi::rule<iter, std::string()> cpp_comment = char_('/') >> char_('/') >> *(char_ - 'n') >> (char_('n') | omit[eoi]);
qi::rule<iter, std::string()> c_comment = char_('/') >> char_('*') >> *(char_ - "*/") >> char_('*') >> char_('/');
qi::rule<iter, std::string()> shell_comment = char_('#') >> *(char_ - 'n') >> (char_('n') | omit[eoi]);
qi::rule<iter, std::string()> comment = cpp_comment
| c_comment
| shell_comment
;
std::string result;
EXPECT_TRUE(qi::parse(b, e, comment, result));
EXPECT_EQ(b, e);
EXPECT_EQ(result, example);
}
失败,出现以下错误:
[----------] 1 test from TestBoost
[ RUN ] TestBoost.cpp_comment
tests/spirit.cpp:56: Failure
Expected: result
Which is: "//* this should be ignored */"
To be equal to: example
Which is: "/* this should be ignored */"
[ FAILED ] TestBoost.cpp_comment (0 ms)
[----------] 1 test from TestBoost (0 ms total)
我不明白为什么。可能在boost文档的某个地方提到了这种行为,但我找不到它。有人知道为什么会这样吗?
如果我把语义动作像这样:
qi::rule<iter, std::string()> comment = cpp_comment[spi::_val = spi::_1]
| c_comment[spi::_val = spi::_1]
| shell_comment[spi::_val = spi::_1]
;
或
qi::rule<iter, std::string()> comment = cpp_comment[spi::_val += spi::_1]
| c_comment[spi::_val += spi::_1]
| shell_comment[spi::_val += spi::_1]
;
它工作,但我真的很想知道为什么原来的代码不能工作。
这是回溯容器属性的经典问题:
- boost::spirit::qi重复解析输出 使用Boost::Spirit (V2.4)解析到容器
这里的想法是使用qi::hold
,或者在这种情况下使用qi::raw
更好,因为它看起来像是要将整个匹配的输入序列作为属性公开:
qi::rule<iter, std::string()>
cpp_comment = "//" >> *~char_('n') >> (eol|eoi),
c_comment = "/*" >> *(char_ - "*/") >> "*/",
shell_comment = '#' >> *~char_('n') >> (eol|eoi),
comment = qi::raw [ cpp_comment | c_comment | shell_comment ];
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <cassert>
namespace qi = boost::spirit::qi;
void test() {
using qi::char_;
using qi::eol;
using qi::eoi;
std::string const example = "/* this should be ignored */";
qi::rule<std::string::const_iterator, std::string()>
cpp_comment = "//" >> *~char_('n') >> (eol|eoi),
c_comment = "/*" >> *(char_ - "*/") >> "*/",
shell_comment = '#' >> *~char_('n') >> (eol|eoi),
comment = qi::raw [ cpp_comment | c_comment | shell_comment ];
std::string result;
bool ok = qi::parse(std::begin(example), std::end(example), comment >> eoi, result);
assert(ok);
std::cout << "expected: " << example << "n";
std::cout << "actual: " << result << "n";
assert(result == example);
}
int main() {
test();
}
打印
expected: /* this should be ignored */
actual: /* this should be ignored */
相关文章:
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- Switch 语句(字符串)一直选择默认值,除非其为零
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 如何比较C 中的两个字符串并使用默认功能
- 如何使用cont char启动字符串_View的默认值
- 当 n 的默认值为字符串长度时,如何反转字符串中的 n 个字符
- 在类实现中为字符串的覆盖默认破坏者
- 在不使用默认算法的情况下对字符串的 std 向量进行排序
- const字符串成员的错误:没有适当的默认构造函数可用
- C++默认构造函数:字符串参数与字符串参数()
- AnsiString作为Embarcadero C++Builder中字符串类型的默认值
- 默认参数声明:为什么默认字符串参数必须是 const
- 使用常量字符串时创建默认构造函数
- cpp-neltib(和 Boost)窗口中的默认字符串类型
- 字符串对的C++向量作为函数参数的默认规范在 gcc-4.1.2 上无效
- 将变量名作为字符串传递给具有默认参数的函数
- 字符串、列表、向量的默认构造函数的C++成本
- 在内联函数中使用字符串流作为默认值
- c++初始化动态内存中c样式字符串的默认值
- spirit默认的语义动作和字符串组成