Chinaunix首页 | 论坛 | 博客
  • 博客访问: 236114
  • 博文数量: 32
  • 博客积分: 424
  • 博客等级: 准尉
  • 技术积分: 465
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-02 10:23
文章分类

全部博文(32)

文章存档

2012年(32)

分类: Python/Ruby

2012-03-23 14:08:31

返回文档首页 

一元运算符(+ - ~ )

(unary operator(+ - ~))

()一元运算符

一元运算符是只有一个操作数的运算符,在Redy中有:'+' , '-' , '~' 这么三种,它们的运算优先级相等,结合方向为自右到左。当这三个运算符的操作数为整数,长整数时,它们代表着正号,负数,取反。例如:

代码1.1

  1. a=1
  2. -a /*结果为-1*/
  3. +a /*结果为1*/
  4. ----a /*四个负号,结果为1*/
  5. ++++a /*不管多少个正号,结果还是1*/
  6. +-+-+-a /*正号对我没影响,可是负号有3个,结果为-1*/
  7. ~a /*1取反,结果为-2*/
  8. ~~a /*两次取反,还原了,结果为1*/

析解器解析代码1.1并为之构造语法树,需要分别用结点来表示这三个一元运算符。在Redy源码中,符号'+' 用结点AstNodePositive表示,符号'-'用结点AstNodeNegative表示,符号'~'用结点AstNodeNegated 表示,这三个结点都继承同一个结点AstNodeUExpr。用uml来表示它们之间的关系为:

1

1的内容为:

  1. AstNodeNegativeAstNodePositiveAstNodeNegated继承AstNodeUExpr

  2. AstNodeUExpr继承AstObject

  3. AstNodeUExpr由一个子结点s_value组成


()语法树实例1

下面来看一元运算符的实例。

代码1.2

  1. -+-1

在代码1.2中有3个一运算符和一个整数型的文字常量,要为之构造语法树,则需4个结点,三个一元运算符结点,一个文字常量结点(文字常量结点在前面文章中讲到)。具体的语法构如下:

2

要图2的语法树跑起来,需要从结点root来始执行,然后递归调用。AstNodeLiteral的执行方式前面已经讲到过,但还有两个节点AstNodePositiveAstNodeNegative的执行方式还没有实现。下面来看:

AstNodePositive的执行方式

代码1.3

  1. AstNodePositive.execute()
  2.     AstNodePositive.s_value.execute() /*执行子节点*/
  3.     value=reg0 /*子结点的执行后的结果,在寄存器reg0中*/
  4.     ret=value.positive() /*调用positive()方法*/
  5.     reg0=ret /*把结果保存存reg0中,供父结点使用*/
  6. end

其中需要说明的是;

1)在前面一章中,介绍了一个简单的虚拟机,该虚拟机有一个寄存器reg0。每个节点执行过后,都必须把结果放在寄存器reg0中。

2)在Redy中每一个对象,如果要支持某种运算符,那就必须实现该运算相对应的方法,例如要支持一元运算符'+',就必须实现positive方法;要支持一元运算符'-',就必须实现negative方法;要支持一元运算符'~',就必须实现negated方法。


AstNodeNegative的执行方式:

代码1.4

  1. AstNodeNegative.execute()
  2.     AstNodeNegative.s_value.execute() /*执行子节点*/
  3.     value=reg0 /*子结点的执行后的结果,在寄存器reg0中*/
  4.     ret=value.negative() /*调用negative()方法*/
  5.     reg0=ret /*把结果保存存reg0中,供父结点使用*/
  6. end

现在来运行图1中的语法树,一点问题都没有了。


()语法树实例2

代码1.5

  1. ~+-4

为代码1.5构造语法树为:

3

在实例1中,已经实现了AstNodeNegative,和AstNodePositive的执行方法,要让图3个语法树跑要来,还需要实现AstNodeNegated的执行方法,具体如下:

代码1.6

  1. AstNodeNegated.execute()
  2.     AstNodeNegated.s_value.execute() /*执行子节点*/
  3.     value=reg0 /*子结点的执行后的结果,在寄存器reg0中*/
  4.     ret=value.Negated() /*调用Negated()方法*/
  5.     reg0=ret /*把结果保存存reg0中,供父结点使用*/
  6. end

Ok,现在就可以执行图3的语法树。


返回文档首页 

附:  代码下载: git clone git://git.code.sf.net/p/redy/code redy-code

AstNodePositive ,AstNodeNegative, AstNodeNegated  位于src/syntax/  文件ast_node_unary_expr中

阅读(1905) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

NosicLin2012-03-26 08:25:10

小尾巴鱼121121: i=3; j=i+(++i)+(++i); j=?.....
在c语言里面 '++' 是一种前缀运算符,表示自增。
redy不支持'++'运算符,当出现'++'时,会被解析成两个正号。
即 i=3 ; ++i 的值表示3 ,而不是4。