Monday, May 31, 2021

Recursive parentheses in syntax

I'm writing a syntax file for a string template DSL (somewhat similar to Bash parameter expansion) which distinguishes between (a) `$(...)` (call it "placeholder") and (b) `(...)` (call it "parens") where placeholder is preferably an Operator and parens is preferably a String where the parentheses themselves are Special, and where placeholders can occur inside non-highlighted text and both can be nested inside (certain parts of) placeholders and inside parens which are inside a placeholder.

I know that Vim regex do not support recursive patterns but I'm pretty confident that this can be pulled off in a syntax definition using regions which contain other regions, but I'm not quite sure if/how. I'm wondering if someone can tell or point me to a relevant example. In particular I'm not sure how/if you can nest a region with some delimiters inside another region with the same delimiters without failing to match the outer closing delimiter or matching past it.

In Perl 5.10+ it corresponds to a regex like this (in lieu of a formal syntax), with the `\(` and `\)` which are part of the syntax replaced with `\{` and `\}` for clarity, and each `$foo` representing some more or less complicated subexpression whose exact shape is (I think) irrelevant to the recursion issue.  Thus this is not the actual regex used to match a placeholder, but it is like an MWE which illustrates how it is supposed to work.

``````perl
my $placeholder_re = qr{
  (?<placeholder>
    \$\{
      $varname_re
      (?:
        $operator_A_re
        (?<parens>
          \s*
          \{
            (?<content>
              (?:
                [^\{\}\$]++
              | \$ (?! \{ ) 
              | (?&placeholder)
              | (?&parens)
              )*?
            )
          \}
          \s*
        )
        $operator_B_re
        (?<parens_B> (?&parens) )
      |
        $some_operator_re
        (?<content_B> (?&parens) | (?&content) )
      )
    \}
  )
}msx;
``````
    
TIA,

/bpj

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/CADAJKhCG13VLQL27oJ4FdLygChsz3RW7COEpoo8PFRjY5bMsyA%40mail.gmail.com.

No comments: