私は小さなコンパイラプロジェクトでソースファイルを解析するためにBoost Spiritを使用しています。ASTに位置情報を付けるにはどうすればいいですか?
構文解析中にエラーが発生した場合は、エラーの位置を出力できますが、後のフェーズで、通常セマンティックチェックを実行するときにはどうすればよいですか?
ソースファイルは自動ルールを使用して抽象構文木に解析されます。 ASTノードに行と列の情報を追加したい。解析中に簡単に実現できる方法はありますか?
私はLexerでboost :: spirit :: classic :: position_iterator2を使用していて、このレクサーを文法に使用しています。
はEDIT 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ノードは自動ルールを使用して構築されます。
私は数日を費やしています。スピリット・レックスを使用している小さなサンプルが役に立ちます。 – sehe
Spirit ParserのSpirit Lexの使い方に関するサンプルを追加しました。これで十分だろうか? –
問題の基本的な解決方法についての回答を追加しました。 –