语义分析完成的功能
image

语义分析是编译器的重要阶段,主要完成以下功能:

  1. 符号表管理
    作用域管理:实现嵌套作用域的进入和退出

    符号存储:记录变量、函数、类型等标识符的信息

    符号查询:支持按名称查找符号,考虑作用域层级

  2. 类型系统实现
    类型表示:定义基本类型(int, float, char等)和复合类型(数组、指针、函数)

类型兼容性:检查赋值、运算中的类型匹配

类型推导:为表达式推断结果类型

  1. 声明检查
    重复声明检测:防止在同一作用域重复声明标识符

未声明使用检查:确保使用的变量、函数都已声明

函数声明验证:检查函数参数和返回类型

  1. 类型检查
    赋值兼容性:检查左值和右值的类型是否匹配

运算类型检查:验证操作数的类型是否支持相应运算

函数调用匹配:检查实参类型与形参类型的兼容性

  1. 控制流检查
    返回语句检查:确保函数有正确的返回值

break/continue位置:验证只能在循环或switch中使用

函数结束路径:检查所有执行路径是否有返回值

  1. 其他语义规则
    数组维度检查:验证数组访问的下标有效性

指针运算限制:确保指针运算的合法性

结构体成员访问:验证成员是否存在

  1. 错误报告
    精准定位:报告错误发生的具体位置(行号)

详细描述:提供清晰的错误信息说明

错误恢复:尽可能继续分析以发现更多错误

  1. 中间表示生成
    带类型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

``