spirit qi中可选解析器的使用
Use of optional parser in spirit qi
我正在尝试解析 "A+C" 形式的加法表达式,或者单独解析 "A"。经过几次测试,我意识到问题显然是我使用了可选的解析器,所以举例说明:
qi::rule<string::iterator, string()> Test;
Test =
(
qi::string("A")[qi::_val= qi::_1]
>> -(
qi::string("B")[qi::_val += qi::_1]
>> qi::string("C")[qi::_val += qi::_1]
)
)
;
string s1, s2;
s1 = "AB";
bool a= qi::parse(s1.begin(), s1.end(), Test, s2);
思路是解析'A'或者"ABC",但是如果s1的值是"AB",没有'C',那么a的值为true。我相信虽然我在运算符“-”之后加上括号然后使用“>>”运算符,但 'C' 部分被认为是可选的,而不是 B>>C 作为一个整体。有什么想法吗?
容器属性没有回溯。
这是一种性能选择。您需要使用例如显式控制传播qi::hold
:
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
using It = std::string::const_iterator;
qi::rule<It, std::string()> Test;
Test =
(
qi::char_('A')
>> -qi::hold [
qi::char_('B')
>> qi::char_('C')
]
)
;
for (std::string const input : { "A", "AB", "ABC" })
{
std::cout << "-------------------------\nTesting '" << input << "'\n";
It f = input.begin(), l = input.end();
std::string parsed;
bool ok = qi::parse(f, l, Test, parsed);
if (ok)
std::cout << "Parsed success: " << parsed << "\n";
else
std::cout << "Parsed failed\n";
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
打印:
-------------------------
Testing 'A'
Parsed success: A
-------------------------
Testing 'AB'
Parsed success: A
Remaining unparsed: 'B'
-------------------------
Testing 'ABC'
Parsed success: ABC
注意我做了一些简化。
另请参阅:
- Boost Spirit: "Semantic actions are evil"?
- boost::spirit::qi duplicate parsing on the output
- Understanding Boost.spirit's string parser
我正在尝试解析 "A+C" 形式的加法表达式,或者单独解析 "A"。经过几次测试,我意识到问题显然是我使用了可选的解析器,所以举例说明:
qi::rule<string::iterator, string()> Test;
Test =
(
qi::string("A")[qi::_val= qi::_1]
>> -(
qi::string("B")[qi::_val += qi::_1]
>> qi::string("C")[qi::_val += qi::_1]
)
)
;
string s1, s2;
s1 = "AB";
bool a= qi::parse(s1.begin(), s1.end(), Test, s2);
思路是解析'A'或者"ABC",但是如果s1的值是"AB",没有'C',那么a的值为true。我相信虽然我在运算符“-”之后加上括号然后使用“>>”运算符,但 'C' 部分被认为是可选的,而不是 B>>C 作为一个整体。有什么想法吗?
容器属性没有回溯。
这是一种性能选择。您需要使用例如显式控制传播qi::hold
:
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
using It = std::string::const_iterator;
qi::rule<It, std::string()> Test;
Test =
(
qi::char_('A')
>> -qi::hold [
qi::char_('B')
>> qi::char_('C')
]
)
;
for (std::string const input : { "A", "AB", "ABC" })
{
std::cout << "-------------------------\nTesting '" << input << "'\n";
It f = input.begin(), l = input.end();
std::string parsed;
bool ok = qi::parse(f, l, Test, parsed);
if (ok)
std::cout << "Parsed success: " << parsed << "\n";
else
std::cout << "Parsed failed\n";
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
打印:
-------------------------
Testing 'A'
Parsed success: A
-------------------------
Testing 'AB'
Parsed success: A
Remaining unparsed: 'B'
-------------------------
Testing 'ABC'
Parsed success: ABC
注意我做了一些简化。
另请参阅:
- Boost Spirit: "Semantic actions are evil"?
- boost::spirit::qi duplicate parsing on the output
- Understanding Boost.spirit's string parser