Ex2 RE To NFA
Ex2 RE To NFA
. Aim: To construct the regular expression into a non-deterministic finite automata and display the transitions table. Theory: Any lexical specification can be given in a regular expression. In order to separate token, the token recognizer has to be designed which starts from conversion of regular expression into NFA.The output of this exercise can be used as the input for the next exercise i.e the conversion of NFA into DFA. Steps: 1. Initialize the transition table 2. Read the regular expression in postfix form and allocate space for the transitions table 3. Develop the code for the five operations such as: Modules: Initialising the table (table is indexed by state number in row and operands and epsilon in column) initNFATransTable concatenation (.) Alternate operation ( | ) Closure operations *, +, ?
Conversion of RE to NFA (make entries in the transition table for the given state and symbols) reg2nfa
Storing the NFA transition table in the file for the next NFA to DFA conversion operation writeNFA
Algorithm: Refer to Figure 3.8 in section 3.4.2 describing the Thompson algorithm and the subsequent discussions with examples.
Source code development: The makefile (project file) has the following files compiled and linked developed in a Linux environment.
scan:
scan.o: scan.cc nfa.h stack.h decl.h g++ -c scan.cc nfa.o: nfa.cc nfa.h stack.h decl.h g++ -c nfa.cc stack.o: stack.cc stack.h decl.h g++ -c stack.cc
int isMember(ElementType e); void findNoChars(ElementType reg[]); int findOpdIndex(ElementType r,ElementType reg[]); public: NFA(); void reg2nfa(ElementType reg[]); void displayTransTable(); void writeNFA(FILE *fp);
};
NFA::NFA() { int i,j,n; startState=0; finalState=0; noOperands=0; noSymbols=0; noOperators=0; maxStates=0; noStates=0; count=0; for(i=0;i<NOOPERATORS;i++) operators[i] = ' '; for(i=0;i<NOOPERANDS;i++) operands[i] = ' '; }
return 0; }
void NFA::findNoChars(ElementType reg[]) { int i=0; for(i=0;reg[i]!='\0';i++) { if(reg[i]>='a'&®[i]<='z') { if(!isMember(reg[i])) { operands[noOperands]=reg[i]; noOperands++; } count++; } else if(reg[i]=='*'||reg[i]=='|'||reg[i]=='+'||reg[i]=='?') { operators[noOperators]; noOperators++; count++; } } }
transTable=(int**)malloc(rows*sizeof(Pointer));
for(n=0;n<rows;n++) { transTable[n]=(int*)malloc(cols*sizeof(Pointer)); }
for(i=0;i<rows;i++) { for(j=0;j<cols;j++) {
transTable[i][j]=-1;
} } }
void NFA::displayTransTable() { int i,j; printf("\n\n\tResultant e-NFA\n\n"); printf("-------------------------------\n"); printf("State\t"); for(i=0;i<noSymbols;i++) printf("%c printf("eps1 ",operands[i]);
eps2\n\n");
printf("-------------------------------\n");
void NFA::writeNFA(FILE *fp) { int i,j; fprintf(fp,"%d\t%d\t%d\t%d\t",noStates,noSymbols,startState,finalState) ; for(i=0;i<noOperands;i++) fprintf(fp," fprintf(fp,"\n"); for(i=0;i<noStates;i++) { //printf("%d: "); %c\t",operands[i]);
int NFA::findOpdIndex(ElementType r,ElementType reg[]) { int o,x; //x=noofoperands(reg); for(o=0;o<noOperands;o++) { if(r==operands[o]) return (o); } return -1; }
void NFA::reg2nfa(ElementType reg[]) { int index=-1,opdIndex=1; int i=0,secondStartState,secondAcceptState,firstAcceptState,firstStartState; Stack s; #define fe noOperands #define se noOperands+1
initNFATransTable(maxStates,noSymbols);
s.createStack(2*count);
for(i=0;reg[i]!='\0';i++) { if(checkOperator(reg[i])==0) { index++; startState=index; s.push(index); opdIndex=findOpdIndex(reg[i],reg); transTable[index][opdIndex]=index+1; index++; finalState=index; s.push(index); } else if(reg[i]=='|') { secondAcceptState=s.topAndPop();//SECOND ACCEPTING secondStartState=s.topAndPop();//SECOND START firstAcceptState=s.topAndPop();//FIRST ACCEPTING firstStartState=s.topAndPop();//FIRST START index++; startState=index; s.push(index); transTable[index][fe]=firstStartState; transTable[index][se]=secondStartState; index++; finalState=index; // // //operand
transTable[firstAcceptState][fe]=index;
transTable[secondAcceptState][fe]=index; s.push(index); } else if(reg[i]=='.') { secondAcceptState=s.topAndPop(); secondStartState=s.topAndPop(); firstAcceptState=s.topAndPop(); firstStartState=s.topAndPop(); startState = firstStartState; //
{ firstAcceptState=s.topAndPop(); firstStartState=s.topAndPop(); index++; startState = index;// transTable[index][fe]=firstStartState; s.push(index); index++; finalState = index;// s.push(index); transTable[firstAcceptState][fe]=index; transTable[firstAcceptState][se]=firstStartState; } else if(reg[i]=='?') { firstAcceptState=s.topAndPop(); firstStartState=s.topAndPop(); index++; startState=index; // s.push(index); transTable[index][fe]=firstStartState; transTable[index][se]=++index; finalState=index; transTable[firstAcceptState][fe]=index; s.push(index); }
} noStates = index+1;
Main function calling the routines for the conversion of regular expression into NFA
#include "decl.h" #include "stack.h" #include "nfa.h" int main() { NFA nfa; char reg[50]; int nofc,nfod; int st,ft; FILE *fp; char fname[20]; printf("Enter Regular expression in Post fix form\n"); scanf("%s",reg); printf("Reg expression is: %s\n",reg);
nfa.reg2nfa(reg); nfa.displayTransTable();
printf("Enter the file name for storing NFA states\n"); scanf("%s",fname); fp=fopen(fname,"w"); if(NULL == fp) { printf("%s:Error file\n",fname); in file open.. Could not write NFA into
Transition Table
NFA
0 1 2
-1
-1 5 -1
-1 -1 -1
-1 -1 -1 3
3 4 5
-1 -1 -1 -1 -1 -1
5 0 -1
-1 2 -1
Transition Table
NFA
0 1 2 3
1 -1 -1 -1
-1 -1 3 -1
-1 -1 2 -1 -1 -1 -1 -1
Exerice for the students: Use this program and verify the transition table for the regular expression (a|b)abb .