c语言语法分析

c语言语法分析
c语言语法分析

/*主程序*/

#include

#include

extern int TESTscan();

extern int TESTparse();

char Scanin[300],Scanout[300]; /*用于接收输入输出文件名*/

FILE *fin,*fout; /*用于指向输入输出文件的指针*/

void main(){

int es=0;

es=TESTscan();/*调词法分析*/

if (es>0) printf("词法分析有错,编译停止!");

else printf("词法分析成功!\n");

if (es==0)

{

es=TESTparse(); /*调语法分析*/

if (es==0) printf("语法分析成功!\n");

else printf("语法分析错误!\n");

}

}

#include

#include

//下面定义保留,为简化程序,使用字符指针数组保存所有保留字。

//如果想增加保留字,可继续添加,并修改保留字数目

#define keywordSum 8

char *keyword[keywordSum]={ "if","else","for","while","do","int","read","write"};

//下面定义纯单分界符,如需要可添加

char singleword[50]="+-*(){};,:";

//下面定义双分界符的首字符

char doubleword[10]="><=!";

extern char Scanin[300], Scanout[300]; //用于接收输入输出文件名,在TEST_main.c中定义extern FILE *fin,*fout; //用于指向输入输出文件的指针,在TEST_main.c中定义

int TESTscan()//词法分析函数

{

char ch,token[40]; //ch为每次读入的字符,token用于保存识别出的单词

int es=0,j,n; //es错误代码,0表示没有错误。j,n为临时变量,控制组合单词时的下标等printf("请输入源程序文件名(包括路径):");

scanf("%s",Scanin);

printf("请输入词法分析输出文件名(包括路径):");

scanf("%s",Scanout);

if ((fin=fopen(Scanin,"r"))==NULL) //判断输入文件名是否正确

{

printf("\n打开词法分析输入文件出错!\n");

return(1);//输入文件出错返回错误代码1

}

if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确

{

printf("\n创建词法分析输出文件出错!\n");

return(2); //输出文件出错返回错误代码2

}

ch=getc(fin);

while(ch!=EOF)

{

while (ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);

if (isalpha(ch)) //如果是字母,则进行标识符处理

{

token[0]=ch; j=1;

ch=getc(fin);

while(isalnum(ch)) //如果是字母数字则组合标识符;如果不是则标识符组合结束{

token[j++]=ch; //组合的标识符保存在token中

ch=getc(fin); //读下一个字符

}

token[j]='\0'; //标识符组合结束

//查保留字

n=0;

while ((n

if (n>=keywordSum) //不是保留字,输出标识符

fprintf(fout,"%s\t%s\n","ID",token); //输出标识符符号

else//是保留字,输出保留字

fprintf(fout,"%s\t%s\n",token,token); //输出保留字符号

} else if (isdigit(ch))//数字处理

{

token[0]=ch; j=1;

ch=getc(fin); //读下一个字符

while (isdigit(ch)) //如果是数字则组合整数;如果不是则整数组合结束

{

token[j++]=ch; //组合整数保存在token中

ch=getc(fin); //读下一个字符

}

token[j]='\0'; //整数组合结束

fprintf(fout,"%s\t%s\n","NUM",token); //输出整数符号

} else if (strchr(singleword,ch)>0) //单分符处理

{

token[0]=ch; token[1]='\0';

ch=getc(fin);//读下一个符号以便识别下一个单词

fprintf(fout,"%s\t%s\n",token,token); //输出单分界符符号

}else if (strchr(doubleword,ch)>0) //双分界符处理

{

token[0]=ch;

ch=getc(fin); //读下一个字符判断是否为双分界符

if (ch=='=') //如果是=,组合双分界符

{

token[1]=ch;token[2]='\0'; //组合双分界符结束

ch=getc(fin); //读下一个符号以便识别下一个单词

} else//不是=则为单分界符

token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token); //输出单或双分界符符号

} else if (ch=='/') //注释处理

{

ch=getc(fin); //读下一个字符

if (ch=='*') //如果是*,则开始处理注释

{ char ch1;

ch1=getc(fin); //读下一个字符

do

{ ch=ch1;ch1=getc(fin);} //删除注释

while ((ch!='*' || ch1!='/')&&ch1!=EOF); //直到遇到注释结束符*/或文件尾

ch=getc(fin);//读下一个符号以便识别下一个单词

} else //不是*则处理单分界符/

{

token[0]='/'; token[1]='\0';

fprintf(fout,"%s\t%s\n",token,token); //输出单分界符/

}

} else//错误处理

{

token[0]=ch;token[1]='\0';

ch=getc(fin); //读下一个符号以便识别下一个单词

es=3; //设置错误代码

fprintf(fout,"%s\t%s\n","ERROR",token); //输出错误符号

}

}

fclose(fin);//关闭输入输出文件

fclose(fout);

return(es); //返回主程序

}

#include

#include

#include

int TESTparse();

int program();

int compound_Stat();

int statement();

int expression_Stat();

int expression();

int bool_expr();

int additive_expr();

int term();

int factor();

int if_stat();

int while_stat();

int for_stat();

int write_stat();

int read_stat();

int declaration_stat();

int declaration_list();

int statement_list();

int compound_stat();

char token[20],token1[40];/*token保存单词符号,token1保存单词值*/ extern char Scanout[300]; /*保存词法分析输出文件名*/

FILE *fp; /*用于指向输入输出文件的指针*/

/*语法分析程序*/

int TESTparse()

{

int es=0;

if((fp=fopen(Scanout,"r"))==NULL)

{

printf("\n打开%s错误!\n",Scanout);

es=10;

}

if (es==0) es=program();

printf("=====语法分析结果!======\n");

switch(es)

{

case 0: printf("语法分析成功!\n");break;

case 10: printf("打开文件%s失败!\n",Scanout);break;

case 1: printf("缺少{!\n");break;

case 2: printf("缺少}!\n");break;

case 3: printf("缺少标识符!\n");break;

case 4: printf("少分号!\n");break;

case 5: printf("缺少(!\n");break;

case 6: printf("缺少)!\n");break;

case 7: printf("缺少操作数!\n");break;

}

fclose(fp);

return(es);

}

/*<程序>::={<声明序列><语句序列>}

//program::={}*/

int program()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if(strcmp(token,"{"))/*判断是否'{'*/

{

es=1;

return(es);

}

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=declaration_list();

if (es>0) return(es);

es=statement_list();

if (es>0) return(es);

if(strcmp(token,"}"))/*判断是否'}'*/

{

es=2;

return(es);

}

return(es);

}

/*<声明序列>::=<声明序列><声明语句>|<声明语句> //::=

//| //该成::={}*/

int declaration_list()

{

int es=0;

while (strcmp(token,"int")==0)

{

es=declaration_stat();

if (es>0) return(es);

}

return(es);

}

/*<声明语句> ::=int <变量>;

//::=int ID;*/

int declaration_stat()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,"ID")) return(es=3); /*不是标识符*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,";") ) return(es=4);

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

}

/*<语句序列>::=<语句序列><语句>|<语句>

//::=|

//改成::={}*/

int statement_list()

{

int es=0;

while (strcmp(token,"}"))

{

es=statement();

if (es>0) return(es);

}

return(es);

}

/*<语句>::=|||

// ||<复合语句>|<表达式语句>

//::= ||

// | |*/

int statement()

{

int es=0;

if (es==0 && strcmp(token,"if")==0) es=if_stat();/**/

if (es==0 && strcmp(token,"while")==0) es=while_stat();/**/

if (es==0 && strcmp(token,"for")==0) es=for_stat();/**/

/*可在此处添加do语句调用*/

if (es==0 && strcmp(token,"read")==0) es=read_stat();/**/

if (es==0 && strcmp(token,"write")==0) es=write_stat();/**/

if (es==0 && strcmp(token,"{")==0) es=compound_stat();/*<复合语句>*/

if (es==0 && (strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")==0)) es=expression_stat();/*<表达式语句>*/

return(es);

}

/*::= if (<表达式>) <语句> [else <语句>]

//::= if () [else < statement >]*/

int if_stat(){

int es=0; /* if */

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,"(")) return(es=5); /*少左括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,")")) return(es=6); /*少右括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=statement();

if (es>0) return(es);

if (strcmp(token,"else")==0)/*else部分处理*/

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=statement();

if (es>0) return(es);

}

return(es);

}

/*::=while(<表达式>) <语句>

//::= while () < statement >*/

int while_stat()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,"(")) return(es=5); /*少左括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,")")) return(es=6); /*少右括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=statement();

return(es);

}

/*::=for(<表达式>;<表达式>;<表达式>) <语句> //::= for(,,)*/

int for_stat()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,"(")) return(es=5); /*少左括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,";")) return(es=4); /*少分号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,";")) return(es=4); /*少分号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,")")) return(es=6); /*少右括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=statement();

return(es);

}

/*::=write <表达式>;

//::=write ;*/

int write_stat()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,";")) return(es=4); /*少分号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

}

/*::=read <变量>;

//::=read ID;*/

int read_stat()

{

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,"ID")) return(es=3); /*少标识符*/ fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

if (strcmp(token,";")) return(es=4); /*少分号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

}

/*<复合语句>::={<语句序列>}

//::={}*/

int compound_stat(){ /*复合语句函数*/

int es=0;

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=statement_list();

return(es);

}

/*<表达式语句>::=<<表达式>;|;

//::=;|;*/

int expression_stat()

{

int es=0;

if (strcmp(token,";")==0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

}

es=expression();

if (es>0) return(es);

if (es==0 && strcmp(token,";")==0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

} else

{

es=4;

return(es);/*少分号*/

}

}

/*<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>

//::=ID=|*/

int expression()

{

int es=0,fileadd;

char token2[20],token3[40];

printf("aaaaaaaaaaa%s\n",token);

if (strcmp(token,"ID")==0)

{

fileadd=ftell(fp); /*记住当前文件位置*/

fscanf(fp,"%s %s\n", &token2,&token3);

printf("%s %s\n",token2,token3);

if (es>0) return(es);

if (strcmp(token2,"=")==0) /*'='*/

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=bool_expr();

} else

{

fseek(fp,fileadd,0); /*若非'='则文件指针回到'='前的标识符*/

printf("%s %s\n",token,token1);

es=bool_expr();

if (es>0) return(es);

}

}else es=bool_expr();

return(es);

}

/*<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式> //::=

// |< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >*/

int bool_expr()

{

int es=0;

es=additive_expr();

if(es>0) return(es);

if (strcmp(token,">")==0 || strcmp(token,">=")==0 ||strcmp(token,"<")==0||strcmp(token,"<=")==0

||strcmp(token,"==")==0||strcmp(token,"!=")==0) {

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=additive_expr();

if(es>0) return(es);

}

return(es);

}

/*<算术表达式>::=<项>{(+|-)<项>}

//::={(+|-)< term >} */

int additive_expr()

{

int es=0;

es=term();

if(es>0) return(es);

while (strcmp(token,"+")==0 || strcmp(token,"-")==0) {

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=term();

if(es>0) return(es);

}

return(es);

}

/*<项>::=<因子>{(*|/)<因子>}

//< term >::={(*| /)< factor >} */

int term()

{

int es=0;

es=factor();

if(es>0) return(es);

while (strcmp(token,"*")==0 || strcmp(token,"/")==0) {

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=factor();

if(es>0) return(es);

}

return(es);

}

/*<因子>::=(<算术表达式>)|<标识符>|<无符号整数>

//< factor >::=()| ID|NUM*/

int factor()

{

int es=0;

if (strcmp(token,"(")==0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

es=expression();

if (es>0) return(es);

if (strcmp(token,")")) return(es=6); /*少右括号*/

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

} else

{

if (strcmp(token,"ID")==0||strcmp(token,"NUM")==0)

{

fscanf(fp,"%s %s\n",&token,&token1);

printf("%s %s\n",token,token1);

return(es);

} else

{

es=7;/*缺少操作数*/

return(es);

}

}

return(es);

}

编译原理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");

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*/ } } /******************************************* 得到一个不是非终结符的符号 ********************************************/

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

编译原理词法分析和语法分析报告 代码(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请注意,第"<

编译原理--词法分析,语法分析,语义分析(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

编译原理设计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语言版)

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

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

编译原理课程设计报告 设计题目编译代码生成器设计 学生姓名 班级 学号 指导老师 成绩

一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块 主程序 词法分析程序语法分析 程序 中间代码 生成程序

2. 表2.1 各种单词符号对应的种别码 单词符号种别码单词符号种别码bgin 1 :17 If 2 := 18 Then 3 < 20 wile 4 <> 21 do 5 <= 22 end 6 > 23 lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26 —14 ( 27 * 15 ) 28 / 16 # 0 详细设计: 4.1界面导入设计 (1)一共三个选项: ①choice 1--------cifafenxi ②choice 2--------yufafenxi ③choice 3--------zhongjiandaima (2)界面演示 图一

语法分析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 '(':

编译原理课程设计报告C语言词法与语法分析器的实现

编译原理课程设计报告 课题名称:编译原理课程设计 C-语言词法与语法分析器的实现

C-词法与语法分析器的实现 1.课程设计目标 (1)题目实用性 C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。(2)C-语言的词法说明 ①语言的关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 ②专用符号: + - * / < <= > >= == != = ; , ( ) [ ] { } /* */ ③其他标记是ID和NUM,通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9 注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。 小写和大写字母是有区别的。 ④空格由空白、换行符和制表符组成。空格通常被忽略。 ⑤注释用通常的c语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置(即注释不能放在标记)上,且可以超过一行。注释不能嵌套。

(3)程序设计目标 能够对一个程序正确的进行词法及语法分析。 2.分析与设计 (1)设计思想 a.词法分析 词法分析的实现主要利用有穷自动机理论。有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。通过有穷自动机理论能够容易的设计出词法分析器。b.语法分析 语法分析采用递归下降分析。递归下降法是语法分析中最易懂的一种方法。它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。 (2)程序流程图 程序主流程图: 词法分析: 语法分析:

语法分析代码2(LR分析器 C语言实现)

#include"status_stack.h" #include"symbol_instr_stack.h" #include"lr.h" //打印LR分析器的工作过程 void print(status *status_p,symbol_instr *symbol_p,symbol_instr *instr_p) { int i; out_stack(status_p); for(i=0;i<20-status_p->top;i++) printf(" "); out_stack1(symbol_p); for(i=0;i<20;i++) printf(" "); out_stack2(instr_p); printf("\n"); } //状态转换函数 int goto_char(status *status_p,symbol_instr *instr_p) { char x; int y,z; x = get_top(instr_p); y = get_top(status_p); z = get_index_char(x); return table[y][z]; } //移进--规约函数 void action(status *status_p,symbol_instr *symbol_p,symbol_instr *instr_p) { int i,j,x; char a; i = goto_char(status_p,instr_p); //规约出错 if(i == -1) printf("\n===============规约出错!================\n"); //规约成功 if(i == 12) printf("\n===============规约成功!================\n"); //移进动作 if(i>=0 && i<=11) { push(status_p,i); a = pop(instr_p); push(symbol_p,a);

C语言词法分析器和C语言语法分析器编译原理课程设计报告书

《编译原理课程设计》课程报告题目 C语言词法分析器和C-语言语法分析器 学生 学生学号 指导教师 提交报告时间 2019 年 6 月 8 日

C语言词法分析器 1 实验目的及意义 1.熟悉C语言词法 2.掌握构造DFA的过程 3.掌握利用DFA实现C语言的词法分析器 4.理解编译器词法分析的工作原理 2 词法特点及正则表达式 2.1词法特点 2.1.1 保留字 AUTO, BREAK , CASE , CHAR , CONST , CONTINUE , DEFAULT , DO , DOUBLE , ELSE, ENUM , EXTERN , FLOAT , FOR , GOTO, IF , INT , LONG , REGISTER , RETURN, SHORT , SIGNED , SIZEOF , STATIC , STRUCT , SWITCH , TYPEDEF , UNION , UNSIGNED , VOID, VOLATILE , WHILE, 2.1.2 符号 + - * / ++ -- += -= *= < <= > >= == != = ; , ( ) [ ] { } /* */ : 2.2 正则表达式 whitespace = (newline|blank|tab|comment)+ digit=0|..|9 nat=digit+ signedNat=(+|-)?nat NUM=signedNat(“.”nat)? letter = a|..|z|A|..|Z ID = letter(letter|digit|“_”)+ CHAR = 'other+' STRING = “other+”

实验三 语法分析的C语言实现

实验三语法分析的C语言实现 一、实验目的 加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法分析。 二、实验要求 1、在实验一(用C语言实现词法分析的程序)的基础上,实现编写语法分析程序,语法 分析程序的实现可以采用任何一种编程工具。 2、对语法规则有明确的定义; 3、编写的分析程序能够对实验一的结果进行正确的语法分析; 4、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利 完成语法分析过程; 三、实验指导1(实现算术表达式的运算) (一)准备 1.阅读课本有关章节,参考P63的表6.3优先关系表。 2.初步编制程序。 3.准备一组测试数据。 (二)程序要求 1.程序输入/输出示例: 输入如下一段C语言源程序: 3+2*(5.5-5) 输出:输出运算的结果4.0。 2. 建议:实验一的词法分析结果保存到文件input.c,实验二直接从input.c读取一个token,将用到的文法规则输出并保存到文件output.c。(注:NUM由词法分析器返回) 3.可选功能:可以根据自身的情况完善语法分析程序的错误处理功能,如对遇到的语法错误给出准确的位置和错误类型提示。 三、实验指导2(用递归下降分析器实现语法分析) (一)准备 1.阅读课本有关章节,特别是P49的代码,明确语言的语法。 2.初步编制程序。 3.准备一组测试数据。 (二)程序要求 1.程序输入/输出示例: 输入如下一段C语言源程序(实现赋值语句或者if语句或者while语句,或者都实现):main() { a = 10*(b+2); if (a>b) a=b else a=c; while (a!=0) a=3+21*a; }

c语言实现语法分析器

实验报告 姓名:张静学号:13031121 【实验名称】一种绘图语言的词法分析器 【实验目的】采用c语言完成词法分析器,练习使用。 【实验内容】 一、问题描述 设计一种简单的函数绘图语言的词法分析器,该绘图语言可以提供一条循环绘图语句,图形变换语句,注释语句,他的词法分析器部分是读取源程序——字符序列,并根据构词规则将其转换为记号流。它可以完成三个任务:(1)滤掉源程序中的注释和无用的成分(如空格,TAB等);(2)输出记号,供语法分析器使用;(3)识别非法输入,并将非法输入作为出错记号提供给语法分析器,以便进行出错处理。 二、问题分析 词法分析器的构造步骤:正规式——NFA——DFA——最小DFA ——编写程序——测试。 1、记号的设计 记号一般有两部分组成:极好的类别,记号的属性。根据 函数绘图语言的特点,可以将记号设计为如下的数据结构: Struct Token

{ Token_Type type;----------类别 char* lexeme;--------------属性,原是输入的字符串double value;----------属性,若记号是常数则是常数的值 double (*FuncPtr)(double);--属性,若记号是函数则是函数指针 }; 函数绘图语言的记号类别划分如下: Enum Token_Type { ORGIN, SCALE, ROT, IS, ------------保留字 TO, STEP, DRAW, FOR, FROM,---------保留字 T,--------------------------------参数 SEMICO, L_BRACKET, R_BRACKET, COMMA--分隔符 PLUS, MINUS, MUL, DIV, POWER,------运算符 FUNC,--------------------------函数 CONST_ID,-------------------常数 NONTOKEN,-----------------空记号 ERRTOKEN-------------------出错记号 }; 2、模式的正规式表示 函数绘图语言的此法可用下是正规式集合表示,其中的letter 和digit是辅助定义 描述词法的正规式

实验5 LL(1)语法分析程序的设计与实现(C语言)教学文稿

实验五LL(1)文法识别程序设计 一、实验目的 通过LL(1)文法识别程序的设计理解自顶向下的语法分析思想。 二、实验重难点 FIRST集合、FOLLOW集合、SELECT集合元素的求解,预测分析表的构造。 三、实验内容与要求 实验内容: 1.阅读并理解实验案例中LL(1)文法判别的程序实现; 2.参考实验案例,完成简单的LL(1)文法判别程序设计。 四、实验学时 4课时 五、实验设备与环境 C语言编译环境 六、实验案例 1.实验要求 参考教材93页预测分析方法,94页图5.11 预测分析程序框图,编写表达式文法的识别程序。要求对输入的LL(1)文法字符串,程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 表达式文法为: E→E+T|T T→T*F|F F→i|(E) 2.参考代码

为了更好的理解代码,建议将图5.11做如下标注:

/* 程序名称:LL(1)语法分析程序*/ /* E->E+T|T */ /* T->T*F|F */ /* F->(E)|i */ /*目的: 对输入LL(1)文法字符串,本程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 /********************************************/ /* 程序相关说明*/ /* A=E' B=T' */ /* 预测分析表中列号、行号*/ /* 0=E 1=E' 2=T 3=T' 4=F */ /* 0=i 1=+ 2=* 3=( 4=) 5=# */ /************************************/ #include"iostream" #include "stdio.h" #include "malloc.h" #include "conio.h" /*定义链表这种数据类型参见: https://www.360docs.net/doc/df1182714.html,/link?url=_owQzf8PRZOt9H-5oXIReh4X0ClHo6zXtRdWrdSO5YBLpKl NvkCk0qWqvFFxjgO0KzueVwEQcv9aZtVKEEH8XWSQCeVTjXvy9lxLQ_mZXeS###*/ struct Lchar{ char char_ch; struct Lchar *next; }Lchar,*p,*h,*temp,*top,*base; /*p指向终结符线性链表的头结点,h指向动态建成的终结符线性链表节点,top和base分 别指向非终结符堆栈的顶和底*/

C语言语法分析器

郑州轻工业学院 编译原理课程设计总结报告 设计题目:词法分析器(语法分析器) 学生姓名: 系别: 专业: 班级: 学号: 指导教师: 20013年6 月2日

目录 一、设计题目 (3) 二、运行环境(软、硬件环境) (3) 三、算法设计的思想 (3) 四、算法流程图 (5) 五、算法设计分析 (5) 六、源代码 (6) 七、运行结果 (11) 八、收获及体会 (12)

(一)设计题目 词法分析器 (二)运行环境 Visual C++.6.0 (三)算法设计的思想 各种单词符号对应的种别码: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 1.主程序示意图: 主程序示意图如下;其中初值包括如下两个方面:

(1)关键字表的初值。 关键字作为特殊标示符处理,把它们预先安排到一张表格中 (称为关键字表),当扫描程序识别出标识符时,查关键字表。 如果能查到匹配的单词,则该单词为关键字,否则为一般的标 识符。关键字表为一个字符串数组,其描述如下: Char*rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”}; (2)程序需要用到的主要变量为syn,token和sum。 2.扫描子程序的算法思想 首先设置3个变量:(1)token用来存放构成单词符号的字符串;(2)sum 用来存放整型单词(3)syn用来存放单词符号的种别码。

(五)算法设计分析 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 其中初值包括如下两个方面:(一)关键字表的初值。关键字作为特殊标示符处理,把它们预先安排到一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如果能查到匹配的单词,则该单词为关键字,否则为一般的标识符。关键字表为一个字符串数组,其描述如下:Char*rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”}; (2)程序需要用到的主要变量为syn,token和sum。 2.扫描子程序的算法思想

编译原理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. 初始化函数void load ( ) 3. 保留字及标识符判断函数void char_search(char *word) 4. 整数类型判断函数void inta_search(char *word)

5. 浮点类型判断函数void intb_search(char *word) 6. 字符串常量判断函数void cc_search(char *word) 7. 字符常量判断函数void c_search(char *word) 同4、5函数图 8.主扫描函数void scan ( )

五、关键代码 #include #include #include char *key0[]={" ","auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","i f","int","long","register","return","short","signed","sizeof","static","struct","switch","typedef","_Complex","_Imaginary ","union","unsigned","void","volatile","while"}; /*保留字表*/ 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++)

C语言词法分析器构造实验报告(1)1

C 语言词法分析器构造实验报告 02计算机(2) 2002374203 冯绍欣 一、题目要求: 完成一个C 语言的词法分析器的构造。此词法分析器能识别附值语句、循环语句、条件语句、并能处理注释。 二、设计方案: 这个词法分析器分析的主要关键字有:main, int, float, char, if, else, for, while, do, switch, case, break; default 。选择要分析的c 文件,首先对其去掉注释和与空格处理,再根据字符的不同类型分析。 1、全局数据结构: 字符数组 set[ ]:存放从文件中读到的所有字符; str[ ]:存放经过注释处理和预空格处理的字符; strtoken[ ]:存放当前分析的字符; 结构体 KEYTABLE :存放关键字及其标号; 全局字符变量 ch :当前读入字符; 全局整型变量 sr, to :数组str, strtoken 的指针。 2、以层次图形式描述模块的组成及调用关系 3、主要函数的设计要求(功能、参数、返回值): openfile :打开文件; GetChar :将下一个输入字符读到ch 中,搜索指示器前移一字符位置; GetBC :检查ch 中的字符是否为空白。若是,则调用GetChar 直至ch 中进入一个非空白字符; Main ( ) Openfile ( ) Analysis ( ) Reflesh() Process() Set32() GetChar() GetBC() Concat() Reserve() IsLetter() IsDigit() Retract() GetChar()

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*/ } [

相关文档
最新文档