Download Compiler Design Lab File and more Lab Reports Compiler Design in PDF only on Docsity!
G.L. Bajaj Institute of Technology and Management
Knowledge Park –III, Greater Noida (Uttar Pradesh)
Department of Computer Science and Technology
Session: 2020-2021 (Odd Semester)
Lab Name: Compiler Design Lab
Lab Code: KCS – 552
Semester: B.Tech CSE(V
TH
Lab File
Submitted To: Submitted By:
Mrs. Sonal Gandhi Name: Shreya Gupta
Roll No.: 1819210255
Index
S.NO. Experiment
Name
Date of
Experiment
Implementation of lexical analyzer and identify tokens from an arithmetic expression
Write a program for String Matching in C.
Write a program for removal of left recursion in the given grammar
Implementation of lexical analyser for arithmetic expression
Write a program in c for left factoring.
Compute first()
Compute follow() for given grammar
Shift reduce parser
Recursive descent parsing
int main()
inti=0,j=0,k=0;
char op[100],key[100],c;
while(1)
scanf("%c",&c);
if(c=='\n')
break;
else
if( c=='+' || c=='-' || c=='*' || c=='/' || c=='=')
op[j]=c;
j++;
else
key[i]=c;
i++;
printf("\nThe keywords and identifiersare:\n");
for(k=0;k<i;k++)
printf("%c is an identifier\n",key[k]);
printf("Special characters are");
for(k=0;k<j;k++)
printf("%c",op[k]);
printf("\nTotal no. of lines are:1");
return 0;
Output:
After writing any character,keyword,identifier we get their specific type.
top++; stack[top] = '{'; } "[" { top++; stack[top] = '['; } ")" { if (stack[top] != '(') { valid = 0; } else if(operands_count>0 && (operands_count-operators_count)!=1){ valid=0; } else{ top--; operands_count=1; operators_count=0; } } "}" { if (stack[top] != '{') { valid = 0; } else if(operands_count>0 && (operands_count-operators_count)!=1){ valid=0; } else{ top--; operands_count=1; operators_count=0; } } "]" { if (stack[top] != '[') { valid = 0; } else if(operands_count>0 && (operands_count-operators_count)!=1){ valid=0; } else{ top--; operands_count=1; operators_count=0; } } "+"|"-"|"*"|"/" { operators_count++;
strcpy(operators[l], yytext); l++; } [0-9]+|[a-zA-Z][a-zA-Z0-9_]* { operands_count++; strcpy(operands[j], yytext); j++; } %% int yywrap() { return 1; } int main() { int k; printf("Enter the arithmetic expression: "); yylex(); if (valid == 1 && top == -1) { printf("\nValid Expression\n"); } else printf("\nInvalid Expression\n"); return 0; }
Output:
will create infinite loop. This is because at every time of production of
grammar S will produce another S without checking any condition.
Procedure:
Start the program.
Ask the user to write a grammar production whether the grammar
is recursive or non- recursive.
Check using conditional statements if the index of the grammar is
same as the general form of left recursion.
If, yes then reduce the left recursion from grammar.
Program:
#include<stdio.h>
#include<string.h>
#define SIZE 10
int main () {
char non_terminal; char beta,alpha;
int num;
char production[10][SIZE];
int index=3; /* starting of the string following "->" */
printf("Enter Number of Production : ");
scanf("%d",&num);
printf("Enter the grammar:\n");
for(int i=0;i<num;i++){
scanf("%s",production[i]);
for(int i=0;i<num;i++){
printf("\nGRAMMAR : : : %s",production[i]);
non_terminal=production[i][0];
if(non_terminal==production[i][index]) {
alpha=production[i][index+1];
printf(" is left recursive.\n");
while(production[i][index]!=0 && production[i][index]!='|')
index++;
if(production[i][index]!=0) {
beta=production[i][index+1];
printf("Grammar without left recursion:\n");
printf("%c->%c%c'",non_terminal,beta,non_terminal);
printf("\n%c'->%c%c'|E\
n",non_terminal,alpha,non_terminal);
else
printf(" can't be reduced\n");
else
printf(" is not left recursive.\n");
index=3;
Output:
Experiment:
Objective: Implementation of Lexical Analyzer for Arithmetic
Expression
Brief Theory:
The lexical analyzer (either generated automatically by a tool like lex, or
hand-crafted) reads in a stream of characters, identifies the lexemes in
the stream, and categorizes them into tokens. This is called
"tokenizing". If the lexer finds an invalid token, it will report an error. A
lexical analyzer generally does nothing with combinations of tokens, a
task left for a parser. For example, a typical lexical analyzer recognizes
parentheses as tokens, but does nothing to ensure that each "(" is
Elimination of LEFT Recursion.
int main()
FILE f1,f2,*f3;
char c,str[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);
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);
else if(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 if(c=='\n')
lineno++;
else
putc(c,f3);
fclose(f2);
fclose(f3);
fclose(f1);
printf("Total no. of lines are:%d",lineno);
Output:
Experiment:
Objective: Write a program in C to do Left factoring
Brief Theory;
Left factoring is a process by which the grammar with common prefixes is transformed
to make it useful for Top down parsers.
If RHS of more than one production starts with the same symbol,
then such a grammar is called as Grammar With Common Prefixes.
A → αβ 1 / αβ 2 / αβ 3 This kind of grammar creates a problematic situation for Top down parsers. Lexical Analyser for arithmetic expression
Top down parsers can not decide which production must be chosen to parse the string in hand. To remove this confusion, we use left factoring. Procedure: Start the program. Check the grammar written by user is in the general form of left factoring given in above diagram. If yes , then change the grammar production according to given formula for left factoring. Stop the program.
Program:
#include<stdio.h> #include<string.h> int main() { char gram[20],part1[20],part2[20],modifiedGram[20],newGram[20]; int i,j=0,k=0,pos,size1,size2; printf("Enter Production : A->"); fgets(gram, 20, stdin); for(i=0;gram[i]!='|';i++,j++) part1[j]=gram[i]; part1[j]='\0'; for(j=++i,i=0;gram[j]!='\0';j++,i++)
} Output:
Experiment:
Objective: Compute First
Brief Theory: We formalise the task of picking a production rule using two functions, FIRST and FOLLOW. FIRST is applied to the r.h.s. of a production rule, and tells us all the terminal symbols that can start sentences derived from that r.h.s. It is defined as: For any terminal symbol a, =.
Procedure:
Start the program.
Removal of Left Factoring.
Check if the grammar production provide by user is free of left
recursion and left factoring.
If yes then find the first by entering terminals including operators
excluding null productions.
Program:
#include<stdio.h>
#include<ctype.h>
void FIRST(char );
int count,n=0;
char prodn[10][10], first[10];
int main()
int i;
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);
for(i=0;i<count;i++)
n=0;
printf("Element :");