Redy语法分析--文字常量结点

本文介绍Redy语言中的文字常量结点及其在语法树中的作用,并通过实例展示如何构建与执行简单的表达式语法树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址: http://blog.chinaunix.net/uid-26750235-id-3142980.html


文字常量结点

(literal constant)

()文字常量结点

在一门语言里面文字常量是基础,Redy里面文字常量有整数,长整数,浮点数,字符串,布尔值。文字常量可以在源程序中显于的使用,例如表达示1+2.3中有两个文字常量,1是整数型的文字常量,2.3是浮点型的文字常量。当解析器解析源代码,为之构造语法树时,需要用一个结点来表示文字常量,该结点称为文字常量结点,文字常量结点是叶结点,它不会再有其它子结点。

redy源码中,用AstNodeLiteral来表示文字常量结点,AstNodeLiteral继承AstObject。因为每一个文字常量结点都对应源代码中的一个文字常量,文字常量有5种:整数,长整数,浮点数,字符串,布尔值,这5种属于Redy中的基本数据类型,它们都继承Rojbect。具体的关系,如下图

图1

在图中有一个头为三角形箭头线段表示AstNodeLiteral继承AstObject。有一头为棱形的线段表示聚合,聚合是代表整体与部分的关系,表示AstNodeLiteralRobject组成。

构造表达式1+2.3的语法树,图片如下:

图2

图2中有两个文字常量结点,结点L1对应于表达式中的整数1,结点L2对应于表达式中浮点数2.3


()简单的虚拟机

在前面语法树的数据结构中讲过,所有AstObject的子类都必须实现结点的执行方式,为了讲述AstNodeLiteral的执行方法,在这里需要引入一个简单的虚拟机,该虚拟机只一个寄存器reg0,没了,该虚拟机就这么简单。

AstNodeLieral的执行方法很简单,就是把它所引用的文字常量的值放入寄存器reg0中,用代码来描述为:

代码1.1

  1. AstNodeLiteral.execute()
  2.     reg0=AstNodeLiteral.l_value
  3. end

如果要让图2中的语法树跑起来的话,还需要实现一个结点AstNodePlus的执行方式,代码描述为:

代码1.2

  1. AstNodePlus.execute()
  2.     AstNodePlus.left.execute() /*执行左边结点*/
  3.     left_value=reg0 /*左边结点执行后的结果保存在寄存器reg0,所以取出即可*/

  4.     AstNodePlus.right.execute() /*执行右边结点*/
  5.     right_value=reg0 /*从寄存器reg0取出右边结点执行后的节果*/

  6.     /*把左边结点的值怀右边结点的值相点后,放入寄存器reg0中*/
  7.     reg0=left_value+right_value 
  8. end

现在执行图中2的语法树没一点问题,假设你想把1+2.3的执行结果输出,用代码描述为:

代码1.3

  1. .....
  2. tree_root=parser("1+2.3"); /*构造语法树*/
  3. tree_root.execute() /*执行语法树*/
  4. result=reg0 /*从寄存器reg0中取出结果*/
  5. print result /*输出结果*/
  6. .....



返回文档首页 

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

AstNodeLiteral的代码位于 sur/syntax/ast_node_literal.h 中


1. 用户与权限管理模块 角色管理: 学生:查看实验室信息、预约设备、提交耗材申请、参与安全考核 教师:管理课题组预约、审批学生耗材申请、查看本课题组使用记录 管理员:设备全生命周期管理、审核预约、耗材采购与分发、安全检查 用户操作: 登录认证:统一身份认证(对接学号 / 工号系统,模拟实现),支持密码重置 信息管理:学生 / 教师维护个人信息(联系方式、所属院系),管理员管理所有用户 权限控制:不同角色仅可见对应功能(如学生不可删除设备信息) 2. 实验室与设备管理模块 实验室信息管理: 基础信息:实验室编号、名称、位置、容纳人数、开放时间、负责人 功能分类:按学科(计算机实验室 / 电子实验室 / 化学实验室)标记,关联可开展实验类型 状态展示:实时显示当前使用人数、设备运行状态(正常 / 故障) 设备管理: 设备档案:名称、型号、规格、购置日期、单价、生产厂家、存放位置、责任人 全生命周期管理: 入库登记:管理员录入新设备信息,生成唯一资产编号 维护记录:记录维修、校准、保养信息(时间、内容、执行人) 报废处理:登记报废原因、时间,更新设备状态为 "已报废" 设备查询:支持按名称、型号、状态多条件检索,显示设备当前可用情况 3. 预约与使用模块 预约管理: 预约规则:学生可预约未来 7 天内的设备 / 实验室,单次最长 4 小时(可设置) 预约流程:选择实验室→选择设备→选择时间段→提交申请(需填写实验目的) 审核机制:普通实验自动通过,高危实验(如化学实验)需教师审核 使用记录: 签到 / 签退:到达实验室后扫码签到,离开时签退,系统自动记录实际使用时长 使用登记:填写实验内容、设备运行情况(正常 / 异常),异常情况需详细描述 违规管理:迟到 15 分钟自动取消预约,多次违规限制预约权限 4. 耗材与安全管理模块 耗材管理: 耗材档案:名称、规格、数量、存放位置、
private void pictureBox1_Paint(object sender, PaintEventArgs e) { if (currentTransform != null) { e.Graphics.Transform = currentTransform; // 直接应用预计算矩阵 } e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // 计算实际绘制区域 var clientRect = pictureBox1.ClientRectangle; // 自动计算数据边界(需要预先获取points的实际范围) float dataMinX = points.Min(p => p.fiveX); float dataMaxX = points.Max(p => p.fiveX); float dataMinY = points.Min(p => p.sexY); float dataMaxY = points.Max(p => p.sexY); // 计算缩放比例 float scaleX = clientRect.Width / (dataMaxX - dataMinX); float scaleY = clientRect.Height / (dataMaxY - dataMinY); float zoomLevel = Math.Min(scaleX, scaleY) * 0.9f; // 保留10%边距 // 计算偏移量 float offsetX = -dataMinX * zoomLevel + (clientRect.Width - (dataMaxX - dataMinX) * zoomLevel) / 2; float offsetY = -dataMinY * zoomLevel + (clientRect.Height - (dataMaxY - dataMinY) * zoomLevel) / 2; e.Graphics.TranslateTransform(offsetX, offsetY); e.Graphics.ScaleTransform(zoomLevel, zoomLevel); currentTransform = e.Graphics.Transform; foreach (var point in points) { // 限制缩放级别最小值 float safeZoom = Math.Max(zoomLevel, 0.001f); float pointSize = Math.Min(4f / safeZoom, 100f); // 限制点尺寸最大值 // 计算坐标(确保用 float 运算) float blueX = point.fiveX - pointSize / 2; float blueY = point.sexY - pointSize / 2; // 检查坐标有效性 if (float.IsInfinity(blueX) || float.IsInfinity(blueY) || float.IsNaN(blueX) || float.IsNaN(blueY)) { continue; } // 绘制蓝色点 e.Graphics.FillEllipse(Brushes.Blue, blueX, blueY, pointSize, pointSize); // 同理处理红色点 float redX = point.eightX - pointSize / 2; float redY = point.nineY - pointSize / 2; if (float.IsInfinity(redX) || float.IsInfinity(redY) || float.IsNaN(redX) || float.IsNaN(redY)) { continue; } e.Graphics.FillEllipse(Brushes.Red, redX, redY, pointSize, pointSize); } if (currentTransform != null) { // 应用相同的变换矩阵 e.Graphics.Transform = currentTransform; // 在此绘制内容,坐标会自动适配 e.Graphics.DrawLine(Pens.Black, dataMinX, dataMinY, dataMaxX, dataMaxY); } }// 绘制蓝色点 e.Graphics.FillEllipse(Brushes.Blue, blueX, blueY, pointSize, pointSize); e.Graphics.FillEllipse(Brushes.Red, redX, redY, pointSize, pointSize);OverflowException 怎么解决
03-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值