Skip to content

Commit a92f44c

Browse files
committed
Quick-n-dirty Lua scanner
1 parent 25ea056 commit a92f44c

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

lib/coderay/scanners/lua.rb

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Scanner for the Lua[http://lua.org] programming lanuage.
4+
#
5+
# The language’s complete syntax is defined in
6+
# {the Lua manual}[http://www.lua.org/manual/5.2/manual.html],
7+
# which is what this scanner tries to conform to.
8+
class CodeRay::Scanners::Lua < CodeRay::Scanners::Scanner
9+
10+
register_for :lua
11+
file_extension "lua"
12+
title "Lua"
13+
14+
KEYWORDS = %w[
15+
and break do else elseif end
16+
for function goto if in
17+
local not or repeat return
18+
then until while
19+
]
20+
21+
PREDEFINED_CONSTANTS = %w[false true nil]
22+
23+
PREDEFINED_EXPRESSIONS = %w[
24+
assert collectgarbage dofile error getmetatable
25+
ipairs load loadfile next pairs pcall print
26+
rawequal rawget rawlen rawset select setmetatable
27+
tonumber tostring type xpcall
28+
]
29+
30+
SCANNER = /
31+
(?<fluff>[\d\D]*?) # eat content up until something we want
32+
(?:
33+
\b(?<keyword>#{KEYWORDS.join('|')})\b
34+
|
35+
(?<blockcomment>
36+
--\[(?<commentequals>=*)\[[\d\D]*?\]\k<commentequals>\]
37+
)
38+
|
39+
(?:
40+
(?<s1q1>")(?<s1>(?:[^\\"\n]|\\[abfnrtvz\\"']|\\\n|\\\d{1,3}|\\x[\da-fA-F]{2})*)(?<s1q2>")
41+
|
42+
(?<s2q1>')(?<s2>(?:[^\\'\n]|\\[abfnrtvz\\"']|\\\n|\\\d{1,3}|\\x[\da-fA-F]{2})*)(?<s2q2>')
43+
|
44+
(?<s3q1>\[(?<stringequals>=*)\[)(?<s3>[\d\D]*?)(?<s3q2>\]\k<stringequals>\])
45+
)
46+
|
47+
(?<comment>
48+
--(?!\[).+
49+
)
50+
|
51+
(?<number>
52+
-? # Allows -2 to be properly highlighted, but makes 10-5 show -5 as a single number
53+
(?:
54+
0[xX][\da-fA-F]+
55+
|
56+
(?:
57+
\d+\.?\d*
58+
|
59+
\d*\.?\d+
60+
)
61+
(?:[eE][-+]?\d+)?
62+
)
63+
)
64+
|
65+
\b(?<constant>#{PREDEFINED_CONSTANTS.join('|')})\b
66+
|
67+
\b(?<library>#{PREDEFINED_EXPRESSIONS.join('|')})\b
68+
|
69+
(?<gotolabel>
70+
::[a-zA-Z_]\w*::
71+
)
72+
|
73+
(?<reserved>
74+
\b_[A-Z]+\b
75+
)
76+
)
77+
/x
78+
79+
CAPTURE_KINDS = {
80+
fluff: :content,
81+
reserved: :reserved,
82+
comment: :comment,
83+
blockcomment: :comment,
84+
keyword: :keyword,
85+
number: :float,
86+
constant: :"predefined-constant",
87+
library: :predefined,
88+
s1q1: :delimiter,
89+
s1: :string,
90+
s1q2: :delimiter,
91+
s2q1: :delimiter,
92+
s2: :string,
93+
s2q2: :delimiter,
94+
s3q1: :delimiter,
95+
s3: :string,
96+
s3q2: :delimiter,
97+
gotolabel: :label,
98+
}
99+
100+
protected
101+
102+
def scan_tokens(tokens, options)
103+
string.gsub(SCANNER) do
104+
CAPTURE_KINDS.each do |capture,kind|
105+
tokens.text_token( $~[capture], kind ) if $~[capture] && !$~[capture].empty?
106+
end
107+
end
108+
tokens
109+
end
110+
111+
end

0 commit comments

Comments
 (0)