Compiler Student Lab File Sample
Compiler Student Lab File Sample
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.
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:
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;
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);
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
while((c=getc(f2))!=EOF){
if(c!='')
str[k++]=c;
else
str[k]='\0';
keyword(str);
k=0;
fclose(f2);
f3=fopen("specialchar","r");
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
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*/
%{
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);}
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
/*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");}
(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>
intcount,n=0;
//Storesthefinalresult
//oftheFirstSets
charcalc_first[10][100];
//Storesthefinalresult
//oftheFollowSets
char calc_follow[10][100];
int m = 0;
char production[10][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;
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];
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
if (c == done[kay])
xxx=1;
if(xxx==1)
continue;
// Function call
findfirst(c,0, 0);
ptr+=1;
done[ptr] = c;
calc_first[point1][point2++] = c;
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){
calc_first[point1][point2++] = first[i];
printf("}\n");
jm = n;
point1++;
printf("\n");
printf(" "
"\n\n");
char donee[count];
ptr = -1;
calc_follow[k][kay]='!';
point1 = 0;
intland=0;
production[e][0];
point2 = 0;
COMPILERDESIGNLAB
14
xxx=0;
//CheckingifFollowofck
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;
donee[ptr] = ck;
calc_follow[point1][point2++] = ck;
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){
calc_follow[point1][point2++] = f[i];
printf("}\n\n");
km = m;
point1++;
voidfollow(charc)
inti,j;
//Adding"$"tothefollow
(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'){
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;
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
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
findfirst(production[j][2], j, 3);
voidfollowfirst(charc,intc1,intc2)
intk;
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
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()
clrscr();
COMPILERDESIGNLAB
20
for (i= 0; i < 10; i++) {
stack[i] = NULL;
ip[i]=NULL;
opt[i][j][1] = NULL;
for(j=0;j<n;j++){
scanf("%s", opt[i][j]);
printf("\t%c",ter[i]);
printf("\n");
printf("\n%c", ter[i]);
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");
if (stack[top] == ter[k])
col = k;
if (ip[i]== ter[k])
row = k;
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");
printf("%c", stack[k]);
printf("\t\t\t");
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'
-> F T'
-> ( 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");
checked:");
gets(input);
if(E())
if(input[i+1]=='\0')
printf("\nString is accepted");
else
printf("\nStringisnotaccepted");
else
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:
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
E->TE'
E'->+TE'/@
T->FT'
T'->*FT'/@
F->(E)/ID
COMPILERDESIGNLAB