Download as pdf or txt
Download as pdf or txt
You are on page 1of 49

INDEX

S.No Program Name Sign.


.
1. Write a program to perform various stack operations using
Array.
2(a). Write a program to check whether given input is a keyword or
not.
2(b).
Write a program to check whether given input is a String
constant or not.

3. Write a program to check whether a string accepted by the


grammar or not.
4.
Practice of LEX/YACC of compiler writing.

5. Write a program to compute FIRST of non-terminal.

6. Write a program to compute FOLLOW of non-terminal.

7.
Write a program for operator Precedence Parser.
8.
Write a program to remove left recursion.

9. Write a program to remove left factoring.


10. Write a program to generate parse tree.
Program: 1

Aim: Write a program to perform various stack operations using Array.


#include<stdio.h>
#include<conio.h>
#define max 6
int a[max],top=0;
void push();
void pop();
void display();
void main()
{
int i=0,ch;
clrscr();
while(i==0)
{
printf("\nenter the choice\n");
printf("1.Push\n");
printf("2.Pop\n");
printf("3.Display\n");
printf("4.Exit\n");
scanf("%d",&ch);

switch(ch)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
i=1;
break;
default:
printf("Invalid Choice\n");
}
}
getch();
}
void push()
{
int data;
if(top==max)
{
printf("Stack Overflow");
}
else
{
printf("Enter the element to insert\n");
scanf("%d",&data);
top=top+1;
a[top]=data;
}
}
void pop()
{
int temp;
if(top==0)
{
printf("Stack Underflow");
}
else
{
temp=a[top];

top=top-1;
printf("\nElement is deleted\n");
}
}

void display()
{
int j;
printf”**** stack elements are ****”);
for(j=1;j<=top;j++)
{
printf("%d\n",a[j]);
}
}
Output
Program: 2(a)

Aim: Write a program to check whether given input is a keyword or not.


#include<stdio.h>

#include<conio.h>

void main(){char
array[32][20]={"if","else","break","continue","typedef","for","while","do","void","float","ch
ar","int","auto","case","const","default","double","enum","extern","goto","long","register","r
eturn","short","signed","sizeof","static","struct","switch","union","unsigned","volatile"};
int flag=1;
char input[1000];
char ch='y';
int i,j,k;
clrscr();
while(ch=='y' || ch=='Y'){
flag=1; // the input is not keyword
printf("Enter any word to check whether it is a keyword or not\n");
scanf("%s",&input);
i=0,j=0,k=0;
for(i=0;i<32;i++){
while(array[i][j]==input[k] && array[i][j] !='\0' && input[k] != '\0')
{
j++;k++;

}
if(array[i][j]=='\0' && input[k]=='\0')
{
flag=0;
break;
}
}// end of for loop
if(flag==0)
printf("The given word is a keyword\n");
else
printf("The given word is not a keyword \n");

printf("Do you want to continue y/n\t");


scanf("%s",&ch);
}
}

Output
Program: 2(b)

Aim: Write a program to check whether given input is a String constant or


not.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int i,n,d=0;
char ch;
char s[10];
clrscr();
printf("\nEnter the string:");
gets(s);
n=strlen(s);
puts(s);
for(int i=0;i<n;i++)
{
if(s[i]>=65&&s[i]<=122)
{
}

else

{
d++;
break;
}
}
if(d==0)
{
printf("\nentered string is valid string constant");
}
else
printf("\nnot a valid string constant");
getch();
}

Output
Program: 3

Aim: Write a program to check whether a string accepted by the grammar


or not.
#include<stdio.h>
#include<conio.h>
void main()
{
int i=0,a=0,b=0;
char s[1000];
clrscr();
printf("s->as\ns->sb\ns->ab\n");
printf("enter the string\n");
scanf("%s",&s[i]);

while(s[i]!='\0' && s[i]=='a')


{
a=1;
i++;
}
while(s[i]!='\0' && s[i]=='b')
{
b=1;
i++;
}
if(s[i]=='\0' && a==1 && b==1)
{
printf("string accepted");
}
else {
while(s[i]=='a'|| s[i]=='b') {
i++; }
if(s[i]=='\0') {
printf("string not accepted");
}
else
{
printf("Invalid Grammar");
}
}
getch();
}

Output
Program: 4

Aim: Practice of LEX/YACC of compiler writing.


A Compiler or interpreter for a programming language is often decomposed into two parts:
1. Read the source program and discover its structure.
2. Process this structure, e.g. to generate the target program.
Lex and Yacc can generate program fragments that solve the first task.
The task of discovering the source structure again is decomposed into subtasks:
1. Split the source files into tokens(Lex).
2. Find the hierarchical structure of program(Yacc).
LEX ( A Lexical Analyzer Generator)

 The main job of a lexical analyzer (scanner) is to break up an input stream into more
usable elements (tokens).
 a = b + c * d;
 ID ASSIGN ID PLUS ID MULT ID SEMI
 Lex is an utility to help you rapidly generate your scanner.
 Lexical analyzers tokenize input streams
 Tokens are the terminals of a language
>English
words, punctuation marks
>Programming language
Identifiers, operators, keywords
 Regular expressions define terminals/tokens.

LEX Source Program

Lex source is separated into three sections by %% delimiters and general format of Lex
source is:

{definitions}

%% (required)

{transition rules}

%% (optional)

{user subroutines}

Example of source program

digit [0-9]

letter [a-zA-Z]

%%

{letter}({letter}|{digit})* printf(“id: %s\n”, yytext);

\n printf(“new line\n”);

%%

main() {

yylex();

}
LEX Source to C Program

• The table is translated to a C program (lex.yy.c) which

– reads an input stream

– partitioning the input into strings which match the given expressions and

– copying it to an output stream if necessary

Overview of LEX

Lex Source Program LEX lex.yy.c

Lex.yy.c C COMPILER a.out

Input a.out tokens

LEX Usage

 To run Lex on a source file, type


lex scanner.l
 It produces a file named lex.yy.c which is a C program for the lexical analyzer.
 To compile lex.yy.c, type
cc lex.yy.c –ll
 To run the lexical analyzer program, type
./a.out < inputfile

YACC - Yet Another Compiler-Compiler:

 Tool which will produce a parser for a given grammar.


 YACC is a program designed to compile a LALR(1) grammar and to produce the
source code of the syntactic analyzer of the language produced by this grammar

YACC file format:

%{

C declarations

%}
Yacc declarations

%%

Grammar rules

%% Additional C code

How YACC works:

File containing desired grammar in yacc


format(gram.y)

yacc program (yacc)

C source program created by yacc (y.tab.c)

C compiler (cc)

Executable program that will parse the grammar given


in gram.y (a.out)

grammar given in gram.y

Working of YACC:

y.tab.c

YACC Source(*.y) y.tab.h


YACC
y.output

y.tab.c C Compiler/Linker a.out

Token Stream a.out Abstract Syntax Tree


YACC File Example:

%{
#include <stdio.h>
%}

%token NAME NUMBER


%%

statement:
LEX v/s YACC:NAME '=' expression
| expression { printf("= %d\n", $1); }
Lex ;

-Lex generates expression


expression: C code for a lexical
'+'analyzer,
NUMBERor { scanner
$$ = $1 + $3; }
| expression '-' NUMBER { $$ = $1 - $3; }
-Lex uses|patterns that match strings in the input{and
NUMBER $$converts
= $1;the} strings to tokens
Yacc ;
%%
int yyerror(char
-Yacc generates C code*s)for syntax analyzer, or parser.
{
fprintf(stderr,
-Yacc uses grammar rules"%s\n",
that allow its);
to analyze tokens from Lex and create a syntax
tree. return 0;
}

int main(void)
LEX
{ with YACC:
yyparse();
Lex Source(Lexical Rules) YACC Rules(Grammar Rules)
return 0;
}

LEX YACC

Lex.yy.c y.tab.c

call
Yylex() Yyparse()
input Parsed input

return token
Program: 5

Aim: Write a program to compute FIRST of non-terminal.


#include<stdio.h>
#include<ctype.h>
void FIRST(char );
int count,n=0;
char prodn[10][10], first[10];
void main()
{
int i,choice;
char c,ch;
printf("How many productions ? :");
scanf("%d",&count);
printf("Enter %d productions epsilon= $ :\n\n",count);
for(i=0;i<count;i++)
scanf("%s%c",prodn[i],&ch);
do
{
n=0;
printf("Element :");
scanf("%c",&c);
FIRST(c);
printf("\n FIRST(%c)= { ",c);
for(i=0;i<n;i++)
printf("%c ",first[i]);
printf("}\n");

printf("press 1 to continue : ");


scanf("%d%c",&choice,&ch);
}
while(choice==1);
}
void FIRST(char c)
{
int j;
if(!(isupper(c)))first[n++]=c;
for(j=0;j<count;j++)
{
if(prodn[j][0]==c)
{
if(prodn[j][2]=='$') first[n++]='$';
else if(islower(prodn[j][2]))first[n++]=prodn[j][2];
else FIRST(prodn[j][2]);
}
}}
Output
Program: 6

Aim: Write a program to compute FOLLOW of non-terminal.


#include<stdio.h>
#include<string.h>
#include<conio.h>
int n,m=0,p,i=0,j=0;
char a[10][10],f[10];
void follow(char c);
void first(char c);
int main()
{
int i,z;
char c,ch;
clrscr();
printf("Enter the no.of productions:");
scanf("%d",&n);
printf("Enter the productions(epsilon=$):\n");
for(i=0;i<n;i++)
scanf("%s%c",a[i],&ch);
do
{
m=0;
printf("Enter the element whose FOLLOW is to be found:");
scanf("%c",&c);
follow(c);
printf("FOLLOW(%c) = { ",c);
for(i=0;i<m;i++)
printf("%c ",f[i]);
printf(" }\n");
printf("Do you want to continue(0/1)?");
scanf("%d%c",&z,&ch);
}
while(z==1);
}
void follow(char c)
{

if(a[0][0]==c)f[m++]='$';
for(i=0;i<n;i++)
{
for(j=2;j<strlen(a[i]);j++)
{
if(a[i][j]==c)
{
if(a[i][j+1]!='\0')first(a[i][j+1]);

if(a[i][j+1]=='\0'&&c!=a[i][0])
follow(a[i][0]);
}
}
}
}
void first(char c)
{
int k;
if(!(isupper(c)))f[m++]=c;
for(k=0;k<n;k++)
{
if(a[k][0]==c)
{
if(a[k][2]=='$') follow(a[i][0]);
else if(islower(a[k][2]))f[m++]=a[k][2];
else first(a[k][2]);
}
}

Output
Program: 7

Aim: Write a program for operator Precedence Parser.


#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
int getOperatorPosition(char );
#define node struct tree1
int matrix[5][5]={
{1,0,0,1,1},
{1,1,0,1,1},
{0,0,0,2,3},
{1,1,3,1,1},
{0,0,0,3,2}};
int tos=-1;
void matrix_value(void);
node create_node(char,node *);
void show_tree( node *);
int isOperator(char );
struct tree1
{
char data;
node *lptr;
node *rptr;
}*first;
struct opr
{
char op_name;
node *t;
}oprate[50];
char cur_op[5]={'+','*','(',')','['};
char stack_op[5]={'+','*','(',')',']'};
void main()
{
char exp[10];

int ssm=0,row=0,col=0;
node *temp;
clrscr();

printf("Enter Exp : ");


scanf("%s",exp);

matrix_value();
while(exp[ssm] != '\0')
{
if(ssm==0)
{
tos++;
oprate[tos].op_name = exp[tos];
}
else
{
if(isOperator(exp[ssm]) == -1)
{
oprate[tos].t = (node*) malloc (sizeof(node));
oprate[tos].t->data = exp[ssm];
oprate[tos].t->lptr = '\0';
oprate[tos].t->rptr = '\0';
}
else
{
row = getOperatorPosition(oprate[tos].op_name);
col = getOperatorPosition(exp[ssm]);
if(matrix[row][col] == 0)
{
tos++;
oprate[tos].op_name = exp[ssm];
}
else if(matrix[row][col] == 1)
{
temp = (node*) malloc (sizeof(node));
temp->data = oprate[tos].op_name;
temp->lptr = (oprate[tos-1].t);
temp->rptr = (oprate[tos].t);
tos--;
oprate[tos].t = temp;
ssm--;
}
else if(matrix[row][col] == 2)
{
//temp = (node*) malloc (sizeof(node));
temp = oprate[tos].t;
tos--;
oprate[tos].t = temp;
}
else if(matrix[row][col] == 3)
{
printf("\nExpression is Invalid...\n");
printf("%c %c can not occur simultaneously\n",oprate[tos].op_name,exp[ssm]);
break;
}
}
}

ssm++;
}
printf("show tree \n\n\n");
show_tree(oprate[tos].t);
printf("Over");
getch();
getch();
}

int isOperator(char c)
{
int i=0;
for(i=0;i<5;i++)
{
if (c==cur_op[i] || c==stack_op[i])
break;
}

if(i==5)
return (-1);
else return i;
}

int getOperatorPosition(char c)
{
int i;
for(i=0;i<5;i++)
{
if (c==cur_op[i] || c==stack_op[i])
break;
}
return i;

void show_tree(node *start)


{
if(start->lptr != NULL)
show_tree(start->lptr);

if(start->rptr != NULL)
show_tree(start->rptr);

printf("%c \n",start->data);
}

void matrix_value(void)
{
int i,j;
printf("OPERATOR PRECEDENCE MATRIX\n");
printf("===========================\n ");

for(i=0; i<5; i++)


{
printf("%c ",stack_op[i]);
}
printf("\n");

for(i=0;i<5;i++)
{
printf("%c ",cur_op[i]);
for(j=0;j<5;j++)
{
if(matrix[i][j] == 0)
printf("< ");
else if(matrix[i][j] == 1)
printf("> ");
else if(matrix[i][j] == 2)
printf("= ");
else if(matrix[i][j] == 3)
printf(" ");
}
printf("\n");
}
}

Output
Program: 8

Aim: Write a program to remove left recursion.


#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;

//Display of Output

cout<<"\n\n********************************";

cout<<"\n AFTER LEFT FACTORING ";

cout<<"\n********************************";

cout<<endl;

for(int cnt3=0;cnt3<=b;cnt3++)

cout<<"Production "<<cnt3+1<<" is: ";

cout<<prodn_new[cnt3].lf;

cout<<"->";

cout<<prodn_new[cnt3].rt;

cout<<endl<<endl;

for(int cnt4=0;cnt4<n;cnt4++)

if(prodn[cnt4].fl==0)

cout<<"Production "<<cnt3++<<" is: ";

cout<<prodn[cnt4].lf;

cout<<"->";

cout<<prodn[cnt4].rt;

cout<<endl<<endl;
}

getch();

} //end of main program

Output
Program: 9

Aim: Write a program to remove left factoring.


#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;

//Display of Output

cout<<"\n\n********************************";

cout<<"\n AFTER LEFT FACTORING ";

cout<<"\n********************************";

cout<<endl;

for(int cnt3=0;cnt3<=b;cnt3++)

cout<<"Production "<<cnt3+1<<" is: ";

cout<<prodn_new[cnt3].lf;

cout<<"->";

cout<<prodn_new[cnt3].rt;

cout<<endl<<endl;

for(int cnt4=0;cnt4<n;cnt4++)

if(prodn[cnt4].fl==0)

cout<<"Production "<<cnt3++<<" is: ";

cout<<prodn[cnt4].lf;

cout<<"->";

cout<<prodn[cnt4].rt;

cout<<endl<<endl;
}

getch();

Output
Program: 10

Aim: Write a program to generate parse tree.


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include<conio.h>
#include<graphics.h>
char next;
void E(void);
void T(void);
void S(void);
void F(void);
void error(int);
void scan(void);
void enter(char);
void leave(char);
void spaces(int);
int level =0;
void main(void)
{
clrscr();
printf(" The Productions are:\n E-->E+T/T\n T-->T*F/F\n F-->id");
printf(“\nEnter The Expression:”);
scan();
printf(“\n*******Parse Tree*******”);
E();
if (next != '#')
error(1);
getch();
}
void E(void)
{
enter('E');
T();
while (next == '+' || next == '-')
{
scan();
T();
}
leave('E');
}
void T(void)
{
enter('T');
S();
while (next == '*' || next == '/')
{
scan();
S();
}
leave('T');
}
void S(void)
{
enter('S');
F();
if (next == '^')
{
scan();
S();
}
leave('S');
}
void F(void)
{
enter('F');
if (isalpha(next))
{
scan();
}
else
if (next == '(')
{
scan();
E();
if (next == ')')
scan();
else
error(2);
}
else
{
error(3);
}
leave('F');
}
void scan(void)
{
while (isspace(next = getchar())); }
void error(int n)
{
printf("\n*** ERROR: %i\n", n);
exit(1);
}
void enter(char name)
{
spaces(level++);
printf("+-%c\n", name);
}
void leave(char name)
{
spaces(--level);
printf("+-%c\n", name);
}
void spaces(int local_level)
{ while (local_level-- > 0)
printf("| ");}
Output
Output
Output
Output

You might also like