| """ |
| pygments.lexers.gdscript |
| ~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Lexer for GDScript. |
| |
| Modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original |
| python.py. |
| |
| :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS. |
| :license: BSD, see LICENSE for details. |
| """ |
| |
| import re |
| |
| from pygments.lexer import RegexLexer, include, bygroups, default, words, \ |
| combined |
| from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
| Number, Punctuation, Whitespace |
| |
| __all__ = ["GDScriptLexer"] |
| |
| |
| class GDScriptLexer(RegexLexer): |
| """ |
| For GDScript source code. |
| """ |
| |
| name = "GDScript" |
| url = 'https://www.godotengine.org' |
| aliases = ["gdscript", "gd"] |
| filenames = ["*.gd"] |
| mimetypes = ["text/x-gdscript", "application/x-gdscript"] |
| |
| def innerstring_rules(ttype): |
| return [ |
| # the old style '%s' % (...) string formatting |
| (r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?" |
| "[hlL]?[E-GXc-giorsux%]", |
| String.Interpol), |
| # backslashes, quotes and formatting signs must be parsed one at a time |
| (r'[^\\\'"%\n]+', ttype), |
| (r'[\'"\\]', ttype), |
| # unhandled string formatting sign |
| (r"%", ttype), |
| # newlines are an error (use "nl" state) |
| ] |
| |
| tokens = { |
| "root": [ |
| (r"\n", Whitespace), |
| (r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")', |
| bygroups(Whitespace, String.Affix, String.Doc)), |
| (r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')", |
| bygroups(Whitespace, String.Affix, String.Doc)), |
| (r"[^\S\n]+", Whitespace), |
| (r"#.*$", Comment.Single), |
| (r"[]{}:(),;[]", Punctuation), |
| (r"(\\)(\n)", bygroups(Text, Whitespace)), |
| (r"\\", Text), |
| (r"(in|and|or|not)\b", Operator.Word), |
| (r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]", |
| Operator), |
| include("keywords"), |
| (r"(func)(\s+)", bygroups(Keyword, Whitespace), "funcname"), |
| (r"(class)(\s+)", bygroups(Keyword, Whitespace), "classname"), |
| include("builtins"), |
| ('([rR]|[uUbB][rR]|[rR][uUbB])(""")', |
| bygroups(String.Affix, String.Double), |
| "tdqs"), |
| ("([rR]|[uUbB][rR]|[rR][uUbB])(''')", |
| bygroups(String.Affix, String.Single), |
| "tsqs"), |
| ('([rR]|[uUbB][rR]|[rR][uUbB])(")', |
| bygroups(String.Affix, String.Double), |
| "dqs"), |
| ("([rR]|[uUbB][rR]|[rR][uUbB])(')", |
| bygroups(String.Affix, String.Single), |
| "sqs"), |
| ('([uUbB]?)(""")', |
| bygroups(String.Affix, String.Double), |
| combined("stringescape", "tdqs")), |
| ("([uUbB]?)(''')", |
| bygroups(String.Affix, String.Single), |
| combined("stringescape", "tsqs")), |
| ('([uUbB]?)(")', |
| bygroups(String.Affix, String.Double), |
| combined("stringescape", "dqs")), |
| ("([uUbB]?)(')", |
| bygroups(String.Affix, String.Single), |
| combined("stringescape", "sqs")), |
| include("name"), |
| include("numbers"), |
| ], |
| "keywords": [ |
| (words(("and", "in", "not", "or", "as", "breakpoint", "class", |
| "class_name", "extends", "is", "func", "setget", "signal", |
| "tool", "const", "enum", "export", "onready", "static", |
| "var", "break", "continue", "if", "elif", "else", "for", |
| "pass", "return", "match", "while", "remote", "master", |
| "puppet", "remotesync", "mastersync", "puppetsync"), |
| suffix=r"\b"), Keyword), |
| ], |
| "builtins": [ |
| (words(("Color8", "ColorN", "abs", "acos", "asin", "assert", "atan", |
| "atan2", "bytes2var", "ceil", "char", "clamp", "convert", |
| "cos", "cosh", "db2linear", "decimals", "dectime", "deg2rad", |
| "dict2inst", "ease", "exp", "floor", "fmod", "fposmod", |
| "funcref", "hash", "inst2dict", "instance_from_id", "is_inf", |
| "is_nan", "lerp", "linear2db", "load", "log", "max", "min", |
| "nearest_po2", "pow", "preload", "print", "print_stack", |
| "printerr", "printraw", "prints", "printt", "rad2deg", |
| "rand_range", "rand_seed", "randf", "randi", "randomize", |
| "range", "round", "seed", "sign", "sin", "sinh", "sqrt", |
| "stepify", "str", "str2var", "tan", "tan", "tanh", |
| "type_exist", "typeof", "var2bytes", "var2str", "weakref", |
| "yield"), prefix=r"(?<!\.)", suffix=r"\b"), |
| Name.Builtin), |
| (r"((?<!\.)(self|false|true)|(PI|TAU|NAN|INF)" r")\b", |
| Name.Builtin.Pseudo), |
| (words(("bool", "int", "float", "String", "NodePath", "Vector2", |
| "Rect2", "Transform2D", "Vector3", "Rect3", "Plane", "Quat", |
| "Basis", "Transform", "Color", "RID", "Object", "NodePath", |
| "Dictionary", "Array", "PackedByteArray", "PackedInt32Array", |
| "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array", |
| "PackedStringArray", "PackedVector2Array", "PackedVector3Array", |
| "PackedColorArray", "null", "void"), |
| prefix=r"(?<!\.)", suffix=r"\b"), |
| Name.Builtin.Type), |
| ], |
| "numbers": [ |
| (r"(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?", Number.Float), |
| (r"\d+[eE][+-]?[0-9]+j?", Number.Float), |
| (r"0[xX][a-fA-F0-9]+", Number.Hex), |
| (r"\d+j?", Number.Integer), |
| ], |
| "name": [(r"[a-zA-Z_]\w*", Name)], |
| "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")], |
| "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")], |
| "stringescape": [ |
| ( |
| r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' |
| r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})", |
| String.Escape, |
| ) |
| ], |
| "strings-single": innerstring_rules(String.Single), |
| "strings-double": innerstring_rules(String.Double), |
| "dqs": [ |
| (r'"', String.Double, "#pop"), |
| (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings |
| include("strings-double"), |
| ], |
| "sqs": [ |
| (r"'", String.Single, "#pop"), |
| (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings |
| include("strings-single"), |
| ], |
| "tdqs": [ |
| (r'"""', String.Double, "#pop"), |
| include("strings-double"), |
| (r"\n", Whitespace), |
| ], |
| "tsqs": [ |
| (r"'''", String.Single, "#pop"), |
| include("strings-single"), |
| (r"\n", Whitespace), |
| ], |
| } |
| |
| def analyse_text(text): |
| score = 0.0 |
| |
| if re.search( |
| r"func (_ready|_init|_input|_process|_unhandled_input)", text |
| ): |
| score += 0.8 |
| |
| if re.search( |
| r"(extends |class_name |onready |preload|load|setget|func [^_])", |
| text |
| ): |
| score += 0.4 |
| |
| if re.search(r"(var|const|enum|export|signal|tool)", text): |
| score += 0.2 |
| |
| return min(score, 1.0) |