56个版本 (22个稳定版本)

7.0.0 2023年12月22日
6.0.3 2023年12月19日
6.0.2 2023年3月23日
6.0.1 2021年7月11日
0.3.0 2017年7月31日

#58解析器实现

Download history 737/week @ 2024-04-16 520/week @ 2024-04-23 586/week @ 2024-04-30 752/week @ 2024-05-07 643/week @ 2024-05-14 645/week @ 2024-05-21 949/week @ 2024-05-28 895/week @ 2024-06-04 1299/week @ 2024-06-11 879/week @ 2024-06-18 767/week @ 2024-06-25 1485/week @ 2024-07-02 1282/week @ 2024-07-09 1079/week @ 2024-07-16 1389/week @ 2024-07-23 739/week @ 2024-07-30

每月4,763 次下载
用于 21 个crate(14个直接使用)

BSD-3-Clause

290KB
8K SLoC

Build Status crates.io docs.rs License

这个crate是一个GLSL450/GLSL460编译器。它能将有效的GLSL格式源代码解析成抽象语法树(AST)。然后,该AST可以被转换成SPIR-V、自己的格式,甚至可以折叠回原始的GLSL String(例如,一个压缩器)。

你可以找到几个模块

  • parser,它导出了解析接口。这里是你可以获得大多数有趣类型和特质的所在地,例如 ParseParseError
  • syntax,它导出了AST和语言定义。如果你查看解构、转译或获取解析的GLSL代码的信息,你可能会操作在这个模块中定义类型的对象。
  • transpiler,它为你提供了GLSL转译器。例如,你可以找到 GLSL到GLSL 转译器,GLSL到SPIR-V 转译器等。
  • visitor,它为你提供了一种访问AST节点并修改它们的方式,包括内部和外部修改。

请随意检查这些模块以获取更多信息。

GLSL解析和转译

解析是你最常进行的操作。这不是必需的(你仍然可以手动创建AST或使用 glsl-quasiquote 在编译时通过在Rust中使用GLSL语法直接创建它)。然而,在本节中,我们将看到如何从字符串解析到几个GLSL类型。

解析架构

基本上,Parse特质提供了您开始解析所需的一切。这个crate围绕类型驱动的解析概念进行设计:解析器是隐藏的,您只需声明您期望的结果类型。

您想要解析的最常见类型是TranslationUnit,它代表一组ExternalDeclaration。一个ExternalDeclaration是着色器顶级层面的声明。它可以是一个全局、统一声明、顶点属性、函数、结构体等。从这个意义上讲,一个TranslationUnit类似于着色器阶段(顶点着色器、片段着色器等)。

您可以解析实现Parse的任何类型。解析器对外部空白敏感,这意味着以空白开始的Expr解析将不会工作(这对TranslationUnit来说不是真的,因为它非常宽容)。

解析一个表达式

让我们尝试解析一个表达式。

use glsl::parser::Parse as _;
use glsl::syntax::Expr;

let glsl = "(vec3(r, g, b) * cos(t * PI * .5)).xxz";
let expr = Expr::parse(glsl);
assert!(expr.is_ok());

在这里,expr是一个AST,其类型为Result<Expr, ParseError>,它表示GLSL表达式(vec3(r, g, b) * cos(t * PI * .5)).xxz,这是RGB颜色与时间的余弦值的外部(标量)乘积,整个东西与XXZ进行了混洗。检查解析过程是否成功是您的责任。

在上一个例子中,GLSL字符串是一个常量,是硬编码的。它可以来自文件、网络或即时构建,但在常量GLSL代码的情况下,最好不在运行时解析字符串,对吗?嗯,glsl-quasiquote正是为此而存在的。您可以要求rustc解析该字符串,如果解析成功,则直接将AST注入到您的代码中。没有Result,只有纯AST。有关详细信息,请参阅glsl-quasiquote

解析整个着色器

顶点着色器、几何着色器、片段着色器以及控制和评估细分着色器可以通过使用TranslationUnitShaderStage类型以相同的方式进行解析。

在这里,一个简单的顶点着色器被解析。

use glsl::parser::Parse as _;
use glsl::syntax::ShaderStage;

let glsl = "
  layout (location = 0) in vec3 pos;
  layout (location = 1) in vec4 col;

  out vec4 v_col;

  uniform mat4 projview;

  void main() {
    v_col = col; // pass color to the next stage
    gl_Position = projview * vec4(pos, 1.);
  }
";
let stage = ShaderStage::parse(glsl);
assert!(stage.is_ok());

访问AST节点

这个crate也在不断增加组合子和函数来转换AST或使用常规Rust创建节点。当您想要处理深度变异、过滤和验证时,Visitor trait将成为您的得力助手。请查看visitor模块,了解如何使用访问者。

关于GLSL版本...

这个crate可以解析GLSL450和GLSL460格式的输入源。在语言层面上,GLSL450和GLSL460之间的差异几乎可以忽略不计,所以两种情况都得到了覆盖。

如果您想知道,两个版本之间的唯一区别是,在GLSL460中,在着色器顶层允许空行上有分号(;)。

依赖关系

~0.8–5MB
~112K SLoC