c语言学习中地语法分析器

c语言学习中地语法分析器
c语言学习中地语法分析器

#include

#include

#include

/*******************************************/

int count=0; /*分解的产生式的个数*/

int number; /*所有终结符和非终结符的总数*/

char start; /*开始符号*/

char termin[50]; /*终结符号*/

char non_ter[50]; /*非终结符号*/

char v[50]; /*所有符号*/

char left[50]; /*左部*/

char right[50][50]; /*右部*/

char first[50][50],follow[50][50]; /*各产生式右部的FIRST和左部的FOLLOW集合*/ char first1[50][50]; /*所有单个符号的FIRST集合*/

char select[50][50]; /*各单个产生式的SELECT集合*/

char f[50],F[50]; /*记录各符号的FIRST和FOLLOW是否已求过*/

char empty[20]; /*记录可直接推出@的符号*/

char TEMP[50]; /*求FOLLOW时存放某一符号串的FIRST集合*/

int validity=1; /*表示输入文法是否有效*/

int ll=1; /*表示输入文法是否为LL(1)文法*/

int M[20][20]; /*分析表*/

char choose; /*用户输入时使用*/

char empt[20]; /*求_emp()时使用*/

char fo[20]; /*求FOLLOW集合时使用*/

/*******************************************

判断一个字符是否在指定字符串中

********************************************/

int in(char c,char *p)

{

int i;

if(strlen(p)==0)

return(0);

for(i=0;;i++)

{

if(p[i]==c)

return(1); /*若在,返回1*/

if(i==strlen(p))

return(0); /*若不在,返回0*/

}

}

/*******************************************

得到一个不是非终结符的符号

********************************************/

char c()

{

char c='A';

while(in(c,non_ter)==1)

c++;

return(c);

}

/*******************************************

分解含有左递归的产生式

********************************************/

void recur(char *point)

{ /*完整的产生式在point[]中*/ int j,m=0,n=3,k;

char temp[20],ch;

ch=c(); /*得到一个非终结符*/

k=strlen(non_ter);

non_ter[k]=ch;

non_ter[k+1]='\0';

for(j=0;j<=strlen(point)-1;j++)

{

if(point[n]==point[0])

{ /*如果'|'后的首符号和左部相同*/ for(j=n+1;j<=strlen(point)-1;j++)

{

while(point[j]!='|'&&point[j]!='\0')

temp[m++]=point[j++];

left[count]=ch;

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

m=0;

count++;

if(point[j]=='|')

{

n=j+1;

break;

}

}

}

else

{ /*如果'|'后的首符号和左部不同*/ left[count]=ch;

right[count][0]='@';

right[count][1]='\0';

count++;

for(j=n;j<=strlen(point)-1;j++)

{

if(point[j]!='|')

temp[m++]=point[j];

else

{

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

printf(" count=%d ",count);

m=0;

count++;

}

}

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

count++;

m=0;

}

}

}

/******************************************* 分解不含有左递归的产生式

********************************************/ void non_re(char *point)

{

int m=0,j;

char temp[20];

for(j=3;j<=strlen(point)-1;j++)

{

if(point[j]!='|')

temp[m++]=point[j];

else

{

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]='\0';

m=0;

count++;

}

}

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]='\0';

count++;

m=0;

}

/*******************************************

读入一个文法

********************************************/ char grammer(char *t,char *n,char *left,char right[50][50]) {

char vn[50],vt[50];

char s;

char p[50][50];

int i,j,k;

printf("请输入文法的非终结符号串:");

scanf("%s",vn);

getchar();

i=strlen(vn);

memcpy(n,vn,i);

n[i]='\0';

printf("请输入文法的终结符号串:");

scanf("%s",vt);

getchar();

i=strlen(vt);

memcpy(t,vt,i);

t[i]='\0';

printf("请输入文法的开始符号:");

scanf("%c",&s);

getchar();

printf("请输入文法产生式的条数:");

scanf("%d",&i);

getchar();

for(j=1;j<=i;j++)

{

printf("请输入文法的第%d条(共%d条)产生式:",j,i); scanf("%s",p[j-1]);

getchar();

}

for(j=0;j<=i-1;j++)

if(p[j][1]!='-'||p[j][2]!='>')

{ printf("\ninput error!");

validity=0;

return('\0');

} /*检测输入错误*/

for(k=0;k<=i-1;k++)

{ /*分解输入的各产生式*/

if(p[k][3]==p[k][0])

recur(p[k]);

else

non_re(p[k]);

}

return(s);

}

/*******************************************

将单个符号或符号串并入另一符号串

********************************************/

void merge(char *d,char *s,int type)

{ /*d是目标符号串,s是源串,type=1,源串中的' @ '一并并入目串;

type=2,源串中的' @ '不并入目串*/

int i,j;

for(i=0;i<=strlen(s)-1;i++)

{

if(type==2&&s[i]=='@')

;

else

{

for(j=0;;j++)

{

if(j

break;

if(j==strlen(d))

{

d[j]=s[i];

d[j+1]='\0';

break;

}

}

}

}

}

/*******************************************

求所有能直接推出@的符号

********************************************/

void emp(char c)

{ /*即求所有由' @ '推出的符号*/ char temp[10];

int i;

for(i=0;i<=count-1;i++)

{

if(right[i][0]==c&&strlen(right[i])==1)

{

temp[0]=left[i];

temp[1]='\0';

merge(empty,temp,1);

emp(left[i]);

}

}

}

/*******************************************

求某一符号能否推出' @ '

********************************************/

int _emp(char c)

{ /*若能推出,返回1;否则,返回0*/ int i,j,k,result=1,mark=0;

char temp[20];

temp[0]=c;

temp[1]='\0';

merge(empt,temp,1);

if(in(c,empty)==1)

return(1);

for(i=0;;i++)

{

if(i==count)

return(0);

if(left[i]==c) /*找一个左部为c的产生式*/

{

j=strlen(right[i]); /*j为右部的长度*/ if(j==1&&in(right[i][0],empty)==1)

return(1);

else if(j==1&&in(right[i][0],termin)==1)

return(0);

else

{

for(k=0;k<=j-1;k++)

if(in(right[i][k],empt)==1)

mark=1;

if(mark==1)

continue;

else

{

for(k=0;k<=j-1;k++)

{

result*=_emp(right[i][k]);

temp[0]=right[i][k];

temp[1]='\0';

merge(empt,temp,1);

}

}

}

if(result==0&&i

continue;

else if(result==1&&i

return(1);

}

}

}

/*******************************************

判断读入的文法是否正确

********************************************/

int judge()

{

int i,j;

for(i=0;i<=count-1;i++)

{

if(in(left[i],non_ter)==0)

{ /*若左部不在非终结符中,报错*/

printf("\nerror1!");

validity=0;

return(0);

}

for(j=0;j<=strlen(right[i])-1;j++)

{

if(in(right[i][j],non_ter)==0&&in(right[i][j],termin)==0&&right[i][j]!='@')

{ /*若右部某一符号不在非终结符、终结符中且不为' @ ',报错*/ printf("\nerror2!");

validity=0;

return(0);

}

}

}

return(1);

}

/*******************************************

求单个符号的FIRST

********************************************/

void first2(int i)

{ /*i为符号在所有输入符号中的序号*/ char c,temp[20];

int j,k,m;

c=v[i];

char ch='@';

emp(ch);

if(in(c,termin)==1) /*若为终结符*/

{

first1[i][0]=c;

first1[i][1]='\0';

}

else if(in(c,non_ter)==1) /*若为非终结符*/

{

for(j=0;j<=count-1;j++)

{

if(left[j]==c)

{

if(in(right[j][0],termin)==1||right[j][0]=='@') {

temp[0]=right[j][0];

temp[1]='\0';

merge(first1[i],temp,1);

}

else if(in(right[j][0],non_ter)==1)

{

if(right[j][0]==c)

continue;

for(k=0;;k++)

if(v[k]==right[j][0])

break;

if(f[k]=='0')

{

first2(k);

f[k]='1';

}

merge(first1[i],first1[k],2);

for(k=0;k<=strlen(right[j])-1;k++)

{

empt[0]='\0';

if(_emp(right[j][k])==1&&k

{

for(m=0;;m++)

if(v[m]==right[j][k+1])

break;

if(f[m]=='0')

{

first2(m);

f[m]='1';

}

merge(first1[i],first1[m],2);

}

else if(_emp(right[j][k])==1&&k==strlen(right[j])-1)

{

temp[0]='@';

temp[1]='\0';

merge(first1[i],temp,1);

}

else

break;

}

}

}

}

}

f[i]='1';

}

/*******************************************

求各产生式右部的FIRST

********************************************/

void FIRST(int i,char *p)

{

int length;

int j,k,m;

char temp[20];

length=strlen(p);

if(length==1) /*如果右部为单个符号*/ {

if(p[0]=='@')

{

if(i>=0)

{

first[i][0]='@';

first[i][1]='\0';

}

else

{

TEMP[0]='@';

TEMP[1]='\0';

}

}

else

{

for(j=0;;j++)

if(v[j]==p[0])

break;

if(i>=0)

{

memcpy(first[i],first1[j],strlen(first1[j]));

first[i][strlen(first1[j])]='\0';

}

else

{

memcpy(TEMP,first1[j],strlen(first1[j]));

TEMP[strlen(first1[j])]='\0';

}

}

}

else /*如果右部为符号串*/ {

for(j=0;;j++)

if(v[j]==p[0])

break;

if(i>=0)

merge(first[i],first1[j],2);

else

merge(TEMP,first1[j],2);

for(k=0;k<=length-1;k++)

{

empt[0]='\0';

if(_emp(p[k])==1&&k

{

for(m=0;;m++)

if(v[m]==right[i][k+1])

break;

if(i>=0)

merge(first[i],first1[m],2);

else

merge(TEMP,first1[m],2);

}

else if(_emp(p[k])==1&&k==length-1) {

temp[0]='@';

temp[1]='\0';

if(i>=0)

merge(first[i],temp,1);

else

merge(TEMP,temp,1);

}

else if(_emp(p[k])==0)

break;

}

}

}

/*******************************************

求各产生式左部的FOLLOW

********************************************/ void FOLLOW(int i)

{

int j,k,m,n,result=1;

char c,temp[20];

c=non_ter[i]; /*c为待求的非终结符*/ temp[0]=c;

temp[1]='\0';

merge(fo,temp,1);

if(c==start)

{ /*若为开始符号*/

temp[0]='#';

temp[1]='\0';

merge(follow[i],temp,1);

}

for(j=0;j<=count-1;j++)

{

if(in(c,right[j])==1) /*找一个右部含有c的产生式*/ {

for(k=0;;k++)

if(right[j][k]==c)

break; /*k为c在该产生式右部的序号*/

for(m=0;;m++)

if(v[m]==left[j])

break; /*m为产生式左部非终结符在所有符号中的序号*/ if(k==strlen(right[j])-1)

{ /*如果c在产生式右部的最后*/

if(in(v[m],fo)==1)

{

merge(follow[i],follow[m],1);

continue;

}

if(F[m]=='0')

{

FOLLOW(m);

F[m]='1';

}

merge(follow[i],follow[m],1);

}

else

{ /*如果c不在产生式右部的最后*/

for(n=k+1;n<=strlen(right[j])-1;n++)

{

empt[0]='\0';

result*=_emp(right[j][n]);

}

if(result==1)

{ /*如果右部c后面的符号串能推出^*/

if(in(v[m],fo)==1)

{ /*避免循环递归*/

merge(follow[i],follow[m],1);

continue;

}

if(F[m]=='0')

{

FOLLOW(m);

F[m]='1';

}

merge(follow[i],follow[m],1);

}

for(n=k+1;n<=strlen(right[j])-1;n++)

temp[n-k-1]=right[j][n];

temp[strlen(right[j])-k-1]='\0';

FIRST(-1,temp);

merge(follow[i],TEMP,2);

}

}

}

F[i]='1';

}

/*******************************************

判断读入文法是否为一个LL(1)文法

********************************************/

int ll1()

{

int i,j,length,result=1;

char temp[50];

for(j=0;j<=49;j++)

{ /*初始化*/

first[j][0]='\0';

follow[j][0]='\0';

first1[j][0]='\0';

select[j][0]='\0';

TEMP[j]='\0';

temp[j]='\0';

f[j]='0';

F[j]='0';

}

for(j=0;j<=strlen(v)-1;j++)

first2(j); /*求单个符号的FIRST集合*/ printf("\n各非终结符导出的first集:");

for(j=0;j<=strlen(v)-1;j++)

printf("%c:%s ",v[j],first1[j]);

printf("\n能导空的非终结符集合:%s",empty);

// printf("\n_emp:");

//for(j=0;j<=strlen(v)-1;j++)

// printf("%d ",_emp(v[j]));

for(i=0;i<=count-1;i++)

FIRST(i,right[i]); /*求FIRST*/

for(j=0;j<=strlen(non_ter)-1;j++)

{ /*求FOLLOW*/

if(fo[j]==0)

{

fo[0]='\0';

FOLLOW(j);

}

}

//printf("\nfirst:");

//for(i=0;i<=count-1;i++)

// printf("%s ",first[i]);

printf("\nfollow集合:");

for(i=0;i<=strlen(non_ter)-1;i++)

printf("%s ",follow[i]);

for(i=0;i<=count-1;i++)

{ /*求每一产生式的SELECT集合*/ memcpy(select[i],first[i],strlen(first[i]));

select[i][strlen(first[i])]='\0';

for(j=0;j<=strlen(right[i])-1;j++)

result*=_emp(right[i][j]);

if(strlen(right[i])==1&&right[i][0]=='@')

result=1;

if(result==1)

{

for(j=0;;j++)

if(v[j]==left[i])

break;

merge(select[i],follow[j],1);

}

}

printf("\nselect集合顺序是:");

for(i=0;i<=count-1;i++)

printf("%s ",select[i]);

memcpy(temp,select[0],strlen(select[0]));

temp[strlen(select[0])]='\0';

for(i=1;i<=count-1;i++)

{ /*判断输入文法是否为LL(1)文法*/

length=strlen(temp);

if(left[i]==left[i-1])

{

merge(temp,select[i],1);

if(strlen(temp)

return(0);

}

else

{

temp[0]='\0';

memcpy(temp,select[i],strlen(select[i]));

temp[strlen(select[i])]='\0';

}

}

return(1);

}

/*******************************************

构造分析表M

********************************************/ void MM()

{

int i,j,k,m;

for(i=0;i<=19;i++)

for(j=0;j<=19;j++)

M[i][j]=-1;

i=strlen(termin);

termin[i]='#'; /*将#加入终结符数组*/

termin[i+1]='\0';

for(i=0;i<=count-1;i++)

{

for(m=0;;m++)

if(non_ter[m]==left[i])

break; /*m为产生式左部非终结符的序号*/ for(j=0;j<=strlen(select[i])-1;j++)

{

if(in(select[i][j],termin)==1)

{

for(k=0;;k++)

if(termin[k]==select[i][j])

break; /*k为产生式右部终结符的序号*/

M[m][k]=i;

}

}

}

}

/*******************************************

判断符号串是否是该文法的句型

********************************************/ void syntax()

{

int i,j,k,m,n,p,q;

char ch;

char S[50],str[50];

printf("请输入该文法的句型:");

scanf("%s",str);

getchar();

i=strlen(str);

str[i]='#';

str[i+1]='\0';

S[0]='#';

S[1]=start;

S[2]='\0';

j=0;

ch=str[j];

while(1)

{

if(in(S[strlen(S)-1],termin)==1)

{

if(S[strlen(S)-1]!=ch)

{

printf("该符号串不是文法的句型!");

return;

}

else if(S[strlen(S)-1]=='#')

{

printf("该符号串是文法的句型.");

return;

}

else

{

S[strlen(S)-1]='\0';

j++;

ch=str[j];

}

}

else

{

for(i=0;;i++)

if(non_ter[i]==S[strlen(S)-1])

break;

for(k=0;;k++)

{

if(termin[k]==ch)

break;

if(k==strlen(termin))

{

printf("词法错误!");

return;

}

}

if(M[i][k]==-1)

{

printf("语法错误!");

return;

}

else

{

m=M[i][k];

if(right[m][0]=='@')

S[strlen(S)-1]='\0';

else

{

p=strlen(S)-1;

q=p;

for(n=strlen(right[m])-1;n>=0;n--)

S[p++]=right[m][n];

S[q+strlen(right[m])]='\0';

}

}

}

printf("S:%s str:",S);

for(p=j;p<=strlen(str)-1;p++)

printf("%c",str[p]);

printf(" \n");

}

}

/*******************************************

一个用户调用函数

********************************************/

void menu()

{

syntax();

printf("\n是否继续?(y or n):");

scanf("%c",&choose);

getchar();

while(choose=='y')

{

menu();

}

}

/*******************************************

主函数

********************************************/

void main()

{

int i,j;

start=grammer(termin,non_ter,left,right); /*读入一个文法*/ printf("count=%d",count);

printf("\n开始符号为:%c",start);

strcpy(v,non_ter);

strcat(v,termin);

printf("\n所有符号集为:%s",v);

printf("\n非终结符集合:{%s",non_ter);

printf("}");

printf("\n终结符集合:{%s",termin);

printf("}");

printf("\n文法所有右边表达式依次是:");

for(i=0;i<=count-1;i++)

printf("%s ",right[i]);

printf("\n文法所有左边开始符依次是:");

for(i=0;i<=count-1;i++)

printf("%c ",left[i]);

if(validity==1)

validity=judge();

//printf("\nvalidity=%d",validity);

if(validity==1)

{

ll=ll1();

// printf("\nll=%d",ll);

if(ll==0)

printf("\n该文法不是一个LL1文法!");

else

{

printf("\n该文法是一个LL(1)文法!");

MM();

// printf("\n");

//for(i=0;i<=19;i++)

// for(j=0;j<=19;j++)

// if(M[i][j]>=0)

//printf("M[%d][%d]=%d ",i,j,M[i][j]);

menu();

}

}

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

语法分析程序的要求

语法分析程序大作业 一、作业目的和要求 通过设计、编制、调试一个典型的语法分析程序(任选有代表性的语法分析方法,如LL(1)、递归下降分析法、LR、算符优先分析法)等,作为编制语法分析程序的依据,对词法分析器所提供的单词序列进行语法检测和结构分析,实现并进一步掌握常用的语法分析方法。 二、作业内容 选择对各种常见高级程序设计语言都较为通用的语法结构作为分析对象(例如表达式、if、while、for等等),给出其文法规则描述(注意,文法规则的描述要符合所选分析方法的要求,比如用LL(1)分析法,文法必须是LL(1)文法),设计并实现一个完整的语法分析程序。 输入:源程序以文件的形式输入。 输出:对于输入的源程序,如果输入源程序是给定文法定义的合法程序,则输出”success”,如果不是,即输入源程序有错误,则输出“Error”,并且尽可能指出出错位置和原因。 三、作业要求 1、说明语法分析的源语言是什么? 能分析的语法成分有哪些(比如if、while、表达式、switch等等)。 给出每个语法规则的文法描述。(可以自定义语法成分,设计合理的语法规则。) 2、说明选择的语法分析方法是哪种?描述总体设计思路和主要的流程图。 3、编程实现,程序中编写的各种函数,需要给出注释,说明函数的作用。 四、结果分析 1、输入正确的源程序截图: 输出结果截图: 2、输入错误的源程序截图: 输出结果截图: 3、总结(自己的心得体会、你编写的语法分析程序的优缺点) 作业分工 上交内容:将以下文件打包压缩,压缩包命名:班级学号姓名_语法分析大作业 学号姓名以组长名字命名即可 1、本报告 2、语法分析程序代码 3、编译生成可执行程序 4、用于测试的源程序代码文件。

词法分析器实验报告及源代码

数学与软件科学学院实验报告 学期:13至14__ 第_2 学期 2014年3月17 日 课程名称:编译原理专业:2011级5_班 实验编号:01 实验项目:词法分析器指导教师_王开端 姓名:张世镪学号: 2011060566 实验成绩: 一、目的 学习编译原理,词法分析是编译的第一个阶段,其任务是从左至右挨个字符地对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号串形式的中间程序。执行词法分析的程序称为词法分析程序,也称为词法分析器或扫描器。词法分析器的功能是输入源程序,输出单词符号 做一个关于C的词法分析器,C++实现 二、任务及要求 1.词法分析器产生下述C的单词序列 这个C的所有的单词符号,以及它们的种别编码和内部值如下表: -* / & <<=>>===!= && || , : ; { } [ ] ( ) ID和NUM的正规定义式为: ID→letter(letter | didit)* NUM→digit digit* letter→a | … | z | A | … | Z

digit→ 0 | … | 9 如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。 三、大概设计 1. 设计原理 词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。 理论基础:有限自动机、正规文法、正规式 词法分析器又称扫描器:执行词法分析的程序 2. 词法分析器的功能和输出形式 功能:输入源程序、输出单词符号 程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符、界符。3. 输出的单词符号的表示形式: (单词种别,单词符号的属性值) 单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。 4. 状态转换图实现

编译原理C语言词法分析器

编译原理 C语言词法分析器 一、实验题目 编制并调试C词法分析程序。 a.txt源代码: ?main() { int sum=0 ,it=1;/* Variable declaration*/ if (sum==1) it++; else it=it+2; }? 设计其词法分析程序,能识别出所有的关键字、标识符、常数、运算符(包括复合运算符,如++)、界符;能过滤掉源程序中的注释、空格、制表符、换行符;并且能够对一些词法规则的错误进行必要的处理,如:标识符只能由字母、数字与下划线组成,且第一个字符必须为字母或下划线。实验要求:要给出所分析语言的词法说明,相应的状态转换图,单词的种别编码方案,词法分析程序的主要算法思想等。 二、实验目的 1、理解词法分析在编译程序中的作用; 2、掌握词法分析程序的实现方法与技术; 3、加深对有穷自动机模型的理解。 三、主要函数 四、设计 1、主函数void main ( ) 2 3

4、整数类型判断函数 char *key1[]={" ","(",")","[","]","{","}",",",";","'"}; /*分隔符表*/

char *key2[]={" ","+","-","*","/","%","<",">","==",">=","<=","!=","!","&&","||","<<",">>","~","|","^","&","=","?:","->","++","--","、","+=","-=","*=","/="}; /*运算符表*/ int xx0[35],xx1[10],xx2[31]; int temp_key3=0,temp_c40=0,temp_c41=0,temp_c42=0,temp_c43=0; /******* 初始化函数*******/ void load() { int mm; for (mm=0;mm<=34;mm++) { xx0[mm]=0; } for (mm=0;mm<=9;mm++) { xx1[mm]=0; } for (mm=0;mm<=30;mm++) { xx2[mm]=0; } FILE *floading; if ((floading=fopen("key0、txt","w"))==NULL) { printf("Error! Can't create file : key0、txt"); return; } fclose (floading); /*建立保留字表文件:key0、txt*/ if ((floading=fopen("key1、txt","w"))==NULL) { printf("Error! Can't create file : key1、txt"); return; } /*建立分隔符表文件:key1、txt*/ if ((floading=fopen("key2、txt","w"))==NULL) { printf("Error! Can't create file : key2、txt"); return; } fclose(floading); /*建立运算符表文件:key2、txt*/ if ((floading=fopen("key3、txt","w"))==NULL) { printf("Error! Can't create file : key3、txt");

编译原理-语法分析器-(java完美运行版) - 副本

实验二语法分析器 一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容 ◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串 进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号 以及LL(1)分析表,对输入符号串自上而下的分析过程。 三、LL(1)分析法实验设计思想及算法 ◆模块结构: (1)定义部分:定义常量、变量、数据结构。 (2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等); (3)控制部分:从键盘输入一个表达式符号串; (4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、如果遇到错误的表达式,应输出错误提示信息。 3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS|/FS (6)S->ε (7)F->(E) (8)F->i 输出的格式如下:

五、实验源程序 LL1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; import java.util.Vector; public class LL1 extends JFrame implements ActionListener { /** * */ private static final long serialVersionUID = 1L; JTextField tf1; JTextField tf2; JLabel l; JButton b0; JPanel p1,p2,p3; JTextArea t1,t2,t3; JButton b1,b2,b3;

c语言语法分析器详解

#include #include #include /*******************************************/ int count=0; /*分解的产生式的个数*/ int number; /*所有终结符和非终结符的总数*/ char start; /*开始符号*/ char termin[50]; /*终结符号*/ char non_ter[50]; /*非终结符号*/ char v[50]; /*所有符号*/ char left[50]; /*左部*/ char right[50][50]; /*右部*/ char first[50][50],follow[50][50]; /*各产生式右部的FIRST和左部的FOLLOW集合*/ char first1[50][50]; /*所有单个符号的FIRST集合*/ char select[50][50]; /*各单个产生式的SELECT集合*/ char f[50],F[50]; /*记录各符号的FIRST和FOLLOW是否已求过*/ char empty[20]; /*记录可直接推出@的符号*/ char TEMP[50]; /*求FOLLOW时存放某一符号串的FIRST集合*/ int validity=1; /*表示输入文法是否有效*/ int ll=1; /*表示输入文法是否为LL(1)文法*/ int M[20][20]; /*分析表*/ char choose; /*用户输入时使用*/ char empt[20]; /*求_emp()时使用*/ char fo[20]; /*求FOLLOW集合时使用*/ /******************************************* 判断一个字符是否在指定字符串中 ********************************************/ int in(char c,char *p) { int i; if(strlen(p)==0) return(0); for(i=0;;i++) { if(p[i]==c) return(1); /*若在,返回1*/ if(i==strlen(p)) return(0); /*若不在,返回0*/ } } /******************************************* 得到一个不是非终结符的符号 ********************************************/

词法分析器的实现与设计

题目:词法分析器的设计与实现 一、引言................................ 错误!未定义书签。 二、词法分析器的设计 (3) 2.1词的内部定义 (3) 2.2词法分析器的任务及功能 (3) 3 2.2.2 功能: (4) 2.3单词符号对应的种别码: (4) 三、词法分析器的实现 (5) 3.1主程序示意图: (5) 3.2函数定义说明 (6) 3.3程序设计实现及功能说明 (6) 错误!未定义书签。 7 7 四、词法分析程序的C语言源代码: (7) 五、结果分析: (12) 摘要:词法分析是中文信息处理中的一项基础性工作。词法分析结果的好坏将直接影响中文信息处理上层应用的效果。通过权威的评测和实际应用表明,IRLAS是一个高精度、高质量的、高可靠性的词法分析系统。众所周知,切分歧义和未登录词识别是中文分词中的两大难点。理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实

现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。Abstract:lexical analysis is a basic task in Chinese information processing. The results of lexical analysis will directly affect the effectiveness of the application of Chinese information processing. The evaluation and practical application show that IRLAS is a high precision, high quality and high reliability lexical analysis system. It is well known that segmentation ambiguity and unknown word recognition are the two major difficulties in Chinese word segmentation. The understanding of lexical analyse the program at compile, deepen of finite automata model for understanding, master lexical analysis program implementation method and technology, using C language subset of a simple language compilation of a scanned again compiler, to deepen to compile the principle solution, master compiler implementation method and technology. 关键词:词法分析器?扫描器?单词符号?预处理 Keywords: lexical analyzer word symbol pretreatment scanner 一、引言 运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。本程序是在Visual?Studio环境下,使用C语言作为开发工具。基于实验任务

语法分析器源代码

#include #include #include #define HIGHER 1 #define LOWER -1 #define EQUAL 0 #define TRUE 1 #define FALSE 0 #define OPER_NUM 50 //默认算符数目 #define VN_NUM 50 //默认非终结符数目#define MAX_BUFFER 128 //每行输入行最大长度 #define MAX_GRA_NUM 20 //最大文法数目#define EMPTY -2 //算符优先表初始值,表示这对算符没有优先关系 #define STACK_SIZE 64 typedef struct { char c; //非终极符符号 int firstvt[OPER_NUM]; //firstvt集,保存算符在oper_list中的下标 int fir_n,last_n; int lastvt[OPER_NUM]; }vn_t; int prior_table[OPER_NUM][OPER_NUM]; char oper_list[OPER_NUM]; int oper_num = 0; vn_t vn_list[VN_NUM]; int vn_num = 0; char *grammar[MAX_GRA_NUM][2]; int gra_num = 0; char start_vn; char stack[STACK_SIZE]; int top = 0; void get_input(char *buf); int buf_deal(char* buf); void get_FIRVT_LASTVT(int vn_n);

C语言编译器的设计与实现.

C语言编译器的设计与实现 01计算机4班18号任春妍2号陈俊我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分: (1) 词法分析部分 (2) 语法分析处理及四元式生成部分 (3) 输出显示部分 一.词法分析器设计 由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值) #define ACC -2 #define syl_if 0 #define syl_else 1 #define syl_while 2 #define syl_begin 3 #define syl_end 4 #define a 5 #define semicolon 6 #define e 7 #define jinghao 8 #define s 9 #define L 10 #define tempsy 11 #define EA 12 #define EO 13 #define plus 14 #define times 15 #define becomes 16 #define op_and 17 #define op_or 18 #define op_not 19 #define rop 20 #define lparent 21 #define rparent 22 #define ident 23 #define intconst 24

编译原理实验二语法分析器LL(1)实现

编译原理程序设计实验报告 ——表达式语法分析器的设计班级:计算机1306班姓名:张涛学号:20133967 实验目标:用LL(1)分析法设计实现表达式语法分析器 实验内容: ⑴概要设计:通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。然后利用LL(1)分析法实现语法分析。 ⑵数据结构: int op=0; //当前判断进度 char ch; //当前字符 char nowword[10]=""; //当前单词 char operate[4]={'+','-','*','/'}; //运算符 char bound[2]={'(',')'}; //界符 struct Token { int code; char ch[10]; }; //Token定义

struct Token tokenlist[50]; //Token数组 struct Token tokentemp; //临时Token变量struct Stack //分析栈定义 { char *base; char *top; int stacksize; }; ⑶分析表及流程图

Begin PUSH(#),PUSH(E) POP(x) x ∈VT x ∈VN x=w end W=#n y NEXT(w) y n err 查LL (1)分析表空? n PUSH (i )err n y 逆序压栈 ⑷关键函数: int IsLetter(char ch) //判断ch 是否为字母 int IsDigit(char ch) //判断ch 是否为数字 int Iskey(char *string) //判断是否为关键字 int Isbound(char ch) //判断是否为界符 int Isboundnum(char ch) //给出界符所在token 值 int init(STack *s) //栈初始化 int pop(STack *s,char *ch) //弹栈操作 int push(STack *s,char ch) //压栈操作 void LL1(); //分析函数 源程序代码:(加入注释)

编译原理课程设计-词法分析器(附含源代码)

编译原理-词法分析器的设计 一.设计说明及设计要求 一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。本课程设计即为词法分析阶段。词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。如保留字(关键字或基本字)、标志符、常数、算符和界符等等。 二.设计中相关关键字说明 1.基本字:也称关键字,如C语言中的 if , else , while , do ,for,case,break, return 等。 2.标志符:用来表示各种名字,如常量名、变量名和过程名等。 3.常数:各种类型的常数,如12,6.88,和“ABC” 等。 4.运算符:如 + ,- , * , / ,%, < , > ,<= , >= 等。5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。 三、程序分析 词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源 程序进行 扫描,产生一个个单词序列,用以语法分析。词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,常将

词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则 调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一 些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。 四、模块设计 下面是程序的流程图 五、程序介绍 在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。 程序的功能:(1)能识别C语言中所有关键字(共32个)(单词种别分别为1 — 32 ,详情见程序代码相关部分,下同) (2)能识别C语言中自定义的标示符(单词种别为 33) (3)能识别C语言中的常数(单词种别为0) (4)能识别C语言中几乎所有运算符(单词种别分别为41 — 54) (5)能识别C语言中绝大多数界符(单词种别分别为 55 — 66)六、运行结果 输入文件infile.txt 运行结果(输出文件 outfile.txt)

编译原理词法分析和语法分析报告 代码(C语言版)

词法分析 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图: 扫描子程序主要部分流程图 其他

词法分析程序的C语言程序源代码: // 词法分析函数: void scan() // 数据传递: 形参fp接收指向文本文件头的文件指针; // 全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。 void scan() { char ch; int flag,j=0,i=-1; while(!feof(fp1)) { ch=fgetc(fp1); flag=judge(ch); printf("%c",ch);//显示打开的文件 if(flag==1||flag==2||flag==3) {i++;buffer[i]=ch;line[i]=row;} else if(flag==4) {i++;buffer[i]='?';line[i]=row;} else if(flag==5) {i++;buffer[i]='~';row++;} else if(flag==7) continue; else cout<<"\n请注意,第"<

词法分析器的设计与实现

目录 一.设计题目 (2) 二.设计要求 (2) 1. 词法分析器的定义 (2) 2. 设计要求 (2) 3. 本程序自行规定: (3) 三.设计作用与目的 (4) 1. 设计作用 (4) 2. 设计目的 (4) 四.运行环境及工具软件 (4) 五.系统设计 (5) 1. 系统总体设计 (5) (1)词法分析器的设计 (5) (2)总体设计框图 (6) (3)总程序流程图 (6) 2. 各子模块设计 (8) (1)字符的识别 (8) (2)关键字的识别 (8) (3)数字的识别 (8) (4)界符的识别 (10) (5)运算处理 (10) 3.相关函数分析 (11) 4. 源程序设计 (12) 六.实验调试结果 (29) 1. 调试工具 (29) 2. 调试步骤 (29) 3. 调试结果 (29) 七.设计中的问题及解决方法 (31) 八.设计心得 (32) 九.参考文献 (34)

词法分析器的设计与实现 一.设计题目 词法分析器的设计与实现 二.设计要求 1. 词法分析器的定义 词法分析顾名思义就是分词。它以程序设计语言编制的源程序作为输入,以单词序列作为输出。分词过程可以通过编制程序自动完成,我们通常称这个分词程序为词法分析器。词法分析器分析的源程序可以是现有的各类程序设计语言源程序也可以是人为给定的模型语言的源程序。本文中的源程序为后者。从词的角度来看,它涉及的内容较为简单,只包括几个较为常用的词类,词类的构成上也适当的作了一些简化。对词进行分析时,我们是按类型进行分析的。不同类型的词在后续的分析中所起的作用不同,相应的操作也各有不同,但同种类型中的词虽然单词的构成不同但从宏观上看它们的操作大体一致。模型语言中的单词可以分为“关键字”、“标识符”、“常数”、“分隔符”、“运算符”几类。一般,关键字在程序设计语言中人为给定 2. 设计要求 对给定的程序通过词法分析器能够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。另外,如果是算术表达式,则需要通过栈、运算符的优先级比较处理等从而计算出最终结果并显示。通过此次课程设计要求掌握从源程序文件中读取有效字符的方法,掌握词法分析的实现方法并上机调试编出的词法分析程序。 在处理表达式前,首先设置两个栈:一是运算符栈,用于在表达式处理过程中存放运算符。在开始时,运算符栈中先压入一个表达式结束符“#”。二是操作数栈,用于在表达式处理过程中存放操作数。然后从左到右依次读出表达式中的各个符号(运算符或操作数),每读出一个符号按以下原则进行处理:

编译原理--词法分析,语法分析,语义分析(C语言)

词法分析 #include #include #include using namespace std; #define MAXN 20000 int syn,p,sum,kk,m,n,row; double dsum,pos; char index[800],len;//记录指数形式的浮点数 char r[6][10]={"function","if","then","while","do","endfunc"}; char token[MAXN],s[MAXN]; char ch; bool is_letter(char c) { return c>='a' && c<='z' || c>='A' && c<='Z'; } bool is_digtial(char c) { return c>='0' && c<='9'; } bool is_dot(char c) { return c==',' || c==';'; } void identifier()//标示符的判断 { m=0; while(ch>='a' && ch<='z' || ch>='0' && ch<='9') { token[m++]=ch; ch=s[++p]; } token[m]='\0';

ch=s[--p]; syn=10; for(n=0;n<6;n++) if(strcmp(token,r[n])==0) { syn=n+1; break; } } void digit(bool positive)//数字的判断{ len=sum=0; ch=s[p]; while(ch>='0' && ch<='9') { sum=sum*10+ch-'0'; ch=s[++p]; } if(ch=='.') { dsum=sum; ch=s[++p]; pos=0.1; while(ch>='0' && ch<='9') { dsum=dsum+(ch-'0')*pos; pos=pos*0.1; ch=s[++p]; } if(ch=='e') { index[len++]=ch; ch=s[++p]; if(ch=='-' || ch=='+') { index[len++]=ch; ch=s[++p]; } if(!(ch>='0' && ch<='9')) { syn=-1; } else

编译原理语法分析器实验

语法分析器的设计 一、实验内容 语法分析程序用LL(1)语法分析方法。首先输入定义好的文法书写文件(所用的文法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST集合,每个非终结符号的FOLLOW集合,以及每个规则的SELECT集合,并判断任意一个非终结符号的任意两个规则的SELECT 集的交集是不是都为空,如果是,则输入文法符合LL(1)文法,可以进行分析。对于文法: G[E]: E->E+T|T T->T*F|F F->i|(E) 分析句子i+i*i是否符合文法。 二、基本思想 1、语法分析器实现 语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。这里采用自顶向下的LL(1)分析方法。 语法分析程序的流程图如图5-4所示。 语法分析程序流程图 该程序可分为如下几步: (1)读入文法 (2)判断正误 (3)若无误,判断是否为LL(1)文法 (4)若是,构造分析表; (5)由句型判别算法判断输入符号串是为该文法的句型。 三、核心思想 该分析程序有15部分组成: (1)首先定义各种需要用到的常量和变量;

(2)判断一个字符是否在指定字符串中; (3)读入一个文法; (4)将单个符号或符号串并入另一符号串; (5)求所有能直接推出&的符号; (6)求某一符号能否推出‘& ’; (7)判断读入的文法是否正确; (8)求单个符号的FIRST; (9)求各产生式右部的FIRST; (10)求各产生式左部的FOLLOW; (11)判断读入文法是否为一个LL(1)文法; (12)构造分析表M; (13)句型判别算法; (14)一个用户调用函数; (15)主函数; 下面是其中几部分程序段的算法思想: 1、求能推出空的非终结符集 Ⅰ、实例中求直接推出空的empty集的算法描述如下: void emp(char c){ 参数c为空符号 char temp[10];定义临时数组 int i; for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找 { if 产生式右部第一个符号是空符号并且右部长度为1, then将该条产生式左部符号保存在临时数组temp中 将临时数组中的元素合并到记录可推出&符号的数组empty中。 } Ⅱ、求某一符号能否推出'&' int _emp(char c) { //若能推出&,返回1;否则,返回0 int i,j,k,result=1,mark=0; char temp[20]; temp[0]=c; temp[1]='\0'; 存放到一个临时数组empt里,标识此字符已查找其是否可推出空字 如果c在可直接推出空字的empty[]中,返回1 for(i=0;;i++) { if(i==count) return(0); 找一个左部为c的产生式 j=strlen(right[i]); //j为c所在产生式右部的长度 if 右部长度为1且右部第一个字符在empty[]中. then返回1(A->B,B可推出空) if 右部长度为1但第一个字符为终结符,then 返回0(A->a,a为终结符) else

编译原理实验报告《LL(1)语法分析器构造》

《LL(1)分析器的构造》实验报告 一、实验名称 LL(1)分析器的构造 二、实验目的 设计、编制、调试一个LL(1)语法分析器,利用语法分析器对符号串的识别,加深对语法分析原理的理解。 三、实验内容和要求 设计并实现一个LL(1)语法分析器,实现对算术文法: G[E]:E->E+T|T T->T*F|F F->(E)|i 所定义的符号串进行识别,例如符号串i+i*i为文法所定义的句子,符号串ii+++*i+不是文法所定义的句子。 实验要求: 1、检测左递归,如果有则进行消除; 2、求解FIRST集和FOLLOW集; 3、构建LL(1)分析表; 4、构建LL分析程序,对于用户输入的句子,能够利用所构造的分析程序进行分析,并显示出分析过程。 四、主要仪器设备 硬件:微型计算机。 软件: Code blocks(也可以是其它集成开发环境)。

五、实验过程描述 1、程序主要框架 程序中编写了以下函数,各个函数实现的作用如下: void input_grammer(string *G);.Xn的FIRST集 string** create_table(string *P,string U,string u,int n,int t,int k,string* first);ppend(1,a) U=u=" ";mpty();n++) { U[n]=G[n][0]; }ength();j++) { if(G[i][j])==string::npos&&(G[i][j])==string::npos) if(G[i][j]!='|'&&G[i][j]!='^') ength();j++) { P[k][0]=U[i];P[k][1]=':';P[k][2]=':';P[k][3]='='; /* if(G[i][j]=='(') { j++;flag=1; for(temp=j;G[i][temp]!=')';temp++); C=G[i][temp+1]; ppend(1,U[i]);GG[m].append("::="); if('|')!=string::npos) GG[m].append("("+beta+")"); else GG[m].append(beta); while(C)!=string::npos){C++;} GG[m].append(1,C); m++; GG[m].append(1,C);GG[m].append("::="); if('|')!=string::npos) GG[m].append("("+arfa+")"); else GG[m].append(arfa); GG[m].append(1,C);GG[m].append("|^"); m++; C++; }ind('^')==string::npos) first[r].append(1,'^');ind(a)==string::npos)ppend(1,a); break;.Yk

编译原理设计c语言的词法分析器

编译原理课程设计报告 题目: 学院: 教师: 姓名: 学号: 班级: 评分: 签字:

编译原理课程设计一:设计c语言的词法分析器 一、实验目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程,加深对词法原理的理解。 二、实验要求 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 三、实验设计 3.1.单词分类及表示 3.1.1 C语言的子集分类 (1)标识符:以字母开头的字母数字串 (2)整数或浮点型。 (3)保留字:for,while,do,else,if,static,int,sizeof,break,continue (4)运算符:+,-,*,/,%,>,<,=,!=,==,<=,>=,!,&,&&,||; (5)界符:"(",")",",",":",";","{","}" 3.1.2单词二元组(单词分类号、单词自身值)

3.2 词法分析器的设计 3.2.1算法设计 3.2.1.1概要设计 从文件中逐个读取字符,只要这五大类的状态序列则继续读取,否则回退字符,在对应类别进行查找,输出单元二次组至另一文件夹。

3.2.1.2状态图设计 3.2.2输入输出设计 输入:通过文件指针从文件中一个一个读取字符 输出:输出单词二元组至文件。格式为(种别码,值) 3.2.3主要函数 void Getchar(FILE *fp ) //读入一个字符 void GetBC(FILE *fp)//读入一个非空字符 void contacat()//连接字符 int letter()//判断是否为字母 int digit()//判断是否为字母 void retract(FILE *fp,char *c)//回退 int reserve (char **k)//处理保留字 int sysmbol(identifier *id)//处理标识符,查找符号表并存放位置若没有则添加int constant(constnumber *con)//存入常数表,并返回它在常数表中的位置

语法分析C语言程序

实验内容: 可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法分析器: (1)E→E+T | E-T | T (2)T→T*F | T/F | F (3)F→P^F | P (4)P→(E) | i 实验环境: Windows XP 实验分析: (1)定义部分:定义常量、变量、数据结构。 (2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等); (3)控制部分:从键盘输入一个表达式符号串; (4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分 实验程序: #include #include using namespace std; stack symbol; stack state; char sen[50]; char sym[12][6]={//符号表 {'s','e','e','s','e','e'}, {'e','s','e','e','e','a'}, {'r','r','s','r','r','r'}, {'r','r','r','r','r','r'}, {'s','e','e','s','e','e'}, {'r','r','r','r','r','r'}, {'s','e','e','s','e','e'}, {'s','e','e','s','e','e'},

{'r','r','s','r','r','r'}, {'r','r','r','r','r','r'}, {'r','r','r','r','r','r'} }; char snum[12][6]={//数字表 {5,1,1,4,2,1}, {3,6,5,3,2,0}, {2,2,7,2,2,2}, {4,4,4,4,4,4}, {5,1,1,4,2,1}, {6,6,6,6,6,6}, {5,1,1,4,2,1}, {5,1,1,4,2,1}, {3,6,5,3,11,4}, {1,1,7,1,1,1}, {3,3,3,3,3,3}, {5,5,5,5,5,5} }; int go2[12][3]={//goto表 {1,2,3}, {0,0,0}, {0,0,0}, {0,0,0}, {8,2,3}, {0,0,0}, {0,9,3}, {0,0,10}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} }; void action(int i,char *&a,char &how,int &num,char &A,int &b)//action函数[i,a] { int j; switch(*a) { case 'i': j=0;break; case '+': j=1;break; case '*': j=2;break; case '(':

相关文档
最新文档