Sie sind auf Seite 1von 51

Exp.

No: 1

TEXT EDITOR

AIM:

To write a program using C++ to implement the concepts of text editor.

ALGORITHM:

1. Start the program.


2. Initialize the necessary variables and using the switch-case statement, take the
input from user for the choice of edition.
3. The functions of the following type are written:
a. Create
b. Display
c. Append
d. Delete
e. Exit
4. Each of them are saved as different text files.
5. The operations are performed.
6. Display the output
7. End the program.
PROGRAM:

TextEditor
#include<stdio.h>
#include<conio.h>
#include<process.h>
int i,j,ec,fg,ec2;
char fn[20],e,c;
FILE *fp1,*fp2,*fp;
void Create();
void Append();
void Delete();
void Display();
void main()
{
do {
clrscr();
printf("\n\t\t***** TEXT EDITOR *****");
printf("\n\n\tMENU:\n\t-----\n ");

printf("\n\t1.CREATE\n\t2.DISPLAY\n\t3.APPEND\n\t4.DELETE\n\t5.EX
IT\n");
printf("\n\tEnter your choice:
"); scanf("%d",&ec);
switch(ec)
{
case 1:
Create();
break;
case 2:
Display();
break;
case 3:
Append();
break;
case 4:
Delete();
break;
case 5:
exit(0);
}
}while(1);
}
void Create()
{
fp1=fopen("temp.txt","w");
printf("\n\tEnter the text and press '.' to
save\n\n\t"); while(1)
{
c=getchar();
fputc(c,fp1);
if(c == '.')
{
fclose(fp1);
printf("\n\tEnter then new filename:
"); scanf("%s",fn);
fp1=fopen("temp.txt","r");
fp2=fopen(fn,"w");
while(!feof(fp1))
{
c=getc(fp1);
putc(c,fp2);
}
fclose(fp2);
break;
}}
}
void Display()
{
printf("\n\tEnter the file name: ");
scanf("%s",fn);
fp1=fopen(fn,"r");
if(fp1==NULL)
{
printf("\n\tFile not
found!"); goto end1;
}
while(!feof(fp1))
{
c=getc(fp1);
printf("%c",c);
}
end1:
fclose(fp1);
printf("\n\n\tPress any key to
continue..."); getch();
}
void Delete()
{
printf("\n\tEnter the file name: ");
scanf("%s",fn);
fp1=fopen(fn,"r");
if(fp1==NULL)
{
printf("\n\tFile not
found!"); goto end2;
}
fclose(fp1);
if(remove(fn)==0)
{
printf("\n\n\tFile has been deleted
successfully!"); goto end2;
}
else
printf("\n\tError!\n");
end2: printf("\n\n\tPress any key to
continue..."); getch();
}
void Append()
{
printf("\n\tEnter the file name: ");
scanf("%s",fn);
fp1=fopen(fn,"r");
if(fp1==NULL)
{
printf("\n\tFile not
found!"); goto end3;
}
while(!feof(fp1))
{
c=getc(fp1);
printf("%c",c);
}
fclose(fp1);
printf("\n\tType the text and press 'Ctrl+S' to
append.\n"); fp1=fopen(fn,"a");
while(1)
{
c=getch();
if(c==19)
goto end3;
if(c==13)
{
c='\n';
printf("\n\t");
fputc(c,fp1);
}
else
{
printf("%c",c);
fputc(c,fp1);
}
}
end3: fclose(fp1);
getch();
}

RESULT:

The C program to implement Text Editor has been successfully written and executed.
Exp.No: 2

LEXICAL ANALYSIS

AIM:

To write a program using C++ to implement the concepts of lexical analysis.

ALGORITHM:

1. Read the input Expression


2. Check whether input is alphabet or digits then store it as identifier
3. If the input is operator store it as symbol
4. Check the input for keywords
PROGRAM:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void removeduplicate();
void final();
int Isiden(char ch);
int Isop(char ch);
int Isdel(char ch);
int Iskey(char * str);
void removeduplicate();

char op[8]={'+','-','*','/','=','<','>','%'};
char del[8]={'}','{',';','(',')','[',']',','};
char *key[]={"int","void","main","char","float"};

//char *operato[]={"+","-","/","*","<",">","=","%","<=",">=","++"};

int idi=0,idj=0,k,opi=0,opj=0,deli=0,uqdi=0,uqidi=0,uqoperi=0,kdi=0,liti=0,ci=0;
int uqdeli[20],uqopi[20],uqideni[20],l=0,j;
char uqdel[20],uqiden[20][20],uqop[20][20],keyword[20][20];
char iden[20][20],oper[20][20],delem[20],litral[20][20],lit[20],constant[20][20];

void lexanalysis(char *str)


{
int i=0;
while(str[i]!='\0')
{
if(Isiden(str[i])) //for identifiers
{
while(Isiden(str[i]))
{
iden[idi][idj++]=str[i++];
}
iden[idi][idj]='\0';
idi++;idj=0;
}
else
if(str[i]=='"') //for literals
{
lit[l++]=str[i];
for(j=i+1;str[j]!='"';j++)
{
lit[l++]=str[j];
}
lit[l++]=str[j];lit[l]='\0';
strcpy(litral[liti++],lit);
i=j+1;
}
else
if(Isop(str[i])) // for operators
{
while(Isop(str[i]))
{
oper[opi][opj++]=str[i++];
}
oper[opi][opj]='\0';
opi++;opj=0;
}
else
if(Isdel(str[i])) //for delemeters
{
while(Isdel(str[i]))
{
delem[deli++]=str[i++];
}
}
else
{
i++;
}
}

removeduplicate();
final();
}

int Isiden(char ch)


{
if(isalpha(ch)||ch=='_'||isdigit(ch)||ch=='.')
return 1;
else
return 0;
}

int Isop(char ch)


{
int f=0,i;
for(i=0;i<8&&!f;i++)
{
if(ch==op[i])
f=1;
}
return f;
}

int Isdel(char ch)


{
int f=0,i;
for(i=0;i<8&&!f;i++)
{
if(ch==del[i])
f=1;
}
return f;
}

int Iskey(char * str)


{
int i,f=0;
for(i=0;i<5;i++)
{
if(!strcmp(key[i],str))
f=1;
}
return f;
}

void removeduplicate()
{
int i,j;
for(i=0;i<20;i++)
{
uqdeli[i]=0;
uqopi[i]=0;
uqideni[i]=0;
}
for(i=1;i<deli+1;i++) //removing duplicate delemeters
{
if(uqdeli[i-1]==0)
{
uqdel[uqdi++]=delem[i-1];
for(j=i;j<deli;j++)
{
if(delem[i-1]==delem[j])
uqdeli[j]=1;
}
}
}

for(i=1;i<idi+1;i++) //removing duplicate identifiers


{
if(uqideni[i-1]==0)
{
strcpy(uqiden[uqidi++],iden[i-1]);
for(j=i;j<idi;j++)
{
if(!strcmp(iden[i-1],iden[j]))
uqideni[j]=1;
}
}
}

for(i=1;i<opi+1;i++) //removing duplicate operators


{
if(uqopi[i-1]==0)
{
strcpy(uqop[uqoperi++],oper[i-1]);
for(j=i;j<opi;j++)
{
if(!strcmp(oper[i-1],oper[j]))
uqopi[j]=1;
}
}
}

}
void final()
{
int i=0;
idi=0;
for(i=0;i<uqidi;i++)
{
if(Iskey(uqiden[i])) //identifying keywords
strcpy(keyword[kdi++],uqiden[i]);
else
if(isdigit(uqiden[i][0])) //identifying constants
strcpy(constant[ci++],uqiden[i]);
else
strcpy(iden[idi++],uqiden[i]);
}

// printing the outputs

printf("\n\tDelemeter are : \n");


for(i=0;i<uqdi;i++)
printf("\t%c\n",uqdel[i]);

printf("\n\tOperators are : \n");


for(i=0;i<uqoperi;i++)
{
printf("\t");
puts(uqop[i]);
}

printf("\n\tIdentifiers are : \n");


for(i=0;i<idi;i++)
{
printf("\t");
puts(iden[i]);
}

printf("\n\tKeywords are : \n");


for(i=0;i<kdi;i++)
{
printf("\t");
puts(keyword[i]);
}

printf("\n\tConstants are :\n");


for(i=0;i<ci;i++)
{
printf("\t");
puts(constant[i]);
}

printf("\n\tLiterals are :\n");


for(i=0;i<liti;i++)
{
printf("\t");
puts(litral[i]);
}
}
void main()
{
char str[50];
//clrscr();
printf("\nEnter the string : ");
scanf("%[^\n]c",str);
lexanalysis(str);
//getch();
}

RESULT:

The C program to implement lexical analysis has been successfully written and
executed.
Exp.No: 3

Regular Expression to NFA

AIM:

To write a program for converting Regular Expression to NFA using C++ Language.

ALGORITHM:

1. Start
2. Get the input from the user
3. Initialize separate variables and functions for Postfix , Display and NFA
4. Create separate methods for different operators like +,*, .
5. By using Switch case Initialize different cases for the input
6. For ' . ' operator Initialize a separate method by using various stack functions do the
same for the other operators like ' * ' and ' + '.
7. Regular expression is in the form like a.b (or) a+b
8. Display the output
9. Stop
PROGRAM:

REtoNFA

#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
char reg[20];
void postfix();
void e_nfa();
void disp(int,char,int);
void main()
{
clrscr();
cin>>reg;
postfix();
cout<<reg<<endl;
e_nfa();
getch();
}
void postfix()
{
char string[10],stack[10];
int string_n=0,stack_n=0;
int n=0;
strcat(reg,"X");
while(reg[n]!='\0')
{switch(reg[n])
{
case 'a' : string [string_n]='a';
string_n++;
string[string_n]='\0';
break;
case 'b' : string[string_n]='b';
string_n++;
string[string_n]='\0';
break;
case '*' : string[string_n]='*';
string_n++;
string[string_n]='\0';
break;
case '(' : stack[stack_n]='(';
stack_n++;
break;
case ')' : stack_n--;
while(stack[stack_n]!='(')
{
string[string_n]=stack[stack_n];
stack[stack_n]='\0';
string_n++;
string[string_n]='\0';
stack_n--;
}
stack[stack_n]='\0';
break;
case 'X' : while(stack_n!=0)
{
stack_n--;
string[string_n]=stack[stack_n];
stack[stack_n]='\0';
string_n++;
string[string_n]='\0';
}
break;
case '+' : if(stack[stack_n-1]!='+'&&stack[stack_n-
1]!='.')
{
stack[stack_n]='+';
stack_n++;
stack[stack_n]='\0';
break;
}
else
{
string[string_n]=stack[stack_n-
1]; string_n++;
stack[stack_n-
1]='+'; break;
}
case '.' : if(stack[stack_n-1]!='+'&&stack[stack_n-
1]!='.')
{
stack[stack_n]='.';
stack_n++;
stack[stack_n]='\0';
break;
}
else
{
string[string_n]=stack[stack_n-
1]; string_n++;
stack[stack_n-
1]='.'; break;
}
default:break;
}
n++;
}
strcpy(reg,string);
}
void e_nfa()
{
int strt[3],last[3],s,l;
int n=0,x=0,i=-1;
while(reg[n]!='\0')
{
switch(reg[n])
{
case 'a':i++;
strt[i]=x++;
last[i]=x++;
disp(strt[i],'a',last[i]);
break;
case 'b':i++;
strt[i]=x++;
last[i]=x++;
disp(strt[i],'b',last[i]);
break;
case '+' : s=x++;
l=x++;
disp(s,'e',strt[i]);
disp(s,'e',strt[i-1]);
disp(last[i],'e',l);
disp(last[i-1],'e',l);
i--;
strt[i]=s;
last[i]=l;

break;
case '.' : disp(last[i-
1],'e',strt[i]); last[i-1]=last[i];
i--;
break;
case '*' : s=x++;
l=x++;
disp(s,'e',strt[i]);
disp(s,'e',l);
disp(last[i],'e',strt[i]);
disp(last[i],'e',l);
strt[i]=s;
last[i]=l;
break;
default:break;
}
n++;
}
cout<<i<<" "<<strt[i]<<" "<<last[i];
}
void disp(int qs,char a,int qf)
{
cout<<qs<<"-->\t"<<a<<"-->\t"<<qf<<"\n";
}

RESULT:

The C++ program to convert Regular expression to NFA has been successfully executed.
Exp.No: 4

NFA to DFA

AIM:

To write a program for converting NFA to DFA using C++ Language.

ALGORITHM:

1. Start
2. Get the input from the user
3. Implement the following sudo code:
Set the only state in SDFA to “unmarked”
while SDFA contains an unmarked state
do Let T be that unmarked state
for each a in % do
S = #-Closure(MoveNFA(T,a))
if S is not in SDFA already then
Add S to SDFA (as an “unmarked”
state) endIf
Set MoveDFA(T,a) to
S endFor
endWhile
for each S in SDFA do
if any s&S is a final state in the NFA
then Mark S an a final state in the DFA
endIf
endFor
4. Print the result.
Stop the program
PROGRAM:

NFAtoDFA

#include <cstdio>
#include <fstream>
#include <iostream>
#include <bitset>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <set>
#define MAX_NFA_STATES 10
#define MAX_ALPHABET_ SIZE
10 using namespace std;
// Representation of an NFA state
class NFAstate
{
public:
int transitions[MAX_ALPHABET_SIZE][MAX_NFA_STATES];
NFAstate()
{
for (int i = 0; i < MAX_ALPHABET_SIZE; i++)
for (int j = 0; j < MAX_NFA_STATES; j++)
transitions[i][j] = -1;
}
}*NFAstates;
// Representation of a DFA
state struct DFAstate
{
bool finalState;
bitset<MAX_NFA_STATES> constituentNFAstates;
bitset<MAX_NFA_STATES> transitions[MAX_ALPHABET_SIZE];
int symbolicTransitions[MAX_ALPHABET_SIZE];
};
set<int> NFA_finalStates;
vector<int> DFA_finalStates;
vector<DFAstate*> DFAstates;
queue<int> incompleteDFAstates;
int N, M; // N -> No. of stattes, M -> Size of input alphabet
// finds the epsilon closure of the NFA state "state" and stores
it into "closure"
void epsilonClosure(int state, bitset<MAX_NFA_STATES> &closure)
{
for (int i = 0; i < N && NFAstates[state].transitions[0][i] != -
1; i++)
if (closure[NFAstates[state].transitions[0][i]] == 0)
{
closure[NFAstates[state].transitions[0][i]] = 1;
epsilonClosure(NFAstates[state].transitions[0][i],
closure);
}
}
// finds the epsilon closure of a set of NFA states "state" and
stores it into "closure"
void epsilonClosure(bitset<MAX_NFA_STATES>
state, bitset<MAX_NFA_STATES> &closure)
{
for (int i = 0; i < N; i++)
if (state[i] == 1)
epsilonClosure(i, closure);
}
void NFAmove(int X, int A, bitset<MAX_NFA_STATES> &Y)
{
for (int i = 0; i < N && NFAstates[X].transitions[A][i] != -1;
i++)
Y[NFAstates[X].transitions[A][i]] = 1;
}
void NFAmove(bitset<MAX_NFA_STATES> X, int A, bitset<MAX_NFA_STATES>
&Y)
{
for (int i = 0; i < N; i++)
if (X[i] == 1)
NFAmove(i, A, Y);
}
int main()
{
int i, j, X, Y, A, T, F, D;
// read in the underlying NFA
ifstream fin("NFA.txt");
fin >> N >> M;
NFAstates = new NFAstate[N];
fin >> F;
for (i = 0; i < F; i++)
{
fin >> X;
NFA_finalStates.insert(X);
}
fin >> T;
while (T--)
{
fin >> X >> A >> Y;
for (i = 0; i < Y; i++)
{
fin >> j;
NFAstates[X].transitions[A][i] = j;
}
}
fin.close();
// construct the corresponding DFA
D = 1;
DFAstates.push_back(new DFAstate); DFAstates[0]-
>constituentNFAstates[0] = 1; epsilonClosure(0,
DFAstates[0]->constituentNFAstates); for (j = 0; j <
N; j++)
if (DFAstates[0]->constituentNFAstates[j] == 1
&& NFA_finalStates.find(
j) != NFA_finalStates.end())
{
DFAstates[0]->finalState = true;
DFA_finalStates.push_back(0);
break;
}
incompleteDFAstates.push(0);
while (!incompleteDFAstates.empty())
{
X = incompleteDFAstates.front();
incompleteDFAstates.pop();
for (i = 1; i <= M; i++)
{
NFAmove(DFAstates[X]->constituentNFAstates, i,
DFAstates[X]->transitions[i]);
epsilonClosure(DFAstates[X]->transitions[i],
DFAstates[X]->transitions[i]);
for (j = 0; j < D; j++)
if (DFAstates[X]->transitions[i]
== DFAstates[j]->constituentNFAstates)
{
DFAstates[X]->symbolicTransitions[i] =
j; break;
}
if (j == D)
{
DFAstates[X]->symbolicTransitions[i] =
D; DFAstates.push_back(new DFAstate);
DFAstates[D]->constituentNFAstates
= DFAstates[X]->transitions[i];
for (j = 0; j < N; j++)
if (DFAstates[D]->constituentNFAstates[j] ==
1 && NFA_finalStates.find(j) !=
NFA_finalStates.end())
{
DFAstates[D]->finalState = true;
DFA_finalStates.push_back(D);
break;
}
incompleteDFAstates.push(D);
D++;
}
}
}
// write out the corresponding DFA
ofstream fout("DFA.txt");
fout << D << " " << M << "\n" << DFA_finalStates.size();
for (vector<int>::iterator it = DFA_finalStates.begin(); it
!= DFA_finalStates.end();
it++) fout << " " << *it;
fout << "\n";
for (i = 0; i < D; i++)
{
for (j = 1; j <= M; j++)
fout << i << " " << j << " "
<< DFAstates[i]->symbolicTransitions[j] << "\n";
}
fout.close();
return 0;
}

RESULT:

The C++ program to convert NFA to DFA has been successfully executed.
Exp.No: 5 (A)

ELIMINATION OF LEFT RECURSION

AIM:

To write a program in C to eliminate left recursion.

ALGORITHM:

1. Start the program.


2. Initialize the arrays for taking input from the user.
3. Prompt the user to input the no. of non-terminals having left recursion
and no. of productions for these non-terminals.
4. Prompt the user to input the right production for non-terminals.
5. Eliminate left recursion using the following rules:-
A->Aα 1| αA 2 | . α.. . . |A m
A->β 1|β 2| . β. . . .| n
Then replace it by
A’->β i A’ i=1,2,3,…..m
A’->α j A’ j=1,2,3,…..n
A’->Ɛ

6. After eliminating the left recursion by applying these rules, display the
productions without left recursion.
7. Stop.
PROGRAM:

leftrecursion

include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<ctype.h>

void main()
{
char a[10],b[50][100]={""},d[50][100]={""},ch;
int i,n,c[10]={0},j,k,t,n1;
clrscr();
printf("\nEnter the non terminals having left recursion:
"); scanf("%s",a);
n=strlen(a);
for(i=0;i<n;i++)
{
printf("\nEnter the no of productions for %c :
",a[i]); scanf("%d",&c[i]);
}
t=0;
for(i=0;i<n;i++)
{
printf("\nEnter the right productions for
%c",a[i]); for(j=0;j<c[i];j++)
{
printf("\n%c->",a[i]);
scanf("%s",b[t]);
t++;
}
t=t+4;
}
t=0;
for(i=0;i<n;i++)
{ for(j=0;j<c[i];j++)
{ if(a[i]==b[t][0])
{
n1=strlen(b[t]);
for(k=1;k<n1;k++)
{
d[t][k-1]=b[t][k];
}
} t++;
}
t=t+4;
}
t=0;
printf("\nAfter eliminating Left Recursion:
\n"); for(i=0;i<n;i++)
{ for(j=0;j<c[i];j++)
{
if(a[i]!=b[t][0])
if(islower(b[t][0]))
printf("\n%c -> %s%c'",a[i],b[t],a[i]);
t++;
}
t=t+4;
}
t=0;
for(i=0;i<n;i++)
{
for(k=0;k<c[i];k++)
{ if(a[i]==b[t][0])
printf("\n%c' ->
%s%c'/%c",a[i],d[t],a[i],(char)238);
else if(isupper(b[t][0]))
printf("\n%c -> %s",a[i],b[t+k]);
t++;
}
t=t+4;
}
getch();
}

RESULT:

The C program to eliminate left recursion has been successfully executed.


Exp.No: 5 (B)

ELIMINATION OF LEFT FACTORING

AIM:

To write a C++ program to remove left factoring from a set of given productions.

ALGORITHM:

1. Start
2. Ask the user to enter the set of productions from which the left factoring
is to be removed.
3. Check for left factoring in the given set of productions by comparing with: A->aB1|aB2
4. If found, replace the particular productions with:
A->aA’
A’->B1 | B2|ɛ
5. Display the output
6. Exit
PROGRAM:

leftfactoring
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>

//Structure Declaration
struct production
{
char lf;
char rt[10];
int prod_rear;
int fl;
};
struct production prodn[20],prodn_new[20]; //Creation of object
//Variables Declaration

int b=-1,d,f,q,n,m=0,c=0;
char terminal[20],nonterm[20],alpha[10],extra[10];
char epsilon='^';
//Beginning of Main Program

void main()
{
clrscr();

//Input of Special characters


cout<<"\nEnter the number of Special characters(except
non-terminals): ";
cin>>q;
cout<<"Enter the special characters for your production:
"; for(int cnt=0;cnt<q;cnt++)
{
cin>>alpha[cnt];
}

//Input of Productions

cout<<"\nEnter the number of productions:


"; cin>>n;
for(cnt=0;cnt<=n-1;cnt++)
{
cout<<"Enter the "<< cnt+1<<" production:
"; cin>>prodn[cnt].lf;
cout<<"->";
cin>>prodn[cnt].rt;
prodn[cnt].prod_rear=strlen(prodn[cnt].rt);
prodn[cnt].fl=0;
}
//Condition for left factoring

for(int cnt1=0;cnt1<n;cnt1++)
{
for(int cnt2=cnt1+1;cnt2<n;cnt2++)
{
if(prodn[cnt1].lf==prodn[cnt2].lf)
{
cnt=0;
int p=-1;
while((prodn[cnt1].rt[cnt]!='\0')&&(prodn[cnt2].rt[cnt]!='\0'))
{
if(prodn[cnt1].rt[cnt]==prodn[cnt2].rt[cnt])
{
extra[++p]=prodn[cnt1].rt[cnt];
prodn[cnt1].fl=1;
prodn[cnt2].fl=1;
}
else
{
if(p==-1)
break;
else
{
int h=0,u=0;
prodn_new[++b].lf=prodn[cnt1].lf;
strcpy(prodn_new[b].rt,extra);
prodn_new[b].rt[p+1]=alpha[c];
prodn_new[++b].lf=alpha[c];
for(int g=cnt;g<prodn[cnt2].prod_rear;g++)
prodn_new[b].rt[h++]=prodn[cnt2].rt[g];
prodn_new[++b].lf=alpha[c];
for(g=cnt;g<=prodn[cnt1].prod_rear;g++)
prodn_new[b].rt[u++]=prodn[cnt1].rt[g];
m=1;
break;
}
}
cnt++;
}
if((prodn[cnt1].rt[cnt]==0)&&(m==0))
{
int h=0;
prodn_new[++b].lf=prodn[cnt1].lf;
strcpy(prodn_new[b].rt,extra);
prodn_new[b].rt[p+1]=alpha[c];
prodn_new[++b].lf=alpha[c];
prodn_new[b].rt[0]=epsilon;
prodn_new[++b].lf=alpha[c];
for(int g=cnt;g<prodn[cnt2].prod_rear;g++)
prodn_new[b].rt[h++]=prodn[cnt2].rt[g];
}
if((prodn[cnt2].rt[cnt]==0)&&(m==0))
{
int h=0;
prodn_new[++b].lf=prodn[cnt1].lf;
strcpy(prodn_new[b].rt,extra);
prodn_new[b].rt[p+1]=alpha[c];
prodn_new[++b].lf=alpha[c];
prodn_new[b].rt[0]=epsilon;
prodn_new[++b].lf=alpha[c];
for(int g=cnt;g<prodn[cnt1].prod_rear;g++)
prodn_new[b].rt[h++]=prodn[cnt1].rt[g];
}
c++;
m=0;
}
}
}

RESULT:

The C++ program to remove left factoring from a set of given productions
has been successfully executed.
Exp.No: 6

FIRST AND FOLLOW

AIM:

To write a program to perform first and follow using C language.

ALGORITHM:

For computing the first:


1. If X is a terminal then FIRST(X) =
{X} Example: F -> (E) | id
We can write it as FIRST(F) -> { ( , id }
2. If X is a non terminal like E -> T then to get
FIRST(E) substitute T with other productions until you get a terminal as the first
symbol 3. If X ->εthenεto addFIRST(X).

For computing the follow:


1. Always check the right side of the productions for a non-terminal, whose
FOLLOW set is being found. ( never see the left side ).
2. (a) If that non-terminal (S,A,B…) is followed by any terminal (a,b…,*,+,(,)…) ,
then add that “terminal” into FOLLOW set.
(b) If that non-terminal is followed by any other non-terminal then add “FIRST of
other non-terminal” into FOLLOW set.
PROGRAM:

First&Follow

#include<stdio.h>
#include<string.h>
#include<conio.h>
#define max 20
char prod[max][10];
char ter[10],nt[10];
char first[10][10],follow[10][10];
int eps[10];
int count=0;

int findpos(char ch)


{
int n;
for(n=0;nt[n]!='\0';n++)
if(nt[n]==ch)
break;
if(nt[n]=='\0')
return 1;
return n;
}
int IsCap(char c)
{
if(c >= 'A' && c<= 'Z')
return 1;
return 0;
}
void add(char *arr,char c)
{
int i,flag=0;
for(i=0;arr[i]!='\0';i++)
{
if(arr[i] == c)
{
flag=1;
break;
}
}
if(flag!=1)
arr[strlen(arr)] = c;
}
void addarr(char *s1,char *s2)
{
int i,j,flag=99;
for(i=0;s2[i]!='\0';i++)
{
flag=0;
for(j=0;;j++)
{
if(s2[i]==s1[j])
{
flag=1;
break;
}
if(j==strlen(s1) && flag!=1)
{
s1[strlen(s1)] = s2[i];
break;
}
}
}
}
void addprod(char *s)
{
int i;
prod[count][0] = s[0];
for(i=3;s[i]!='\0';i++)
{
if(!IsCap(s[i]))
add(ter,s[i]);
prod[count][i-2] = s[i];
}
prod[count][i-2] =
'\0'; add(nt,s[0]);
count++;
}
void findfirst()
{
int i,j,n,k,e,n1;
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
{
n = findpos(prod[j][0]);
if(prod[j][1] ==
(char)238) eps[n] = 1;
else
{
for(k=1,e=1;prod[j][k]!='\0' && e==1;k++)
{
if(!IsCap(prod[j][k]))
{
e=0;
add(first[n],prod[j][k]);
}
else
{
n1 = findpos(prod[j][k]);
addarr(first[n],first[n1]);
if(eps[n1] == 0)
e=0;
}
}
if(e==1)
eps[n]=1;
}
}
}
}
void findfollow()
{
int i,j,k,n,e,n1;
n = findpos(prod[0][0]);
add(follow[n],'#');
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
{
k = strlen(prod[j])-1;
for(;k>0;k--)
{
if(IsCap(prod[j][k]))
{
n=findpos(prod[j][k]);
if(prod[j][k+1] == '\0') // A -> aB
{
n1 = findpos(prod[j][0]);
addarr(follow[n],follow[n1]);
}
if(IsCap(prod[j][k+1])) // A -> aBb
{
n1 = findpos(prod[j][k+1]);
addarr(follow[n],first[n1]);
if(eps[n1]==1)
{
n1=findpos(prod[j][0]);
addarr(follow[n],follow[n1]);
}
}
else if(prod[j][k+1] != '\0')
add(follow[n],prod[j][k+1]);
}
}
}
}
}
void main()
{
char s[max],i;
printf("\nEnter the productions(type 'end' at the last of
the production)\n");
scanf("%s",s);
while(strcmp("end",s))
{
addprod(s);
scanf("%s",s);
}
findfirst();
findfollow();
for(i=0;i<strlen(nt);i++)
{
printf("%c\t",nt[i]);
printf("%s",first[i]);
if(eps[i]==1)
printf("%c\t",(char)238);
else
printf("\t");
printf("%s\n",follow[i]);
}
getch();
}

RESULT:

The C program to perform first and follow has been successfully executed.
Exp.No: 7

PREDICTIVE PARSING TABLE

AIM:

To write a C program to construct a predictive parsing table.

ALGORITHM:

1. Start the program.


2. Initialize the required variables.
3. Get the number of coordinates and productions from the user.
4. Perform the following
for (each→αin productionG){
A for (eachα)) terminal a in FIRST(
add→αtoAM[A, a];
ifεis( inα)) FIRST(
for (each symbol b in
FOLLOW(A)) add→αtoAM[A, b];
5. Print the resulting stack.
6. Print if the grammar is accepted or not.
7. Exit the program.
PROGRAM:

PredictiveParsingTable

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char fin[10][20],st[10][20],ft[20][20],fol[20][20];
int a=0,e,i,t,b,c,n,k,l=0,j,s,m,p;
clrscr();
printf("enter the no. of
coordinates\n"); scanf("%d",&n);
printf("enter the productions in a
grammar\n"); for(i=0;i<n;i++)
scanf("%s",st[i]);
for(i=0;i<n;i++)
fol[i][0]='\0';
for(s=0;s<n;s++)
{
for(i=0;i<n;i++)
{
j=3;
l=0;
a=0;
l1:if(!((st[i][j]>64)&&(st[i][j]<91)))
{
for(m=0;m<l;m++)
{
if(ft[i][m]==st[i][j])
goto s1;
}
ft[i][l]=st[i][j];
l=l+1;
s1:j=j+1;
}
else
{
if(s>0)
{
while(st[i][j]!=st[a][0])
{
a++;
}
b=0;
while(ft[a][b]!='\0')
{
for(m=0;m<l;m++)
{
if(ft[i][m]==ft[a][b])
goto s2;
}
ft[i][l]=ft[a][b];
l=l+1;
s2:b=b+1;
}
}
}
while(st[i][j]!='\0')
{
if(st[i][j]=='|')
{
j=j+1;
goto l1;
}
j=j+1;
}
ft[i][l]='\0';
}
}
printf("first pos\n");
for(i=0;i<n;i++)
printf("FIRS[%c]=%s\n",st[i][0],ft[i]);
fol[0][0]='$';
for(i=0;i<n;i++)
{
k=0;
j=3;
if(i==0)
l=1;
else
l=0;
k1:while((st[i][0]!=st[k][j])&&(k<n))
{
if(st[k][j]=='\0')
{
k++;
j=2;
}
j++;
}
j=j+1;
if(st[i][0]==st[k][j-1])
{
if((st[k][j]!='|')&&(st[k][j]!='\0'))
{
a=0;
if(!((st[k][j]>64)&&(st[k][j]<91)))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==st[k][j])
goto q3;
}
fol[i][l]=st[k][j];
l++;
q3:
}
else
{
while(st[k][j]!=st[a][0])
{
a++;
}
p=0;
while(ft[a][p]!='\0')
{
if(ft[a][p]!='@')
{
for(m=0;m<l;m++)
{
if(fol[i][m]==ft[a][p])
goto q2;
}
fol[i][l]=ft[a][p];
l=l+1;
}
else
e=1;
q2:p++;
}
if(e==1)
{
e=0;
goto a1;
}
}
}
else
{
a1:c=0;
a=0;
while(st[k][0]!=st[a][0])
{
a++;
}
while((fol[a][c]!='\0')&&(st[a][0]!=st[i][0]))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==fol[a][c])
goto q1;
}
fol[i][l]=fol[a][c];
l++;
q1:c++;
}
}
goto k1;
}
fol[i][l]='\0';
}
printf("follow pos\n");
for(i=0;i<n;i++)
printf("FOLLOW[%c]=%s\n",st[i][0],fol[i]);
printf("\n");
s=0;
for(i=0;i<n;i++)
{
j=3;
while(st[i][j]!='\0')
{
if((st[i][j-1]=='|')||(j==3))
{
for(p=0;p<=2;p++)
{
fin[s][p]=st[i][p];
}
t=j;
for(p=3;((st[i][j]!='|')&&(st[i][j]!='\0'));p++)
{
fin[s][p]=st[i][j];
j++;
}
fin[s][p]='\0';
if(st[i][k]=='@')
{
b=0;
a=0;
while(st[a][0]!=st[i][0])
{
a++;
}
while(fol[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],fol[a][b],fin[s]);
b++;
}
}
else if(!((st[i][t]>64)&&(st[i][t]<91)))
printf("M[%c,%c]=%s\n",st[i][0],st[i][t],fin[s]);
else
{
b=0;
a=0;
while(st[a][0]!=st[i][3])
{
a++;
}
while(ft[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],ft[a][b],fin[s]);
b++;
}
}
s++;
}
if(st[i][j]=='|')
j++;
}
}
getch();
}

RESULT:

The C program to construct predictive parsing table has been successfully executed.
Exp.No: 8

SHIFT REDUCE PARSING

AIM:

To write a C program to perform Shift Reduce Parsing.

ALGORITHM:

1. Start the program.


2. Initialize the required variables.
3. Enter the input symbol.
4. Perform the following:

for top-of-stack symbol, s, and next input


symbol, a shift x: (x is a STATE number)
push a, then x on the top of the stack and
advance ip to point to the next input symbol.

reduce y: (y is a PRODUCTION
number) Assume that the production
is of the form A ==> beta

pop 2 * |beta| symbols of the stack. At this


point the top of the stack should be a state number,
say s’. push A, then goto of T[s’,A] (a state number)
on the top of the stack. Output the production
A ==> beta.

5. Print if string is accepted or not.


6. Stop the program.
PROGRAM:

shiftreduceparsing

#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"string.h"
char ip_sym[15],stack[15];
int ip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
{
clrscr();
printf("\n\t\t SHIFT REDUCE
PARSER\n"); printf("\n GRAMMER\n");
printf("\n E->E+E\n E->E/E");
printf("\n E->E*E\n E->a/b");
printf("\n enter the input
symbol:\t"); gets(ip_sym);
printf("\n\t stack implementation table");
printf("\n stack\t\t input symbol\t\t action");
printf("\n______\t\t ____________\t\t
______\n"); printf("\n $\t\t%s$\t\t\t--
",ip_sym); strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)

{
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
check();
st_ptr++;
}
st_ptr++;
check();
}
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp2[1]='\0';
if((!strcmpi(temp2,"a"))||(!strcmpi(temp2,"b")))
{
stack[st_ptr]='E';
if(!strcmpi(temp2,"a"))
printf("\n $%s\t\t%s$\t\t\tE->a",stack,
ip_sym); else
printf("\n $%s\t\t%s$\t\t\tE-
>b",stack,ip_sym); flag=1;
}
if((!strcmpi(temp2,"+"))||(strcmpi(temp2,"*"))||(!strcmpi(temp2,"/")
))
{
flag=1;
}
if((!strcmpi(stack,"E+E"))||(!strcmpi(stack,"E\E"))||(!strcmpi(stack
,"E*E")))
{
strcpy(stack,"E");
st_ptr=0;
if(!strcmpi(stack,"E+E"))
printf("\n $%s\t\t%s$\t\t\tE-
>E+E",stack,ip_sym); else
if(!strcmpi(stack,"E\E"))
printf("\n $%s\t\t %s$\t\t\tE-
>E\E",stack,ip_sym); else
printf("\n $%s\t\t%s$\t\t\tE-
>E*E",stack,ip_sym); flag=1;
}

if(!strcmpi(stack,"E")&&ip_ptr==len)
{
printf("\n
$%s\t\t%s$\t\t\tACCEPT",stack,ip_sym); getch();
exit(0);
}
if(flag==0)
{
printf("\n%s\t\t\t%s\t\t
reject",stack,ip_sym); exit(0);
}
return;
}

RESULT:

The C program to implement shift reduce parsing has been successfully executed.
Exp.No: 9

LEADING AND TRAILING

AIM:

To write a C++ program to compute the leading and trailing of the given grammar.

ALGORITHM:

1. For Leading, check for the first non-terminal.


2. If found, print it.
3. Look for next production for the same non-terminal.
4. If not found, recursively call the procedure for the single non-terminal present
before the comma or End Of Production String.
5. Include it's results in the result of this non-terminal.
6. For trailing, we compute same as leading but we start from the end of the
production to the beginning.
7. Stop
PROGRAM:

leading&trailing
#include<iostream.h>
#include<string.h>
#include<conio.h>
int nt,t,top=0;
char s[50],NT[10],T[10],st[50],l[10][10],tr[50][50];
int searchnt(char a)
{
int count=-1,i;
for(i=0;i<nt;i++)
{
if(NT[i]==a)
return i;
}
return count;
}
int searchter(char a)
{
int count=-1,i;
for(i=0;i<t;i++)
{
if(T[i]==a)
return i;
}
return count;
}
void push(char a)
{
s[top]=a;
top++;
}
char pop()
{
top--;
return s[top];
}
void installl(int a,int b)

{
if(l[a][b]=='f')
{
l[a][b]='t';
push(T[b]);
push(NT[a]);
}
}
void installt(int a,int b)
{
if(tr[a][b]=='f')
{
tr[a][b]='t';
push(T[b]);
push(NT[a]);
}
}

void main()
{
int i,s,k,j,n;
char pr[30][30],b,c;
clrscr();
cout<<"Enter the no of
productions:"; cin>>n;
cout<<"Enter the productions one by one\n";
for(i=0;i<n;i++)
cin>>pr[i];
nt=0;
t=0;
for(i=0;i<n;i++)
{
if((searchnt(pr[i][0]))==-1)
NT[nt++]=pr[i][0];
}
for(i=0;i<n;i++)
{
for(j=3;j<strlen(pr[i]);j++)
{
if(searchnt(pr[i][j])==-1)
{
if(searchter(pr[i][j])==-
1) T[t++]=pr[i][j];
}
}
}
for(i=0;i<nt;i++)
{
for(j=0;j<t;j++)
l[i][j]='f';
}
for(i=0;i<nt;i++)
{
for(j=0;j<t;j++)

tr[i][j]='f';
}
for(i=0;i<nt;i++)
{
for(j=0;j<n;j++)
{
if(NT[(searchnt(pr[j][0]))]==NT[i])
{
if(searchter(pr[j][3])!=-1)
installl(searchnt(pr[j][0]),searchter(pr[j][3]));
else
{
for(k=3;k<strlen(pr[j]);k++)
{
if(searchnt(pr[j][k])==-1)
{
installl(searchnt(pr[j][0]),searchter(pr[j][k]));
break;
}
}
}
}
}
}
while(top!=0)
{
b=pop();
c=pop();
for(s=0;s<n;s++)
{
if(pr[s][3]==b)
installl(searchnt(pr[s][0]),searchter(c));
}
}
for(i=0;i<nt;i++)
{
cout<<"Leading["<<NT[i]<<"]"<<"\t{";
for(j=0;j<t;j++)
{
if(l[i][j]=='t')
cout<<T[j]<<",";
}
cout<<"}\n";
}

top=0;
for(i=0;i<nt;i++)
{
for(j=0;j<n;j++)
{
if(NT[searchnt(pr[j][0])]==NT[i])
{
if(searchter(pr[j][strlen(pr[j])-1])!=-1)
installt(searchnt(pr[j][0]),searchter(pr[j][strlen(pr[j])-1]));
else
{
for(k=(strlen(pr[j])-1);k>=3;k--)
{
if(searchnt(pr[j][k])==-1)
{
installt(searchnt(pr[j][0]),searchter(pr[j][k]));
break;
}
}
}
}
}
}
while(top!=0)
{
b=pop();
c=pop();
for(s=0;s<n;s++)
{
if(pr[s][3]==b)
installt(searchnt(pr[s][0]),searchter(c));
}
}
for(i=0;i<nt;i++)
{
cout<<"Trailing["<<NT[i]<<"]"<<"\t{";
for(j=0;j<t;j++)
{
if(tr[i][j]=='t')
cout<<T[j]<<",";
}
cout<<"}\n";
}
getch();
}

RESULT:

The C++ program to compute the leading and trailing of the given grammar
has been successfully executed.
Exp.No: 10

LR(0) ITEM CONSTRUCTION

AIM:
To perform LR(0) Item construction on a production using C programming.

ALGORITHM:
1. Start.
2. Create structure for production with LHS and RHS.
3. Open file and read input from file.
4. Build state 0 from extra grammar Law S' -> S $ that is all start symbol of grammar
and one Dot ( . ) before S symbol.
5. If Dot symbol is before a non-terminal, add grammar laws that this non-terminal is in
Left Hand Side of that Law and set Dot in before of first part of Right Hand Side.
6. If state exists (a state with this Laws and same Dot position), use that instead.
7. Now find set of terminals and non-terminals in which Dot exist in before.
8. If step 7 Set is non-empty go to 9, else go to 10.
9. For each terminal/non-terminal in set step 7 create new state by using all
grammar law that Dot position is before of that terminal/non-terminal in reference
state by increasing Dot point to next part in Right Hand Side of that laws.
10. Go to step 5.
11. End of state building.
12. Display the output.
13. End.
PROGRAM:
lr(0)construction

#include<stdio.h>
#include<string.h>
#include<conio.h>

int i,j,k,m,n=0,o,p,ns=0,tn=0,rr=0,ch=0;
char
read[15][10],gl[15],gr[15][10],temp,templ[15],tempr[15][10],*ptr,tem
p2[5],dfa[15][15];

struct states
{
char lhs[15],rhs[15][10];
int n;
}I[15];

int compstruct(struct states s1,struct states s2)


{
int t;
if(s1.n!=s2.n)
return 0;
if( strcmp(s1.lhs,s2.lhs)!=0 )
return 0;
for(t=0;t<s1.n;t++)
if( strcmp(s1.rhs[t],s2.rhs[t])!=0 )
return 0;
return 1;
}

void moreprod()
{
int r,s,t,l1=0,rr1=0; char
*ptr1,read1[15][10];
for(r=0;r<I[ns].n;r++)
{
ptr1=strchr(I[ns].rhs[l1],'.');
t=ptr1-I[ns].rhs[l1];
if( t+1==strlen(I[ns].rhs[l1]) )
{
l1++;
continue;
}
temp=I[ns].rhs[l1][t+1];
l1++;
for(s=0;s<rr1;s++)
if( temp==read1[s][0] )
break;
if(s==rr1)
{
read1[rr1][0]=temp;
rr1++;
}
else
continue;

for(s=0;s<n;s++)
{
if(gl[s]==temp)
{
I[ns].rhs[I[ns].n][0]='.';
I[ns].rhs[I[ns].n][1]=NULL;
strcat(I[ns].rhs[I[ns].n],gr[s]);
I[ns].lhs[I[ns].n]=gl[s];
I[ns].lhs[I[ns].n+1]=NULL;
I[ns].n++;
}
}
}
}

void canonical(int l)
{
int t1;
char read1[15][10],rr1=0,*ptr1;
for(i=0;i<I[l].n;i++)
{
temp2[0]='.';
ptr1=strchr(I[l].rhs[i],'.');
t1=ptr1-I[l].rhs[i];
if( t1+1==strlen(I[l].rhs[i]) )
continue;
temp2[1]=I[l].rhs[i][t1+1];
temp2[2]=NULL;

for(j=0;j<rr1;j++)
if( strcmp(temp2,read1[j])==0 )
break;
if(j==rr1)
{
strcpy(read1[rr1],temp2);
read1[rr1][2]=NULL;
rr1++;
}
else
continue;

for(j=0;j<I[0].n;j++)
{
ptr=strstr(I[l].rhs[j],temp2);
if( ptr )
{
templ[tn]=I[l].lhs[j];
templ[tn+1]=NULL;
strcpy(tempr[tn],I[l].rhs[j]);
tn++;
}
}

for(j=0;j<tn;j++)
{
ptr=strchr(tempr[j],'.'); p=ptr-
tempr[j]; tempr[j][p]=tempr[j][p+1];
tempr[j][p+1]='.';
I[ns].lhs[I[ns].n]=templ[j];
I[ns].lhs[I[ns].n+1]=NULL;
strcpy(I[ns].rhs[I[ns].n],tempr[j]);
I[ns].n++;

moreprod();
for(j=0;j<ns;j++)
{
//if ( memcmp(&I[ns],&I[j],sizeof(struct
states))==1 )
if( compstruct(I[ns],I[j])==1 )
{
I[ns].lhs[0]=NULL;
for(k=0;k<I[ns].n;k++)
I[ns].rhs[k][0]=NULL;
I[ns].n=0;
dfa[l][j]=temp2[1];
break;
}
}
if(j<ns)
{
tn=0;
for(j=0;j<15;j++)
{
templ[j]=NULL;
tempr[j][0]=NULL;
}
continue;
}

dfa[l][j]=temp2[1];
printf("\n\nI%d :",ns);
for(j=0;j<I[ns].n;j++)
printf("\n\t%c ->
%s",I[ns].lhs[j],I[ns].rhs[j]); getch();
ns++;
tn=0;
for(j=0;j<15;j++)
{
templ[j]=NULL;
tempr[j][0]=NULL;
}
}
}

void main()
{
FILE *f;
int l;
clrscr();
for(i=0;i<15;i++)
{
I[i].n=0;
I[i].lhs[0]=NULL;
I[i].rhs[0][0]=NULL;
dfa[i][0]=NULL;
}

f=fopen("tab6.txt","r");
while(!feof(f))
{
fscanf(f,"%c",&gl[n]);
fscanf(f,"%s\n",gr[n]);
n++;
}

printf("THE GRAMMAR IS AS FOLLOWS\n");


for(i=0;i<n;i++)
printf("%c -> %s\n",gl[i],gr[i]);

I[0].lhs[0]='Z';
strcpy(I[0].rhs[0],".S");
I[0].n++;
l=0;
for(i=0;i<n;i++)
{
temp=I[0].rhs[l][1];
l++;
for(j=0;j<rr;j++)
if( temp==read[j][0] )
break;
if(j==rr)
{
read[rr][0]=temp;
rr++;
}
else
continue;
for(j=0;j<n;j++)
{
if(gl[j]==temp)
{
I[0].rhs[I[0].n][0]='.';
strcat(I[0].rhs[I[0].n],gr[j]);
I[0].lhs[I[0].n]=gl[j];
I[0].n++;
}
}
}
ns++;
printf("\nI%d :\n",ns-1);
for(i=0;i<I[0].n;i++)
printf("\t%c -> %s\n",I[0].lhs[i],I[0].rhs[i]);

for(l=0;l<ns;l++)
canonical(l);

printf("\n\n\n\t\tPRESS ANY KEY TO


EXIT"); getch();
}

RESULT:

The C program to compute the leading and trailing of the given grammar
has been successfully executed.

Das könnte Ihnen auch gefallen