|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.gdscript |
|
4 ~~~~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexer for GDScript. |
|
7 |
|
8 Modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original |
|
9 python.py. |
|
10 |
|
11 :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. |
|
12 :license: BSD, see LICENSE for details. |
|
13 """ |
|
14 |
|
15 import re |
|
16 |
|
17 from pygments.lexer import RegexLexer, include, bygroups, default, words, \ |
|
18 combined |
|
19 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
20 Number, Punctuation |
|
21 |
|
22 __all__ = ["GDScriptLexer"] |
|
23 |
|
24 line_re = re.compile(".*?\n") |
|
25 |
|
26 |
|
27 class GDScriptLexer(RegexLexer): |
|
28 """ |
|
29 For `GDScript source code <https://www.godotengine.org>`_. |
|
30 """ |
|
31 |
|
32 name = "GDScript" |
|
33 aliases = ["gdscript", "gd"] |
|
34 filenames = ["*.gd"] |
|
35 mimetypes = ["text/x-gdscript", "application/x-gdscript"] |
|
36 |
|
37 def innerstring_rules(ttype): |
|
38 return [ |
|
39 # the old style '%s' % (...) string formatting |
|
40 ( |
|
41 r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?" |
|
42 "[hlL]?[E-GXc-giorsux%]", |
|
43 String.Interpol, |
|
44 ), |
|
45 # backslashes, quotes and formatting signs must be parsed one at a time |
|
46 (r'[^\\\'"%\n]+', ttype), |
|
47 (r'[\'"\\]', ttype), |
|
48 # unhandled string formatting sign |
|
49 (r"%", ttype), |
|
50 # newlines are an error (use "nl" state) |
|
51 ] |
|
52 |
|
53 tokens = { |
|
54 "root": [ |
|
55 (r"\n", Text), |
|
56 ( |
|
57 r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")', |
|
58 bygroups(Text, String.Affix, String.Doc), |
|
59 ), |
|
60 ( |
|
61 r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')", |
|
62 bygroups(Text, String.Affix, String.Doc), |
|
63 ), |
|
64 (r"[^\S\n]+", Text), |
|
65 (r"#.*$", Comment.Single), |
|
66 (r"[]{}:(),;[]", Punctuation), |
|
67 (r"\\\n", Text), |
|
68 (r"\\", Text), |
|
69 (r"(in|and|or|not)\b", Operator.Word), |
|
70 ( |
|
71 r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]", |
|
72 Operator, |
|
73 ), |
|
74 include("keywords"), |
|
75 (r"(func)((?:\s|\\\s)+)", bygroups(Keyword, Text), "funcname"), |
|
76 (r"(class)((?:\s|\\\s)+)", bygroups(Keyword, Text), "classname"), |
|
77 include("builtins"), |
|
78 ( |
|
79 '([rR]|[uUbB][rR]|[rR][uUbB])(""")', |
|
80 bygroups(String.Affix, String.Double), |
|
81 "tdqs", |
|
82 ), |
|
83 ( |
|
84 "([rR]|[uUbB][rR]|[rR][uUbB])(''')", |
|
85 bygroups(String.Affix, String.Single), |
|
86 "tsqs", |
|
87 ), |
|
88 ( |
|
89 '([rR]|[uUbB][rR]|[rR][uUbB])(")', |
|
90 bygroups(String.Affix, String.Double), |
|
91 "dqs", |
|
92 ), |
|
93 ( |
|
94 "([rR]|[uUbB][rR]|[rR][uUbB])(')", |
|
95 bygroups(String.Affix, String.Single), |
|
96 "sqs", |
|
97 ), |
|
98 ( |
|
99 '([uUbB]?)(""")', |
|
100 bygroups(String.Affix, String.Double), |
|
101 combined("stringescape", "tdqs"), |
|
102 ), |
|
103 ( |
|
104 "([uUbB]?)(''')", |
|
105 bygroups(String.Affix, String.Single), |
|
106 combined("stringescape", "tsqs"), |
|
107 ), |
|
108 ( |
|
109 '([uUbB]?)(")', |
|
110 bygroups(String.Affix, String.Double), |
|
111 combined("stringescape", "dqs"), |
|
112 ), |
|
113 ( |
|
114 "([uUbB]?)(')", |
|
115 bygroups(String.Affix, String.Single), |
|
116 combined("stringescape", "sqs"), |
|
117 ), |
|
118 include("name"), |
|
119 include("numbers"), |
|
120 ], |
|
121 "keywords": [ |
|
122 ( |
|
123 words( |
|
124 ( |
|
125 "and", |
|
126 "in", |
|
127 "not", |
|
128 "or", |
|
129 "as", |
|
130 "breakpoint", |
|
131 "class", |
|
132 "class_name", |
|
133 "extends", |
|
134 "is", |
|
135 "func", |
|
136 "setget", |
|
137 "signal", |
|
138 "tool", |
|
139 "const", |
|
140 "enum", |
|
141 "export", |
|
142 "onready", |
|
143 "static", |
|
144 "var", |
|
145 "break", |
|
146 "continue", |
|
147 "if", |
|
148 "elif", |
|
149 "else", |
|
150 "for", |
|
151 "pass", |
|
152 "return", |
|
153 "match", |
|
154 "while", |
|
155 "remote", |
|
156 "master", |
|
157 "puppet", |
|
158 "remotesync", |
|
159 "mastersync", |
|
160 "puppetsync", |
|
161 ), |
|
162 suffix=r"\b", |
|
163 ), |
|
164 Keyword, |
|
165 ), |
|
166 ], |
|
167 "builtins": [ |
|
168 ( |
|
169 words( |
|
170 ( |
|
171 "Color8", |
|
172 "ColorN", |
|
173 "abs", |
|
174 "acos", |
|
175 "asin", |
|
176 "assert", |
|
177 "atan", |
|
178 "atan2", |
|
179 "bytes2var", |
|
180 "ceil", |
|
181 "char", |
|
182 "clamp", |
|
183 "convert", |
|
184 "cos", |
|
185 "cosh", |
|
186 "db2linear", |
|
187 "decimals", |
|
188 "dectime", |
|
189 "deg2rad", |
|
190 "dict2inst", |
|
191 "ease", |
|
192 "exp", |
|
193 "floor", |
|
194 "fmod", |
|
195 "fposmod", |
|
196 "funcref", |
|
197 "hash", |
|
198 "inst2dict", |
|
199 "instance_from_id", |
|
200 "is_inf", |
|
201 "is_nan", |
|
202 "lerp", |
|
203 "linear2db", |
|
204 "load", |
|
205 "log", |
|
206 "max", |
|
207 "min", |
|
208 "nearest_po2", |
|
209 "pow", |
|
210 "preload", |
|
211 "print", |
|
212 "print_stack", |
|
213 "printerr", |
|
214 "printraw", |
|
215 "prints", |
|
216 "printt", |
|
217 "rad2deg", |
|
218 "rand_range", |
|
219 "rand_seed", |
|
220 "randf", |
|
221 "randi", |
|
222 "randomize", |
|
223 "range", |
|
224 "round", |
|
225 "seed", |
|
226 "sign", |
|
227 "sin", |
|
228 "sinh", |
|
229 "sqrt", |
|
230 "stepify", |
|
231 "str", |
|
232 "str2var", |
|
233 "tan", |
|
234 "tan", |
|
235 "tanh", |
|
236 "type_exist", |
|
237 "typeof", |
|
238 "var2bytes", |
|
239 "var2str", |
|
240 "weakref", |
|
241 "yield", |
|
242 ), |
|
243 prefix=r"(?<!\.)", |
|
244 suffix=r"\b", |
|
245 ), |
|
246 Name.Builtin, |
|
247 ), |
|
248 (r"((?<!\.)(self|false|true)|(PI|TAU|NAN|INF)" r")\b", Name.Builtin.Pseudo), |
|
249 ( |
|
250 words( |
|
251 ( |
|
252 "bool", |
|
253 "int", |
|
254 "float", |
|
255 "String", |
|
256 "NodePath", |
|
257 "Vector2", |
|
258 "Rect2", |
|
259 "Transform2D", |
|
260 "Vector3", |
|
261 "Rect3", |
|
262 "Plane", |
|
263 "Quat", |
|
264 "Basis", |
|
265 "Transform", |
|
266 "Color", |
|
267 "RID", |
|
268 "Object", |
|
269 "NodePath", |
|
270 "Dictionary", |
|
271 "Array", |
|
272 "PackedByteArray", |
|
273 "PackedInt32Array", |
|
274 "PackedInt64Array", |
|
275 "PackedFloat32Array", |
|
276 "PackedFloat64Array", |
|
277 "PackedStringArray", |
|
278 "PackedVector2Array", |
|
279 "PackedVector3Array", |
|
280 "PackedColorArray", |
|
281 "null", |
|
282 ), |
|
283 prefix=r"(?<!\.)", |
|
284 suffix=r"\b", |
|
285 ), |
|
286 Name.Builtin.Type, |
|
287 ), |
|
288 ], |
|
289 "numbers": [ |
|
290 (r"(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?", Number.Float), |
|
291 (r"\d+[eE][+-]?[0-9]+j?", Number.Float), |
|
292 (r"0[xX][a-fA-F0-9]+", Number.Hex), |
|
293 (r"\d+j?", Number.Integer), |
|
294 ], |
|
295 "name": [(r"[a-zA-Z_]\w*", Name)], |
|
296 "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")], |
|
297 "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")], |
|
298 "stringescape": [ |
|
299 ( |
|
300 r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' |
|
301 r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})", |
|
302 String.Escape, |
|
303 ) |
|
304 ], |
|
305 "strings-single": innerstring_rules(String.Single), |
|
306 "strings-double": innerstring_rules(String.Double), |
|
307 "dqs": [ |
|
308 (r'"', String.Double, "#pop"), |
|
309 (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings |
|
310 include("strings-double"), |
|
311 ], |
|
312 "sqs": [ |
|
313 (r"'", String.Single, "#pop"), |
|
314 (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings |
|
315 include("strings-single"), |
|
316 ], |
|
317 "tdqs": [ |
|
318 (r'"""', String.Double, "#pop"), |
|
319 include("strings-double"), |
|
320 (r"\n", String.Double), |
|
321 ], |
|
322 "tsqs": [ |
|
323 (r"'''", String.Single, "#pop"), |
|
324 include("strings-single"), |
|
325 (r"\n", String.Single), |
|
326 ], |
|
327 } |
|
328 |
|
329 def analyse_text(text): |
|
330 score = 0.0 |
|
331 |
|
332 if re.search( |
|
333 r"func (_ready|_init|_input|_process|_unhandled_input)", text |
|
334 ): |
|
335 score += 0.8 |
|
336 |
|
337 if re.search( |
|
338 r"(extends |class_name |onready |preload|load|setget|func [^_])", |
|
339 text |
|
340 ): |
|
341 score += 0.4 |
|
342 |
|
343 if re.search(r"(var|const|enum|export|signal|tool)", text): |
|
344 score += 0.2 |
|
345 |
|
346 return min(score, 1.0) |