Автор: 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 (один раз для списка слов, второй для приведения слов в подсвечиваемом тексте), надо будет позже доработать.