Need a bit of help with an instaparse grammar

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,

4 Likes