|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.c_like |
|
4 ~~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexers for other C-like languages. |
|
7 |
|
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 import re |
|
13 |
|
14 from pygments.lexer import RegexLexer, include, bygroups, inherit, words, \ |
|
15 default |
|
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
17 Number, Punctuation |
|
18 |
|
19 from pygments.lexers.c_cpp import CLexer, CppLexer |
|
20 from pygments.lexers import _mql_builtins |
|
21 |
|
22 __all__ = ['PikeLexer', 'NesCLexer', 'ClayLexer', 'ECLexer', 'ValaLexer', |
|
23 'CudaLexer', 'SwigLexer', 'MqlLexer'] |
|
24 |
|
25 |
|
26 class PikeLexer(CppLexer): |
|
27 """ |
|
28 For `Pike <http://pike.lysator.liu.se/>`_ source code. |
|
29 |
|
30 .. versionadded:: 2.0 |
|
31 """ |
|
32 name = 'Pike' |
|
33 aliases = ['pike'] |
|
34 filenames = ['*.pike', '*.pmod'] |
|
35 mimetypes = ['text/x-pike'] |
|
36 |
|
37 tokens = { |
|
38 'statements': [ |
|
39 (words(( |
|
40 'catch', 'new', 'private', 'protected', 'public', 'gauge', |
|
41 'throw', 'throws', 'class', 'interface', 'implement', 'abstract', 'extends', 'from', |
|
42 'this', 'super', 'constant', 'final', 'static', 'import', 'use', 'extern', |
|
43 'inline', 'proto', 'break', 'continue', 'if', 'else', 'for', |
|
44 'while', 'do', 'switch', 'case', 'as', 'in', 'version', 'return', 'true', 'false', 'null', |
|
45 '__VERSION__', '__MAJOR__', '__MINOR__', '__BUILD__', '__REAL_VERSION__', |
|
46 '__REAL_MAJOR__', '__REAL_MINOR__', '__REAL_BUILD__', '__DATE__', '__TIME__', |
|
47 '__FILE__', '__DIR__', '__LINE__', '__AUTO_BIGNUM__', '__NT__', '__PIKE__', |
|
48 '__amigaos__', '_Pragma', 'static_assert', 'defined', 'sscanf'), suffix=r'\b'), |
|
49 Keyword), |
|
50 (r'(bool|int|long|float|short|double|char|string|object|void|mapping|' |
|
51 r'array|multiset|program|function|lambda|mixed|' |
|
52 r'[a-z_][a-z0-9_]*_t)\b', |
|
53 Keyword.Type), |
|
54 (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'), |
|
55 (r'[~!%^&*+=|?:<>/@-]', Operator), |
|
56 inherit, |
|
57 ], |
|
58 'classname': [ |
|
59 (r'[a-zA-Z_]\w*', Name.Class, '#pop'), |
|
60 # template specification |
|
61 (r'\s*(?=>)', Text, '#pop'), |
|
62 ], |
|
63 } |
|
64 |
|
65 |
|
66 class NesCLexer(CLexer): |
|
67 """ |
|
68 For `nesC <https://github.com/tinyos/nesc>`_ source code with preprocessor |
|
69 directives. |
|
70 |
|
71 .. versionadded:: 2.0 |
|
72 """ |
|
73 name = 'nesC' |
|
74 aliases = ['nesc'] |
|
75 filenames = ['*.nc'] |
|
76 mimetypes = ['text/x-nescsrc'] |
|
77 |
|
78 tokens = { |
|
79 'statements': [ |
|
80 (words(( |
|
81 'abstract', 'as', 'async', 'atomic', 'call', 'command', 'component', |
|
82 'components', 'configuration', 'event', 'extends', 'generic', |
|
83 'implementation', 'includes', 'interface', 'module', 'new', 'norace', |
|
84 'post', 'provides', 'signal', 'task', 'uses'), suffix=r'\b'), |
|
85 Keyword), |
|
86 (words(('nx_struct', 'nx_union', 'nx_int8_t', 'nx_int16_t', 'nx_int32_t', |
|
87 'nx_int64_t', 'nx_uint8_t', 'nx_uint16_t', 'nx_uint32_t', |
|
88 'nx_uint64_t'), suffix=r'\b'), |
|
89 Keyword.Type), |
|
90 inherit, |
|
91 ], |
|
92 } |
|
93 |
|
94 |
|
95 class ClayLexer(RegexLexer): |
|
96 """ |
|
97 For `Clay <http://claylabs.com/clay/>`_ source. |
|
98 |
|
99 .. versionadded:: 2.0 |
|
100 """ |
|
101 name = 'Clay' |
|
102 filenames = ['*.clay'] |
|
103 aliases = ['clay'] |
|
104 mimetypes = ['text/x-clay'] |
|
105 tokens = { |
|
106 'root': [ |
|
107 (r'\s', Text), |
|
108 (r'//.*?$', Comment.Singleline), |
|
109 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline), |
|
110 (r'\b(public|private|import|as|record|variant|instance' |
|
111 r'|define|overload|default|external|alias' |
|
112 r'|rvalue|ref|forward|inline|noinline|forceinline' |
|
113 r'|enum|var|and|or|not|if|else|goto|return|while' |
|
114 r'|switch|case|break|continue|for|in|true|false|try|catch|throw' |
|
115 r'|finally|onerror|staticassert|eval|when|newtype' |
|
116 r'|__FILE__|__LINE__|__COLUMN__|__ARG__' |
|
117 r')\b', Keyword), |
|
118 (r'[~!%^&*+=|:<>/-]', Operator), |
|
119 (r'[#(){}\[\],;.]', Punctuation), |
|
120 (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex), |
|
121 (r'\d+[LlUu]*', Number.Integer), |
|
122 (r'\b(true|false)\b', Name.Builtin), |
|
123 (r'(?i)[a-z_?][\w?]*', Name), |
|
124 (r'"""', String, 'tdqs'), |
|
125 (r'"', String, 'dqs'), |
|
126 ], |
|
127 'strings': [ |
|
128 (r'(?i)\\(x[0-9a-f]{2}|.)', String.Escape), |
|
129 (r'.', String), |
|
130 ], |
|
131 'nl': [ |
|
132 (r'\n', String), |
|
133 ], |
|
134 'dqs': [ |
|
135 (r'"', String, '#pop'), |
|
136 include('strings'), |
|
137 ], |
|
138 'tdqs': [ |
|
139 (r'"""', String, '#pop'), |
|
140 include('strings'), |
|
141 include('nl'), |
|
142 ], |
|
143 } |
|
144 |
|
145 |
|
146 class ECLexer(CLexer): |
|
147 """ |
|
148 For eC source code with preprocessor directives. |
|
149 |
|
150 .. versionadded:: 1.5 |
|
151 """ |
|
152 name = 'eC' |
|
153 aliases = ['ec'] |
|
154 filenames = ['*.ec', '*.eh'] |
|
155 mimetypes = ['text/x-echdr', 'text/x-ecsrc'] |
|
156 |
|
157 tokens = { |
|
158 'statements': [ |
|
159 (words(( |
|
160 'virtual', 'class', 'private', 'public', 'property', 'import', |
|
161 'delete', 'new', 'new0', 'renew', 'renew0', 'define', 'get', |
|
162 'set', 'remote', 'dllexport', 'dllimport', 'stdcall', 'subclass', |
|
163 '__on_register_module', 'namespace', 'using', 'typed_object', |
|
164 'any_object', 'incref', 'register', 'watch', 'stopwatching', 'firewatchers', |
|
165 'watchable', 'class_designer', 'class_fixed', 'class_no_expansion', 'isset', |
|
166 'class_default_property', 'property_category', 'class_data', |
|
167 'class_property', 'thisclass', 'dbtable', 'dbindex', |
|
168 'database_open', 'dbfield'), suffix=r'\b'), Keyword), |
|
169 (words(('uint', 'uint16', 'uint32', 'uint64', 'bool', 'byte', |
|
170 'unichar', 'int64'), suffix=r'\b'), |
|
171 Keyword.Type), |
|
172 (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'), |
|
173 (r'(null|value|this)\b', Name.Builtin), |
|
174 inherit, |
|
175 ], |
|
176 'classname': [ |
|
177 (r'[a-zA-Z_]\w*', Name.Class, '#pop'), |
|
178 # template specification |
|
179 (r'\s*(?=>)', Text, '#pop'), |
|
180 ], |
|
181 } |
|
182 |
|
183 |
|
184 class ValaLexer(RegexLexer): |
|
185 """ |
|
186 For Vala source code with preprocessor directives. |
|
187 |
|
188 .. versionadded:: 1.1 |
|
189 """ |
|
190 name = 'Vala' |
|
191 aliases = ['vala', 'vapi'] |
|
192 filenames = ['*.vala', '*.vapi'] |
|
193 mimetypes = ['text/x-vala'] |
|
194 |
|
195 tokens = { |
|
196 'whitespace': [ |
|
197 (r'^\s*#if\s+0', Comment.Preproc, 'if0'), |
|
198 (r'\n', Text), |
|
199 (r'\s+', Text), |
|
200 (r'\\\n', Text), # line continuation |
|
201 (r'//(\n|(.|\n)*?[^\\]\n)', Comment.Single), |
|
202 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline), |
|
203 ], |
|
204 'statements': [ |
|
205 (r'[L@]?"', String, 'string'), |
|
206 (r"L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", |
|
207 String.Char), |
|
208 (r'(?s)""".*?"""', String), # verbatim strings |
|
209 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?', Number.Float), |
|
210 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), |
|
211 (r'0x[0-9a-fA-F]+[Ll]?', Number.Hex), |
|
212 (r'0[0-7]+[Ll]?', Number.Oct), |
|
213 (r'\d+[Ll]?', Number.Integer), |
|
214 (r'[~!%^&*+=|?:<>/-]', Operator), |
|
215 (r'(\[)(Compact|Immutable|(?:Boolean|Simple)Type)(\])', |
|
216 bygroups(Punctuation, Name.Decorator, Punctuation)), |
|
217 # TODO: "correctly" parse complex code attributes |
|
218 (r'(\[)(CCode|(?:Integer|Floating)Type)', |
|
219 bygroups(Punctuation, Name.Decorator)), |
|
220 (r'[()\[\],.]', Punctuation), |
|
221 (words(( |
|
222 'as', 'base', 'break', 'case', 'catch', 'construct', 'continue', |
|
223 'default', 'delete', 'do', 'else', 'enum', 'finally', 'for', |
|
224 'foreach', 'get', 'if', 'in', 'is', 'lock', 'new', 'out', 'params', |
|
225 'return', 'set', 'sizeof', 'switch', 'this', 'throw', 'try', |
|
226 'typeof', 'while', 'yield'), suffix=r'\b'), |
|
227 Keyword), |
|
228 (words(( |
|
229 'abstract', 'const', 'delegate', 'dynamic', 'ensures', 'extern', |
|
230 'inline', 'internal', 'override', 'owned', 'private', 'protected', |
|
231 'public', 'ref', 'requires', 'signal', 'static', 'throws', 'unowned', |
|
232 'var', 'virtual', 'volatile', 'weak', 'yields'), suffix=r'\b'), |
|
233 Keyword.Declaration), |
|
234 (r'(namespace|using)(\s+)', bygroups(Keyword.Namespace, Text), |
|
235 'namespace'), |
|
236 (r'(class|errordomain|interface|struct)(\s+)', |
|
237 bygroups(Keyword.Declaration, Text), 'class'), |
|
238 (r'(\.)([a-zA-Z_]\w*)', |
|
239 bygroups(Operator, Name.Attribute)), |
|
240 # void is an actual keyword, others are in glib-2.0.vapi |
|
241 (words(( |
|
242 'void', 'bool', 'char', 'double', 'float', 'int', 'int8', 'int16', |
|
243 'int32', 'int64', 'long', 'short', 'size_t', 'ssize_t', 'string', |
|
244 'time_t', 'uchar', 'uint', 'uint8', 'uint16', 'uint32', 'uint64', |
|
245 'ulong', 'unichar', 'ushort'), suffix=r'\b'), |
|
246 Keyword.Type), |
|
247 (r'(true|false|null)\b', Name.Builtin), |
|
248 ('[a-zA-Z_]\w*', Name), |
|
249 ], |
|
250 'root': [ |
|
251 include('whitespace'), |
|
252 default('statement'), |
|
253 ], |
|
254 'statement': [ |
|
255 include('whitespace'), |
|
256 include('statements'), |
|
257 ('[{}]', Punctuation), |
|
258 (';', Punctuation, '#pop'), |
|
259 ], |
|
260 'string': [ |
|
261 (r'"', String, '#pop'), |
|
262 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), |
|
263 (r'[^\\"\n]+', String), # all other characters |
|
264 (r'\\\n', String), # line continuation |
|
265 (r'\\', String), # stray backslash |
|
266 ], |
|
267 'if0': [ |
|
268 (r'^\s*#if.*?(?<!\\)\n', Comment.Preproc, '#push'), |
|
269 (r'^\s*#el(?:se|if).*\n', Comment.Preproc, '#pop'), |
|
270 (r'^\s*#endif.*?(?<!\\)\n', Comment.Preproc, '#pop'), |
|
271 (r'.*?\n', Comment), |
|
272 ], |
|
273 'class': [ |
|
274 (r'[a-zA-Z_]\w*', Name.Class, '#pop') |
|
275 ], |
|
276 'namespace': [ |
|
277 (r'[a-zA-Z_][\w.]*', Name.Namespace, '#pop') |
|
278 ], |
|
279 } |
|
280 |
|
281 |
|
282 class CudaLexer(CLexer): |
|
283 """ |
|
284 For NVIDIA `CUDA™ <http://developer.nvidia.com/category/zone/cuda-zone>`_ |
|
285 source. |
|
286 |
|
287 .. versionadded:: 1.6 |
|
288 """ |
|
289 name = 'CUDA' |
|
290 filenames = ['*.cu', '*.cuh'] |
|
291 aliases = ['cuda', 'cu'] |
|
292 mimetypes = ['text/x-cuda'] |
|
293 |
|
294 function_qualifiers = set(('__device__', '__global__', '__host__', |
|
295 '__noinline__', '__forceinline__')) |
|
296 variable_qualifiers = set(('__device__', '__constant__', '__shared__', |
|
297 '__restrict__')) |
|
298 vector_types = set(('char1', 'uchar1', 'char2', 'uchar2', 'char3', 'uchar3', |
|
299 'char4', 'uchar4', 'short1', 'ushort1', 'short2', 'ushort2', |
|
300 'short3', 'ushort3', 'short4', 'ushort4', 'int1', 'uint1', |
|
301 'int2', 'uint2', 'int3', 'uint3', 'int4', 'uint4', 'long1', |
|
302 'ulong1', 'long2', 'ulong2', 'long3', 'ulong3', 'long4', |
|
303 'ulong4', 'longlong1', 'ulonglong1', 'longlong2', |
|
304 'ulonglong2', 'float1', 'float2', 'float3', 'float4', |
|
305 'double1', 'double2', 'dim3')) |
|
306 variables = set(('gridDim', 'blockIdx', 'blockDim', 'threadIdx', 'warpSize')) |
|
307 functions = set(('__threadfence_block', '__threadfence', '__threadfence_system', |
|
308 '__syncthreads', '__syncthreads_count', '__syncthreads_and', |
|
309 '__syncthreads_or')) |
|
310 execution_confs = set(('<<<', '>>>')) |
|
311 |
|
312 def get_tokens_unprocessed(self, text): |
|
313 for index, token, value in CLexer.get_tokens_unprocessed(self, text): |
|
314 if token is Name: |
|
315 if value in self.variable_qualifiers: |
|
316 token = Keyword.Type |
|
317 elif value in self.vector_types: |
|
318 token = Keyword.Type |
|
319 elif value in self.variables: |
|
320 token = Name.Builtin |
|
321 elif value in self.execution_confs: |
|
322 token = Keyword.Pseudo |
|
323 elif value in self.function_qualifiers: |
|
324 token = Keyword.Reserved |
|
325 elif value in self.functions: |
|
326 token = Name.Function |
|
327 yield index, token, value |
|
328 |
|
329 |
|
330 class SwigLexer(CppLexer): |
|
331 """ |
|
332 For `SWIG <http://www.swig.org/>`_ source code. |
|
333 |
|
334 .. versionadded:: 2.0 |
|
335 """ |
|
336 name = 'SWIG' |
|
337 aliases = ['swig'] |
|
338 filenames = ['*.swg', '*.i'] |
|
339 mimetypes = ['text/swig'] |
|
340 priority = 0.04 # Lower than C/C++ and Objective C/C++ |
|
341 |
|
342 tokens = { |
|
343 'statements': [ |
|
344 # SWIG directives |
|
345 (r'(%[a-z_][a-z0-9_]*)', Name.Function), |
|
346 # Special variables |
|
347 ('\$\**\&?\w+', Name), |
|
348 # Stringification / additional preprocessor directives |
|
349 (r'##*[a-zA-Z_]\w*', Comment.Preproc), |
|
350 inherit, |
|
351 ], |
|
352 } |
|
353 |
|
354 # This is a far from complete set of SWIG directives |
|
355 swig_directives = set(( |
|
356 # Most common directives |
|
357 '%apply', '%define', '%director', '%enddef', '%exception', '%extend', |
|
358 '%feature', '%fragment', '%ignore', '%immutable', '%import', '%include', |
|
359 '%inline', '%insert', '%module', '%newobject', '%nspace', '%pragma', |
|
360 '%rename', '%shared_ptr', '%template', '%typecheck', '%typemap', |
|
361 # Less common directives |
|
362 '%arg', '%attribute', '%bang', '%begin', '%callback', '%catches', '%clear', |
|
363 '%constant', '%copyctor', '%csconst', '%csconstvalue', '%csenum', |
|
364 '%csmethodmodifiers', '%csnothrowexception', '%default', '%defaultctor', |
|
365 '%defaultdtor', '%defined', '%delete', '%delobject', '%descriptor', |
|
366 '%exceptionclass', '%exceptionvar', '%extend_smart_pointer', '%fragments', |
|
367 '%header', '%ifcplusplus', '%ignorewarn', '%implicit', '%implicitconv', |
|
368 '%init', '%javaconst', '%javaconstvalue', '%javaenum', '%javaexception', |
|
369 '%javamethodmodifiers', '%kwargs', '%luacode', '%mutable', '%naturalvar', |
|
370 '%nestedworkaround', '%perlcode', '%pythonabc', '%pythonappend', |
|
371 '%pythoncallback', '%pythoncode', '%pythondynamic', '%pythonmaybecall', |
|
372 '%pythonnondynamic', '%pythonprepend', '%refobject', '%shadow', '%sizeof', |
|
373 '%trackobjects', '%types', '%unrefobject', '%varargs', '%warn', |
|
374 '%warnfilter')) |
|
375 |
|
376 def analyse_text(text): |
|
377 rv = 0 |
|
378 # Search for SWIG directives, which are conventionally at the beginning of |
|
379 # a line. The probability of them being within a line is low, so let another |
|
380 # lexer win in this case. |
|
381 matches = re.findall(r'^\s*(%[a-z_][a-z0-9_]*)', text, re.M) |
|
382 for m in matches: |
|
383 if m in SwigLexer.swig_directives: |
|
384 rv = 0.98 |
|
385 break |
|
386 else: |
|
387 rv = 0.91 # Fraction higher than MatlabLexer |
|
388 return rv |
|
389 |
|
390 |
|
391 class MqlLexer(CppLexer): |
|
392 """ |
|
393 For `MQL4 <http://docs.mql4.com/>`_ and |
|
394 `MQL5 <http://www.mql5.com/en/docs>`_ source code. |
|
395 |
|
396 .. versionadded:: 2.0 |
|
397 """ |
|
398 name = 'MQL' |
|
399 aliases = ['mql', 'mq4', 'mq5', 'mql4', 'mql5'] |
|
400 filenames = ['*.mq4', '*.mq5', '*.mqh'] |
|
401 mimetypes = ['text/x-mql'] |
|
402 |
|
403 tokens = { |
|
404 'statements': [ |
|
405 (words(_mql_builtins.keywords, suffix=r'\b'), Keyword), |
|
406 (words(_mql_builtins.c_types, suffix=r'\b'), Keyword.Type), |
|
407 (words(_mql_builtins.types, suffix=r'\b'), Name.Function), |
|
408 (words(_mql_builtins.constants, suffix=r'\b'), Name.Constant), |
|
409 (words(_mql_builtins.colors, prefix='(clr)?', suffix=r'\b'), |
|
410 Name.Constant), |
|
411 inherit, |
|
412 ], |
|
413 } |