中文脚本编译器的设计与实现(一)概论(2)编译器的总体结构

32 篇文章 0 订阅
6 篇文章 0 订阅

脚本编译器的目标是将源脚本文件变成可执行文件。

比如下面这一段源码

#以下是测试脚本
让 x 变成 (10+2)/50+2/5+100;

输出 "x -> " 拼接 x ;


如果(x 小于或等于 100)
{
	输出 "x 是个很小的数";
}
否则
{
	输出 "x 是个较大的数";
}

让 x 变成 1;(x 小于等于 10) 时则重复执行 
{
	输出 ("x -> " 拼接 x);
	让 x 变成 x+1;    #非专业程序员对这一句很困惑
}

输出 "x -> " 拼接 x ;

经过编译后变成了如下可执行的代码:

L0: goto L1;
L1: $env = array_pop($envStack);
L2: $env['x']=(10+2)/50+2/5+100;
L3: echo "x -> ".$env['x'],"\n";
L4: if (!($env['x']<=100)) goto L7;
L5: echo "x 是个很小的数","\n";
L6: goto L8;
L7: echo "x 是个较大的数","\n";
L8: $env['x']=1;
L9: if (!($env['x']<=10)) goto L13;
L10: echo ("x -> ".$env['x']),"\n";
L11: $env['x']=$env['x']+1;
L12: goto L9;
L13: echo "x -> ".$env['x'],"\n";
L14: goto L15;
L15: $this->procState='finished';
L16: ;

可能有的人会好奇,以上是可执行的代码吗?

是的,以上的内容就是可以执行的php代码。

但是又和平常我们见到的php代码不太一样,最明显的特点是,以上代码的每一行都有标号,而且有非常多的goto语句。有的php的开发人员可能很少用到goto语句,但实际上所有的程序结构最终都可以归结为条件goto结构。

只要有了条件跳转,分支结构,循环结构都可以用条件跳转来实现。

有的人可能会问,为什么要将源脚本编译成可执行的php脚本呢?不能编译成机器代码吗?

回答是,只要设计出相应的编译规则,源脚本就可以编译成任何你想要的目标语言,比如机器语言,汇编语言,C语言,php语言,python语言等等。

在这里我将源脚本编译成php语言后,就可以让php执行得到的编译结果。

我的目标并不是追求执行的高效,而是追求开发的高效,所以编译成php代码就可以了。实际上如果有需要,我也可以将源码编译成C语言,然后再调用C语言的编译器编译成机器代码。

为了完成从源码到目标代码的转换,我们一般不会一次到位,而是要分成几步走。大致说来,可以分成三大步

  1. 词法分析,将源文本切分成一个一个的记号串(token)
  2. 语法分析,将输入的记号(token)数组归约为各级语法单元
  3. 生成目标代码,根据语法分析的结果,将记号串翻译成目标语言的指令块

需要注意的是,本项目采用边进行语法分析,边进行目标代码的生成。语法分析的归约过程完成了,目标代码的翻译(编译)也就完成了。这种操作方式可以称之为语法制导翻译。

插一句,上面提到将源码编译成可执行的php代码,不需要像C编译器那样编译完成后还要做链接工作,由于不用考虑链接,所以项目就可以很简炼。即使是为了追求执行的高效,也完全可以先编译成C代码,然后再编译成可执行文件。所谓大树底下好乘凉,C语言可是一株参天大树啊。

按照上面的总的设计原则,本项目的总体结构如下:

在这里插入图片描述

其中
1 : script_lexer.php 为词法分析器,引用lexi_rule目录下的词法规则文件

2: script_parser.php为语法分析器,调用syntax_rule目录下的语法规则文件

3: coder目录下存放各种编码器,编码器被语法分析器在语法分析的过程中调用,用于生成目标代码,编码器与语法分析器是可组合的,要生成另一种目标语言时只要换用相应的编码器即可,其它的模块不用改动。

4: script_engine.php为目标代码的执行引擎,相当于java语言中jvm的地位,用于执行目标代码,中断,恢复执行等等。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值