Hey guys thank you for the reply. The ordered choice operator works !
As a conclusion to this thread, here is some code using @floop solution and another suggested to me by Alex Engelberg on the instaparse channel of the clojure slack.
Here is @floop’s solution using PEG’s ordered choice operator in the doc
rule:
(insta/defparser ex-with-choice
"
doc = (tag / text)*
text = #'[^@]*'
tag = <'@'> #'[a-z]\\w*' text-block*
text-block = <'{'> inner-text <'}'>
<inner-text> = #'[^}]*'
")
Alex’s solution uses PEG’s negative lookahead operator:
(insta/defparser ex-with-lookahead
"
doc = (text | tag)*
text = #'[^@]*'
tag = <'@'> #'[a-z]\\w*' text-block* !text-block
text-block = <'{'> inner-text <'}'>
<inner-text> = #'[^}]*'
")
The solutions seem to yield the same results
(= (ex-with-choice "some text @tag1{inner text}{inner text 2} some text 2 @tag2 other text")
(ex-with-lookahead "some text @tag1{inner text}{inner text 2} some text 2 @tag2 other text"))
;=> true
Which is:
(ex-with-choice "some text @tag1{inner text}{inner text 2} some text 2 @tag2 other text")
;=>
[:doc
[:text "some text "]
[:tag "tag1" [:text-block "inner text"] [:text-block "inner text 2"]]
[:text " some text 2 "]
[:tag "tag2"]
[:text " other text"]]
The PEG extensions in instaparse are very useful indeed.
Thx again. Cheers,