• 基于原microc改进的编程语言原理与编译


    编程语言原理与编译

    1. 项目自评等级:(1-5) 请根据自己项目情况填写下表

    1.1 解释器

    功能完善程度自评备注
    bool 类型51
    float 类型52
    char 类型52
    For 循环54
    DoWhile 循环54
    DoUntil 循环54
    switch-case53
    模式匹配 match53
    自增自减 ++、–53可以识别 i++ 和 ++i
    三目运算符?:53
    += -= *= /=语法糖53
    位运算 << >>53
    占位符 pass52
    break54
    Continue54
    print 重写53

    1.2 编译器

    功能完善程度自评备注
    bool 类型51
    float 类型52
    char 类型52
    For 循环54
    DoWhile 循环54
    DoUntil 循环54
    switch-case53
    模式匹配 match53
    自增自减 ++、–53可以识别 i++ 和 ++i
    三目运算符?:53
    += -= *= /=语法糖53
    位运算 << >>53
    占位符 pass52
    break54
    Continue54
    print 重写53
    Java 虚拟机54新增了 11 条指令及新 print 和新类型的实现

    1.3 优化编译器

    功能完善程度自评备注
    bool 类型51
    float 类型52
    char 类型52
    For 循环54
    DoWhile 循环54
    DoUntil 循环54
    switch-case53
    模式匹配 match53
    自增自减 ++、–53可以识别 i++ 和 ++i
    三目运算符?:53
    += -= *= /=语法糖53
    位运算 << >>53
    占位符 pass52
    break54
    Continue54
    print 重写53
    Java 虚拟机54新增了 11 条指令及新 print 和新类型的实现

    2. 项目说明

    2.1 文件目录结构

    • src - Java 虚拟机
    • test/testinterpc - 解释器测试样例
    • test/testmicroc- 编译器测试样例
    • test/testMicroCC- 优化编译器测试样例
    • Absyn.fs - 抽象语法
    • CLex.fsl - fslex 词法定义
    • CPar.fsy - fsyacc 语法定义
    • Parse.fs - 语法解析器
    • Interp.fs - 解释器
    • interpc.fsproj - 解释器项目文件
    • Comp.fs - 编译器
    • microc.fsproj - 优化编译器项目文件
    • Contcomp.fs - 优化编译器
    • microcc.fsproj - 优化编译器项目文件
    • Machine.fs - 机器指令定义

    2.2 项目运行

    解释器
    //编译解释器 interpc.exe 命令行程序 
    dotnet restore  interpc.fsproj  //可选
    dotnet clean  interpc.fsproj    //可选
    dotnet build -v n interpc.fsproj //构建,-v n查看详细生成过程
    
    //执行解释器
    ./bin/Debug/net5.0/interpc.exe 测试文件 参数
    dotnet run -p interpc.fsproj 测试文件 参数
    dotnet run -p interpc.fsproj -g 测试文件 参数 //显示token AST 等调试信息
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    编译器
    //构建 microc.exe 编译器程序 
    dotnet restore  microc.fsproj //可选
    dotnet clean  microc.fsproj  //可选
    dotnet build  microc.fsproj  //构建
    
    dotnet run -p microc.fsproj 测试文件  // 执行编译器,编译测试文件,并输出.out 文件
    dotnet run -p microc.fsproj -g 测试文件   // -g 查看调试信息
    
    ./bin/Debug/net5.0/microc.exe -g 测试文件  // 直接执行构建的.exe文件,同上效果
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    优化编译器
    dotnet restore  microcc.fsproj
    dotnet clean  microcc.fsproj
    dotnet build  microcc.fsproj  //构建编译器
    
    dotnet run -p microcc.fsproj 测试文件 //执行编译器
    ./bin/Debug/net5.0/microcc.exe 测试文件  //直接执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Java 虚拟机
    javac Machine.java
    java Machine .out文件 参数
    
    javac Machinetrace.java
    java Machinetrace .out文件 参数
    java Machinetrace .out文件 参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3 功能实现(具体说明仅在解释器中,编译器和优化编译器不再重复)

    解释器

    解释器基于原 microc 改进并在其上新增了上表所列的功能并对部分功能进行了改进。

    • bool 类型

      通过 bool 关键词定义,只支持赋值为 truefalse,可以通过 print'b' 类型来输出。

      void main(){
        bool x;
        bool k;
        x=true;
        k=false;
        print 'b' : x;
        print 'b' : k;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    在这里插入图片描述

    • char 类型

      通过 char 关键词定义,支持赋值使用 ' ' 包裹的一个字符,可以通过 print'c' 类型来输出。

      void main(){
        char a;
        a='a';
        print 'c' : a;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    在这里插入图片描述

    • float 类型

      通过 float 关键词定义,支持浮点数赋值,支持向下数据类型转换,可以通过 print'f' 类型来输出。

      void main(){
        float a;
        a=1.1111;
        print 'f' : a;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    在这里插入图片描述

    • For 循环

      for 循环的语句结构为:

      for(表达式 1; 表达式 2; 表达式 3){
      语句块
      }

      运行过程为:

      1. 先执行“表达式 1”
      2. 再执行“表达式 2”,如果它的值为真(非 0),则执行循环体,否则结束循环。
      3. 执行完循环体后再执行“表达式 3”。
      4. 重复执行步骤 2) 和 3),直到“表达式 2”的值为假,就结束循环。

      上面的步骤中,2) 和 3) 是一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。

      void main(int n){
        int i;
        for (i=0;i<n;i=i+1){
          print 'd' : i;
        }
        print 'd' : n;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    在这里插入图片描述

    • DoWhile

      dowhile 循环的语句结构为:

      do
      {
      语句块;
      }
      while (表达式);

      进入循环时,程序会先执行一次循环体,然后会对表达式进行判断,若表达式满足条件,继续执行,反之退出循环

      void main(int n){
        int i;
        i=0;
        do{
          i=i+2;
          print 'd' : i;
        }while(i<n);
        print 'd' : n;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    在这里插入图片描述

    • DoUntil

      DoUntil 循环的语句结构为:

      do
      {
      语句块;
      }
      until(表达式);

      进入循环时,程序会先执行一次循环体,然后会对表达式进行判断,若表达式不满足条件,继续执行,反之退出循环

      void main(int n){
        int i;
        i=0;
        do{
          print 'd' : i;
          i=i+1;
        }until(i>n);
        print 'd' : n;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    在这里插入图片描述

    • 三目运算符

      三目运算符的格式为:

      <表达式1> ? <表达式2> : <表达式3>;
      
      • 1

      返回值:先求表达式 1 的值,如果为真,则执行表达式 2,并返回表达式 2 的结果;如果表达式 1 的值为假,则执行表达式 3,并返回表达式 3 的结果。

      void main(int n){
        int x;
        x=n>6 ? 0:1;
        print 'd' : x;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    在这里插入图片描述

    • 位运算 << >>

      >> 右移操作会将运算数的二进制向右移动 n 位,<< 左移操作会将运算数的二进制向左移动 n

      int main(){
        int n;
        n=30;
        print 'd' : n;
        print 'd' :n<<3;
        print 'd' :n>>2;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    在这里插入图片描述

    • switch-case

      多分支选择的 switch 语句的格式为

      switch(表达式){
      case 常量表达式 1: 语句 1;
      case 常量表达式 2: 语句 2;

      case 常量表达式 n: 语句 n;
      default: 语句 n+1;
      }

      计算表达式的值, 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有 case 后的语句。如表达式的值与所有 case 后的常量表达式均不相同时,则执行 default 后的语句。

      void main(int n){
        switch(n){
          case 1: {print 'd' : 1;break;}
          case 2: {print 'd' :0;break;}
          default: print 'd' : 233;
        }
        print 'd' : n;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    在这里插入图片描述

    • 模式匹配 match

      match 语句的格式为

      match ecp with:

      | 条件 1 -> 语句块 1

      | _ -> 语句块 n

      逐个比较判断体 ecp 与下面哪个条件一致则执行对应语句块,若都不一致,则执行 _ 后的语句块 n

      void main(int ecp){
        match ecp with
        | 1 -> {print 'd' : ecp;break;}
        | 2 -> {print 'd' : ecp+1;break;}
        | _ -> print 'd' : 0;
        print 'd' : ecp;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    在这里插入图片描述

    • 自增自减 ++ –

      ++ 和–可以实现参数的 +1,如 I++ 等价于 I=I+1

      其中 I++ 表示返回 I 的值,然后 I+1,++I 表示先 I+1 然后返回 I 的值

      void main(int n){
        print 'd' : n;
        n=n++;
        print 'd' : n;
        n=++n;
        print 'd' : n;
        n=n--;
        print 'd' : n;
        n=--n;
        print 'd' : n;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    在这里插入图片描述

    • += -= *= /= 语法糖

      I+=n 等价于 I=I+nI-=n 等价于 I=I-nI*=n 等价于 I=I*nI/=n 等价于 I=I/n

      void main(int n){
        int a;
        a=1;
        a+=n;
        print 'd' :a;
        int b;
        b=2;
        b-=n;
        print 'd':b;
        int c;
        c=4;
        c*=n;
        print 'd':c;
        int d;
        d=6;
        d/=n;
        print 'd':d;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

    在这里插入图片描述

    • 占位符 PASS

      占位符思想来源于 python,用于占位,没有实际含义。

      int main(){
        int i;
        for (i = 0; i < 10; i++) {
            pass;
        }
        print 'c':'1';
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    在这里插入图片描述

    • continue

      跳过本次循环剩下语句,直接进入下一次循环

      void main(){
        int i;
        i=0;
        do{
            i=i+1;
            if (i%2==0) 
                continue;
            print 'd' : i;
        }
        while(i<100);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    在这里插入图片描述

    • print

      为了适应新的数据类型,所以我们重写了 print,在此处我们定义了三种类型符:c-char,d-int,f-float

      void main(){
        print 'd' :1;
      }
      
      • 1
      • 2
      • 3
  • 相关阅读:
    AI也需要透明度?是的,需要
    Python 命令行参数:Argparse 与 Click
    【1990年-2022年】地级市人均GDP数据集(excel+shp)
    LeetCode 2360. 图中的最长环
    docker容器启动rabbitmq
    ssm(Spring+SpringMVC+MyBatis)台球室内乒乓球室体育器械租赁收费系统
    【Redis学习1】Redis持久化机制详解
    认识字符集、ASCII、GBK、Unicode、UTF-8
    达梦8数据库导出导入
    FebHost:CO域名在搜索引擎排名中是否高于.COM域名?
  • 原文地址:https://blog.csdn.net/newlw/article/details/127414563