提振精神istream的迭代器给误报 [英] boost spirit istream iterator giving false positives

查看:119
本文介绍了提振精神istream的迭代器给误报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图让精神,从这个文件解析的人物,因为它的输入。我宁愿不读完整的字符串到内存中,如果在所有可能的。

So I'm trying to get spirit to parse the characters from this file as it's input. I'd rather not read the full string into memory if at all possible.

这是我目前的相关code时,Rosters_Grammar是我使用指定我需要的语法语法文件。

This is my current relevant code, the Rosters_Grammar is a grammar file that I am using to specify my desired grammar.

#include "StdAfx.h"
#include "Interpreter.h"
#include "Rosters_Grammar.h"
#include <boost\spirit\include\qi.hpp>
#include <fstream>

bool Interpreter::invoke(std::string path)
{
  //Define our parser type and iterator types.
  typedef boost::spirit::istream_iterator iter_type;
  typedef Rosters_Grammar<iter_type> parser_type;

  //Create an instance of our grammar parser and pass it an appropriate project.
  parser_type grammar_parser(project);

  //Open the target file and wrap ifstream into the iterator.
  std::ifstream in = std::ifstream(path);
  if(in.is_open()){

    //Disable Whitespace Skipping
    in.unsetf(std::ios::skipws);

    iter_type begin(in);
    iter_type end;

    //Phrase parse the grammar
    return boost::spirit::qi::phrase_parse(begin,
                                             end, 
                                       qi::int_ , 
                                       boost::spirit::qi::space);
  }
  else{
    return false;
  }
}

这是出现的问题是我的解析总是成功的某些原因。鉴于名册的语法,我可以告诉它的读取输入的一部分,因为它是执行相应的动作,并如预期的正确的输入准确有效。然而,解析器不坏输入失败,它只是通过文件部分停止的方式时,返回真。

The issue that comes up is my parse ALWAYS succeeds for some reason. Given the roster grammar I can tell it's reading part of the input because it is performing actions accordingly, and works exactly as expected for proper input. However the parser doesn't fail on bad input, it just stops part the way through the file and returns a true.

我目前的文件内容是整数和字符串的重复,这样

My current file contents are a repetition of ints and strings, such that

45布里
  23 butter_scotch

45 Brie 23 butter_scotch

应该读罚款和接受。弦乐像

Should be read fine and accepted. Strings like

45苹果苹果苹果

不应该。但是鉴于这种刺痛,解析器应该失败。相反,它为执行45苹果的行动,然后返回一个真正的解析。我认为它的东西与我的迭代器,但我不能肯定。
在上面贴code,我有气:: int_作为我的解析器,也不管我的输入数据,它总是成功。因此,我不相信我的语法文件不应该是相关的问题在这里。
我已经得到的数据,到目前为止失败的唯一方法是使用!补气:: EPS为我的解析器输入。

should not be. However given this sting, the parser should fail. Instead it performs actions for "45 Apple" and then returns a true for the parse. I think it's something with my iterators but I can't be sure. In the above posted code, I have qi::int_ as my parser, and it always succeeds regardless of my input data. So I don't believe my grammar file should not be relevant to the problem here. The only way I've gotten the data to fail so far is with !qi::eps as my parser input.

感谢您的帮助任何人都可以给我!

Thanks for any help anyone could give me!

编辑:
寻找到它多一点之后,我真的认为我的船长是出于某种原因的问题。
我的理解是,phrase_parse传递2迭代器,某种形式的语法和跳跃分析器。它tokenizes基于跳跃分析器的输入端,并在语法使用这些标记。

After looking into it a bit more, I actually think my skipper is the problem for some reason. The way I understand it, phrase_parse is passed 2 iterators, a grammar of some kind, and a skip parser. It tokenizes the input based on the skip parser, and uses those tokens in the grammar.

没有禁用空白跳跃的迭代器类型,我的结果分析出45 appleappleapple,并用它,它只有成功45苹果。

Without disabling whitespace skipping for the iterator type, my result parses out "45 appleappleapple", and with it it succeeds with only "45 apple."

推荐答案

我们无法看到的语法,因为你没有张贴。

We can't see the grammar because you didn't post it.

我可以看到你DONOT检查wheter输入已被完全消耗:

I can see that you donot check wheter the input has been completely consumed:

    return boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser ,
           qi::space);

您可以通过修复,要么要求齐:: EOI

You can fix that by either requiring qi::eoi:

    return boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser >> qi::eoi,
           qi::space);

或者你可以检查的迭代器:

Or you can check the iterators:

    bool ok = boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser ,
           qi::space);

    if (begin != end)
        std::cerr << "Remaining unparsed: '" << std::string(begin, end) << "'\n";

    return ok && (begin == end);

最后,注意的语义动作的永远不会在回溯的情况下,撤销的副作用。参见:

Finally, note that side-effects of semantic actions can never be undone in the case of backtracking. See also:

  • Boost Spirit: "Semantic actions are evil"?

这篇关于提振精神istream的迭代器给误报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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