Download
100 lines 4.2 KiBXMLModified 2026-10-16 raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
<!--
  BP (Bruce's Parsing Expression Grammar tool, https://github.com/bruce-hill/bp)
  lexer for chroma, for .bp grammar files.

  Covers "# comments", rule definitions ("name:" / "name::"), string
  literals, replacement strings after "=>" with their @captures, character
  literals and ranges (`a-z,A-Z), escape sequences (\n, \x1F, \N, \i),
  repetition counts (3, 1-2, 2+), captures (@name=, @name:, @:tag=),
  pattern primitives (. .. ^ ^^ $ $$ | _ __) and the operators.
-->
<lexer>
  <config>
    <name>BP</name>
    <alias>bp</alias>
    <filename>*.bp</filename>
    <mime_type>text/x-bp</mime_type>
  </config>
  <rules>
    <state name="root">
      <rule pattern="#[^\n]*"><token type="CommentSingle"/></rule>

      <!-- rule definition at the start of a line: name: pat  or  name:: pat -->
      <rule pattern="^([ \t]*)([A-Za-z][A-Za-z0-9-]*)([ \t]*)(::?)">
        <bygroups>
          <token type="TextWhitespace"/>
          <token type="NameFunction"/>
          <token type="TextWhitespace"/>
          <token type="Operator"/>
        </bygroups>
      </rule>

      <!-- replacement: => "text with @captures" -->
      <rule pattern="(=&gt;)([ \t]*)(&quot;)([^&quot;\n]*)(&quot;)">
        <bygroups>
          <token type="Operator"/>
          <token type="TextWhitespace"/>
          <token type="LiteralStringDouble"/>
          <usingself state="replacement"/>
          <token type="LiteralStringDouble"/>
        </bygroups>
      </rule>
      <rule pattern="(=&gt;)([ \t]*)(')([^'\n]*)(')">
        <bygroups>
          <token type="Operator"/>
          <token type="TextWhitespace"/>
          <token type="LiteralStringSingle"/>
          <usingself state="replacement"/>
          <token type="LiteralStringSingle"/>
        </bygroups>
      </rule>
      <rule pattern="=&gt;"><token type="Operator"/></rule>

      <!-- string literals have no escapes -->
      <rule pattern="&quot;[^&quot;\n]*&quot;"><token type="LiteralStringDouble"/></rule>
      <rule pattern="'[^'\n]*'"><token type="LiteralStringSingle"/></rule>

      <!-- character literals and ranges: `a  `a-z  `a-z,A-Z,_ -->
      <rule pattern="`(?:[^\n]-[^\n]|[^\n])(?:,(?:[^\n]-[^\n]|[^\n]))*"><token type="LiteralStringChar"/></rule>

      <!-- escape sequences and ranges: \n \x1F \033 \x00-x1F \r,n  plus \N \C \i \I \b -->
      <rule pattern="\\(?:x[0-9a-fA-F]{1,2}|[0-7]{1,3}|[A-Za-z])(?:[-,](?:x[0-9a-fA-F]{1,2}|[0-7]{1,3}|[A-Za-z]))*"><token type="LiteralStringEscape"/></rule>
      <rule pattern="\\[^\n]"><token type="LiteralStringEscape"/></rule>

      <!-- captures and backreferences: @name= @name: @:tag= @name:: @ -->
      <rule pattern="(@)(:?)([A-Za-z!][A-Za-z0-9-]*)([ \t]*)(=|::?)">
        <bygroups>
          <token type="Operator"/>
          <token type="Operator"/>
          <token type="NameVariable"/>
          <token type="TextWhitespace"/>
          <token type="Operator"/>
        </bygroups>
      </rule>
      <rule pattern="@"><token type="Operator"/></rule>

      <!-- repetition counts: 5  1-3  2+  -->
      <rule pattern="\d+(?:[ \t]*-[ \t]*\d+|\+)?"><token type="LiteralNumber"/></rule>

      <!-- pattern primitives -->
      <rule pattern="\.\.|\^\^|\^|\$\$|\$|\||\.|__|_"><token type="KeywordConstant"/></rule>

      <!-- builtin rules from builtins.bp -->
      <rule pattern="\b(?:parens|braces|brackets|anglebraces|string|id|var|word|Hex|hex|HEX|digit|int|number|esc|tab|nl|cr|crlf|lf|abc|Abc|ABC|ws|Nl)\b(?![-])"><token type="NameBuiltin"/></rule>
      <rule pattern="[A-Za-z][A-Za-z0-9-]*"><token type="Name"/></rule>

      <rule pattern="!~|[/!*+%~&lt;&gt;=:]"><token type="Operator"/></rule>
      <rule pattern="[()\[\];{}]"><token type="Punctuation"/></rule>
      <rule pattern="\n"><token type="TextWhitespace"/></rule>
      <rule pattern="[ \t]+"><token type="TextWhitespace"/></rule>
      <rule pattern="."><token type="Text"/></rule>
    </state>

    <state name="replacement">
      <rule pattern="@[A-Za-z0-9][A-Za-z0-9-]*"><token type="LiteralStringInterpol"/></rule>
      <rule pattern="\\(?:x[0-9a-fA-F]{1,2}|[0-7]{1,3}|.)"><token type="LiteralStringEscape"/></rule>
      <rule pattern="[^@\\]+"><token type="LiteralStringDouble"/></rule>
      <rule pattern="[@\\]"><token type="LiteralStringDouble"/></rule>
    </state>
  </rules>
</lexer>