0% found this document useful (0 votes)
2 views22 pages

CD File

The document outlines a Compiler Design Lab course at Ajay Kumar Garg Engineering College, detailing various programming assignments related to lexical analysis, syntax parsing, and finite automata. It includes specific programming tasks such as designing a lexical analyzer in C, implementing tools like Lex and YACC, and generating specifications for syntactic categories. Additionally, it provides sample code and aims for each program, showcasing practical applications in compiler design.

Uploaded by

Aditya Singh
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)
2 views22 pages

CD File

The document outlines a Compiler Design Lab course at Ajay Kumar Garg Engineering College, detailing various programming assignments related to lexical analysis, syntax parsing, and finite automata. It includes specific programming tasks such as designing a lexical analyzer in C, implementing tools like Lex and YACC, and generating specifications for syntactic categories. Additionally, it provides sample code and aims for each program, showcasing practical applications in compiler design.

Uploaded by

Aditya Singh
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/ 22

AJAY KUMAR GARG ENGINEERING COLLEGE

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

COMPILER DESIGN LAB (BCS652)

COURSE : B.Tech
BRANCH : Computer Science
SECTION : CS-01
SEMESTER : VI
GROUP :A

SUBMITTED BY SUBMITTED TO
Name: Aditya Singh Mr. Sachin Jain
Roll No.: 2200270120014 Assistant Professor, CSE

Session-2025-26 (Odd Sem.)


INDEX
S.no Name of Experiment Date Sign
01 Design and implement a lexical analyzer for given
language using C and the lexical analyzer should
ignore redundant spaces, tabs and new lines.
02 Implementation of Lexical Analyzer using Lex Tool
03 Generate YACC specification for a few syntactic
categories.
a) Program to recognize a valid arithmetic expression
that uses operator +, – , * and /.
b) Program to recognize a valid variable which starts
with a letter followed by any number of letters or
digits.
c) Implementation of Calculator using LEX and
YACC
d) Convert the BNF rules into YACC form and write
code to generate abstract syntax tree
04 Write program to find ε – closure of all states of any
given NFA with ε transition.
05 Write program to convert NFA with ε transition to
NFA without ε transition.
06 Write program to convert NFA to DFA

07 Write program to minimize any given DFA

08 Develop an operator precedence parser for a given


language.
09 Write program to find Simulate First and Follow of
any given grammar.
10 Construct a recursive descent parser for an
expression
PROGRAM-1:
AIM: Design and implement a lexical analyzer for given language using C and
the lexical analyzer should ignore redundant spaces, tabs and new lines.

#include<string.h>
#include<conio.h>
#include<ctype.h>
#include<stdio.h>
void main()
{
FILE *f1;
char c,str[10];
int lineno=1,num=0,i=0;
clrscr();
printf("\nEnter the c program\n");
f1=fopen("input.txt","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input.txt","r");
while((c=getc(f1))!=EOF) // TO READ THE GIVEN FILE
{
if(isdigit(c)) // TO RECOGNIZE NUMBERS
{
num=c-48;
c=getc(f1);
while(isdigit(c))
{
num=num*10+(c-48);
c=getc(f1);
}
printf("%d is a number \n",num);
ungetc(c,f1);
}
else if(isalpha(c)) // TO RECOGNIZE KEYWORDS AND IDENTIFIERS
{
str[i++]=c;
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
str[i++]=c;
c=getc(f1);
}
str[i++]='\0';
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0||strcmp("static",str)==0||
strcmp("switch",str)==0||strcmp("case",str)==0) // TYPE 32 KEYWORDS
printf("%s is a keyword\n",str)
else
printf("%s is a identifier\n",str);
ungetc(c,f1);
i=0;
}
else if(c==' '||c=='\t') // TO IGNORE THE SPACE
printf("\n");
else if(c=='\n') // TO COUNT LINE NUMBER
lineno++;
else // TO FIND SPECIAL SYMBOL
printf("%c is a special symbol\n",c);
}
printf("Total no. of lines are: %d\n",lineno);
fclose(f1);
getch();
}
OUTPUT

Enter the c program


int main()
{
int a=10,20;
charch;
float f;
}^Z
The numbers in the program are: 10 20
The keywords and identifiersare:
int is a keyword
main is an identifier
int is a keyword
a is an identifier
char is a keyword
ch is an identifier
float is a keyword
f is an identifier
Special characters are ( ) { = , ; ; ; }
Total no. of lines are:5
PROGRAM-2:
AIM: Implementation of Lexical Analyzer using Lex Tool.

/* program name is lexp.l */


%{
/* program to recognize a c program */
int COMMENT=0;
int cnt=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
"*/" {COMMENT = 0; cnt++;}
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n 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\t%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)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
if(!file)
{
printf("could not open %s \n",argv[1]);
exit(0);
}
yyin = file;
}
yylex();
printf("\n\n Total No.Of comments are %d",cnt);
return 0;
}
int yywrap()
{
return 1;
}
/* program name is lexp.l */
%{
/* program to recognize a c program */
int COMMENT=0;
int cnt=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
"*/" {COMMENT = 0; cnt++;}
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n 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\t%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)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
III B.Tech II Sem CD Lab Manual
WISE Page 8
if(!file)
{
printf("could not open %s \n",argv[1]);
exit(0);
}
yyin = file;
}
yylex();
printf("\n\n Total No.Of comments are %d",cnt);
return 0;
}
int yywrap()
{
return 1;
}

Input:

#include<stdio.h>
main()
{
int a,b;
}

Output:

#include<stdio.h> is a PREPROCESSOR DIRECTIVE


FUNCTION
main ()
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS
PROGRAM-3:
AIM: Generate YACC specification for a few syntactic categories.

a) Program to recognize a valid arithmetic expression that uses operator +,


– , * and /.

arithmetic.y
%{
#include<stdio.h>
%}
%token ID NUMBER
%left '+' '-'
%left '*' '/'
%%
stmt:expr {printf("valid Expression\n");}
;
expr: expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| '(' expr ')'
| NUMBER
| ID
;
%%
int main ()
{
do
{printf("Enter the expression\n");
yyparse();
}while(1);
return 1;
}
int yyerror (char *msg)
{
printf("Invalid Expression\n");
}
yywrap()
{
return(1);
}
arithmetic.l
%{
#include "y.tab.h"
extern int yylval;
%}
%%
[a-zA-Z] {return ID;}
[0-9] {return NUMBER;}
\n { printf ("reached end of
line\n"); return 0;
}
. { printf ("found other data \"%s\"\n",
yytext); return yytext[0];
/* so yacc can see things like '+', '-', and '=' */
}

b) Program to recognize a valid variable which starts with a letter followed


by any number of letters or digits.
valid.y
%{
#include<stdio.h>
#include<stdlib.h>
%}
%token DIGIT LETTER
%start S
%%
S : variable { printf("Valid Variable\n"); }
;
variable : LETTER alphanumeric
;
alphanumeric :LETTER alphanumeric
|DIGIT alphanumeric
|LETTER
|DIGIT
;
%%
int main ()
{
do
{printf("Enter the expression\n");
yyparse();
}while(1);
return 1;
}
int yyerror (char *msg)
{
printf("Invalid Expression\n");
}
yywrap()
{
return(1);
}
valid.l
%{
#include "y.tab.h"
extern int yylval;
%}
%%
[a-zA-Z] {return LETTER;}
[0-9] {return DIGIT;}
\n { printf ("reached end of
line\n"); return 0;
}
. { printf ("found other data \"%s\"\n",
yytext); return yytext[0];
/* so yacc can see things like '+', '-', and '=' */
}

c) Implementation of Calculator using LEX and YACC

calculator.y
%{
#include <stdio.h>
//extern FILE *yyin;
%}
%token NUMBER
%start S
%%
S : E { printf("Expression_value= %d\n", $1); }
;
E : E '+' NUMBER { $$ = $1 + $3;
printf ("Recognized '+' expression.\n");
}
| E '-' NUMBER { $$ = $1 - $3;
printf ("Recognized '-' expression.\n");
}
| E '*' NUMBER { $$ = $1 * $3;
printf ("Recognized '*' expression.\n");
}
| E '/' NUMBER { if($3==0)
{
printf("Cannot divide by 0");
break;
}
else
$$ = $1 / $3;
printf ("Recognized '/' expression.\n");
}
| NUMBER { $$ = $1;
printf ("Recognized a number.\n");
}
;
%%
int main ()
{
//yyin=fopen("s.txt","r");
do
{printf("Enter the expression\n");
yyparse();
}while(1);
return 1;
}
int yyerror (char *msg)
{
printf("Invalid Expression\n");
}
yywrap()
{
return(1);
}
calculator.l
%{
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ { yylval = atoi (yytext);
printf ("scanned the number %d\n",
yylval); return NUMBER; }
[ \t] { printf ("skipped whitespace\n"); }
\n { printf ("reached end of line\n");
return 0;
}
. { printf ("found other data \"%s\"\n",
yytext); return yytext[0];
/* so yacc can see things like '+', '-', and '=' */
}
%%
How to run
yacc -d
calculator.y lex
calculator.l
gcc y.tab.c lex.yy.c
./a.out
PROGRAM-4:
AIM: Write program to find ε-closure of states of any given NFA ε- transition

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
char NFA_FILE[MAX_LEN];
char buffer[MAX_LEN];
int zz = 0;
// Structure to store DFA states and their
// status ( i.e new entry or already
present) struct DFA {
char
*states; int
count;
} dfa;
int last_index = 0;
FILE *fp;
int symbols;
/* reset the hash map*/
void reset(int ar[], int size) {
int i;
// reset all the values of
// the mapping array to
zero for (i = 0; i < size; i++)
{ ar[i] = 0;
}
}
// Check which States are present in the e-closure
/* map the states of NFA to a hash
set*/ void check(int ar[], char S[]) {
int i, j;
// To parse the individual states of
NFA int len = strlen(S);
for (i = 0; i < len; i++) {
// Set hash map for the position
// of the states which is found
j = ((int)(S[i]) - 65);
ar[j]++;
}
}
// To find new Closure States
void state(int ar[], int size, char S[]) {
int j, k = 0;
// Combine multiple states of NFA
// to create new states of
DFA for (j = 0; j < size; j++) {
if (ar[j] != 0)
S[k++] = (char)(65 + j);
}
// mark the end of the
state S[k] = '\0';
}
// To pick the next closure from closure
set int closure(int ar[], int size) {
int i;
// check new closure is present or
not for (i = 0; i < size; i++) {
if (ar[i] == 1)
return i;
}
return (100);
}
// Check new DFA states can be
// entered in DFA table or not
int indexing(struct DFA *dfa) {
int i;
for (i = 0; i < last_index; i++) {
if (dfa[i].count == 0)
return 1;
}
return -1;
}
/* To Display epsilon closure*/
void Display_closure(int states, int closure_ar[],
char *closure_table[],
char *NFA_TABLE[][symbols + 1],
char *DFA_TABLE[][symbols]) {
for (i = 0; i < states; i++) {
reset(closure_ar, states);
closure_ar[i] = 2;
// to neglect blank entry
if (strcmp(&NFA_TABLE[i][symbols], "-") != 0) {
// copy the NFA transition state to buffer
strcpy(buffer, &NFA_TABLE[i][symbols]);
check(closure_ar, buffer);
int z = closure(closure_ar, states);
// till closure get completely
saturated while (z != 100)
{
if (strcmp(&NFA_TABLE[z][symbols], "-") != 0) {
strcpy(buffer, &NFA_TABLE[z][symbols]);
// call the check
function
check(closure_ar, buffer);
}
closure_ar[z]++;
z = closure(closure_ar, states);
}
}
// print the e closure for every states of NFA
printf("\n e-Closure (%c) :\t", (char)(65 + i));
bzero((void *)buffer, MAX_LEN);
state(closure_ar, states, buffer);
strcpy(&closure_table[i], buffer);
printf("%s\n", &closure_table[i]);
}
}
/* To check New States in DFA */
int new_states(struct DFA *dfa, char S[]) {
int i;
// To check the current state is already
// being used as a DFA state or not in
// DFA transition table
for (i = 0; i < last_index; i++) {
if (strcmp(&dfa[i].states, S) == 0)
return 0;
}
// push the new
strcpy(&dfa[last_index++].states, S);
// set the count for new states entered
// to zero
dfa[last_index - 1].count = 0;
return 1;
}
// Transition function from NFA to DFA
// (generally union of closure operation )
void trans(char S[], int M, char *clsr_t[], int st,
char *NFT[][symbols + 1], char TB[]) {
int len = strlen(S);
int i, j, k, g;
int arr[st];
int sz;
reset(arr,
st);
char temp[MAX_LEN], temp2[MAX_LEN]; char
*buff;
// Transition function from NFA to
DFA for (i = 0; i < len; i++) {
j = ((int)(S[i] - 65));
strcpy(temp, &NFT[j][M]);
if (strcmp(temp, "-") != 0) {
sz = strlen(temp);
g = 0;
while (g < sz) {
k = ((int)(temp[g] - 65));
strcpy(temp2, &clsr_t[k]);
check(arr, temp2);
g++;
}
}
}
bzero((void *)temp, MAX_LEN);
state(arr, st, temp);
if (temp[0] != '\0') {
strcpy(TB, temp);
} else strcpy(TB,
"-");
}
/* Display DFA transition state table*/
void Display_DFA(int last_index, struct DFA *dfa_states,
char *DFA_TABLE[][symbols]) {
int i, j;
printf("\n\n********************************************************
\n\n");
printf("\t\t DFA TRANSITION STATE TABLE \t\t \n\n");
printf("\n STATES OF DFA :\t\t");
for (i = 1; i < last_index; i++) printf("%s,
", &dfa_states[i].states); printf("\n");
printf("\n GIVEN SYMBOLS FOR DFA: \t");
for (i = 0; i < symbols; i++)
printf("%d, ", i);
printf("\n\n");
printf("STATES\t");
for (i = 0; i < symbols; i++)
printf("|%d\t", i);
printf("\n");
// display the DFA transition state
table printf(" +
\n")
; for (i = 0; i < zz; i++) {
printf("%s\t", &dfa_states[i + 1].states);
for (j = 0; j < symbols; j++) { printf("|%s
\t", &DFA_TABLE[i][j]);
}
printf("\n");
}
}
// Driver
Code int
main() { int i,
j, states;
char T_buf[MAX_LEN];
// creating an array dfa structures
struct DFA *dfa_states = malloc(MAX_LEN * (sizeof(dfa)));
states = 6, symbols = 2;
printf("\n STATES OF NFA :\t\t");
for (i = 0; i < states; i++)
printf("%c, ", (char)(65 + i));
printf("\n");
printf("\n GIVEN SYMBOLS FOR NFA: \t");
for (i = 0; i < symbols; i++)
printf("%d, ", i);
printf("eps");
printf("\n\n");
char *NFA_TABLE[states][symbols + 1];
// Hard coded input for NFA table
char *DFA_TABLE[MAX_LEN][symbols];
strcpy(&NFA_TABLE[0][0], "FC");
strcpy(&NFA_TABLE[0][1], "-");
strcpy(&NFA_TABLE[0][2], "BF");
strcpy(&NFA_TABLE[1][0], "-");
strcpy(&NFA_TABLE[1][1], "C");
strcpy(&NFA_TABLE[1][2], "-");
strcpy(&NFA_TABLE[2][0], "-");
strcpy(&NFA_TABLE[2][1], "-");
strcpy(&NFA_TABLE[2][2], "D");
strcpy(&NFA_TABLE[3][0], "E");
strcpy(&NFA_TABLE[3][1], "A");
strcpy(&NFA_TABLE[3][2], "-");
strcpy(&NFA_TABLE[4][0], "A");
strcpy(&NFA_TABLE[4][1], "-");
strcpy(&NFA_TABLE[4][2], "BF");
strcpy(&NFA_TABLE[5][0], "-");
strcpy(&NFA_TABLE[5][1], "-");
strcpy(&NFA_TABLE[5][2], "-");
printf("\n NFA STATE TRANSITION TABLE \n\n\n");
printf("STATES\t");
for (i = 0; i < symbols; i++)
printf("|%d\t", i);
printf("eps\n");
// Displaying the matrix of NFA transition table
printf(" + \n");
for (i = 0; i < states; i++) {
printf("%c\t", (char)(65 + i));
for (j = 0; j <= symbols; j++) {
printf("|%s \t", &NFA_TABLE[i][j]);
}
printf("\n");
}
int closure_ar[states];
char *closure_table[states];
Display_closure(states, closure_ar, closure_table, NFA_TABLE, DFA_TABLE);
strcpy(&dfa_states[last_index++].states, "-");
dfa_states[last_index - 1].count =
1; bzero((void *)buffer, MAX_LEN);
strcpy(buffer, &closure_table[0]);
strcpy(&dfa_states[last_index++].states, buffer);
int Sm = 1, ind =
1; int start_index =
1;
}

OUTPUT
STATES OF NFA : A, B, C, D, E, F,
GIVEN SYMBOLS FOR NFA: 0, 1, eps
NFA STATE TRANSITION TABLE

STATES 0 1 eps
A FC - BF
B - C -
C - - D
D E A -
E A - BF
F - - -

e-Closure (A) : ABF


e-Closure (B) : B
e-Closure (C) : CD
e-Closure (D) : D
e-Closure (E) : BEF
e-Closure (F) : F
PROGRAM-1:
AIM: Design and implement a lexical analyzer for given language using C
and the lexical analyzer should ignore redundant spaces, tabs and new lines.

You might also like