通过上面的讨论,形成了以下类:
VarDecl ParmVarDecl FunctionDecl BreakStmt CompoundStmt ContinueStmt IfStmt ReturnStmt WhileStmt DeclStmt BinaryOperator CallExpr DeclRefExpr ParenExpr UnaryOperator OpaqueValueExpr IntegerLiteral StringLiteral
接下来需要分别讨论之间的关系以及 llvm ir 的生成策略
一、类间关系
1、顶层类:Decl
Decl 类包含了所有表征定义的类,自顶向下顺序来说:
-
NamedDecl:表征声明是有名变量,有一些变量的声明可以不需要声明名字,这是 C++ 中的某些特性。在我们的实验中不需要考虑。
-
ValueDecl:Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it is a function designator) or an enum。简单来说,是含有实际内容的定义,包括变量、函数的定义,这也是本次实验的限定,所以不需要考虑。
-
DeclaratorDecl:待定,反正没啥用
我们所需要的声明(无论是之后的数组还是函数)DeclaratorDecl层已经够了,即保留一个顶层即可(直接就是Decl)。
2、顶层类:Stmt
Stmt 是最基本的结构,表征一个语句,一般带有分号。我们涉及的 Stmt 如下图所示:
在Expr上层其实还存在一个ValueStmt,但上述一样可以省略。上文讨论到的用于类型转换类的CastExpr,此处并没用到。其中DeclStmt的实质内容,是Decl。
下面综述一下 Expr 各部分的含义:
-
BinaryOperator:二元运算符,包含 =
-
CallExpr:函数调用,如printf,getint等
-
DeclRefExpr:变量的引用,如 b = a*2,则 a 就是DeclRefExpr类。
-
ParenExpr:带括号的表达式
-
UnaryOperator:一元运算符表达式
3、重构前后信息量
按照SysY文法,构建等价语法结构如上图所示,既然能够构建得出,说明此种分类方式的表现力足够,因此可以用这些类搭建AST。
二、LLVM生成策略
总的来说,对于上面重构的AST形式,我期望的生成方式是在各类内通过统一的方法进行 IR 生成。对此我们需分析上述各个类的 IR 耦合度是否支持我们这样做。当然,在此之前,必须对LLVM IR 的语法进行简单陈述。
1、LLVM IR
Instructions
-
opcode:add,sub
-
operands
-
one or zero result values
-
Explicitly typed
Instruction classes
-
Arithmetic instructions
%sum = add i32 %a, 10
-
Compare Ins