返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >如何利用Python实现简单C++程序范围分析
  • 645
分享到

如何利用Python实现简单C++程序范围分析

2024-04-02 19:04:59 645人浏览 泡泡鱼
摘要

目录1. 实验说明2. 项目使用3. 算法原理3.1 构建CFG3.2 构建Constraint Graph3.3 构建E-SSA Constraint Graph3.4 三步法3.

1. 实验说明

问题要求:针对静态单赋值(SSA)形式的函数中间代码输入,输出函数返回值的范围

实现思路: 基本根据 2013年在CGo会议上提出的“三步法”范围分析法加以实现[3],求得各个变量的范围

算法优势:空间复杂度和时间复杂度都是 O(n),效率高

算法瓶颈: “三步法”的功能存在较大局限,它只能分析各个变量的最大范围,对活跃变量只做了最简单的考虑,因此最终得到的范围比较不准确,往往只能得到范围的一个界

2. 项目使用

python main.py (ssa文件路径在main.py中设置)

不需要安装任何库。

3. 算法原理

简单概括:采用三步法(2013年在CGO会议上提出)

3.1 构建CFG

代码:\src\eSSAConstraintGraph.py; \src\structure.py

功能:解析SSA,构建CFG。

由于函数之间存在调用关系,因此首先把SSA划分成不同的函数的SSA,再分别构建CFG。CFG中保留了每一个函数的语句、Block之间的关系,为下一步构建Constraint Graph打基础。

CFG的结构如下:

# CFG类      
class CFG:
    def __init__(self):
        self.name = ''
        self.Blocks = []
        self.Edges = []
        self.Arguments = []

3.2 构建Constraint Graph

代码:\src\eSSAConstraintGraph.py

三步法的前提是构建Constraint Graph数据结构如下。在这一步中,我用自己定义的数据类型Mynode来表示一条Constraint

# Constraint Graph类      
class ConstraintGraph:
    def __init__(self, cfg):
        self.MyNodes = []            #基本节点,每一个节点是一个Constraint
        self.MyConditions = []        #用于后面E-SSA Constraint Graph补充条件
        self.cfg = cfg             
        self.Arguments = []            #输入参数
        self.returnName = ''        #输出参数
# MyNode : Constraint Graph的节点,也就是保存变量范围的地方
class MyNode:
    def __init__(self, t= "", name = "",  args = [], result = [], fromBlock = 0, Statement = ''):
        self.type = t             #节点类型:leave 叶节点存放范围和值 #op运算符 #var变量名
        self.name = name.strip()  #节点名称:运算名称,或变量名称
        self.args = args    #参数,一个节点是另一个节点的argument,意味着二者之间有边相连
        self.result = result        #被用到哪,一个节点是另一个节点的result,意味着二者之间有边相连
        self.Conditions = []        #约束条件, 在后面E-SSA Constraint Graph中补充条件
        self.fromBlock = fromBlock  #在CFG的哪个Block中定义的
        self.Statement = Statement  #在SSA中的哪条Statement中
        self.Range = Range()        #节点范围
        self.size = ''
        self.input = False
# Range由两个Bound组成 
class Range:
    def __init__(self ):
        self.lowBound = Bound()
        self.highBound = Bound()
# Bound由值和类型组成
class Bound:
    def __init__(self):
        self.value = 'None'      # inf 最大值 ; -inf 最小值; None 未设置; Not Exists 不存在
        self.size = 'None'       #边界是 int or float

需要注意的是,在解决两个函数之间的调用关系时,将被调用的函数**内联进原函数**。我将被调用的函数的所有变量名都加入相应的后缀,比如`foo`调用`bar`函数,那么`bar`中的变量`i_1`将被更名保存为`i_1#bar$1`,其中#是变量原名和后缀分割符,$是函数名和一个随机数的分割符,\$的作用是为了区分多次调用同一个函数的情况。

3.3 构建E-SSA Constraint Graph

代码:`\src\eSSAConstraintGraph.py`

这一步用于解决条件的添加。诸如`if (i_2 < j_3)`这样的条件。在MyNode节点类型中,我设置了Conditions结构用于保存条件。Condition的数据结构如下:

 Class Description : Constraint Graph中的条件,附加在MyNode中

class MyCondition:
    def __init__(self, condition, index):
        self.condition = condition
        self.arg1 = re.sub("\(.*\)", "",condition.split()[0].strip())
        self.arg2 = re.sub("\(.*\)", "",condition.split()[2].strip())
        self.op = condition.split()[1].strip()
        self.index = index

其中,arg1和arg2分别表示条件的两个参数,op表示条件的比较运算符。在Future Resolution这一步会进行比较,进行范围的约束。

以t7.ssa为例,得到的E-SSA Constraint Graph如下:

call bar$1  in 2 : |Arguments: i_2,|Result: |Conditions: 
var i_2  in 2 : |Arguments: |Result: bar$1,i#bar$1,i_2#bar$1,|Conditions: 
var j_4  in 2 : |Arguments: _1#bar$1,|Result: bar$2,i#bar$2,i_2#bar$2,|Conditions: 
ret bar$1  in 2 : |Arguments: |Result: j_4,|Conditions: 
call bar$2  in 2 : |Arguments: j_4,|Result: |Conditions: 
var k_6  in 2 : |Arguments: _1#bar$2,|Result: _7,|Conditions: 
ret bar$2  in 2 : |Arguments: |Result: k_6,|Conditions: 
var _7  in 2 : |Arguments: k_6,|Result: |Conditions: 
var i_2#bar$1  in 3 : |Arguments: i_2,|Result: +,-,|Conditions: 0#bar$1 0|
leaf 10  in 3 : |Arguments: |Result: +,|Conditions: 
op +  in 3 : |Arguments: i_2#bar$1,10,|Result: _3#bar$1,|Conditions: 0#bar$1 0|
var _3#bar$1  in 3 : |Arguments: +,|Result: PHI,|Conditions: 0#bar$1 0|
leaf 5  in 4 : |Arguments: |Result: -,|Conditions: 
op -  in 4 : |Arguments: 5,i_2#bar$1,|Result: _4#bar$1,|Conditions: 0#bar$1 1|
var _4#bar$1  in 4 : |Arguments: -,|Result: PHI,|Conditions: 0#bar$1 1|
op PHI  in 4 : |Arguments: _3#bar$1,_4#bar$1,|Result: _1#bar$1,|Conditions: 0#bar$1 1|
var _1#bar$1  in 4 : |Arguments: PHI,|Result: j_4,|Conditions: 0#bar$1 1|
leaf i#bar$1  in  : |Arguments: i_2,|Result: |Conditions: 
var i_2#bar$2  in 3 : |Arguments: j_4,|Result: +,-,|Conditions: 0#bar$2 0|
leaf 10  in 3 : |Arguments: |Result: +,|Conditions: 
op +  in 3 : |Arguments: i_2#bar$2,10,|Result: _3#bar$2,|Conditions: 0#bar$2 0|
var _3#bar$2  in 3 : |Arguments: +,|Result: PHI,|Conditions: 0#bar$2 0|
leaf 5  in 4 : |Arguments: |Result: -,|Conditions: 
op -  in 4 : |Arguments: 5,i_2#bar$2,|Result: _4#bar$2,|Conditions: 0#bar$2 1|
var _4#bar$2  in 4 : |Arguments: -,|Result: PHI,|Conditions: 0#bar$2 1|
op PHI  in 4 : |Arguments: _3#bar$2,_4#bar$2,|Result: _1#bar$2,|Conditions: 0#bar$2 1|
var _1#bar$2  in 4 : |Arguments: PHI,|Result: k_6,|Conditions: 0#bar$2 1|
leaf i#bar$2  in  : |Arguments: j_4,|Result: |Conditions: 

Conditions:
i_2(D) >= 0#bar$1 0#bar$1,i_2(D) >= 0#bar$2 0#bar$2,
```Http://www.biyezuopin.vip

3.4 三步法

3.4.1 Widen

代码:`\src\rangeAnalysis.py`

Widen 步骤用于将 变量范围扩大。此步骤可以在O(n)阶段内完成。基于原理如下:可以形象的理解为:在进行Φ操作时,如果发现变量范围向上增加,就直接扩大到inf,如果发现变量范围向下减小,就直接减小到-inf。

这样下来后,每一个MyNode的范围都会扩大到最大。

3.4.2 Future Resolution &  Narrow

代码:`\src\rangeAnalysis.py`

在Widen步骤中,只能解决每一个变量内部之间的赋值行为,在Future Resolution步骤,可以对变量之间的运算、以及条件进行处理。

我用了复杂的`ConditionHandle()`函数来解决条件变量的Constraint问题。我在每一个MyNode中添加了Conditions结构,用Condition约束来代替变量替换。这样可以大大减少变量替换带来的麻烦。

在`ConditionHandle()`中,我将条件拆分成`arg1` `arg2`和`op`三部分,将他们组合成条件为真的范围,和条件为假的范围。并把相应的范围赋给相应的变量,以及检查此路径是否可以相通。

以`t7.ssa`为例,三步法得到的所有变量的范围如下:

Enter Range For i: -10 10
bar$1 None None | Range:  Not Exists Not Exists
i_2 int int | Range:  -10 10
j_4 int int | Range:  0 20
bar$1 None None | Range:  Not Exists Not Exists
bar$2 None None | Range:  Not Exists Not Exists
k_6 int int | Range:  5 30
bar$2 None None | Range:  Not Exists Not Exists
_7 int int | Range:  5 30
i_2#bar$1 int int | Range:  -10 10
10 None None | Range:  10 10
+ int int | Range:  0 20
_3#bar$1 int int | Range:  0 20
5 None None | Range:  5 5
- int int | Range:  Not Exists Not Exists
_4#bar$1 int int | Range:  15 -5
PHI int int | Range:  0 20
_1#bar$1 int int | Range:  0 20
i#bar$1 None None | Range:  Not Exists Not Exists
i_2#bar$2 int int | Range:  0 20
10 None None | Range:  10 10
+ int int | Range:  10 30
_3#bar$2 int int | Range:  10 30
5 None None | Range:  5 5
- int int | Range:  Not Exists Not Exists
_4#bar$2 int int | Range:  5 -15
PHI int int | Range:  5 30
_1#bar$2 int int | Range:  5 30
i#bar$2 None None | Range:  Not Exists Not Exists

可以直接得到结果变量_7的范围为:_7 int int | Range: 5 30

4. 实验结果

# t1.SSA
Reference Range:[100, 100]
Output Range: [100, +inf]
# t2.SSA
Reference Range:[200, 300]
Output Range: [200, +inf]
# t3.SSA
Reference Range:[20, 50]
Output Range: [20, +inf]
# t4.SSA
Reference Range:[0, +inf]
Output Range: [0, +inf]
# t5.SSA
Reference Range:[210, 210]
Output Range: [0, +inf]
# t6.SSA
Reference Range:[-9, 10]
Output Range: [-9, 10]
# t7.SSA
Reference Range:[16, 30]
Output Range: [5, 30]
# t8.SSA
Reference Range:[-3.2192308, 5.94230769]
Output Range: [-0.41923075526423315, 14.700000286102295]
# t9.SSA
Reference Range:[9791, 9791]
Output Range: [-10, +inf]
# t10.SSA
Reference Range:[-10, 40]
Output Range: [1, 1]

5. 总结

在本实验中,我采用Python语言对SSA形式的C程序进行解析,并采用三步法针对特定输入进行了相应的范围分析。收货了写代码的乐趣,也为最后的效果遗憾。

最后的效果中,10个benchmark的结果中准确结果寥寥无几。尤其是上界,很多都直接到无穷了。这一方面是为了追求时间效率和空间效率,放弃了模拟执行采用三步法的缺陷,另一方面也是因为我没有想到合适的改进方法。

到此这篇关于如何利用Python实现简单c++程序范围分析的文章就介绍到这了,更多相关Python实现简单C++程序范围分析内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何利用Python实现简单C++程序范围分析

本文链接: https://lsjlt.com/news/139803.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何利用Python实现简单C++程序范围分析
    目录1. 实验说明2. 项目使用3. 算法原理3.1 构建CFG3.2 构建Constraint Graph3.3 构建E-SSA Constraint Graph3.4 三步法3....
    99+
    2024-04-02
  • 怎么用Python实现简单的C++程序范围
    本篇内容主要讲解“怎么用Python实现简单的C++程序范围”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python实现简单的C++程序范围”吧!1. 实验说明问题要求:针对静态单赋值(...
    99+
    2023-06-29
  • 如何利用python实现简单的情感分析
    今天小编给大家分享一下如何利用python实现简单的情感分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1 数据导入及预处...
    99+
    2023-07-02
  • 如何利用C++实现一个简单的学生考试成绩分析程序?
    随着教育事业的发展,学术考试已成为了人们日常生活中重要的一部分。而对于学生而言,考试成绩是衡量自己学习成果的重要指标。因此,对考试成绩进行科学的分析和统计是非常有必要的。在这里,我们将介绍如何使用C++实现一个简单的学生考试成绩分析程序。一...
    99+
    2023-11-02
    分析 C++ 学生
  • 利用python实现简单的情感分析实例教程
    目录1 数据导入及预处理1.1 数据导入1.2 数据描述1.3 数据预处理2 情感分析2.1 情感分2.2 情感分直方图2.3 词云图2.4 关键词提取3 积极评论与消极评论3.1 ...
    99+
    2024-04-02
  • 如何利用C++实现一个简单的聊天室程序?
    如何利用C++实现一个简单的聊天室程序?在信息时代,人们越来越注重网络交流。而聊天室作为一种常见的沟通工具,具有实时性和交互性的特点,被广泛应用于各个领域。本文将介绍如何利用C++语言实现一个简单的聊天室程序。首先,我们需要建立一个基于客户...
    99+
    2023-11-04
    C++ 实现 聊天室程序
  • 如何利用C++实现一个简单的网页爬虫程序?
    如何利用C++实现一个简单的网页爬虫程序?简介:互联网是一个信息的宝库,而通过网页爬虫程序可以轻松地从互联网上获取大量有用的数据。本文将介绍如何使用C++编写一个简单的网页爬虫程序,以及一些常用的技巧和注意事项。一、准备工作安装C++编译器...
    99+
    2023-11-04
    C++ 网页爬虫 程序实现
  • C#如何实现简单订单管理程序
    这篇文章主要介绍“C#如何实现简单订单管理程序”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C#如何实现简单订单管理程序”文章能帮助大家解决问题。订单管理的控制台程序,能够实现添加订单、删除订单、修...
    99+
    2023-06-30
  • C++如何调用简单的python程序
    目录一、基本环境的搭建二、直接在C++里面调用执行python语句三、调用python脚本文件里面的定义函数调用不含参数的函数调用含多个参数的函数总结一、基本环境的搭建 首先,用vs...
    99+
    2023-02-17
    C++调用python程序 C++调用python C++调用python
  • 如何利用C++实现一个简单的音乐播放器程序?
    如何利用C++实现一个简单的音乐播放器程序?音乐播放器是我们日常生活中常见的应用程序之一。它能够让我们随时随地欣赏到自己喜爱的音乐,舒缓压力,享受美妙的音乐世界。下面,我将介绍如何使用C++编写一个简单的音乐播放器程序。首先,我们需要了解音...
    99+
    2023-11-02
    音乐播放器 C++ 实现
  • 如何利用C++实现一个简单的邮件客户端程序?
    如何利用C++实现一个简单的邮件客户端程序?随着互联网的快速发展,电子邮件已经成为人们日常生活中必不可少的一部分。作为一名程序员,掌握如何利用C++语言来实现一个简单的邮件客户端程序无疑是非常重要的。本文将以1500个字以内的篇幅,介绍如何...
    99+
    2023-11-04
    C++利用MQTT实现邮件客户端 C++邮件客户端编程指南 C++邮件客户端实现步骤
  • Python如何实现简单的GUI程序
    这篇文章主要介绍Python如何实现简单的GUI程序,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、记事本源码#python简易记事本from tkinter import *from...
    99+
    2023-06-29
  • 如何利用C++实现一个简单的电子邮件发送程序?
    如何利用C++实现一个简单的电子邮件发送程序?随着互联网的普及,电子邮件已经成为人们日常生活和工作中不可或缺的一部分。在C++编程中,我们可以利用SMTP(Simple Mail Transfer Protocol)协议实现一个简单的电子邮...
    99+
    2023-11-02
    C++ 电子邮件 发送程序
  • 如何利用C++实现一个简单的网站访问统计程序?
    随着互联网的迅速发展,越来越多的网站开始关注网站访问数据的统计,并将这些数据用于网站的优化和改进。因此,开发一个简单的网站访问统计程序对于网站管理者来说非常有用。而其中一个实现这一目标的可能性是通过使用C++,该语言可以帮助您以更高效的方式...
    99+
    2023-11-04
    网站 统计 访问
  • 微信小程序如何实现日期范围选择
    本篇内容介绍了“微信小程序如何实现日期范围选择”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!样式如下:分别点击开始日期和结束日期选择时间(底...
    99+
    2023-07-02
  • 如何利用Python+Vue实现简单的前后端分离
    目录准备工作前端后端数据库总结准备工作 安装Node环境安装Python环境 注意:项目整个过程需要从后往前,即先数据库->后端->前端;启动流程也是先启动后端项目,再启...
    99+
    2024-04-02
  • Python如何实现的简单购物车程序
    购物车程序需求: 用户输入购物预算 展示商品列表 用户购买商品,每次购买后提示用户购买信息和剩余预算 购物完成后打印购物花费和购物清单,并将商品从原列表移除 实现代码如下: #...
    99+
    2022-06-02
    python 购物车 python 购物车程序
  • 如何进行Python Helloworld程序的简单实现
    本篇文章为大家展示了如何进行Python Helloworld程序的简单实现,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。对于一个学习过编程语言的朋友来说,肯定会对Helloworld这一词汇记忆深...
    99+
    2023-06-17
  • Python如何实现简单购物车小程序
    小编给大家分享一下Python如何实现简单购物车小程序,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下要求代码# --*--coding:utf-8--*--# Author: 村雨...
    99+
    2023-06-29
  • 如何利用C++实现一个简单的电影评分系统?
    如何利用C++实现一个简单的电影评分系统?电影评分系统是一个能够让用户对所观看的电影进行评分和评论的系统。在这个系统中,用户可以选择电影并针对其进行评分,同时也可以查看其他用户的评分和评论。在这篇文章中,我们将介绍如何使用C++编程语言实现...
    99+
    2023-11-02
    C++电影评分系统
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作