文字常量结点
(literal constant)
(一)文字常量结点
在一门语言里面文字常量是基础,Redy里面文字常量有整数,长整数,浮点数,字符串,布尔值。文字常量可以在源程序中显于的使用,例如表达示1+2.3中有两个文字常量,1是整数型的文字常量,2.3是浮点型的文字常量。当解析器解析源代码,为之构造语法树时,需要用一个结点来表示文字常量,该结点称为文字常量结点,文字常量结点是叶结点,它不会再有其它子结点。
在redy源码中,用AstNodeLiteral来表示文字常量结点,AstNodeLiteral继承AstObject。因为每一个文字常量结点都对应源代码中的一个文字常量,文字常量有5种:整数,长整数,浮点数,字符串,布尔值,这5种属于Redy中的基本数据类型,它们都继承Rojbect。具体的关系,如下图
图1
在图中有一个头为三角形箭头线段表示AstNodeLiteral继承AstObject。有一头为棱形的线段表示聚合,聚合是代表整体与部分的关系,表示AstNodeLiteral由Robject组成。
构造表达式1+2.3的语法树,图片如下:
图2
图2中有两个文字常量结点,结点L1对应于表达式中的整数1,结点L2对应于表达式中浮点数2.3。
(二)简单的虚拟机
在前面语法树的数据结构中讲过,所有AstObject的子类都必须实现结点的执行方式,为了讲述AstNodeLiteral的执行方法,在这里需要引入一个简单的虚拟机,该虚拟机只一个寄存器reg0,没了,该虚拟机就这么简单。
AstNodeLieral的执行方法很简单,就是把它所引用的文字常量的值放入寄存器reg0中,用代码来描述为:
代码1.1
- AstNodeLiteral.execute()
- reg0=AstNodeLiteral.l_value
- end
如果要让图2中的语法树跑起来的话,还需要实现一个结点AstNodePlus的执行方式,代码描述为:
代码1.2
- AstNodePlus.execute()
- AstNodePlus.left.execute() /*执行左边结点*/
- left_value=reg0 /*左边结点执行后的结果保存在寄存器reg0,所以取出即可*/
- AstNodePlus.right.execute() /*执行右边结点*/
- right_value=reg0 /*从寄存器reg0取出右边结点执行后的节果*/
- /*把左边结点的值怀右边结点的值相点后,放入寄存器reg0中*/
- reg0=left_value+right_value
- end
现在执行图中2的语法树没一点问题,假设你想把1+2.3的执行结果输出,用代码描述为:
代码1.3
- .....
- tree_root=parser("1+2.3"); /*构造语法树*/
- tree_root.execute() /*执行语法树*/
- result=reg0 /*从寄存器reg0中取出结果*/
- print result /*输出结果*/
- .....
附: 代码下载: git clone git://git.code.sf.net/p/redy/code redy-code
AstNodeLiteral的代码位于 sur/syntax/ast_node_literal.h 中