Tesearis.GlslParser 1.0.0

dotnet add package Tesearis.GlslParser --version 1.0.0
                    
NuGet\Install-Package Tesearis.GlslParser -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tesearis.GlslParser" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tesearis.GlslParser" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Tesearis.GlslParser" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tesearis.GlslParser --version 1.0.0
                    
#r "nuget: Tesearis.GlslParser, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tesearis.GlslParser@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tesearis.GlslParser&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Tesearis.GlslParser&version=1.0.0
                    
Install as a Cake Tool

Tesearis.GlslParser

Standalone GLSL/GLSL ES lexer, preprocessor and syntax tree for shader source.

Tesearis.GlslParser parses GLSL source — either a whole standalone file or a region embedded inside a document (e.g. a ShaderLab GLSLPROGRAM/GLSLINCLUDE block) — into an immutable, strongly-typed AST for static analysis and diagnostics tooling. It's a genuinely independent implementation with no runtime dependencies at all, so it stays consumable entirely on its own.

Features

  • Zero dependencies: no runtime dependencies at all.
  • Standalone and embeddable: parses a whole .glsl/.vert/.frag file directly, or a substring embedded inside a document.
  • Full core grammar: structs, interface blocks (uniform/buffer/in/out blocks), layout qualifiers, precision statements, functions, and full statement/expression parsing inside function bodies.
  • Real preprocessor: genuine #define/#undef macro expansion, #if/#ifdef/#ifndef/#elif/#else/#endif conditional evaluation, and GLSL's #version/#extension directives (recognized structurally, not interpreted — see below).
  • Best-effort recovery: never throws on malformed source; it returns a (possibly partial) tree plus a full diagnostics list.
  • Targeted: netstandard2.0 (for use in older/.NET-Framework-era tooling) and net8.0.

What this library does not do

  • It never reads files from disk.
  • It never resolves #include targets.
  • It doesn't evaluate #version/#extension/predefined macros like GL_ES — what those actually enable is environment-provided information (the GLSL compiler's own behavior), which is out of scope for this library. They're surfaced structurally on the AST (CompilationUnitNode.Version/.Extensions) for a caller to interpret.
  • No C-style cast syntax exists in core GLSL, so this parser has no CastExpressionNode at all — type conversion is parsed as ordinary constructor-call syntax (float(x), vec3(x)), which InvocationExpressionNode already covers.

Usage

Parsing a standalone file

using Tesearis.GlslParser.Parsing;
using Tesearis.GlslParser.Syntax;

GlslParseResult result = Glsl.Parse(sourceText, "shader.glsl");

if (result.HasErrors)
{
    foreach (var diagnostic in result.Diagnostics)
    {
        Console.WriteLine(diagnostic);
    }
}

var compilationUnit = (CompilationUnitNode)result.Root;
foreach (var declaration in compilationUnit.Declarations)
{
    Console.WriteLine(declaration.Kind);
}

Glsl.Parse never throws on malformed input — it always returns a (possibly partial) tree in result.Root alongside result.Diagnostics.

Parsing an embedded region

Use Glsl.ParseEmbedded when the GLSL source is a substring of a larger document (e.g. a ShaderLab GLSLPROGRAM block). Spans and diagnostics are reported in terms of the outer document, using the offset/line where the embedded block starts:

GlslParseResult result = Glsl.ParseEmbedded(
    body: glslBlockText,
    baseOffset: glslBlockStartOffset,
    fileName: "MyShader.shader",
    baseLine: glslBlockStartLine);

Walking the syntax tree

using System.Linq;

var functions = result.Root.DescendantsAndSelf().OfType<FunctionDeclarationNode>();

For more structured traversal, subclass GlslVisitor and override the node kinds you care about:

class FunctionCollector : GlslVisitor
{
    public List<FunctionDeclarationNode> Functions { get; } = new();

    public override void VisitFunctionDeclaration(FunctionDeclarationNode node)
    {
        Functions.Add(node);
        base.DefaultVisit(node);
    }
}

var collector = new FunctionCollector();
collector.Visit(result.Root);

To inspect the whole tree at a glance, GlslTreeDumper.Dump renders it as indented text:

string dump = GlslTreeDumper.Dump(result.Root, result.Source);

Diagnostics

using Tesearis.GlslParser.Diagnostics;

foreach (Diagnostic diagnostic in result.Diagnostics)
{
    Console.WriteLine(diagnostic); // "shader.glsl(3,10): error GL0203: ..."
}

Building & testing

dotnet build Tesearis.GlslParser.slnx
dotnet test Tesearis.GlslParser.slnx

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 108 8/21/2026