0% found this document useful (0 votes)
31 views39 pages

CD Practical Jignasha

CD Practicals

Uploaded by

Jignasha V Soni
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views39 pages

CD Practical Jignasha

CD Practicals

Uploaded by

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

Compiler Design (3170701)

PRACTICAL – 1
AIM: Implementation of Finite Automata and String Validation.
Code:
#include <iostream.h>
#include <string.ha>
using namespace std;
#define MAX 100
int main() {
char str[MAX];
char f = 'a';
cout << "Enter the string to be checked: ";
cin >> str;

for (int i = 0; str[i] != '\0'; i++) {


switch (f) {
case 'a':
if (str[i] == '0') f = 'b';
else if (str[i] == '1') f = 'a';
break;
case 'b':
if (str[i] == '0') f = 'b';
else if (str[i] == '1') f = 'c';
break;
case 'c':
if (str[i] == '0') f = 'b';
else if (str[i] == '1') f = 'a';
break;
}
}
if (f == 'c')
cout << "String is accepted.";
else
cout << "String is not accepted.";
return 0;
}
Output:

VIEAT/B.E/SEM-VII/220943107040
1
Compiler Design (3170701)

PRACTICAL – 2
AIM: Introduction to Lex Tool.
LEX:
Lex plays a crucial role in compilers by classifying tokens based on their specific functions. To grasp the
concept of Lex in Compiler Design, we must first comprehend Lexical Analysis. This article will delve in
to Lex, but let’s start with an overview of Lexical Analysis.
Lexical Analysis:
Lexical Analysis is the initial phase of compiler design. It processes input, which is a sequence of charact
ers, and outputs tokens— a process known as tokenization. Tokens can be categories like identifiers, sepa
rators, keywords, operators, constants, and special characters. This process involves three main stages:
1. Tokenization: Converts the stream of characters into tokens.
2. Error Reporting: Identifies and reports lexical errors such as excessive length or unmatched strin
gs.
3. Comment Removal: Strips away comments, blank spaces, newlines, and indentation.
What is Lex in Compiler Design?
Lex is a software tool that creates Lexical Analyzers, which transform a sequence of characters into token
s. Essentially, Lex operates as a compiler. It accepts input and translates it into specific patterns. Lex is of
ten used alongside YACC (Yet Another Compiler Compiler). The tool was developed by Mike Lesk and
Eric Schmidt.
Function of Lex:
1. Initial Step:
 The source code, written in Lex language and saved as ‘File.l’, is fed into the Lex Compiler, com
monly known as Lex, producing an output file named lex.yy.c.
2. Subsequent Step:
 The lex.yy.c file is then passed to the C compiler, which outputs an ‘a.out’ file. Finally, the a.out f
ile processes a stream of characters and produces tokens as output.

lex.yy.c: It is a C program.
File.l: It is a Lex source program
a.out: It is a Lexical analyzer

VIEAT/B.E/SEM-VII/220943107040
2
Compiler Design (3170701)
Lex File Structure
A Lex program is composed of three sections, divided by %% delimiters:

1. Declarations:
 Includes variable declarations.
2. Translation Rules:
 Composed of patterns and their corresponding actions.
3. Auxiliary Procedures:
 Contains auxiliary functions that are used in the actions.
These sections ensure a structured approach to defining the lexical analyzer.
For example:
declaration
number[0-9]
%%
translation
if {return (IF);}
%%
auxiliary function
int numberSum()

VIEAT/B.E/SEM-VII/220943107040
3
Compiler Design (3170701)

PRACTICAL – 3
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>
#include <string.h>
char word[] = "Jignasha";
int count = 0;
%}
%%
[a-zA-Z]+ {
if(strcmp(yytext,word)==0)
count++;
}
.;
%%
void main(){
yyin = fopen("input.txt", "r");
yylex();
printf("Number of occurrence of word \"Jignasha\" is %d.", count);
}
int yywrap() {
return 1;
}
Input.txt:
Hello ther Jignasha Soni Here,
Computer Enginnering student.

Output:

VIEAT/B.E/SEM-VII/220943107040
4
Compiler Design (3170701)

b. Ceasor Cypher:
%{
char ch;
%}
%%
[a-z] {
ch = yytext[0];
ch = ch + 3;
if(ch > 'z') ch = ch - ('z' + 1 - 'a');
printf("%c",ch);
}
[A-Z] {
ch = yytext[0];
ch = ch + 3;
if(ch > 'Z') ch = ch - ('Z' + 1 - 'A');
printf("%c",ch);
}
%%
void main(){
printf("Enter character :");
yylex();
}
int yywrap() {
return 1;
}

Output:

VIEAT/B.E/SEM-VII/220943107040
5
Compiler Design (3170701)

c. Extract single and multiline comments:


%{
#include <stdio.h>
%}
%%
\/\/(.*) {};
\/\*(.*\n)*.*\*\/ {};
%%
int yywrap(){
return 1;
}
int main(){
yyin=fopen("main.c","r");
yyout=fopen("out.c","w");
yylex();
return 0;
}
Before Execution main.c

After Execuion out.c

VIEAT/B.E/SEM-VII/220943107040
6
Compiler Design (3170701)

PRACTICAL – 4
AIM: Implement following Programs Using Lex
a. Convert Roman to Decimal
b. Check weather given statement is compound or simple
c. Extract html tags from .html file

a. Convert Roman to Decimal


%{
#include <stdio.h>
%}
%%
"I" {printf("1");}
"II" {printf("2");}
"III" {printf("3");}
"IV" {printf("4");}
"V" {printf("5");}
"VI" {printf("6");}
"VII" {printf("7");}
"VIII" {printf("8");}
"IX" {printf("9");}
"X" {printf("10");}
"XX" {printf("20");}
"XXX" {printf("30");}
"XL" {printf("40");}
"L" {printf("50");}
"C" {printf("100");}
"M" {printf("1000");}
.{
printf("Invalid");
}
%%
void main(){
printf("Enter a only capital roman number :");
yylex();
}
int yywrap(){
return 1;
}
Output:

VIEAT/B.E/SEM-VII/220943107040
7
Compiler Design (3170701)

b. Check weather given statement is compound or simple


%{
#include <stdio.h>
int is_Simple = 1;
%}
%%
[ \t]+[aA][nN][dD][ \t]+ {
is_Simple = 0;
}
[ \t]+[oO][rR][ \t]+ {
is_Simple = 0;
}
[ \t]+[bB][uU][tT][ \t]+ {
is_Simple = 0;
} . {;}
%%
void main(){
printf("Enter a sentence :");
yylex();
if(is_Simple == 1){
printf("This is a simple sentence");
}
Else
{
printf("This is a compound sentence");
}
}
int yywrap(){
return 1;
}
OUTPUT:

VIEAT/B.E/SEM-VII/220943107040
8
Compiler Design (3170701)
c. Extract html tags from .html file.
#include
#include
#include
void extractHtmlTags(FILE *file) {
int c;
int insideTag = 0;
printf("HTML Tags in the file:\n");
while ((c = fgetc(file)) != EOF) {
if (c == '<') {
insideTag = 1;
putchar(c);
}
else if (c == '>') {
insideTag = 0;
putchar(c);
putchar('\n');
}
else if (insideTag) {
putchar(c);
}}}
int main() {
FILE *file;
char fileName[100];
printf("Enter the HTML file name: ");
scanf("%s", fileName);
file = fopen(fileName, "r");
if (file == NULL) {
printf("Error opening file.\n");
return 1; }
extractHtmlTags(file);
fclose(file);
return 0;
}
Output:

VIEAT/B.E/SEM-VII/220943107040
9
Compiler Design (3170701)

PRACTICAL – 5
AIM: Implementation of Recursive Descent Parser without backtracking
Input: The string to be parsed.
Output: Whether string parsed successfully or not.
Explanation: Students have to implement the recursive procedure for RDP for a
typical grammar. The production no. are displayed as they are used to derive the
string.

Code:

#include<stdio.h>

#include<ctype.h>

#include<string.h>

void Tprime();

void Eprime();

void E();

void check();

void T();
char expression[10];
int count,flag;
int main()
{
count =0;
flag = 0;
printf("\nEnter an Algebraic Expression:\t"); scanf("%s", expression);
E();
if((strlen(expression) == count) && (flag == 0))
{
printf("\nThe Expression %s is Valid\n", expression);
}
else
{ printf("\nThe Expression %s is Invalid\n", expression);
}}
void E(){

VIEAT/B.E/SEM-VII/220943107040
10
Compiler Design (3170701)
T();
Eprime(); }
void T(){
check();
Tprime(); }
void Tprime()
{
if(expression[count] =='*')
{
count++;
check();
Tprime();
}}
void check(){
if(isalnum(expression[count]))
{
count++;
}
else if(expression[count] == '(')
{
count++; E();
if(expression[count] == ')')
{
count++;
}
else
{ flag = 1;
}
}
else {
flag = 1;
}}
void Eprime(){
if(expression[count] =='+')
{
count++; T();
Eprime();
}}

VIEAT/B.E/SEM-VII/220943107040
11
Compiler Design (3170701)

Output:

VIEAT/B.E/SEM-VII/220943107040
12
Compiler Design (3170701)

PRACTICAL – 6
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.
Code:

#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("Howmanyproductions? :");
scanf("%d",&count);
printf("Enter %d productionsepsilon=$:\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++)

VIEAT/B.E/SEM-VII/220943107040
13
Compiler Design (3170701)
{
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:

VIEAT/B.E/SEM-VII/220943107040
14
Compiler Design (3170701)

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

Intermediate code

Intermediate code is used to translate the source code into the machine code. Intermediate code lies
between the high-level language and the machine language.

o If the compiler directly translates source code into the machine code without generating
intermediate code then a full native compiler is required for each new machine.
o The intermediate code keeps the analysis portion same for all the compilers that's whyit
doesn't need a full compiler for every unique machine.
o Intermediate code generator receives input from its predecessor phase and semantic
analyzer phase. It takes input in the form of an annotated syntax tree.
o Using the intermediate code, the second phase of the compiler synthesis phase is
changed according to the target machine.
Intermediate representation

Intermediate code can be represented in two ways:

1. High Level intermediate code:

High level intermediate code can be represented as source code. To enhance performance of source
code, we can easily apply code modification. But to optimize the target machine, it is less preferred.

2. Low Level intermediate code

Low level intermediate code is close to the target machine, which makes it suitable for register and
memory allocation etc. it is used for machine-dependent optimizations.

Three address code


o Three-address code is an intermediate code. It is used by the optimizing compilers.
o In three-address code, the given expression is broken down into several separate
instructions. These instructions can easily translate into assembly language.
o Each Three address code instruction has at most three operands. It is a combination of
assignment and a binary operator.
Example

Given Expression:

1. a := (-c * b) + (-c * d)
Three-address code is as follows: t1

VIEAT/B.E/SEM-VII/220943107040
15
Compiler Design (3170701)

:= -c
t2 := b*t1 t3
:= -c

t4 := d * t3 t5
:= t2 + t4 a := t5

t is used as registers in the target program.


The three address code can be represented in two forms: quadruples and triples.

VIEAT/B.E/SEM-VII/220943107040
16
Compiler Design (3170701)

PRACTICAL – 8
AIM: Extract Predecessor and Successor from given Control Flow Graph.

Code :

#include<stdio.h>

#include<string.h>

char *input;
int i=0;
char lasthandle[6],stack[50],handles[][5]={")E(","E*E","E+E","i","E^E"};
//(E) becomes ) E ( when pushedto stack)
int top=0,l;
char prec[9][9]={ /*input*/
/*stack + - * / ^ i ( ) $ */
/* + */ '>', '>','<','<','<','<','<','>','>',
/* - */ '>', '>','<','<','<','<','<','>','>',
/* * */ '>', '>','>','>','<','<','<','>','>',
/* / */ '>', '>','>','>','<','<','<','>','>',
/* ^ */ '>', '>','>','>','<','<','<','>','>',
/* i */ '>', '>','>','>','>','e','e','>','>',
/* ( */ '<', '<','<','<','<','<','<','>','e',
/* ) */ '>', '>','>','>','>','e','e','>','>',
/* $ */ '<', '<','<','<','<','<','<','<','>',
};
int getindex(char c)
{ switch(c)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;
case ')':return 7;
case '$':return 8;
}

}
int shift() {

VIEAT/B.E/SEM-VII/220943107040
17
Compiler Design (3170701)
stack[++top]=*(input+i++);
stack[top+1]='\0';
} int reduce()
{
int i,len,found,t; for(i=0;i<5;i++)//selecting
handles
{
len=strlen(handles[i]);
if(stack[top]==handles[i][0]&&top+1>=len)
{
found=1;
for(t=0;t<len;t
++)
{ if(stack[top-t]!=handles[i][t])
{
found=0;
break;

}}
if(found==1)
{
stack[top-t+1]='E';
top=top-t+1;
strcpy(lasthandle,handles[i]);
stack[top+1]='\0';
return 1;//successfulreduction
}
}

}
return 0;
}
void dispstack() { int j;
for(j=0;j<=top;j++)
printf("%c",stack[j]);
}
void dispinput(){ int j; for(j=i;j<l;j++)
printf("%c",*(input+j));
} void main() {
int j; input=(char*)malloc(50*sizeof(char));
printf("\nEnter the string\n");
scanf("%s",input);
VIEAT/B.E/SEM-VII/220943107040
18
Compiler Design (3170701)
input=strcat(input,"$");
l=strlen(input);
strcpy(stack,"$");
printf("\nSTACK\tINPUT\tACTION");
while(i<=l) { shift();
printf("\n"); dispstack();
printf("\t");
dispinput(); printf("\tShift");
if(prec[getindex(stack[top])][getindex(input[i])]=='>')
{ while(reduce()){ printf("\
n"); dispstack();
printf("\t");
dispinput();
printf("\tReduced: E->%s",lasthandle);
}
}}
if(strcmp(stack,"$E$")==0) printf("\nAccepted;"); else
printf("\nNot Accepted;");
getch(); }

Output:

VIEAT/B.E/SEM-VII/220943107040
19
Compiler Design (3170701)

PRACTICAL – 9
AIM: Introduction to YACC and generate Calculator Program..

Code :

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.

YACC input file is divided into three parts.


In 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 thespecification 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). 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 themain() 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 (particularlyimportant 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
textualdescription of the LALR(1) parsing table used by the parser. This is useful for tracking

VIEAT/B.E/SEM-VII/220943107040
20
Compiler Design (3170701)
down how the parser solves conflicts.
For Compiling YACC Program:
Write lex program in a file file.l and yacc in a file file.y
Open Terminal and Navigate to the Directorywhere you have saved the files. type
lexfile.l type yacc file.y
type cc lex.yy.c y.tab.h -ll type
./a.out

Source Code:

LEX:
%{
#include<stdio.h> #include
"y.tab.h" extern int yylval;
%}
%%
[0-9]+ {
yylval=atoi(yytext); return NUMBER; }
[\t] ;
[\n] return0;
. return yytext[0];
%%
int yywrap() {
return 1;}

YAAC:
%{
#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;}

VIEAT/B.E/SEM-VII/220943107040
21
Compiler Design (3170701)
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
;
%%
void main(){
77666666printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");
yyparse();
if(flag==0)
printf("\nEnteredarithmeticexpressionis Valid\n\n");
}
void yyerror(){
printf("\nEnteredarithmeticexpressionis Invalid\n\n");
flag=1;
}

Output:

VIEAT/B.E/SEM-VII/220943107040
22
Compiler Design (3170701)

PRACTICAL – 10
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.
Code:

#include<stdio.h>
#include<string.h> int
n,m=0,p,i=0,j=0;
char a[10][10],followResult[10];
void follow(charc);
void first(charc);
void addToResult(char); int
main()
{
int i;
int choice;
char c,ch;
printf("Enterthe no.ofproductions: ");
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); 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(Press1 to continue....................)?");
scanf("%d
%c",&choice,&ch); }
while(choice==1); }
void follow(char c)
{ if(a[0][0]==c)addToResult('$');

VIEAT/B.E/SEM-VII/220943107040
23
Compiler Design (3170701)
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(charc)
{ 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;
}

Output:

VIEAT/B.E/SEM-VII/220943107040
24
Compiler Design (3170701)

PRACTICAL – 11
Aim: Implement a C program for constructing LL (1) parsing.

Code:

#include<stdio.h
#include<string.h>
#define TSIZE 128
int table[100][TSIZE];
char terminal[TSIZE];
char nonterminal[26];
struct product{
char str[100]; int
len;
}pro[20]; int
no_pro;
char first[26][TSIZE]; char follow[26]
[TSIZE];
// stores first of each production in form A->ß char
first_rhs[100][TSIZE];
// check if the symbol is
nonterminal int isNT(char c) {
return c >= 'A' && c <= 'Z'; }
// reading data from the file void
readFromFile() {
FILE* fptr;
fptr = fopen("text.txt", "r"); char
buffer[255];
int i;
int j;
while (fgets(buffer, sizeof(buffer), fptr))
{ printf("%s", buffer); j = 0;
nonterminal[buffer[0] - 'A'] = 1;
for (i = 0; i < strlen(buffer) - 1; ++i) { if
(buffer[i] == '|') {
++no_pro;
pro[no_pro - 1].str[j] = '\0'; pro[no_pro - 1].len = j;

-
pro[no_pro].str[0 pro[no_pr
=
] o
1].str[0];
pro[no_pro].str[1 = pro[no_pr -
] o
VIEAT/B.E/SEM-VII/220943107040
25
Compiler Design (3170701)

1].str[1];
pro[no_pro].str[2] =pro[no_pro- 1].str[2]; j = 3;} else
{ pro[no_pro].str[j] = buffer[i];
++j;
if (!isNT(buffer[i]) && buffer[i] != '-' && buffer[i] != '>')
{ terminal[buffer[i]] =1;
}
}
}
pro[no_pro].len =j;
++no_pro;
}
}
voidadd_FIRST_A_to_FOLLOW_B(char A, char B){ int
i; for (i = 0; i < TSIZE; ++i) {
if (i != '^')
follow[B - 'A'][i] = follow[B - 'A'][i] || first[A - 'A'][i];
}
}
voidadd_FOLLOW_A_to_FOLLOW_B(char A, char B){ int
i; for (i = 0; i < TSIZE; ++i) {
if (i != '^')
follow[B - 'A'][i] = follow[B - 'A'][i] || follow[A - 'A'][i];
}
}
void FOLLOW(){ int t
=0;
int i, j, k, x;
while (t++ < no_pro) {
for (k = 0; k < 26; ++k) {
if (!nonterminal[k])
continue; char nt = k + 'A';
for (i = 0; i < no_pro; ++i) {
for (j = 3; j < pro[i].len; ++j) {
if (nt == pro[i].str[j]) {
for (x = j + 1; x < pro[i].len; ++x) { char sc
= pro[i].str[x];
if (isNT(sc)) { add_FIRST_A_to_FOLLOW_B(sc, nt); if (first[sc - 'A']
['^'])
continue; }
else { follow[nt - 'A'][sc] = 1; } break;
VIEAT/B.E/SEM-VII/220943107040
26
Compiler Design (3170701)
}
if (x == pro[i].len) add_FOLLOW_A_to_FOLLOW_B(pro[i].str[0], nt);
}}}}}}
voidadd_FIRST_A_to_FIRST_B(char A, char B){ int
i; for (i = 0; i < TSIZE; ++i) {
if (i != '^') {
first[B - 'A'][i] = first[A - 'A'][i] || first[B - 'A'][i]; } } } void
FIRST(){
int i, j;
int t =0;
while (t < no_pro) {
for (i = 0; i < no_pro; ++i) {
for (j = 3; j < pro[i].len; ++j) { char sc
= pro[i].str[j];
if (isNT(sc)){
add_FIRST_A_to_FIRST_B(sc, pro[i].str[0]); if (first[sc
-'A']['^'])
continue; } else
{
first[pro[i].str[0] - 'A'][sc] = 1;
}
break;
}
if (j == pro[i].len) first[pro[i].str[0] - 'A']['^']
= 1;
}
++t;
}}
void add_FIRST_A_to_FIRST_RHS B(char A, int B){
int i;
for (i = 0; i < TSIZE; ++i) {
if (i != '^')
first_rhs[B][i] = first[A - 'A'][i] || first_rhs[B][i];
}
}
// Calculates FIRST(ß)for each A->ß
void FIRST_RHS(){
int i, j;
int t =0;
while (t < no_pro) {
for (i = 0; i < no_pro; ++i) {
VIEAT/B.E/SEM-VII/220943107040
27
Compiler Design (3170701)
for (j = 3; j < pro[i].len; ++j) { char sc
= pro[i].str[j];
if (isNT(sc)) { add_FIRST_A_to_FIRST_RHS B(sc, i); if (first[sc
-'A']['^'])
continue; } else
{
first_rhs[i][sc] = 1; }
break; }
if (j == pro[i].len) first_rhs[i]
['^'] = 1; }
++t;
}}
int
main()
{ readFromFile();
follow[pro[0].str[0] - 'A']['$'] = 1;
FIRST();
FOLLOW();
FIRST_RHS();
int i, j, k;
printf("\n");
for (i = 0; i < no_pro; ++i) {
if (i == 0 || (pro[i - 1].str[0] !=pro[i].str[0])) { char c =
pro[i].str[0];
printf("FIRST OF %c: ", c); for (j
= 0; j < TSIZE; ++j) {
if (first[c - 'A'][j]) {
printf("%c ", j); } }
printf("\n"); } }
printf("\n");
for (i = 0; i < no_pro; ++i) {
if (i == 0 || (pro[i - 1].str[0] !=pro[i].str[0])) { char c =
pro[i].str[0];
printf("FOLLOW OF %c: ", c); for (j
= 0; j < TSIZE; ++j) {
if (follow[c - 'A'][j]) { printf("%c ", j);
}}
printf("\n");
}}
printf("\n");
for (i = 0; i < no_pro; ++i) { printf("FIRST OF

VIEAT/B.E/SEM-VII/220943107040
28
Compiler Design (3170701)
%s: ", pro[i].str); for (j = 0; j < TSIZE; ++j)
{ if (first_rhs[i][j]) {
printf("%c ", j); } } printf("\n");
}
terminal['$'] =1;
terminal['^'] = 0;
printf("\n");
printf("\n\t**************** LL(1) PARSING TABLE *******************\n");
printf("\t \
n"); printf("%-10s", "");
for (i = 0; i < TSIZE; ++i) {
if (terminal[i])
printf("%-10c", i); } printf("\n");
int p =0;
for (i = 0; i < no_pro; ++i) {
if (i != 0 && (pro[i].str[0] != pro[i - 1].str[0])) p = p +1;
for (j = 0; j < TSIZE; ++j) {
if (first_rhs[i][j] && j != '^')
{ table[p][j] = i + 1; }
else if (first_rhs[i]['^']) {
for (k = 0; k < TSIZE; ++k) {
if (follow[pro[i].str[0] -
'A'][k]){ table[p][k] = i + 1; } } } } }
k = 0;
for (i = 0; i < no_pro; ++i) {
if (i == 0 || (pro[i - 1].str[0] != pro[i].str[0])) {
printf("%-10c", pro[i].str[0]); for (j
= 0; j < TSIZE; ++j) {
if (table[k][j]) {
printf("%-10s", pro[table[k][j] - 1].str);} else if (terminal[j]) {
printf("%-10s", ""); } }
++k;
printf("\n");
}}}

VIEAT/B.E/SEM-VII/220943107040
29
Compiler Design (3170701)

Output:

VIEAT/B.E/SEM-VII/220943107040
30
Compiler Design (3170701)

PRACTICAL – 12
Aim: Implement a C program to implement LALR parsing.

Code:

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
voidpush(char*,int*,char);
char stacktop(char*);
voidisproduct(char,char); int
ister(char);
int isnter(char);
int isstate(char);
void error();
voidisreduce(char,char); char
pop(char *,int *);
void printt(char*,int *,char [],int);
void rep(char[],int);
struct action { char row[6][5];
};
const struct 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"}
}; struct gotol { char r[3][4]; };
const struct gotol 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"},

VIEAT/B.E/SEM-VII/220943107040
31
Compiler Design (3170701)
{"emp","emp","emp"},
{"emp","emp","emp"},};
char ter[6]={'i','+','*',')','(','$'};
char nter[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]; }; const
struct grammar rl[6]={
{'E',"e+T"}, {'E',"T"},
{'T',"T*F"},
{'T',"F"},
{'F',"(E)"},
{'F',"i"},
};
void main()
{ char inp[80],x,p,dl[80],y,bl='a';
int i=0,j,k,l,n,m,c,len;
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++) 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 "); else

VIEAT/B.E/SEM-VII/220943107040
32
Compiler Design (3170701)
printf(" \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;

} } char stacktop(char*s) { char


i; i=s[top];
return i;
} void isproduct(char x,char p)
{
int k,l;
k=ister(x);
l=isstate(p);
}
strcpy(temp,A[l-1].row[k-
1]); int ister(char x) { int
i;
for(i=0;i<6;i++) if(x==ter[i]) return
i+1;
return 0;
} int isnter(char x) {
int i;
for(i=0;i<3;i++) if(x==nter[i])
return i+1;
return 0;
} int isstate(char p) {
int i;
for(i=0;i<12;i++) if(p==states[i])
return i+1;
return 0;
}
void error() {
printf(" error in theinput ");
exit(0);
}
void isreduce(char x,char p)
{
int k,l;
VIEAT/B.E/SEM-VII/220943107040
33
Compiler Design (3170701)
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;
} void printt(char *t,int *p,char inp[],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) { 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;
}}

Output:
VIEAT/B.E/SEM-VII/220943107040
34
Compiler Design (3170701)

VIEAT/B.E/SEM-VII/220943107040
35
Compiler Design (3170701)

PRACTICAL – 13
Aim: Implement a C program to implement operator precedence parsing.

Code:

#inclu
de<std
io.h>
#inclu
de<stri
ng.h>
char
*input
;
int i=0;
char lasthandle[6],stack[50],handles[][5]={")E(","E*E","E+E","i","E^E"};
//(E) becomes )E( when
pushed to stack int top=0,l;
char prec[9][9]={
/*input*/
/*stack + - * / ^ i ( ) $ */
/* + */ '>','>','<','<','<','<','<','>','>',
/* - */ '>', '>','<','<','<','<','<','>','>',
/* * */ '>', '>','>','>','<','<','<','>','>',
/* / */ '>', '>','>','>','<','<','<','>','>',
/* ^ */ '>', '>','>','>','<','<','<','>','>',
/* i */ '>', '>','>','>','>','e','e','>','>',
/* ( */ '<','<','<','<','<','<','<','>','e',
/* ) */ '>','>','>','>','>','e','e','>','>',
/* $ */ '<', '<','<','<','<','<','<','<','>',
};
int getindex(char c)
{
switch(c)
{
case '+':return 0;
case '-':return1;

VIEAT/B.E/SEM-VII/220943107040
36
Compiler Design (3170701)

case '*':return 2;
case '/':return3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;
case ')':return 7;
case '$':return 8;
}
}
int shift()
{
stack[++top]=*(input+i++);
stack[top+1]='\0';
}
int reduce()
{
int i,len,found,t; for(i=0;i<5;i+
+)//selecting handles
{
len=strlen(handles[i]);
if(stack[top]==handles[i]
[0]&&top+1>=len)
{
found=1;
for(t=0;t<len;t++)
{
if(stack[top-t]!=handles[i][t])
{
found=0;
break;
}
}
if(found==1)
{
stack[top-
t+1]='E';
top=top-t+1;

VIEAT/B.E/SEM-VII/220943107040
37
Compiler Design (3170701)

strcpy(lasthandle,handles[i]);
stack[top+1]='\0';
return 1;//successfulreduction
}}}
return 0;
}
void dispstack()
{
int j;
for(j=0;j<=t
op;j++)
printf("%c",
stack[j]);
}
void dispinput()
{
int j; for(j=i;j<l;j++)
printf("%c",*(input+j)
);
}
void main()
{
int j;
input=(char*)malloc(50*sizeof(
char)); printf("\nEnter the
string\n"); scanf("%s",input);
input=strcat(input,"$");
l=strlen(input);
strcpy(stack,"$"); printf("\
nSTACK\tINPUT\tACTION");
while(i<=l)
{
shift(); printf("\
n"); dispstack();
printf("\t");
dispinput();
printf("\tShift");
if(prec[getindex(stack[top])][getindex(input[i])]=='>')
{

VIEAT/B.E/SEM-VII/220943107040
38
Compiler Design (3170701)

while(reduce())
{
printf("\n");
dispstack(); printf("\
t"); dispinput();
printf("\tReduced: E->%s",lasthandle);}
}}
if(strcmp(stack,"$
E$")==0)
printf("\
nAccepted;");
else
printf("\nNot Accepted;");
}
Output :

VIEAT/B.E/SEM-VII/220943107040
39

You might also like