基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)

为了完美解析GLSL源码,获取其中的信息(都有哪些in/out/uniform等),我决定做个GLSL编译器的前端(以后简称编译器或FrontEndParser)。

以前我做过一个CGCompiler,可以自动生成LL(1)文法的编译器代码(C#语言的)。于是我从《The OpenGL ® Shading Language》(以下简称"PDF")找到一个GLSL的文法,就开始试图将他改写为LL(1)文法。等到我重写了7次后发现,这是不可能的。GLSL的文法超出了LL(1)的范围,必须用更强的分析算法。于是有了现在的LALR(1)Compiler

《现代编译原理-c语言描述》(即"虎书")中提供了详尽的资料。我就以虎书为理论依据。

虎书中的下图表明了各种类型的文法的范围。一般正常的程序语言都是符合LALR(1)文法的。

由于LR(0)是SLR的基础,SLR是LR(1)的基础;又由于LR(1)是LALR(1)的基础(这看上去有点奇怪),所以我必须从LR(0)文法开始一步一步实现LALR(1)算法

基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)

输入

给定文法,这个文法所描述的语言的全部信息就都包含进去了。文法里包含了这个语言的关键字、推导结构等所有信息。这也是我觉得YACC那些东西不好的地方:明明有了文法,还得自己整理出各种关键字。

下面是一个文法的例子:

1 // 虎书中的文法3-10
2 <S> ::= <V> "=" <E> ;
3 <S> ::= <E> ;
4 <E> ::= <V> ;
5 <V> ::= "x" ;
6 <V> ::= "*" <E> ;
 

下面是6个符合此文法的代码:

1 x
2 *x
3 x = x
4 x = * x
5 *x = x
6 **x = **x

输出

输出结果是此文法的编译器代码(C#)。这主要是词法分析器LexicalAnalyzer和语法分析器SyntaxParser两个类。

之后利用C#的CSharpCodeProvider和反射技术来加载、编译、运行生成的代码,用一些例子(例如上面的*x = x)测试是否能正常运行。只要能正常生成语法树,就证明了我的LALR(1)Compiler的实现是正确的。

例如对上述文法的6个示例代码,LALR(1)Compiler可以分别dump出如下的语法树:

1 (__S)[S][<S>]
2  └─(__E)[E][<E>]
3      └─(__V)[V][<V>]
4          └─(__xLeave__)[x][x]
x

相关文章:

  • 2023-01-05
  • 2021-11-06
  • 2022-12-23
  • 2021-08-18
  • 2022-12-23
  • 2022-12-23
  • 2021-07-06
  • 2021-04-22
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-12-14
  • 2021-07-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案