0% found this document useful (0 votes)
49 views

Compiler Design Lab Report

Uploaded by

test46.aman
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)
49 views

Compiler Design Lab Report

Uploaded by

test46.aman
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/ 44

INDIAN INSTITUTE OF INFORMATION

TECHNOLOGY, MANIPUR

Dr. Rajkumari Bidyalakshmi Devi


5th Semester
CS3044: Compiler Design

Date: - 08-11-2023
Name: -Mahi Chhawchharia
Roll no: -220103029
Subject: - CS3044: Compiler Design Lab

Department of Computer Science & Engineering


Senapati, India – 795002
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-1

1. What is LEX in compiler Design? Explain the structure of a LEX program.

Lex is a program that generates lexical analyzer. It is used with YACC (Yet
Another Compiler Compiler) parser generator.
The lexical analyzer is a program that transforms an input stream into a
sequence of tokens.
It reads the input stream and produces the source code as output through
implementing the lexical analyzer in the C program.

Structure of a LEX program:


%{
Definition section
%}

%%
Rules section
%%

User Subroutine section

2. Write a lex program to check whether a given number is even or odd.


%{
#include<stdio.h>
int i;
%}

%%
[0-9]+ {i=atoi(yytext);
if(i%2==0)
printf("Even");
else
printf("Odd");}
%%

int yywrap(){}
int main()
{

yylex();
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-1

3. Write a lex program to count the no. of vowels and consonants in a given
string.

%{
#include<stdio.h>
int vowels=0;
int consonants=0;
%}
%%

[aeiouAEIOU] {vowels++;}
[a-zA-Z] {consonants++;}
%%

int yywrap(){}

void main()
{
printf("Enter the string:\n");
yylex();
printf("\nNumber of vowels=%d\n",vowels);
printf("Number of consonants=%d\n",consonants);

}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-1
4. Write a lex program to check whether a given number is an Armstrong number
or not.
%{
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
void check(char* a);
extern char* yytext;
%}

%%
[0-9]+ check(yytext);
%%

int yywrap() {}

void check(char* a)
{
int num = atoi(a);
int p = strlen(a);
int y = 0, temp = num;
while (num > 0)
{
y += pow((num % 10), p);
num = num / 10;
}
if (y == temp)
printf("%d is an Armstrong number\n", temp);
else
printf("%d is not an Armstrong number\n", temp);
}

int main()
{
yylex();
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-2

1. Write a lex program to count the positive numbers, negative numbers, and
fractions.
%{
#include<stdio.h>
int pos=0, neg=0,frac=0;
%}

%%
[0-9]+ { pos++;}
-[0-9]+ { neg++;}
[0-9]*\.[0-9]+ { frac++; }
-[0-9]*\.[0-9]+ { frac++; }
%%

int yywrap(){}

int main()
{
printf("Enter the string:\n");
yylex();
printf("\nNumber of positive number = %d\n",pos);
printf("Number of negative number = %d\n",neg);
printf("Number of fraction number = %d\n",frac);
return 0;

}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-2
2. Write a lex program to count words that are less than 10 and greater than 5
from a given sentence.
%{
#include<stdio.h>
#include<string.h>
int l=0,c=0;
%}

%%
[a-zA-Z]+ {
l= strlen(yytext);
if(l<10 && l>5)
c++;
}

%%

int yywrap(){}

int main()
{
printf("Enter the string:\n");
yylex();
printf("\nNumber of words < 10 but > 5 = %d\n",c);
return 0;

}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-2
3. Write a lex program to count the no. of vowels and consonants in a given
string.

%{
#include<stdio.h>
int line_c=0, space_c=0,tab_c=0;
%}

%%
[\n] { line_c++;}
[ ] { space_c++;}
[\t] { tab_c++; }
[^\t] {}
%%

int yywrap(){}

int main()
{
printf("Enter the string:\n");
yylex();
printf("\nNumber of lines = %d\n",line_c);
printf("Number of spaces = %d\n",space_c);
printf("Number of tabs = %d\n",tab_c);
return 0;

}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-3

1. Write a Lex program to count the total number of tokens.


%{
int opCount = 0;
int idenCount = 0;
int keyCount = 0;
int ssCount = 0;
int token =0;
%}
KEYWORDS
(auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|
for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|
typedef|union|unsigned|void|volatile|while)
ARITHMETIC (\+|-|\*|\/|%|\+\+|--)
RELATIONAL (==|!=|>=|<=|>|<)
LOGICAL (&&|\|\||!)
BITWISE (\^|\||&|<<|>>)
ASSIGNMENT (=|\+=|-=|\*=|\/=|%=)
OPERATORS ({ARITHMETIC}|{RELATIONAL}|{LOGICAL}|{BITWISE}|{ASSIGNMENT})
SPECIAL_SYMBOLS [;{}\(\)\[\]@#$,"`~!&?\\\.\*]
%%
[\t]+ ;

{OPERATORS} {
opCount++;
}

{KEYWORDS} {
keyCount++;
}

[a-zA-Z_][a-zA-Z0-9_]* {
idenCount++;
}
{SPECIAL_SYMBOLS} {
ssCount++;
}

. {}

\n {}
%%
int main()
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-3

{
printf("Write the C program:\n");
yylex();
token = opCount+idenCount+keyCount+ssCount;
printf("Number of Tokens: %d\n", token);
return 0;
}

2. Write a lex program to recognize identifiers, keywords, and numbers.


%{

int identifiersCount = 0;
int keywordsCount = 0;
int num = 0;
%}

KEYWORDS
(auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|
for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|
typedef|union|unsigned|void|volatile|while)
%%

[\t]+ ;

{KEYWORDS} {
keywordsCount++;
}

[a-zA-Z_][a-zA-Z0-9_]* {
identifiersCount++;
}

[0-9]*[eE][+-]?[0-9]+ { num++; }
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-3

[0-9]*\.[0-9]+ { num++; }
[0-9]+ { num++;}
. {}

\n {}

%%

int main()
{
printf("Write the C program:\n");
yylex();

printf("Number of Identifiers: %d\n", identifiersCount);


printf("Number of Keywords: %d\n", keywordsCount);
printf("Number of Numbers: %d\n", num);
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4

1. Write a lex program to identify the REAL PRECISION of the given number.
%{
#include<stdio.h>
int pre=0;

%}
F1 [0-9]*\.[0-9]+
%%
{F1} {
char *d = yytext;
int flag =0;
pre = 0;
while(*d != '\0')
{
if(*d == '.')
{
flag =1;
d++;

}
if(flag == 1)
{
pre++;
}
d++;
}

printf("Precision : %d \n ",pre);
}
[0-9]+ {printf("Precision : 0\n ");}
. {}
[\t\n]+ {}
%%
int main()
{
yylex();
return 0;
}
int yywrap()
{
return 1;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4
OUTPUT:

2. Write a program to implement the elimination of left recursion.


#include <bits/stdc++.h>
using namespace std;

class NonTerminal {
string name; // Stores the Head of production rule
vector<string> productionRules; // Stores the body of production rules

public:
NonTerminal(string name) {
this->name = name;
}

// Returns the head of the production rule


string getName() {
return name;
}

// Returns the body of the production rules


void setRules(vector<string> rules) {
productionRules.clear();
for (auto rule : rules){
productionRules.push_back(rule);
}
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4

vector<string> getRules() {
return productionRules;
}

void addRule(string rule) {


productionRules.push_back(rule);
}

// Prints the production rules


void printRule() {
string toPrint = "";
toPrint += name + " ->";

for (string s : productionRules){


toPrint += " " + s + " |";
}

toPrint.pop_back();
cout << toPrint << endl;
}
};

class Grammar {
vector<NonTerminal> nonTerminals;

public:
// Add rules to the grammar
void addRule(string rule) {
bool nt = 0;
string parse = "";

for (char c : rule){


if (c == ' ') {
if (!nt) {
NonTerminal newNonTerminal(parse);
nonTerminals.push_back(newNonTerminal);
nt = 1;
parse = "";
} else if (parse.size()){
nonTerminals.back().addRule(parse);
parse = "";
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4
}else if (c != '|' && c != '-' && c != '>'){
parse += c;
}
}
if (parse.size()){
nonTerminals.back().addRule(parse);
}
}

void inputData() {
string rule="";
cout << "Enter production rule : ";
getline(cin, rule);
addRule(rule);

// Algorithm for eliminating the non-Immediate Left Recursion


void solveNonImmediateLR(NonTerminal &A, NonTerminal &B) {
string nameA = A.getName();
string nameB = B.getName();

vector<string> rulesA, rulesB, newRulesA;


rulesA = A.getRules();
rulesB = B.getRules();

for (auto rule : rulesA) {


if (rule.substr(0, nameB.size()) == nameB) {
for (auto rule1 : rulesB){
newRulesA.push_back(rule1 + rule.substr(nameB.size()));
}
}
else{
newRulesA.push_back(rule);
}
}
A.setRules(newRulesA);
}

// Algorithm for eliminating Immediate Left Recursion


void solveImmediateLR(NonTerminal &A) {
string name = A.getName();
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4
string newName = name + "'";

vector<string> alphas, betas, rules, newRulesA, newRulesA1;


rules = A.getRules();

// Checks if there is left recursion or not


for (auto rule : rules) {
if (rule.substr(0, name.size()) == name){
alphas.push_back(rule.substr(name.size()));
}
else{
betas.push_back(rule);
}
}

// If no left recursion, exit


if (!alphas.size())
return;

if (!betas.size())
newRulesA.push_back(newName);

for (auto beta : betas)


newRulesA.push_back(beta + newName);

for (auto alpha : alphas)


newRulesA1.push_back(alpha + newName);

// Amends the original rule


A.setRules(newRulesA);
newRulesA1.push_back("\u03B5");

// Adds new production rule


NonTerminal newNonTerminal(newName);
newNonTerminal.setRules(newRulesA1);
nonTerminals.push_back(newNonTerminal);
}

// Eliminates left recursion


void applyAlgorithm() {
int size = nonTerminals.size();
for (int i = 0; i < size; i++){
for (int j = 0; j < i; j++){
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-4
solveNonImmediateLR(nonTerminals[i], nonTerminals[j]);
}
solveImmediateLR(nonTerminals[i]);
}
}

// Print all the rules of grammar


void printRules() {
for (auto nonTerminal : nonTerminals){
nonTerminal.printRule();
}
}
};

int main(){
//freopen("output.txt", "w+", stdout);

Grammar grammar;
grammar.inputData();
grammar.applyAlgorithm();
grammar.printRules();

return 0;
}

OUTPUT:
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-5
1. Write a program in any language to implement the recursive descent parser.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str[32];
char *ptr;
int E(), E_prime(), T(), T_prime(), F();
int F()
{
if( *ptr == '(')
{
ptr++;
if(E())
{
if( *ptr == ')')
{
ptr++;
return 1;
}
else return 0;
}
else return 0;
}
else if (*ptr == 'i' && *(ptr+1) == 'd')
{
ptr++;
return 1;
}
else
{
return 0;
}
}
int T_prime()
{
if( *ptr == '*')
{
ptr++;
if(F())
{
if(T_prime())
return 1;
else
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-5
return 0;
}
else
{
return 0;
}
}
}

int E_prime()
{
if( *ptr == '+')
{
ptr++;
if(T())
{
if(E_prime())
return 1;
else
return 0;
}
else
{
return 0;
}
}
}

int T()
{
if(F())
{
if(T_prime())
return 1;
else
return 0;
}
else
{
return 0;
}
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-5

int E()
{
if(T())
{
if(E_prime())
return 1;
else
return 0;
}
else
{
return 0;
}
}
int main()
{

printf("E -> TE'\nE' -> +TE' | ε\nT -> FT'\nT' -> *FT' | ε\nF ->(E) |
id\n");
int ch =1;
do{

printf("Enter the string without spaces:");


scanf("%s", str);
ptr = str;
if(E())
printf("Input string is ACCEPTED by the above grammar!!\n");
else
printf("Input string is NOT ACCEPTED by the above grammar!!\n");

printf("Enter 0 to exit the parser \nEnter any charcter other than 0 to


continue\n Choice:");
scanf("%d", &ch);
}while(ch != 0);

return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-5
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-6

1. Write a program to implement the predictive parser for the following


grammar:
E->E+T|T
T->T*F|F
F->(E)|id

#include <iostream>
#include <string>
#include <map>
#include <stack>

using namespace std;

// Grammar
const string prod[] = {"E->T A", "A->+ T A | e", "T->F B", "B->* F B | e",
"F->(E) | i"};
const string first[] = {"i", "+, e", "i", "*, e", "i"};
const string follow[] = {"$, )", "$, )", "+, $, )", "+, $, )", "*, +, $, )"};

// Define the parsing table using map


map<string, map<char, string>> table;

// Initialize the parsing table


void initializeTable() {
table["E"]['('] = "E->T A";
table["E"]['i'] = "E->T A";
table["E"]['+'] = "EMPTY";
table["E"]['*'] = "EMPTY";
table["E"][')'] = "EMPTY";
table["E"]['$'] = "EMPTY";

table["A"]['('] = "EMPTY";
table["A"]['i'] = "EMPTY";
table["A"]['+'] = "A->+ T A";
table["A"]['*'] = "EMPTY";
table["A"][')'] = "e";
table["A"]['$'] = "e";

table["T"]['('] = "T->F B";


table["T"]['i'] = "T->F B";
table["T"]['+'] = "EMPTY";
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-6

table["T"]['*'] = "EMPTY";
table["T"][')'] = "EMPTY";
table["T"]['$'] = "EMPTY";

table["B"]['('] = "EMPTY";
table["B"]['i'] = "EMPTY";
table["B"]['+'] = "e";
table["B"]['*'] = "B->* F B";
table["B"][')'] = "e";
table["B"]['$'] = "e";

table["F"]['('] = "F->(E)";
table["F"]['i'] = "F->i";
table["F"]['+'] = "EMPTY";
table["F"]['*'] = "EMPTY";
table["F"][')'] = "EMPTY";
table["F"]['$'] = "EMPTY";
}

void display(stack<char> s) {
stack<char> temp = s;
while (!temp.empty()) {
cout << temp.top();
temp.pop();
}
}

void printGrammarAndTable() {
cout << "Grammar:\n";
for (const string& p : prod) {
cout << p << endl;
}

cout << "\nPredictive Parsing Table:\n";


cout << " ( i + * ) $\n";
cout << "-------------------------------------\n";
for (const auto& nonTerminal : table) {
cout << nonTerminal.first << " ";
for (char c : {'(', 'i', '+', '*', ')', '$'}) {
string value = table.at(nonTerminal.first).count(c) ?
table.at(nonTerminal.first).at(c) : "EMPTY";
cout << value << " ";
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-6

}
cout << endl;
}
cout << "-------------------------------------\n";
}

int main() {
string input;
cout << "Enter the input string terminated with $ to parse: ";
cin >> input;

if (input.back() != '$') {
cout << "Input String Entered Without End Marker $" << endl;
return 1;
}

stack<char> s;
s.push('$');
s.push('E');

int i = 0;
cout << "\nStack\t Input\tAction" << endl;
cout <<
"-------------------------------------------------------------------" << endl;

initializeTable();
printGrammarAndTable();

while (input[i] != '$' && !s.empty() && s.top() != '$') {


display(s);
cout << "\t\t" << input.substr(i) << "\t";

char stackTop = s.top();


char inputChar = input[i];

if (stackTop == inputChar) {
cout << "\tMatched " << inputChar << endl;
s.pop();
i++;
} else {
string stackTopStr(1, stackTop);
string inputCharStr(1, inputChar);
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-6

string curp = table[stackTopStr][inputChar];


if (curp == "e") {
cout << "\tApply epsilon production\n";
s.pop(); // Pop the non-terminal for epsilon production
// No need to push anything onto the stack for epsilon production
} else if (curp == "EMPTY") {
cout << "\nInvalid String - Rejected\n";
return 1;
} else {
cout << "\tApply production " << curp << endl;
s.pop();
// Push in reverse order, skipping '->'
for (int j = curp.size() - 1; j >= 3; j--) {
if (curp[j] != ' ' && curp[j] != '-') {
s.push(curp[j]);
}
}
}
}
}

display(s);
cout << "\t\t" << input.substr(i) << "\t";
cout <<
"\n-------------------------------------------------------------------" <<
endl;

if (s.top() == '$' && input[i] == '$') {


cout << "\nValid String - Accepted\n";
} else {
cout << "Invalid String - Accepted\n";
}

return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-6
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-7
1. Write a YACC program to implement a calculator and recognize a valid
arithmetic expression

lex.l

%{
#include "y.tab.h"
%}

%%
[0-9]+ { yylval = atoi(yytext); return TERM; }
[\t ] { }
\n { return '\n'; }
\+ { return '+'; }
\- { return '-'; }
\* { return '*'; }
\/ { return '/'; }
\( { return '('; }
\) { return ')'; }
. { return yytext[0]; }
%%

int yywrap() {
return 1;
}

calculator.y

%{
#include<stdio.h>
#include<stdlib.h>
int yylex(void);
void yyerror(const char *s);
%}

%token TERM

%%

calc:
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-7
expr '\n' { printf("Output for the arithmetic expression is : %d\n",
$1); }
| calc expr '\n' { printf("Output for the arithmetic expression is : %d\n",
$2); }
;

expr:
expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { if ($3 == 0) yyerror("Division by 0 - Mathematical
Error"); else $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
| TERM { $$ = $1; }
;

%%

void yyerror(const char *s) {


fprintf(stderr, "Error: %s\n", s);
}

int main() {
printf("Enter the valid arithmetic expression :\n");
yyparse();
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-7
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-8

1. Write a YACC program for converting infix to postfix expression.

lex.l

%{
#include "y.tab.h"
#include <stdio.h>
#include <stdlib.h>
extern int yylval;
%}

%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
.|\n { return *yytext; }
%%

int yywrap() {
return 1;
}

postfix.y

%{
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int yylex(void);
void yyerror(char *s);
%}

%token NUMBER
%left '+' '-'
%left '*' '/'
%right UMINUS
%right '^'

%%
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-8

lines:
| lines E '\n' { printf("\nAnswer: %d\n", $2);
printf("\nEnter the infix expression: ");}
;

E: E '+' E { $$ = $1 + $3; printf(" + "); }


| E '-' E { $$ = $1 - $3; printf(" - "); }
| E '*' E { $$ = $1 * $3; printf(" * "); }
| E '/' E { $$ = $1 / $3; printf(" / "); }
| '(' E ')' { $$ = $2; }
| '-' E %prec UMINUS { $$ = -$2; }
| NUMBER { $$ = yylval; printf("%d ", yylval); }
;

%%

void yyerror(char *s) {


fprintf(stderr, "%s\n", s);
}

int main(void) {
printf("\nEnter the infix expression: ");
yyparse();
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-8
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-9
1. Write a YACC program to accept a sequence of 0s and 1s which end and start
either with 0 or 1.

lex.l

%{
#include<stdio.h>
#include<stdlib.h>
#include "y.tab.h"
extern int yylval;
%}

%%
0 { yylval = 0; return Z; }
1 { yylval = 1; return O; }
[ \t] { ; }
\n { return 0; }
. { return yytext[0]; }
%%

int yywrap()
{
return 1;
}

start-end.y

%{
#include <stdlib.h>
#include <stdio.h>
int yylex();
void yyerror(char *s);
%}

%token Z O
%%
r : s { printf("\nGrammar ACCEPTS the sequence\n"); }

s : n { $$ = $1; }
| Z a { $$ = $2; }
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-9
| O b { $$ = $2; }
;

a : n a { $$ = $1; }
| Z { $$ = $1; }
;

b : n b { $$ = $1; }
| O { $$ = $1; }
;

n : Z { $$ = $1; }
| O { $$ = $1; }
;
%%

int main()
{
printf("Enter the sequence: \n");
yyparse();
return 0;
}

void yyerror(char *s)


{
fprintf(stdout, "\nGrammar does NOT ACCEPTS the sequence\n");
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-9
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-10

1. Write a program to implement SLR parser for any grammar.

#include <stdio.h>
#include <string.h>

#define MAX 100

int stack[MAX];
int top = -1;

void push(int state) {


if (top < MAX - 1) {
stack[++top] = state;
} else {
printf("Stack overflow!\n");
}
}

void pop() {
if (top >= 0) {
top--;
} else {
printf("Stack underflow!\n");
}
}

int peek() {
if (top >= 0) {
return stack[top];
}
return -1;
}
const char* rules[2] = { "S->aA", "A->b" };
int actionTable[4][3] = {
{1, -1, -1},
{-1, 2, -1},
{-1, -1, 0},
{-1, -1, -1}
};

void parse(const char* input) {


MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-10

int i = 0;
char symbol = input[i];
push(0);
while (1) {
int state = peek();

if (symbol == 'a') {
if (actionTable[state][0] == 1) {
printf("Shift: a\n");
push(1);
symbol = input[++i];
} else {
printf("Error: Unexpected symbol 'a'\n");
break;
}
} else if (symbol == 'b') {
if (actionTable[state][1] == 2) {
printf("Shift: b\n");
push(2);
symbol = input[++i];
} else if (actionTable[state][1] == -1 && state == 1) {
printf("Reduce: A -> b\n");
pop();
pop();
push(2);
} else {
printf("Error: Unexpected symbol 'b'\n");
break;
}
} else if (symbol == '$') {
if (actionTable[state][2] == 0) {
printf("Input accepted.\n");
break;
} else {
printf("Error: Input not accepted.\n");
break;
}
} else {
printf("Error: Invalid symbol '%c'\n", symbol);
break;
}
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-10

}
int main() {
char input[MAX];
printf("Grammar:\nS → aA\nA->b\n");
printf("Enter a string to parse (end with $): ");
scanf("%s", input);
if (input[strlen(input) - 1] != '$') {
printf("Error: Input must end with '$' to mark the end of the
string.\n");
return 1;
}

printf("Parsing input: %s\n", input);


parse(input);
return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11

1. Write a program to implement 3 address codes.

// code in C for a = b * -c + b * -c

#include <stdio.h>
#include <string.h>

typedef struct {
char op[3];
char arg1[10];
char arg2[10];
char result[10];
} TAC;

int temp_count = 0;

void newTemp(char *temp) {


sprintf(temp, "t%d", temp_count++);
}

void generateTAC(char *expr, TAC tac[], int *index) {


char temp1[10], temp2[10], temp3[10], temp4[10];
char op1, op2;

sscanf(expr, "%s = %s %c %s %c %s %c %s", temp1, temp2, &op1,


temp3, &op2, temp4, &op1, temp3);

newTemp(tac[*index].result);
strcpy(tac[*index].op, "-");
strcpy(tac[*index].arg1, temp3);
strcpy(tac[*index].arg2, "");
(*index)++;

char negTemp[10];
strcpy(negTemp, tac[*index - 1].result);

newTemp(tac[*index].result);
strcpy(tac[*index].op, "*");
strcpy(tac[*index].arg1, temp2);
strcpy(tac[*index].arg2, negTemp);
(*index)++;
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11

char mulTemp1[10];
strcpy(mulTemp1, tac[*index - 1].result);

newTemp(tac[*index].result);
strcpy(tac[*index].op, "-");
strcpy(tac[*index].arg1, temp3);
strcpy(tac[*index].arg2, "");
(*index)++;

strcpy(negTemp, tac[*index - 1].result);

newTemp(tac[*index].result);
strcpy(tac[*index].op, "*");
strcpy(tac[*index].arg1, temp2);
strcpy(tac[*index].arg2, negTemp);
(*index)++;

char mulTemp2[10];
strcpy(mulTemp2, tac[*index - 1].result);

newTemp(tac[*index].result);
strcpy(tac[*index].op, "+");
strcpy(tac[*index].arg1, mulTemp1);
strcpy(tac[*index].arg2, mulTemp2);
(*index)++;

char addTemp[10];
strcpy(addTemp, tac[*index - 1].result);

strcpy(tac[*index].op, "=");
strcpy(tac[*index].arg1, addTemp);
strcpy(tac[*index].arg2, "");
strcpy(tac[*index].result, temp1);
(*index)++;
}

int main() {
char expr[50] = "a = b * -c + b * -c";
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11
TAC tac[10];
int index = 0;

generateTAC(expr, tac, &index);

printf("Three-Address Code:\n");
for (int i = 0; i < index; i++) {
if (strcmp(tac[i].op, "=") == 0) {
printf("%s = %s\n", tac[i].result, tac[i].arg1);
} else {
printf("%s = %s %s %s\n", tac[i].result, tac[i].arg1, tac[i].op,
tac[i].arg2);
}
}

return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11

//Code in cpp generalised version not fully correct but just attempt at it

#include <iostream>
#include <stack>
#include <sstream>
#include <vector>
#include <cctype>

using namespace std;

struct TAC {
string op;
string arg1;
string arg2;
string result;
};

vector<TAC> threeAddressCode;

string newTemp() {
static int tempCount = 0;
return "t" + to_string(tempCount++);
}

void generateTAC(string op, string arg1, string arg2, string result) {


TAC tac = {op, arg1, arg2, result};
threeAddressCode.push_back(tac);
}

int precedence(char op) {


if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
if (op == 'u') return 3;

return 0;
}

void infixToTAC(const string& expr) {


stack<char> operators;
stack<string> operands;
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11
istringstream iss(expr);
string token;

while (iss >> token) {


if (isalnum(token[0])) {
operands.push(token);
} else if (token[0] == '(') {
operators.push('(');
} else if (token[0] == ')') {
while (!operators.empty() && operators.top() != '(') {
string op = string(1, operators.top());
operators.pop();

string arg2 = operands.top(); operands.pop();


string arg1 = operands.top(); operands.pop();
string result = newTemp();

generateTAC(op, arg1, arg2, result);


operands.push(result);
}
operators.pop();
} else {
while (!operators.empty() && precedence(operators.top()) >= precedence(token[0])) {
string op = string(1, operators.top());
operators.pop();

string arg2 = operands.top(); operands.pop();


string arg1 = operands.top(); operands.pop();
string result = newTemp();

generateTAC(op, arg1, arg2, result);


operands.push(result);
}
operators.push(token[0]);
}
}

while (!operators.empty()) {
string op = string(1, operators.top());
operators.pop();

string arg2 = operands.top(); operands.pop();


string arg1 = operands.top(); operands.pop();
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11
string result = newTemp();

generateTAC(op, arg1, arg2, result);


operands.push(result);
}
}

void printTAC() {
for (const auto& tac : threeAddressCode) {
cout << tac.result << " = " << tac.arg1 << " " << tac.op << " " << tac.arg2 << endl;
}
}

int main() {
string expression;
cout<< "u for unary minus\n";
cout << "Enter an expression: ";
getline(cin, expression);

infixToTAC(expression);
cout << "\nThree Address Code:\n";
printTAC();

return 0;
}
MAHI CHHAWCHHARIA
220103029
LAB ASSIGNMENT-11

You might also like