【发布时间】:2012-02-03 14:18:08
【问题描述】:
我正在使用 Boost Spirit 来解析一个小型编译器项目中的源文件。
如果在解析过程中出现错误,我可以打印错误的位置,但我在后期如何做,通常是在执行语义检查时?
我的源文件使用自动规则解析为抽象语法树。我想将 line 和 col 信息添加到 AST 节点中。在解析过程中是否有一种简单的方法可以实现这一点?
我在我的 Lexer 中使用 boost::spirit::classic::position_iterator2,然后在我的语法中使用这个词法分析器。
谢谢
为 sehe 编辑:
词法分析器是这样定义的:
typedef std::string::iterator base_iterator_type;
typedef boost::spirit::classic::position_iterator2<base_iterator_type> pos_iterator_type;
typedef boost::spirit::lex::lexertl::token<pos_iterator_type> Tok;
typedef boost::spirit::lex::lexertl::actor_lexer<Tok> lexer_type;
template<typename L>
class SpiritLexer : public lex::lexer<L> {
//Token definitions
}
typedef lexer_type::iterator_type Iterator;
typedef SpiritLexer<lexer_type> Lexer;
语法是这样定义的:
struct EddiGrammar : qi::grammar<lexer::Iterator, ast::SourceFile()> {
EddiGrammar(const lexer::Lexer& lexer);
//Token definitions
};
最后,这是我解析源代码的方式:
ast::SourceFile program
std::ifstream in(file.c_str());
in.unsetf(std::ios::skipws);
in.seekg(0, std::istream::end);
std::size_t size(static_cast<size_t>(in.tellg()));
in.seekg(0, std::istream::beg);
std::string contents(size, 0);
in.read(&contents[0], size);
pos_iterator_type position_begin(contents.begin(), contents.end(), file);
pos_iterator_type position_end;
Lexer lexer;
EddiGrammar grammar(lexer);
bool r = spirit::lex::tokenize_and_parse(position_begin, position_end, lexer, grammar, program);
在我的语法中,我通过引用一些词法分析器标记来使用词法分析器。例如:
else_ %=
lexer.else_
>> lexer.left_brace
>> *(instruction)
>> lexer.right_brace;
我所有的 AST 节点都是使用自动规则构建的。
【问题讨论】:
-
几天前我花了一些时间。您使用 Spirit Lex 的究竟如何的小样本会很有帮助。
-
我添加了关于如何使用 Spirit Parser 中的 Spirit Lex 的示例。我希望这就够了?
-
我添加了一个关于该问题的基本解决方案的答案。
标签: c++ boost-spirit