Department of Computer Science &
Engineering
COMPILER DESIGN (CD)
LAB FILE
BCS- 652
B.Tech. CSE 3rd Year (VI Sem)
Academic Session 2024-25
Student Name: Kumar Shivam
Roll no.: 2302220109012
Faculty Name: Ms. Prachi Jain
Department of Computer Science & Engineering
Student’s Name: Kumar Shivam Rollno.:2302220109012
INDEX
S. No. LIST OF EXPERIMENT’S DATE OF TEACHER’S GRADE
COMPELETION SIGNATURE
1. Design a lexical analyzer for given language and the lexical
analyzer should ignore redundant spaces, tabs and new lines
2. Simulate First and Follow of a Grammar.
3. Develop an operator precedence parser for a given language.
4. Construct a recursive descent parser for an
expression.
5. Construct a LL(1) parser for an expression
6. Design predictive parser for the given language
7. Implementation of shift reduce parsing algorithm.
8. Design a LALR bottom up parser for the given language.
9. Implement the lexical analyzer using lex or other lexical
analyzer generating tools
10. Write a program to perform loop unrolling.
11. Convert the BNF rules into YACC form and write code to
generate abstract syntax tree.
12. Write a program for constant propagation.
PROGRAM-1
Design a lexical analyzer for given language and the lexical analyzer should ignore
redundant spaces, tabs and new lines
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_LEN 100
// Function to check if a word is a C keyword
int isKeyword(const char *str) {
const char *keywords[] = {
"int", "float", "char", "double", "if", "else", "for", "while",
"do", "return", "switch", "case", "break", "continue", "void", "static"
};
int n = sizeof(keywords) / sizeof(keywords[0]);
for (int i = 0; i < n; ++i) {
if (strcmp(str, keywords[i]) == 0) return 1;
return 0;
int main() {
FILE *fp;
char c, str[MAX_LEN];
int i;
// Create temporary file to simulate reading from a file
fp = tmpfile(); // creates a temporary in-memory file
if (!fp) {
perror("Unable to create temporary file");
return 1;
// Prompt user to enter code
char input_line[1000];
printf("Enter your code (type END on a new line to finish):\n");
while (fgets(input_line, sizeof(input_line), stdin)) {
if (strcmp(input_line, "END\n") == 0) break;
fputs(input_line, fp);
rewind(fp); // reset file pointer to beginning
// Start lexical analysis
while ((c = fgetc(fp)) != EOF) {
// Skip whitespace (spaces, tabs, newlines)
if (isspace(c)) continue;
// Identifiers or keywords
if (isalpha(c) || c == '_') {
i = 0;
str[i++] = c;
while (isalnum(c = fgetc(fp)) || c == '_') {
str[i++] = c;
str[i] = '\0';
ungetc(c, fp);
if (isKeyword(str))
printf("<%s, KEYWORD>\n", str);
else
printf("<%s, IDENTIFIER>\n", str);
// Numbers
else if (isdigit(c)) {
i = 0;
str[i++] = c;
while (isdigit(c = fgetc(fp))) {
str[i++] = c;
str[i] = '\0';
ungetc(c, fp);
printf("<%s, NUMBER>\n", str);
// Operators and special symbols
else {
if (strchr("+-*/=%;:,(){}[]<>!", c)) {
printf("<%c, SYMBOL>\n", c);
}
fclose(fp);
return 0;
Output:
PROGRAM-2
Simulate First and Follow of a Grammar.
a) FIRST
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 10
char prod[MAX][10];
int nop;
void FIRST(char[], char);
void addResult(char[], char);
int main() {
int i;
char c, choice;
char res[20];
printf("How many number of productions? : ");
scanf("%d", &nop);
printf("Enter the productions (like E=E+T or T=*F):\n");
for (i = 0; i < nop; i++) {
printf("Production %d: ", i + 1);
scanf("%s", prod[i]);
}
do {
printf("\nFind the FIRST of: ");
scanf(" %c", &c);
memset(res, '\0', sizeof(res));
FIRST(res, c);
printf("FIRST(%c) = { ", c);
for (i = 0; res[i] != '\0'; i++)
printf("%c ", res[i]);
printf("}\n");
printf("Press 'y' to continue: ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
return 0;
}
void FIRST(char res[], char c) {
int i, j, k;
char subres[20];
int hasEpsilon;
if (!isupper(c)) {
addResult(res, c);
return;
}
for (i = 0; i < nop; i++) {
if (prod[i][0] == c) {
if (prod[i][2] == '$') {
addResult(res, '$');
} else {
j = 2;
while (prod[i][j] != '\0') {
memset(subres, '\0', sizeof(subres));
FIRST(subres, prod[i][j]);
hasEpsilon = 0;
for (k = 0; subres[k] != '\0'; k++) {
if (subres[k] == '$') {
hasEpsilon = 1;
} else {
addResult(res, subres[k]);
}
}
if (!hasEpsilon)
break;
j++;
}
if (prod[i][j] == '\0') {
addResult(res, '$');
}
}
}
}
}
void addResult(char res[], char val) {
int k;
for (k = 0; res[k] != '\0'; k++) {
if (res[k] == val)
return;
}
res[k] = val;
res[k + 1] = '\0';
}
Output:
b) FOLLOW
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char prod[10][10];
char res[10];
int nop, m = 0;
void FOLLOW(char c);
void first(char c);
void result(char c);
int main() {
int i, choice;
char c, ch;
printf("Enter the number of
productions: ");
scanf("%d", &nop);
printf("Enter the productions (like
E=E+T):\n");
for (i = 0; i < nop; i++) {
printf("Production %d: ", i + 1);
scanf(" %s", prod[i]);
}
do {
m = 0;
memset(res, 0, sizeof(res));
printf("Find FOLLOW of --> ");
scanf(" %c", &c);
FOLLOW(c);
printf("FOLLOW(%c) = { ", c);
for (i = 0; i < m; i++) {
printf("%c ", res[i]);
}
printf("}\n");
printf("Do you want to continue?
(Press 1 to continue): ");
scanf("%d", &choice);
} while (choice == 1);
return 0;
}
void FOLLOW(char c) {
int i, j;
if (prod[0][0] == c)
result('$'); // $ is added to FOLLOW
of start symbol
for (i = 0; i < nop; i++) {
for (j = 2; j < strlen(prod[i]); j++) {
if (prod[i][j] == c) {
if (prod[i][j + 1] != '\0') {
first(prod[i][j + 1]);
}
if (prod[i][j + 1] == '\0' && c
!= prod[i][0]) {
FOLLOW(prod[i][0]);
}
}
}
}
}
void first(char c) {
int k;
if (!isupper(c)) {
result(c);
return;
}
for (k = 0; k < nop; k++) {
if (prod[k][0] == c) {
if (prod[k][2] == '$') {
FOLLOW(prod[k][0]); // ε →
follow of LHS
} else if (!isupper(prod[k][2])) {
result(prod[k][2]);
} else {
first(prod[k][2]); // recursive
}
}
}
}
void result(char c) {
int i;
for (i = 0; i < m; i++) {
if (res[i] == c)
return;
}
res[m++] = c;
}
Output:
PROGRAM-3
Develop an operator precedence parser for a given language.
#include <stdio.h>
#include <string.h>
char stack[20], ip[20], opt[10][10];
char ter[10];
int top = 0, n;
int getIndex(char symbol)
for (int i = 0; i < n; i++) {
if (ter[i] == symbol)
return i;
return -1;
int main()
int i, j, row, col;
printf("Enter the number of terminals: ");
scanf("%d", &n);
printf("Enter the terminals: ");
scanf("%s", ter);
printf("Enter the Operator Precedence Table (one character per entry: <, =, >):\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("Enter relation between %c and %c: ", ter[i], ter[j]);
scanf(" %c", &opt[i][j]);
printf("\nOperator Precedence Table:\n\t");
for (i = 0; i < n; i++) {
printf("%c\t", ter[i]);
printf("\n");
for (i = 0; i < n; i++) {
printf("%c\t", ter[i]);
for (j = 0; j < n; j++) {
printf("%c\t", opt[i][j]);
printf("\n");
printf("\nEnter the input string (append $ at the end): ");
scanf("%s", ip);
top = 0;
stack[top] = '$';
i = 0;
printf("\nSTACK\t\tINPUT\t\tACTION\n");
while (1) {
printf("%s\t\t%s\t\t", stack, &ip[i]);
char topSymbol = stack[top];
char currentSymbol = ip[i];
row = getIndex(topSymbol);
col = getIndex(currentSymbol);
if (topSymbol == '$' && currentSymbol == '$')
printf("Accepted\n");
break;
if (row == -1 || col == -1)
printf("Error: invalid symbol.\n");
break;
char precedence = opt[row][col];
if (precedence == '<' || precedence == '=')
// Shift
stack[++top] = currentSymbol;
i++;
printf("Shift\n");
else if (precedence == '>')
// Reduce
printf("Reduce\n");
top--; // remove one symbol (basic simulation)
else
printf("Error: no precedence relation.\n");
break;
return 0;
Output:
PROGRAM-4
Construct a recursive descent parser for an expression.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char input[100];
int i = 0, error = 0;
void E();
void Eprime();
void T();
void Tprime();
void F();
int main() {
printf("Enter an arithmetic expression: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0'; // remove trailing newline
E();
if (i == strlen(input) && error == 0)
printf("\nAccepted..!!!\n");
else
printf("\nRejected..!!!\n");
return 0;
void E() {
T();
Eprime();
void Eprime() {
if (input[i] == '+') {
i++;
T();
Eprime();
void T() {
F();
Tprime();
void Tprime() {
if (input[i] == '*') {
i++;
F();
Tprime();
void F() {
if (input[i] == '(') {
i++;
E();
if (input[i] == ')') {
i++;
} else {
error = 1;
} else if (isalpha(input[i])) {
i++;
while (isalnum(input[i]) || input[i] == '_') {
i++;
} else {
error = 1;
Output:
PROGRAM-5
Construct a LL(1) parser for an expression
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char stack[100], input[100];
int top = -1, i = 0;
// Predictive Parsing Table
// Non-terminals: E=0, X=1, T=2, Y=3, F=4
// Terminals: + * i ( ) $
char *table[5][6] = {
/* E */ {"", "", "TX", "TX", "", ""},
/* X */ {"+TX","", "", "", "e", "e"},
/* T */ {"", "", "FY", "FY", "", ""},
/* Y */ {"e", "*FY","", "", "e", "e"},
/* F */ {"", "", "i", "(E)", "", ""}
};
int getRow(char nonTerminal)
switch (nonTerminal)
case 'E': return 0;
case 'X': return 1;
case 'T': return 2;
case 'Y': return 3;
case 'F': return 4;
default: return -1;
int getCol(char terminal)
switch (terminal)
case '+': return 0;
case '*': return 1;
case 'i': return 2;
case '(': return 3;
case ')': return 4;
case '$': return 5;
default: return -1;
void push(char c)
stack[++top] = c;
char pop()
return stack[top--];
}
void displayStackAndInput()
for (int j = 0; j <= top; j++)
printf("%c", stack[j]);
printf("\t\t");
for (int j = i; input[j] != '\0'; j++)
printf("%c", input[j]);
printf("\t\t");
int main() {
printf("Enter the input string (end with $): ");
scanf("%s", input);
if (input[strlen(input) - 1] != '$')
strcat(input, "$");
top = -1;
push('$');
push('E');
printf("\nStack\t\tInput\t\tAction\n");
while (top >= 0)
{
displayStackAndInput();
char stackTop = stack[top];
char currentInput = input[i];
if (stackTop == currentInput && stackTop == '$')
printf("Accepted!\n");
break;
else if (stackTop == currentInput)
printf("Match %c\n", currentInput);
pop();
i++;
else if (isupper(stackTop))
int row = getRow(stackTop);
int col = getCol(currentInput == 'i' ? 'i' : currentInput);
if (row == -1 || col == -1 || strcmp(table[row][col], "") == 0) {
printf("Error: No rule for %c with %c\n", stackTop, currentInput);
break;
char production[10];
strcpy(production, table[row][col]);
printf("%c → %s\n", stackTop, strcmp(production, "e") == 0 ? "ε" : production);
pop();
if (strcmp(production, "e") != 0) {
for (int k = strlen(production) - 1; k >= 0; k--)
push(production[k]);
else
printf("Error: Mismatched symbol %c on stack\n", stackTop);
break;
if (stack[top] == '$' && input[i] == '$')
printf("\n✅ Parsing completed. String accepted.\n");
} else
printf("\n❌ Parsing failed. String rejected.\n");
return 0;
}
Output:
PROGRAM-6
Design predictive parser for the given language
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 30
char stack[100];
int top = -1;
char nt[] = {'E', 'X', 'T', 'Y', 'F'}; // Non-terminals
char t[] = {'+', '*', 'i', '(', ')', '$'}; // Terminals
int n1 = 5, n2 = 6;
// LL(1) Parsing table
char table[5][6][10] = {
{"", "", "TX", "TX", "", ""},
{"+TX", "", "", "", "e", "e"},
{"", "", "FY", "FY", "", ""},
{"e", "*FY", "", "", "e", "e"},
{"", "", "i", "(E)", "", ""}
};
// Map non-terminal to index
int getNTIndex(char c) {
for (int i = 0; i < n1; i++)
if (nt[i] == c) return i;
return -1;
}
// Map terminal to index
int getTIndex(char c) {
for (int i = 0; i < n2; i++)
if (t[i] == c) return i;
return -1;
void push(char c) {
stack[++top] = c;
void pop() {
top--;
int main() {
char input[SIZE];
printf("Enter input string (end with $): ");
scanf("%s", input);
// Initialize stack
top = -1;
push('$');
push('E');
int i = 0;
printf("\nSTACK\t\tINPUT\t\tACTION\n");
while (1) {
// Print current stack
for (int k = 0; k <= top; k++) printf("%c", stack[k]);
printf("\t\t%s\t\t", &input[i]);
char X = stack[top];
char a = input[i];
if (X == '$' && a == '$') {
printf("✔️ Accepted\n");
break;
if (X == a) {
pop();
i++;
printf("Match %c\n", a);
} else if (getNTIndex(X) != -1) {
int row = getNTIndex(X);
int col = getTIndex(a);
if (row == -1 || col == -1 || strcmp(table[row][col], "") == 0 || strcmp(table[row][col], "n")
== 0) {
printf("❌ Error: No rule for %c with %c\n", X, a);
break;
} else {
printf("%c → %s\n", X, strcmp(table[row][col], "e") == 0 ? "ε" : table[row][col]);
pop();
if (strcmp(table[row][col], "e") != 0) {
for (int j = strlen(table[row][col]) - 1; j >= 0; j--) {
push(table[row][col][j]);
}
}
} else {
printf("❌ Error: Mismatched symbol %c\n", X);
break;
return 0;
Output:
PROGRAM-7
Implementation of shift reduce parsing algorithm.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char ip_sym[15], stack[15];
int ip_ptr = 0, st_ptr = 0, len, i;
char temp[2], temp2[2];
char act[15];
void check();
int main() {
printf("\n\t\tSHIFT REDUCE PARSER\n");
printf("\nGRAMMAR:");
printf("\nE -> E+E\nE -> E/E\nE -> E*E\nE -> a/b\n");
printf("\nEnter the input string (e.g., a+a*a): ");
scanf("%s", ip_sym);
printf("\nStack\t\tInput Symbol\t\tAction");
printf("\n \t\t \t\t ");
printf("\n$\t\t%s$\t\t--", ip_sym);
strcpy(act, "Shift ");
temp[0] = ip_sym[ip_ptr];
temp[1] = '\0';
strcat(act, temp);
len = strlen(ip_sym);
for (i = 0; i < len; i++) {
stack[st_ptr++] = ip_sym[ip_ptr]; // push to stack
stack[st_ptr] = '\0';
ip_sym[ip_ptr] = ' ';
ip_ptr++;
printf("\n$%s\t\t%s$\t\t\t%s", stack, ip_sym, act);
strcpy(act, "Shift ");
temp[0] = ip_sym[ip_ptr];
temp[1] = '\0';
strcat(act, temp);
check(); // Try reducing after each shift
check(); // Final check after input is consumed
return 0;
void check() {
int flag = 0;
// Reduce a or b to E
if (stack[st_ptr - 1] == 'a' || stack[st_ptr - 1] == 'b') {
printf("\n$");
stack[st_ptr - 1] = 'E';
for (int j = 0; j < st_ptr; j++) printf("%c", stack[j]);
printf("\t\t%s$\t\t\tE->%c", ip_sym, stack[st_ptr - 1]);
flag = 1;
}
// Reduce E+E, E*E, E/E to E
while (st_ptr >= 3) {
if ((stack[st_ptr - 3] == 'E') &&
(stack[st_ptr - 2] == '+' || stack[st_ptr - 2] == '*' || stack[st_ptr - 2] == '/') &&
(stack[st_ptr - 1] == 'E')) {
char op = stack[st_ptr - 2];
st_ptr -= 3;
stack[st_ptr++] = 'E';
stack[st_ptr] = '\0';
printf("\n$%s\t\t%s$\t\t\tE->E%cE", stack, ip_sym, op);
flag = 1;
} else break;
// Accept if fully reduced to E and input is consumed
if (!strcmp(stack, "E") && ip_ptr == len) {
printf("\n$%s\t\t%s$\t\t\tACCEPT\n", stack, ip_sym);
exit(0);
if (flag == 0 && ip_ptr == len) {
printf("\n$%s\t\t%s$\t\t\tREJECT\n", stack, ip_sym);
exit(0);
}
Output:
PROGRAM-8
Design a LALR bottom up parser for the given language.
{%
#nclude<stdio.h> #include<conio.h> intyylex(void);
%}
%token ID
%start line
%%
line:expr '\n', {printf("%d",S1);} expr:expr'+'term {SS=S1+S3;}
|term
term:term'*'factor {SS=S1+S3;}
|factor
factor:'('expr')' {SS=S2;}
|ID
%%
yylex()
char c[10],i;
gets(c); if(isdigit(c))
yylval=c; return ID;
return c;
}
Output:
$vi lalr.y
$yacc –v lalr.y
$vi y.output
y.output contains the ouput
1 line : expr '\n'
2 expr : expr '+' term
3 | term
4 term : term '*' factor
5 | factor
6 factor : '(' expr ')'
7 | ID
^L state 0
$accept : . line $end (0)
ID shift 1
'(' shift 2
. error line goto 3
exprgoto 4
term goto 5
state 1
factor : ID . (7)
. reduce 7
state 2
factor : '(' . expr ')' (6)
ID shift 1
'(' shift 2
. error exprgoto 7
term goto 5
factor goto 6
state 3
$accept : line . $end (0)
$end accept state 4
line :expr . '\n' (1)
expr :expr . '+' term (2) '\n' shift 8
'+' shift 9
. error state 5
expr : term . (3)
term : term . '*' factor (4) '*' shift 10
'\n' reduce 3
'+' reduce 3
')' reduce 3
state 6
term : factor . (5)
. reduce 5
state 7
expr :expr . '+' term (2) factor : '(' expr . ')' (6)
'+' shift 9
')' shift 11
. error state 8
line :expr '\n' . (1)
. reduce 1
state 9
expr :expr '+' . term (2)
ID shift 1
'(' shift 2
. error term goto 12
factor goto 6
state 10
term : term '*' . factor (4)
ID shift 1
'(' shift 2
. error factor goto 13
state 11
factor : '(' expr ')' . (6)
. reduce 6
state 12
expr :expr '+' term . (2) term : term . '*' factor (4)
'*' shift 10
'\n' reduce 2
'+' reduce 2
')' reduce 2
state 13
term : term '*' factor . (4)
. reduce 4
8 terminals, 5 nonterminals
8 grammar rules, 14 states
PROGRAM-9
Implement the lexical analyzer using lex or other lexical analyzer generating tools
// Program name as “lexicalfile.l”
%{
#include<stdio.h>
%}
delim
[\t] ws
{delim}
+
letter [A-Za-
z] digit [0-9]
id {letter}({letter}|{digit})*
num {digit}+(\.{digit}+)?(E[+|-]?{digit}+)?
%%
ws {printf("no action");}
if|else|then {printf("%s is a keyword",yytext);} // TYPE 32 KEYWORDS
{id} {printf("%s is a identifier",yytext);}
{num} {printf(" it is a number");}
"<" {printf("it is a relational operator less than");}
"<=" {printf("it is a relational operator less than or
equal");} ">" {printf("it is a relational operator
greater than");}
">=" {printf("it is a relational operator greater
than");} "==" {printf("it is a relational operator
equal");}
"<>" {printf("it is a relational operator not equal");}
%%
main()
{
yylex();
}
Output:
lexlexicalfi
le.l cc
lex.yy.c -
ll if
if is a keyword
number
number is a
identifier 254
It is a number
<>
it is a relational operator not equal
^Z
PROGRAM-10
Write a program to perform loop unrolling.
#include<stdio.h> int main()
int i; for(i=0;i<10;i+=2)
printf("fun(%d)\n",i+1);
printf("fun(%d)\n",i+2);
Output:
fun(1)
fun(2)
fun(3)
fun(4)
fun(5)
fun(6)
fun(7)
fun(8)
fun(9) fun(10)
PROGRAM-11
Convert the BNF rules into YACC form and write code to generate abstract syntax
tree.
<int.l>
%{
#include"y.tab.h"
#include<stdio.h>****
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-
9]* number [0-9]+|([0-9]*\.[0-
9]+)
%%
main\(\) return
MAIN; if return
IF;
else return ELSE;
while return
WHILE; int |
char |
float return TYPE;
{identifier}
{strcpy(yylval.var,yytext); return
VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
\<= |
==
{strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
<int.y>
%{
#include<string.
h>
#include<stdio.
h> struct quad
{
char
op[5];
char
arg1[10];
char
arg2[10];
char
result[10];
}QUAD[30];
struct stack
{
int
items[100]
; int top;
}stk;
int
Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
| CONDST
| WHILEST
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1)
;
strcpy($$,QUAD[Index++].result
);
}
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FAL
SE");
strcpy(QUAD[Index].result,"-
1"); push(Index);
Index++;
}
BLO
CK {
strcpy(QUAD[Index].op,"GOTO
");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-
1"); push(Index);
Index++;
};
ELSEST: ELSE{
tInd=p
op();
Ind=p
op();
push(t
Ind);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLO
CK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
| IFST ELSEST
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"=="); strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE"); strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
} BLOCK {
strcpy(QUAD[Index].op,"GOTO"); strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
};
ELSEST: ELSE{
tInd=pop(); Ind=pop(); push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
} BLOCK{
Ind=pop(); sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR
{AddQuadruple($2,$1,$3,$$); StNo=Index-1;
}
| VAR
| NUM
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FAL
SE");
strcpy(QUAD[Index].result,"-
1"); push(Index);
Index++;
}
BLO
CK {
strcpy(QUAD[Index].op,"GOTO
");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-
1"); push(Index);
Index++;
}
%%
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE
*fp;
int i;
if(arg
c>1)
{
fp=fopen(argv[1],"r")
; if(!fp)
{
printf("\n File not found"); exit(0);
yyin=fp;
yyparse();
printf("\n\n\t\t ----------------------------""\n\t\t Pos Operator Arg1 Arg2 Result" "\n\t\t--------- ");
for(i=0;i<Index;i++)
printf("\n\t\t %d\t %s\t %s\t %s\t
%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
printf("\n\t\t ");
printf("\n\n"); return 0;
void push(int data)
stk.top++; if(stk.top==100)
printf("\n Stack overflow\n"); exit(0);
stk.items[stk.top]=data;
int pop()
{
int data;
if(stk.top=
=-1)
{
printf("\n Stack
underflow\n"); exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"t%d",tIndex++)
; strcpy(result,QUAD[Index++].result);
}
yyerror()
{
printf("\n Error on line no:%d",LineNo);
}
Input:
$vi
test1.
c
main(
)
{
int
a,b,
c;
if(a
<b)
{
a=a+b;
}
while(a<b)
{
a=a+b;
if(a<=b)
c=a-b;
else
c=a+b;
Output:
$lex int.l
$yacc –d –v int.y
$gcc lex.yy.c y.tab.c –lm
$./a.out test1.c
PROGRAM-12
Write a program for constant propagation.
#include<stdio.h> int main()
int x, y, z; x = 10;
y = x + 45;
z = y + 4;
printf("The value of z = %d", z); return 0;
Output:
$ vi test.c
$ cc –c –S test.c
$ vi test.s //before optimization assembly code
main:
pushl %ebp
movl %esp,
%ebp andl $-
16, %esp subl
$32, %esp
movl $10,
20(%esp)
movl 20(%esp),
%eax addl $45,
%eax
movl %eax,
24(%esp) movl
24(%esp), %eax
addl $4, %eax
movl %eax,
28(%esp) movl
$.LC0,
%eax movl
28(%esp),
%edx movl
%edx,
4(%esp) movl
%eax,
(%esp) call printf
movl $0,
%eax leave
ret
$ cc –c –S -O2 test.c
$ vi test.s //after optimization assembly
code main:
pushl %ebp
movl %esp,
%ebp andl
$-16,
%esp subl
$16, %esp
movl $59,
4(%esp) movl
$.LC0,
(%esp) call
printf
xorl %eax,
%eax leave
ret