126 lines
4.1 KiB
Ruby
126 lines
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Rouge
|
|
module Lexers
|
|
class Q < RegexLexer
|
|
title 'Q'
|
|
desc 'The Q programming language (kx.com)'
|
|
tag 'q'
|
|
aliases 'kdb+'
|
|
filenames '*.q'
|
|
mimetypes 'text/x-q', 'application/x-q'
|
|
|
|
identifier = /\.?[a-z][a-z0-9_.]*/i
|
|
|
|
def self.keywords
|
|
@keywords ||= %w[do if while select update delete exec from by]
|
|
end
|
|
|
|
def self.word_operators
|
|
@word_operators ||= %w[
|
|
and or except inter like each cross vs sv within where in asof bin binr cor cov cut ej fby
|
|
div ij insert lj ljf mavg mcount mdev mmax mmin mmu mod msum over prior peach pj scan scov setenv ss
|
|
sublist uj union upsert wavg wsum xasc xbar xcol xcols xdesc xexp xgroup xkey xlog xprev xrank
|
|
]
|
|
end
|
|
|
|
def self.builtins
|
|
@builtins ||= %w[
|
|
first enlist value type get set count string key max min sum prd last flip distinct raze neg
|
|
desc differ dsave dev eval exit exp fills fkeys floor getenv group gtime hclose hcount hdel hopen hsym
|
|
iasc idesc inv keys load log lsq ltime ltrim maxs md5 med meta mins next parse plist prds prev rand rank ratios
|
|
read0 read1 reciprocal reverse rload rotate rsave rtrim save sdev show signum sin sqrt ssr sums svar system
|
|
tables tan til trim txf ungroup var view views wj wj1 ww
|
|
]
|
|
end
|
|
|
|
state :root do
|
|
# q allows a file to start with a shebang
|
|
rule %r/#!(.*?)$/, Comment::Preproc, :top
|
|
rule %r//, Text, :top
|
|
end
|
|
|
|
state :top do
|
|
# indented lines at the top of the file are ignored by q
|
|
rule %r/^[ \t\r]+.*$/, Comment::Special
|
|
rule %r/\n+/, Text
|
|
rule %r//, Text, :base
|
|
end
|
|
|
|
state :base do
|
|
rule %r/\n+/m, Text
|
|
rule(/^.\)/, Keyword::Declaration)
|
|
|
|
# Identifiers, word operators, etc.
|
|
rule %r/#{identifier}/ do |m|
|
|
if self.class.keywords.include? m[0]
|
|
token Keyword
|
|
elsif self.class.word_operators.include? m[0]
|
|
token Operator::Word
|
|
elsif self.class.builtins.include? m[0]
|
|
token Name::Builtin
|
|
elsif /^\.[zQqho]\./ =~ m[0]
|
|
token Name::Constant
|
|
else
|
|
token Name
|
|
end
|
|
end
|
|
|
|
# White space and comments
|
|
rule(%r{\s+/.*}, Comment::Single)
|
|
rule(/[ \t\r]+/, Text::Whitespace)
|
|
rule(%r{^/$.*?^\\$}m, Comment::Multiline)
|
|
rule(%r{^\/[^\n]*$(\n[^\S\n]+.*$)*}, Comment::Multiline)
|
|
# til EOF comment
|
|
rule(/^\\$/, Comment, :bottom)
|
|
rule(/^\\\\\s+/, Keyword, :bottom)
|
|
|
|
# Literals
|
|
## strings
|
|
rule(/"/, Str, :string)
|
|
## timespan/stamp constants
|
|
rule(/(?:\d+D|\d{4}\.[01]\d\.[0123]\d[DT])(?:[012]\d:[0-5]\d(?::[0-5]\d(?:\.\d+)?)?|([012]\d)?)[zpn]?\b/,
|
|
Literal::Date)
|
|
## time/minute/second constants
|
|
rule(/[012]\d:[0-5]\d(?::[0-5]\d(\.\d+)?)?[uvtpn]?\b/, Literal::Date)
|
|
## date constants
|
|
rule(/\d{4}\.[01]\d\.[0-3]\d[dpnzm]?\b/, Literal::Date)
|
|
## special values
|
|
rule(/0[nNwW][hijefcpmdznuvt]?/, Keyword::Constant)
|
|
|
|
# operators to match before numbers
|
|
rule(%r{'|\/:|\\:|':|\\|\/|0:|1:|2:}, Operator)
|
|
|
|
## numbers
|
|
rule(/(\d+[.]\d*|[.]\d+)(e[+-]?\d+)?[ef]?/, Num::Float)
|
|
rule(/\d+e[+-]?\d+[ef]?/, Num::Float)
|
|
rule(/\d+[ef]/, Num::Float)
|
|
rule(/0x[0-9a-f]+/i, Num::Hex)
|
|
rule(/[01]+b/, Num::Bin)
|
|
rule(/[0-9]+[hij]?/, Num::Integer)
|
|
## symbols and paths
|
|
rule(%r{(`:[:a-z0-9._\/]*|`(?:[a-z0-9.][:a-z0-9._]*)?)}i, Str::Symbol)
|
|
rule(/(?:<=|>=|<>|::)|[?:$%&|@._#*^\-+~,!><=]:?/, Operator)
|
|
|
|
rule %r/[{}\[\]();]/, Punctuation
|
|
|
|
# commands
|
|
rule(/\\.*\n/, Text)
|
|
|
|
end
|
|
|
|
state :string do
|
|
rule(/"/, Str, :pop!)
|
|
rule %r/\\([\\nr]|[01][0-7]{2})/, Str::Escape
|
|
rule %r/[^\\"\n]+/, Str
|
|
rule %r/\\/, Str # stray backslash
|
|
end
|
|
|
|
state :bottom do
|
|
rule %r/.*\z/m, Comment::Multiline
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|