在现代编程语言中,许多编译器都使用了类型推断技术,以使得代码更加简洁易读。如Java 7引入的Diamond操作符
List
因为左边声明的类型是List
其实这种类型推断的技术可以被应用到语法解析阶段,例如基于BNF范式的语法解析器可以在解析过程中记录方法参数或变量的类型,以便后续代码生成。
以下是一个简单的Java方法声明的BNF文法:
MethodDecl ::= ReturnType Identifier ‘(’ (VariableDecl (‘,’ VariableDecl)*) ‘)’ Block ReturnType ::= Type | ‘void’ VariableDecl ::= Type Identifier
如果在语法解析过程中,编译器记录了VariableDecl的类型,那么可以在后续的代码生成过程中减少类型检查或类型转换的工作。在这个例子中,我们可以添加一个属性type到VariableDecl中,来记录这个变量的类型。在解析VariableDecl时,我们可以在语法解析树上记录type信息:
VariableDecl ::= Type Identifier {VarType = Type}
在解析完一个方法的参数列表后,我们可以将所有VariableDecl的 type信息汇总到当前MethodDecl节点的 typeList中:
MethodDecl ::= ReturnType Identifier ‘(’ (VariableDecl (‘,’ VariableDecl)*) ‘)’ Block {typeList= [VariableDecl_1.type, VariableDecl_2.type, ...]}
在解析表达式时,解析器会利用这些type信息来推断每个操作数的类型及整个表达式的类型,以方便类型检查和类型转换。
总之,编译器确实可以在语法解析阶段进行类型推断,来减少后续代码生成阶段