0% found this document useful (0 votes)
40 views55 pages

BDA Assignment

The document discusses implementing string validation and finite automata using C programming. It includes code for validating if a string is a valid identifier by checking the characters. It also includes code to generate random strings and check if they start and end with 'b' using finite automata concepts. Finally, it discusses the Lex and Flex tools for generating scanners/lexical analyzers by specifying regular expressions and actions. It provides examples of using Lex to generate a histogram of words in a file, implement a Caesar cipher, and extract comments from C code.

Uploaded by

v.tofficial TV
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views55 pages

BDA Assignment

The document discusses implementing string validation and finite automata using C programming. It includes code for validating if a string is a valid identifier by checking the characters. It also includes code to generate random strings and check if they start and end with 'b' using finite automata concepts. Finally, it discusses the Lex and Flex tools for generating scanners/lexical analyzers by specifying regular expressions and actions. It provides examples of using Lex to generate a histogram of words in a file, implement a Caesar cipher, and extract comments from C code.

Uploaded by

v.tofficial TV
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

PSE / CE / CD (3170701) Enrollment no.

201120107070

PRACTICAL: 01
AIM: Implementation of Finite Automata and String Validation

String Validation:
#include <bits/stdc++.h>
using namespace std;

// Function that returns true if str


// is a valid identifier
bool isValid(string str, int n)
{

// If first character is invalid


if (!((str[0] >= 'a' && str[0] <= 'z')
|| (str[0] >= 'A' && str[0] <= 'Z')
|| str[0] == '_'))
return false;

// Traverse the string for the rest of the characters


for (int i = 1; i < str.length(); i++) {
if (!((str[i] >= 'a' && str[i] <= 'z')
|| (str[i] >= 'A' && str[i] <= 'Z')
|| (str[i] >= '0' && str[i] <= '9')
|| str[i] == '_'))
return false;
}

// String is a valid identifier


1|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

return true;
}

// Driver code
int main()
{
string str = "pacific";
int n = str.length();

if (isValid(str, n))
cout <<"Valid";

else
cout << "Invalid";

return 0;
}

2|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

Finite automata
//to find a string starts and ends with b
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int generate_fxn(int maxi){
int x = 0;
while (x < maxi) {
char word = 'a' + rand() % 2; //generate first word of string
cout << word << " ";
x++;

// if the first character is 'b'


if (word == 'b') {
if (x == maxi) //checks if it has only one word then print yes
cout << "YES\n";

while (x < maxi) { //else generate the full string


word = 'a' + rand() % 2;
cout << word << " ";
x++;

if (word == 'b' && x == maxi) { //if it is the last character and 'b'
cout << "\nYes, it satisfies the condition\n";
}
else if (x == maxi) {
cout << "\nNO\n";

3|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

}
}
}
else { //if it does not start with 'b' then print NO
while (x < maxi) {
word = 'a' + rand() % 2;
cout << word << " ";
x++;
}
cout << "\nNo, it doesn't satisfy the condition\n";
}
}
return 0;
}

int main()
{
//srand is used to produce diffent random number each time you compile.
srand(time(0));

int maxi = 1 + rand() % 10; // we are generating random number from 1-10
generate_fxn(maxi);
return 0;
}

4|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

5|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 02
AIM: Introduction to Lex Tool.

LEX: A Scanner Generator


Lex is a program designed to generate scanners, also known as tokenizes, which recognize lexical
patterns in text. Lex is an acronym that stands for "lexical analyser generator." It is intended primarily
for Unix-based systems.

Helps write programs whose control flow is directed by in-stances of regular expressions in the
input stream.

Table of regular expressions

+ associated actions

Lex

Output: C code implementing a scanner:

6|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

function: yylex()
file: lex.yy.c

yylex() :

– matches the input stream against the table of regularexpressions supplied

– carries out the associated action when a match is found.

FLEX:

Flex (fast lexical analyser generator) is a free and open-source software alternative to Lex. It is a
computer program that generates lexical analysers.It is a tool for generating programs that perform
pattern-matching on text

FLEX is generally used in the manner depicted here:

First, FLEX reads a specification of a scanner either from an input file *.l, or from standard input,
and it generates as output a C source file lex.yy.c. Then, lex.yy.c is compiled and to produce an
executable a.exe.
Finally,a.exe analyses its input stream and transforms it into a sequence of tokens.

*.l is in the form of pairs of regular expressions and C code. (sample1.l, sample2.l)
lex.yy.c defines a routine yylex() that uses the specification to recognize tokens.
a.exe is actually the scanner.

Flex specifications Lex source:


{Definitions}
%% {Rules} %%
{user subroutines }

7|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

Installation Step:

1. flex-2.5.4a-1.exe
2. bison-2.4.1-setup.exe
3. After that, do a full install in a directory of your preference without spaces in the name. I
suggest C:\GnuWin32. Do not install it in the default (C:\Program Files (x86)\GnuWin32)
because bison has problems with spaces in directory names, not to say parenthesis.
4. Also, consider installing Dev-CPP in the default directory (C:\Dev-Cpp)
5. After that, set the PATH variable to include the bin directories of gcc (in C:\Dev-Cpp\bin)
and flex\bison (in C:\GnuWin32\bin).
6. To do that, copy this: ;C:\Dev-Cpp\bin;C:\GnuWin32\bin and append it to the end of the
PATH variable, defined in the place show by this figure:

7. Open a prompt, cd to the directory where your ".l" and ".y" are, and compile them with:
I have a flex file name Hello.l in the location C:\lexyacc

---------------------------------------
commands for flex:
---------------------------------------

to build type : [for the lex file being count.l]


flex count.l
to compile type :
gcc lex.yy.c

8|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

to run/execute type:
a.exe
Example:

counter.l

%{
#include<stdio.h>
int lines=0, words=0,s_letters=0,c_letters=0, num=0, spl_char=0,total=0;

%}

%%
\n { lines++; words++;}
[\t ' '] words++;
[A-Z] c_letters++;
[a-z] s_letters++;
[0-9] num++;
. spl_char++;
%%

main(void)
{
yyin= fopen("myfile.txt","r");
yylex();
total=s_letters+c_letters+num+spl_char;
printf(" This File contains ...");
printf("\n\t%d lines", lines);
printf("\n\t%d words",words);
printf("\n\t%d small letters", s_letters);
printf("\n\t%d capital letters",c_letters);
printf("\n\t%d digits", num);
printf("\n\t%d special characters",spl_char);
printf("\n\tIn total %d characters.\n",total);
}

int yywrap()
{
9|Page
PSE / CE / CD (3170701) Enrollment no. 201120107070

return(1);
}

OUTPUT:

myfile.txt:
This is my 1st lex program!!!
Cheers!! It works!!:)

The output will be

This file contains.


2 lines
9 words
30 small letters
3 capital letters
1 digits
9 special characters
In total 43 characters.

10 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 03
AIM: Implement following Programs Using Lex.
a. Generate Histogram of words
b. Ceasor Cypher
c. Extract single and multiline comments from C Program

a. Generate Histogram of words


%{
#include<stdio.h>
/*Global variables*/
int tchar=0,tword=0,tspace=0;
%}
/*Rule Section*/
%%
/*Increase the tspace and tword whenever encounter whitespace.*/
" " {tspace++;tword++;}

/*Increase the tword whenever encounter newline character and tab mate
character.*/
[\t\n] tword++;
[^\n\t] tchar++;

%%
/*call the yywrap function*/
int yywrap()

{
return 1;

11 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

}
int main()
{
yyin=fopen("q4.txt","r");
/*call the yylex function.*/
yylex();

printf("Number of character:: %d\nNumber of words::


%d\nNumber of spaces:: %d\n",tchar,tword,tspace);
return 0;

Input:

Output:

12 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

b. Ceasor Cypher

%%
[a-z] {char ch = yytext[0];ch += 3;
if (ch> 'z') ch -= ('z'+1- 'a');printf
("%c" ,ch );
}
[A-Z] { char ch = yytext[0] ;ch += 3;
if (ch> 'Z') ch -= ('Z'+1- 'A');
printf("%c",ch);
}
%%

Output:

13 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

c.Extract single and multiline comments from C Program.

/*Definition Section*/
%{
#include<stdio.h>
%}
/*Rule Section*/
%%
/*Regular expression for single line comment*/
\/\/(.*) {};
/*Regular expression for multi line comment*/
\/\*(.*\n)*.*\*\/ {}
%%
/*call the yywrap function*/ int yywrap()
{
return 1;
}
/*Auxiliary function*/
/*Driver function*/ int main()
{
yyin=fopen("input6.c","r");
yyout=fopen("out.c","w");
/*call the yylex function.*/ yylex();

14 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

return 0;

Input:

Output:

15 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 04
AIM: Implement following Programs Using Lex.
a. Validate Keyword, Number or Word
b. Check weather given statement is compound or simple
c. Extract html tags from .html file

a. Validate Keyword, Number or Word:

%{

#include<stdio.h>
%}
%%
if |
else |
printf printf("%s is a keyword", yytext);
[0-9]+ printf("%s is a number", yytext);
[a-z A-Z]+ printf("%s is a word", yytext);

%%
int main()
{
printf("\n enter the value:");
yylex();
}
int yywrap()
{
return 1;
}

16 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

b. Check weather given statement is compound or simple

%{
#include<stdio.h>
int flag=0;
%}

%%
and |
or |
but |
because |
if |
then |
nevertheless { flag=1; }
. ;
\n { return 0; }
%%

int main()
{
printf("Enter the sentence:\n");
yylex();
if(flag==0)
printf("Simple sentence\n");
else
printf("compound sentence\n");
}

int yywrap( )
{
return 1;
}

17 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

OUTPUT :

18 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

c. Extract html tags from .html file


%{
#include<stdio.h>
%}
%%
\<[^>]*\> fprintf(yyout,"%s\n",yytext);
.|\n;
%%
int yywrap()
{
return 1;
}
int main()
{
yyin=fopen("input7.html","r");

yyout=fopen("output7.txt","w");

yylex();

return 0;
}

19 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Input

Output

20 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 05
AIM: Finding “First” set
Input: The string consists of grammar symbols.Output: The
First set for a given string.
Explanation:
The student has to assume a typical grammar. The program when run will ask for the string
to be entered. The program will find the First set of the given string.

#include<stdio.h>

#include<ctype.h>

void FIRST(char );

int count,n=0;

char prodn[10][10], first[10];

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]);

21 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

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]);

22 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

OUTPUT:

23 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 06
AIM: Generate 3-tuple intermediate code for given infix expression.

#include<stdio.h>
#include<conio.h>
#include<string.h>
char op[2],arg1[5],arg2[5],result[5];
void main()
{
FILE *fp1,*fp2;
fp1=fopen("input.txt","r");
fp2=fopen("output.txt","w");
while(!feof(fp1))
{

fscanf(fp1,"%s%s%s%s",op,arg1,arg2,result);
if(strcmp(op,"+")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nADD R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"*")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nMUL R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}

24 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

if(strcmp(op,"-")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nSUB R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"/")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nDIV R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"=")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nMOV %s,R0",result);
}
}
fclose(fp1);
fclose(fp2);
getch();
}
}

25 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Output :

26 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 07
AIM: Introduction to YACC and generate Calculator Program.

 A parser generator is a program that takes as input a specification of a syntax,


and produces as output a procedure for recognizing that language.
 Historically, they are also called compiler-compilers.
 YACC (yet another compiler-compiler) is an LALR(1) (LookAhead, Left-to-
right, Rightmost derivation producer with 1 lookahead token) parser
generator. YACC was originally designed for being complemented by Lex.
Input File:
YACC input file is divided into three parts.

/* definitions */

....

%%

/* rules */

....

%%

/* auxiliary routines */
....

27 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Input File: Definition Part:

 The definition part includes information about the tokens used in the syntax definition:

%token NUMBER

%token ID

 Yacc automatically assigns numbers for tokens, but it can be overridden by

%token NUMBER 621

 Yacc also recognizes single characters as tokens. Therefore, assigned token numbers
should not overlap ASCII codes.
 The definition part can include C code external to the definition of the parser and
variable declarations, within %{ and %} in the first column.
 It can also include the specification of the starting symbol in the grammar:

%start nonterminal

Input File: Rule Part:

 The rules part contains grammar definition in a modified BNF form.


 Actions is C code in { } and can be embedded inside (Translation schemes).

28 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Input File: Auxiliary Routines Part:

 The auxiliary routines part is only C code.


 It includes function definitions for every function needed in rules part.

 It can also contain the main() function definition if the parser is going to be run as a
program.
 The main() function must call the function yyparse().

Input File:

 If yylex() is not defined in the auxiliary routines sections, then it should be


included: #include "lex.yy.c"
 YACC input file generally finishes with:
.y

Output Files:

 The output of YACC is a file named y.tab.c

 If it contains the main() definition, it must be compiled to be executable.

 Otherwise, the code can be an external function definition for the function int
yyparse()

 If called with the –d option in the command line, Yacc produces as output a header file
y.tab.h with all its specific definition (particularly important are token definitions to be
included, for example, in a Lex input file). If called with the –v option, Yacc produces as
output a file y.output containing a textual description of the LALR(1) parsing table used by
the parser. This is useful for tracking down how the parser solves conflicts.

29 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Program to generate Calculator :

LEX PART:

%{

#include<stdio.h>

#include "y.tab.h"

extern int yylval;

%}

%%

[0-9]+ {

yylval=atoi(yytext);

return NUMBER;

[\t] ;

[\n] return 0;

. return yytext[0];

%%

int yywrap()

return 1;

YACC PART:

%{

30 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

#include<stdio.h>

int flag=0;

%}

%token NUMBER

%left '+' '-'

%left '*' '/' '%'

%left '(' ')'

%%

ArithmeticExpression: E{

printf("\nResult=%d\n",$$);

return 0;

};

E:E'+'E {$$=$1+$3;}

|E'-'E {$$=$1-$3;}

|E'*'E {$$=$1*$3;}

|E'/'E {$$=$1/$3;}

|E'%'E {$$=$1%$3;}

|'('E')' {$$=$2;}

| NUMBER {$$=$1;}

%%

31 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

void main()

printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");

yyparse();

if(flag==0)

printf("\nEntered arithmetic expression is Valid\n\n");

void yyerror()

printf("\nEntered arithmetic expression is Invalid\n\n");

flag=1;

OUTPUT:

32 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 08
AIM: Finding “Follow” set
Input: The string consists of grammar symbols. Output: The Follow
set for a given string.
Explanation: The student has to assume a typical grammar. The
program when run will ask for the string to be entered. The program
will find the Follow set of the given string.

#include<stdio.h>
#include<string.h>
int n,m=0,p,i=0,j=0;
char
a[10][10],followResult[10]; void
follow(char c);
void first(char c);
void addToResult(char);
int main()
{
int i;
int choice;
char c,ch;
printf("Enter the no.of productions: ");
scanf("%d", &n);
printf(" Enter %d productions\nProduction with multiple terms should be give as separate
productions \n", n);
for(i=0;i<n;i++)
scanf("%s%c",a[i],&ch)
;

33 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

// gets(a[i]);
do
{
m=0;
printf("Find FOLLOW of --
>"); scanf(" %c",&c);
follow(c);
printf("FOLLOW(%c) = {
",c); for(i=0;i<m;i++)
printf("%c
",followResult[i]); printf("
}\n");
printf("Do you want to continue(Press 1 to continue ....)?");
scanf("%d%c",&choice,&ch);
}
while(choice==1);
}
void follow(char c)
{
if(a[0][0]==c)addToResult('$');
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]);
}
}
}
34 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

}
void first(char c)
{
int k;
if(!(isupper(c)))
//f[m++]=c;
addToResult(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];
addToResult(a[k][2]);
else first(a[k][2]);
} }
}
void addToResult(char c)
{
int i;
for( i=0;i<=m;i++)
if(followResult[i]==c)
return;
followResult[m++]=c;
}

35 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

OUTPUT:

36 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 09
AIM: Implement a C program for constructing LL (1) parsing.
GRAMMER:
E->TA
A->+TA|^ T->FB
B->*FB|^
F->t|(E)

#include<stdio.h>
#include<conio.h>
#include<string.h>
char s[20],stack[20];
void main()
{
char m[5][6][3]={"tb"," "," ","tb"," "," "," ","+tb"," "," ","n","n","fc"," "," ","fc"," "," ","
","n","*fc"," a
","n","n","i"," "," ","(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;
clrscr();
printf("\n Enter the input string: ");
scanf("%s",s);
strcat(s,"$");
n=strlen(s);
stack[0]='$';
stack[1]='e';
i=1;
j=0;
printf("\nStack Input\n");

37 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

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 'i': str2=0;
break;
case '+': str2=1;
break;
case '*': str2=2;
break;
case '(': str2=3;
break;
case ')': str2=4;
break;
38 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

case '$': str2=5;


break;
}
if(m[str1][str2][0]=='\0')
{
printf("\nERROR");
exit(0);
}
else if(m[str1][str2][0]=='n')
i--;
else if(m[str1][str2][0]=='i')
stack[i]='i';
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");
getch();
}

39 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

OUTPUT:

40 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 10
AIM: Write a C program for constructing recursive descent
parsing.

#include<stdio.h>
#include<conio.h>
char input[100];
char prod[100][100];
intpos=-1,l,st=-1;
charid,num;
void E();
void T();
void F();
void advance();
void Td();
void Ed();
void advance()
{
pos++;
if(pos<l)
{
if(input[pos]>='0'&& input[pos]<='9')
{
num=input[pos];
id='\0';
}
if((input[pos]>='a' || input[pos]>='A')&&(input[pos]<='z' || input[pos]<='Z'))
{id=input[pos];
num='\0';
}
}
}
void E()

41 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

{
strcpy(prod[++st],"E->TE'");
T();
Ed();
}
void Ed()
{
int p=1;
if(input[pos]=='+')
{
p='+';
strcpy(prod[++st],"E'->+TE'");
advance();
T();
Ed();
}
if(input[pos]=='-')
{ p='-';
strcpy(prod[++st],"E'->-TE'");
advance();
T();
Ed();
}
if(p==1)
{
strcpy(prod[++st],"E'->null");
}
}

void T()
{
strcpy(prod[++st],"T->FT'");
F();
Td();

42 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

}
void Td()
{
int p=1;
if(input[pos]=='*')
{
p='*';
strcpy(prod[++st],"T'->*FT'");
advance();
F();
Td();
}
if(input[pos]=='/')
{ p='/';
strcpy(prod[++st],"T'->/FT'");
advance();
F();
Td();
}
if(p==1)
strcpy(prod[++st],"T'->null");
}
void F()
{
if(input[pos]==id) {
strcpy(prod[++st],"F->id");
advance(); }
if(input[pos]=='(')
{
strcpy(prod[++st],"F->(E)");
advance();
E();
if(input[pos]==')') {
//strcpy(prod[++st],"F->(E)");

43 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

advance(); }
}
if(input[pos]==num)
{
strcpy(prod[++st],"F->num");
advance();
}
}
int main()
{
inti;
clrscr();
printf("Enter Input String ");
scanf("%s",input);
l=strlen(input);
input[l]='$';
advance();
E();
if(pos==l)
{
printf("String Accepted\n");
for(i=0;i<=st;i++)
{
printf("%s\n",prod[i]);
}
}
else
{
printf("String rejected\n");
}
getch();
return 0 ;
}

44 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

Input Grammar:
E-> TE’
E’-> +TE’ | -TE’ | null
T-> FT’
T’-> *FT’| /FT’ | null
F-> id/ (E)/ num

Output:

45 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 11
AIM: Implement a C program to implement LALR parsing.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
void push(char *,int *,char);
charstacktop(char *);
voidisproduct(char,char);
intister(char);
intisnter(char);
intisstate(char);
void error();
voidisreduce(char,char);
char pop(char *,int *);
voidprintt(char *,int *,char [],int);
void rep(char [],int);
struct action
{
char row[6][5];
};
conststruct action A[12]={ {"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
{"sf","emp","emp","se","emp","emp"},
{"emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"} };

46 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

structgotol
{
char r[3][4];
};
conststructgotol G[12]={ {"b","c","d"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"i","c","d"},
{"emp","emp","emp"},
{"emp","j","d"},
{"emp","emp","k"},
{"emp","emp","emp"},
{"emp","emp","emp"}, };
charter[6]={'i','+','*',')','(','$'};
charnter[3]={'E','T','F'};
char states[12]={'a','b','c','d','e','f','g','h','m','j','k','l'};
char stack[100];
int top=-1;
char temp[10];
struct grammar
{
char left;
char right[5];
};
conststruct grammar rl[6]={
{'E',"e+T"}, {'E',"T"},
{'T',"T*F"}, {'T',"F"},
{'F',"(E)"}, {'F',"i"}};
void main()
{
charinp[80],x,p,dl[80],y,bl='a';
inti=0,j,k,l,n,m,c,len;
clrscr();

47 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

printf(" Enter the input :");


scanf("%s",inp);
len=strlen(inp);
inp[len]='$';
inp[len+1]='\0';
push(stack,&top,bl);
printf("\n stack \t\t\t input");
printt(stack,&top,inp,i);
do {
x=inp[i];
p=stacktop(stack);
isproduct(x,p);
if(strcmp(temp,"emp")==0)
error();
if(strcmp(temp,"acc")==0)
break;
else
{
if(temp[0]=='s')
{
push(stack,&top,inp[i]);
push(stack,&top,temp[1]);
i++;
}
else
{
if(temp[0]=='r')
{
j=isstate(temp[1]);
strcpy(temp,rl[j-2].right);
dl[0]=rl[j-2].left;
dl[1]='\0';
n=strlen(temp);
for(k=0;k<2*n;k++)

48 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

pop(stack,&top);
for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]);
l=top;
y=stack[l-1];
isreduce(y,dl[0]);
for(m=0;temp[m]!='\0';m++)
push(stack,&top,temp[m]);
}
}
}
printt(stack,&top,inp,i);
}
while(inp[i]!='\0');
if(strcmp(temp,"acc")==0)
printf(" \n accept the input ");
elseprintf(" \n do not accept the input ");
getch();
}

void push(char *s,int *sp,char item)


{
if(*sp==100)
printf(" stack is full ");
else
{
*sp=*sp+1;
s[*sp]=item;
}
}
charstacktop(char *s)
{
char i;
i=s[top];

49 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

return i;
}
voidisproduct(char x,char p)
{
intk,l;
k=ister(x);
l=isstate(p);
strcpy(temp,A[l-1].row[k-1]);
}
intister(char x)
{
inti;
for(i=0;i<6;i++)
if(x==ter[i])
return i+1;
return 0;
}
intisnter(char x)
{
inti;
for(i=0;i<3;i++)
if(x==nter[i])
return i+1;
return 0;
}
intisstate(char p)
{
inti;
for(i=0;i<12;i++)
if(p==states[i])
return i+1;
return 0;
}
void error()

50 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

{
printf(" error in the input ");
exit(0);
}
voidisreduce(char x,char p)
{
intk,l;
k=isstate(x);
l=isnter(p);
strcpy(temp,G[k-1].r[l-1]);
}
char pop(char *s,int *sp)
{
char item;
if(*sp==-1)
printf(" stack is empty ");
else
{
item=s[*sp];
*sp=*sp-1;
}
return item;
}
voidprintt(char *t,int *p,charinp[],int i)
{
int r;
printf("\n");
for(r=0;r<=*p;r++)
rep(t,r);
printf("\t\t\t");
for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
}
void rep(char t[],int r)

51 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

{
char c;
c=t[r];
switch(c)
{
case 'a': printf("0");
break;
case 'b': printf("1");
break;
case 'c': printf("2");
break;
case 'd': printf("3");
break;
case 'e': printf("4");
break;
case 'f': printf("5");
break;
case 'g': printf("6");
break;
case 'h': printf("7");
break;
case 'm': printf("8");
break;
case 'j': printf("9");
break;
case 'k': printf("10");
break;
case 'l': printf("11");
break;
default :printf("%c",t[r]);
break;
}
}

52 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

OUTPUT

Input Grammar:

E->E+T
E->T
T->T*F
T->F
F->(E)
F->I

53 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

PRACTICAL: 12
AIM: Write a C program to implement operator precedence
parsing.
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

// function f to exit from the loop


// if given condition is not true
void f()
{
printf("Not operator grammar");
exit(0);
}

void main()
{
char grm[20][20], c;

// Here using flag variable,


// considering grammar is not operator grammar
int i, n, j = 2, flag = 0;

// taking number of productions from user


scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%s", grm[i]);

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


c = grm[i][2];

54 | P a g e
PSE / CE / CD (3170701) Enrollment no. 201120107070

while (c != '\0') {

if (grm[i][3] == '+' || grm[i][3] == '-'


|| grm[i][3] == '*' || grm[i][3] == '/')

flag = 1;

else {

flag = 0;
f();
}

if (c == '$') {
flag = 0;
f();
}

c = grm[i][++j];
}
}

if (flag == 1)
printf("Operator grammar");
}

55 | P a g e

You might also like