如何使用斜杠在精神Lex模式
How to use a slash in Spirit Lex patterns?
下面的代码使用
可以正常编译clang++ -std=c++11 test.cpp -o test
但是当运行时抛出异常
的实例抛出后被调用"boost::词法分析程序::runtime_error"目前不支持what(): Lookahead('/')。
问题是输入和/或正则表达式(第12行和39行)中的斜杠(/),但我找不到解决方案如何正确地转义它。有提示吗?
#include <string>
#include <cstring>
#include <boost/spirit/include/lex.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
std::string regex("FOO/BAR");
template <typename Type>
struct Lexer : boost::spirit::lex::lexer<Type> {
Lexer() : foobar_(regex) {
this->self.add(foobar_);
}
boost::spirit::lex::token_def<std::string> foobar_;
};
template <typename Iterator, typename Def>
struct Grammar
: qi::grammar <Iterator, qi::in_state_skipper<Def> > {
template <typename Lexer> Grammar(const Lexer & _lexer);
typedef qi::in_state_skipper<Def> Skipper;
qi::rule<Iterator, Skipper> rule_;
};
template <typename Iterator, typename Def>
template <typename Lexer>
Grammar<Iterator, Def>::Grammar(const Lexer & _lexer)
: Grammar::base_type(rule_) {
rule_ = _lexer.foobar_;
}
int main() {
// INPUT
char const * first("FOO/BAR");
char const * last(first + strlen(first));
// LEXER
typedef lex::lexertl::token<const char *> Token;
typedef lex::lexertl::lexer<Token> Type;
Lexer<Type> l;
// GRAMMAR
typedef Lexer<Type>::iterator_type Iterator;
typedef Lexer<Type>::lexer_def Def;
Grammar<Iterator, Def> g(l);
// PARSE
bool ok = lex::tokenize_and_phrase_parse (
first
, last
, l
, g
, qi::in_state("WS")[l.self]
);
// CHECK
if (!ok || first != last) {
std::cout << "Failed parsing input file" << std::endl;
return 1;
}
return 0;
}
正如她所指出的那样,/
很可能被用作前瞻性操作符,很可能采用flex的语法。不幸的是,Spirit没有使用更正常的向前看语法(并不是说我认为其他语法更优雅;它只会让人对regex语法的所有细微变化感到困惑)。
如果看re_tokeniser.hpp
:
// Not an escape sequence and not inside a string, so
// check for meta characters.
switch (ch_)
{
...
case '/':
throw runtime_error("Lookahead ('/') is not supported yet.");
break;
...
}
它认为你不在转义序列中,也不在字符串中,所以它检查元字符。/
被认为是向前看的元字符(即使该功能没有实现),并且必须转义,尽管Boost文档根本没有提到这一点。
尝试用反斜杠(即"\/"
,如果使用原始字符串则为"/"
)转义/
(不在输入中)。或者,其他人建议使用[/]
.
我认为这是Spirit Lex文档中的一个错误,因为它没有指出/
必须转义。
编辑:向sehe和cv_and_he致敬,他们帮助纠正了我之前的一些想法。如果他们在这里发布答案,一定要给他们一个+1。
相关文章:
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 此模式的C++RegEx
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 使用可变模板的Broadcaster/Listener模式
- c++方法参数只能在linux的发布模式下自行更改
- 资源管理设计模式
- 使用 mod_gsoap 部署服务时,如何在 Gsoap 中更改 soap 上下文的模式?
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 小字符串优化(调试与发布模式)
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 在C++的一系列数字中查找重复模式
- 是否允许使用带有"w+"模式的 freopen 进行标准设置?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- 与 IPv4 点分十进制表示法匹配的 lex 模式
- 如何使用斜杠在精神Lex模式