How to annotate the AST with position information with boost spirit x3?
Asked Answered
B

0

7

So, I've written my grammar and would like to provide some debug information like line numbers in order to be able to step through the generated executable code with my own debugger.

After some googling I found that one can fully define the tag classes used in the rules like this:

x3::rule<class CodeLine, ast::InstructionOrDirectiveAndArgs> const code_line = "code_line";

auto const code_line_def = ...

class CodeLine {
public:
    template <typename T, typename Iterator, typename Context>
    inline void on_success(Iterator const& first, Iterator const& last, T& ast, Context const& context) {

        static std::uint64_t line = 0;
        auto& error_handler = x3::get<error_handler_tag>(context).get();
        error_handler.tag(ast, first, last);
        ast.line_no = line;
        if (*last == '\0') {
            line = 0;
        } else {
            line += 1;
        }
    }
};

In this fully defined tag classes one can implement an on_success method which is called when the rule could be successfully matched. So I implemented the tag class for the rule that matches a line of code. But since I couldn't find a way to obtain the current line number from spirit I resorted to a static variable that tracks the current line. The problem is to know when to reset the line counter, as you can see at my quite dumb try.

This seems to be a very convoluted way to keep track of the line numbers so there has to be a better way.

The question is now, what is the best or correct way to get the current line number?

Thanks for reading!

Bayless answered 22/3, 2016 at 21:21 Comment(6)
I won't have time - right now - to write it up here, but I've previously figured it out in these streams: livecoding.tv/sehe/playlists/RJvnR-spirit-x3-tinkering I think it's in episode #1-3. Sorry it's so slow, I too, had to work from the samples and library code :)Violence
About the line numbers, use the linepos iterator from support (include/support_linepos_iterator.hpp, from memory)Violence
@Violence I am having difficulties getting the video you've linked playing. I've signed up for the site, but it tells me "Something went wrong! Video cannot be played." - are these videos available on some other platform?Heracles
@Heracles well, for me it's worse, it just 404s (part 2 gives me the "Something went wrong" indeed). LiveCoding has chosen to go the "nagging" route, instead of "free content creation" route. Too bad (though I still got a free T-shirt out of it). I'll bookmark this, so that I might just add a proper answer here instead.Violence
What you have written is basically x3::annotate_on_success with manual character checking. Interestingly, the library does track line numbers because on_error handlers print them upon expectation failure - you can customize the error message (by appending a string) but unfortunately there is no way to obtain that line number currently. I think the simplest solution would be to just note iterator position and then compare it with an array of integers (line break positions) that would be generated from input.Alderson
#57263350 this could be of interestViolence

© 2022 - 2024 — McMap. All rights reserved.