vim modifications
[cinan.git] / .vim / autoload / omni / cpp / tokenizer.vim
blob16e0be2307cacb6c1967b4afc0ce92bb5257f756
1 " Description: Omni completion tokenizer
2 " Maintainer:  Vissale NEANG
3 " Last Change: 26 sept. 2007
4 " TODO: Generic behaviour for Tokenize()
6 " From the C++ BNF
7 let s:cppKeyword = ['asm', 'auto', 'bool', 'break', 'case', 'catch', 'char', 'class', 'const', 'const_cast', 'continue', 'default', 'delete', 'do', 'double', 'dynamic_cast', 'else', 'enum', 'explicit', 'export', 'extern', 'false', 'float', 'for', 'friend', 'goto', 'if', 'inline', 'int', 'long', 'mutable', 'namespace', 'new', 'operator', 'private', 'protected', 'public', 'register', 'reinterpret_cast', 'return', 'short', 'signed', 'sizeof', 'static', 'static_cast', 'struct', 'switch', 'template', 'this', 'throw', 'true', 'try', 'typedef', 'typeid', 'typename', 'union', 'unsigned', 'using', 'virtual', 'void', 'volatile', 'wchar_t', 'while', 'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not', 'not_eq', 'or', 'or_eq', 'xor', 'xor_eq']
9 let s:reCppKeyword = '\C\<'.join(s:cppKeyword, '\>\|\<').'\>'
11 " The order of items in this list is very important because we use this list to build a regular
12 " expression (see below) for tokenization
13 let s:cppOperatorPunctuator = ['->*', '->', '--', '-=', '-', '!=', '!', '##', '#', '%:%:', '%=', '%>', '%:', '%', '&&', '&=', '&', '(', ')', '*=', '*', ',', '...', '.*', '.', '/=', '/', '::', ':>', ':', ';', '?', '[', ']', '^=', '^', '{', '||', '|=', '|', '}', '~', '++', '+=', '+', '<<=', '<%', '<:', '<<', '<=', '<', '==', '=', '>>=', '>>', '>=', '>']
15 " We build the regexp for the tokenizer
16 let s:reCComment = '\/\*\|\*\/'
17 let s:reCppComment = '\/\/'
18 let s:reComment = s:reCComment.'\|'.s:reCppComment
19 let s:reCppOperatorOrPunctuator = escape(join(s:cppOperatorPunctuator, '\|'), '*./^~[]')
22 " Tokenize a c++ code
23 " a token is dictionary where keys are:
24 "   -   kind = cppKeyword|cppWord|cppOperatorPunctuator|unknown|cComment|cppComment|cppDigit
25 "   -   value = 'something'
26 "   Note: a cppWord is any word that is not a cpp keyword
27 function! omni#cpp#tokenizer#Tokenize(szCode)
28     let result = []
30     " The regexp to find a token, a token is a keyword, word or
31     " c++ operator or punctuator. To work properly we have to put 
32     " spaces and tabs to our regexp.
33     let reTokenSearch = '\(\w\+\)\|\s\+\|'.s:reComment.'\|'.s:reCppOperatorOrPunctuator
34     " eg: 'using namespace std;'
35     "      ^    ^
36     "  start=0 end=5
37     let startPos = 0
38     let endPos = matchend(a:szCode, reTokenSearch)
39     let len = endPos-startPos
40     while endPos!=-1
41         " eg: 'using namespace std;'
42         "      ^    ^
43         "  start=0 end=5
44         "  token = 'using'
45         " We also remove space and tabs
46         let token = substitute(strpart(a:szCode, startPos, len), '\s', '', 'g')
48         " eg: 'using namespace std;'
49         "           ^         ^
50         "       start=5     end=15
51         let startPos = endPos
52         let endPos = matchend(a:szCode, reTokenSearch, startPos)
53         let len = endPos-startPos
55         " It the token is empty we continue
56         if token==''
57             continue
58         endif
60         " Building the token
61         let resultToken = {'kind' : 'unknown', 'value' : token}
63         " Classify the token
64         if token =~ '^\d\+'
65             " It's a digit
66             let resultToken.kind = 'cppDigit'
67         elseif token=~'^\w\+$'
68             " It's a word
69             let resultToken.kind = 'cppWord'
71             " But maybe it's a c++ keyword
72             if match(token, s:reCppKeyword)>=0
73                 let resultToken.kind = 'cppKeyword'
74             endif
75         else
76             if match(token, s:reComment)>=0
77                 if index(['/*','*/'],token)>=0
78                     let resultToken.kind = 'cComment'
79                 else
80                     let resultToken.kind = 'cppComment'
81                 endif
82             else
83                 " It's an operator
84                 let resultToken.kind = 'cppOperatorPunctuator'
85             endif
86         endif
88         " We have our token, let's add it to the result list
89         call extend(result, [resultToken])
90     endwhile
92     return result
93 endfunc