编译原理课程设计词法分析(有代码)

合集下载

编译原理课程设计-词法分析器

编译原理课程设计-词法分析器

计算机与信息学院编译原理课程设计实验报告专业班级计算机科学与技术专业08-4班学生姓名及学号胡义涛20082645课程教学班号0001任课教师王仲宾实验指导教师王仲宾实验地点逸夫楼5072010~2011 第三学年第一学期一、实验目的和要求:设计并实现一个C语言(或C++语言)的词法分析程序,加深对词法分析原理的理解。

二、试验设计和算法分析:实验原理:程序流程:置初值→调用扫描子程序→输出串结束→输出单词二元组→是→否→结束词法分析主程序示意图待分析的简单语言的词法(1) 关键字:begin if then while do end所有关键字都是小写。

(2)运算符和界符::= + - * / < > <= <> >= ; ( ) #(3)空格由空白、制表符和换行符组成。

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

三、源代码:#include "stdio.h"#include "string.h"#include "conio.h"#include "ctype.h"char prog[80]={'\0'},token[8]; /*存放构成单词符号的字符串*/char ch;int syn, /*存放单词字符的种别码*/n,sum, /*存放整数型单词*/m,p; /*p是缓冲区prog的指针,m是token的指针*/char*rwtab[6]={"begin","if","then","while","do","end" };void scaner(){m=0;sum=0;for(n=0;n<8;n++){token[n]='\0';}ch=prog[p++];while(ch==' '){ch=prog[p++];}if(isalpha(ch)) //ch为字母字符{while(isalpha(ch)||isdigit(ch))//ch 为字母字符或者数字字符{token[m++]=ch;ch=prog[p++];}token[m++]='\0';ch=prog[p--];syn=10;for(n=0;n<6;n++){ if(strcmp(token,rwtab[n])==0) //字符串的比较{syn=n+1;break;}}}elseif(isdigit(ch)) //ch是数字字符{while(isdigit(ch)) //ch是数字字符{sum=sum*10+ch-'0';ch=prog[p++];}ch=prog[p--];syn=11;}elseswitch(ch) //匹配表示符{case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=20;ch=prog[p--];}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='=')syn=24;token[m++]=ch;}else{syn=23;ch=prog[p--];}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;ch=prog[p--];break;case'10':syn=12;token[0]='n';break;case'11':syn=12;token[0]='n';break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case'=':syn=25;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0 ;token[0]=ch;break;default:syn=-1;}}main(){printf("\n\n对应信息:\n""1.1-6为关键字\n""2.10-11为字符或常量\n""3.12-28为表示符\n");p=0;printf("\nplease input string:\n");do {ch=getchar();prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11: printf("(%d,%d)\n",syn,sum);break;case -1: printf("\n ERROR;\n");break;default: printf("(%d,%s)\n",syn,token); }}while(syn!=0);getch();}四、实验结果及总结:输出:总结:通过该实验,主要有以下几方面收获:一、对实验原理有更深的理解。

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

编译原理词法分析和语法分析报告 代码(C语言版)
s_find=MarkPush(s_find,str[0],r_find->relationship);
admit=0;
for(in=0;in<cal-1;in++){str[in]=str[in+1];}
str[in]='\0';
cal--;
r_find=r_find->next;
}//:入栈~
if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='r'){//:规约
词法分析
三、词法分析程序的算法思想:
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
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);
struct Sign *next;

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;/*********************下面是一些重要数据结构的声明***************************/struct token//词法token结构体{int code;//编码int num;//递增编号token *next;};token *token_head,*token_tail;//token队列struct str//词法string结构体{int num;//编号string word;//字符串内容str *next;};str *string_head,*string_tail;//string队列struct ivan//语法产生式结构体{char left;//产生式的左部string right;//产生式的右部int len;//产生式右部的长度};ivan css[20];//语法20个产生式struct pank//语法action表结构体{char sr;//移进或归约int state;//转到的状态编号};pank action[46][18];//action表int go_to[46][11];//语法go_to表struct ike//语法分析栈结构体,双链{ike *pre;int num;//状态int word;//符号编码ike *next;};ike *stack_head,*stack_tail;//分析栈首尾指针struct L//语义四元式的数据结构{int k;string op;//操作符string op1;//操作数string op2;//操作数string result;//结果L *next;//语义四元式向后指针L *Ltrue;//回填true链向前指针L *Lfalse;//回填false链向前指针};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//四元式链,true链,false链struct symb//语义输入时符号表{string word;//变量名称int addr;//变量地址symb *next;};symb *symb_head,*symb_tail;//语义符号链表/*********************下面是与词法分析相关的一些函数的声明***************************/void scan();//按字符读取源文件void cifa_main();//词法分析主程序int judge(char ch);//判断输入字符的类型void out1(char ch);//写入token.txtvoid out3(char ch,string word);//写入string.txtvoid input1(token *temp);//插入结点到队列tokenvoid input3(str *temp);//插入结点到队列stringvoid output();//输出三个队列的内容void outfile();//输出三个队列的内容到相应文件中/*********************下面是与语法分析相关的一些函数的声明***************************/void yufa_main();//语法分析主程序void yufa_initialize();//初始化语法分析数据结构int yufa_SLR1(int a);//语法分析主体部分int ID1(int a);//给输入字符编号,转化成action表列编号string ID10(int i);//给输入字符反编号int ID2(char ch);//给非终结状态编号,转化成go_to表列编号int ID20(char ch);//给非终结状态编号char ID21(int j);//给非终结状态反编号void add(ike *temp);//给ike分析栈链表增加一个结点void del();//给ike分析栈链表删除一个结点/*********************下面是与语义分析相关的一些函数的声明***************************/void yuyi_main(int m);//语义分析主程序void add_L_four(L *temp);//向四元式链中加一个结点void add_L_true(L *temp);//向true链中加一个结点void add_L_false(L *temp);//向false链中加一个结点void add_symb(symb *temp);//向语义符号表链中加一个结点void output_yuyi();//输出中间代码四元式和最后符号表string newop(int m);//把数字变成字符串string id_numtoname(int num);//把编号转换成相应的变量名int lookup(string m);//变量声明检查/*********************下面是一些全局变量的声明***************************/FILE *fp;//文件指针int wordcount;//标志符计数int err;//标志词法分析结果正确或错误int nl;//读取行数int yuyi_linshi;//语义临时变量string E_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;//用于记录一些特殊的字符位置信息/****************************主程序开始**************************/int main(){cout<<"************************"<<endl;cout<<"* 说明:*"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cifa_main();//词法yufa_main();//语法output_yuyi();//语义cout<<endl;system("pause");return(0);}/****************************以上是主程序,以下是词法**************************/void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//初始化三个队列的首尾指针L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//初始化字符计数器err=0;//初始化词法分析错误标志nl=1;//初始化读取行数scan();if(err==0){char m;output();cout<<"词法分析正确完成!"<<endl<<endl<<"如果将结果保存到文件中请输入y ,否则请输入其它字母:";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"结果成功保存在token.txt和sting.txt两个文件中,请打开查看"<<endl;cout<<endl;}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<"请输入源文件路径及名称:";cin>>document;cout<<endl;cout<<"************************"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"************************"<<endl;if((fp=fopen(document,"rt"))==NULL){err=1;cout<<"无法找到该文件!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6)continue;else{cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch)int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')') flag=1;//界符else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//字母else if(ch==' ')flag=4;//空格else if(feof(fp))flag=5;//结束else if(ch=='\n'){flag=6;//换行nl++;}elseflag=0;//非法字符return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;//界符编码default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word){token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int") {if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//关键字编码input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6)return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//形成字符串else{err=1;cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl; return;}}void input1(token *temp){if(token_head->next == NULL){token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp;token_tail->next=temp;}}void input3(str *temp){if(string_head->next == NULL){string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp;string_tail->next=temp;}}void output(){cout<<"token表内容如下:"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<"符号表内容如下:"<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//写文件ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl;temp3=temp3->next;}}/****************************以上是词法,以下是语法**************************/void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"************************"<<endl;yufa_initialize();//初始化语法分析数据结构token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<"语法分析过程如下:"<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//语法分析if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//最后输入$来完成语法分析}}void yufa_initialize(){stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail;stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head;stack_tail->next=NULL;//初始化栈分析链表css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R";css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int";css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B";css[12].left='B';css[12].right="id>id";css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M";css[15].left='S';css[15].right="while B do M";css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len);}css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//初始化产生式for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//初始化action表for(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//初始化go_to表/****************************以下是给action表和go_to表赋初值************************/action[0][0].sr='s';action[0][0].state=2; action[1][17].sr='@';//结束action[2][1].sr='s';action[2][1].state=3; action[3][2].sr='s';action[3][2].state=4; action[4][0].sr='s';action[4][0].state=5; action[5][4].sr='s';action[5][4].state=6; action[6][11].sr='s';action[6][11].state=7; action[7][3].sr='r';action[7][3].state=4; action[8][3].sr='r';action[8][3].state=3; action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18; action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31; action[24][12].sr='s';action[24][12].state=34; action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29;action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10; action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8; action[37][10].sr='r';action[37][10].state=8; action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45; action[42][6].sr='s';action[42][6].state=43; action[43][0].sr='s';action[43][0].state=36; action[43][1].sr='s';action[43][1].state=41; action[44][2].sr='r';action[44][2].state=5; action[44][3].sr='r';action[44][3].state=5; action[44][5].sr='s';action[44][5].state=39; action[44][6].sr='r';action[44][6].state=5;action[45][2].sr='r';action[45][2].state=9;action[45][3].sr='r';action[45][3].state=9;action[45][5].sr='r';action[45][5].state=9;action[45][6].sr='r';action[45][6].state=9;action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[10][2]=11;go_to[13][7]=22;go_to[13][8]=2 1;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;go_to[19][8]=20;go_to[23][6]=24;go_to[2 5][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;go_to[41][4]=38;go_to[41][5]=37;go_to[4 3][4]=44;go_to[43][5]=37;/****************************action表和go_to表赋初值完毕************************/}int ID1(int i)//按action表,给输入字符编号{int j;j=-1;if(i==25) {j=0;id_num++;}//设置变量名称标志if(i==1) {j=8,id_left=id_num;}//设置产生试左边变量名称标志if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//设置if语句中then位置标志if(i==35) {j=15;id_while=L_four_tail->k+1;}//设置while语句中while位置标志if(i==36) {j=16;id_do=L_four_tail->k+1;}//设置while语句中do位置标志if(i==37) j=11;return(j);}string ID10(int i)//反编号输入字符{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while";if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//按go_to表给非终结符编号{int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10;return(j);}int ID20(char ch)//给非终结符编号{int j;j=-1;if(ch=='P') j=100;if(ch=='D') j=101;if(ch=='R') j=102;if(ch=='E') j=103;if(ch=='T') j=104;if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//反编号非终结符{char ch;if(j==100 || j==0) ch='P';if(j==101 || j==1) ch='D';if(j==102 || j==2) ch='R';if(j==103 || j==3) ch='E';if(j==104 || j==4) ch='T';if(j==105 || j==5) ch='F';if(j==106 || j==6) ch='B';if(j==107 || j==7) ch='M';if(j==108 || j==8) ch='S';if(j==109 || j==9) ch='L';if(j==1010 || j==10) ch='N'; return(ch);}void add(ike *temp)//加一个结点{if(stack_head->next==stack_tail) {temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre; temp->next=stack_tail;stack_tail->pre->next=temp; stack_tail->pre=temp;}}void del()//删除一个结点{stack_tail->pre->pre->next=stack_tail;stack_tail->pre=stack_tail->pre->pre;}int yufa_SLR1(int w){/*cout<<"当前输入符号:"<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag错误标志,0正常移进,1错误,2归约,3结束char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//动作state_temp=action[stack_tail->pre->num][w].state;//状态变化if(sr_temp=='#')//错误动作{flag=1;err=3;cout<<"语法分析出错!"<<endl;}else if(sr_temp=='s')//移进动作{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<"动作(移进):"*/<<sr_temp<<state_temp<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//归约动作{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//查go_to表add(temp);cout/*<<"动作(归约):"*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//在产生树的同时进行语义分析}else if(sr_temp=='@')//结束动作{cout<<"END"/*<<"动作(归约):"<<sr_temp<<state_temp*/<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"语法分析正确完成!"<<endl;}else//其他意外情况{flag=1;err=3;cout<<"语法分析出错!"<<endl;}return(flag);}/****************************以上是语法,以下是语义**************************/void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//变量声明时加入符号表链{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num);Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//归约E→E+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//申请临时变量E_name="t"+newop(yuyi_linshi); temp->result=E_name;add_L_four(temp);//加一个四元式结点}if(m==6)//归约E→T{E_name=T_name;}if(m==7)//归约T→T*F{temp->op="*";temp->op1=T_name;temp->op2=F_name;yuyi_linshi++;//申请临时变量T_name="t"+newop(yuyi_linshi); temp->result=T_name;add_L_four(temp);//加一个四元式结点}if(m==8)//归约T→F{T_name=F_name;}if(m==9)//归约F→(E){F_name=E_name;}if(m==10)//归约F→id{id_name=id_numtoname(id_num);F_name=id_name;k=lookup(id_name);//检查变量是否声明if(k==0){err=2;errword=id_name;return;}}if(m==12)//归约B→id>id{temp->op="J>";id1_num=id_num-1;id1_name=id_numtoname(id1_num);k=lookup(id1_name);//检查变量是否声明if(k==0){err=2;errword=id1_name;return;}id2_num=id_num;id2_name=id_numtoname(id2_num);k=lookup(id2_name);//检查变量是否声明if(k==0){err=2;errword=id2_name;return;}temp->result="-1";temp->op1=id1_name;temp->op2=id2_name;add_L_four(temp);//加一个四元式结点add_L_true(temp);//加一个true链结点L *temp2;temp2=new L;temp2->op="J";temp2->op1=" ";temp2->op2=" ";temp2->result="-1";add_L_four(temp2);//加一个四元式结点add_L_false(temp2);//加一个false链结点}if(m==13)//归约M→id=E{temp->op="=";temp->op1=E_name;temp->op2=" ";id_name=id_numtoname(id_left);temp->result=id_name;add_L_four(temp);//加一个四元式结点yuyi_linshi=-1;//临时变量开始重新计数}if(m==14)//归约S→if B then M{int a;a=id_then;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+1;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}if(m==15)//归约S→while B do M{int a;a=id_do;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+2;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L *temp1;temp1=new L;temp1->op="J";temp1->op1=" ";temp1->op2=" ";temp1->next=NULL;temp1->result="L"+newop(id_while);add_L_four(temp1);//加一个四元式结点L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}}string newop(int m)//数字变成字符串{int shang,yushu;string chuan,chuan1;shang=m;chuan="";while(1){yushu=shang%10;chuan=chuan+char(48+yushu);shang=shang/10;if(shang==0)break;}int i;char *ch;ch=&chuan[0];chuan1="";for(i=strlen(ch)-1;i>=0;i--)chuan1=chuan1+chuan[i];return(chuan1);}void add_L_four(L *temp)//加一个四元式结点{temp->k=L_four_tail->k+1;if(L_four_head->next == NULL){L_four_head->next=temp;L_four_tail->next=temp;}else{L_four_tail->next->next=temp;L_four_tail->next=temp;}L_four_tail->k=L_four_tail->next->k;}void add_L_true(L *temp)//加一个true链结点{temp->Ltrue=L_true_head->Ltrue;L_true_head->Ltrue=temp;}void add_L_false(L *temp)//加一个false链结点{temp->Lfalse=L_false_head->Lfalse;L_false_head->Lfalse=temp;}void add_symb(symb *temp)//加一个语义符号表链结点{if(symb_head->next == NULL){temp->addr=0;symb_head->next=temp;symb_tail->next=temp;}else{temp->addr=symb_tail->next->addr+4;symb_tail->next->next=temp;symb_tail->next=temp;}}void output_yuyi(){if(err==0)//语义分析正确时的输出{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cout<<"中间代码如下:"<<endl;L *temp;temp=L_four_head->next;while(temp!=NULL){。

【编译原理】词法分析(CC++源代码+实验报告)

【编译原理】词法分析(CC++源代码+实验报告)

【编译原理】词法分析(CC++源代码+实验报告)⽂章⽬录1 实验⽬的和内容1.1实验⽬的(1)根据 PL/0 语⾔的⽂法规范,编写PL/0语⾔的词法分析程序;或者调研词法分析程序的⾃动⽣成⼯具LEX或FLEX,设计并实现⼀个能够输出单词序列的词法分析器。

(2)通过设计调试词法分析程序,实现从源程序中分离出各种类型的单词;加深对课堂教学的理解;提⾼词法分析⽅法的实践能⼒。

(3)掌握从源程序⽂件中读取有效字符的⽅法和产⽣源程序的内部表⽰⽂件的⽅法。

(4)掌握词法分析的实现⽅法。

(5)上机调试编出的词法分析程序。

1.2实验内容根据PL/0语⾔的⽂法规范,编写PL/0语⾔的词法分析程序。

要求:(1)把词法分析器设计成⼀个独⽴⼀遍的过程。

(2)词法分析器的输出形式采⽤⼆元式序列,即:(单词种类, 单词的值)2 设计思想2.1单词种类及其正规式(1)基本字单词的值单词类型正规式rbegin beginsym begincall callsym callconst constsym constdo dosym doend endsym endif ifsym ifodd oddsym oddprocedure proceduresym procedureread readsym readthen thensym thenvar varsym varwhile whilesym whilewrite writesym write(2)标识符单词的值单词类型正规式r标识符ident(字母)(字母|数字)*(3)常数单词的值单词类型正规式r常数number(数字)(数字)*(4)运算符单词的值单词类型正规式r+plus+-minus-*times*/slash/=eql=<>neq<><lss<<=leq<=>gtr>>=geq>=:=becomes:=(5)界符单词的值单词类型正规式r(lparen()rparen),comma,;semicolon;.period.2.2 根据正规式构造NFA下⾯我们根据上述的正规式来构造该⽂法的NFA,如下图所⽰,其中状态0为初态,凡带双圈的状态均为终态,状态24是识别不出单词符号的出错情形,其他状态的识别情况如下图中右边的注释所⽰。

编译原理课程设计词法分析

编译原理课程设计词法分析

编译原理课程设计词法分析程序姓名:*******班级:********************学号:************日期:2011-12-30词法分析程序设计课程设计目的:运用所学习的知识和语言,设计编制和调试一个具体的词法分析程序,通过运行程序从而加深对词法分析的理解。

课程设计要求:通过对PL/0词法分析程序(GETSYS)的分析,编制一个具有以下功能的词法分析程序:a.输入待进行词法分析的源程序,输出为单词串,即由(单词,类别)所组成的二元组序列;b.有一定的错误检查能力,例如能发现2a这类不能作为单词的字符串。

课程设计思路:词法分析所能分辨的符号有,常数,字符,关键字,界符,运算符等类型,设计的程序要求可以分辨各种不同的类型,可以运用C语言文件操作的功能,导入一个已经存在的文本文件,对文本文件的内容进行此法分析,并且把分析结果导入到另外一个文件当中。

主要变量说明:运用C语言的宏定义功能,1~11这十二个数字分别用来表示不同的关键字,12代表标示符类型ID,13代表常数类型INT,14代表界符类型JF,15代表运算符类型YSF。

定义一个长度为30的数组,用来存放标示符和常量。

设置指向固定文件的指针write和read,用来进行对文件的操作。

算法描述:A.设置一个字符串匹配函数looksame,对于以字母开头的字符串,对其进行与关键字的匹配,如果对于匹配关键字的字符串,则将字符串识别为关键字。

B.设置一个字符类型和字符串输出函数out,把从文件中读出的字符串,以及它预定义的类型输出,同时将词法分析的一段结果输入到指定文件中,同时输出到命令窗口。

C.设置一个报错函数error,对于文件中未能够识别的字符进行报错处理,输入报错信息“书写格式错误,未被识别”。

D.设置功能函数function,进行具体的词法分析功能,不断对文件中的字符进行读出,按照字符串类型进判断分类,调用字符串匹配函数用来识别关键字,调用out函数,用来识别普通的常量以及标示符,同时对于界符和运算符进行识别,同时输出到指定的文件中。

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

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

char ch='\0';
/*从字符缓冲区读取当前字符*/
int count=0;
/*词法分析结果缓冲区计数器*/
static char spelling[10]={""}; /*存放识别的字*/
static char line[81]={""}; /*一行字符缓冲区,最多 80 个字符*/
char *pline;
scaner(); main() {p=0;
printf("\n please input a string(end with '#'):/n"); do{
scanf("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; do{ scaner(); switch(syn)
EO
19
B or(即布尔表达式中的 B∨ )
Plus
34
“+”
Times
36
Becomes
38
Op_and
39
Op_or
40
Op_not
41
Rop
42
Lparent
48
Rparent
49
Ident
56
Intconst
57
#define sy_if
0
#define sy_then 1
#define sy_else 2
case '*': syn=15; token[m++]=ch; break;
case '/': syn=16; token[m++]=ch; break;

编译原理实验 (词法语法分析 附源代码

编译原理实验 (词法语法分析 附源代码

编译原理实验报告******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。

PL/0语言文法的EBNF表示如下:<程序>::=<分程序>.<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句><常量说明> ::=CONST<常量定义>{,<常量定义>};<常量定义> ::=<标识符>=<无符号整数><无符号整数> ::= <数字>{<数字>}<变量说明> ::=V AR <标识符>{, <标识符>};<标识符> ::=<字母>{<字母>|<数字>}<过程说明> ::=<过程首部><分程序>{; <过程说明> };<过程首部> ::=PROCEDURE <标识符>;<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>|<复合语句>|<读语句><写语句>|<空><赋值语句> ::=<标识符>:=<表达式><复合语句> ::=BEGIN <语句> {;<语句> }END<条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式><表达式> ::= [+|-]<项>{<加法运算符> <项>}<项> ::= <因子>{<乘法运算符> <因子>}<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’<加法运算符> ::= +|-<乘法运算符> ::= *|/<关系运算符> ::= =|#|<|<=|>|>=<条件语句> ::= IF <条件> THEN <语句><过程调用语句> ::= CALL 标识符<当循环语句> ::= WHILE <条件> DO <语句><读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’<写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’<字母> ::= a|b|…|X|Y|Z<数字> ::= 0|1|…|8|9【预处理】对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。

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

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

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求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和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

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

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

词法分析一、实验目的二、设计、编制并调试一个词法分析程序, 加深对词法分析原理的理解。

三、实验要求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和sum3.2 扫描子程序的算法思想:首先设置3个变量: ①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn 用来存放单词符号的种别码。

词法分析java编译原理课程设计

词法分析java编译原理课程设计

词法分析java编译原理课程设计一、教学目标本课程旨在让学生掌握词法分析在Java编译原理中的应用,理解并能够运用Java的基本词法规则,包括关键字、标识符、常量、运算符等。

通过本课程的学习,学生应能熟练使用Java编译器进行程序的编译和调试,理解编译过程中词法分析的原理和实现。

具体来说,知识目标包括:1.掌握Java语言的基本词法规则。

2.理解词法分析在编译过程中的作用和重要性。

3.熟悉Java编译器的使用方法和技巧。

技能目标包括:1.能够使用Java编译器进行程序的编译和调试。

2.能够分析并解决Java程序中的词法错误。

3.能够理解和编写简单的词法分析器。

情感态度价值观目标包括:1.培养学生对编译原理的兴趣和好奇心。

2.培养学生解决问题的能力和团队合作的精神。

3.培养学生对编程语言和计算机科学的热爱。

二、教学内容本课程的教学内容主要包括Java的基本词法规则、词法分析的原理和实现、以及Java编译器的使用方法。

具体的教学大纲如下:1.第一章:Java语言概述–Java语言的历史和发展–Java语言的特点和优势–Java语言的应用领域2.第二章:Java的基本词法规则–关键字和保留字–标识符的命名规则–常量的分类和声明–运算符的分类和用法3.第三章:词法分析原理–词法分析在编译过程中的作用–词法分析器的实现方法–词法分析器的测试和优化4.第四章:Java编译器使用–Java编译器的安装和配置–编译和运行Java程序的基本步骤–分析并解决编译过程中的词法错误5.第五章:实战演练–编写简单的Java程序–使用Java编译器进行编译和调试–分析并解决程序中的词法错误三、教学方法为了提高学生的学习兴趣和主动性,本课程将采用多种教学方法相结合的方式。

包括:1.讲授法:通过讲解和演示,让学生掌握Java的基本词法规则和词法分析的原理。

2.讨论法:学生进行小组讨论,培养团队合作的精神,并促进学生对问题的深入思考。

编译原理-词法分析(附源码)

编译原理-词法分析(附源码)

词法分析实验报告一、实验项目名称词法分析二、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。

并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

三、实验环境Windows 10Microsoft Visual Studio 2015四、实验内容编制一个读单词过程,源程序为一个文件,读取该文件,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、界符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

单词的内部编码如下:1、保留字:if、int、for、while、do、return、break、continue;单词种别码为1;2、标识符:除保留字外的以字母开头,后跟字母、数字的字符序列;单词种别码为2;3、常数为无符号整形数;单词种别码为3;4、运算符包括:+、-、*、/、=;单词种别码为4;5、分隔符包括:,、;、{、}、(、);单词种别码为5。

五、实验步骤在词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并填入适当的信息表。

经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。

(1) 定义部分:定义常量、变量、数据结构。

(2) 初始化:从文件将源程序全部输入到字符缓冲区中。

(3) 取单词前:去掉多余空白。

(4) 取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。

(5) 显示结果六、源程序清单、测试数据、结果#include<iostream>#include<string>#include<fstream>#define MAX 100using namespace std;void main(){//二维char数组主存储的初始化char a[MAX][15], ch = 'a', before;int i = 0, j = 0;for (i = 0; i < MAX; i++){for (j = 0; j < 15; j++){a[i][j] = NULL;}}i = 0;j = 0;fstream file;//文件打开并读入字符file.open("D:\\text.txt",ios::in);if (file){cout <<"文件打开成功"<< endl;}while (!file.eof())//换行是10,空格是32{before = ch;file.read(&ch, 1);//**********************************************************************符号*******************************************************************||||*************************************************************前一字符为符号当前为字母数字*************************************************************************************** *******************************************************************||if ( ((ch >= 32 && ch <= 47) || (ch == 10) || (ch >= 58 && ch <= 64) ||(ch >= 91 && ch <= 94 )||(ch==96)||( ch >= 123 && ch <= 126)) || (((before >= 32 && before <= 47) || (before == 10) || (before >= 58 && before <= 64) || (before >= 91 && before <= 94) || (before == 96) || (before >= 123 && before <= 126))) && (ch > 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch>=48 && ch<=57) ){if (ch != 32 && ch != 10){i++;j = 0;}}if (ch != 32 && ch != 10){a[i][j] = ch;j++;}}file.close();ofstream fileout("D:\\out.txt", ios::ate);//判断字符串并输出for (int k = 0; k < i; k++){if (a[k][0] >= 65 && a[k][0] <= 90 || a[k][0] >= 97 && a[k][0] <= 122)//判断第一个字符是字母{if (a[k][1] >= 65 && a[k][1] <= 90 || a[k][1] >= 97 && a[k][1] <= 122)//判断第二个字符是字母{//判断是不是保留字string AA(a[k]);if (pare("if") == 0){cout <<"(1,\"if\")"<< endl;fileout <<"(1,\"if\")\n";}else if (pare("int") == 0){cout <<"(1,\"int\")"<< endl;fileout <<"(1,\"int\")\n";}else if (pare("for") == 0){cout <<"(1,\"for\")"<< endl;fileout <<"(1,\"for\")\n";}else if (pare("while") == 0){cout <<"(1,\"while\")"<< endl;fileout <<"(1,\"while\")\n";}else if (pare("do") == 0){cout <<"(1,\"do\")"<< endl;fileout <<"(1,\"do\")\n";}else if (pare("return") == 0){cout <<"(1,\"return\")"<< endl;fileout <<"(1,\"return\")\n";}else if (pare("break") == 0){cout <<"(1,\"break\")"<< endl;fileout <<"(1,\"break\")\n";}else if (pare("continue") == 0){cout <<"(1,\"continue\")"<< endl;fileout <<"(1,\"break\")\n";}else{cout <<"(2,\""<< AA <<"\")"<< endl;fileout <<"(2,\""<< AA <<"\")\n";}}else if (a[k][1] >= '0' || a[k][1] <= '9'){string AA(a[k]);cout <<"(2,\""<< AA <<"\")"<< endl;fileout <<"(2,\""<< AA <<"\")\n";}}else if (a[k][0] >= '0' && a[k][0] <= '9'){int judge = 0;int sss = 1;while(a[k][sss]!=NULL){if (a[k][sss] < '0' || a[k][sss] > '9' ){judge = 1;}sss++;}string AA(a[k]);if (judge == 0){cout <<"(3,\""<< AA <<"\")"<< endl;fileout <<"(3,\""<< AA <<"\")\n";}else{cout <<"(错误的单词:"<< AA <<"\")"<< endl;fileout <<"(错误的单词:"<< AA <<"\")\n";}}else if (a[k][0] == 42 || a[k][0] == 43|| a[k][0] == 45 || a[k][0] == 47 ||a[k][0] == 61){string AA(a[k]);cout <<"(4,\""<< AA <<"\")"<< endl;fileout <<"(4,\""<< AA <<"\")\n";}else if (a[k][0] == 44 || a[k][0] == 59 || a[k][0] == 40 || a[k][0] == 41 || a[k][0] == 123 || a[k][0] == 125){string AA(a[k]);cout <<"(5,\""<< AA <<"\")"<< endl;fileout <<"(5,\""<< AA <<"\")\n";}else if(a[k][0]!=NULL){string AA(a[k]);cout <<"(不支持的符号:"<< AA <<"\")"<< endl;fileout <<"(不支持的符号:"<< AA <<"\")\n";}}fileout.close();}七、实验小结和思考在本次实验中,我遇到了很多小问题,值得一提的是在拆输入的字符串时如何拆分成正确的单词,这很重要,拆分单词时我用的是识别字符的ACSCii码以及字符前后的组合,将识别出的单词存入已初始化的字符数组中。

完整版编译原理词法分析和语法分析报告代码C语言版1

完整版编译原理词法分析和语法分析报告代码C语言版1

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1待分析的简单的词法(1)关键字:beg in if the n while do end所有的关键字都是小写。

(2)运算符和界符:= + -*/<<=<>>>= = ;()#(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2各种单词符号对应的种别码:2.3词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begi n x:=9: if x>9 then x:=2*x+1/3; end # 的源文件,经过词法分析后输出如下序列:(1,begi n)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1主程序示意图:主程序示意图如图3-1所示。

其中初始包括以下两个方面:⑴关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表) ,当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = { begi n”,if ”,f hen ”,While ”,d o”,en d",};图3-1(2 )程序中需要用到的主要变量为syn,token和sum3.2扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;② sum用来整型单词;③ syn用来存放单词符号的种别码。

编译原理词法分析和语法分析报告+代码[C语言版]

编译原理词法分析和语法分析报告+代码[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 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码2.3 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(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和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

词法分析设计实验报告(附代码)

词法分析设计实验报告(附代码)

实验一词法分析设计实验学时:4实验类型:综合实验要求:必修一、实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。

二、实验内容用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。

通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。

以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。

(2)统计行数和列数用于错误单词的定位。

(3)删除空格类字符,包括回车、制表符空格。

(4)按拼写单词,并用(内码,属性)二元式表示。

(属性值——token的机内表示)(5)如果发现错误则报告出错(6)根据需要是否填写标识符表供以后各阶段使用。

单词的基本分类:◆关键字:由程序语言定义的具有固定意义的标识符。

也称为保留字例如if、 for、while、printf ;单词种别码为1。

◆标识符:用以表示各种名字,如变量名、数组名、函数名;◆常数:任何数值常数。

如 125, 1,0.5,3.1416;◆运算符:+、-、*、/;◆关系运算符: <、<=、= 、>、>=、<>;◆分界符:;、,、(、)、[、];三、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。

3、根据测试数据进行测试。

测试实例应包括以下三个部分:◆全部合法的输入。

◆各种组合的非法输入。

◆由记号组成的句子。

4、词法分析程序设计要求输出形式:例:输入VC++语言的实例程序:If i=0 then n++;a﹤= 3b %);输出形式为:单词二元序列类型位置(行,列)(单词种别,单词属性)for (1,for ) 关键字(1,1)i ( 6,i ) 标识符(1,2)= ( 4,= ) 关系运算符(1,3)0 ( 5,0 ) 常数(1,4)then ( 1,then) 关键字(1,5)n (6,n ) 标识符(1,6)++ Error Error (1,7); ( 2, ; ) 分界符(1,8)a (6,a ) 标识符(2,1)﹤= (4,<= ) 关系运算符(2,2)3b Error Error (2,4)% Error Error (2,4)) ( 2, ) ) 分界符(2,5); ( 2, ; ) 分界符(2,6)实验报告正文:◆功能描述:该程序具有词法分析功能,即面对一段程序源代码,通过该程序,能检查出源代码是否由词法错误。

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

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

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求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和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

编译原理课程设计_词法语法分析器

编译原理课程设计_词法语法分析器

编译原理课程设计Course Design of Compiling(课程代码3273526)半期题目:词法和语法分析器实验学期:大三第二学期学生班级:2014级软件四班学生学号:2014112218学生姓名:何华均任课教师:丁光耀信息科学与技术学院2017.6课程设计1-C语言词法分析器1.题目C语言词法分析2.内容选一个能正常运行的c语言程序,以该程序出现的字符作为单词符号集,不用处理c语言的所有单词符号。

将解析到的单词符号对应的二元组输出到文件中保存可以将扫描缓冲区与输入缓冲区合成一个缓冲区,一次性输入源程序后就可以进行预处理了3.设计目的掌握词法分析算法,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解4.设计环境(电脑语言环境)语言环境:C语言CPU:i7HQ6700内存:8G5.概要设计(单词符号表,状态转换图)5.1 词法分析器的结构词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

词法分析程序可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词.为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序:1) ch 存放最新读进的源程序字符2) strToken 存放构成单词符号的字符串3) Buffer 字符缓冲区4)struct keyType 存放保留字的符号和种别5.3 状态转换图6.详细设计(数据结构,子程序)算法思想:首先设置3个变量:①strToken用来存放构成单词符号的字符串;②ch 用来字符;③struct keyType用来存放单词符号的种别码。

扫描子程序主要部分流程如下图所示。

7.程序清单// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。

//#include"stdafx.h"#include"stdio.h"#include"stdlib.h"#include"conio.h"#include"string.h"#define N 47char ch;char strToken[20];//存放构成单词符号的字符串char buffer[1024]; //字符缓冲区struct keyType {char keyname[256];int value;}Key[N] = { { "$ID",0 },{ "$INT",1 },{ "auto",2 },{ "break",3 },{ "case",4 }, { "char",5 },{ "const",6 },{ "continue",7 },{ "default",8 },{ "do",9 }, { "double",10 },{ "else",11 },{ "enum",12 },{ "extern",13 },{ "float",14 }, { "for",15 },{ "goto",16 },{ "if",17 },{ "int",18 },{ "long",19 },{ "register",20 }, { "return",21 },{ "short",22 },{ "signed",23 },{ "sizeof",24 },{ "static",25 }, { "struct",26 },{ "switch",27 },{ "typedef",28 },{ "union",29 },{ "unsigned",30 }, { "void",31 },{ "volatile",32 },{ "while",33 },{ "=",34 },{ "+",35 },{ "-",36 },{ "*",37 }, { "/",38 },{ "%",39 },{ ",",40 },{ ";",41 },{ "(",42 },{ ")",43 },{ "?",44 },{ "clear", 45 },{ "#",46 } };void GetChar() //读一个字符到ch中{int i;if (strlen(buffer)>0) {ch = buffer[0];for (i = 0; i<256; i++)buffer[i] = buffer[i + 1];}elsech = '\0';}void GetBC()//读一个非空白字符到ch中{int i;while (strlen(buffer)) {i = 0;ch = buffer[i];for (; i<256; i++) buffer[i] = buffer[i + 1];if (ch != ' '&&ch != '\n'&&ch != '\0') break;}}void ConCat()//把ch连接到strToken之后{char temp[2];temp[0] = ch;temp[1] = '\0';strcat(strToken, temp);}bool Letter()//判断ch是否为字母{if (ch >= 'A'&&ch <= 'Z' || ch >= 'a'&&ch <= 'z')return true;elsereturn false;}bool Digit()//判断ch是否为数字{if (ch >= '0'&&ch <= '9')return true;elsereturn false;}int Reserve()//用strToken中的字符查找保留字表,并返回保留字种别码,若返回0,则非保留字{int i;for (i = 0; i<N; i++)if (strcmp(strToken, Key[i].keyname) == 0)return Key[i].value;return 0;}void Retract()//把ch中的字符回送到缓冲区{int i;if (ch != '\0') {buffer[256] = '\0';for (i = 255; i>0; i--)buffer[i] = buffer[i - 1];buffer[0] = ch;}ch = '\0';}keyType ReturnWord(){strcpy(strToken, "\0");int c;keyType tempkey;GetBC();if (ch >= 'A'&&ch <= 'Z' || ch >= 'a'&&ch <= 'z') { ConCat();GetChar();while (Letter() || Digit()) {ConCat();GetChar();}Retract();c = Reserve();strcpy(tempkey.keyname, strToken);if (c == 0)tempkey.value = 0;elsetempkey.value = Key[c].value;}else if (ch >= '0'&&ch <= '9') {ConCat();GetChar();while (Digit()) {ConCat();GetChar();}Retract();strcpy(tempkey.keyname, strToken);tempkey.value = 1;}else {ConCat();strcpy(tempkey.keyname, strToken);tempkey.value = Reserve();}return tempkey;}/*主函数*/int main() {//文件操作FILE *fp;if ((fp = fopen("E:\\作业\\编译原理\\Ccode.txt", "r")) == NULL) { printf("cannot open file/n"); exit(1);}while (!feof(fp)) {if (fgets(buffer, 250, fp) != NULL){printf("E:\\作业\\编译原理\\Ccode.txt\n");}}keyType temp;printf("单词\t种别号\n");while (strlen(buffer)) {temp = ReturnWord();printf("%s\t %d\n\n", temp.keyname, temp.value);}printf("the end!\n");getch();return 0;}8.运行结果E:/作业/编译原理/Code.txt运行结果九、 实验体会通过本次次法分析设计实验,我加深了对词法分析过程的理解。

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

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

信息工程学院实验报告(2010 ~2011 学年度第一学期)姓名:柳冠天学号:2081908318班级:083词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求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和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

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

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

编译原理 -词法分析器的设计一.设计说明及设计要求一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。

本课程设计即为词法分析阶段。

词法分析阶段是编译过程的第一个阶段。

这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。

如保留字(关键字或基本字)、标志符、常数、算符和界符等等。

二.设计中相关关键字说明1.基本字:也称关键字,如 C 语言中的 if , else , while , do ,for,case,break, return 等。

2.标志符:用来表示各种名字,如常量名、变量名和过程名等。

3.常数:各种类型的常数,如12,,和“ ABC”等。

4.运算符:如+ ,- , * , / ,%, < , > ,<= , >=等。

5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。

三、程序分析词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词序列,用以语法分析。

词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。

然而,更一般的情况,常将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。

词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。

四、模块设计下面是程序的流程图五、程序介绍在程序当前目录里建立一个文本文档,取名为 ,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。

程序结果输出在同一个目录下,文件名为,此文件为自动生成。

本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《编译原理》课程实验报告题目词法分析专业计算机科学与技术班级2013级计双班学号2013708033姓名刘畅指导老师郑瑶石河子大学信息学院计算机系2014 年11 月20 日一. 实验序号:《编译原理》词法分析实验二. 实验题目:词法分析三. 实验日期: 2014年11月20日四. 实验环境(操作系统,开发语言)操作系统:Windows开发语言:C五. 实验要求1)将标识符的词法改为“以大写字母或小写字母开头或下划线开头,后面可以跟大写字母或小写字母或数字或下划线”。

2)将<条件>中的表示相等关系的单词“=”改为“= =”;增加用于识别自增、自减、关系运算符、逻辑运算符及逗号运算符的相关语句。

3)将原来无小数的数改为可以识别整数和小数的数。

4)增加识别字符常量和字符串常量的识别。

5)或按C语言要求编写一个完整的用于识别C语言中各类单词的词法分析程序。

六. 实验步骤1)用PL/0语言编写测试用例源程序。

用C语言编写词法分析程序。

2)运行词法分析程序,读入PL/0语言的测试用例源程序,进行词法分析。

3)设立断点,单步运行词法分析程序,依次单个输出单词。

分析和理解词法分析程序,解释词法分析程序中的数据和变量变化的原因和输出结果。

4)根据上述“实验要求”修改词法分析程序,同时也应修改PL/0语言测试用例源程序中的相应的单词。

5)运行修改后的词法分析程序,读入修改后的PL/0语言测试用例源程序,进行词法分析。

七. 实验结果(测试用例源程序,运行结果截图)测试用例源程序:const c1=5.61,c2=20,c3='S',c4="abc";var num1,num2,count,sum1,sum2;procedure func1;var y1,y2;beginy1:=1;y2:=x2end;beginnum1:=c1;if num1>0&&num2!=5 then sum1=0;if num1<=0||num2>0 then sum1=sum1+1;count:=1;while x1!=x2 dox1++;num2:=c2;if num2==10 thensum2=num2--;else if num2>10 thennum2=num2-1;else thennum2=num2+1;call func1End运行结果截图:八. 实验体会(词法分析程序修改的地方,解决问题的方法、心得体会等)1.将标识符的词法改为“以大写字母或小写字母开头,后面可以跟大写字母或小写字母或数字或下划线”。

其主要代码如下:if(cACharacter>='a'&&cACharacter<='z'||cACharacter>='A'&& cACharacter<='Z') //如果当前字符是小写的字母{//标识符或保留字以a..z开头nAWordIndex=0;//单词的第一个字符do{if(nAWordIndex<MAX_LENGTH_OF_A_WORD)szAWord[nAWordIndex++]=cACharacter;//把当前字符放进单词数组里,单词数组下标加一cACharacter=GetACharacterFromFile();//从文件中再读取一个字符}while((cACharacter>='a' && cACharacter<='z' || cACharacter>='0' && cACharacter<='9' || cACharacter>='A' && cACharacter<='Z' || cACharacter=='_') && cACharacter!=EOF);其中在if语句中增加了以大写字母开头的判断语句,在while中增加了可以跟大写字母或小写字母或数字或下划线。

2.将<条件>中的表示相等关系的单词“=”改为“= =”;增加用于识别自增、自减、关系运算符、逻辑运算符及逗号运算符的相关语句。

if(cACharacter=='='){cACharacter=GetACharacterFromFile();//取下一个符号if(cACharacter=='=')//如果下一个符号是'='{//则单词是相等符号"=="g_Words[g_nWordsIndex].eType=EQL;//单词类型为单词类型枚举值EQLstrcpy(g_Words[g_nWordsIndex].szName,"==");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}else{//单词仅是'='g_Words[g_nWordsIndex].eType=ASSIGN;//单词类型为单词类型枚举值ASSIGNstrcpy(g_Words[g_nWordsIndex].szName,"=");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一return OK;}}elseif(cACharacter=='!')//检测是'!='{cACharacter=GetACharacterFromFile();//再取一个符号if(cACharacter=='='){//单词是"!="g_Words[g_nWordsIndex].eType=NEQL;//单词类型为单词类型枚举值NEQLstrcpy(g_Words[g_nWordsIndex].szName,"!=");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}return OK;}elseif(cACharacter=='&') //检测是逻辑与&&{cACharacter=GetACharacterFromFile();//再取一个符号if(cACharacter=='&'){g_Words[g_nWordsIndex].eType=AND;//单词类型为单词类型枚举值ANDstrcpy(g_Words[g_nWordsIndex].szName,"&&");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}return OK;}elseif(cACharacter=='|') //检测是逻辑与||{cACharacter=GetACharacterFromFile();//再取一个符号if(cACharacter=='|'){g_Words[g_nWordsIndex].eType=OR;//单词类型为单词类型枚举值ORstrcpy(g_Words[g_nWordsIndex].szName,"||");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}return OK;}elseif(cACharacter=='+'){cACharacter=GetACharacterFromFile();//取下一个符号if(cACharacter=='+')//如果下一个符号是'+'{//则单词是相等符号"++"g_Words[g_nWordsIndex].eType=INC;//单词类型为单词类型枚举值INCstrcpy(g_Words[g_nWordsIndex].szName,"++");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}else{//单词仅是'+'g_Words[g_nWordsIndex].eType=PLUS;//单词类型为单词类型枚举值PLUSstrcpy(g_Words[g_nWordsIndex].szName,"+");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一return OK;}}elseif(cACharacter=='-'){cACharacter=GetACharacterFromFile();//取下一个符号if(cACharacter=='-')//如果下一个符号是'-'{//则单词是相等符号"--"g_Words[g_nWordsIndex].eType=DEC;//单词类型为单词类型枚举值DECstrcpy(g_Words[g_nWordsIndex].szName,"--");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}else{//单词仅是'-'g_Words[g_nWordsIndex].eType=MINUS;//单词类型为单词类型枚举值MINUSstrcpy(g_Words[g_nWordsIndex].szName,"-");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;//在源代码文件中单词所在的行数g_nWordsIndex++;//识别出的单词个数加一return OK;}}elseif(cACharacter==',')//检测是逗号运算符{g_Words[g_nWordsIndex].eType=COMMA;//单词类型为单词类型枚举值COMMAstrcpy(g_Words[g_nWordsIndex].szName,",");//识别出的单词放进单词队列g_Words中g_Words[g_nWordsIndex].nLineNo=g_nLineNo;g_nWordsIndex++;//识别出的单词个数加一cACharacter=GetACharacterFromFile();//再取一个符号,为下一步准备return OK;}其代码主要是按照前面的“<=”修改,并在WORD_TYPE_ENUM中增加了相应的单词类型枚举值,并改变了输出。

相关文档
最新文档