3

単純な引用符で囲まれた文字列を解析しようとしたときに、奇妙なことに遭遇しました。"string"そこで、 orのような引用符で囲まれた文字列を正常に解析するこの単純なパーサーを作成しました""

#include <iostream>
#include "boost/spirit/include/qi.hpp"

namespace qi      = boost::spirit::qi;
namespace iso8859 = boost::spirit::iso8859_1;


int main( int argc, char* argv[] )
{
    using namespace qi;

    std::string input = "\"\"";

    std::string::const_iterator front = input.cbegin();
    std::string::const_iterator end   = input.cend();
    bool parseSuccess = phrase_parse( front, end,
                                      '\"' >> *~char_('\"') >> '\"',
                                      iso8859::space );

    if ( front != end )
    {
        std::string trail( front, end );
        std::cout << "String parsing trail: " << trail << std::endl;
    }

    if ( !parseSuccess )
        std::cout << "Error parsing input string" << std::endl;

    std::cout << "Press enter to exit" << std::endl;
    std::cin.get();
    return 0;
}

これはすべて完全に正常に機能しますが、引用符で囲まれた文字列の前のものも解析するように解析ルールを拡張すると、突然壊れます..

したがって、たとえば、これは正常に解析されます。

std::string input = "normalString 10.0 1.5 1.0 1.0 1.0 1.0" 解析ルールあり:

*char_ >> *double_

そして、このルールを引用符で囲まれた文字列ルールと組み合わせると、次のようになります。

std::string input = "normalString 10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\""

解析ルールあり:

*char_ >> *double_ >> '\"' >> *~char_('\"') >> '\"'

突然機能しなくなり、解析が失敗します。理由がわかりません。誰でもこれを説明できますか?

編集:念のため、Boost 1.53を使用しています

4

1 に答える 1

2

cv_and_heが以前に述べたように - あなた*char_はすべてを食べ、「更新された」パーサーシーケンスから、なぜそれが機能しなかったのか推測できます :-)

#include <iostream>
#include "boost/spirit/include/qi.hpp"

namespace qi      = boost::spirit::qi;
namespace iso8859 = boost::spirit::iso8859_1;

int main( int argc, char* argv[] )
{
    using namespace qi;

    std::vector< std::string > inputVec{
        "normalString 10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\"",
        "normalString \"quotedString\"",
        "10.0 1.5 1.0 1.0 1.0 1.0 \"quotedString\"",
        "10.0 1.5 1.0 1.0 1.0 1.0 \"\"",
        "\"\""};

    for( const auto &input : inputVec )
    {
        std::string::const_iterator front = input.cbegin();
        std::string::const_iterator end   = input.cend();
        bool parseSuccess = phrase_parse( front, end,
            no_skip [ *(char_ - space - double_ - '\"') ] 
            >> *double_ >> '\"' >> *~char_('\"') >> '\"',
          iso8859::space );    
        if ( parseSuccess && front == end)
            std::cout << "success:";
        else
            std::cout << "failure:";
         std::cout << "`" << input << "`" << std::endl;
    }
    return 0;
}
于 2013-08-16T19:44:51.837 に答える