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[\d a-fA-F]{2})*)(?<s1q2>")
41
+ |
42
+ (?<s2q1>')(?<s2>(?:[^\\ '\n ]|\\ [abfnrtvz\\ "']|\\ \n |\\ \d {1,3}|\\ x[\d a-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][\d a-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