|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.felix |
|
4 ~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexer for the Felix language. |
|
7 |
|
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 from pygments.lexer import RegexLexer, include, bygroups, default, words, \ |
|
13 combined |
|
14 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
15 Number, Punctuation |
|
16 |
|
17 __all__ = ['FelixLexer'] |
|
18 |
|
19 |
|
20 class FelixLexer(RegexLexer): |
|
21 """ |
|
22 For `Felix <http://www.felix-lang.org>`_ source code. |
|
23 |
|
24 .. versionadded:: 1.2 |
|
25 """ |
|
26 |
|
27 name = 'Felix' |
|
28 aliases = ['felix', 'flx'] |
|
29 filenames = ['*.flx', '*.flxh'] |
|
30 mimetypes = ['text/x-felix'] |
|
31 |
|
32 preproc = ( |
|
33 'elif', 'else', 'endif', 'if', 'ifdef', 'ifndef', |
|
34 ) |
|
35 |
|
36 keywords = ( |
|
37 '_', '_deref', 'all', 'as', |
|
38 'assert', 'attempt', 'call', 'callback', 'case', 'caseno', 'cclass', |
|
39 'code', 'compound', 'ctypes', 'do', 'done', 'downto', 'elif', 'else', |
|
40 'endattempt', 'endcase', 'endif', 'endmatch', 'enum', 'except', |
|
41 'exceptions', 'expect', 'finally', 'for', 'forall', 'forget', 'fork', |
|
42 'functor', 'goto', 'ident', 'if', 'incomplete', 'inherit', 'instance', |
|
43 'interface', 'jump', 'lambda', 'loop', 'match', 'module', 'namespace', |
|
44 'new', 'noexpand', 'nonterm', 'obj', 'of', 'open', 'parse', 'raise', |
|
45 'regexp', 'reglex', 'regmatch', 'rename', 'return', 'the', 'then', |
|
46 'to', 'type', 'typecase', 'typedef', 'typematch', 'typeof', 'upto', |
|
47 'when', 'whilst', 'with', 'yield', |
|
48 ) |
|
49 |
|
50 keyword_directives = ( |
|
51 '_gc_pointer', '_gc_type', 'body', 'comment', 'const', 'export', |
|
52 'header', 'inline', 'lval', 'macro', 'noinline', 'noreturn', |
|
53 'package', 'private', 'pod', 'property', 'public', 'publish', |
|
54 'requires', 'todo', 'virtual', 'use', |
|
55 ) |
|
56 |
|
57 keyword_declarations = ( |
|
58 'def', 'let', 'ref', 'val', 'var', |
|
59 ) |
|
60 |
|
61 keyword_types = ( |
|
62 'unit', 'void', 'any', 'bool', |
|
63 'byte', 'offset', |
|
64 'address', 'caddress', 'cvaddress', 'vaddress', |
|
65 'tiny', 'short', 'int', 'long', 'vlong', |
|
66 'utiny', 'ushort', 'vshort', 'uint', 'ulong', 'uvlong', |
|
67 'int8', 'int16', 'int32', 'int64', |
|
68 'uint8', 'uint16', 'uint32', 'uint64', |
|
69 'float', 'double', 'ldouble', |
|
70 'complex', 'dcomplex', 'lcomplex', |
|
71 'imaginary', 'dimaginary', 'limaginary', |
|
72 'char', 'wchar', 'uchar', |
|
73 'charp', 'charcp', 'ucharp', 'ucharcp', |
|
74 'string', 'wstring', 'ustring', |
|
75 'cont', |
|
76 'array', 'varray', 'list', |
|
77 'lvalue', 'opt', 'slice', |
|
78 ) |
|
79 |
|
80 keyword_constants = ( |
|
81 'false', 'true', |
|
82 ) |
|
83 |
|
84 operator_words = ( |
|
85 'and', 'not', 'in', 'is', 'isin', 'or', 'xor', |
|
86 ) |
|
87 |
|
88 name_builtins = ( |
|
89 '_svc', 'while', |
|
90 ) |
|
91 |
|
92 name_pseudo = ( |
|
93 'root', 'self', 'this', |
|
94 ) |
|
95 |
|
96 decimal_suffixes = '([tTsSiIlLvV]|ll|LL|([iIuU])(8|16|32|64))?' |
|
97 |
|
98 tokens = { |
|
99 'root': [ |
|
100 include('whitespace'), |
|
101 |
|
102 # Keywords |
|
103 (words(('axiom', 'ctor', 'fun', 'gen', 'proc', 'reduce', |
|
104 'union'), suffix=r'\b'), |
|
105 Keyword, 'funcname'), |
|
106 (words(('class', 'cclass', 'cstruct', 'obj', 'struct'), suffix=r'\b'), |
|
107 Keyword, 'classname'), |
|
108 (r'(instance|module|typeclass)\b', Keyword, 'modulename'), |
|
109 |
|
110 (words(keywords, suffix=r'\b'), Keyword), |
|
111 (words(keyword_directives, suffix=r'\b'), Name.Decorator), |
|
112 (words(keyword_declarations, suffix=r'\b'), Keyword.Declaration), |
|
113 (words(keyword_types, suffix=r'\b'), Keyword.Type), |
|
114 (words(keyword_constants, suffix=r'\b'), Keyword.Constant), |
|
115 |
|
116 # Operators |
|
117 include('operators'), |
|
118 |
|
119 # Float Literal |
|
120 # -- Hex Float |
|
121 (r'0[xX]([0-9a-fA-F_]*\.[0-9a-fA-F_]+|[0-9a-fA-F_]+)' |
|
122 r'[pP][+\-]?[0-9_]+[lLfFdD]?', Number.Float), |
|
123 # -- DecimalFloat |
|
124 (r'[0-9_]+(\.[0-9_]+[eE][+\-]?[0-9_]+|' |
|
125 r'\.[0-9_]*|[eE][+\-]?[0-9_]+)[lLfFdD]?', Number.Float), |
|
126 (r'\.(0|[1-9][0-9_]*)([eE][+\-]?[0-9_]+)?[lLfFdD]?', |
|
127 Number.Float), |
|
128 |
|
129 # IntegerLiteral |
|
130 # -- Binary |
|
131 (r'0[Bb][01_]+%s' % decimal_suffixes, Number.Bin), |
|
132 # -- Octal |
|
133 (r'0[0-7_]+%s' % decimal_suffixes, Number.Oct), |
|
134 # -- Hexadecimal |
|
135 (r'0[xX][0-9a-fA-F_]+%s' % decimal_suffixes, Number.Hex), |
|
136 # -- Decimal |
|
137 (r'(0|[1-9][0-9_]*)%s' % decimal_suffixes, Number.Integer), |
|
138 |
|
139 # Strings |
|
140 ('([rR][cC]?|[cC][rR])"""', String, 'tdqs'), |
|
141 ("([rR][cC]?|[cC][rR])'''", String, 'tsqs'), |
|
142 ('([rR][cC]?|[cC][rR])"', String, 'dqs'), |
|
143 ("([rR][cC]?|[cC][rR])'", String, 'sqs'), |
|
144 ('[cCfFqQwWuU]?"""', String, combined('stringescape', 'tdqs')), |
|
145 ("[cCfFqQwWuU]?'''", String, combined('stringescape', 'tsqs')), |
|
146 ('[cCfFqQwWuU]?"', String, combined('stringescape', 'dqs')), |
|
147 ("[cCfFqQwWuU]?'", String, combined('stringescape', 'sqs')), |
|
148 |
|
149 # Punctuation |
|
150 (r'[\[\]{}:(),;?]', Punctuation), |
|
151 |
|
152 # Labels |
|
153 (r'[a-zA-Z_]\w*:>', Name.Label), |
|
154 |
|
155 # Identifiers |
|
156 (r'(%s)\b' % '|'.join(name_builtins), Name.Builtin), |
|
157 (r'(%s)\b' % '|'.join(name_pseudo), Name.Builtin.Pseudo), |
|
158 (r'[a-zA-Z_]\w*', Name), |
|
159 ], |
|
160 'whitespace': [ |
|
161 (r'\n', Text), |
|
162 (r'\s+', Text), |
|
163 |
|
164 include('comment'), |
|
165 |
|
166 # Preprocessor |
|
167 (r'#\s*if\s+0', Comment.Preproc, 'if0'), |
|
168 (r'#', Comment.Preproc, 'macro'), |
|
169 ], |
|
170 'operators': [ |
|
171 (r'(%s)\b' % '|'.join(operator_words), Operator.Word), |
|
172 (r'!=|==|<<|>>|\|\||&&|[-~+/*%=<>&^|.$]', Operator), |
|
173 ], |
|
174 'comment': [ |
|
175 (r'//(.*?)\n', Comment.Single), |
|
176 (r'/[*]', Comment.Multiline, 'comment2'), |
|
177 ], |
|
178 'comment2': [ |
|
179 (r'[^/*]', Comment.Multiline), |
|
180 (r'/[*]', Comment.Multiline, '#push'), |
|
181 (r'[*]/', Comment.Multiline, '#pop'), |
|
182 (r'[/*]', Comment.Multiline), |
|
183 ], |
|
184 'if0': [ |
|
185 (r'^\s*#if.*?(?<!\\)\n', Comment, '#push'), |
|
186 (r'^\s*#endif.*?(?<!\\)\n', Comment, '#pop'), |
|
187 (r'.*?\n', Comment), |
|
188 ], |
|
189 'macro': [ |
|
190 include('comment'), |
|
191 (r'(import|include)(\s+)(<[^>]*?>)', |
|
192 bygroups(Comment.Preproc, Text, String), '#pop'), |
|
193 (r'(import|include)(\s+)("[^"]*?")', |
|
194 bygroups(Comment.Preproc, Text, String), '#pop'), |
|
195 (r"(import|include)(\s+)('[^']*?')", |
|
196 bygroups(Comment.Preproc, Text, String), '#pop'), |
|
197 (r'[^/\n]+', Comment.Preproc), |
|
198 # (r'/[*](.|\n)*?[*]/', Comment), |
|
199 # (r'//.*?\n', Comment, '#pop'), |
|
200 (r'/', Comment.Preproc), |
|
201 (r'(?<=\\)\n', Comment.Preproc), |
|
202 (r'\n', Comment.Preproc, '#pop'), |
|
203 ], |
|
204 'funcname': [ |
|
205 include('whitespace'), |
|
206 (r'[a-zA-Z_]\w*', Name.Function, '#pop'), |
|
207 # anonymous functions |
|
208 (r'(?=\()', Text, '#pop'), |
|
209 ], |
|
210 'classname': [ |
|
211 include('whitespace'), |
|
212 (r'[a-zA-Z_]\w*', Name.Class, '#pop'), |
|
213 # anonymous classes |
|
214 (r'(?=\{)', Text, '#pop'), |
|
215 ], |
|
216 'modulename': [ |
|
217 include('whitespace'), |
|
218 (r'\[', Punctuation, ('modulename2', 'tvarlist')), |
|
219 default('modulename2'), |
|
220 ], |
|
221 'modulename2': [ |
|
222 include('whitespace'), |
|
223 (r'([a-zA-Z_]\w*)', Name.Namespace, '#pop:2'), |
|
224 ], |
|
225 'tvarlist': [ |
|
226 include('whitespace'), |
|
227 include('operators'), |
|
228 (r'\[', Punctuation, '#push'), |
|
229 (r'\]', Punctuation, '#pop'), |
|
230 (r',', Punctuation), |
|
231 (r'(with|where)\b', Keyword), |
|
232 (r'[a-zA-Z_]\w*', Name), |
|
233 ], |
|
234 'stringescape': [ |
|
235 (r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' |
|
236 r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape) |
|
237 ], |
|
238 'strings': [ |
|
239 (r'%(\([a-zA-Z0-9]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?' |
|
240 '[hlL]?[diouxXeEfFgGcrs%]', String.Interpol), |
|
241 (r'[^\\\'"%\n]+', String), |
|
242 # quotes, percents and backslashes must be parsed one at a time |
|
243 (r'[\'"\\]', String), |
|
244 # unhandled string formatting sign |
|
245 (r'%', String) |
|
246 # newlines are an error (use "nl" state) |
|
247 ], |
|
248 'nl': [ |
|
249 (r'\n', String) |
|
250 ], |
|
251 'dqs': [ |
|
252 (r'"', String, '#pop'), |
|
253 # included here again for raw strings |
|
254 (r'\\\\|\\"|\\\n', String.Escape), |
|
255 include('strings') |
|
256 ], |
|
257 'sqs': [ |
|
258 (r"'", String, '#pop'), |
|
259 # included here again for raw strings |
|
260 (r"\\\\|\\'|\\\n", String.Escape), |
|
261 include('strings') |
|
262 ], |
|
263 'tdqs': [ |
|
264 (r'"""', String, '#pop'), |
|
265 include('strings'), |
|
266 include('nl') |
|
267 ], |
|
268 'tsqs': [ |
|
269 (r"'''", String, '#pop'), |
|
270 include('strings'), |
|
271 include('nl') |
|
272 ], |
|
273 } |