小明初学C++,已明白了四则运算、关系运算、逻辑运算、赋值运算、输入输出、简单选择和循环结构的用法,但他的英语不太好,记不住太多的保留字,于是他利用汉语拼音做保留字,山寨C++,发明了一种表达自己思想的算法描述规则。
规则很简单:他将开始程序头部以一个拼音名字标记,C++程序中的"{,}"用拼音“kaishi,jieshu”直观表示;选择和循环只采用一种单一的结构,且保留字也分别用对应的拼音表示,不过在表示选择或循环条件时他去掉了多余的小括号;输入输出也用拼音表示;数据类型只保留了整型(int)和实型(float),并用拼音表示,且按他的习惯变量在前,类型在后。
现在小明想请熟悉C++的你帮他写一个程序,将用他设计的算法描述规则写成的算法,翻译成C++源码。输入文件扩展名为.ming,输出文件扩展名为.cpp,如下例:
小明算法(test.ming):
chengxu1
kaishi
i,j zhengxing;
k shixing;
i=1;j=0;
shuru k;
xunhuan i<10
kaishi
j=j+i;
i++;
jieshu
ruguo j>10
kaishi
k=j*1.0/i;
jieshu
shuchu k,j;
jieshu
翻译成的C++源码(test.cpp):
#include <iostream>
using namespace std;
int main()
{
int i,j;
float k;
i=1;j=0;
cin>>k;
while( i<10)
{
j=j+i;
i++;
}
if(j>10)
k=j*1.0/i;
cout<<k<<j;
return 0;
}
#include<stdio.h>
#include<string.h>
#define MaxSize 1000
static int point=0; //记录执行到被翻译字符串位置
int pointBefore=0;
typedef struct
{
char data[MaxSize]; //存放字符串
int length; //存放串长
}SqString;
//将伪代码中的标志字符转化成SqString的形式
SqString changeSign(char sign[])
{
int i;
SqString str;
for(i=0;sign[i]!='\0';i++)
{
str.data[i]=sign[i];
}
str.length=i;
return str;
}
void StrAssign(SqString &s,char cstr[]) //将一个字符串常量赋给串s(s为引用型参数)
{
int i;
for(i=0;cstr[i]!='\0';i++)
{
s.data[i]=cstr[i];
}
s.length=i;
}
int index(SqString s,SqString t) //BF算法 串的模式皮匹配
{
int i=0,j=0;
while(i<s.length&&j<t.length)
{
if(s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和字串依次匹配下一个节点
j++;
point++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=t.length)
return (i-t.length);
else
return(-1);
}
/*******用于第一次匹配时出现while和if情况时对后面条件语句范围的确定*/
int indexKaishi(SqString s,SqString t) //BF算法 串的模式皮匹配
{
int i=point,j=0;
while(i<s.length&&j<t.length)
{
if(s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和字串依次匹配下一个节点
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=t.length)
return (i-t.length);
else
return(-1);
}
bool piPei(SqString s,SqString t) //BF算法 串的模式皮匹配
{
int i=point,j=0;int startAddres=point;
while(i<s.length&&j<t.length)
{
if(s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和字串依次匹配下一个节点
j++;
point++;
}
else
{
point=startAddres;
return false;
}
}
if(j>=t.length)
return true;// (i-t.length);下标
else
return false;
}
//主要用在第二种情况匹配时,获取分号的下标
int indexFenhao(SqString s)
{
int i=point;
SqString ex;
char exe[]={";"};
StrAssign(ex,exe);
while(i<s.length)
{
if(s.data[i]==ex.data[0])
break;
else
i++;
}
return i-1;
}
/*当在第一遍查找没有符合匹配规则的标志字符串时,开始从分号前面截取特定长度的字符串,进行第二次字符匹配*/
//返回串s中从下标为(1<=i<=StrLength(s))的字符开始的到下标为j的字符组成的子串。参数不正确时返回一个空串
SqString SubStr(SqString s,int i,int j)
{
SqString str;
int k,n;
str.length=0;
if(i<0||i>s.length||j<0)
return str;
for(n=0,k=i;k<=j;k++,n++)
str.data[n]=s.data[k];
str.length=n;
// point=point+str.length+1; //为修补第三次匹配时出现的BUG增加的语句,第二次匹配完成时没有此条语句,因为不止在第三种匹配时调用此函数所以结果修补错误,将语句放在了piPeiSame3中
return str;
}
bool secondPiPei(SqString s,SqString t) //BF算法 串的模式皮匹配
{
int i=0,j=0;
while(i<s.length&&j<t.length)
{
if(s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和字串依次匹配下一个节点
j++;
}
else
{
return false;
}
}
if(j>=t.length)
{
return true;
}
else
return false;
}
//输出串
void DispStr(SqString s) //输出串S中的所有值
{
int i;
if(s.length>0)
{
for(i=0;i<s.length;i++)
printf("%c",s.data[i]);
}
return;
}
//伪代码中,输入输出语句的优化处理,如果出现“,”则将其转换成“<<”或者“>>”;
void input(SqString s)
{
int i;
SqString ex;
char exe[]={","};
StrAssign(ex,exe);
for(i=0;i<s.length;i++)
{
if(s.data[i]==ex.data[0])
printf(">>");
else
printf("%c",s.data[i]);
}
printf(";\n");
}
void output(SqString s)
{
int i;
SqString ex;
char exe[]={","};
StrAssign(ex,exe);
for(i=0;i<s.length;i++)
{
if(s.data[i]==ex.data[0])
printf("<<");
else
printf("%c",s.data[i]);
}
printf(";\n");
}
//遍历串
void BianLiTxt()
{
}
/*******************************匹配规则
chengxu1 => #include<iostream> using namespace std;
kaishi => {
, => ,
jieshu => }
zhengxing=> int
shixing => float
xunhuan => while 输出while之后,需要自行输出()和kaishi 之前的内容
ruguo => if 输出if之后,需要自行输出()和kaishi 之前的内容
shuchu => cout<<
***************************************************/
//实现翻译程序的主要部分的函数
void judgeSame3(SqString s){ //在第二次匹配失败的情况下,进行第三种方式匹配
DispStr(SubStr(s,pointBefore,indexFenhao(s)));
printf(";");
printf("\n");
point=indexFenhao(s)+2;
}
void judgeSame2(SqString s) //在第一次匹配失败的情况下,进行第二种方式匹配
{
if(secondPiPei(SubStr(s,indexFenhao(s)-8,indexFenhao(s)),changeSign("zhengxing"))==true) //截取分号前9个字符与zhengxing比较判断
{
printf("int ");
DispStr(SubStr(s,pointBefore,indexFenhao(s)-9));
printf(";");
printf("\n");
point=indexFenhao(s)+2;
}
else if(secondPiPei(SubStr(s,indexFenhao(s)-6,indexFenhao(s)),changeSign("shixing"))==true)
{
printf("float ");
DispStr(SubStr(s,pointBefore,indexFenhao(s)-7));
printf(";");
printf("\n");
point=indexFenhao(s)+2;
}
else
judgeSame3(s);
}
void judgeSame1(SqString s) //第一次匹配
{
while(point<s.length)
{
if(piPei(s,changeSign("chengxu1"))==true) //chengxu1
{
pointBefore=point; //用于记录匹配之后的point的位置,方便出现第二种情况时,输出数据类型与上一次匹配位置之间的字符串
printf("#include<iostream>\nusing namespace std;\nint main()\n");
}
else if(piPei(s,changeSign("kaishi"))==true) //kaishi
{
pointBefore=point;
printf("{\n");
}
/* else if(piPei(s,changeSign(","))==true) //,
{
printf(",");
}*/
else if(piPei(s,changeSign("xunhuan"))==true) //xunhuan
{
pointBefore=point;
printf("while("); //需要对while 和if情况单独处理
DispStr(SubStr(s,pointBefore,indexKaishi(s,changeSign("kaishi"))-1));
printf(")\n");
point=indexKaishi(s,changeSign("kaishi"));
}
else if(piPei(s,changeSign("ruguo"))==true) //ruguo
{
pointBefore=point;
printf("if(");
DispStr(SubStr(s,pointBefore,indexKaishi(s,changeSign("kaishi"))-1));
printf(")\n");
point=indexKaishi(s,changeSign("kaishi"));
}
else if(piPei(s,changeSign("shuru"))==true) //需要对输入后面的内容进行判断是否含有,
{
pointBefore=point;
printf("cin>>");
input(SubStr(s,pointBefore,indexFenhao(s)));
point=indexFenhao(s)+2;
}
else if(piPei(s,changeSign("shuchu"))==true) //需要对输出后面的内容进行判断是否含有,
{
pointBefore=point;
printf("cout<<");
output(SubStr(s,pointBefore,indexFenhao(s)));
point=indexFenhao(s)+2;
}
else if(piPei(s,changeSign("jieshu"))==true)
{
pointBefore=point;
if(pointBefore+2>s.length)
{
printf("return 0;\n}\n");
}
else
printf("}\n");
}
else
{
pointBefore=point;
judgeSame2(s);
}
}
}
int main()
{
SqString s;
char cstr[MaxSize]={"chengxu1kaishii,j zhengxing;k shixing;i=1;j=0;shuru k;xunhuan i<10kaishij=j+i;i++;jieshuruguo j>10kaishik=j*1.0/i;jieshushuchu k,j;jieshu"};
StrAssign(s,cstr);
judgeSame1(s);
return 0;
}