标签: boost-spirit

使用惰性求值实现三元类型 if

我正在为一个if函数实现一个生产规则:

qi::rule<Iterator, ascii::space_type, double(void)> f_if;
f_if = qi::ascii::string("if")
            >> qi::char_('(')
            >> (comparator >> ',' >> expression >> ',' >> expression) [qi::_val = boost::phoenix::bind(&Grammar<Iterator>::function_if, this, qi::_1, qi::_2, qi::_3)]
            >> qi::char_(')')
            ;
Run Code Online (Sandbox Code Playgroud)

表达式比较器声明为

qi::rule<Iterator, ascii::space_type, double(void)> expression;
qi::rule<Iterator, ascii::space_type, bool(void)> comparator;
Run Code Online (Sandbox Code Playgroud)

并且绑定函数具有原型

 double function_if(bool comparator, double left, double right);
Run Code Online (Sandbox Code Playgroud)

我可以做些什么,以便根据比较器的值仅评估一个表达式吗?

boost-spirit boost-spirit-qi

3
推荐指数
1
解决办法
327
查看次数

解析除关键字之外的标识符

我正在努力编写一个标识符解析器,它解析一个不是关键字的字母字符串。关键字都在一个表中:

struct keywords_t : x3::symbols<x3::unused_type> {
    keywords_t() {
        add("for", x3::unused)
                ("in", x3::unused)
                ("while", x3::unused);
    }
} const keywords;
Run Code Online (Sandbox Code Playgroud)

标识符的解析器应该是这样的:

auto const identifier_def =       
            x3::lexeme[
                (x3::alpha | '_') >> *(x3::alnum | '_')
            ];
Run Code Online (Sandbox Code Playgroud)

现在我尝试将这些组合起来,以便标识符解析器在解析关键字时失败。我是这样试的:

auto const identifier_def =       
                x3::lexeme[
                    (x3::alpha | '_') >> *(x3::alnum | '_')
                ]-keywords;
Run Code Online (Sandbox Code Playgroud)

和这个:

auto const identifier_def =       
                x3::lexeme[
                    (x3::alpha | '_') >> *(x3::alnum | '_') - keywords
                ];
Run Code Online (Sandbox Code Playgroud)

它适用于大多数输入,但如果字符串以关键字开头,例如int, whilefoo, forbar解析器无法解析此字符串。我怎样才能让这个解析器正确?

c++ parsing boost-spirit c++14 boost-spirit-x3

3
推荐指数
1
解决办法
668
查看次数

进入振奋精神;齐还是X3?

我正在和一个朋友为一个小型个人项目做翻译;我们开始实现所有的类和一般结构,在这些结构中代码将被翻译,然后执行只是为了将实际的解析代码推迟到这些结构中。

现在我们必须构建解析器,经过一番搜索,我发现到处都是关于灵气和灵气 X3 的帖子和人,好像它们是(我认为它们是)两种不同的方式来制作解析器,但没有一个说不同,哪个更近,我应该从哪个开始。

目的是,给定一个代码字符串,输出最终错误,如果一切都遵守语法和逻辑,则将代码转换为我们已经构建的类的树。我们想在解析过程中检查一致性,例如“您正在使用未声明的变量”类型的错误。

我不确定这两个库如何以不同的方式对待事物。

boost-spirit boost-spirit-qi boost-spirit-x3

3
推荐指数
1
解决办法
979
查看次数

关于提升精神的建议

我想知道Boost精神图书馆有多好.

我已经开始阅读文档,但它似乎是一个非常庞大的框架,并要求有很多时间来掌握.我真的不想浪费我的时间在一个尽可能不那么精彩的框架上.

我想从非常了解它的用户那里得到关于这个框架的一些意见.

c++ boost-spirit

2
推荐指数
1
解决办法
353
查看次数

使用Spirit.Qi消除语法糖

我正在尝试解析一个类似于lisp的语言,它具有一些常用函数的语法糖.例如,加号函数可以写成(+ 1 2)或1 + 2.我认为在尝试解释语言之前消除语法糖将大大方便解释过程,因为那时,唯一的评估规则是需要实现的将是函数调用,并且所有中缀运算符都必须具有相应的内置函数.我以为我可以创建一个解析器来迭代从词法分析器收到的标记,并重新排序它们以将表达式放入前缀表示法.但是这需要解析器的输出也是令牌列表.这在Spirit.Qi有可能吗?据我所知,Spirit.Qi构建了一个层次结构,而不是一个线性的令牌列表.

boost-spirit boost-spirit-qi boost-spirit-lex

2
推荐指数
1
解决办法
112
查看次数

用lookahead解决模糊的boost :: spirit :: qi语法

我想要一个名称 - 值对列表.每个列表都以'.'结尾.和EOL.每个名称 - 值对用':'分隔.每对由';'分隔 在列表中.例如

NAME1: VALUE1; NAME2: VALUE2; NAME3: VALUE3.<EOL>
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是值包含'.' 并且最后一个值总是消耗'.' 在EOL.我可以使用某种前瞻来确保最后一个'.' 在EOL被区别对待之前?

c++ boost boost-spirit boost-spirit-qi

2
推荐指数
1
解决办法
614
查看次数

提升精神在服务器应用程序上实现小型单行DSL

如果之前已经回答过这个问题,请道歉.

我想在我工作的服务器应用程序中插入一个小型DSL.语法很简单,即使在这个早期阶段,我也很难过.我无法理解如何在精神上构建语法.

以下是我要测试的语法示例:

WHERE [not] <condition> [ and | or <condition> ] <command> [parameters]
Run Code Online (Sandbox Code Playgroud)

WHERE子句将通过测试内部存储上的命名属性来从内部存储中选择多个对象.然后将所选对象的矢量作为输入传递给命令对象.

我想对每个对象执行两种可能的测试:

<property> = "value"
Run Code Online (Sandbox Code Playgroud)

<property> like <regexp>
Run Code Online (Sandbox Code Playgroud)

还有2个命令:

print <propertyName> [, <propertyName> [...]]
Run Code Online (Sandbox Code Playgroud)

set <propertyName> = "value" [, <propertyName> = "value" [...] ]
Run Code Online (Sandbox Code Playgroud)

所以语法的例子是:

where currency like "GBP|USD" set logging = 1, logfile = "myfile"
Run Code Online (Sandbox Code Playgroud)

where not status = "ok" print ident, errorMessage
Run Code Online (Sandbox Code Playgroud)

我知道这是一个很大的问题,但我想知道是否有任何精神专家可以在几秒钟内完成这个语法?我解析LIKE和=,但在尝试将它与AND,OR和NOT混合时卡住了.对我来说,问题是在思考精神如何解决这个问题时不知道从哪里开始.

c++ dsl boost boost-spirit boost-spirit-qi

2
推荐指数
1
解决办法
968
查看次数

Boost.spirit:解析数字char和string

我需要解析一行包含unsigned int,X要丢弃的字符和一个字符串,所有这些都用一个或多个空格分隔.例如,1234 X abcd

bool a = qi::phrase_parse(first, last,
      uint_[ref(num) = _1] >> lit('X') >> lexeme[+(char_ - ' ')],
      space, parsed_str);
Run Code Online (Sandbox Code Playgroud)

上面的代码解析了这三个部分,但字符串最终包含一个垃圾字符(?abcd),大小为5而不是4.

我的解析器出了什么问题?为什么字符串中有垃圾?

c++ boost-spirit boost-phoenix boost-spirit-qi

2
推荐指数
1
解决办法
1922
查看次数

提升:精神:业力:如何获得当前的产出位置?

我想生成一些格式化的输出.为此,需要一些缩进.因此,在生成期间的某个时刻,我希望获得当前位置,以便使用该数量缩进以下行.

这是一个最小的例子.请假设,我们不知道karma::lit("Some text: ")编译期间的输出有多长.实际上,这个前导文本可能由几个规则生成.

#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <boost/spirit/include/karma.hpp>
using namespace std;

int main() {
  vector<int> v { 0, 1, 2, 3 };
  {
    namespace karma = boost::spirit::karma;
    karma::rule<ostream_iterator<char>, std::vector<int>() > myRule =
        karma::lit("Some text: ") << (karma::int_ % karma::eol);
    karma::generate(ostream_iterator<char>(cout), myRule, v);
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这产生了

Some text: 0
1
2
3
Run Code Online (Sandbox Code Playgroud)

我想结果:

Some text: 0
           1
           2
           3
Run Code Online (Sandbox Code Playgroud)

要实现这一点,需要在生成向量之前知道当前位置.那么,类似的东西qi::raw[]呢?

更新:指向此点生成输出的指针也可以.

c++ boost boost-spirit boost-spirit-karma

2
推荐指数
1
解决办法
650
查看次数

使用boost精神x3解析为具有布尔或枚举成员的结构

如果我有一个结构:

struct person{
    bool is_male;
    std::string name;
    std::vector<std::string> friends;
}
Run Code Online (Sandbox Code Playgroud)

要么

enum class gender_t{male, female}
struct person{
        gender_t gender;
        std::string name;
        std::vector<std::string> friends;
}
Run Code Online (Sandbox Code Playgroud)

如何使用boost.spirit X3解析此结构?规则如何解析“ alice male bob”之类的字符串,解析器将返回一个名称为alice的对象,该对象是male,并且有一个朋友bob。如果这个人不是女性,那么如果性别只是露骨的话,会是什么样?

c++ parsing boost-spirit c++14 boost-spirit-x3

2
推荐指数
1
解决办法
384
查看次数