2013-12-11 36 views
2

所以我试图让精神来解析这个文件中的字符,因为它是输入。如果可能的话,我宁愿不把完整的字符串读入内存。助推精神istream迭代器给出误报

这是我目前的相关代码,Rosters_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; 
    } 
} 

出现的问题是我的解析总是成功的原因。鉴于名册语法,我可以告诉它正在读取输入的一部分,因为它正在执行相应的操作,并且正确地按照预期正确输入。然而,解析器在错误输入时不会失败,它只是通过文件停止部分并返回true。

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

45布里 23 butter_scotch

应该读罚款和接受。像

琴弦 “45苹果苹果苹果”

不应该。然而,考虑到这种情况,解析器应该会失败。相反,它执行“45 Apple”的操作,然后为解析返回true。我认为这是我的迭代器的东西,但我不能确定。 在上面的发布代码中,我有qi :: int_作为我的分析器,并且无论我的输入数据如何,它都会成功。所以我不相信我的语法文件不应该与这里的问题相关。 我得到数据失败的唯一方法是使用!qi :: eps作为我的分析器输入。

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

编辑: 经过深入研究,我确实认为我的船长出于某种原因是个问题。 我的理解是,phrase_parse传递了2个迭代器,某种语法和一个跳过解析器。它基于跳过解析器标记输入,并在语法中使用这些标记。

在不禁用迭代器类型的空白跳过的情况下,我的结果解析出“45 appleappleapple”,并且只有“45苹果”才能成功。

回答

2

我们无法看到语法,因为您没有发布它。

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

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

您可以修复,通过任一要求qi::eoi

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

或者你可以检查迭代器:

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); 

Finall y,注意在回溯的情况下,的语义动作的副作用永远不能撤销。另请参见:

+0

哇。我在这里根本不对。我曾认为只有在整个输入被消耗的情况下,解析才被认为是成功的。这整个时间我都在想。感谢现实检查。这应该有很大帮助! – Rabidsheep