Compiler Assignment
Compiler Assignment
COMPILER CONSTRUCTION
LAB ASSIGNMENT
Submitted by:
Shantanu Dev
101917052
COPC-3
October,2021
Q. Design a Minimized DFA for the generic Regular Expression This will involve three
steps:
• Generate the NFA using Thomson's Construction
• Generate the DFA using Subset Construction
• Minimize the DFA generated
CODE :
#include<bits/stdc++.h>
using namespace std;
struct nst
{ vector<int> a[2], e; bool
f=0;
};
vector<nst> nfa;
struct dst
{ int a[2] = {-1,-1}; bool
f=0;
};
vector<dst> dfa;
stack<int> st;
int nfa_size, dfa_size; string
dispregex;
struct nst init_nfa_state;
struct dst init_dfa_state;
void custom_clear() { for(int i=0; i<100; i++)
cout<<endl;
}
1 | Page
string insert_concat(string regexp){ string ret=""; char
c,c2; for(unsigned int i=0; i<regexp.size(); i++){
c=regexp[i]; if(i+1<regexp.size()){
c2=regexp[i+1]; ret+=c;
if(c!='('&&c2!=')'&&c!='+'&&c2!='+'&&c2!='*'){ ret+='.';
}
}}
ret+=regexp[regexp.size()-1]; return ret;
}
void character(int i)
{ nfa.push_back(init_nfa_state);
nfa.push_back(init_nfa_state);
nfa[nfa_size].a[i].push_back(nfa_size+
1); st.push(nfa_size); nfa_size++;
st.push(nfa_size); nfa_size++;
}
void union_()
{ nfa.push_back(init_nfa_state);
nfa.push_back(init_nfa_state); int d =
st.top(); st.pop(); int c = st.top();
st.pop(); int b = st.top(); st.pop(); int a =
st.top(); st.pop();
nfa[nfa_size].e.push_back(a);
nfa[nfa_size].e.push_back(c);
nfa[b].e.push_back(nfa_size+1);
nfa[d].e.push_back(nfa_size+1);
st.push(nfa_size); nfa_size++;
st.push(nfa_size); nfa_size++;
2 | Page
}
void concatenation()
{ int d = st.top(); st.pop(); int c =
st.top(); st.pop(); int b =
st.top(); st.pop(); int a =
st.top(); st.pop();
nfa[b].e.push_back(c);
st.push(a); st.push(d);
}
void kleene_star()
{ nfa.push_back(init_nfa_state);
nfa.push_back(init_nfa_state); int b = st.top();
st.pop(); int a = st.top(); st.pop();
nfa[nfa_size].e.push_back(a);
nfa[nfa_size].e.push_back(nfa_size+1);
nfa[b].e.push_back(a);
nfa[b].e.push_back(nfa_size+1); st.push(nfa_size);
nfa_size++; st.push(nfa_size); nfa_size++;
}
3 | Page
}
}
void display_nfa()
{ cout<<endl<<endl;
cout<<"Phase 1: regex to nfa conversion using thompson's construction algorithm\n";
cout<<" \n";
cout<<"State\t|\ta\t|\tb\t|\teps\t|accepting state|"<<endl;
cout<<" \n";
for(unsigned int i=0; i<nfa.size(); i++)
{ cout<<i<<"\t|\t";
for(unsigned int j=0; j<nfa[i].a[0].size(); j++)cout<<nfa[i].a[0][j]<<' '; cout<<"\t|\t";
for(unsigned int j=0; j<nfa[i].a[1].size(); j++)cout<<nfa[i].a[1][j]<<' '; cout<<"\t|\t";
for(unsigned int j=0; j<nfa[i].e.size(); j++)cout<<nfa[i].e[j]<<' '; cout<<"\t|\t";
if(nfa[i].f)cout<<"Yes"; else cout<<"No"; cout<<"\t|\n";
}
cout<<" \n";
}
4 | Page
{ string postfix="";
stack<char> op; char
c;
for(unsigned int i=0; i<regexp.size(); i++)
{ switch(regexp[i])
{ case 'a':
case 'b': postfix+=regexp[i]; break;
case '(': op.push(regexp[i]); break;
case ')':
while(op.top()!='('){
postfix+=op.top();
op.pop(); } op.pop(); break;
default:
while(!op.empty()){
c=op.top();
if(priority(c)>=priority(regexp[i])){
postfix+=op.top(); op.pop();
} else break;
}
op.push(regexp[i]);
}
//cout<<regexp[i]<<' '<<postfix<<endl;
}
while(!op.empty())
{ postfix += op.top();
op.pop();
} return postfix;
}
5 | Page
void print_dfa(){
cout<<endl;
cout<<"NFA TO DFA CONVERSION"<<endl;
cout<<" "<<endl;
cout<<"STATE\t|\t"<<"a"<<"\t|\t"<<"b"<<"\t|\t"<<"FINAL"<<"\t|"<<endl;
cout<<" "<<endl; for(int i=0;i<dfa.size();i++){
cout<<i<<"\t|\t"<<dfa[i].a[0]<<"\t|\t"<<dfa[i].a[1]<<"\t|\t"<<dfa[i].f<<"\t|"<<endl;
}
cout<<" "<<endl;
}
6 | Page
}
} } return
temp;
}
si=que.front(); temp2=state_change(2,si);
si=temp2;
for (set<int>::iterator it=si.begin(); it!=si.end(); ++it){
7 | Page
epsilon_closure(*it,si);
} if(mp.count(si)==0){
mp[si]=ct++; que.push(si);
dfa[p].a[1]=ct-1;
} else{
dfa[p].a[1]=mp.find(si)->second;
} temp2.clear();
que.pop(); p++; } for(int
i=0;i<p;i++){
if(dfa[i].a[0]==-1)dfa[i].a[0]=p; if(dfa[i].a[1]==-1)dfa[i].a[1]=p;
} dfa.push_back(init_dfa_state);
dfa[p].a[0]=p; dfa[p].a[1]=p;
//cout<<p<<endl;
}
8 | Page
}
if(!part[1].size()) part.erase(part.end());
/// Loop until no new partition is created bool chk=true; /// Check if
any new partition is created int strt = 0; /// Starting State
while(chk) {
chk=false;
part[i].clear();
part[i].push_back(trans[0].second);
for(k=1; k<trans.size() and (trans[k].first==trans[k-1].first); k++) {
part[i].push_back(trans[k].second);
}
while(k<trans.size()) {
9 | Page
if(trans[k].first!=trans[k-1].first) {
part.push_back(vector<int> ()); m++;
}
grp[trans[k].second] = m;
part[m].push_back(trans[k].second); k++;
}
}
}
}
}
void print_menu(){
10| Page
cout<<"\n \n";
cout<<"Input Regex: "<<dispregex<<endl<<endl; cout<<"1.
NFA\n"; cout<<"2. Intermediate DFA\n"; cout<<"3. Minimized
DFA\n"; cout<<"4. Simulation\n"; cout<<"Press any other key to
exit...\n\n";
}
11| Page
for(unsigned i=0;i<input.size();i++){ if(input[i]=='a')
next_state=get<0>(min_dfa[curr_state]);
else next_state=get<1>(min_dfa[curr_state]);
cout<<input[i]<<"\t|\t"<<curr_state<<"\t|\t"<<next_state<<"\t|\n"; curr_state=next_state;
}
cout<<" "<<endl;
cout<<endl<<"Verdict: ";
if(curr_state>=0&&get<2>(min_dfa[curr_state]))cout<<"Accepted"; else cout<<"Rejected";
cout<<endl;
}
int main()
{ custom_clear(); string
regexp,postfix;
cout<<"Enter Regular Expression: "; cin>>regexp;
dispregex=regexp; regexp=insert_concat(regexp); postfix
= regexp_to_postfix(regexp); cout<<"Postfix Expression:
"<<postfix<<endl; postfix_to_nfa(postfix);
cout<<endl<<endl;
12| Page
pair<int,vector<tuple<int,int,bool> > > min_dfa_tmp = minimize_dfa(dfa);
getchar(); custom_clear();
while(1){
print_menu(); char
choice;
choice=getchar();
custom_clear();
switch(choice) { case
'1':
display_nfa();
getchar(); break;
case '2': print_dfa();
getchar(); break;
case '3':
print(min_dfa);
getchar(); break;
case '4':
simulate(start_st,min_dfa); break;
default:
exit(EXIT_SUCCESS);
} } cout<<endl<<endl; cout<<"Enter string : ";
string input; cin.ignore(); getline(cin,input); int
curr_state,next_state; while(input!=""){
//cout<<input<<endl; curr_state=start_st;
13| Page
for(unsigned i=0;i<input.size();i++){
if(curr_state>=0){ if(input[i]=='a')
next_state=get<0>(min_dfa[curr_state]);
else
next_state=get<1>(min_dfa[curr_state]);
if(next_state>=0){
cout<<input[i]<<" : State "<<curr_state<<" -> State "<<next_state<<endl;
}
else cout<<input[i]<<" : State "<<curr_state<<" -> Trap State"<<endl;
}
else cout<<input[i]<<" : Trapped"<<endl; curr_state=next_state;
} if(curr_state>=0&&get<2>(min_dfa[curr_state]))cout<<"accepted"; else
cout<<"rejected"; cout<<endl<<endl;
cout<<"Enter string : "; getline(cin,input);
} return 0;
}
14| Page