?? 實驗一詞法分析.cpp
字號:
#include<conio.h>
#include<iostream>
#include<iomanip>
#include<string.h>
#include<fstream>
#include <stdlib.h>
using namespace std;
int checkprotect(char t[]);
void checkicon(char t[]);
struct node
{
char t[10];
};
struct node1
{
char item[15];
node1 *next;
};
int hr=0;
int kline=0;
int op=0;
node1 *head=NULL;//保存標識符的指針
static int init=0;
void main()
{
char filename[30];
cout<<"*******************"<<endl;
cout<<"姓名: 張 帆"<<endl;
cout<<"班級: 04(3)班"<<endl;
cout<<"學號: 200433101093"<<endl;
cout<<"*******************"<<endl;
cout<<"輸入要編譯的程序名: ";
char c[20];
cin>>c;
fstream file;
file.open(c,ios::in);
char newline[80]=" ";
char word[80]=" ";
char temp[80]=" ";
int em;
node1 *p=NULL;
node1 *q=NULL;
int j=0;
int m=0;
int n=0;
int newlength=0;
int wordlength=0;
int flag;
int nextline=0;
while(1)
{
file.getline(newline,80);
if(strcmp(newline,"")==0)
break;
kline++;//記錄當前的行數
newlength=strlen(newline);//讀取新的一行的長度
//下面進行單行的分析,以空格為界
//每次讀入一段字符,進行相應的操作
for(j=0;j<newlength;j++)
{
m=0;//保存每一個單詞都是從t字符數組的第一位開始的
while(newline[j]==' ')
{
j++;
}
//****************************************************************************************************
//字符常數缺右邊的單引號(字符常數要求左、右邊用單引號界定,不能跨行);
if(newline[j]==39)
{
m=0;
for(j++;(j<newlength)&&(newline[j]!=39);j++,m++)
temp[m]=newline[j];
if(j==newlength)
{
if(hr==0)
{
hr=1;
}
cout<<"miss right ' at line "<<kline<<endl;
flag=strlen(temp);
for(em=0;em<flag;em++)
{
temp[em]=0;
}
flag=strlen(word);
for(em=0;em<flag;em++)
{
word[em]=0;
}
break;
}
else
{
p=head;
for(m=1;p!=NULL;q=p,p=p->next,m++)
{
if(strcmp(p->item,temp)==0)
{
if(hr==0){
cout<<"(38,"<<m<<") ";
op++;
if(op%5==0)
cout<<endl;
break;}
}
}
if(head==NULL)
{
head=new node1;
strcpy(head->item,temp);
head->next=NULL;
if(hr==0){
cout<<"(38,1) ";
op++;
if(op%5==0)
cout<<endl;}
}
else
if(p==NULL&&q!=NULL)
{
q->next=new node1;
strcpy(q->next->item,temp);
q->next->next=NULL;
if(hr==0){
cout<<"(38,"<<m<<") ";
op++;
if(op%5==0)
cout<<endl;}
}
j++;
flag=strlen(temp);
for(em=0;em<flag;em++)
{
temp[em]=0;
}
flag=strlen(word);
for(em=0;em<flag;em++)
{
word[em]=0;
}
}
}
//*************************************************************************************************
//注釋部分缺右邊的界符*/(注釋要求左右邊分別用/*和*/界定,不能跨行)。
if(newline[j]=='/'&&newline[j+1]=='*')
{
for(j=j+2;j<newlength-1;j++)
if(newline[j]=='*'&&newline[j+1]=='/')
break;
if(j==newlength-1)
{
if(hr==0)
{
hr=1;
}
cout<<"miss right '*/' at line "<<kline<<endl;
break;
}
else
{
j++;
continue;
}
}
//**************************************************************************************************
//**************************************************************************************************
//以空格為界,將讀入的一行字符進行隔離分析
while(newline[j]!=' '&&newline[j]!=39&&j<newlength)
{
word[m]=newline[j];
m++;
j++;
}
if(newline[j]==39)
j--;
wordlength=strlen(word);
for(m=0;m<wordlength;m++)
{
if(!(
(word[m]>=65&&word[m]<=91)
||(word[m]>=97&&word[m]<=122)
||(word[m]>=39&&word[m]<=62)
||(word[m]==32)
||(word[m]==93)
))
{
if(hr==0)
{
hr=1;
}
cout<<"illegal sympol at line"<<kline<<endl;
wordlength=0;
break;
}
}
//對讀出來的的單詞進行分析
//讀取要分析的字符串長度
for(n=0;n<wordlength;n++)
{
m=0;
while(
(n<wordlength)&&(word[n]!='+')
&&(word[n]!='-')&&(word[n]!='*')
&&(word[n]!='/')&&(word[n]!='=')
&&(word[n]!='<')&&(word[n]!='>')
&&(word[n]!=':')&&(word[n]!='.')
&&(word[n]!=';')&&(word[n]!=','))
{
temp[m]=word[n];
n++;
m++;
}//當字符不是單界符且字符還沒有讀完時,就將其讀到temp中
if(m!=0)//m不等于零,表示在temp中有東西
{//判斷讀到的字符是啥東西
m=checkprotect(temp);
if(m==36)
{
checkicon(temp);
}
}
if(n<=wordlength)
{
switch(word[n])
{
case '+':{if(hr==0){cout<<"(43,-) ";op++;if(op%5==0)cout<<endl;break;}}
case '-':{if(hr==0){cout<<"(45,-) ";op++;if(op%5==0)cout<<endl;break;}}
case '*':{if(hr==0){cout<<"(41,-) ";op++;if(op%5==0)cout<<endl;break;}}
case '=':{if(hr==0){cout<<"(56,-) ";op++;if(op%5==0)cout<<endl;break;}}
case '<':{
if(n+1<=wordlength)
if(word[n+1]=='=')
{if(hr==0){cout<<"(54,-) ";op++;if(op%5==0)cout<<endl;n++;}}
else if(word[n+1]=='>')
{if(hr==0){cout<<"(55,-) ";op++;if(op%5==0)cout<<endl;n++;}}
else
{if(hr==0){cout<<"(53,-) ";op++;if(op%5==0)cout<<endl;}}
break;
}
case '>':{
if(n+1<=wordlength)
if(word[n+1]=='=')
{if(hr==0){cout<<"(58,-) ";op++;if(op%5==0)cout<<endl;n++;}}
else
{if(hr==0){cout<<"(57,-) ";op++;if(op%5==0)cout<<endl;}}
break;
}
case ':':{
if(n+1<=wordlength)
if(word[n+1]=='=')
{if(hr==0){cout<<"(51,-) ";op++;if(op%5==0)cout<<endl;n++;}}
else
{if(hr==0){cout<<"(50,-) ";op++;if(op%5==0)cout<<endl;}}
break;
}
case '.':{
if(n+1<=wordlength)
if(word[n+1]=='.')
{if(hr==0){cout<<"(47,-) ";op++;if(op%5==0)cout<<endl;n++;}}
else
{if(hr==0){cout<<"(46,-) ";op++;if(op%5==0)cout<<endl;}}
break;
}
case ';':{if(hr==0){cout<<"(52,-) ";op++;if(op%5==0)cout<<endl;break;}}
case ',':{if(hr==0){cout<<"(44,-) ";op++;if(op%5==0)cout<<endl;break;}}
case '/':{if(hr==0){cout<<"(48,-) ";op++;if(op%5==0)cout<<endl;break;}}
}
}
flag=strlen(temp);
for(em=0;em<flag;em++)
{
temp[em]=0;
}
}
flag=strlen(word);
for(em=0;em<flag;em++)
{
word[em]=0;
}
}
for(em=0;em<strlen(newline);em++)
{
newline[em]=' ';
}
}
file.close();
_getch();
}
void checkicon(char ty[])
{
int length=strlen(ty);
int number=1;
node1 *p=NULL;
node1 *q=NULL;
int k=1;
if(length==1)
{
if(ty[0]=='('){if(hr==0){cout<<"(39,-) ";op++;if(op%5==0)cout<<endl;return;}}
if(ty[0]==')'){if(hr==0){cout<<"(40,-) ";op++;if(op%5==0)cout<<endl;return;}}
if(ty[0]=='['){if(hr==0){cout<<"(59,-) ";op++;if(op%5==0)cout<<endl;return;}}
if(ty[0]==']'){if(hr==0){cout<<"(60,-) ";op++;if(op%5==0)cout<<endl;return;}}
if(ty[0]=='/'){if(hr==0){cout<<"(48,-) ";op++;if(op%5==0)cout<<endl;return;}}
}
for(int qw=0;qw<length;qw++)
{
if(ty[qw]<'0'||ty[qw]>'9')
{
number=0;
break;
}
}
if(number==0)
{
if(ty[0]>='0'&&ty[0]<='9')
{
if(hr==0)
{
hr=1;
}
cout<<"illegal id at line"<<kline<<endl;
return;
}
for(qw=0;qw<length;qw++)
{
if((ty[qw]=='(')||(ty[qw]==')')||(ty[qw]=='/')||(ty[qw]=='[')
||(ty[qw]==']')||(ty[qw]==39))
{
if(hr==0)
{
hr=1;
}
cout<<"illegal id at line"<<kline<<endl;
return;
}
}
}
for(p=head;p!=NULL;q=p,p=p->next,k++)
{
if(strcmp(p->item,ty)==0)
{
if(number==0)
{
if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
else
{
if(hr==0){cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
break;
}
}
if(head==NULL)
{
head=new node1;
strcpy(head->item,ty);
head->next=NULL;
if(number==0)
{
if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
else
{
if(hr==0){ cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
}
else
if(p==NULL&&head!=NULL)
{
q->next=new node1;
strcpy(q->next->item,ty);
q->next->next=NULL;
if(number==0)
{
if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
else
{
if(hr==0){cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
}
}
}
int checkprotect(char ty[])
{
static node f[36];
if(init==0)
{
strcpy(f[1].t,"and");
strcpy(f[2].t,"array");
strcpy(f[3].t,"begin");
strcpy(f[4].t,"bool");
strcpy(f[5].t,"call");
strcpy(f[6].t,"case");
strcpy(f[7].t,"char");
strcpy(f[8].t,"constant");
strcpy(f[9].t,"dim");
strcpy(f[10].t,"do");
strcpy(f[11].t,"else");
strcpy(f[12].t,"end");
strcpy(f[13].t,"false");
strcpy(f[14].t,"for");
strcpy(f[15].t,"if");
strcpy(f[16].t,"input");
strcpy(f[17].t,"integer");
strcpy(f[18].t,"not");
strcpy(f[19].t,"of");
strcpy(f[20].t,"or");
strcpy(f[21].t,"output");
strcpy(f[22].t,"procedure");
strcpy(f[23].t,"program");
strcpy(f[24].t,"read");
strcpy(f[25].t,"real");
strcpy(f[26].t,"repeat");
strcpy(f[27].t,"set");
strcpy(f[28].t,"stop");
strcpy(f[29].t,"then");
strcpy(f[30].t,"to");
strcpy(f[31].t,"true");
strcpy(f[32].t,"until");
strcpy(f[33].t,"var");
strcpy(f[34].t,"while");
strcpy(f[35].t,"write");
init++;
}
for(int i=1;i<36;i++)
if(strcmp(f[i].t,ty)==0)
{
if(hr==0){
if(i<10)
cout<<"("<<i<<" ,-) ";
else
cout<<"("<<i<<",-) ";
op++;if(op%5==0)cout<<endl;}
break;
}
return i;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -