gpt4 book ai didi

c++ - 防止 Boost Spirit Symbol 解析器过早接受关键字

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:20 25 4
gpt4 key购买 nike

当以有效关键字(符号)开头时,如何防止 Boost Spirit 符号解析器接受关键字(符号)。我希望该构造无法将“ONEMORE”作为一个整体进行解析,并且无法成功解析“ONE”,因为这是一个有效的关键字,然后在“MORE”上失败。

下面是代码的实际输出:

Keyword as a number: 1
Keyword as a number: 2
Keyword as a number: 1
Invalid keyword: MORETHREE

这就是我喜欢的样子:

Keyword as a number: 1
Keyword as a number: 2
Invalid keyword: ONEMORE
Keyword as a number: 3

该代码只是一个示例,用于说明要点。

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

void printNumber( unsigned u )
{
cout << "Keyword as a number: " << u << endl;
}

void printInvalidKeyword( const string &s )
{
cout << "Invalid keyword: " << s << endl;
}

template <typename Iterator>
struct keyword_parser : qi::grammar<Iterator, ascii::space_type>
{
struct mySymbols_ : qi::symbols<char, unsigned>
{
mySymbols_()
{
add
("ONE" , 1)
("TWO" , 2)
("THREE" , 2)
;
}

} mySymbols;

keyword_parser() : keyword_parser::base_type(start)
{
using qi::_1;
using qi::raw;
using ascii::char_;

start %= *(
mySymbols[&printNumber]
|
invalid[&printInvalidKeyword]
);

invalid = +char_;

}

qi::rule<Iterator, ascii::space_type> start;
qi::rule<Iterator, std::string(), ascii::space_type> invalid;
};

int main()
{
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef keyword_parser<iterator_type> keyword_parser;

std::string s = "ONE TWO ONEMORE THREE";
iterator_type b = s.begin();
iterator_type e = s.end();
phrase_parse(b, e, keyword_parser(), space);

return 0;
}

最佳答案

qi::repository::distinct或者自己采取一些措施:

start %= *(
keyword [cout << val("Keyword as a number: ") << _1 << endl]
| invalid [cout << val("Invalid keyword: ") << _1 << endl]
);

keyword = mySymbols >> !(char_("a-zA-Z0-9_"));

invalid = +ascii::graph;

规则声明为

qi::rule<Iterator, ascii::space_type> start;

// lexemes do not ignore embedded skippables
qi::rule<Iterator, int()> keyword;
qi::rule<Iterator, std::string()> invalid;

查看 Live On Coliru

打印:

Keyword as a number: 1
Keyword as a number: 2
Invalid keyword: ONEMORE
Keyword as a number: 2

完整来源:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct keyword_parser : qi::grammar<Iterator, ascii::space_type>
{
struct mySymbols_ : qi::symbols<char, unsigned>
{
mySymbols_()
{
add
("ONE" , 1)
("TWO" , 2)
("THREE" , 2)
;
}

} mySymbols;

keyword_parser() : keyword_parser::base_type(start)
{
using qi::_1;
using ascii::char_;
using phx::val;

start %= *(
keyword [cout << val("Keyword as a number: ") << _1 << endl]
| invalid [cout << val("Invalid keyword: ") << _1 << endl]
);

keyword = mySymbols >> !(char_("a-zA-Z0-9_"));

invalid = +ascii::graph;

}

qi::rule<Iterator, ascii::space_type> start;
// lexemes do not ignore embedded skippables
qi::rule<Iterator, int()> keyword;
qi::rule<Iterator, std::string()/*IMPLICIT LEXEME:, ascii::space_type*/> invalid;
};

int main()
{
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef keyword_parser<iterator_type> keyword_parser;

std::string s = "ONE TWO ONEMORE THREE";
iterator_type b = s.begin();
iterator_type e = s.end();
phrase_parse(b, e, keyword_parser(), space);

return 0;
}

关于c++ - 防止 Boost Spirit Symbol 解析器过早接受关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21960167/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com