您好,欢迎来到飒榕旅游知识分享网。
搜索
您的当前位置:首页编译原理课程设计____C语言编译器的实现

编译原理课程设计____C语言编译器的实现

来源:飒榕旅游知识分享网
南华大学

编译原理课程设计名:编译代生成器设计

专业 计算机科学与技术 学生姓名 熊浩斌 班 级 计算机01班 学 号 *********** 指导老师 陈星

实验地点 8栋 2-209

完成日期:2013.6.2

一、课程设计的目的

编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。

二、课程设计的要求

1、 明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。

2、 按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正

确。

3、 写出完整的算法框架。 4、 编写完整的编译程序。

三、课程设计的内容

课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。

四、总体设计方案及详细设计 总体设计方案: 1.总体模块

主程序 词法分析程序 语法分析程序 中间代码生成程序 2.

表2.1 各种单词符号对应的种别码

单词符号 bgin If Then wile do end lettet(letter|digit)* dight dight* + — * / 种别码 1 2 3 4 5 6 10 11 13 14 15 16 = ; ( ) # 单词符号 : := < <> <= > >= 种别码 17 18 20 21 22 23 24 25 26 27 28 0 详细设计:

4.1界面导入设计

(1)一共三个选项:

①choice 1--------cifafenxi

②choice 2--------yufafenxi ③choice 3--------zhongjiandaima (2)界面演示

图一

图二

图三

4.2词法分析程序 (1)流程图设计

输出单词二元组 调用扫描子程序 置初值

否 输入串结束 是 结束 (2)具体功能的具体设计

1、cifafenxi( )

首先设置prog[n]来接收输入的语句,以‘#’来结束; 调用扫描子程序 scaner1( ),每一次得到一个类型码; 用switch判别相应输出; 直到syn1=0为止。

2、扫描子程序scaner1( )-----------------扫描输入的语句 首先设置3个变量:

①token1用来存放构成单词符号的字符串; ②sum1用来存放整型单词; ③syn1用来存放单词符号的类型码。 有关scaner1()中关键点解析:

while((ch==' ')||(ch=='\\n')) ch=prog[p++]; ;忽略空格

if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))

{ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) { token[m++]=ch; ch=prog[p++];

} ;判别标识符 ③

for(n=0;n<6;n++)

if(strcmp(token,rwtab[n])==0) { syn=n+1; break;

} ;标识符是否是关键字

if((ch>='0')&&(ch<='9'))

{ while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; ch=prog[p++]; } }

;判别整数

(3) 词法分析的运行结果

输入

begin x:=1; y:=1+2;end # 输出

4.3语法分析程序 (1) 具体功能的具体设计

1.yufafenxi()---------------分析程序

给出算术表达式文法,进行适当的文法变换

输入——表达式;输出——表达式语法是否正确。

2.子程序的功能描述

(3) 语法分析的运行结果

分析成功图

分析失败图

4.4 中间代码生成程序

(1)总体描述

采用递归下降(自上而下)的语法制导翻译法。 在前两次试验的基础上改进。

词法分析程序  语法分析程序  语义分析程序 编译器。不断完善, 不断改进。渐变的过程。 单词符号及种别表

单词符号 main int float double char if else do while l(l|d)* 种别编码 1 2 3 4 5 6 7 8 9 10 内部字符串 单词值 ( +|-|ε ) d*(.dd* | ε)( e ( +|-|ε ) dd*|ε) 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 二进制数值表示 = + - * / ( ) { } , ; > >= < <= == !=

(2)程序结构描述

(3) 程序的功能描述

从文件中读入表达式,输出其四元式的结果序列

递归下降示意图

是否为调用scanner 是否为(? 调用scanner 是否为)? 调用scanner 调用语句块分析函数出错处理

(4)详细功能描述

void scanner(); //扫描 void lrparser();

void staBlock(int *nChain); //语句块 void staString(int *nChain); //语句串 void sta(int *nChain); //语句 void fuzhi(); //赋值语句

void tiaojian(int *nChain); //条件语句 void xunhuan(); //循环语句 char* E(); //Expresiion表达式 char* T(); //Term项 char* F(); //Factor因子

char *newTemp(); //自动生成临时变量

void backpatch(int p,int t); //回填 int merge(int p1,int p2); //合并p1和p2

void emit(char *res,char *num1,char *op,char *num2); //生成四元式 void emit(char *res,char *num1,char *op,char *num2)

该函数的功能是生成一个三地址语句送到四式表中

char *newTemp()

该函数的功能是会动一个新的临时变量,临时变量名产生的

顺序是T1,T2,T3,…. int merge(int p1,int p2)

该函数的功能是将以P1,P2为链首的两条链合并成一条链,

返回时的函数值作为合并后的链首。 void backpatch(int p,int t)

该函数的功能是把P所链接的每个四元式的第四区段(result段)都回

填t。 void fuzhi()

该函数的功能是对赋值语句进行分析。

void tiaojian(int *nChain)

该函数的功能是对条件语句进行分析。

void xunhuan()

该函数的功能是对循环语句进行分析。

(4) 结果演示

图一 简单语句生成四元式

图二 if语句的四元式

图三 循环语句四元式生成

生成

(5)汇编生成

if(strcmp(fourCom[i].opera,\"=\")==0) {

printf(\"Move AX,%1s\\n\ printf(\"Move %5s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"+\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"ADD Ax,%1s\\n\printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"-\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"SUB Ax,%1s\\n\ printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"*\")==0) {

printf(\"Mov AL,%1s\\n\ printf(\"MUL %1s\\n\ printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"/\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"DIv %1s\\n\

printf(\"Mov %1s,AL\\n\}

if(strcmp(fourCom[i].opera,\"goto\")==0) {

printf(\"jmp L%1s\\n\ }

结果演示

五、课程设计的体会与总结

经过一个星期的编译原理课程设计,本人在陈宏建老师的指导下,顺利完成该课程设 计。通过该课程设计,收获颇多。

词法分析的基本任务是从字符串表示的源程序中识别出具有意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成,更加加深了对词法分析原理的理解。

通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”调用scaner函数读下一个单词符号调用IrParse结束。递归下降分析的大致流程为:“先判断是否为begin”不是则“出错处理”,若是则“调用scaner函数”调用语句串分析函数“判断是否为end”不是则“出错处理”,若是则调用scaner函数“判断syn=0&&kk=0是否成立”成立则说明分析成功打印出来。不成立则“出错处理”。

一、对实验原理有更深的理解

通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的。通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。

二、对该理论在实践中的应用有深刻的理解

通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。 三、激发了学习的积极性

通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。以前对与计算机操

在这次课程设计中,我就是按照实验指导的思想来完成。加深了理解文件系统的内部功能及内部实现,培养实践动手能力和程序开发能力的目的。

附录-----程序清单

#include #include #include #include using namespace std; #define MAX 100

char inputstream[50]; //存储输入句子 int temp1=0; //数组下标 int right1; //判断输出信息

int m2=0,sum2=0;//sum用于计算运算符的个数

//m用于标记输入表达式中字符的个数 char JG='A';

char str[MAX];//用于存输入表达式 int tokene=0;//左括号的标志 char prog1[80],token1[8],ch1; int syn1,p1,m1,n1,sum1;

char *rwtab1[6]={\"begin\

int r1 ;

char prog[80]; //存放所有输入字符 char token[8]; //存放词组 char ch; //单个字符

int syn,p,m,n,i; //syn:种别编码 double sum; int count;

int isSignal; //是否带正负号(0不带,1负号,2正号) int isError;

int isDecimal; //是否是小数 double decimal; //小数 int isExp; //是否是指数 int index; //指数幂

int isNegative; //是否带负号

double temp; int temp2;

int repeat; //是否连续出现+,-

int nextq;

int kk; //临时变量的标号 int ntc,nfc,nnc,nnb,nna;

char *rwtab[9]={\"main\ struct{ char result[10]; //字符串(字符数组) char arg1[10]; char opera[10]; char arg2[10];

}fourCom[20]; //结构体数组

cifafenxi(); yufafenxi();

zhongjiandaima(); scaner1(); void e(); void e1(); void t(); void t1(); void f();

void lrparser();

void staBlock(int *nChain); //语句块 void staString(int *nChain); //语句串 void sta(int *nChain); //语句 void fuzhi(); //赋值语句

void tiaojian(int *nChain); //条件语句 void xunhuan(); //循环语句 char* E(); //Expresiion表达式 char* T(); //Term项 char* F(); //Factor因子

char *newTemp(); //自动生成临时变量 void backpatch(int p,int t); //回填

int merge(int p1,int p2); //合并p1和p2

void emit(char *res,char *num1,char *op,char *num2); //生成四元式

void scanner(); //扫描 void lrparser()

{ int nChain; nfc=ntc=1; nextq=1; if(syn==1) //main { scanner(); if(syn==26) //( { scanner(); if(syn==27) //) { scanner(); staBlock(&nChain); } else printf(\"缺少右括号\\n\"); } else printf(\"缺少左括号\\n\"); } else printf(\"缺少main\\n\"); }

//<语句块> ::= '{'<语句串>'}'

void staBlock(int *nChain) //语句块 { if(syn==28) //{ { scanner(); staString(nChain); //backpatch(*nChain,nextq); if(syn==29) //} scanner(); //读下一个 else printf(\"缺少}号\\n\"); } else printf(\"缺少{号\\n\"); }

//<语句串>::=<语句>{;<语句>}; void staString(int *nChain) //语句串 { sta(nChain); backpatch(*nChain,nextq); while(syn==31) //; { scanner(); sta(nChain); } //backpatch(*nChain,nextq-1); }

void sta(int *nChain) //语句 {

if(syn==10) { fuzhi(); //*nChain=0; } else if(syn==6) //if { tiaojian(nChain); } else if(syn==8) //do xunhuan(); }

//<条件语句>->if(<条件>)<语句块> void tiaojian(int *nChain) { char res[10],num1[10],num2[10],op[10]; int nChainTemp; //<条件>-><表达式><关系运算符><表达式> if(syn==6) //if { scanner(); //strcpy(num1,E()); if(syn==26) //( { scanner(); strcpy(num1,E()); if((syn<=37)&&(syn>=32)) { switch(syn) { case 32: strcpy(op,\">\"); break; case 33: strcpy(op,\">=\"); break; case 34: strcpy(op,\"<\"); break; case 35: strcpy(op,\"<=\"); break; case 36: strcpy(op,\"==\"); break; case 37: strcpy(op,\"!=\"); break; default: printf(\"error\"); } } scanner(); strcpy(num2,E());

strcat(num1,op); strcat(num1,num2); //nfc=nextq+1; ntc=nextq; //记住if语句位置 emit(\"0\ nfc=nextq; //if中表达式为假 emit(\"0\ //第一个0已回填 backpatch(ntc,nextq); //ntc链接的所有四元式都回填nextq } if(syn==27) //) scanner(); staBlock(&nChainTemp); //语句块 *nChain=merge(nChainTemp,nfc); } }

//<循环语句>::=do <语句块>while <条件> void xunhuan() { char res[10],num1[10],num2[10],op[10]; int nChainTemp; if(syn==8) //do { nnc=nextq; //记住if语句位置,emit之后nextq就变了 //emit(\"0\ scanner(); staBlock(&nChainTemp); //语句块 if(syn==9) //while { scanner(); if(syn==26) //( { scanner(); strcpy(num1,E()); if((syn<=37)&&(syn>=32)) { switch(syn) { case 32: strcpy(op,\">\"); break; case 33: strcpy(op,\">=\"); break; case 34: strcpy(op,\"<\"); break; case 35:

strcpy(op,\"<=\"); break; case 36: strcpy(op,\"==\"); break; case 37: strcpy(op,\"!=\"); break; default: printf(\"error\"); } } scanner(); strcpy(num2,E()); strcat(num1,op); strcat(num1,num2); nnb=nextq; emit(\"0\ backpatch(nnb,nnc); nna=nextq; emit(\"0\ backpatch(nna,nextq); } if(syn==27) //) scanner(); } } }

void fuzhi() //赋值语句只有1个操作数 { char res[10],num[10]; //num操作数 if(syn==10) //字符串 { strcpy(res,token); //结果 scanner(); if(syn==21) //= { scanner(); strcpy(num,E()); emit(res,num,\"=\ } else { printf(\"缺少=号\\n\"); } } }

char* E() //Expression表达式 { char *res,*num1,*op,*num2; res=(char *)malloc(10); num1=(char *)malloc(10);

op=(char *)malloc(10); num2=(char *)malloc(10); strcpy(num1,T()); while((syn==22)||(syn==23)) //+ - { if(syn==22) //+ strcpy(op,\"+\"); else strcpy(op,\"-\"); scanner(); strcpy(num2,T()); strcpy(res,newTemp()); emit(res,num1,op,num2); strcpy(num1,res); } return num1; }

char* T() //Term项 { char *res,*num1,*op,*num2; res=(char *)malloc(10); num1=(char *)malloc(10); op=(char *)malloc(10); num2=(char *)malloc(10); strcpy(num1,F()); while((syn==24)||(syn==25)) //* / { if(syn==24) strcpy(op,\"*\"); else strcpy(op,\"/\"); scanner(); strcpy(num2,F()); strcpy(res,newTemp()); emit(res,num1,op,num2); strcpy(num1,res); } return num1; }

char* F() //Factor因子 { char *res; res=(char *)malloc(10); if(syn==10) //字符串 { strcpy(res,token); scanner(); } else if(syn==20) //二进制数 { itoa((int)sum,res,10); //整数转换为字符串 scanner(); } else if(syn==26) //( { scanner();

res=E(); if(syn==27) //) { scanner(); } else isError=1; } else isError=1; return res; }

char *newTemp() { char *p; char varTemp[10]; p=(char *)malloc(10); kk++; itoa(kk,varTemp,10); strcpy(p+1,varTemp); p[0]='T'; return p; }

//将p所链接的每个四元式的第四个分量都回填t void backpatch(int p,int t) { int w,circle=p; while(circle) //circle不为0的时候 { w=atoi(fourCom[circle].result); //四元式circle第四分量内容 //strcpy(fourCom[circle].result,t); //把t填进四元式circle的第四分量 sprintf(fourCom[circle].result,\"%d\ circle=w; //w记录的是链条上下一个四元式,移动! } return; }

int merge(int p1,int p2) //合并p1和p2 { char circle,nResult; if(p2==0) nResult=p1; else { nResult=circle=p2; while(atoi(fourCom[circle].result)) //四元式第四个分量不为0 { circle=atoi(fourCom[circle].result); //strcpy(fourCom[circle].result,p1); sprintf(fourCom[circle].result,\"%s\ } //目的是用p1的值覆盖0 } return nResult; //p2是头,p1覆盖0,接在p2后边 }

void emit(char *res,char *num1,char *op,char *num2)

{ strcpy(fourCom[nextq].result,res); strcpy(fourCom[nextq].arg1,num1); strcpy(fourCom[nextq].opera,op); strcpy(fourCom[nextq].arg2,num2); nextq++; }

void scanner() {

sum=0; decimal=0; m=0;

for(n=0;n<8;n++) token[n]=NULL;

ch=prog[p++]; //从prog中读出一个字符到ch中 while(ch==' '||ch=='\\n') //跳过空字符(无效输入) ch=prog[p++];

if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))) //ch是字母字符 {

while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9'))) {

token[m++]=ch; //ch=>token ch=prog[p++]; //读下一个字符 }

token[m++]='\\0'; p--; //回退一格 syn=10; //标识符

//如果是\"begin\标识符中的一个 for(n=0;n<9;n++)

if(strcmp(token,rwtab[n])==0) {

syn=n+1; break; } }

else if((ch>='0')&&(ch<='9')) { IsNum:

if(isSignal==1) { //token[m++]='-'; }

while((ch>='0')&&(ch<='9')) {

sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的 ch=prog[p++]; }

if(ch=='.') {

isDecimal=1; ch=prog[p++]; count=0; //之前忘了清零,123.123+123.123#两个浮点数就无法识别

while((ch>='0')&&(ch<='9')) {

//pow(x,y)计算x的y次幂

temp=(ch-'0')*pow(0.1,++count); decimal=decimal+temp; //AddToDec(); ch=prog[p++]; }

sum=sum+decimal; }

if(ch=='e'||ch=='E') {

isExp=1;

ch=prog[p++]; if(ch=='-') {

isNegative=1; ch=prog[p++]; }

while((ch>='0')&&(ch<='9')) {

//指数

index=index*10+ch-'0'; ch=prog[p++]; }

//10的幂

//123e3代表123*10(3)

//sum=sum*pow(10,index);是错误的 if(isNegative)

sum=sum*pow(0.1,index); else

sum=sum*pow(10,index);

} if(isSignal==1) { sum=-sum; isSignal=0; }

p--; syn=20; }

else switch(ch) {

case '<': m=0;

token[m++]=ch; ch=prog[p++]; if(ch=='=') {

syn=35;

token[m++]=ch; } else {

syn=34;

p--; }

break;

case '>': m=0;

token[m++]=ch; ch=prog[p++]; if(ch=='=') {

syn=33;

token[m++]=ch; } else {

syn=32; p--; }

break;

case '=': m=0;

token[m++]=ch; ch=prog[p++]; if(ch=='=') {

syn=36;

token[m++]=ch; } else {

syn=21; p--; }

break; case '+': temp2=prog[p]; token[m++]=ch; if((temp2>='0')&&(temp2<='9')&&(repeat==1)) { isSignal=2; ch=prog[p++]; repeat=0; goto IsNum; } if(((temp2=='+')||(temp2=='-'))&&(repeat==0)) //如果重复出现符号,才将后边的+,-视为正负号 { repeat=1; //ch=prog[p++]; } syn=22;

break; case '-': temp2=prog[p]; token[m++]=ch; if((temp2>='0')&&(temp2<='9')&&(repeat==1)) { isSignal=1; ch=prog[p++]; //读\"-\"下一个字符 repeat=0; goto IsNum; //转到数字的识别 } if(((temp2=='+')||(temp2=='-'))&&(repeat==0)) 的+,-视为正负号 { repeat=1; //预言会重复 //ch=prog[p++]; //读下一个字符 } syn=23; break; case '*': temp2=prog[p]; token[m++]=ch; if(temp2=='+') { isSignal=2; repeat=1; } else if(temp2=='-') { isSignal=1; repeat=1; } syn=24; break;

case '/':

syn=25;

token[m++]=ch; break; case '(': temp2=prog[p]; token[m++]=ch; if(temp2=='+') { isSignal=2; repeat=1; } else if(temp2=='-') { isSignal=1; repeat=1; }

//如果重复出现符号,才将后边 syn=26; break; case ')':

syn=27;

token[m++]=ch; break; case '{':

syn=28;

token[m++]=ch; break; case '}':

syn=29;

token[m++]=ch; break; case ',':

syn=30;

token[m++]=ch; break; case ';':

syn=31;

token[m++]=ch; break; case'#': syn=0;

token[m++]=ch; break; default: syn=-1; } }

zhongjiandaima(){ p=0; count=0; isDecimal=0; index=0; repeat=0; kk=0; printf(\"\\nPlease input your source string:\\n\"); do{ ch=getchar(); prog[p++]=ch; }while(ch!='#'); p=0; isError=0; scanner(); lrparser(); for(i=1;iif(strcmp(fourCom[i].opera,\"=\")==0)

{

printf(\"Move AX,%1s\\n\ printf(\"Move %5s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"+\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"ADD Ax,%1s\\n\printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"-\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"SUB Ax,%1s\\n\ printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"*\")==0) {

printf(\"Mov AL,%1s\\n\ printf(\"MUL %1s\\n\ printf(\"Mov %1s,Ax\\n\}

if(strcmp(fourCom[i].opera,\"/\")==0) {

printf(\"Mov AX,%1s\\n\ printf(\"DIv %1s\\n\ printf(\"Mov %1s,AL\\n\}

if(strcmp(fourCom[i].arg2,\"goto\")==0&&strcmp(fourCom[i].arg1,\"if\")==0) {

printf(\"cmp %1s\\n\printf(\"jnc %1s\\n\ } else {

printf(\"jmp %1s\\n\} } return; }

void main()

{ printf(\" \\n\"); printf(\" \\n\"); printf(\"

##################################################################### \\n\");

printf(\" choice 1--------cifafenxi\\n\"); printf(\" choice 2--------yufafenxi\\n\");

printf(\" choice 3--------zhongjiandaima\\n\\n\"); printf(\"

##################################################################### \\n\");

scanf(\"%d\do

{

switch(r1) {

case 1: cifafenxi();

scanf(\"%d\ break; case 2:yufafenxi() ;

scanf(\"%d\ break;

case 3:zhongjiandaima(); scanf(\"%d\ break;

default: printf(\"error,please input again\"); break; }

}while(r1!=0); }

cifafenxi() {p1=0;

printf(\" ------------------Welcome(cifafenxi)-----------------\"); printf(\"\\n please input a string(end with '#'):/n\"); do{

scanf(\"%c\ prog1[p1++]=ch1; }while(ch1!='#'); p1=0; do{

scaner1(); switch(syn1)

{case 11:printf(\"( %-10d%5d )\\n\ break;

case -1:printf(\"you have input a wrong string\\n\");

exit(0);

default: printf(\"( %-10s%5d )\\n\ break; }

}while(syn1!=0); }

scaner1() { sum1=0;

for(m1=0;m1<8;m1++)token1[m1++]=NULL; ch1=prog1[p1++]; m1=0;

while((ch1==' ')||(ch1=='\\n'))ch1=prog1[p1++];

if(((ch1<='z')&&(ch1>='a'))||((ch1<='Z')&&(ch1>='A')))

{ while(((ch1<='z')&&(ch1>='a'))||((ch1<='Z')&&(ch1>='A'))||((ch1>='0')&&(ch1<='9'))) {token1[m1++]=ch1; ch1=prog1[p1++]; } p1--; syn1=10;

for(n1=0;n1<6;n1++)

if(strcmp(token1,rwtab1[n1])==0) { syn1=n1+1; break; } }

else if((ch1>='0')&&(ch1<='9')) { while((ch1>='0')&&(ch1<='9')) { sum1=sum1*10+ch1-'0'; ch1=prog1[p1++]; } p1--; syn1=11; }

else switch(ch1)

{ case '<':token1[m1++]=ch1; ch1=prog1[p1++]; if(ch1=='=') { syn1=22;

token1[m1++]=ch1; } else

{ syn1=20; p1--; } break;

case '>':token1[m1++]=ch1; ch1=prog1[p1++]; if(ch1=='=') { syn1=24;

token1[m1++]=ch1; } else

{ syn1=23; p1--; } break;

case '+': token1[m1++]=ch1; ch1=prog1[p1++]; if(ch1=='+') { syn1=17;

token1[m1++]=ch1; } else

{ syn1=13; p1--; } break;

case '-':token1[m1++]=ch1; ch1=prog1[p1++]; if(ch1=='-') { syn1=29;

token1[m1++]=ch1; } else

{ syn1=14; p1--; }

break;

case '!':ch1=prog1[p1++]; if(ch1=='=') { syn1=21;

token1[m1++]=ch1; } else

{ syn1=31; p1--; } break;

case '=':token1[m1++]=ch1; ch1=prog1[p1++]; if(ch1=='=') { syn1=25;

token1[m1++]=ch1; } else

{ syn1=18; p1--; } break;

case '*': syn1=15;

token1[m1++]=ch1; break; case '/': syn1=16;

token1[m1++]=ch1; break; case '(': syn1=27;

token1[m1++]=ch1; break; case ')': syn1=28;

token1[m1++]=ch1; break; case '{': syn1=5;

token1[m1++]=ch1; break; case '}': syn1=6;

token1[m1++]=ch1; break; case ';': syn1=26;

token1[m1++]=ch1; break;

case '\\\"': syn1=30;

token1[m1++]=ch1; break; case '#': syn1=0;

token1[m1++]=ch1; break; case ':':syn1=17;

token1[m1++]=ch1; break; default: syn1=-1; break; }

token1[m1++]='\\0';

} /**/

yufafenxi() {

printf(\" ------------------Welcome(yufafenxi)-----------------\"); right1=1;

cout<<\"请输入您要分析的字符串以#结束(^为空字符):\"<>inputstream; e();

if((inputstream[temp1]=='#')&&right) cout<<\"分析成功\"<cout<<\"分析失败\"<void e() {

cout<<\"E->TE'\"<void e1() {

if(inputstream[temp1]=='+') {

cout<<\"E'->+TE'\"<if (inputstream[temp1]!='#'||inputstream[temp1]!=')') {

cout<<\"T'->^\"<right1=0; }

void t() {

cout<<\"T->FT'\"<void t1() {

if(inputstream[temp1]=='*') {

cout<<\"T'->*FT'\"<if (inputstream[temp1]!='#'&&inputstream[temp1]!=')'&&inputstream[temp1]!='+')

{

cout<<\"T'->^\"<void f() {

if(inputstream[temp1]=='i') {

cout<<\"F->i\"<if(inputstream[temp1]=='(') {

cout<<\"F->(E)\"<if(inputstream[temp1]==')') {

cout<<\"F->(E)\"<right1=0; }

else right1 =0; }

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- sarr.cn 版权所有 赣ICP备2024042794号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务