我正在尝试编写一个与词法分析器(当一个更大的项目的一部分)一起工作的精神语法组件,或者只是用qi :: parsers(例如int_)进行测试。
下面是一个示例解析器(一种解析int的非常详细的方法)。问题是lex_int
功能。如果令牌是qi::unused_type
(没有词法分析器)&amp ;;我想要使用第二次重载。提供词法分析器的第一个。我想我必须使用一些模板或MPL技术,因为tok.integer_
是qi::unused_type
的编译错误。
顺便说一句,即使定义了USE_LEXER
,它现在也会掉落核心。使用预处理器定义代码定义工作正常,但这似乎是上个世纪。
namespace qi = boost::spirit::qi;
namespace lex = boost::spirit::lex;
#define USE_MYINT
#define USE_LEXER
// my grammar replacing int_
template<typename Iterator, typename Skipper=qi::space_type>
struct my_int : qi::grammar<Iterator, int(), Skipper>
{
qi::rule<Iterator, int(), Skipper> start;
template<typename TokenDef>
my_int(TokenDef &tok): my_int::base_type(start)
{
start %= lex_int(tok);
BOOST_SPIRIT_DEBUG_NODE(start);
}
// overload for lexer
template<typename TokenDef>
decltype(start) lex_int(TokenDef &tok)
{
return tok.integer_;
}
// overload for no lexer
// template<typename TokenDef>
decltype(start) lex_int(qi::unused_type)
{
return qi::int_;
}
};
完整(可编辑)示例位于dual_grammar.cc该示例适用于USE_MYINT
和USE_LEXER
已定义&amp;未定义。目标是通过USE_AUTO_SELECT
符号自动选择。
答案 0 :(得分:2)
做有用的,不是花哨的。相信我,这会比你预期的更伤害你(包括在你的应用程序在生产中崩溃之前不会出现的可怕类错误。)
提示1:使用Spirit,行内的颜色
事实是你无法按价值真正返回基于Proto的表达模板,因为他们沉浸在对临时工具的引用中。这些意味着超出包含它们的完整表达式的结尾(这是典型的表达模板:它们是假表达式,但它们可以包含在构造模板表达式期间以临时形式存在的文字,直到parser::compile()
)。
正是出于这个原因,任何使用运行时工厂的尝试(如lex_int
)都会导致痛苦。
昨天看起来有点:)
为了缓解这些问题,你可以将所有决定都转移到编译时间(我知道你已经尝试了,但你仍然按值传递规则,这不是静态的,因为Spirit V2在一切都可以被constexpr
证明的时候,没有写过。如果你看起来吃了Proto-0x,你会发现这就是图书馆的未来。
所以,实际上你可以专门研究检测Iterator
是一个令牌迭代器的特征上的语法。
请注意,您可能也想利用这个机会禁用Skipper,因为使用qi::space_type
解析器作为队长通常对词法分析器没有意义。
老实说,我只是编写单独的解析器。或者更好的是,承诺一个。我倾向于使用Qi-only解析器,因为它可以带来更大的灵活性。
提示2:如果不是为了灵活性,为什么[我们]使用Spirit?
如果我真的需要将语法转换为并且需要最终性能,我会使用像ANTLR或CoCo / R这样的解析器生成器,甚至手动解析我的解析器。