语义分析完成的功能

语义分析是编译器的重要阶段,主要完成以下功能:
-
符号表管理
作用域管理:实现嵌套作用域的进入和退出符号存储:记录变量、函数、类型等标识符的信息
符号查询:支持按名称查找符号,考虑作用域层级
-
类型系统实现
类型表示:定义基本类型(int, float, char等)和复合类型(数组、指针、函数)
类型兼容性:检查赋值、运算中的类型匹配
类型推导:为表达式推断结果类型
- 声明检查
重复声明检测:防止在同一作用域重复声明标识符
未声明使用检查:确保使用的变量、函数都已声明
函数声明验证:检查函数参数和返回类型
- 类型检查
赋值兼容性:检查左值和右值的类型是否匹配
运算类型检查:验证操作数的类型是否支持相应运算
函数调用匹配:检查实参类型与形参类型的兼容性
- 控制流检查
返回语句检查:确保函数有正确的返回值
break/continue位置:验证只能在循环或switch中使用
函数结束路径:检查所有执行路径是否有返回值
- 其他语义规则
数组维度检查:验证数组访问的下标有效性
指针运算限制:确保指针运算的合法性
结构体成员访问:验证成员是否存在
- 错误报告
精准定位:报告错误发生的具体位置(行号)
详细描述:提供清晰的错误信息说明
错误恢复:尽可能继续分析以发现更多错误
- 中间表示生成
带类型AST:为AST节点添加类型信息
语义注解:为后续代码生成阶段提供必要信息
常量折叠:在编译时计算常量表达式
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include <stack>
#include <sstream>
#include <cctype>
// **类型系统**
enum class TypeKind {
VOID,
INT,
FLOAT,
CHAR,
DOUBLE,
ARRAY,
POINTER,
FUNCTION
};
struct TypeInfo {
TypeKind kind;
std::shared_ptr<TypeInfo> base_type; // 用于数组、指针
int array_size; // 数组大小
std::vector<TypeKind> param_types; // 函数参数类型
TypeKind return_type; // 函数返回类型
TypeInfo(TypeKind k = TypeKind::VOID) : kind(k), array_size(-1), return_type(TypeKind::VOID) {}
bool operator==(const TypeInfo& other) const {
if (kind != other.kind) return false;
switch (kind) {
case TypeKind::ARRAY:
return array_size == other.array_size && *base_type == *other.base_type;
case TypeKind::POINTER:
return *base_type == *other.base_type;
case TypeKind::FUNCTION:
if (return_type != other.return_type) return false;
if (param_types.size() != other.param_types.size()) return false;
for (size_t i = 0; i < param_types.size(); ++i) {
if (param_types[i] != other.param_types[i]) return false;
}
return true;
default:
return true;
}
}
std::string toString() const {
switch (kind) {
case TypeKind::VOID: return "void";
case TypeKind::INT: return "int";
case TypeKind::FLOAT: return "float";
case TypeKind::CHAR: return "char";
case TypeKind::DOUBLE: return "double";
case TypeKind::ARRAY:
return base_type->toString() + "[" + (array_size > 0 ? std::to_string(array_size) : "") + "]";
case TypeKind::POINTER:
return base_type->toString() + "*";
case TypeKind::FUNCTION: {
std::string result = TypeInfo(return_type).toString() + "(";
for (size_t i = 0; i < param_types.size(); ++i) {
if (i > 0) result += ", ";
result += TypeInfo(param_types[i]).toString();
}
result += ")";
return result;
}
default: return "unknown";
}
}
};
// 符号表项
struct Symbol {
std::string name;
TypeInfo type;
int scope_level;
bool is_function;
bool is_defined; // 对于函数,是否已定义
Symbol(const std::string& n, const TypeInfo& t, int sl, bool is_func = false)
: name(n), type(t), scope_level(sl), is_function(is_func), is_defined(false) {}
};
// 抽象语法树节点
class ASTNode {
public:
TypeInfo type; // 节点的类型信息
int line_number;
ASTNode() : line_number(0) {}
virtual ~ASTNode() = default;
virtual void semanticCheck() = 0;
virtual std::string toString() const = 0;
};
// 符号表类
class SymbolTable {
private:
std::vector<std::unordered_map<std::string, Symbol>> scopes;
std::stack<int> scope_stack;
int current_scope;
public:
SymbolTable() : current_scope(0) {
enterScope(); // 全局作用域
}
// 进入新作用域
void enterScope() {
scopes.push_back(std::unordered_map<std::string, Symbol>());
scope_stack.push(current_scope);
current_scope = scopes.size() - 1;
}
// 退出当前作用域
void exitScope() {
if (!scope_stack.empty()) {
current_scope = scope_stack.top();
scope_stack.pop();
if (!scopes.empty()) {
scopes.pop_back();
}
}
}
// 添加符号
bool addSymbol(const std::string& name, const TypeInfo& type, bool is_function = false) {
if (scopes.empty()) return false;
// 检查当前作用域是否已存在同名符号
if (scopes.back().find(name) != scopes.back().end()) {
return false; // 重复声明
}
Symbol sym(name, type, current_scope, is_function);
scopes.back()[name] = sym;
return true;
}
// 查找符号
Symbol* findSymbol(const std::string& name) {
for (int i = scopes.size() - 1; i >= 0; --i) {
auto it = scopes[i].find(name);
if (it != scopes[i].end()) {
return &(it->second);
}
}
return nullptr;
}
// 标记函数为已定义
bool markFunctionDefined(const std::string& name) {
Symbol* sym = findSymbol(name);
if (sym && sym->is_function) {
sym->is_defined = true;
return true;
}
return false;
}
// 获取当前作用域级别
int getCurrentScopeLevel() const {
return current_scope;
}
};
// 语义分析器
class SemanticAnalyzer {
private:
SymbolTable symbol_table;
std::vector<std::string> errors;
public:
// 类型兼容性检查
bool isTypeCompatible(const TypeInfo& t1, const TypeInfo& t2) {
// 基本类型兼容性规则
if (t1.kind == t2.kind) {
return true;
}
// 数值类型之间的隐式转换
if ((t1.kind == TypeKind::INT || t1.kind == TypeKind::FLOAT ||
t1.kind == TypeKind::CHAR || t1.kind == TypeKind::DOUBLE) &&
(t2.kind == TypeKind::INT || t2.kind == TypeKind::FLOAT ||
t2.kind == TypeKind::CHAR || t2.kind == TypeKind::DOUBLE)) {
return true;
}
// 指针和数组的兼容性
if (t1.kind == TypeKind::POINTER && t2.kind == TypeKind::ARRAY) {
return *t1.base_type == *t2.base_type;
}
return false;
}
// 添加错误信息
void addError(int line, const std::string& message) {
std::ostringstream oss;
oss << "Line " << line << ": " << message;
errors.push_back(oss.str());
}
// 获取错误信息
const std::vector<std::string>& getErrors() const {
return errors;
}
// 检查是否有错误
bool hasErrors() const {
return !errors.empty();
}
};
// 变量声明节点
class VarDeclNode : public ASTNode {
private:
std::string var_name;
std::shared_ptr<ASTNode> init_value;
SemanticAnalyzer& analyzer;
SymbolTable& symbol_table;
public:
VarDeclNode(const std::string& name, const TypeInfo& t,
std::shared_ptr<ASTNode> init, SemanticAnalyzer& a, SymbolTable& st)
: var_name(name), init_value(init), analyzer(a), symbol_table(st) {
type = t;
}
void semanticCheck() override {
// 检查变量是否已声明
if (symbol_table.findSymbol(var_name)) {
analyzer.addError(line_number, "重复声明的变量: " + var_name);
return;
}
// 添加到符号表
if (!symbol_table.addSymbol(var_name, type)) {
analyzer.addError(line_number, "无法添加符号到符号表: " + var_name);
return;
}
// 检查初始化表达式
if (init_value) {
init_value->semanticCheck();
// 检查类型兼容性
if (!analyzer.isTypeCompatible(type, init_value->type)) {
analyzer.addError(line_number, "类型不匹配: 无法将 " +
init_value->type.toString() + " 赋值给 " + type.toString());
}
}
}
std::string toString() const override {
return "VarDecl: " + var_name + " : " + type.toString();
}
};
// 变量引用节点
class VarRefNode : public ASTNode {
private:
std::string var_name;
SemanticAnalyzer& analyzer;
SymbolTable& symbol_table;
public:
VarRefNode(const std::string& name, SemanticAnalyzer& a, SymbolTable& st)
: var_name(name), analyzer(a), symbol_table(st) {}
void semanticCheck() override {
Symbol* sym = symbol_table.findSymbol(var_name);
if (!sym) {
analyzer.addError(line_number, "未定义的变量: " + var_name);
type = TypeInfo(TypeKind::INT); // 给一个默认类型继续分析
return;
}
type = sym->type; // 设置引用节点的类型
}
std::string toString() const override {
return "VarRef: " + var_name + " : " + type.toString();
}
};
// 二元操作节点
class BinaryOpNode : public ASTNode {
private:
std::string op;
std::shared_ptr<ASTNode> left;
std::shared_ptr<ASTNode> right;
SemanticAnalyzer& analyzer;
public:
BinaryOpNode(const std::string& op, std::shared_ptr<ASTNode> l,
std::shared_ptr<ASTNode> r, SemanticAnalyzer& a)
: op(op), left(l), right(r), analyzer(a) {}
void semanticCheck() override {
left->semanticCheck();
right->semanticCheck();
// 检查操作数类型兼容性
if (!analyzer.isTypeCompatible(left->type, right->type)) {
analyzer.addError(line_number, "操作数类型不兼容: " +
left->type.toString() + " 和 " + right->type.toString());
}
// 设置结果类型(简化处理,实际需要更复杂的类型推导)
type = left->type;
}
std::string toString() const override {
return "BinaryOp: " + op + " (" + left->toString() + ", " + right->toString() + ")";
}
};
// 函数声明节点
class FunctionDeclNode : public ASTNode {
private:
std::string func_name;
std::vector<std::pair<std::string, TypeInfo>> params;
std::shared_ptr<ASTNode> body;
SemanticAnalyzer& analyzer;
SymbolTable& symbol_table;
public:
FunctionDeclNode(const std::string& name, const std::vector<std::pair<std::string, TypeInfo>>& p,
std::shared_ptr<ASTNode> b, SemanticAnalyzer& a, SymbolTable& st)
: func_name(name), params(p), body(b), analyzer(a), symbol_table(st) {}
void semanticCheck() override {
// 构建函数类型
TypeInfo func_type;
func_type.kind = TypeKind::FUNCTION;
func_type.return_type = type.kind;
for (const auto& param : params) {
func_type.param_types.push_back(param.second.kind);
}
// 添加到符号表
if (!symbol_table.addSymbol(func_name, func_type, true)) {
analyzer.addError(line_number, "重复声明的函数: " + func_name);
return;
}
// 进入函数作用域
symbol_table.enterScope();
// 添加参数到符号表
for (const auto& param : params) {
if (!symbol_table.addSymbol(param.first, param.second)) {
analyzer.addError(line_number, "重复声明的参数: " + param.first);
}
}
// 检查函数体
if (body) {
body->semanticCheck();
}
// 标记函数为已定义
symbol_table.markFunctionDefined(func_name);
// 退出函数作用域
symbol_table.exitScope();
}
std::string toString() const override {
std::string result = "FunctionDecl: " + func_name + "(";
for (size_t i = 0; i < params.size(); ++i) {
if (i > 0) result += ", ";
result += params[i].first + " : " + params[i].second.toString();
}
result += ") -> " + type.toString();
return result;
}
};
// 函数调用节点
class FunctionCallNode : public ASTNode {
private:
std::string func_name;
std::vector<std::shared_ptr<ASTNode>> args;
SemanticAnalyzer& analyzer;
SymbolTable& symbol_table;
public:
FunctionCallNode(const std::string& name, const std::vector<std::shared_ptr<ASTNode>>& a,
SemanticAnalyzer& anal, SymbolTable& st)
: func_name(name), args(a), analyzer(anal), symbol_table(st) {}
void semanticCheck() override {
// 查找函数
Symbol* sym = symbol_table.findSymbol(func_name);
if (!sym || !sym->is_function) {
analyzer.addError(line_number, "未定义的函数: " + func_name);
type = TypeInfo(TypeKind::INT); // 默认返回类型
return;
}
// 检查参数匹配
if (args.size() != sym->type.param_types.size()) {
analyzer.addError(line_number, "函数调用参数数量不匹配: 期望 " +
std::to_string(sym->type.param_types.size()) +
", 实际 " + std::to_string(args.size()));
} else {
// 检查每个参数的类型
for (size_t i = 0; i < args.size(); ++i) {
args[i]->semanticCheck();
if (!analyzer.isTypeCompatible(TypeInfo(sym->type.param_types[i]), args[i]->type)) {
analyzer.addError(line_number, "参数 " + std::to_string(i+1) +
" 类型不匹配: 期望 " +
TypeInfo(sym->type.param_types[i]).toString() +
", 实际 " + args[i]->type.toString());
}
}
}
// 设置返回类型
type = TypeInfo(sym->type.return_type);
}
std::string toString() const override {
std::string result = "FunctionCall: " + func_name + "(";
for (size_t i = 0; i < args.size(); ++i) {
if (i > 0) result += ", ";
result += args[i]->toString();
}
result += ")";
return result;
}
};
// 赋值语句节点
class AssignmentNode : public ASTNode {
private:
std::shared_ptr<ASTNode> left;
std::shared_ptr<ASTNode> right;
SemanticAnalyzer& analyzer;
public:
AssignmentNode(std::shared_ptr<ASTNode> l, std::shared_ptr<ASTNode> r, SemanticAnalyzer& a)
: left(l), right(r), analyzer(a) {}
void semanticCheck() override {
left->semanticCheck();
right->semanticCheck();
// 检查左值是否可赋值
// 这里简化处理,实际需要检查左值是否是变量、数组元素等
// 检查类型兼容性
if (!analyzer.isTypeCompatible(left->type, right->type)) {
analyzer.addError(line_number, "赋值类型不兼容: 无法将 " +
right->type.toString() + " 赋值给 " + left->type.toString());
}
type = left->type;
}
std::string toString() const override {
return "Assignment: " + left->toString() + " = " + right->toString();
}
};
int main() {
// 创建语义分析器和符号表
SemanticAnalyzer analyzer;
SymbolTable symbol_table;
// 构建示例AST
std::vector<std::shared_ptr<ASTNode>> ast;
// 添加全局变量声明
ast.push_back(std::make_shared<VarDeclNode>("x", TypeInfo(TypeKind::INT),
nullptr, analyzer, symbol_table));
// 添加函数声明
std::vector<std::pair<std::string, TypeInfo>> params = {
{"a", TypeInfo(TypeKind::INT)},
{"b", TypeInfo(TypeKind::INT)}
};
auto func_body = std::make_shared<BinaryOpNode>("+",
std::make_shared<VarRefNode>("a", analyzer, symbol_table),
std::make_shared<VarRefNode>("b", analyzer, symbol_table),
analyzer
);
ast.push_back(std::make_shared<FunctionDeclNode>("add", params, func_body,
analyzer, symbol_table));
// 添加函数调用
std::vector<std::shared_ptr<ASTNode>> call_args = {
std::make_shared<VarRefNode>("x", analyzer, symbol_table),
std::make_shared<VarRefNode>("y", analyzer, symbol_table) // 未定义变量
};
ast.push_back(std::make_shared<FunctionCallNode>("add", call_args, analyzer, symbol_table));
// 执行语义分析
for (auto& node : ast) {
node->semanticCheck();
}
// 输出错误信息
if (analyzer.hasErrors()) {
std::cout << "语义分析错误:" << std::endl;
for (const auto& error : analyzer.getErrors()) {
std::cout << error << std::endl;
}
} else {
std::cout << "语义分析通过" << std::endl;
}
// 输出带类型信息的AST
std::cout << "\n带类型信息的AST:" << std::endl;
for (const auto& node : ast) {
std::cout
``
浙公网安备 33010602011771号