编译原理实验报告
NFA->DFA 、lexical analyzer
一、NFA转成DFA
1.源代码
#include<set>
#include<stack>
#include<iostream>
using namespace std;
//Triad(三元组): S→aB即(S,a,B) .
struct Triad{
char start;
char edge;
char end;
};
set<char>e_closure(set<char>, Triad[], int);
set<char>move(set<char>,char, Triad[], int);
void determined(Triad [], int, char*, int);
const int MAX_NODES =20;
int main(){
int N;
cout<<"请输入边数:"<<endl;
cin>>N;
Triad* G=new Triad[N];
cout<<"请输入正规文法(*代表E ,#代表终态,约定输入时先输入以始态开始的三元组):"<<endl;
for(int i=0; i<N; i++){
cin>>G[i].start>>G[i].edge>>G[i].end;
}
set<char> Edge;
for(int j=0; j<N; j++)
{
Edge.insert(G[j].edge);
}
int n=Edge.size();
char*input=new char[n];
set<char>::iterator it;
int j=0;
for (it = Edge.begin(); it!= Edge.end(); it++){
input[j]=*it;
j++;
}
determined(G, N, input, n);
system("pause");
return 0;
}
set<char> e_closure(set<char> T,Triad G[], int N){
set<char> U=T;
stack<char> S;
set<char>::iterator it;
for (it = U.begin(); it != U.end(); it++)
{
S.push(*it);
}
char t;
while (!S.empty()){
t = S.top();
S.pop();
for (int i=0;i<N;i++){
if(G[i].start== t && G[i].edge=='*'){
U.insert(G[i].end);
S.push(G[i].end);
}
}
}
return U;
}
set<char> move(set<char> I, char a,Triad G[], int N){
set<char> U;
set<char>::iterator it;
for (it = I.begin(); it !=I.end(); it++)
for(int i=0; i<N; i++){
if(G[i].start==*it && G[i].edge==a)
U.insert(G[i].end);
}
return U;
}
void determined(Triad G[], int N, char*input, int n){
cout<<endl<<"确定后的DFA:"<<endl;
bool marked[MAX_NODES];
for(int i=0; i<MAX_NODES; i++)
marked[i]=false;
set<char> C[MAX_NODES];
char s0=G[0].start;
set<char> T0,T1;
T0.insert(s0);
T1=e_closure(T0,G, N);
C[0]=T1;
int i=0;
while(!C[i].empty() && marked[i]==false && i<MAX_NODES){
marked[i]=true;
//下面被注释代码可用于输出图中求出来的集合
/*
set<char>::iterator it;
cout<<i<<":";
for (it = C[i].begin(); it != C[i].end(); it++)
cout<<*it<<",";
cout<<endl;
*/
for(int j=0; j<n; j++){
if(input[j] != '*'){
set<char> U=e_closure(move(C[i], input[j],G,N),G,N);
if(!U.empty()){
bool inC=false;
int k=0;
while(!C[k].empty() && k<MAX_NODES){
if(U==C[k]){
inC=true;
break;
}
k++;
}
if(!inC){
k=0;
while(!C[k].empty() && k<MAX_NODES)
{
k++;
}
C[k]=U;
}
cout<<j<<"—"<<input[j]<<""<<k<<endl;
}
}
}
i++;
}
//下面求出确定化后的终态
cout<<"终态为:";
i=0;
while(!C[i].empty()){
bool is_final_state=false;
set<char>::iterator it;
for ( it=C[i].begin(); it != C[i].end(); it++){
if(*it== '#'){
is_final_state=true;
break;
}
}
if(is_final_state) cout<<i<<",";
i++;
}
cout<<endl;
}
2.读入数据
测试数据:课本P50例3.6
3.运行结果:
二、词法分析程序
1.源代码
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
//关键字
string key[6]={"main","int","if","else","while","do"};
//关键字的种别码
int keyNum[6]={1,2,3,4,5,6};
//运算符和界符
string symbol[17]={"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};
//char symbol[12]={'<','>','!=','>=','<=','==',',',';','(',')','{','}'};
//运算符和界符的种别码
int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
//存放文件取出的字符
string letter[1000];
//将字符转换为单词
string words[1000];
int length; //保存程序中字符的数目
int num;
int isSymbol(string s){ //判断运算符和界符
int i;
for(i=0;i<17;i++){
if(s==symbol[i])
return symbolNum[i];
}
return 0;
}
//判断是否为数字
bool isNum(string s){
if(s>="0" && s<="9")
return true;
return false;
}
//判断是否为字母
bool isLetter(string s)
{
if(s>="a" && s<="z")
return true;
return false;
}
//判断是否为关键字,是返回种别码
int isKeyWord(string s){
int i;
for(i=0;i<6;i++){
if(s==key[i])
return keyNum[i];
}
return 0;
}
//返回单个字符的类型
int typeword(string str){
if(str>="a" && str<="z") // 字母
return 1;
if(str>="0" && str<="9") //数字
return 2;
if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"
||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符
return 3;
return 0;
}
string identifier(string s,int n){
int j=n+1;
int flag=1;
while(flag){
if(isNum(letter[j]) || isLetter(letter[j])){
s=(s+letter[j]).c_str();
if(isKeyWord(s)){
j++;
num=j;
return s;
}
j++;
}
else{
flag=0;
}
}
num=j;
return s;
}
string symbolStr(string s,int n){
int j=n+1;
string str=letter[j];
if(str==">"||str=="="||str=="<"||str=="!") {
s=(s+letter[j]).c_str();
j++;
}
num=j;
return s;
}
string Number(string s,int n){
int j=n+1;
int flag=1;
while(flag){
if(isNum(letter[j])){
s=(s+letter[j]).c_str();
j++;
}
else{
flag=0;
}
}
num=j;
return s;
}
void print(string s,int n){
cout<<"("<<s<<","<<n<<")"<<endl;
}
void TakeWord(){ //取单词
int k;
for(num=0;num<length;){
string str1,str;
str=letter[num];
k=typeword(str);
switch(k){
case 1:
{
str1=identifier(str,num);
if(isKeyWord(str1))
print(str1,isKeyWord(str1));
else
print(str1,0);
break;
}
case 2:
{
str1=Number(str,num);
print(str1,24);
break;
}
case 3:
{
str1=symbolStr(str,num);
print(str1,isSymbol(str1));
break;
}
}
}
}
int main(){
char w;
int i,j;
freopen("D:\\VS1\\code2\\NFAconverttoDFA\\lexicalanalyzer\\s.txt","r",stdin);
freopen("D:\\VS1\\code2\\NFAconverttoDFA\\lexicalanalyzer\\result.txt","w",stdout); //从控制台输出,而不是文本输出
length=0;
while(cin>>w){
if(w!=' '){
letter[length]=w;
length++;
} //去掉程序中的空格
}
TakeWord();
for(j=0;j<length;j++){
cout<<letter[j]<<endl;
}
fclose(stdin);//关闭文件
fclose(stdout);//关闭文件
system("puase");
return 0;
}
2.读入数据
s.txt如下:
int main(){
int a,b;
a=103;
if(a>=b){
a=a*b;
}
}
注意修改路径
freopen("D:\\VS1\\code2\\NFAconverttoDFA\\lexicalanalyzer\\s.txt","r",stdin);
freopen("D:\\VS1\\code2\\NFAconverttoDFA\\lexicalanalyzer\\result.txt","w",stdout); //从控制台输出,而不是文本输出
3.运行结果:
result.txt
(int,2)
(main,1)
((,15)
(),16)
({,17)
(int,2)
(a,0)
(,,13)
(b,0)
(;,14)
(a,0)
(=,23)
(103,24)
(;,14)
(if,3)
((,15)
(a,0)
(>=,10)
(b,0)
(),16)
({,17)
(a,0)
(=,23)
(a,0)
(*,21)
(b,0)
(;,14)
(},18)
(},18)
i
n
t
m
a
i
n
(
)
{
i
n
t
a
,
b
;
a
=
1
0
3
;
i
f
(
a
>
=
b
)
{
a
=
a
*
b
;
}
}