LLVM12第三章之语义分析

1、Cale语言介绍

1.1、cale语言的语法形式(无二义性且非左递归文法)

在这里插入图片描述

1.2、cale语言示例

在这里插入图片描述

2、语义分析器

语义分析器负责遍历 AST 并检查语言的各种语义规则,例如:在使用变量之前必须声明变量,或者变量的类型必须在表达式中兼容。如果发现可以改进的情况,还可以输出警告。

2.1、语义分析类Sema定义

class Sema {
public:
  bool semantic(AST *Tree);
};

2.2、Sema类方法实现

semantic方法负责检查传入的AST语法书是否存在语义错误。其中DeclCheck类通过访问者模式对AST树进行语义检查。

bool Sema::semantic(AST *Tree) {
  if (!Tree)
    return false;
  DeclCheck Check;
  // 当前AST树接受访问者Check的访问
  Tree->accept(Check);
  return Check.hasError();
}

2.3、DeclCheck类实现

class DeclCheck : public ASTVisitor {
  llvm::StringSet<> Scope;       // 记录形参列表名称
  bool HasError;                 // 记录语义检查时是否存在错误

  // 错误类型:表达式使用未命名的形参、同名形参被指定两种错误
  enum ErrorType { Twice, Not };

  // 打印错误信息
  void error(ErrorType ET, llvm::StringRef V) {
    llvm::errs() << "Variable " << V << " "
                 << (ET == Twice ? "already" : "not")
                 << " declared\n";
    HasError = true;
  }

public:
  DeclCheck() : HasError(false) {}

  bool hasError() { return HasError; }
  
  // 检查Factor对象,如果Factor对应的标识符未在形参列表中声明,视为存在未声明的形参错误
  virtual void visit(Factor &Node) override {
    if (Node.getKind() == Factor::Ident) {
      if (Scope.find(Node.getVal()) == Scope.end())
        error(Not, Node.getVal());
    }
  };

	// 检查二元运算BinaryOp对象
  virtual void visit(BinaryOp &Node) override {
    // 递归检查左右表达式,并判断左右表达式是否存在
    if (Node.getLeft())
      // 二元运算的左表达式接受当前vistor访问
      Node.getLeft()->accept(*this);
    else
      HasError = true;
    if (Node.getRight())
     // 二元运算的右表达式接受当前vistor访问
      Node.getRight()->accept(*this);
    else
      HasError = true;
  };

  // 检查WithDecl对象
  virtual void visit(WithDecl &Node) override {
    // 编译calc语句所有的形参,保存到Scope容器中
    for (auto I = Node.begin(), E = Node.end(); I != E;
         ++I) {
         // 如果Scope容器中已存在当前形参,插入失败,认为存在同名形参错误
      if (!Scope.insert(*I).second)
        error(Twice, *I);
    }
    // 检查Calc语句的表达式
    if (Node.getExpr())
     // Calc语句的表达式接受当前vistor访问
      Node.getExpr()->accept(*this);
    else
      HasError = true;
  };
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值