Certificate
SSM COLLEGE OF ENGINEERING
Department of Computer Science Engineering
PARIHASPORA PATTAN BARAMULLA, KASHMIR
NAME:
ENROLL:
UNIVERSITYENROLL:
SEMESTER:
SECTION:
This is certified to be the bonafide work of the student in the “COMPILER DESIGN”
laboratory (CourseCode:CSE-70220L) during the academic session of autumn-2024.
Mr. Suhail Ashraf Mrs. Yasmin
Teacher Incharge HOD CSE
1
1. Design a lexical analyzer for given language and the lexical analyzer should ignore
redundant spaces, tabs and new lines. It should also ignore comments. Although the
syntax specification states that identifiers can be arbitrarily long, you may restrict the
length to some reasonable value. Simulate the same in C language.
ALGORITHM:
1. InitializeDataStructures:
Definedatastructuresfortokensandtheirtypes.
Initializeabuffertoreadthesourcecode.
Setupcountersandpointersfortraversal.
2. ReadInput:
Readtheentiresourcecodefromafileintoabuffer.
3. SkipWhitespaceandComments:
Traversethebuffercharacterbycharacter.
Skipspaces,tabs,andnewlines.
Detectandskipsingle-linecommentsstartingwith//untiltheendoftheline.
Detectandskipmulti-linecommentsstartingwith/*andendingwith*/.
4. Tokenization:
Identifytokensbasedoncharacterpatterns:
o IdentifiersandKeywords:
▪ If a letter or underscore is encountered, read characters until a non-alphanumeric
character is found.
▪ Check if the resulting string is a keyword; if so, classify it as a keyword, otherwise
classify it as an identifier.
o Numbers:
▪ Ifadigitisencountered,readcharactersuntilanon-digitcharacterisfound.
▪ Classifytheresultingstringasanumber.
o OperatorsandPunctuation:
▪ Ifapunctuationmarkoroperatorsymbolisencountered,classifyitaccordingly.
o UnknownTokens:
COMPILERDESIGNLAB
2
▪ Ifthecharacterdoesnotmatchanyknownpattern,classifyitasanunknowntoken.
5. RestrictIdentifierLength:
Enforceamaximumlengthforidentifiersandtruncateifnecessary.
6. StoreTokens:
Storeeachidentifiedtokenalongwithitstypeinalistorarray.
7. OutputTokens:
Providethelistoftokensforfurtherprocessingoroutputthemasneeded.
PROGRAM:
#include<string.h>
#include<ctype.h>
#include<stdio.h>
voidkeyword(charstr[10])
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||strcmp("int",str)==0||strc
mp("float",str)==0||strcmp("char",str)==0||strcmp("double",str)==0||
strcmp("static",str)==0||strcmp("switch",str)==0||strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%sisanidentifier",str);
main()
FILE*f1,*f2,*f3;
charc,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
COMPILERDESIGNLAB
3
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF){
if(isdigit(c))
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c)){
tokenvalue*=10+c-'0';
c=getc(f1);
num[i++]=tokenvalue;
ungetc(c,f1);
elseif(isalpha(c))
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
putc(c,f2);
c=getc(f1);
putc('',f2);
ungetc(c,f1);
else if(c==''||c=='\t')
printf("");
else
COMPILERDESIGNLAB
4
if(c=='\n')
lineno++;
else
putc(c,f3);
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF){
if(c!='')
str[k++]=c;
else
str[k]='\0';
keyword(str);
k=0;
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial characters are");
while((c=getc(f3))!=EOF)
printf("%c",c);
COMPILERDESIGNLAB
5
printf("\n");
fclose(f3);
printf("Totalno.oflinesare:%d",lineno);
Input:
EnterProgram$fortermination:
inta[3],t1,t2;
t1=2;a[0]=1;a[1]=2;a[t1]=3;
t2=-(a[2]+t1*6)/(a[2]-t1);
ift2>5then
print(t2);
else {
int t3;
t3=99;
t2=-25;
print(-t1+t2*t3);/*thisisacommenton2lines*/
}endif
(cntrl+z)
Output:
Variables : a[3] t1 t2 t3
Operator : - + * / >
Constants : 2 1 36 5 99 -25
Keywords : int if then else endif
Special Symbols : , ; ( ) { }
Comments:thisisacommenton2lines
COMPILERDESIGNLAB
6
02. ImplementtheLexicalAnalyzerusingJLex,flexorother lexicalanalyzergenerating
tools.
LOGIC: Read the input string. Check whether the string is identifier/ keyword /symbol by using the rules of
identifier and keywords using LEX Tool
PROCEDURE:Gototerminal.Openvieditor,Lexlex.l,cclex.yy.c,./a.out
RESOURCE:LinuxusingPutty
ALGORITHM:
1. InstalltheLexicalAnalyzerGenerator:
DownloadandinstallJLex,Flex,oranothersuitabletool.
2. DefinetheLexicalSpecification:
Createaspecificationfilewiththeappropriatesyntaxforthechosentool.
Definetokens,whitespace,comments,andotherlexicalrules.
3. WriteTokenDefinitions:
Specifyregularexpressionsforeachtokentype(keywords,identifiers,numbers,operators).
Includeactionstobeperformedwheneachtokenisrecognized.
4. HandleWhitespaceandComments:
Definepatternsforwhitespace(spaces,tabs,newlines)andcomments(single-lineandmulti-line).
Specifyactionstoignorethesepatterns.
5. GeneratetheLexicalAnalyzer:
Runthelexicalanalyzergeneratortoproducethesourcecode.
6. IntegratetheLexicalAnalyzer:
Compilethegeneratedsourcecode.
Integrateitwiththerestofyourcompilerorinterpreter.
7. TesttheLexicalAnalyzer:
Createtestcasestoensurethelexicalanalyzercorrectlytokenizestheinput.
COMPILERDESIGNLAB
PROGRAM:
7
/*programnameislexp.l*/
%{
/* program to recognize a c program */
int COMMENT=0;
%}
identifier[a-zA-Z][a-zA-Z0-9]*
%%
#.*{printf("\n%sisaPREPROCESSORDIRECTIVE",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;}
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
"*/" {COMMENT = 0;}
/*printf("\n\n\t%sisaCOMMENT\n",yytext);}*/
{identifier}\({if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
{{if(!COMMENT)printf("\nBLOCKBEGINS");}}{if(!COMMENT)printf("\nBLOCKENDS");}
{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%sisanASSIGNMENTOPERATOR",yytext);}
<=|>=|<|==|>{if(!COMMENT)printf("\n\t%sisaRELATIONALOPERATOR",yytext);}
%%
intmain(intargc,char**argv)
if(argc>1)
FILE*file;
file=fopen(argv[1],"r");if(!file)
COMPILERDESIGNLAB
8
printf("couldnotopen%s\n",argv[1]);exit(0);
yyin=file;
yylex();
printf("\n\n");
return 0;
intyywrap()
return0;
Input
$vivar.c
#include
main()
inta,b;
Output
$lexlex.l
$cclex.yy.c
$./a.outvar.c
#includeisaPREPROCESSORDIRECTIVEFUNCTION
main()
BLOCKBEGINS
intisaKEYWORD
aIDENTIFIER
bIDENTIFIER
BLOCKENDS
COMPILERDESIGNLAB
9
03. CprogramtocalculatetheFirstandFollowsetsofagivengrammar.
ALGORITHM:
Step1:Initialize
1. InputtheGrammar:Readthegrammarproductions.
2. InitializeFirstandFollowSets:Createanemptysetforeachnon-terminalinthegrammar.
Step2:ComputeFirstSets
1. FirstofTerminals:Foreachterminal,itsFirstsetistheterminalitself.
2. FirstofNon-Terminals:
o For each production A -> α (where A is a non-terminal and α is a string of terminals and non-
terminals):
▪ Ifαisaterminal,addαtoFirst(A).
▪ Ifαisanon-terminalB,recursivelyaddFirst(B)toFirst(A):
▪ IfFirst(B)containsε,continuetothenextsymbolinα.
▪ Ifαisε,addεtoFirst(A).
Step3:ComputeFollowSets
1. FollowofStartSymbol:Add$(endofinputmarker)totheFollowsetofthestartsymbol.
2. FollowofNon-Terminals:
o ForeachproductionA->αBβ(whereA,Barenon-terminals,andα,βarestrings):
▪ AddFirst(β)(exceptε)toFollow(B).
▪ IfβisemptyorFirst(β)containsε,addFollow(A)toFollow(B).
o ForeachproductionA->αB:
▪ AddFollow(A)toFollow(B).
Step4:RepeatUntilStable
1.Iterate:RepeattheabovestepsuntilnomorechangesoccurintheFirstandFollowsets.
COMPILERDESIGNLAB
10
PROGRAM:
#include <ctype.h>
#include <stdio.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);
intcount,n=0;
//Storesthefinalresult
//oftheFirstSets
charcalc_first[10][100];
//Storesthefinalresult
//oftheFollowSets
char calc_follow[10][100];
int m = 0;
// Stores the production rules
char production[10][10];
char f[10], first[10];
int k;
charck;
int e;
COMPILERDESIGNLAB
11
intmain(intargc,char**argv)
int jm = 0;
int km = 0;
inti,choice;
char c, ch;
count = 8;
// The Input grammar
strcpy(production[0],"X=TnS");
strcpy(production[1],"X=Rm");
strcpy(production[2],"T=q");
strcpy(production[3],"T=#");
strcpy(production[4],"S=p");
strcpy(production[5],"S=#");
strcpy(production[6],"R=om");
strcpy(production[7],"R=ST");
intkay;
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] = '!';
intpoint1=0,point2,xxx;
COMPILERDESIGNLAB
12
for(k=0;k<count;k++){
c = production[k][0];
point2 = 0;
xxx=0;
//CheckingifFirstofchas
//alreadybeencalculated
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++) {
intlark=0,chk=0;
for(lark=0;lark<point2;lark++){
if(first[i]==calc_first[point1][lark]){
COMPILERDESIGNLAB
13
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;
intland=0;
for (e= 0; e< count;e++) {ck =
production[e][0];
point2 = 0;
COMPILERDESIGNLAB
14
xxx=0;
//CheckingifFollowofck
// has already been calculated
for(kay=0;kay<=ptr;kay++)
if (ck == donee[kay])
xxx = 1;
if(xxx==1)
continue;lan
d += 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++) {
intlark=0,chk=0;
for(lark=0;lark<point2;lark++){
if (f[i] == calc_follow[point1][lark]) {
chk = 1;
break;
COMPILERDESIGNLAB
15
if(chk==0){
printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i];
printf("}\n\n");
km = m;
point1++;
voidfollow(charc)
inti,j;
//Adding"$"tothefollow
// set of the start symbolif
(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]){
//CalculatethefollowoftheNon-TerminalintheL.H.S.
COMPILERDESIGNLAB
16
// of the production
follow(production[i][0]);
voidfindfirst(charc,intq1,intq2)
intj;
// 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++] = '#';
elseif(production[q1][q2]!='\0'
&&(q1!=0||q2!=0)){
//RecursiontocalculateFirstofNewNon-Terminal
// we encounter after epsilon
findfirst(production[q1][q2], q1,
(q2+1));
else
first[n++]='#';
COMPILERDESIGNLAB
17
else if (!isupper(production[j][2])) {
first[n++] = production[j][2];
else{
//RecursiontocalculateFirstofNewNon-Terminal
// we encounter at the beginning
findfirst(production[j][2], j, 3);
voidfollowfirst(charc,intc1,intc2)
intk;
// 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;
//IncludingtheFirstsetofthe
//Non-TerminalintheFollowof
//theoriginalquery
while(calc_first[i][j]!='!'){
if(calc_first[i][j]!='#'){
COMPILERDESIGNLAB
18
f[m++]=calc_first[i][j];
else{
if(production[c1][c2]=='\0'){
//Casewherewereachthe
// end of a production
follow(production[c1][0]);
else{
//Recursiontothenextsymbol
// in case we encounter a "#"
followfirst(production[c1][c2], c1,
c2+1);
j++;
COMPILERDESIGNLAB
19
04. DevelopanOperatorPrecedenceParserforagivenlanguage.
ALGORITHM:
1. DefineOperatorPrecedenceTable:
o Createatablethatdefinestheprecedenceandassociativityofoperators.
2. InitializeDataStructures:
o Usestacksforoperatorsandoperands.
3. ParsetheExpression:
o Readtokensfromtheinputexpression.
o Ifthetokenisanoperand,pushitontotheoperandstack.
o If the token is an operator, handle it based on its precedence relative to the operator on topof
the operator stack:
▪ Pop operators from the operator stack to the output until the top of the stack has an
operator of lower precedence.
▪ Pushthecurrentoperatorontotheoperatorstack.
4. FinalizeParsing:
o Afterreadingalltokens,popallremainingoperatorsfromtheoperatorstacktotheoutput.
5. EvaluatetheExpression:
o Usetheoperandstacktoevaluatetheexpressionbasedontheoperators.
PROGRAM:
#include<stdio.h>
#include<conio.h>
void main()
char stack[20], ip[20], opt[10][10][1], ter[10];
int i, j, k, n, top = 0, col, row;
clrscr();
COMPILERDESIGNLAB
20
for (i= 0; i < 10; i++) {
stack[i] = NULL;
ip[i]=NULL;
for (j= 0; j< 10; j++) {
opt[i][j][1] = NULL;
printf("Enter the no.of terminals :\n");
scanf("%d", & n);
printf("\nEnter the terminals :\n");
scanf("%s", & ter);
printf("\nEnter the table values :\n");
for (i = 0; i < n; i++) {
for(j=0;j<n;j++){
printf("Enter the value for %c %c:", ter[i], ter[j]);
scanf("%s", opt[i][j]);
printf("\n**** OPERATOR PRECEDENCE TABLE ****\n");
for (i = 0; i < n; i++) {
printf("\t%c",ter[i]);
printf("\n");
for (i = 0; i < n; i++) {
printf("\n%c", ter[i]);
for (j = 0; j < n; j++) {
printf("\t%c",opt[i][j][0]);
stack[top]='$';
COMPILERDESIGNLAB
21
printf("\nEnter the input string:");
scanf("%s", ip);
i=0;
printf("\nSTACK\t\t\tINPUT STRING\t\t\tACTION\n");
printf("\n%s\t\t\t%s\t\t\t", stack, ip);
while (i <= strlen(ip)) {
for (k = 0; k < n; k++) {
if (stack[top] == ter[k])
col = k;
if (ip[i]== ter[k])
row = k;
if ((stack[top] == '$') && (ip[i] == '$')) {
printf("String is accepted\n");
break;
}elseif((opt[col][row][0]=='<')||(opt[col][row][0]=='='))
stack[++top] = opt[col][row][0];
stack[++top] = ip[i];printf("Shift
%c", ip[i]);
i++;
}else{
if(opt[col][row][0]=='>'){
while(stack[top]!='<'){
--top;
top = top - 1;
printf("Reduce");
}else{
printf("\nStringisnotaccepted");
COMPILERDESIGNLAB
22
break;
printf("\n");
for (k =0; k <= top; k++) {
printf("%c", stack[k]);
printf("\t\t\t");
for (k = i; k < strlen(ip); k++) {
printf("%c", ip[k]);
printf("\t\t\t");
getch();
COMPILERDESIGNLAB
23
05. ConstructaRecursiveDescent Parserforanexpression.
ALGORITHM:
1. DefinetheGrammar:
o Definethegrammarrulesforthearithmeticexpressions.
o Example grammar:
E -> T E'
E' ->+ T E' |- T E' |ε T
-> F T'
T' ->* FT' | / FT' |ε F
-> ( E ) | id
2. Tokenization:
o Createatokenizerthatconvertstheinputstringintoasequenceoftokens.
o Tokens include identifiers (numbers), operators (+, -, *, /), parentheses ((, )), and the end-of-
input marker.
3. InitializeParsing:
o Initializetheinputstringandstartposition.
o Definethecurrentlookaheadtoken.
4. WriteRecursiveFunctionsforEachNon-Terminal:
o Writeafunctionforeachnon-terminalinthegrammar:
▪ EforExpression
▪ E'forExpressionPrime
▪ TforTerm
▪ T'forTermPrime
▪ FforFactor
5. ImplementtheParsingLogic:
o Eachfunctionshouldimplementtheproductionrulesforitscorrespondingnon-terminal.
o Userecursivecallstoparsesub-expressions.
6. MatchFunction:
o Implement a match function to compare the current token with the expected token and
advance to the next token if they match.
COMPILERDESIGNLAB
24
7. ErrorHandling:
o Adderrorhandlingtodetectandreportsyntaxerrors.
PROGRAM:
#include
#include
#include
charinput[100];
int i,l;
voidmain()
clrscr();
printf("\nRecursivedescentparsingforthefollowinggrammar\n");
printf("\nE->TE'\nE'->+TE'/@\nT->FT'\nT'->*FT'/@\nF->(E)/ID\n"); printf("\nEnter the string to be
checked:");
gets(input);
if(E())
if(input[i+1]=='\0')
printf("\nString is accepted");
else
printf("\nStringisnotaccepted");
else
printf("\nString not accepted");
getch();
E()
if(T())
COMPILERDESIGNLAB
25
{
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(0);
else
return(1);
T()
if(F())
COMPILERDESIGNLAB
26
{
if(TP())
return(1);
else
return(0);
else
return(0);
TP()
if(input[i]=='*')
i++;
if(F())
if(TP())
return(1);
else
return(0);
else
return(0);
else
return(1);
F()
if(input[i]=='(')
COMPILERDESIGNLAB
27
{
i++;
if(E())
if(input[i]==')')
i++;
return(1);
else
return(0);
else
return(0);
elseif(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')
i++;
return(1);
else
return(0);
INPUT&OUTPUT:
Recursive descent parsing for the following grammar
E->TE'
E'->+TE'/@
T->FT'
T'->*FT'/@
F->(E)/ID
COMPILERDESIGNLAB
28
Enter the string to be checked: (a+b)*c
String is accepted
Recursive descent parsing for the following grammar
E->TE'
E'->+TE'/@
T->FT'
T'->*FT'/@
F->(E)/ID
Enter the string to be checked:a/c+d
String is not accepted
COMPILERDESIGNLAB