boost spirit distinct关键字未按预期工作

boost spirit distinct关键字未按预期工作,boost,boost-spirit,Boost,Boost Spirit,这是我的小样品。。我有一种语言,在解析时,我有类似的东西 foo() nextfoo() <-- here an error appears because of the keyword "next" 但是这不起作用。。sombody能解释为什么吗 特别问题。。只要我使用上面的语法,我就会得到一个模板编译器错误,工作示例必须按以下方式编写(关键字列表是内联的,而不是规则)。我假设这与规则的类型规范有关。。但是什么才是正确的呢 name_valid = distinct(no

这是我的小样品。。我有一种语言,在解析时,我有类似的东西

 foo()
 nextfoo()  <-- here an error appears because of the keyword "next" 
但是这不起作用。。sombody能解释为什么吗

特别问题。。只要我使用上面的语法,我就会得到一个模板编译器错误,工作示例必须按以下方式编写(关键字列表是内联的,而不是规则)。我假设这与规则的类型规范有关。。但是什么才是正确的呢

 name_valid =   distinct(nocaselit(L"next")| nocaselit(L"else") | ... )
 [ lexeme[+(boost::spirit::standard_wide::alpha | '_') >> *(boost

谢谢

distinct指令在
[]
块中使用主题解析器,而不是
()
。在
()
中,指定边界处不允许的排除(通常是由标识符字符组成的字符集)

也考虑使用<代码> Q::符号与<代码> Q::NoIICASE >但内部使用TIE,这就不需要任何回溯。

当我接近计算机时,我将提供一个工作示例。同时,请随意查看此处的现有示例:

演示

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;
namespace enc = boost::spirit::standard_wide;

template <typename It>
struct Grammar : qi::grammar<It> {

    Grammar() : Grammar::base_type(start) {
        using namespace qi;
        auto kw = qr::distinct(copy(enc::alnum | L'_'));

        start         = skip(enc::space) [function_call];
        function_call = identifier >> L'(' >> L')';
        identifier    = !keyword >> raw[(enc::alpha|L'_') >> *(enc::alnum|L'_')];

        keyword       = kw[ no_case[keywords] ];
        BOOST_SPIRIT_DEBUG_NODES((start)(function_call)(identifier)(keyword));
    }
  private:
    qi::rule<It> start;
    qi::rule<It, enc::space_type> function_call;

    // implicit lexemes
    struct keywords_t : qi::symbols<wchar_t> {
        keywords_t() { 
            this->add
                (L"as")(L"class")(L"dim")(L"else")(L"end")(L"false")
                (L"for")(L"function")(L"if")(L"new")(L"next")(L"sub")
                (L"then")(L"to")(L"true");
        }
    } keywords;
    qi::rule<It, std::string()> identifier, keyword;
};

int main() {
    using It = std::wstring::const_iterator;
    Grammar<It> const g;

    for (std::wstring input : {
            L"foo()",
            L"nextfoo()",
        })
    {
        It f=input.begin(), l=input.end();
        if (parse(f, l, g)) {
            std::wcout << L"Parse success\n";
        } else {
            std::wcout << L"Parse failed\n";
        }

        if (f!=l) {
            std::wcout << L"Remaining unparsed input: '" << std::wstring(f,l) << L"\n";
        }
    }
}

正如所料

您是如何定义nocaselit的?这不是我以前见过的东西。将nocaselit放在文本中..添加了一个工作示例您的示例工作。。无论如何,我不明白为什么我的第一个版本也有“!Keywords”不能完成与第一个版本使用
相同的工作!关键字
不使用不同的,而是使用(请参见
kw()
)。要理解它,请始终接受第一个匹配(以及最长的匹配,如果适用)
intfoo
不匹配
int
(离开
foo
)。
 name_valid =   distinct(nocaselit(L"next")| nocaselit(L"else") | ... )
 [ lexeme[+(boost::spirit::standard_wide::alpha | '_') >> *(boost
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;
namespace enc = boost::spirit::standard_wide;

template <typename It>
struct Grammar : qi::grammar<It> {

    Grammar() : Grammar::base_type(start) {
        using namespace qi;
        auto kw = qr::distinct(copy(enc::alnum | L'_'));

        start         = skip(enc::space) [function_call];
        function_call = identifier >> L'(' >> L')';
        identifier    = !keyword >> raw[(enc::alpha|L'_') >> *(enc::alnum|L'_')];

        keyword       = kw[ no_case[keywords] ];
        BOOST_SPIRIT_DEBUG_NODES((start)(function_call)(identifier)(keyword));
    }
  private:
    qi::rule<It> start;
    qi::rule<It, enc::space_type> function_call;

    // implicit lexemes
    struct keywords_t : qi::symbols<wchar_t> {
        keywords_t() { 
            this->add
                (L"as")(L"class")(L"dim")(L"else")(L"end")(L"false")
                (L"for")(L"function")(L"if")(L"new")(L"next")(L"sub")
                (L"then")(L"to")(L"true");
        }
    } keywords;
    qi::rule<It, std::string()> identifier, keyword;
};

int main() {
    using It = std::wstring::const_iterator;
    Grammar<It> const g;

    for (std::wstring input : {
            L"foo()",
            L"nextfoo()",
        })
    {
        It f=input.begin(), l=input.end();
        if (parse(f, l, g)) {
            std::wcout << L"Parse success\n";
        } else {
            std::wcout << L"Parse failed\n";
        }

        if (f!=l) {
            std::wcout << L"Remaining unparsed input: '" << std::wstring(f,l) << L"\n";
        }
    }
}
Parse success
Parse success