lexeme['\'' >> +(char_ - '\'') >> '\''];
+p
意味着
p
必须
match
one-or-more
times
. 如果必须接受空字符串,请使用
Kleene-star operator, which allows
zero-or-more
matches
lexeme['\'' >> *(char_ - '\'') >> '\''];
现场演示
此外,不正确,其中
"$(_FIND('')"
或
"_FIND('')"
将解析为“正确”
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
using Params = std::pair<std::string, std::string>;
namespace qi = boost::spirit::qi;
template <typename It>
struct find_parser : qi::grammar<It, Params()> {
find_parser() : find_parser::base_type(start)
{
using namespace qi;
start = skip(space) [ "$(" >> find >> ")" | find ];
find
= '_' >> lit("FIND") >> lit('(')
>> quoted_string >> -(',' >> quoted_string) // 2nd parameter optional
>> ')' >> '_'
;
quoted_string = "'" >> *~char_("'") >> "'";
BOOST_SPIRIT_DEBUG_NODES((start)(find)(quoted_string))
}
private:
qi::rule<It, Params()> start;
// rules with skipper
qi::rule<It, Params(), qi::space_type> find;
// implicit lexemes
qi::rule<It, std::string()> quoted_string;
};
int main() {
using It = std::string::const_iterator;
find_parser<It> const p;
for (std::string const input : {
"_FIND('Something', 'Something else')_",
"_ FIND('Something', 'Something else') _",
"$(_FIND('Something', 'Something else')_)",
"$( _FIND( 'Something', 'Something else' )_ )",
// second arg empty
"_FIND('Something', '')_",
"_ FIND('Something', '') _",
"$(_FIND('Something', '')_)",
"$( _FIND( 'Something', '' )_ )",
// optional args omitted
"_FIND('Something')_",
"_ FIND('Something') _",
"$(_FIND('Something')_)",
"$( _FIND( 'Something' )_ )",
})
{
std::cout << "-------- " << input << " ------------\n";
It f = input.begin(), l = input.end();
Params parsed;
if (parse(f, l, p, parsed))
std::cout << "Parsed: '" << parsed.first << "', '" << parsed.second << "'\n";
else
std::cout << "Parsing failed\n";
if (f!=l)
std::cout << " -- Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}