可能因“初始化后"失败的eps解析器.可能会失败 [英] eps parser that can fail for a "post-initialization" that could fail

查看:147
本文介绍了可能因“初始化后"失败的eps解析器.可能会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 Boost X3快速入门教程,并注意到线

I'm reading the Boost X3 Quick Start tutorial and noticed the line

eps是一种特殊的精神分析器,它不消耗任何输入,但始终会成功.我们使用它来初始化规则的综合属性,然后将其初始化为零. [...]以这种方式使用eps非常适合进行初始化之前和之后的初始化.

eps is a special spirit parser that consumes no input but is always successful. We use it to initialize the rule's synthesized attribute, to zero before anything else. [...] Using eps this way is good for doing pre and post initializations.

现在,我不禁想知道eps_that_might_fail在解析后的输入的一部分上进行某种语义/后分析是否有用,这可能会失败,使内部具有某种检查的局部性语法.

Now I can't help but wonder if an eps_that_might_fail would be useful to do some sort of semantic/post analysis on a part of the parsed input, which could fail, to have some sort of locality of the check inside the grammar.

是否存在可能失败的eps,使用此结构进行额外的输入验证是否是个好主意?

Is there a might-fail eps, and is it a good idea to do extra input verification using this construct?

一个我想传达的可怕例子:

A terrible example of what I'm trying to convey:

int_ >> eps_might_fail[is_prime]

如果我没记错的话,这只会解析质数,并允许完整的解析器在期望质数的位置失败.

This will only parse prime numbers, if I'm not mistaken, and allow for the full parser to fail at the point where it expects a prime number.

推荐答案

语义操作是为此目的而设计的.

Semantic actions are intended for this.

最自然的例子是

 qi::int_ [ qi::_pass = is_prime(qi::_1) ]

请务必在存在语义动作的情况下使用%=规则分配,因为如果没有规则分配,语义动作将禁用自动属性传播.

Be sure to use %= rule assignment in the presence of semantic actions, because without it, semantic actions disable automatic attribute propagation.

显然,您也可以更加冗长,写

You could, obviously, also be more verbose, and write

 qi::int_ >> qi::eps(is_prime(qi::_val))

如您所见,引用的文档略微不完整:eps已经可以接受一个参数,在这种情况下,懒惰的参与者is_prime(qi::_val)可以确定是否成功执行失败.

As you can see, that quoted documentation is slightly incomplete: eps can already take a parameter, in this case the lazy actor is_prime(qi::_val), that determines whether it succeeds of fails.

在Spirit X3中,除了X3不与Phoenix集成之外,都应用相同的机制.这意味着两件事:

In Spirit X3 the same mechanism applies, except that X3 doesn't integrate with Phoenix. This means two things:

  • 从正面来看,我们可以仅使用核心语言功能(lambda)进行语义操作,从而使学习曲线不太陡峭
  • 不利的一面是,x3::eps的1个参数版本没有一个懒惰的演员
  • on the up-side, we can just use core language features (lambdas) for semantic actions, making the learning curve less steep
  • on the downside, there's no 1-argument version of x3::eps that takes a lazy actor

这是X3的演示程序:

在Coliru上直播

#include <boost/spirit/home/x3.hpp>

namespace parser {
    using namespace boost::spirit::x3;

    auto is_ltua = [](auto& ctx) {
        _pass(ctx) = 0 == (_attr(ctx) % 42); 
    };

    auto start = int_ [ is_ltua ];

}

#include <iostream>

int main() {
    for (std::string const txt : { "43", "42", "84", "85" }) {
        int data;
        if (parse(txt.begin(), txt.end(), parser::start, data))
            std::cout << "Parsed " << data << "\n";
        else
            std::cout << "Parse failed (" << txt << ")\n";
    }
}

打印

Parse failed (43)
Parsed 42
Parsed 84
Parse failed (85)

这篇关于可能因“初始化后"失败的eps解析器.可能会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆