当前位置: 首页 > 知识库问答 >
问题:

Boost Qi使用函数编写规则

巴帅
2023-03-14

我正试图为一种语言的多个子集定义一些Boost::spirit::qi解析器,并尽可能减少代码重复。为此,我创建了一些基本的规则构建函数。最初的解析器工作得很好,但是一旦我开始使用组合函数,我的解析器似乎就不再工作了。

一般语言的形式是:

A B: C

语言中有一些子集,其中< code>A 、< code>B或< code>C必须是特定的类型,例如< code>A是int,而< code>B和< code>C是floats。以下是我为该子语言使用的解析器:

using entry = boost::tuple<int, float, float>;

template <typename Iterator>
struct sublang : grammar<Iterator, entry(), ascii::space_type>
{
   sublang() : sublang::base_type(start)
   {
       start = int_ >> float_ >> ':' >> float_;
   }
   rule<Iterator, entry(), ascii::space_type> start;
};

但是由于有许多子集,我试图创建一个函数来构建我的解析器规则:

template<typename AttrName, typename Value>
auto attribute(AttrName attrName, Value value)
{
    return attrName >> ':' >> value;
}

这样我就可以更容易地为每个子集构建解析器,而不需要重复的信息:

// in sublang
start = int_ >> attribute(float_, float_);

然而这失败了,我不知道为什么。在我的clang测试中,解析失败了。在g中,程序似乎崩溃了。

以下是完整的示例代码:http://coliru.stacked-crooked.com/a/8636f19b2e9bff8d

当前代码有什么问题?解决此问题的正确方法是什么?我希望避免在每个子语言解析器中指定属性和其他元素的语法。

共有1个答案

车诚
2023-03-14

非常简单:在Spirit(或任何基于Boost Proto和Boost Phoenix的EDSL)上使用<code>auto</code>很可能是未定义的行为

现在,你通常可以用

  • BOOST_SPIRIT_AUTO
  • boost::proto::deep_copy
  • 最新版本的Boost中提供的新功能(TODO添加链接)

在这种情况下,

template<typename AttrName, typename Value>
auto attribute(AttrName attrName, Value value) {
    return boost::proto::deep_copy(attrName >> ':' >> value);
}

修复它:住在科利鲁

> < li>

您可以将< code>qi::lazy[]与继承的属性一起使用。

在使用C和BOOST读取JSON文件时,我在<code>prop_key

您可以查看Spirit Repository中的关键字列表运算符。它旨在允许更轻松地构建语法,例如:

no_constraint_person_rule %=
    kwd("name")['=' > parse_string ]
  / kwd("age")   ['=' > int_]
  / kwd("size")   ['=' > double_ > 'm']
  ;

这可能与Nabialek技巧相结合。我会在SO上搜索答案以获取示例。(一个是语法平衡问题)

¹ 除了完全无状态的演员(埃里克·尼布勒对此)和表达式占位符。例如,参见

  • 将解析器分配给自动变量
  • 定义的行为在提升::精神::qi::p hrase_parse
  • C 提升气递归规则构建
  • 提升精神V2 qi与优化级别相关的bug

一些例子

  • 在Boost勇气中定义使用子解析器参数化的解析器
  • 从备选解析器表达式的可变参数列表生成勇气解析器表达式
 类似资料:
  • 问题内容: 我有一个函数数组,我试图产生一个由数组中元素组成的函数。我的方法是: 此方法似乎无效,将不胜感激。 (我要反转列表,因为这是我希望函数成为的组合顺序) 问题答案: 它不起作用,因为您在循环中创建的所有匿名函数都引用相同的循环变量,因此共享其最终值。 作为快速解决方案,您可以将分配替换为: 或者,您可以从函数返回lambda: 要了解发生了什么,请尝试以下实验: 这个结果使许多人感到惊讶

  • 我有一个函数数组,我试图生成一个函数,它由数组中的元素组成。我的做法是: 此方法似乎不起作用,请给予帮助。 (我正在反转列表,因为这是我希望函数的组合顺序)

  • 我们正在使用JBoss Drools来外部化我们正在构建的某些服务中一些特别容易更改的业务逻辑。 在我们的开发人员可以创建和维护这些规则的地方,这些规则运行得很好,我们有很好的集成水平和集成工作流。 我们希望将其应用扩展到一种需要非常高级别定制的新服务。本质上,“专家用户”需要能够设置两种不同类型的规则: > “标准”规则-这些几乎是隐含的规则,我们知道这些规则是常见的需求,我们可以构建UI来设置

  • 到现在为止,你只使用了作为stdio.h头文件一部分的函数。在这个练习中你将要编写并使用自己的函数。 #include <stdio.h> #include <ctype.h> // forward declarations int can_print_it(char ch); void print_letters(char arg[]); void print_arguments(int a

  • 本文向大家介绍编写strcpy 函数相关面试题,主要包含被问及编写strcpy 函数时的应答技巧和注意事项,需要的朋友参考一下 已知strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc);其中strDest是目的字符串, strSrc 是源字符串。 (1)不调用C++/C 的字符串库函数,请编写函数 strcpy 。 (2)str

  • 我目前正试图用源SDK用C编写一个LookAt函数。我做了一些研究,发现了很多链接,但其中很多都是关于统一或Glm的,并且使用了四元数和旋转矩阵,但我不需要这些。 所以,我的问题是: 我在门户2。我有一个位置坐标为x,y,z的目标,我有我的球员的位置和他的旋转角度(偏航,俯仰,滚动)。当我使用目标坐标作为参数的函数时,我希望我的播放器看到目标<我发现:点看点,但效果不太好,最后的角度从来都不好。