Repository: alecthomas/chroma
Pull request #892 (2023-11-24 19:01:43)

Add an Alloy lexer
This PR adds an Alloy lexer, based on the Pygments one. This was generated using the following command:

```bash
python3 _tools/pygments2chroma_xml.py \
  pygments.lexers.dsls.AlloyLexer \
  > lexers/embedded/alloy.xml
```

Once again it looks like i'm the only person that needs this, so there's no corresponding issue.

alecthomas: Ah the README change conflicts with your previous PR I think.
DanilaFe: It sure does. I will rebase.
DanilaFe: There, ready for your review again and conflict-free :) 

Patch:
diff --git a/README.md b/README.md
index 95e095e..25af3e0 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ translators for Pygments lexers and styles.
 
 | Prefix | Language                                                                                                                                                                                                                             |
 | :----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-|   A    | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, AutoHotkey, AutoIt, Awk                                                                             |
+|   A    | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Alloy, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, AutoHotkey, AutoIt, Awk                                                                             |
 |   B    | Ballerina, Bash, Bash Session, Batchfile, BibTeX, Bicep, BlitzBasic, BNF, BQN, Brainfuck                                                                                                                                             |
 |   C    | C, C#, C++, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Chapel, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Crystal, CSS, Cython                    |
 |   D    | D, Dart, Dax, Diff, Django/Jinja, dns, Docker, DTD, Dylan                                                                                                                                                                                 |
diff --git a/lexers/embedded/alloy.xml b/lexers/embedded/alloy.xml
new file mode 100644
index 0000000..1de9ea6
--- /dev/null
+++ b/lexers/embedded/alloy.xml
@@ -0,0 +1,58 @@
+
+<lexer>
+  <config>
+    <name>Alloy</name>
+    <alias>alloy</alias>
+    <filename>*.als</filename>
+    <mime_type>text/x-alloy</mime_type>
+    <dot_all>true</dot_all>
+  </config>
+  <rules>
+    <state name="sig">
+      <rule pattern="(extends)\b"><token type="Keyword"/><pop depth="1"/></rule>
+      <rule pattern="[a-zA-Z_][\w]*&quot;*"><token type="Name"/></rule>
+      <rule pattern="[^\S\n]+"><token type="TextWhitespace"/></rule>
+      <rule pattern=","><token type="Punctuation"/></rule>
+      <rule pattern="\{"><token type="Operator"/><pop depth="1"/></rule>
+    </state>
+    <state name="module">
+      <rule pattern="[^\S\n]+"><token type="TextWhitespace"/></rule>
+      <rule pattern="[a-zA-Z_][\w]*&quot;*"><token type="Name"/><pop depth="1"/></rule>
+    </state>
+    <state name="fun">
+      <rule pattern="[^\S\n]+"><token type="TextWhitespace"/></rule>
+      <rule pattern="\{"><token type="Operator"/><pop depth="1"/></rule>
+      <rule pattern="[a-zA-Z_][\w]*&quot;*"><token type="Name"/><pop depth="1"/></rule>
+    </state>
+    <state name="fact">
+      <rule><include state="fun"/></rule>
+      <rule pattern="&quot;\b(\\\\|\\[^\\]|[^&quot;\\])*&quot;"><token type="LiteralString"/><pop depth="1"/></rule>
+    </state>
+    <state name="root">
+      <rule pattern="--.*?$"><token type="CommentSingle"/></rule>
+      <rule pattern="//.*?$"><token type="CommentSingle"/></rule>
+      <rule pattern="/\*.*?\*/"><token type="CommentMultiline"/></rule>
+      <rule pattern="[^\S\n]+"><token type="TextWhitespace"/></rule>
+      <rule pattern="(module|open)(\s+)"><bygroups><token type="KeywordNamespace"/><token type="TextWhitespace"/></bygroups><push state="module"/></rule>
+      <rule pattern="(sig|enum)(\s+)"><bygroups><token type="KeywordDeclaration"/><token type="TextWhitespace"/></bygroups><push state="sig"/></rule>
+      <rule pattern="(iden|univ|none)\b"><token type="KeywordConstant"/></rule>
+      <rule pattern="(int|Int)\b"><token type="KeywordType"/></rule>
+      <rule pattern="(var|this|abstract|extends|set|seq|one|lone|let)\b"><token type="Keyword"/></rule>
+      <rule pattern="(all|some|no|sum|disj|when|else)\b"><token type="Keyword"/></rule>
+      <rule pattern="(run|check|for|but|exactly|expect|as|steps)\b"><token type="Keyword"/></rule>
+      <rule pattern="(always|after|eventually|until|release)\b"><token type="Keyword"/></rule>
+      <rule pattern="(historically|before|once|since|triggered)\b"><token type="Keyword"/></rule>
+      <rule pattern="(and|or|implies|iff|in)\b"><token type="OperatorWord"/></rule>
+      <rule pattern="(fun|pred|assert)(\s+)"><bygroups><token type="Keyword"/><token type="TextWhitespace"/></bygroups><push state="fun"/></rule>
+      <rule pattern="(fact)(\s+)"><bygroups><token type="Keyword"/><token type="TextWhitespace"/></bygroups><push state="fact"/></rule>
+      <rule pattern="!|#|&amp;&amp;|\+\+|&lt;&lt;|&gt;&gt;|&gt;=|&lt;=&gt;|&lt;=|\.\.|\.|-&gt;"><token type="Operator"/></rule>
+      <rule pattern="[-+/*%=&lt;&gt;&amp;!^|~{}\[\]().\&#x27;;]"><token type="Operator"/></rule>
+      <rule pattern="[a-zA-Z_][\w]*&quot;*"><token type="Name"/></rule>
+      <rule pattern="[:,]"><token type="Punctuation"/></rule>
+      <rule pattern="[0-9]+"><token type="LiteralNumberInteger"/></rule>
+      <rule pattern="&quot;\b(\\\\|\\[^\\]|[^&quot;\\])*&quot;"><token type="LiteralString"/></rule>
+      <rule pattern="\n"><token type="TextWhitespace"/></rule>
+    </state>
+  </rules>
+</lexer>
+


Test patch:
diff --git a/lexers/testdata/alloy.actual b/lexers/testdata/alloy.actual
new file mode 100644
index 0000000..89ff54e
--- /dev/null
+++ b/lexers/testdata/alloy.actual
@@ -0,0 +1,16 @@
+sig Node {
+  edges: set Node
+}
+
+fact "Connected graph" {
+  some n: Node | n.*edges = Node
+}
+
+fact "No self edges" {
+  no iden & edges
+}
+
+one sig Ball {
+  -- note the var
+  var loc: Node
+}
diff --git a/lexers/testdata/alloy.expected b/lexers/testdata/alloy.expected
new file mode 100644
index 0000000..743e54f
--- /dev/null
+++ b/lexers/testdata/alloy.expected
@@ -0,0 +1,77 @@
+[
+  {"type":"KeywordDeclaration","value":"sig"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Node"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"{"},
+  {"type":"TextWhitespace","value":"\n  "},
+  {"type":"Name","value":"edges"},
+  {"type":"Punctuation","value":":"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Keyword","value":"set"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Node"},
+  {"type":"TextWhitespace","value":"\n"},
+  {"type":"Operator","value":"}"},
+  {"type":"TextWhitespace","value":"\n\n"},
+  {"type":"Keyword","value":"fact"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"LiteralString","value":"\"Connected graph\""},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"{"},
+  {"type":"TextWhitespace","value":"\n  "},
+  {"type":"Keyword","value":"some"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"n"},
+  {"type":"Punctuation","value":":"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Node"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"|"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"n"},
+  {"type":"Operator","value":".*"},
+  {"type":"Name","value":"edges"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"="},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Node"},
+  {"type":"TextWhitespace","value":"\n"},
+  {"type":"Operator","value":"}"},
+  {"type":"TextWhitespace","value":"\n\n"},
+  {"type":"Keyword","value":"fact"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"LiteralString","value":"\"No self edges\""},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"{"},
+  {"type":"TextWhitespace","value":"\n  "},
+  {"type":"Keyword","value":"no"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"KeywordConstant","value":"iden"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"\u0026"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"edges"},
+  {"type":"TextWhitespace","value":"\n"},
+  {"type":"Operator","value":"}"},
+  {"type":"TextWhitespace","value":"\n\n"},
+  {"type":"Keyword","value":"one"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"KeywordDeclaration","value":"sig"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Ball"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Operator","value":"{"},
+  {"type":"TextWhitespace","value":"\n  "},
+  {"type":"CommentSingle","value":"-- note the var"},
+  {"type":"TextWhitespace","value":"\n  "},
+  {"type":"Keyword","value":"var"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"loc"},
+  {"type":"Punctuation","value":":"},
+  {"type":"TextWhitespace","value":" "},
+  {"type":"Name","value":"Node"},
+  {"type":"TextWhitespace","value":"\n"},
+  {"type":"Operator","value":"}"},
+  {"type":"TextWhitespace","value":"\n"}
+]