0% found this document useful (0 votes)
18 views54 pages

Shivam CD

This document is a lab file for a Compiler Design course for B.Tech. CSE students, detailing various programming assignments related to lexical analysis, parsing, and grammar simulation. It includes specific tasks such as designing a lexical analyzer, simulating FIRST and FOLLOW sets, and implementing different types of parsers. The document also contains code snippets for each program demonstrating the implementation of these tasks.

Uploaded by

himanshumth2004
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)
18 views54 pages

Shivam CD

This document is a lab file for a Compiler Design course for B.Tech. CSE students, detailing various programming assignments related to lexical analysis, parsing, and grammar simulation. It includes specific tasks such as designing a lexical analyzer, simulating FIRST and FOLLOW sets, and implementing different types of parsers. The document also contains code snippets for each program demonstrating the implementation of these tasks.

Uploaded by

himanshumth2004
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/ 54

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

You might also like