The problem with my current grammar is that it matches each character in a Lyric individually (but it does completely match a LineComment correctly.) Attempting to make it greedy via Lyric { ![\n]+ } makes it so that comments at the end of a line are recognized as being apart of a Lyric instead of a LineComment.
I’ve been reading up on the Lezer docs but I fully admit I understand very little of it, but not for lack of trying! I feel like I’m probably misusing tokens here but I’m not sure how to move forward here.
You’re right in that it shouldn’t consume double slashes; I hadn’t thought of it that way and viewing the problem like that does make a solution more obvious. That being said, the solution of:
Lyric { ![\n/] Lyric? | "/" (@eof | ![\n/] Lyric?) } (yours had a tiny parsing error in missing the closing paren) works for all cases except a line that is just a “/” followed by empty lines.
Going back to my original text, if we add a new line:
Hello world! // a comment
// This is also a comment
I'm Wardell!
/
Now the tree looks like:
Lyric(“Hello world!”)
LineComment(“// a comment”)
LineComment(“// This is also a comment”)
Lyric(“I’m Wardell!”)
Error("/")
I honestly think this is fine (and a far-cry better than what I had before) since Lezer is already pretty generous with errors and all I really care about is correct representation of comments; I can assume any errors are just lines to-be until proven otherwise.
Ugh, indeed, that token isn’t correct, and it seems like it isn’t possible to express exactly what we need here with a strictly regular expression, so you will have to write a (simple) external tokenizer for your Lyric token.
The external tokenizer effectively just keeps consuming character by character until it either hits a new line, an end of file, or a double //. Once it finds its end condition, it spits out a single token and exits.
It did take me an embarrassingly long time before I realized the token I’m supposed to pass into Input.acceptToken is supposed to be retrieved from a compiled grammar. I tried to give it everything else before I found out.