编译器指令重排_编译器-7:指令

编译器指令重排

问候,

介绍

文章的这一部分晚了一个星期。 我为此表示歉意; 我的借口是:

bizzy,bizzy,bizzy; 我参加了一门不错的课程,我不得不讲一点,

根本没有时间写作。

我们已经走了很长一段路; 先前的文章讨论了以下方面

的编译器:

1:概述,概述编译器和

他们编译的语言;

2:负责转换字符的令牌生成器(或词法分析器)

输入流到令牌输入流;

3:形式语法,描述一种(编程)语言的语法,并且

形成实施语言解析器的指南;

4:编译器的多个部分所需的所有必要簿记; 的

表格定义函数,运算符和其他预定义符号;

5:解析器要注意令牌流是否遵循某种语法。

解析器与编译器的代码生成器部分紧密合作。

6:执行或评估生成的指令序列的解释器。

使用说明

本文的最后一部分讨论了说明本身。 每一个

指令实现此接口:


public interface Instruction extends Serializable { 
    public void execute(Interpreter interpreter) throws InterpreterException;
    public void initialize(String token, int arity);
} 
第二种方法仅在指令为

建造。 第一种方法由解释器调用。 就这些了

解释器感兴趣的是:按以下顺序调用每个指令:

说明。

这是指令类层次结构的顶部:


Instruction
    |
    +-------+- AbstractInstruction
        |
        +-------+- AbstractFunctionInstruction
        |    |
        |    +----------- FunctionInstruction
        |    |
        |    +----------- UserInstruction
        |
        +--------- QuoteInstruction 
AbstractInstruction类实现特定对象的名称和属性

指令。 指令的均等性等于

该特定指令占用的堆栈; 例如'+'的组合

运算符等于2,名称等于“ +”。

在AbstractInstruction下方,有两种指令的子类型:

AbstractFunctionInstruction和QuoteInstruction。 第一个子类

实现普通的内置函数以及用户定义的函数。

QuoteInstruction实现特殊的函数类型指令。 一个例子

这样的指令是IfInstruction:Arity等于3及其名称

是“如果”。 允许我们键入以下内容:


if (x, y, z) 
如果表达式“ x”不等于零,则“ if”函数的值等于

'y',否则该值等于'z'。 如您先前所读

本文的一部分,将生成的x,y和z指令传递给

IfInstruction原样,即'if'指令传递了

组成表达式“ x”的指令要执行的解释器。

如果堆栈的顶部元素不为零,则“ y”的指令序列

传递给解释器,否则用于表达的指令序列

“ z”被传递给解释器。

FunctionInstruction是普通内置函数的基类

例如'sin','cos','log'等。UserInstruction处理所有用户定义的

功能。

功能

运算符实现为FunctionInstructions。 没什么奇怪的

关于它; 比较一下:


add(x, y)
x+y 
只是源代码中的符号有点“奇怪”,即“ +”

运算符兼作“添加”功能; 两者是相同的。

函数从堆栈中弹出其参数并计算其值。 对于“ +”

运算符将添加操作数,并将结果推回堆栈中。 对于,

例如,“正弦”函数,从堆栈中弹出一个操作数,正弦为

计算并把结果再次推回堆栈。

与其在每个类中实现所有的推送和弹出,

AbstractFunctionInstruction会处理所有这一切。 查看随附的源代码

与本文的前一部分。

实现了以下功能:

+-! (一元运算符)

<<= ==!=> =>

+-

* /

^

罪恶谭

经验日志

最大最小吸收

所有功能都具有众所周知的语义。

堆栈功能

除了这些“正常”功能外,还可以使用其他功能

显式操纵数据栈。

实现了以下功能:

arg(n):将第n个元素从堆栈的顶部移到顶部;

top(n):将第n个元素从堆栈的顶部复制到顶部;

clear():清除整个堆栈;

depth():推送堆栈上堆栈元素的数量。

您可以使用附件中提供的软件来使用这些功能

本文前面的部分。 如果破坏堆栈,则不会造成任何危害,即

解释器发出错误的栈信号并抛出异常

被打印,执行就停止了。 如果要使用Interpreter类

在您自己的软件中,您可以打印一条消息并开始评估另一个序列

指令。 随意玩。

清单

我们的小语言支持简单的列表,例如'+'功能/操作符可以

在简单的双操作数上调用,例如“ 3 + 4”,但其一个或两个

操作数也可以是列表。 如果一个操作数是一个列表,则所有列表都具有

简单的意思是:一维相同长度的列表; 这里

以下是一些示例:


{3, 4} + 5         // {8, 9}
{3, 4} + {5, 6}        // {8, 10}
{3, 4} + {5, 6, 7}    // error
{3, 4} + {5, {6, 7}}    // error
min({3, 6}, {5, 4})    // {3, 4}
max({3, 6}, 5)        // {5, 6} 
AbstractFunctionInstruction负责处理所有这一切; 如果至少

操作数是一个列表,然后所有表示该函数的操作数的列表

需要简单且长度相同。 AbstractFunctionInstruction通过

函数的双操作数并收集结果。 最终它建立

再次列出结果。

一些函数绕过该机制,即它们自己处理列表操作数。

还记得“ listfunc”保留字吗? 使用“ listfunc”定义的用户功能

标记保留字,以便绕过上述机制。

还有一些内置函数可以处理列表:

append(x,y)//将y附加到x

aslist(n)//将前n个堆栈元素存储在列表中

concat(x,y)//将x和y合并到一个新列表中

head(x)//列表x的第一个元素

tail(x)//除列表x的第一个元素外的所有元素

join(x,y)//加入两个列表x和y

size(x)//列表x中的元素数

同样,请随意使用这些功能。 好有趣。 看看你能找到什么

append,concat和join确实可以做到以及它们之间的区别。

报价说明

上面已经提到了QuoteInstructions之一; 有三种

这些定义的指令中:

if(x,y,z)//如果(x)则y else z

while(x,y)// 0或y的最后结果

generate(x,y)//而(x)将y附加到列表

请尝试使用随附的软件(请参阅上一篇文章)

如果您喜欢冒险,请使用已经实现的类作为蓝图

为您自己的功能。 如果不是冒险的话。 别忘了改变

.properties文件。

结束语

鉴于这篇大型文章中描述的所有软件,轻而易举地

实施一个表达式评估器。 只需几行代码即可完成

工作。 这个口译员不仅可以做很多,但我留给你

想像力想出可以将这个小系统

辛苦了 即使只是打印生成的指令(尝试!)也可以

是一个教育经历:您将免费看到后缀翻译的中缀。

这是评估器方法:


// evaluate the expression, throws InterpreterExcetpion if anything's wrong
public double evaluate(String expression) throws InterpreterException { 
    // parse the string
    Code code= new Parser().parse(new StringReader(expression)); 
    // do the evaluation and get the stack top
    Value value= new Interpreter().executeSub(code); 
    // convert the value back to a double
    return value.getDbl();
} 
我希望人们实际上已经阅读了这一切。 如果您这样做:恭喜,您

一定学到了很多东西,我希望附带的软件可以是任何

为您使用。

下一个技巧将涉及文本处理和查询。 我其实还没有

实施任何操作,但我会提出一些建议。

亲切的问候,

乔斯

翻译自: https://bytes.com/topic/java/insights/672530-compilers-7-instructions

编译器指令重排

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值