I am having problems with this mini-grammar, which tries to match markdown-like header constructs.
role Like-a-word {
regex like-a-word { \S+ }
}
role Span does Like-a-word {
regex span { <like-a-word>[\s+ <like-a-word>]* }
}
grammar Grammar::Headers does Span {
token TOP {^ <header> \v+ $}
token hashes { '#'**1..6 }
regex header {^^ <hashes> \h+ <span> [\h* $0]? $$}
}
I would like it to match ## Easier ##
as a header, but instead it takes ##
as part of span
:
TOP
| header
| | hashes
| | * MATCH "##"
| | span
| | | like-a-word
| | | * MATCH "Easier"
| | | like-a-word
| | | * MATCH "##"
| | | like-a-word
| | | * FAIL
| | * MATCH "Easier ##"
| * MATCH "## Easier ##"
* MATCH "## Easier ##\n"
「## Easier ##
」
header => 「## Easier ##」
hashes => 「##」
span => 「Easier ##」
like-a-word => 「Easier」
like-a-word => 「##」
The problem is that the [\h* $0]?
simply does not seem to work, with span
gobbling up all available words. Any idea?
?
after*
. – Deaden$0
to match, when there are no positional captures? – Fermitoken
unless you know you need one of the other options (regex
,rule
, andmethod
). – Youthfulregex
if you are sure you need backtracking, because backtracking will frequently unnecessarily make parsing run literally millions of times slower than necessary, or worse. If you switch all yourregex
declarations totoken
you'll see that your code will continue to parse correctly (at least for your trial input "## Easier ##\n") but will quite plausibly run vastly faster on large or complex inputs. – Youthfullike-a-word
, to a token, though. – Conflagration