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="(=>)([ \t]*)(")([^"\n]*)(")">
<bygroups>
<token type="Operator"/>
<token type="TextWhitespace"/>
<token type="LiteralStringDouble"/>
<usingself state="replacement"/>
<token type="LiteralStringDouble"/>
</bygroups>
</rule>
<rule pattern="(=>)([ \t]*)(')([^'\n]*)(')">
<bygroups>
<token type="Operator"/>
<token type="TextWhitespace"/>
<token type="LiteralStringSingle"/>
<usingself state="replacement"/>
<token type="LiteralStringSingle"/>
</bygroups>
</rule>
<rule pattern="=>"><token type="Operator"/></rule>
<!-- string literals have no escapes -->
<rule pattern=""[^"\n]*""><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="!~|[/!*+%~<>=:]"><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>
|