我应该使用flex / yacc编写Direct3D着色器模型语言编译器吗?

时间:2010-02-10 19:30:09

标签: compilation yacc direct3d flex-lexer

我将为Direct3D的Shader Model语言创建一个编译器。编译器的目标平台和开发环境在Windows / VC ++上。 对于那些不熟悉着色器模型语言的人,这里是语言组成的指令示例(有些指令有点过时,但语法与我将使用的版本基本相同)。

Here

And here

我正在考虑将flex / yacc作为开发编译器的框架。这些适合这项工作吗?在原生C ++中有没有更好的开发框架?

1 个答案:

答案 0 :(得分:3)

在我看来,普通的词法分析器和/或解析器生成器通常对编写汇编程序没有多大帮助。它们主要用于处理相对复杂的语法,但对于汇编程序而言,“语法”通常是如此微不足道,以至于这样的生成器比帮助更容易受阻。

典型的汇编程序主要是表驱动的 - 首先创建一个已定义操作码的表,以及它将生成的指令的特征(例如,必须为其指定的寄存器的数量和类型)。您通常有一个(较小的,在着色器的情况下,可能更小)表定义如何编码寻址模式等。

大多数汇编程序通过查询该表来工作 - 即它从输入中读取内容,并尝试在表中查找它。如果它不存在,它会给出一条错误消息,说明它是一个未知的操作码。如果找到了,它会从表中获取有关与该操作码相关的操作数的信息。它试图读取许多操作数。如果不能,则会出现错误,说明指令有问题。如果可以,它会对指令进行编码,然后重新开始。

当然,有一些地方需要处理的比这更多。在您定义类似标签的位置时,它必须在符号表中记录该标签的名称和位置。当它遇到类似分支到该地址的东西时,它必须查找目标并适当地编码其地址。

只有当您决定支持宏时,您才会离开该基本模型。根据您使用它们的详细程度,使用解析器生成器以及宏扩展工具可能是值得的。再说一次,鉴于着色器大多非常小,宏对于这样的汇编程序来说不太可能是一个非常高的优先级。

编辑:重读它,我应该澄清/纠正一点。当语法本身变得复杂时,解析器生成器的使用并不多,就像语法允许复杂的语句一样。考虑一个非常简单的语法:

expression := expression '+' value
            | expression '-' value
            | value

即使这只允许加法和减法,它仍然定义任意复杂的语句(或者至少任意加长或减去任意长的值串)。当然,对于一个相当琐碎的真实语言,我们通常会进行乘法,除法,函数调用等。

这与典型的汇编语言有很大不同,每种指令都有固定的格式。例如,加法或减法操作恰好有两个源操作数和一个目标操作数。