码迷,mamicode.com
首页 > 其他好文 > 详细

C程序片段并发性测试以及前趋图的自动生成

时间:2015-07-31 10:41:00      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:

VX2012平台。C++完成主程序,JAVA实现界面。

所谓程序并发性是指在计算机系统中同时存在有多个程序,宏观上看,这些程序是同时向前推进的.在单CPU环境下,这些并发执行的程序是交替在CPU上运行的。分析程序之间的的可并发性,并利用伯恩斯坦条件来判定各程序之间能否并发执行,同时通过词法语法分析自动生成程序之间的前趋图(DAG图),对我们分析程序很有好处。


//by hfut yzk
#include"stdafx.h"
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<fstream>
using namespace std;
/************************************************************结构体定义************************************************************/
#pragma region    结构体定义
struct  kind
{
    string na;																									   //单词
    int num;																									   //内码
    string type;																							    	//类型
    int l,r;																											 //行列数
};
struct var_que									                                                           //每个变量对应俩个程序读写情况队列
{
    vector<int>r,w;
};
#pragma endregion</span>


/* ***********************************************************变量定义************************************************************** */
#pragma region    变量定义

int line=1,row=1;																						//行列号
//char c;
const int num_pro=10;																				//程序数量
map<char,int>ma;																						//运算符表
vector<kind>res;																						 //视图表
int tree[10000][30];                                                                                //字典树
int numv=0;int w[10000];                                                                    //字典树变量值
int key=0;  int flag=0;	int flag1=0;												    //key统计关键字,flag统计标识符
char *pro[100];																					    //程序文件路径名
ifstream in;																							    //文件对象	
map<string,int>getid ;																		     //标识符编号
var_que vq[100];																				  //变量 对每个程序的读写情况
void  test_for_berstein();			                                                         //berstein条件的判定
#pragma endregion</span>


/* ***********************************************************函数声明**************************************************************/
#pragma region 函数声明

void start(int id);																				//启动函数	
void testit(int id,char c,string s);													//标识符是否左值测试1
void testitf(int id,string s);																//标识符是否左值测试2
void init();																							//初始化函数
void insert(string s);																			//字典树插入函数		
void reads()	;																						//读入数据
bool test(int u);																					//是否保留字前缀
void f1(char &c,int id)	;																	// 关键字标识符分析器
void f2(char &c)			;																		  //数字分析器
void f3(char &c)			;																		 //分界符、运算符等其他分析器
bool test_other(char x)	;																 //测试是否运算符
void  test_for_same_w(string s,int id) ;                                         //防止同程序的变量多次记录
void get_graph()			;																		  //生成前趋图		

#pragma endregion</span>

/************************************************************函数实现区************************************************************/

#pragma region 函数实现
/************************************************************初始化函数************************************************************/
void  init()                                                                                         
{
    //res.clear();
    flag=0;
	return ;
}

/*******************************************************字典树数据插入函数***********************************************************/
void insert(string s)																			
{
    int u=0;
    for(int i=0;i<s.size();i++)
    {
        if(tree[u][s[i]-'a']==0)
           tree[u][s[i]-'a']=++numv;
        u=tree[u][s[i]-'a'];
    }
    w[u]=key++;
	return ;
}

/***********************************************************读入数据函数***************************************************************/
void reads()
{
   ma['[']=1;ma[']']=2;ma[',']=3;ma[';']=4;ma['(']=5;ma[')']=6;ma['{']=7;ma['}']=8;
   ma['+']=9;ma['-']=10;ma['*']=11;ma['/']=12;ma['%']=13;ma['&']=14;ma['|']=15;ma['.']=16;
   string s;
   ifstream  inkey("H:/course/OS/OS_program/key.txt");					   //保留字读入
   while(s!="end")
   {
       inkey>>s;
       insert(s);
   }
																															//程序的读入
    pro[1]="H:/course/OS/OS_program/program1.txt";
    pro[2]="H:/course/OS/OS_program/program2.txt";
    pro[3]="H:/course/OS/OS_program/program3.txt";
	pro[4]="H:/course/OS/OS_program/program4.txt";
	pro[5]="H:/course/OS/OS_program/program5.txt";
	pro[6]="H:/course/OS/OS_program/program6.txt";
	pro[7]="H:/course/OS/OS_program/program7.txt";
	pro[8]="H:/course/OS/OS_program/program8.txt";
	pro[9]="H:/course/OS/OS_program/program9.txt";
	pro[10]="H:/course/OS/OS_program/program10.txt";

    for(int i=1;i<=num_pro;i++)
     {
         init();
         in.open(pro[i]);
         start(i);
         in.close();
     }
	return;
}

/*******************************************************是否保留字前缀测试器********************************************************/
bool test(int u)																		
{
    for(int i=0;i<26;i++)
    {
        if(tree[u][i]!=0)
			return 1;
    }
    return 0;
}

/******************************************************关键字标识符分析器************************************************************/
void f1(char &c,int id)															
{
    int mark=1;
    string s;
    s+=c;
    int u=0;
    if(tree[u][c-'a']!=0)                                      //是否关键字
       u=tree[u][c-'a'];
    else                        
		 mark=0;
    while(c=in.get())                                         //关键字测试
    {
        if(!(c>='a'&&c<='z'))
          if(c!='_')
            if(!(c>='0'&&c<='9'))
              break;
        if(mark==1)
        {
             if(tree[u][c-'a']!=0)
               u=tree[u][c-'a'];
              else 
				  mark=0;
        }
        s+=c;
    }
    if(test(u))	                                            //出现保留字前缀情况为标识符
	{
		mark=0;
	}													
    kind t;                                                 //录入
    t.na=s;
    t.l=line;
    t.r=row;
    if(mark==0)
    {
        t.num=++flag;
        if(getid.find(s)==getid.end())                                                 //防止重复
         {
            getid[s]=++flag1;
         }
         int dex=(vq[getid[s]].r.size())-1;										    //防止同程序的变量多次记录
        if(dex>=0&&vq[getid[s]].r[dex]==id)
           ;
        else   
			vq[getid[s]].r.push_back(id);

        t.type="     标识符";
      testit(id,c,s);                                                                                 //左值测试1
	   testitf(id,s);																					//左值测试2
    }
    else
    {
        t.num=w[u];
        t.type="     关键字";
    }
    res.push_back(t);
    return ;
}

/***************************************************************数字分析器**********************************************************/
void f2(char &c)																				
{
    string s;
    s+=c;
    c=in.get();
    while(c>='0'&&c<='9')
    {
        s+=c;
        c=in.get();
    }
    int mark=1;
    while(c>='a'&&c<='z')
      {s+=c;mark=0;c=in.get();}
    kind t;
    t.na=s;
    t.l=line;
    t.r=row;
    if(mark==1)
    {
        //char *p;
    //strcpy_(p,s.c_str());
    t.num=0;//t.num=atoi(p);
    t.type="    数字";
    }
    else
    {
        t.type="    error";
        t.num=0;
    }
    res.push_back(t);
    return ;
}                                 

/**********************************************分界符、运算符等其他分析器********************************************************/
void f3(char &c)                    
{
    string s;
    kind t;
    t.l=line;t.r=row;
    if(ma.find(c)!=ma.end())
    {
        t.na+=c;
        if(ma[c]<=8)
			 t.type="     分界符";
        else
			 t.type="     运算符";
        t.num=ma[c];
        c=in.get();
    }
    else
    {
        t.type="   关系运算符";
        if(c=='>')
        {
             c=in.get();
             if(c=='=')
             {
                 t.na=">=";
                 t.num=1;
                 c=in.get();
             }
             else
             {
                t.na=">";
                t.num=2;
             }
        }
       else if(c=='<')
        {
              c=in.get();
              if(c=='=')
              {
                t.na="<=";
                 t.num=3;
                 c=in.get();
              }
              else if(c=='>')
              {
                  t.na="<>";
                  t.num=4;
                  c=in.get();
              }
              else
              {
                  t.na="<";
                  t.num=5;
              }
        }
        else if(c=='=')
        {
            t.na="=";
            t.num=6;
            c=in.get();
        }
    }
    res.push_back(t);
    return ;
}

/**********************************************测试是否运算符***********************************************************************/
bool test_other(char x)																				
{
    if(x=='+'||x=='-'||x=='*'||x=='/'||x=='%'||x=='&'||x=='^'||x=='|')
      return 1;
    else 
	  return 0;
}

/*********************************************同程序的变量记录判断****************************************************************/
void  test_for_same_w(string s,int id)
{
	   int dex=(vq[getid[s]].w.size())-1;										    //防止同程序的变量多次记录
                  if(dex>=0&&vq[getid[s]].w[dex]==id)
                          ;
                   else   
					    vq[getid[s]].w.push_back(id);
}

/*********************************************左值测试器1************************************************************************/
void testitf(int id,string s)                                                                                          //测试++a/--a
{
	int ss=in.tellg();																										//定位当前文件指针位置
	int go=s.size()+2;																									//到该变量前面一个位置
	   in.seekg(-go,ios::cur);
    for(;;go++)
    {
		char c=in.get();
        if(c==' ')
		{
			 in.seekg(-2,ios::cur);
			continue;
		}
        else if(c=='+')
        {
               	 in.seekg(-2,ios::cur);
				  c=in.get();
				  if(c=='+')
		     	{
				test_for_same_w(s, id);
				  }
        }
		else if(c=='-')
        {
               	 in.seekg(-2,ios::cur);
				  c=in.get();
				  if(c=='-')
		     	{
				  test_for_same_w(s, id);
				  }
        }
        break;
    }
    go=ss-in.tellg();
    in.seekg(go,ios::cur);
}

/*********************************************左值测试器2************************************************************************/
void testit(int id,char c,string s)										                                 										
{
    int go=0;
    int ss=in.tellg();
    for(;;go++)                   
    {
        if(c==' ')																															//忽略空格
		{
			c=in.get();
			continue;
		}
        else if(c=='=')																													//排除==干扰
        {
            if(in.peek()!='=')
             	test_for_same_w(s, id);
        }
        else if(test_other(c))
        {
            if(in.peek()=='=')
            	test_for_same_w(s, id);
        }
         if(c=='+')
        {
          if(in.peek()=='+')
             	test_for_same_w(s, id);
        }
         else if(c=='-')
        {
          if(in.peek()=='-')
             	test_for_same_w(s, id);
        }
        break;
    }
    go=ss-in.tellg();
    in.seekg(go,ios::cur);
}


/****************************************************总控程序******************************************************************/
void start(int id)																														//启动
{
    char c;
    c=in.get();
     while(1)
    {
        if(c=='@')break;
	/*	cout<<in.tellg();
		cout<<"c:"<<c<<":c"<<endl;*/
		if(int(in.tellg())==-1)break;
        while(c==' '||c=='\t')
		{
			c=in.get();
			row++;
		}
           if(c=='\n')
          {
              line++;
              row=1;
              c=in.get();
              continue;
          }
        if(c>='a'&&c<='z')
           f1(c,id);
        else if(c>='0'&&c<='9')
           f2(c);
        else
           f3(c);
        row++;
        if(c=='\n')
          {
              line++;
              row=1;
              c=in.get();
          }
    }
	 return  ;
}

/********************************************************  生成前趋图***********************************************************/
void get_graph()																									
{
	ofstream out("H:/course/OS/OS_program/graph.txt");
	out<< num_pro<<endl;
	 for(int i=1;i<=flag1;i++)
    {
              for(int w=0;w<vq[i].w.size();w++)
			  { 
                    for(int r=0;r<vq[i].r.size();r++)                                              
					{
						if(vq[i].w[w]<vq[i].r[r])                                                                         //写后读                          
							  out<<vq[i].w[w]<<" "<<vq[i].r[r]<<" "<<"1"<<endl;
						else if (vq[i].w[w]>vq[i].r[r])																	//读后写
						     out<<vq[i].r[r]<<" "<<vq[i].w[w]<<" "<<"2"<<endl;
					}
					 for(int ww=w+1;ww<vq[i].w.size();ww++)											//写后写
					{
							  out<<vq[i].w[w]<<" "<<vq[i].w[ww]<<" "<<"3"<<endl;
					}
               }
	 }
	 out<<-1<<endl;
	 return ;
}							

/********************************************************  伯恩斯坦条件判定程序并发性***********************************************************/
void  test_for_berstein()																									
{
	cout<<"According to the conditions of Berstein , The following programs can not be executed concurrently:\n";
	 for(int i=1;i<=flag1;i++)
    {
              for(int w=0;w<vq[i].w.size();w++)
			  { 
                    for(int r=0;r<vq[i].r.size();r++)                                              
					{
						if(vq[i].w[w]<vq[i].r[r])                                                                         //写后读                          
							  cout<<"Program"<<vq[i].w[w]<<" "<<"Program"<<vq[i].r[r]<<" "<<"for the conflict of RAW.\n"<<endl;
						else if (vq[i].w[w]>vq[i].r[r])																	//读后写
						     cout<<"Program"<<vq[i].r[r]<<" "<<"Program"<<vq[i].w[w]<<" "<<"for the conflict of  WAR.\n"<<endl;
					}
					 for(int ww=w+1;ww<vq[i].w.size();ww++)											//写后写
					{
							 cout<<"Program"<<vq[i].w[w]<<" "<<"Program"<<vq[i].w[ww]<<" "<<"for the conflict of  WAW.\n"<<endl;
					}
               }
	 }
	 return ;
}							


#pragma endregion</span>

/**************************************************主函数***************************************************************************/

int _tmain()
{
    reads();
	
	 test_for_berstein();
	get_graph(); 
	//cout<<"graph get successfully!\n";
    ofstream out("H:/course/OS/OS_program/res.txt");
   // out<<"单词"<<'\t'<<'\t'<<"二元序列"<<'\t'<<'\t'<<"类型"<<'\t'<<'\t'<<"位置(行,列)"<<endl;
    for(int i=0;i<res.size();i++)
      {
                          /*  out<<res[i].na<<'\t'<<'\t'<<"("<<res[i].num<<","<<
							res[i].na<<")"<<'\t'<<'\t'<<res[i].type<<'\t'<<'\t'<<"("<<res[i].l<<","
							<<res[i].r<<")"<<endl;*/
		                   out<<res[i].na<<'\t'<<'\t'<<res[i].type<<endl;
      }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

C程序片段并发性测试以及前趋图的自动生成

标签:

原文地址:http://blog.csdn.net/u011498819/article/details/47165143

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!