Redy语法分析--一元运算符(+ - ~)

3158阅读 1评论2012-03-23 NosicLin
分类:Python/Ruby

返回文档首页 

一元运算符(+ - ~ )

(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中

上一篇:Redy语法分析--语句与复合语句结点
下一篇:让语法树跑起来--开篇(1)

文章评论