1local info = {
2 version = 1.002,
3 comment = "scintilla lpeg lexer for lua",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files",
7}
8
9local P, R, S, C, Cmt, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cmt, lpeg.Cp
10local match, find = string.match, string.find
11local setmetatable = setmetatable
12
13local lexers = require("scite-context-lexer")
14
15local patterns = lexers.patterns
16local token = lexers.token
17
18local lualexer = lexers.new("lua","scite-context-lexer-lua")
19
20local luawhitespace = lualexer.whitespace
21
22local stringlexer = lexers.load("scite-context-lexer-lua-longstring")
23
24
25local directives = { }
26
27local keywords = {
28 "and", "break", "do", "else", "elseif", "end", "false", "for", "function",
29 "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true",
30 "until", "while",
31}
32
33local functions = {
34 "assert", "collectgarbage", "dofile", "error", "getmetatable",
35 "ipairs", "load", "loadfile", "module", "next", "pairs",
36 "pcall", "print", "rawequal", "rawget", "rawset", "require",
37 "setmetatable", "tonumber", "tostring", "type", "unpack", "xpcall", "select",
38
39 "string", "table", "coroutine", "debug", "file", "io", "lpeg", "math", "os", "package", "bit32", "utf8",
40}
41
42local constants = {
43 "_G", "_VERSION", "_M", "...", "_ENV",
44
45 "__add", "__call", "__concat", "__div", "__idiv", "__eq", "__gc", "__index",
46 "__le", "__lt", "__metatable", "__mode", "__mul", "__newindex",
47 "__pow", "__sub", "__tostring", "__unm", "__len",
48 "__pairs", "__ipairs",
49 "__close",
50 "NaN",
51 "<const>", "<toclose>",
52}
53
54local internals = {
55 "add", "call", "concat", "div", "idiv", "eq", "gc", "index",
56 "le", "lt", "metatable", "mode", "mul", "newindex",
57 "pow", "sub", "tostring", "unm", "len",
58 "pairs", "ipairs",
59 "close",
60}
61
62local depricated = {
63 "arg", "arg.n",
64 "loadstring", "setfenv", "getfenv",
65 "pack",
66}
67
68local csnames = {
69 "commands",
70 "context",
71
72
73 "metafun",
74 "metapost",
75}
76
77local level = nil
78local setlevel = function(_,i,s) level = s return i end
79
80local equals = P("=")^0
81
82local longonestart = P("[[")
83local longonestop = P("]]")
84local longonestring = (1-longonestop)^0
85
86local longtwostart = P("[") * Cmt(equals,setlevel) * P("[")
87local longtwostop = P("]") * equals * P("]")
88
89local sentinels = { } setmetatable(sentinels, { __index = function(t,k) local v = "]" .. k .. "]" t[k] = v return v end })
90
91local longtwostring = P(function(input,index)
92 if level then
93
94 local sentinel = sentinels[level]
95 local _, stop = find(input,sentinel,index,true)
96 return stop and stop + 1 - #sentinel or #input + 1
97 end
98end)
99
100local longtwostring_body = longtwostring
101
102local longtwostring_end = P(function(input,index)
103 if level then
104
105 local sentinel = sentinels[level]
106 local _, stop = find(input,sentinel,index,true)
107 return stop and stop + 1 or #input + 1
108 end
109end)
110
111local longcomment = Cmt(#("[[" + ("[" * C(equals) * "[")), function(input,index,level)
112
113 local sentinel = sentinels[level]
114 local _, stop = find(input,sentinel,index,true)
115 return stop and stop + 1 or #input + 1
116end)
117
118local space = patterns.space
119local any = patterns.any
120local eol = patterns.eol
121local exactmatch = patterns.exactmatch
122local justmatch = patterns.justmatch
123
124local squote = P("'")
125local dquote = P('"')
126local escaped = P("\\") * P(1)
127local dashes = P("--")
128
129local spacing = token(luawhitespace, space^1)
130local rest = token("default", any)
131
132local shortcomment = token("comment", dashes * (1-eol)^0)
133local longcomment = token("comment", dashes * longcomment)
134
135
136
137
138local shortstring = token("quote", dquote)
139 * token("string", (escaped + (1-dquote))^0)
140 * token("quote", dquote)
141 + token("quote", squote)
142 * token("string", (escaped + (1-squote))^0)
143 * token("quote", squote)
144
145
146
147
148
149
150
151
152local string = shortstring
153
154
155lexers.embed(lualexer, stringlexer, token("quote",longtwostart), token("string",longtwostring_body) * token("quote",longtwostring_end))
156
157local integer = P("-")^-1 * (patterns.hexadecimal + patterns.decimal)
158local number = token("number", patterns.float + integer)
159 * (token("error",R("AZ","az","__")^1))^0
160
161
162
163
164
165local utf8character = P(1) * R("\128\191")^1
166local validword = (R("AZ","az","__") + utf8character) * (R("AZ","az","__","09") + utf8character)^0
167local validsuffix = (R("AZ","az") + utf8character) * (R("AZ","az","__","09") + utf8character)^0
168
169local identifier = token("default",validword)
170
171
172
173
174local operator = token("special", S('+-*/%^#=<>;:,{}[]().|~'))
175
176local optionalspace = spacing^0
177local hasargument = #S("{([")
178
179
180
181local gotokeyword = token("keyword", P("goto"))
182 * spacing
183 * token("grouping",validword)
184local gotolabel = token("keyword", P("::"))
185 * (spacing + shortcomment)^0
186 * token("grouping",validword)
187 * (spacing + shortcomment)^0
188 * token("keyword", P("::"))
189
190local p_keywords = exactmatch(keywords)
191local p_functions = exactmatch(functions)
192local p_constants = exactmatch(constants)
193local p_internals = P("__")
194 * exactmatch(internals)
195
196local p_finish = #(1-R("az","AZ","__"))
197
198local p_csnames = justmatch(csnames)
199local p_ctnames = P("ctx") * R("AZ","az","__")^0
200local keyword = token("keyword", p_keywords)
201local builtin = token("plain", p_functions)
202local constant = token("data", p_constants)
203local internal = token("data", p_internals)
204local csname = token("user", p_csnames + p_ctnames)
205 * p_finish * optionalspace * (
206 hasargument
207 + ( token("special", S(".:")) * optionalspace * token("user", validword) )^1
208 )^-1
209
210
211
212local identifier = token("default", validword)
213 * ( optionalspace * token("special", S(".:")) * optionalspace * (
214 token("warning", p_keywords) +
215 token("data", p_internals) +
216 token("default", validword )
217 ) )^0
218
219lualexer.rules = {
220 { "whitespace", spacing },
221 { "keyword", keyword },
222 { "function", builtin },
223 { "constant", constant },
224 { "csname", csname },
225 { "goto", gotokeyword },
226 { "identifier", identifier },
227 { "string", string },
228 { "number", number },
229 { "longcomment", longcomment },
230 { "shortcomment", shortcomment },
231 { "label", gotolabel },
232 { "operator", operator },
233 { "rest", rest },
234}
235
236lualexer.folding = {
237
238 ["if"] = { ["keyword"] = 1 },
239 ["do"] = { ["keyword"] = 1 },
240 ["function"] = { ["keyword"] = 1 },
241 ["repeat"] = { ["keyword"] = 1 },
242 ["until"] = { ["keyword"] = -1 },
243 ["end"] = { ["keyword"] = -1 },
244
245
246
247 ["["] = {
248 ["comment"] = 1,
249
250 },
251 ["]"] = {
252 ["comment"] = -1
253
254 },
255
256
257 ["{"] = { ["special"] = 1 },
258 ["}"] = { ["special"] = -1 },
259}
260
261
262
263local cstoken = R("az","AZ","\127\255") + S("@!?_")
264local texcsname = P("\\") * cstoken^1
265local commentline = P("%") * (1-S("\n\r"))^0
266
267local texcomment = token("comment", Cmt(commentline, function() return directives.cld_inline end))
268
269local longthreestart = P("\\!!bs")
270local longthreestop = P("\\!!es")
271local longthreestring = (1-longthreestop)^0
272
273local texstring = token("quote", longthreestart)
274 * token("string", longthreestring)
275 * token("quote", longthreestop)
276
277local texcommand = token("warning", texcsname)
278
279lualexer.directives = directives
280
281lualexer.rules_cld = {
282 { "whitespace", spacing },
283 { "texstring", texstring },
284 { "texcomment", texcomment },
285 { "texcommand", texcommand },
286 { "keyword", keyword },
287 { "function", builtin },
288 { "csname", csname },
289 { "goto", gotokeyword },
290 { "constant", constant },
291 { "identifier", identifier },
292 { "string", string },
293 { "longcomment", longcomment },
294 { "shortcomment", shortcomment },
295 { "number", number },
296 { "label", gotolabel },
297 { "operator", operator },
298 { "rest", rest },
299}
300
301return lualexer
302 |