码迷,mamicode.com
首页 > 其他好文 > 详细

编译原理词法分析

时间:2015-07-05 23:56:49      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

#include<iostream>
#include<String>
#include <strstream>
using namespace std;

#define N 200;
/*
关键字结构体定义
*/
typedef struct keyword{
char name[20];
}KeyWord;
/*
符号表结构体定义
*/
typedef struct symboltable{
char name[20]; //token值
string attribute; //属性值
}SymbolTable;
//把关键字事先保存到结构体中
KeyWord keywords[20] = {"void","main","int","float","const","for","if","else","continue","while",
"switch","case","break","typedef","struct","char","double","return","endl"};
SymbolTable symboltables[10][10000];

int position=0; //定义符号表指针
int record = 0;
bool isKey; //bool型变量判断是否为关键字
char current[50]; //定义字符数组暂存当前的token
FILE *file; //文件读取操作
char ch;
char temp1[10000000]; //定义char数组保存从文件中读取的数据


//添加词法分析结果到符号表
void addSimpleTable(char current[],bool iskey)
{
record = (int)position/10000;
int i = 0;
if(!iskey) //若识别的字母不为关键字则正常保存token的属性值否则属性值赋值为“-1”
{
strstream ss;
string s;
ss << position;
ss >> symboltables[record][position].attribute;
}
else if(iskey)
symboltables[record][position].attribute="-1";
while(current[i]!=‘\0‘)
{
symboltables[record][position].name[i] = current[i];
i++;
}
position++;
}

void addSimpleTable2(char current[],string id)
{
record = (int)position/100000;
int i = 0;
symboltables[record][position].attribute = id;
while(current[i]!=‘\0‘)
{
symboltables[record][position].name[i] = current[i];
i++;
}
position++;
}
//判断是否为关键字
void isKeyWord(char current[])
{

int i=0;
isKey=false;
int count = 0;
for(int j =0;j<20;j++)
{
i=0;count=0;
while(current[i]!=‘\0‘)
{
if(current[i]!=keywords[j].name[i])
{
i++;break;
}
else {
i++;count++;
}
}
if(count==i&&keywords[j].name[i]==‘\0‘)
{
isKey=true;
break;
}
}
addSimpleTable(current,isKey);
}
/*
直接转向法处理数字
*/
void isDigital(char str[],int &i)
{
bool end = false;
int state = 1;
memset(&current,0,sizeof(current));
int current_begin = 0;
current[current_begin++] = str[i];
while(!end)
{
switch(state){
case 1:i++;
if((str[i]>47)&&(str[i]<58))
{
state = 1;
current[current_begin++] = str[i];
}
else if(str[i]==‘.‘)
{
state = 3;
current[current_begin++] = str[i];
}
else state = 2;
break;
case 2:i--;addSimpleTable(current,false);end=true;break;
case 3:i++;
current[current_begin++] = str[i];
if((str[i]>47)&&(str[i]<58))
state = 4;
break;
case 4:i++;
if((str[i]>47)&&(str[i]<58))
{
state = 4;
current[current_begin++] = str[i];
}
else if(str[i] == ‘E‘)
{
state = 6;
current[current_begin++] = str[i];
}
else
{
state = 5;
}
break;
case 5:i--;addSimpleTable(current,false);end=true;break;
case 6:i++;
current[current_begin++] = str[i];
if(str[i]==‘+‘||str[i]==‘-‘)
state=7;
else if((str[i]>47)&&(str[i]<58))
state=8;
break;
case 7:i++;
current[current_begin++] = str[i];
state=8;
break;
case 8:i++;
if((str[i]>47)&&(str[i]<58))
{
state=8;
current[current_begin++] = str[i];
}
else state=9;
break;
case 9:i--;addSimpleTable(current,false);end=true;break;
}
}

}
/*
直接转向法处理字母
*/
void isLetter(char str[],int &i)
{
bool end = false;
int state = 1;
memset(&current,0,sizeof(current));
int current_begin = 0;
current[current_begin++] = str[i];
while(!end)
{
switch(state)
{
case 1:i++;
if(((str[i]>=‘a‘)&&(str[i]<=‘z‘))||((str[i]>=‘A‘)&&(str[i]<=‘Z‘))||((str[i]>47)&&(str[i]<58)))
{
state = 1;
current[current_begin++] = str[i];
}
else {state=2;}
break;
case 2:i--;isKeyWord(current);end=true;break;
}
}
}
/*
直接转向法处理注释
*/
void isAnnotation(char str[],int &i)
{
bool end = false;
int state = 1;
while(!end)
{
switch(state)
{
case 1:i++;
if(str[i]==‘*‘)
state=2;
else if(str[i]==‘/‘)
state=5;
break;
case 2:i++;
if(str[i]==‘*‘)
state=3;
else state=2;
break;
case 3:i++;
if(str[i]==‘/‘)
state=4;
break;
case 4:end=true;break;
case 5:end=true;
while(str[i]!=‘\n‘)
{
i++;
}
break;
}
}
}
/*
直接转向法处理运算符等
*/
void isRelop(char str[],int &i)
{
bool end = false;
int state = 0;
int current_begin = 0;
i--;
memset(&current,0,sizeof(current)); //清空current数组值
while(!end)
{
switch(state)
{
case 0:i++;
if(str[i]==‘<‘)
{
state=1;
current[current_begin++] = str[i];
}
else if(str[i]==‘=‘)
{
state=5;
current[current_begin++] = str[i];
}
else if(str[i]==‘>‘)
{
state=7;
current[current_begin++] = str[i];
}
break;
case 1:i++;
if(str[i]==‘=‘)
{
state=2;
current[current_begin++] = str[i];
}
else if(str[i]==‘>‘)
{
state=3;
current[current_begin++] = str[i];
}
else state=4;
break;
case 2:addSimpleTable2(current,"LE");end=true;break;
case 3:addSimpleTable2(current,"NE");end=true;break;
case 4:addSimpleTable2(current,"LT");i--;end=true;break;
case 5:i++;
if(str[i]==‘=‘)
{
state=5;
current[current_begin++] = str[i];
}
else state=6;
break;
case 6:addSimpleTable2(current,"EQ");i--;end=true;break;
case 7:i++;
if(str[i]==‘=‘)
{
state=8;
current[current_begin++] = str[i];
}
else state=9;
break;
case 8:addSimpleTable2(current,"GE");end=true;break;
case 9:addSimpleTable2(current,"GT");i--;end=true;break;

}
}

}
/*
处理加减乘除等运算符
*/
void isOther(char str[],int &i)
{
memset(&current,0,sizeof(current));
switch(str[i]){
case ‘+‘:
if(str[i+1]==‘=‘)
{ current[0]=‘+‘;
current[1]=‘=‘;
i++;
}
else current[0]=‘+‘;break;
case ‘-‘:
if(str[i+1]==‘=‘)
{
current[0]=‘-‘;
current[1]=‘=‘;
i++;
}
else current[0]=‘-‘;break;
case ‘*‘:if(str[i+1]==‘=‘)
{
current[0]=‘*‘;
current[1]=‘=‘;
i++;
}
else current[0]=‘*‘;break;
case ‘/‘:if(str[i+1]==‘=‘)
{
current[0]=‘/‘;
current[1]=‘=‘;
i++;
}
else current[0]=‘/‘;break;
case ‘%‘:if(str[i+1]==‘=‘)
{
current[0]=‘%‘;
current[1]=‘=‘;
i++;
}
else current[0]=‘%‘;break;
case ‘!‘: current[0]=‘!‘;
current[1]=‘=‘;
i++; break;
case ‘&‘: if(str[i+1]==‘&‘)
{
current[0]=‘&‘;
current[1]=‘&‘;
i++;
}
else current[0]=‘&‘;break;
case ‘|‘: current[0]=‘|‘;
current[1]=‘|‘;
i++; break;
case ‘#‘:current[0]=‘#‘; break;
case ‘ ‘: break;
case ‘\t‘: break;
case ‘\n‘: break;
case ‘;‘:current[0]=‘;‘; break;
case ‘,‘:current[0]=‘,‘; break;
case ‘:‘:current[0]=‘:‘; break;
case ‘.‘:current[0]=‘.‘; break;
case ‘(‘:current[0]=‘(‘; break;
case ‘)‘:current[0]=‘)‘; break;
case ‘{‘:current[0]=‘{‘; break;
case ‘}‘:current[0]=‘}‘; break;
case ‘[‘:current[0]=‘[‘; break;
case ‘]‘:current[0]=‘]‘; break;
case ‘"‘:int count = 0;
current[count]=str[i];
count++;
i++;
while(str[i]!=‘"‘)
{
current[count]=str[i];
count++;
i++;
}
current[count]=str[i];
break;
}
if(current[0]!=NULL)
addSimpleTable(current,false);
}
/*
对输入的字符串处理
*/
void solve(char str[])
{
int i = 0;
while(str[i]!=EOF)
{
if((str[i]>47)&&(str[i]<58))
{ isDigital(str,i);i++;} //是数字
else if(((str[i]>=‘a‘)&&(str[i]<=‘z‘))||((str[i]>=‘A‘)&&(str[i]<=‘Z‘)))
{ isLetter(str,i); i++;} //是字母
else if((str[i]==‘/‘&&str[i+1]==‘/‘)||(str[i]==‘/‘&&str[i+1]==‘*‘))
{ isAnnotation(str,i); i++;} //是注释
else if(str[i]==‘>‘||str[i]==‘<‘||str[i]==‘=‘)
{ isRelop(str,i);i++;} //是运算符,如>,<等
else
{ isOther(str,i);i++;} //处理加减乘除等运算符
}
}

void test(char str[]){
int i=0;
while(str[i]!=EOF)
{
cout<<str[i];
i++;
}
}
void output()
{
cout<<"词法分析最终的结果如下:"<<endl;
int i=0,j=0;
int count = 0;
while(count<=record)
{
while(symboltables[count][i].name[0]!= NULL)
{
cout<<"(";
j=0;
while(symboltables[count][i].name[j]!= NULL)
{
cout<<symboltables[count][i].name[j];
j++;
}
if(symboltables[count][i].attribute!= "-1")
{
cout<<","<<symboltables[count][i].attribute<<")"<<endl;
i++;
}
else {
i++;
cout<<")"<<endl;
}
}
count++;
}
}
void getFile()
{
char path[30];
cout<<"请输入文件位置完整路径:(如J:/test/source.txt)"<<endl;
cin>>path;
// J:/test/source.txt
if((file=fopen(path,"r"))==NULL)
{
cout<<"文件路径不对,无法读取文件"<<endl;
}
}
void scanner(){
getFile();
int j=0;
while(ch!=EOF)
{
ch=fgetc(file);
temp1[j] = ch;
j++;
}
temp1[j]=EOF;
// test(temp1);
solve(temp1);
}
void infor()
{
cout<<‘\t‘<<"***************************************************************"<<endl;
cout<<‘\t‘<<"**"<<" "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" 编译原理词法分析 作者: 孙贤伟 "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" 1.实现数字,字母,注释,关键字及其他运算符识别处理 "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" 2.实现从文件读取程序并以符号表形式呈现最终分词结果 "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" "<<"**"<<endl;
cout<<‘\t‘<<"**"<<" "<<"**"<<endl;
cout<<‘\t‘<<"***************************************************************"<<endl;
}
int main(){
/* for(int i=0;i<200000;i++)
{
symboltables[i].attribute = " ";
for(int j=0;j<20;j++)
symboltables[i].name[j] = NULL;
}
*/
infor();
scanner();
output();
fclose(file);
return 0;
}

编译原理词法分析

标签:

原文地址:http://www.cnblogs.com/sxianwei/p/4623279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!