-- Copyright 2006-2019 Mitchell mitchell.att.foicica.com. See License.txt. -- Lua LPeg lexer. -- Original written by Peter Odding, 2007/04/04. local lexer = require('lexer') local token, word_match = lexer.token, lexer.word_match local P, R, S = lpeg.P, lpeg.R, lpeg.S local lex = lexer.new('lua') -- Whitespace. lex:add_rule('whitespace', token(lexer.WHITESPACE, lexer.space^1)) -- Keywords. lex:add_rule('keyword', token(lexer.KEYWORD, word_match[[ and break do else elseif end false for function if in local nil not or repeat return then true until while -- Added in 5.2. goto ]])) -- Functions and deprecated functions. local func = token(lexer.FUNCTION, word_match[[ assert collectgarbage dofile error getmetatable ipairs load loadfile next pairs pcall print rawequal rawget rawset require select setmetatable tonumber tostring type xpcall -- Added in 5.2. rawlen ]]) local deprecated_func = token('deprecated_function', word_match[[ -- Deprecated in 5.2. getfenv loadstring module setfenv unpack ]]) lex:add_rule('function', func + deprecated_func) lex:add_style('deprecated_function', lexer.STYLE_FUNCTION..',italics') -- Constants. lex:add_rule('constant', token(lexer.CONSTANT, word_match[[ _G _VERSION -- Added in 5.2. _ENV ]])) -- Libraries and deprecated libraries. local library = token('library', word_match[[ -- Coroutine. coroutine coroutine.create coroutine.resume coroutine.running coroutine.status coroutine.wrap coroutine.yield -- Coroutine added in 5.3. coroutine.isyieldable -- Module. package package.cpath package.loaded package.loadlib package.path package.preload -- Module added in 5.2. package.config package.searchers package.searchpath -- UTF-8 added in 5.3. utf8 utf8.char utf8.charpattern utf8.codepoint utf8.codes utf8.len utf8.offset -- String. string string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper -- String added in 5.3. string.pack string.packsize string.unpack -- Table. table table.concat table.insert table.remove table.sort -- Table added in 5.2. table.pack table.unpack -- Table added in 5.3. table.move -- Math. math math.abs math.acos math.asin math.atan math.ceil math.cos math.deg math.exp math.floor math.fmod math.huge math.log math.max math.min math.modf math.pi math.rad math.random math.randomseed math.sin math.sqrt math.tan -- Math added in 5.3. math.maxinteger math.mininteger math.tointeger math.type math.ult -- IO. io io.close io.flush io.input io.lines io.open io.output io.popen io.read io.stderr io.stdin io.stdout io.tmpfile io.type io.write -- OS. os os.clock os.date os.difftime os.execute os.exit os.getenv os.remove os.rename os.setlocale os.time os.tmpname -- Debug. debug debug.debug debug.gethook debug.getinfo debug.getlocal debug.getmetatable debug.getregistry debug.getupvalue debug.sethook debug.setlocal debug.setmetatable debug.setupvalue debug.traceback -- Debug added in 5.2. debug.getuservalue debug.setuservalue debug.upvalueid debug.upvaluejoin ]]) local deprecated_library = token('deprecated_library', word_match[[ -- Module deprecated in 5.2. package.loaders package.seeall -- Table deprecated in 5.2. table.maxn -- Math deprecated in 5.2. math.log10 -- Math deprecated in 5.3. math.atan2 math.cosh math.frexp math.ldexp math.pow math.sinh math.tanh -- Bit32 deprecated in 5.3. bit32 bit32.arshift bit32.band bit32.bnot bit32.bor bit32.btest bit32.extract bit32.lrotate bit32.lshift bit32.replace bit32.rrotate bit32.rshift bit32.xor -- Debug deprecated in 5.2. debug.getfenv debug.setfenv ]]) lex:add_rule('library', library + deprecated_library) lex:add_style('library', lexer.STYLE_TYPE) lex:add_style('deprecated_library', lexer.STYLE_TYPE..',italics') -- Identifiers. lex:add_rule('identifier', token(lexer.IDENTIFIER, lexer.word)) local longstring = lpeg.Cmt('[' * lpeg.C(P('=')^0) * '[', function(input, index, eq) local _, e = input:find(']'..eq..']', index, true) return (e or #input) + 1 end) -- Strings. lex:add_rule('string', token(lexer.STRING, lexer.delimited_range("'") + lexer.delimited_range('"')) + token('longstring', longstring)) lex:add_style('longstring', lexer.STYLE_STRING) -- Comments. lex:add_rule('comment', token(lexer.COMMENT, '--' * (longstring + lexer.nonnewline^0))) -- Numbers. local lua_integer = P('-')^-1 * (lexer.hex_num + lexer.dec_num) lex:add_rule('number', token(lexer.NUMBER, lexer.float + lua_integer)) -- Labels. lex:add_rule('label', token(lexer.LABEL, '::' * lexer.word * '::')) -- Operators. lex:add_rule('operator', token(lexer.OPERATOR, '..' + S('+-*/%^#=<>&|~;:,.{}[]()'))) -- Fold points. local function fold_longcomment(text, pos, line, s, symbol) if symbol == '[' then if line:find('^%[=*%[', s) then return 1 end elseif symbol == ']' then if line:find('^%]=*%]', s) then return -1 end end return 0 end lex:add_fold_point(lexer.KEYWORD, 'if', 'end') lex:add_fold_point(lexer.KEYWORD, 'do', 'end') lex:add_fold_point(lexer.KEYWORD, 'function', 'end') lex:add_fold_point(lexer.KEYWORD, 'repeat', 'until') lex:add_fold_point(lexer.COMMENT, '[', fold_longcomment) lex:add_fold_point(lexer.COMMENT, ']', fold_longcomment) lex:add_fold_point(lexer.COMMENT, '--', lexer.fold_line_comments('--')) lex:add_fold_point('longstring', '[', ']') lex:add_fold_point(lexer.OPERATOR, '(', ')') lex:add_fold_point(lexer.OPERATOR, '[', ']') lex:add_fold_point(lexer.OPERATOR, '{', '}') return lex