Professional Documents
Culture Documents
19071A12F2 - Sumanth .M
19071A12F7 - P. Deekshitha
19071A12G4 - M. Prashansa
19071A12H6 - V. Akhil
1. S.RENU DEEPTHI
-Assistant Professor
2. B.SRIVANI
-Assistant Professor
ABSTRACT
The lexical analyzer needs to scan and identify only a finite set of valid string/token/lexeme
that belong to the language in hand. It searches for the pattern defined by the language
rules.
Regular expressions have the capability to express finite languages by defining a pattern for
finite strings of symbols. The grammar defined by regular expressions is known as regular
grammar. The language defined by regular grammar is known as regular language.
In DFA, for each input symbol, one can determine the state to which the machine will
move. Hence, it is called Deterministic Automaton. As it has a finite number of states, the
machine is called Deterministic Finite Machine or Deterministic Finite Automaton.
PROBLEM DEFINITION
Regular expression is an important notation for specifying patterns. Each pattern matches a
set of strings, so regular expressions serve as names for a set of strings. Programming
language tokens can be described by regular languages. The specification of regular
expressions is an example of a recursive definition. Regular languages are easy to
understand and have efficient implementation.
Example
Q = {a, b, c},
∑ = {0, 1},
q0 = {a},
F = {c}, and
Step 1: Design a transition diagram for given regular expression, using NFA with ε moves.
First, we will construct the transition diagram for a given regular expression
Now we have got NFA without ε. Now we will convert it into required DFA for
that, we will first write a transition table for this NFA.
Removal of Null Moves from Finite Automata:
#include<bits/stdc++.h>
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;
void custom_clear() {
for(int i=0; i<100; i++) cout<<endl;
}
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++;
}
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++;
}
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";
}
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;
}
si=que.front();
temp2=state_change(2,si);
si=temp2;
for (set<int>::iterator it=si.begin(); it!=si.end(); ++it){
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;
}
if(!part[1].size()) part.erase(part.end());
int k, m = part.size()-1;
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()) {
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(){
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";
}
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);
int final_state=st.top();st.pop();
int start_state=st.top();st.pop();
//cout<<start_state<<' '<<final_state<<endl;
nfa[final_state].f=1;
set<int> si;
queue<set<int> > que;
nfa_to_dfa(si,que,start_state);
cout<<endl<<endl;
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;
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;
}
Output:
INTERMIDIATE DFA
MINIMIZED DFA
STRING ACCEPTANCE