Автор: frs
Дата сообщения: 11.11.2010 04:44
Решил посмотреть, релизацию lua лексеров в scintillua-ru-r1302
Ставил опыты на vb лексере. Приделал пару костылей.
[more=vb.lua]-- Copyright 2006-2010 Mitchell Foral mitchell<att>caladbolg.net. See LICENSE.
-- VisualBasic LPeg lexer
module(..., package.seeall)
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local ws = token('whitespace', space^1)
-- comments
local comment = token('comment', (P("'") + 'REM ') * nonnewline^0)
-- strings
local string = token('string', delimited_range('"', nil, true, false, '\n'))
-- numbers
local number = token('number', (float + integer) * S('LlUuFf')^-2)
-- keywords
local keyword = token('keyword', word_match(word_list{
-- control
'If', 'Then', 'Else', 'ElseIf', 'EndIf', 'While', 'Wend', 'For', 'To', 'Each',
'In', 'Step', 'Case', 'Select', 'EndSelect', 'Return', 'Continue', 'Do',
'Until', 'Loop', 'Next', 'With', 'Exit',
-- operators
'Mod', 'And', 'Not', 'Or', 'Xor', 'Is',
-- storage types
'Call', 'Class', 'Const', 'Dim', 'Redim', 'Function', 'Sub', 'Property',
'End', 'Set', 'Let', 'Get', 'New', 'Randomize',
-- storage modifiers
'Private', 'Public', 'Default', 'Global',
-- constants
'Empty', 'False', 'Nothing', 'Null', 'True'
},true),false,true))
-- types
local type = token('type', word_match(word_list{
'Boolean', 'Byte', 'Char', 'Date', 'Decimal', 'Double', 'Long', 'Object',
'Short', 'Single', 'String'
},true),false,true))
-- identifier
local identifier = token('identifier', word)
-- operators
local operator = token('operator', S('=><+-*^&:.,_();\\/'))
function LoadTokens()
local vb = vb
add_token(vb, 'whitespace', ws)
add_token(vb, 'keyword', keyword)
add_token(vb, 'type', type)
add_token(vb, 'comment', comment)
add_token(vb, 'identifier', identifier)
add_token(vb, 'string', string)
add_token(vb, 'number', number)
add_token(vb, 'operator', operator)
add_token(vb, 'any_char', any_char)
-- embedding VB in another language
if hypertext then
local html = hypertext
local tag = html.TokenPatterns.tag
local case_insensitive = html.case_insensitive_tags
-- search for something of the form <script language="vbscript">
local script_element = word_match(word_list{'script'}, nil, case_insensitive_tags)
start_token = #(P('<') * script_element *
P(function(input, index)
if input:find('[^>]+language%s*=%s*(["\'])vbscript%1') then return index end
end)) * tag -- color tag normally, and tag passes for start_token
end_token = #('</' * script_element * ws^0 * '>') * tag -- </script>
vb.TokenPatterns.operator = token('operator', S('=>+-*^&:.,_()')) +
'<' * -('/' * script_element)
vb.TokenPatterns.any_char = token('vb_default', any - end_token)
make_embeddable(vb, html, start_token, end_token)
end
end
Fold = require'folder' {
['+'] = {'Function', 'Then', 'Repeat', 'For', 'Sub','Do While','Do Until','Select Case','While','Do'},
['-'] = {'End', 'Until','Next','Loop','Wend'},
['+-'] = {'Else','ElseIf', 'Case'},
types = {'keyword', ['operator']={'{','}'}, ['comment']={'\''}},
true
}[/more] - приделывал фолдинг, внёс чуток правок в ключевые слова (имхо, лучше в будущем их считывать из соответствующих *.properties файлов), внёс независимость подсветки операторов от строчности-заглавности написания, для чего пришлось чуток подправить lexers.lua (на существующие лексеры других языков не повлияет),
[more=lexer.lua]function word_list(word_table,case_insensitive)
local hash = {}
if case_insensitive then
for _, v in ipairs(word_table) do hash[v:lower()] = true end
else
for _, v in ipairs(word_table) do hash[v] = true end
end
return hash
end[/more] - реализация костыльная т.к. в лексере языка приходится дважды указывать case_independance (один раз для списка слов, второй для приведения слов в подсвечиваемом тексте), надо будет позже доработать.