CD Manual r20

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 34

1 Write a Lex program to implement a Lexical Analyzer using LEX-tool.

2 Write a C Program to simulate Lexical Analyzer to validate a given input string.

3 Write a C Program to implement Brute force technique of Top down parsing.

4 Write a C Program to compute the First and Follow sets for the given Grammar.

5 Write a C Program to check the validity of input string using predictive parser.

6 Write a C program to implement LR Parser to accept the given input string.

7 Simulate the calculator using LEX and YACC tool.

8 Write a C program to implement Code Generation Algorithm for a given expression.

PART B
Write a Lex program to implement a Lexical Analyzer using LEX-tool.
Step1: Lex program contains three sections: definitions, rules, and user subroutines. Each
section must be separated from the others by a line containing only the delimiter, %%.
The format is as follows: definitions %% rules %% user_subroutines

Step2: In definition section, the variables make up the left column, and their definitions
make up the right column. Any C statements should be enclosed in %{..}%. Identifier is
defined such that the first letter of an identifier is alphabet and remaining letters are
alphanumeric.

Step3: In rules section, the left column contains the pattern to be recognized in an input
file to yylex(). The right column contains the C program fragment executed when that
pattern is recognized. The various patterns are keywords, operators, new line character,
number, string, identifier, beginning and end of block, comment statements, preprocessor
directive statements etc.

Step4: Each pattern may have a corresponding action, that is, a fragment of C source code
to execute when the pattern is matched.

Step5: When yylex() matches a string in the input stream, it copies the matched text to an
external character array, yytext, before it executes any actions in the rules section.

Step6: In user subroutine section, main routine calls yylex(). yywrap() is used to get more
input.
Step7: The lex command uses the rules and actions contained in file to generate a
program, lex.yy.c, which can be compiled with the cc command. That program can then
receive input, break the input into the logical pieces defined by the rules in file, and run
program fragments contained in the actions in file.

//Implementation of Lexical Analyzer using Lex tool


%{
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int |
float |
char |
double |
while |
for |
struct |
typedef |
do |
if |
break |
continue |
void |
switch |
return |
else |
goto {printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("BLOCK ENDS ");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",yytext);}
\".*\" {if(!COMMENT)printf("\n\t %s is a STRING",yytext);}
[0-9]+ {if(!COMMENT) printf("\n %s is a NUMBER ",yytext);}
\)(\:)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t %s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc, char **argv)
{
FILE *file;
file=fopen("var.c","r");
if(!file)
{
printf("could not open the file");
exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}

INPUT:
//var.c
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
OUTPUT:
EX-2

Write a C Program to simulate Lexical Analyzer to validate a given input string


%{
int len=0;
%}

// Rules to identify if a character apart from alphabets


// occurs in a string

%%
[a-zA-Z]+ {printf("No character other than alphabets");}

/* here . will match any other character than alphabets


because alphabets are already matched above
* will matches 0 or more characters in front of it.
*/

.* {printf("character other than alphabets present"); }


%%

// code section
int yywrap() { }
int main()
{
yylex();
return 0;
}

Ex-3

Write a C Program to implement Brute force technique of Top down parsing.

/* Program to Implement Recursive Descent Parsing */

#include<stdio.h>

//#include<conio.h>

#include<string.h>

char input[100];

int i,l;

int main()

printf("recursive decent parsing for the grammar");

printf("\n E->TEP|\nEP->+TEP|@|\nT->FTP|\nTP->*FTP|@|\nF->(E)|ID\n");

printf("enter the string to check:");

scanf("%s",input);

if(E()){

if(input[i]=='$')

printf("\n string is accepted\n");

else

printf("\n string is not accepted\n");

}
}

E(){

if(T()){

if(EP())

return(1);

else

return(0);

else

return(0);

EP(){

if(input[i]=='+'){

i++;

if(T()){

if(EP())

return(1);

else

return(0);

else

return(1); }}

T(){

if(F()){

if(TP())

return(1);
else

return(0); }

else

return(0);

printf("String is not accpeted\n");

TP(){

if(input[i]=='*'){

i++;

if(F()){

if(TP())

return(1)

else

return(0); }

else

return(0);

printf("The string is not accepted \n");

else

return(1); }

F(){

if(input[i]=='('){

i++;

if(E()){

if(input[i]==')'){
i++;

return(1); }

else

return(0);

printf("String is not accepted\n");

else

return(0);

else

if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')

i++;

return(1);

else

return(0);

}
OUTPUT:

$ cc rdp.c

$ ./a.out

recursive decent parsing for the grammar

E->TEP|

EP->+TEP|@|
T->FTP|

TP->*FTP|@|

F->(E)|ID

enter the string to check:(i+i)*i

string is accepted

EX-4

Write a C Program to compute the First and Follow sets for the given Grammar.

// C program to calculate the First and

// Follow sets of a given grammar

#include<stdio.h>

#include<ctype.h>

#include<string.h>

// Functions to calculate Follow

void followfirst(char, int, int);

void follow(char c);

// Function to calculate First

void findfirst(char, int, int);

int count, n = 0;

// Stores the final result

// of the First Sets

char calc_first[10][100];
// Stores the final result

// of the Follow Sets

char calc_follow[10][100];

int m = 0;

// Stores the production rules

char production[10][10];

char f[10], first[10];

int k;

char ck;

int e;

int main(int argc, char **argv)

int jm = 0;

int km = 0;

int i, choice;

char c, ch;

count = 8;

// The Input grammar

strcpy(production[0], "E=TR");
strcpy(production[1], "R=+TR");

strcpy(production[2], "R=#");

strcpy(production[3], "T=FY");

strcpy(production[4], "Y=*FY");

strcpy(production[5], "Y=#");

strcpy(production[6], "F=(E)");

strcpy(production[7], "F=i");

int kay;

char done[count];

int ptr = -1;

// Initializing the calc_first array

for(k = 0; k < count; k++) {

for(kay = 0; kay < 100; kay++) {

calc_first[k][kay] = '!';

int point1 = 0, point2, xxx;

for(k = 0; k < count; k++)

c = production[k][0];
point2 = 0;

xxx = 0;

// Checking if First of c has

// already been calculated

for(kay = 0; kay <= ptr; kay++)

if(c == done[kay])

xxx = 1;

if (xxx == 1)

continue;

// Function call

findfirst(c, 0, 0);

ptr += 1;

// Adding c to the calculated list

done[ptr] = c;

printf("\n First(%c) = { ", c);

calc_first[point1][point2++] = c;

// Printing the First Sets of the grammar

for(i = 0 + jm; i < n; i++) {


int lark = 0, chk = 0;

for(lark = 0; lark < point2; lark++) {

if (first[i] == calc_first[point1][lark])

chk = 1;

break;

if(chk == 0)

printf("%c, ", first[i]);

calc_first[point1][point2++] = first[i];

printf("}\n");

jm = n;

point1++;

printf("\n");

printf("-----------------------------------------------\n\n");
char donee[count];

ptr = -1;

// Initializing the calc_follow array

for(k = 0; k < count; k++) {

for(kay = 0; kay < 100; kay++) {

calc_follow[k][kay] = '!';

point1 = 0;

int land = 0;

for(e = 0; e < count; e++)

ck = production[e][0];

point2 = 0;

xxx = 0;

// Checking if Follow of ck

// has already been calculated

for(kay = 0; kay <= ptr; kay++)

if(ck == donee[kay])
xxx = 1;

if (xxx == 1)

continue;

land += 1;

// Function call

follow(ck);

ptr += 1;

// Adding ck to the calculated list

donee[ptr] = ck;

printf(" Follow(%c) = { ", ck);

calc_follow[point1][point2++] = ck;

// Printing the Follow Sets of the grammar

for(i = 0 + km; i < m; i++) {

int lark = 0, chk = 0;

for(lark = 0; lark < point2; lark++)

if (f[i] == calc_follow[point1][lark])

{
chk = 1;

break;

if(chk == 0)

printf("%c, ", f[i]);

calc_follow[point1][point2++] = f[i];

printf(" }\n\n");

km = m;

point1++;

void follow(char c)

int i, j;

// Adding "$" to the follow

// set of the start symbol


if(production[0][0] == c) {

f[m++] = '$';

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

for(j = 2;j < 10; j++)

if(production[i][j] == c)

if(production[i][j+1] != '\0')

// Calculate the first of the next

// Non-Terminal in the production

followfirst(production[i][j+1], i, (j+2));

if(production[i][j+1]=='\0' && c!=production[i][0])

// Calculate the follow of the Non-Terminal

// in the L.H.S. of the production

follow(production[i][0]);
}

void findfirst(char c, int q1, int q2)

int j;

// The case where we

// encounter a Terminal

if(!(isupper(c))) {

first[n++] = c;

for(j = 0; j < count; j++)

if(production[j][0] == c)

if(production[j][2] == '#')

if(production[q1][q2] == '\0')
first[n++] = '#';

else if(production[q1][q2] != '\0'

&& (q1 != 0 || q2 != 0))

// Recursion to calculate First of New

// Non-Terminal we encounter after epsilon

findfirst(production[q1][q2], q1, (q2+1));

else

first[n++] = '#';

else if(!isupper(production[j][2]))

first[n++] = production[j][2];

else

// Recursion to calculate First of

// New Non-Terminal we encounter

// at the beginning
findfirst(production[j][2], j, 3);

void followfirst(char c, int c1, int c2)

int k;

// The case where we encounter

// a Terminal

if(!(isupper(c)))

f[m++] = c;

else

int i = 0, j = 1;

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

if(calc_first[i][0] == c)

break;

}
//Including the First set of the

// Non-Terminal in the Follow of

// the original query

while(calc_first[i][j] != '!')

if(calc_first[i][j] != '#')

f[m++] = calc_first[i][j];

else

if(production[c1][c2] == '\0')

// Case where we reach the

// end of a production

follow(production[c1][0]);

else

// Recursion to the next symbol


// in case we encounter a "#"

followfirst(production[c1][c2], c1, c2+1);

j++;

Output :

First(E)= { (, i, }
First(R)= { +, #, }
First(T)= { (, i, }
First(Y)= { *, #, }
First(F)= { (, i, }

-----------------------------------------------

Follow(E) = { $, ), }
Follow(R) = { $, ), }
Follow(T) = { +, $, ), }
Follow(Y) = { +, $, ), }
Follow(F) = { *, +, $, ), }
Ex-5

Write a C Program to check the validity of input string using predictive parser.

/* Program to Implement Predictive Parsing */

#include<stdio.h>

#include<string.h>

int spt=0,ipt=0;

char s[20],ip[15];

char *m[5][6]={{"TG","\0","\0","TG","\0","\0"},{"\0","+TG","\0","\0","e","e"},{"FH","\0","\
0","FH","\0","\0"},{"\0","e","FH","\0","e","e"},{"i","\0","\0","(E)","\0","\0"}};

char nt[5]={'E','G','T','H','F'};

char t[6]={'i','+','*','(',')','$'};

int nti(char c) {

int i;

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

if(nt[i]==c)

return(i); }

return(6); }

int ti(char c) {

int i;

for(i=0;i<6;i++) {

if(t[i]==c)

return(i); }

return(7); }

int main()
{

char prod[4],temp[4];

int l,k,j;

printf(

"enter input string:");

scanf("%s",ip);

strcat(ip,"$");

s[0]='$';

s[1]='E';

s[2]='\0';

spt=1;

while(1) {

if(ip[ipt]=='$'&&s[spt]=='$')

break;

if(ti(s[spt])<5||s[spt]=='$') {

if(s[spt]==ip[ipt]) {

spt--

ipt++; }

else

error();

else if(nti(s[spt]<6))

{
py(prod,m[nti(s[spt])][ti(ip[ipt])]);

if(prod=='\0')

perror();

l=strlen(prod);

for(k=l

-1,j=0;k>=0&&j<=l;k--,j++)

temp[j]=prod[k];

for(k=0;k<l;k++)

prod[k]=temp[k];

s[spt--]='\0';

strcat(s,prod);

spt=spt+l;

if(s[spt]=='e')

s[spt--]='\0';

else

error(); }

if(s[spt]=='$'&&ip[ipt]=='$')

printf("\n input is parsed \n");

else

error();

return 0; }

error()

printf("input is not parsed\n");

exit(1);
return 0;

$ cc preparsing.c

$ ./a.out

enter input string:i+i*i$

input is parsed

Ex-6

Write a C program to implement LR Parser to accept the given input string.

#include<stdio.h>

#include<string.h>

char s[30],stack[20];

int main()

char m[5][6][3]={{"tb"," "," ","tb"," "," "},

{" ","+tb"," "," ","n","n"},

{"fc"," "," ","fc"," "," ",},

{" ","n","*fc"," ","n","n"},

{"d"," "," ","(e)"," "," "}};

int size[5][6]={2,0,0,2,0,0,0,3,0,0,1,1,2,0,0,2,0,0,0,1,3,0,1,1,1,0,0,3,0,0};

int i,j,k,n,str1,str2;

printf("\n enter the input string:");

scanf("%s",s);

strcat(s,"$");

n=strlen(s);

stack[0]='$';
stack[1]='e';

i=1;

j=0;

printf("\n stack input\n");

printf("\n");

while((stack[i]!='$')&&(s[j]!='$'))

if(stack[i]=s[j])

i--;

j++;

switch(stack[i])

case 'e':str1=0;

break;

case 'b':str1=1;

break;

case 't':str1=2;

break;

case 'c':str1=3;

break;

case 'f':str1=4;

break; }

switch(s[j]) {

case 'd':str2=0;

break;
case '+':str2=1;

break;

case '*':str2=2;

break;

case '(':str2=3;

break;

case ')':str2=4;

break;

case '$':str2=5;

break; }

if(m[str1][str2][0]=='$') {

printf("\n error\n");

return(0); }

else if(m[str1][str2][0]='n') i--;

else if(m[str1][str2][0]='i')

stack[i]='d';

else {

for(k=size[str1][str2]

-1;k>=0;k--

stack[i]=m[str1][str2][k];

i++; }i--; }

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

printf("%c",stack[k]);

printf(" ");

for(k=j;k<=n;k++)
printf("%c",s[k]);

printf("\n");

printf("\n SUCCESS");

OUTPUT: $ cc ll1parsing.c

$ ./a.out

enter the input string:i+i*i

stack input +i*i$

i*i$

*i$

i$

$ SUCCESS

Ex-2:

faculty@pec-server:~$ ./a.out

enter the input string:i+i*i

stack input

+i*i$
i*i$
*i$
i$
$

SUCCESSfaculty@pec-server:~$ ./a.out

enter the input string:ii

stack input

Segmentation fault (core dumped)


faculty@pec-server:~$

Ex-3
faculty@pec-server:~$ ./a.out

enter the input string:i/i

stack input

Segmentation fault (core dumped)


faculty@pec-server:~$ ./a.out

enter the input string:i+i

stack input

+i$
i$
$

Ex-7
Simulate the calculator using LEX and YACC tool

Yacc program

%{
#include<ctype.h>
#include<stdio.h>
#define YYSTYPE double
%}
%token NUMBER
%left'+''-'
%left'*''/'
%right UMINUS
%%
lines:lines expr'\n'
{
printf("%g\n",$2);}
|lines'\n'
|/*E*/
;
expr:expr'+'expr{$$=$1+$3;}
|expr'-'expr{$$=$1-$3;}
|expr'*'expr{$$=$1*$3;}
|expr'/'expr{$$=$1/$3;}
|'('expr')'{$$=$2;}
|'-'expr%prec UMINUS{$$=-$2;}
|NUMBER
;
%%
yylex() {
int c;
while((c=getchar())==' ')
;
if((c=='.')||(isdigit(c
))){
ungetc(c,stdin);
scanf("%lf",&yylval);
return NUMBER; }
return c; }
int main() {
yyparse();
return 1; }
int yyerror() {
return 1; }
int yywrap() {
return 1;
}
OUTPUT : $ yacc calc.y
$ gcc -o calc y.tab.c
$ ./calc 1+2/3*6 5

Ex-8
Write a C program to implement Code Generation Algorithm for a given expression.

Code generator
/* Program to Implement Code Generation */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int label[20];
int no=0;
int main() {
FILE *fp1,*fp2;
char fname[10],op[10],ch;
char operand1[8],operand2[8],result[8];
int i=0,j=0;
printf("\n enter the filename of intermediate code\n");
scanf("%s",fname);
fp1=fopen(fname,"r");
fp2=fopen("target.txt","w");
if(fp1==NULL||fp2==NULL) {
printf("\n error opening the file");
exit(0);
}
while(!feof(fp1)) {
fprintf(fp2,"\n");
fscanf(fp1,"%s",op);
i++;
if(check_label(i))
fprintf(fp2,"\nlabel#%d",i);
if(strcmp(op,"print")==0) {
fscanf(fp1,"%s",result);
fprintf(fp2,"\n\tOUT%s",result);
}
if(strcmp(op,"goto")==0) {
fscanf(fp1,"%s%s",operand1,operand2);
label[no++]=atoi(operand2); }
if(strcmp(op,"[]=")==0) {
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\tSTORE%s[%s],%s",operand1,operand2,result);
}
if(strcmp(op,"uminus")==0)
{
fscanf(fp1,"%s,%s",operand1,result);
fprintf(fp2,"\n\t,LOAD%s",operand1);
fprintf(fp2,"\n\tSTORE R1,%s",result);
}
switch(op[0])
{
case '*':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD",operand1);
fprintf(fp2,"\n\t LOAD %s,R1",operand2);
fprintf(fp2,"\n\t MUL R1,R0");
fprintf(fp2,"\n\t STORE R0,%s",result);
break;
case '+':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD%s,R0",operand1);
fprintf(fp2,"\n\t LOAD %s,R1",operand2);
fprintf(fp2,"\n\t ADD R1,R0");
fprintf(fp2,"\n\t STORE R0,%s",result);
break;
case '-':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD%s,R0",operand1);
fprintf(fp2,"\n\t LOAD %s,R1",operand2);
fprintf(fp2,"\n\t SUB R1,R0");
fprintf(fp2,"\n\t STORE R0,%s",result);
break;
case '/':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD%s,R0",operand1);
fprintf(fp2,"\n\t LOAD %s,R1",operand2);
fprintf(fp2,"\n\t DIV R1,R0");
fprintf(fp2,"\n\t STORE R0,%s",result);
break;
case '=':
fscanf(fp1,"%s%s",operand1,result);
fprintf(fp2,"\n\t STORE %s%s",operand1,result);
break;
case '>':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD%s,R0",operand1);
fprintf(fp2,"\n\t JGT%S,label#%s",operand2,result);
label[no++]=atoi(result);
break;
case '<':
fscanf(fp1,"%s%s%s",operand1,operand2,result);
fprintf(fp2,"\n\t LOAD%s,R0",operand1);
fprintf(fp2,"\n\t JLT%s,label#%s",operand2,result);
label[no++]=atoi(result);
break; }}
fclose(fp2);
fclose(fp1);
fp2=fopen("target.txt","r");
if(fp2==NULL) {
printf("error opening in file\n");
exit(0); }
do{
ch=fgetc(fp2);
printf("%c",ch); }
while(ch!=EOF);
fclose(fp1);
return 0; }
int check_label(int k) {
int i;
for(i=0;i<no;i++) {
if(k==label[i])
return 1;
}
return 0;
}

faculty@pec-server:~$ vi code1.c
faculty@pec-server:~$ gcc code1.c
faculty@pec-server:~$ ./a.out

enter the filename of intermediate code


input.txt

LOADt2,R0
LOAD t2,R1
DIV R1,R0
STORE R0,uminus

OUTt2

LOADt3,R0
LOAD t4,R1
ADD R1,R0
STORE R0,print

ÿfaculty@pec-server:~$vi target.txt

LOADt2,R0
LOAD t2,R1
DIV R1,R0
STORE R0,uminus

OUTt2

LOADt3,R0
LOAD t4,R1
ADD R1,R0
STORE R0,print

You might also like