{"id":15036274,"url":"https://github.com/elamaunt/gdshrapt","last_synced_at":"2025-04-09T23:23:46.424Z","repository":{"id":40667269,"uuid":"369616509","full_name":"elamaunt/GDShrapt","owner":"elamaunt","description":"GDShrapt is object-oriented one-pass parser of GDScript programming language.","archived":false,"fork":false,"pushed_at":"2024-06-16T19:59:42.000Z","size":872,"stargazers_count":38,"open_issues_count":2,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-13T14:22:08.795Z","etag":null,"topics":["converter","csharp","csharp-library","dot-net","gdscript","gdshrapt","godot","godot-engine","godot-engine-editor","lexer","library","parser","plugin","reader","rewriter","shrapt","tool","translator"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elamaunt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":"elamaunt","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2021-05-21T18:03:19.000Z","updated_at":"2024-09-08T03:58:40.000Z","dependencies_parsed_at":"2023-12-23T15:29:27.585Z","dependency_job_id":"9c345b35-098d-4f70-9aa7-2a186af95e68","html_url":"https://github.com/elamaunt/GDShrapt","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elamaunt%2FGDShrapt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elamaunt%2FGDShrapt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elamaunt%2FGDShrapt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elamaunt%2FGDShrapt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elamaunt","download_url":"https://codeload.github.com/elamaunt/GDShrapt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248126982,"owners_count":21052124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["converter","csharp","csharp-library","dot-net","gdscript","gdshrapt","godot","godot-engine","godot-engine-editor","lexer","library","parser","plugin","reader","rewriter","shrapt","tool","translator"],"created_at":"2024-09-24T20:30:40.857Z","updated_at":"2025-04-09T23:23:45.998Z","avatar_url":"https://github.com/elamaunt.png","language":"C#","funding_links":["https://patreon.com/elamaunt"],"categories":[],"sub_categories":[],"readme":"# GDShrapt\n\nGDShrapt is an object-oriented one-pass parser of GDScript 2.0. Now the main goal is a production-ready parser, lexical analyzer. \nThe project written in C# and free to use. \nGDScript is the main language of [Godot Engine](https://github.com/godotengine/godot)\n\n**The project is created on personal initiative and on enthusiasm.**\n\n## GDShrapt.Reader\n\nGDShrapt.Reader allows to build a lexical tree or generate a new code from scratch.\n\n### How to install\n\nCurrently the latest **4.3.2-alpha version** from [Nuget](https://www.nuget.org/packages/GDShrapt.Reader).\n\nInstallation from Nuget console:\n```\nInstall-Package GDShrapt.Reader -Version 4.3.2-alpha\n```\n## Capabilities, plan and what can be parsed\n\n| Capability  | Is completed |\n| ------------- | ------------- |\n| One pass parsing | YES |\n| Lexical tree structure | YES |\n| Class declaration parsing | YES |\n| Methods declaration parsing | YES |\n| Enums parsing | YES |\n| Atributes declaration parsing | YES |\n| Variables declaration parsing | YES |\n| Export block parsing | YES |\n| Arrays parsing | YES |\n| Dictionary parsing | YES |\n| 'Match' statement parsing | YES |\n| 'For' statement parsing | YES |\n| 'While' statement parsing | YES |\n| 'If-Elif-Else' statement parsing | YES |\n| 'Yield' statement parsing | YES |\n| Ternar 'If' expression parsing | YES |\n| Signals parsing | YES |\n| Strings parsing | YES |\n| Numbers parsing | YES |\n| Methods calls parsing | YES |\n| Single operators parsing | YES |\n| Dual operators parsing | YES |\n| Static types parsing | YES |\n| Expressions priority sorting | YES |\n| Basic tokenization managment | YES |\n| Save formatting while parsing | YES |\n| Save comments while parsing | YES |\n| Moving from tokens to parent | YES |\n| NodePath and GetNode short syntax parsing | YES |\n| Inner class parsing | YES |\n| Tree walking and node visiting | YES |\n| Syntax cloning | YES |\n| Syntax factory | YES |\n| Syntax errors managment and properly handling | IN PLAN |\n| Code formatting | IN PLAN |\n| Custom formatter | IN PLAN |\n| Tree diff tool | IN PLAN |\n\n## Last updates\n\n#### 4.3.2-alpha\nFixed line breaks inside brackets, enums, dictionaries, arrays. Fixed comments parsing inside brackets.\n\n#### 4.3.1-alpha\nFixed ovewflows.\nFixed dictionary parsing if it contains invalid characters.\nFixed multiline string parsing if it starts with new line character.\nFixed some cases in expression and statements resolving.\nFixed yield expression.\n\n## Reading samples\n\n### Parse class\n\nGDScript input:\n\n```gdscript\ntool\nclass_name HTerrainDataSaver\nextends ResourceFormatSaver\n\nconst HTerrainData = preload(\"./ hterrain_data.gd\")\n\n\nfunc get_recognized_extensions(res):\n\tif res != null and res is HTerrainData:\n\t\treturn PoolStringArray([HTerrainData.META_EXTENSION])\n\treturn PoolStringArray()\n\n\nfunc recognize(res):\n\treturn res is HTerrainData\n\n\nfunc save(path, resource, flags):\n\tresource.save_data(path.get_base_dir())\n```\n\nParser usage:\n\n```csharp\n // Initialize a reader instance\n var reader = new GDScriptReader();\n \n // Parse the raw code\n var @class = reader.ParseFileContent(code); // returns instance of type GDClassDeclaration \n \n // Get 'extends' atribute information\n Console.WriteLine(@class.Extends.Type.Sequence); // outputs base class name \"ResourceFormatSaver\"\n \n // Get 'class_name' atribute information\n Console.WriteLine(@class.ClassName.Type.Sequence); // outputs current class name \"HTerrainDataSaver\"\n \n // Check 'tool' atribute \n Console.WriteLine(@class.IsTool); // outputs true \n \n // Enumerates all class variables\n foreach(GDVariableDeclaration variable in @class.Variables)\n {\n    Console.WriteLine(method.Identifier.Sequence); // outputs variables's name\n }\n \n // Enumerates all class methods\n foreach(GDMethodDeclaration method in @class.Methods)\n {\n    Console.WriteLine(method.Identifier.Sequence); // outputs method's name\n    \n    // Enumerates all method statements\n    foreach(GDStatement st in method.Statements)\n    {\n        // ... your code\n    }\n }\n```\n\n\n### Get comments from GDScript code\n\n```csharp\n var @class = reader.ParseFileContent(code);\n \n // Add 'using System.Linq;'\n var comments = @class.AllTokens\n                .OfType\u003cGDComment\u003e()\n                .Select(x =\u003e x.ToString()) // Convert token to string\n                .ToArray();\n```\n\n## Tree building samples or GDScript runtime generation\n\nGDShrapt supports many styles to simplify a code generation process. Just use the GD static class to create a token or a node. \n\n### Short style\n\n```csharp\n// Build a custom class. Safe code generation. Dont control a code style\nvar declaration = GD.Declaration.Class(\n                GD.List.Atributes(\n                    GD.Atribute.Tool(),\n                    GD.Atribute.ClassName(\"Generated\"),\n                    GD.Atribute.Extends(\"Node2D\")),\n\n                GD.Declaration.Const(\"my_constant\", GD.Expression.String(\"Hello World\")),\n                GD.Declaration.OnreadyVariable(\"parameter\", GD.Expression.True()),\n\n                GD.Declaration.Method(\"_start\",\n                    GD.Expression.Call(GD.Expression.Identifier(\"print\"), GD.Expression.String(\"Hello world\"))\n                    )\n                );\n\ndeclaration.UpdateIntendation(); // Auto update tabs (recursively)\n\nvar code = declaration.ToString(); // Get the string representation\n```\n\nThe result is code like:\n\n```gdscript\ntool\nclass_name Generated\nextends Node2D\n\nconst my_constant = \"Hello World\"\n\nonready var parameter = true\n\nfunc _start():\n\tprint(\"Hello world\")\n```\n\n### Methods chain style\n\n```csharp\n// Build a custom class. Full tokens control, but unsafe for exceptions\nvar declaration = GD.Declaration.Class()\n                .AddAtributes(x =\u003e x\n                    .AddToolAtribute()\n                    .AddNewLine()\n                    .AddClassNameAtribute(\"Generated\")\n                    .AddNewLine()\n                    .AddExtendsAtribute(\"Node2D\"))\n                .AddNewLine()\n                .AddNewLine()\n                .AddMembers(x =\u003e x\n                    .AddVariable(\"a\")\n                    .AddNewLine()\n                    .AddConst(\"message\", GD.Expression.String(\"Hello\"))\n                    .AddNewLine()\n                    .AddNewLine()\n                    .AddMethod(x =\u003e x\n                        .AddFuncKeyword()\n                        .AddSpace()\n                        .Add(\"_start\")\n                        .AddOpenBracket()\n                        .AddCloseBracket()\n                        .AddStatements(x =\u003e x\n                            .AddNewLine()\n                            .AddNewLine()\n                            .AddIntendation()\n                            .AddCall(GD.Expression.Identifier(\"print\"), GD.Expression.String(\"Hello world\"))\n                            .AddNewLine()\n                            .AddNewLine()\n                            .AddIntendation()\n                            .AddPass())));\n\ndeclaration.UpdateIntendation(); // Auto update tabs (recursively)\n\nvar code = declaration.ToString(); // Get the string representation\n```\n\n### Tokens list style\n\n```csharp\n// Build a custom class. Full tokens control but unsafe for types\nvar declaration = GD.Declaration.Class(\n                GD.List.Atributes(\n                    GD.Atribute.Tool(),\n                    GD.Syntax.NewLine,\n                    GD.Atribute.ClassName(\"Generated\"),\n                    GD.Syntax.NewLine,\n                    GD.Atribute.Extends(\"Node2D\")),\n\n                GD.Syntax.NewLine,\n                GD.Syntax.NewLine,\n\n                GD.Declaration.Variable(\n                     GD.Keyword.Const,\n                     GD.Syntax.OneSpace,\n                     GD.Syntax.Identifier(\"my_constant\"),\n                     GD.Syntax.OneSpace,\n                     GD.Syntax.Assign,\n                     GD.Syntax.OneSpace,\n                     GD.Syntax.String(\"Hello World\")),\n\n                GD.Syntax.NewLine,\n                GD.Syntax.NewLine,\n\n                GD.Declaration.Variable(\n                    GD.Keyword.Onready,\n                    GD.Syntax.OneSpace,\n                    GD.Keyword.Var,\n                    GD.Syntax.OneSpace,\n                    GD.Syntax.Identifier(\"parameter\"),\n                    GD.Syntax.OneSpace,\n                    GD.Syntax.Assign,\n                    GD.Syntax.OneSpace,\n                    GD.Expression.True()),\n\n                GD.Syntax.NewLine,\n                GD.Syntax.NewLine,\n\n                GD.Declaration.Method(\n                    GD.Keyword.Func,\n                    GD.Syntax.OneSpace,\n                    GD.Syntax.Identifier(\"_start\"),\n                    GD.Syntax.OpenBracket,\n                    GD.Syntax.CloseBracket,\n                    GD.Syntax.Colon,\n\n                    GD.Syntax.NewLine,\n                    GD.Syntax.Intendation(1),\n                    GD.Expression.Call(\n                        GD.Expression.Identifier(\"print\"),\n                        GD.Syntax.OpenBracket,\n                        GD.List.Expressions(GD.Expression.String(\"Hello world\")),\n                        GD.Syntax.CloseBracket)));\n\nvar code = declaration.ToString(); // Get the string representation\n```\n\n### Custom style initialization\n\n```csharp\n// The sample of a For statement initizalization with a predefined style. It is how the GD.Statement.For method works.\n// You must know the 'form' to use this format. \n// For example a code line like \"[1] = GD.Syntax.Space()\" will insert a space token BEFORE the first static point in the nodes form.\n// In the code below the first point of the For statement is the iterator's variable name.\npublic static GDForStatement For(GDIdentifier variable, GDExpression collection, GDExpression body) =\u003e new GDForStatement()\n            {\n                ForKeyword = new GDForKeyword(),\n                [1] = GD.Syntax.Space(),\n                Variable = variable,\n                [2] = GD.Syntax.Space(),\n                InKeyword = new GDInKeyword(),\n                [3] = GD.Syntax.Space(),\n                Collection = collection,\n                Colon = new GDColon(),\n                [5] = GD.Syntax.Space(),\n                Expression = body\n            };\n```\n\nYou may use a combination of the styles.\n\n### Calculating properties\n\n```csharp\n\nGDSyntaxToken token = null; // any token\n\ntoken.StartLine // calculate the start line of the token in the code\ntoken.EndLine // calculate the end line of the token in the code\ntoken.Length // calculate the length of the token\ntoken.StartColumn // calculate the start column in the line\ntoken.EndColumn // calculate the end column in the line\ntoken.NewLinesCount // calculate new line characters in the token. \n\ntoken.ClassMember // find the nearest class member from parents\ntoken.MainClassDeclaration // find the main class contains the token\ntoken.Parents // enumerate all parents of the token\n```\n\nFor more samples see the [tests](src/GDShrapt.Reader.Tests/ParsingTests.cs).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felamaunt%2Fgdshrapt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felamaunt%2Fgdshrapt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felamaunt%2Fgdshrapt/lists"}