逻辑非运算符在提升::精神::QI 中不起作用
the logical not operator not working in boost::spirit::qi
如果在 qi::grammar 中,我使用此基本规则
expression = (boost::spirit::ascii::string("aaa"));
它将解析"AAA",仅此而已
当我使用这个(注意!)时,它根本不解析任何内容,而我希望它在除"aaa"之外的所有内容上都成功
expression = !(boost::spirit::ascii::string("aaa"));
我会错过一些包含吗?我正在使用提升 1.54.0。
编辑:
抱歉,这有点草稿,我为我的第一次试验修改了计算器示例......
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream>
#include <string>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_not_predicate.hpp>
/*
*
__grammar_calculator.cpp
HEADERS +=
__grammar_calculator.h
*/
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
///////////////////////////////////////////////////////////////////////////
// Our calculator grammar
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct calculator : qi::grammar<Iterator, int(), ascii::space_type>
{
calculator() : calculator::base_type(expression)
{
using qi::_val;
using qi::_1;
using qi::uint_;
using boost::spirit::qi::lit;
using boost::spirit::ascii::string;
expression = !(boost::spirit::ascii::string("aaa"));
}
qi::rule<Iterator, int(), ascii::space_type> expression, term, factor;
};
}
///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////nn";
std::cout << "Expression parser...nn";
std::cout << "/////////////////////////////////////////////////////////nn";
std::cout << "Type an expression...or [q or Q] to quitnn";
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef client::calculator<iterator_type> calculator;
calculator calc; // Our grammar
std::string str;
int result;
while (std::getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, calc, space, result);
if (r && iter == end)
{
std::cout << "-------------------------n";
std::cout << "Parsing succeededn";
//std::cout << "result = " << result << std::endl;
std::cout << "-------------------------n";
}
else
{
std::string rest(iter, end);
std::cout << "-------------------------n";
std::cout << "Parsing failedn";
//std::cout << "stopped at: ": " << rest << ""n";
std::cout << "-------------------------n";
}
}
std::cout << "Bye... :-) nn";
return 0;
}
编辑2:
同样的一个更干净一点:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <boost/spirit/include/qi_not_predicate.hpp>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct test : qi::grammar<Iterator>
{
test() : test::base_type(expression)
{
using boost::spirit::ascii::string;
expression = (boost::spirit::ascii::string("aaa"));
}
qi::rule<Iterator> expression;
};
}
int main()
{
std::cout << "/////////////////////////////////////////////////////////nn";
std::cout << "Expression parser...nn";
std::cout << "/////////////////////////////////////////////////////////nn";
std::cout << "Type an expression...or [q or Q] to quitnn";
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef client::test<iterator_type> test;
test tester; // Our grammar
std::string str;
while (std::getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, tester, space);
if (r && iter == end)
{
std::cout << "-------------------------n";
std::cout << "Parsing succeededn";
std::cout << "-------------------------n";
}
else
{
std::string rest(iter, end);
std::cout << "-------------------------n";
std::cout << "Parsing failedn";
std::cout << "-------------------------n";
}
}
std::cout << "Bye... :-) nn";
return 0;
}
答:
问题来自测试:
if (r && iter == end)
正如所指出的,运算符没有消耗任何东西,所以 iter!=end
在下文中,Sehe提供了一些替代方案。
对于它的价值:
- 正如其他人指出的那样,
operator&
和operator!
是零宽度的前瞻断言(它们不匹配而是"窥视",匹配成功或失败)。
你会想知道
-
否定字符集:
qi::char_("a-z") // matches lowercase letters
~qi::char_("a-z")//匹配除小写字母以外的任何内容
-
"解析器减法" - 考虑异常:
qi::char_ - qi::char_("a-z") // equivalent to ~qi::char_("a-z") qi::char_("a-z") - "keyword" // any lowercase letters, but not if it spells "keyword"
编辑以便向前扫描到下一个"%{",您可以执行以下操作
qi::omit [ qi::char_ - "{%" ] >> "{%"
请注意,您并不总是需要将文本"包装"在qi::lit
中,除非表达式尚未涉及 Qi 域中的原始表达式。
编辑 2 如何使用!
和&
的示例:
&qi::int_ >> +qi::char_ // parse a string, **iff** it starts with an integer
或
!keyword_list >> identifier // parse any identifier that's not a known keyword
相关文章:
- 提升精神:解析布尔表达式并简化为规范范式
- 如何克服提升精神AST混乱
- 增强精神解析器规则以检测语句中的特殊结尾
- 提升精神 V2 Qi 语法线程安全吗?
- 提升精神 QI:在元组上自动规则演绎,在替代函数中带有序列
- 提升::精神::qi::语法和可变参数模板
- 增强精神Qi-列表解析具有两个组件序列
- 为什么这个提升::精神::qi规则与输入不匹配
- TBB 并行化解析与引导::精神::qi
- 递归精神.Qi语法的分割错误
- 提升::精神::Qi 关键字和标识符
- 提升精神解析器 Lex->qi:让"undocumented" on_success机制发挥作用
- 提升::精神::QI规则减少解析错误
- 使用提升::精神::qi 重新合成中间值
- 逻辑非运算符在提升::精神::QI 中不起作用
- 更丰富的错误返回消息用于提升::精神::qi 解析
- 提升精神2:跟随QI的进度百分比::p阿尔瑟。我的代码中有什么不好?
- 重载精神语法以使用lexer或qi解析器
- 为什么这个提升::精神::qi规则没有成功解析?
- 提升精神:Lex + Qi错误报告