From f941d464e27e5a80e1f6e4943b02e3cbe9ff9897 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 22 Jun 2022 10:53:38 -0700 Subject: [PATCH] Add Chapel Lexer --- README.md | 2 +- lexers/chapel.go | 62 +++++++++++++++++++++++++++++++++ lexers/testdata/chapel.actual | 6 ++++ lexers/testdata/chapel.expected | 43 +++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 lexers/chapel.go create mode 100644 lexers/testdata/chapel.actual create mode 100644 lexers/testdata/chapel.expected diff --git a/README.md b/README.md index 445fb967d..8eb2cb921 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Prefix | Language :----: | -------- A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, Arduino, Awk B | Ballerina, Base Makefile, Bash, Batchfile, BibTeX, Bicep, BlitzBasic, BNF, Brainfuck -C | C, C#, C++, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Crystal, CSS, Cython +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, Diff, Django/Jinja, Docker, DTD, Dylan E | EBNF, Elixir, Elm, EmacsLisp, Erlang F | Factor, Fish, Forth, Fortran, FSharp diff --git a/lexers/chapel.go b/lexers/chapel.go new file mode 100644 index 000000000..5f6f0901c --- /dev/null +++ b/lexers/chapel.go @@ -0,0 +1,62 @@ +package lexers + +import ( + . "github.com/alecthomas/chroma/v2" // nolint +) + +// Chapel lexer. +var Chapel = Register(MustNewLexer( + &Config{ + Name: "Chapel", + Aliases: []string{"chapel", "chpl"}, + Filenames: []string{"*.chpl"}, + MimeTypes: []string{}, + }, + func() Rules { + return Rules{ + "root": { + {`\n`, TextWhitespace, nil}, + {`\s+`, TextWhitespace, nil}, + {`\\\n`, Text, nil}, + {`//(.*?)\n`, CommentSingle, nil}, + {`/(\\\n)?[*](.|\n)*?[*](\\\n)?/`, CommentMultiline, nil}, + {Words(``, `\b`, `config`, `const`, `in`, `inout`, `out`, `param`, `ref`, `type`, `var`), KeywordDeclaration, nil}, + {Words(``, `\b`, `false`, `nil`, `none`, `true`), KeywordConstant, nil}, + {Words(``, `\b`, `bool`, `bytes`, `complex`, `imag`, `int`, `locale`, `nothing`, `opaque`, `range`, `real`, `string`, `uint`, `void`), KeywordType, nil}, + {Words(``, `\b`, `atomic`, `single`, `sync`, `borrowed`, `owned`, `shared`, `unmanaged`, `align`, `as`, `begin`, `break`, `by`, `catch`, `cobegin`, `coforall`, `continue`, `defer`, `delete`, `dmapped`, `do`, `domain`, `else`, `enum`, `except`, `export`, `extern`, `for`, `forall`, `foreach`, `forwarding`, `if`, `implements`, `import`, `index`, `init`, `inline`, `label`, `lambda`, `let`, `lifetime`, `local`, `new`, `noinit`, `on`, `only`, `otherwise`, `override`, `pragma`, `primitive`, `private`, `prototype`, `public`, `reduce`, `require`, `return`, `scan`, `select`, `serial`, `sparse`, `subdomain`, `then`, `this`, `throw`, `throws`, `try`, `use`, `when`, `where`, `while`, `with`, `yield`, `zip`), Keyword, nil}, + {`(iter)(\s+)`, ByGroups(Keyword, TextWhitespace), Push("procname")}, + {`(proc)(\s+)`, ByGroups(Keyword, TextWhitespace), Push("procname")}, + {`(operator)(\s+)`, ByGroups(Keyword, TextWhitespace), Push("procname")}, + {`(class|interface|module|record|union)(\s+)`, ByGroups(Keyword, TextWhitespace), Push("classname")}, + {`\d+i`, LiteralNumber, nil}, + {`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil}, + {`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil}, + {`\d+[Ee][-+]\d+i`, LiteralNumber, nil}, + {`(\d*\.\d+)([eE][+-]?[0-9]+)?i?`, LiteralNumberFloat, nil}, + {`\d+[eE][+-]?[0-9]+i?`, LiteralNumberFloat, nil}, + {`0[bB][01]+`, LiteralNumberBin, nil}, + {`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil}, + {`0[oO][0-7]+`, LiteralNumberOct, nil}, + {`[0-9]+`, LiteralNumberInteger, nil}, + {`"(\\\\|\\"|[^"])*"`, LiteralString, nil}, + {`'(\\\\|\\'|[^'])*'`, LiteralString, nil}, + {`(=|\+=|-=|\*=|/=|\*\*=|%=|&=|\|=|\^=|&&=|\|\|=|<<=|>>=|<=>|<~>|\.\.|by|#|\.\.\.|&&|\|\||!|&|\||\^|~|<<|>>|==|!=|<=|>=|<|>|[+\-*/%]|\*\*)`, Operator, nil}, + {`[:;,.?()\[\]{}]`, Punctuation, nil}, + {`[a-zA-Z_][\w$]*`, NameOther, nil}, + }, + "classname": { + {`[a-zA-Z_][\w$]*`, NameClass, Pop(1)}, + }, + "procname": { + {`([a-zA-Z_][.\w$]*|\~[a-zA-Z_][.\w$]*|[+*/!~%<>=&^|\-:]{1,2})`, NameFunction, Pop(1)}, + {`\(`, Punctuation, Push("receivertype")}, + {`\)+\.`, Punctuation, nil}, + }, + "receivertype": { + {Words(``, `\b`, `atomic`, `single`, `sync`, `borrowed`, `owned`, `shared`, `unmanaged`), Keyword, nil}, + {Words(``, `\b`, `bool`, `bytes`, `complex`, `imag`, `int`, `locale`, `nothing`, `opaque`, `range`, `real`, `string`, `uint`, `void`), KeywordType, nil}, + {`[^()]*`, NameOther, Pop(1)}, + }, + } + }, +)) diff --git a/lexers/testdata/chapel.actual b/lexers/testdata/chapel.actual new file mode 100644 index 000000000..45ae57779 --- /dev/null +++ b/lexers/testdata/chapel.actual @@ -0,0 +1,6 @@ +config const numMessages = 100; + +forall msg in 1..numMessages do + writeln("Hello, world! (from iteration ", msg, " of ", numMessages, ")"); + +// Oh, and a comment for good measure. diff --git a/lexers/testdata/chapel.expected b/lexers/testdata/chapel.expected new file mode 100644 index 000000000..c92fdd486 --- /dev/null +++ b/lexers/testdata/chapel.expected @@ -0,0 +1,43 @@ +[ + {"type":"KeywordDeclaration","value":"config"}, + {"type":"TextWhitespace","value":" "}, + {"type":"KeywordDeclaration","value":"const"}, + {"type":"TextWhitespace","value":" "}, + {"type":"NameOther","value":"numMessages"}, + {"type":"TextWhitespace","value":" "}, + {"type":"Operator","value":"="}, + {"type":"TextWhitespace","value":" "}, + {"type":"LiteralNumberInteger","value":"100"}, + {"type":"Punctuation","value":";"}, + {"type":"TextWhitespace","value":"\n\n"}, + {"type":"Keyword","value":"forall"}, + {"type":"TextWhitespace","value":" "}, + {"type":"NameOther","value":"msg"}, + {"type":"TextWhitespace","value":" "}, + {"type":"KeywordDeclaration","value":"in"}, + {"type":"TextWhitespace","value":" "}, + {"type":"LiteralNumberInteger","value":"1"}, + {"type":"Operator","value":".."}, + {"type":"NameOther","value":"numMessages"}, + {"type":"TextWhitespace","value":" "}, + {"type":"Keyword","value":"do"}, + {"type":"TextWhitespace","value":"\n "}, + {"type":"NameOther","value":"writeln"}, + {"type":"Punctuation","value":"("}, + {"type":"LiteralString","value":"\"Hello, world! (from iteration \""}, + {"type":"Punctuation","value":","}, + {"type":"TextWhitespace","value":" "}, + {"type":"NameOther","value":"msg"}, + {"type":"Punctuation","value":","}, + {"type":"TextWhitespace","value":" "}, + {"type":"LiteralString","value":"\" of \""}, + {"type":"Punctuation","value":","}, + {"type":"TextWhitespace","value":" "}, + {"type":"NameOther","value":"numMessages"}, + {"type":"Punctuation","value":","}, + {"type":"TextWhitespace","value":" "}, + {"type":"LiteralString","value":"\")\""}, + {"type":"Punctuation","value":");"}, + {"type":"TextWhitespace","value":"\n\n"}, + {"type":"CommentSingle","value":"// Oh, and a comment for good measure.\n"} +]