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

Pcc

Pcc
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

Pcc

Pcc
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 33

Principle of Compiler Construction

CBCPC14
PRACTICAL FILE
2024-25

Submitted by: Submitted to:

Name: Keshav Dr. R S Raw

Roll No.: 2022UCB6526

Branch: CSDA

Section: 1

Netaji Subhas University of Technology


(East Campus)
Geeta Colony, New Delhi
Delhi - 110031
INDEX

S. No. Experiments Page no. Sign

Develop simple language processors like desk calculator


1.
and assembler.

2. Design a small high-level language.

Develop a lexical analyzer and a syntax analyzer for a


3. simple high-level language using the LEX and YACC tools.
Also implement the bookkeeper module.

Design a small high-level language and implement a


compiler for the same. If the target machine of the
4.
compiler is a hypothetical machine, then implement a
simulator for it.

5. Develop a simple calculator using LEX and YACC tools.

6. Implement a program for symbol table using hashing

7. Implement a two-pass assembler

8. Implement a bottom-up parser using YACC tool.

9. Represent ‘C’ language using Context Free Grammar

Write a program to generate the three address code for


10.
the given expression.
Practical-1
Aim: Develop simple language processors like desk calculator and assembler.
1) Desk Calculator
Code:
#include <stdio.h>
#include <stdlib.h>
float calculate(float num1, float num2, char operator) {
switch (operator) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
case '/':
if (num2 != 0) {
return num1 / num2;
} else {
printf("Error: Division by zero.\n");
exit(1);
}
default:
printf("Error: Invalid operator.\n");
exit(1);
}
}
int main() {
float num1, num2;
char operator;
printf("Enter first number: ");
scanf("%f", &num1);
printf("Enter an operator (+, -, *, /): ");
scanf(" %c", &operator);
printf("Enter second number: ");
scanf("%f", &num2);
float result = calculate(num1, num2, operator);
printf("Result: %.2f\n", result);
return 0;
}
Output:
2) Assembler
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printMeaningfulInstruction(const char *instruction) {
char command[10];
char operand1[10];
char operand2[10];
int scanned = sscanf(instruction, "%s %s %s", command, operand1,
operand2);
if (scanned < 2) {
printf("Error: Invalid instruction format: %s\n", instruction);
return;
}
if (strcmp(command, "LOAD") == 0) {
printf("Meaning: Load value from %s into the accumulator.\n",
operand1);
} else if (strcmp(command, "STORE") == 0) {
printf("Meaning: Store value from the accumulator into %s.\n",
operand1);
} else if (strcmp(command, "ADD") == 0) {
if (scanned == 2) {
printf("Meaning: Add value from %s to the accumulator.\n",
operand1);
} else {
printf("Error: ADD requires one operand.\n");
}
} else if (strcmp(command, "SUB") == 0) {
if (scanned == 2) {
printf("Meaning: Subtract value from %s from the accumulator.\
n", operand1);
} else {
printf("Error: SUB requires one operand.\n");
}
} else if (strcmp(command, "MULT") == 0) {
if (scanned == 2) {
printf("Meaning: Multiply value from %s with the accumulator.\
n", operand1);
} else {
printf("Error: MULT requires one operand.\n");
}
} else if (strcmp(command, "DIV") == 0) {
if (scanned == 2) {
printf("Meaning: Divide the accumulator by value from %s.\n",
operand1);
} else {
printf("Error: DIV requires one operand.\n");
}
} else {
printf("Error: Unknown command %s\n", command);
}
}

int main() {
// Predefined assembly instructions
const char *instructions[] = {
"LOAD A",
"STORE B",
"ADD C",
"SUB D",
"MULT E",
"DIV F",
"ADD", // Example of missing operand
"LOAD A B", // Example of incorrect format (too many operands)
"UNKNOWN X" // Example of an unrecognized command
};

// Process each instruction


for (int i = 0; i < sizeof(instructions) / sizeof(instructions[0]); i++)
{
printf("Instruction: %s\n", instructions[i]);
printMeaningfulInstruction(instructions[i]);
printf("\n");
}
return 0;
}

Output:
Practical-2
Aim: Design a small high-level language.
Code:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum {
TOKEN_EOF,
TOKEN_VAR,
TOKEN_ID,
TOKEN_EQUALS,
TOKEN_NUMBER,
TOKEN_PLUS,
TOKEN_SEMICOLON
} TokenType;

// Define a token.
typedef struct {
TokenType type;
const char *start;
int length;
} Token;

// Declare the functions.


void lexer(const char *, Token *, int *);

int main() {
char input[1024];
printf("Enter code: ");
// Use fgets to read a full line with spaces.
if (!fgets(input, sizeof(input), stdin)) {
fprintf(stderr, "Error reading input.\n");
return 1;
}

const char *source = input;


Token tokens[256];
int tokenCount = 0;
lexer(source, tokens, &tokenCount);

// Print the tokens.


for (int i = 0; i < tokenCount; i++) {
printf("Token %d: type = %d, start = %.*s, length = %d\n",
i, tokens[i].type, tokens[i].length, tokens[i].start,
tokens[i].length);
}
return 0;
}

// Lexer function to tokenize the input.


void lexer(const char *source, Token *tokens, int *tokenCount) {
const char *start = source;
while (*source != '\0') {
if (isspace(*source)) {
// Ignore all the whitespace.
source++;
start = source;
} else if (isalpha(*source)) {
// Identifier or keyword.
while (isalpha(*source)) {
source++;
}
if (source - start == 3 && strncmp(start, "var", 3) == 0) {
tokens[*tokenCount].type = TOKEN_VAR;
} else {
tokens[*tokenCount].type = TOKEN_ID;
}
tokens[*tokenCount].start = start;
tokens[*tokenCount].length = source - start;
(*tokenCount)++;
start = source;
} else if (isdigit(*source)) {
// Number
while (isdigit(*source)) {
source++;
}
tokens[*tokenCount].type = TOKEN_NUMBER;
tokens[*tokenCount].start = start;
tokens[*tokenCount].length = source - start;
(*tokenCount)++;
start = source;
} else {
// Operator or punctuation.
switch (*source) {
case '=':
tokens[*tokenCount].type = TOKEN_EQUALS;
break;
case '+':
tokens[*tokenCount].type = TOKEN_PLUS;
break;
case ';':
tokens[*tokenCount].type = TOKEN_SEMICOLON;
break;
default:
printf("Unknown character: %c\n", *source);
return;
}
tokens[*tokenCount].start = start;
tokens[*tokenCount].length = 1;
(*tokenCount)++;
source++;
start = source;
}
}
// Add the EOF token at the end.
tokens[*tokenCount].type = TOKEN_EOF;
tokens[*tokenCount].start = start;
tokens[*tokenCount].length = 0;
(*tokenCount)++;
}

Output:
Practical-3
Aim: Develop a lexical analyzer and a syntax analyzer for a simple high-level language using the
LEX and YACC tools. Also implement the bookkeeper module.

Code:
1) Create and Compile Lex file (lex simple.l)
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h" // This header file is generated by YACC
%}

%%

[0-9]+ { yylval.num = atoi(yytext); return NUMBER; }


"=" { return ASSIGN; }
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"(" { return LPAREN; }
")" { return RPAREN; }
[ \t\n] { /* skip whitespace */ }
[A-Za-z_][A-Za-z0-9_]* { yylval.str = strdup(yytext); return
IDENTIFIER; }

%%

int yywrap(void) {
return 1;
}

2) Create and Compiler Yacc file (yacc -d simple.y)


%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bookkeeper.h" // Include the bookkeeper module
%}

%union {
int num;
char* str;
}

%token <num> NUMBER


%token <str> IDENTIFIER
%token ASSIGN ADD SUB MUL DIV LPAREN RPAREN

%type <num> expression term factor

%%

program:
program statement
| /* empty */
;

statement:
IDENTIFIER ASSIGN expression {
add_variable($1, $3); // Add the variable to bookkeeper
printf("Assigned %d to %s\n", $3, $1);
}
| expression {
printf("Result: %d\n", $1);
}
;

expression:
term {
$$ = $1;
}
| expression ADD term {
$$ = $1 + $3;
}
| expression SUB term {
$$ = $1 - $3;
}
;

term:
factor {
$$ = $1;
}
| term MUL factor {
$$ = $1 * $3;
}
| term DIV factor {
$$ = $1 / $3;
}
;

factor:
NUMBER {
$$ = $1;
}
| IDENTIFIER {
$$ = get_variable($1); // Get the value from bookkeeper
}
| LPAREN expression RPAREN {
$$ = $2;
}
;

%%

int main(void) {
yyparse();
return 0;
}

int yyerror(char *s) {


fprintf(stderr, "Syntax error: %s\n", s);
return 0;
}

3) Create c file for bookkeeper module


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

#define MAX_VARS 100

typedef struct {
char* name;
int value;
} Variable;

Variable variables[MAX_VARS];
int var_count = 0;

int get_variable(char* name) {


for (int i = 0; i < var_count; i++) {
if (strcmp(variables[i].name, name) == 0) {
return variables[i].value;
}
}
printf("Error: Undefined variable %s\n", name);
exit(1); // Exit if the variable is not found
}

void add_variable(char* name, int value) {


// Check if the variable already exists
for (int i = 0; i < var_count; i++) {
if (strcmp(variables[i].name, name) == 0) {
variables[i].value = value;
return;
}
}

// Add a new variable


if (var_count < MAX_VARS) {
variables[var_count].name = strdup(name);
variables[var_count].value = value;
var_count++;
} else {
printf("Error: Maximum variable limit reached\n");
exit(1);
}
}

4) Create header file for bookkeeper module (bookkeeper.h)


#ifndef BOOKKEEPER_H
#define BOOKKEEPER_H
int get_variable(char* name);
void add_variable(char* name, int value);

#endif

5) Compile Yacc Output (gcc -c y.tab.c)


6) Compile lex Output (gcc -c lex.yy.c)
7) Run (gcc lex.yy.o y.tab.o bookkeeper.c -o simple) to link everything and create execution
file
8) Run ./simple <input.txt in terminal

Input:

Output:

Practical-4
Aim: Design a small high-level language and implement a compiler for the same. If the target
machine of the compiler is a hypothetical machine, then implement a simulator for it.

Code:

1) Create and Compile Lex file (lex MiniLang.l)

%{
#include "MiniLang.tab.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
%}
%%
let { return LET; }
if { return IF; }
then { return THEN; }
else { return ELSE; }
print { return PRINT; }

\"[^\"]*\" { yylval.sval = strdup(yytext); return STRING; } // Match


strings
[0-9]+ { yylval.ival = atoi(yytext); return NUMBER; }
[a-zA-Z_][a-zA-Z0-9_]* { yylval.sval = strdup(yytext); return IDENTIFIER;
}

"=" { return ASSIGN; }


";" { return SEMICOLON; }
"+" { return PLUS; }
"*" { return MULT; }
">" { return GT; }

[ \t\n] { /* Ignore whitespace */ }


. { printf("Unknown character: %s\n", yytext); }

%%

int yywrap() {
return 1;
}

2) Create and Compiler Yacc file (yacc -d MiniLang.y)


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

// Define a symbol table for variable storage


typedef struct {
char *name;
int value;
} Symbol;

Symbol symbolTable[100];
int symbolCount = 0;

// Function to add or update a symbol in the symbol table


void setSymbolValue(char *name, int value) {
for (int i = 0; i < symbolCount; i++) {
if (strcmp(symbolTable[i].name, name) == 0) {
symbolTable[i].value = value;
return;
}
}
symbolTable[symbolCount].name = strdup(name);
symbolTable[symbolCount].value = value;
symbolCount++;
}

// Function to retrieve a symbol's value


int getSymbolValue(char *name) {
for (int i = 0; i < symbolCount; i++) {
if (strcmp(symbolTable[i].name, name) == 0) {
return symbolTable[i].value;
}
}
printf("Error: Undefined variable %s\n", name);
return 0;
}

// Error handler function


void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}

%}

// Define the types of values yylval can hold


%union {
int ival; // For integer values
char *sval; // For identifiers and strings
}

// Token declarations with data types


%token <ival> NUMBER
%token <sval> IDENTIFIER STRING
%token LET IF THEN ELSE PRINT ASSIGN SEMICOLON PLUS MULT GT

// Non-terminal declarations with data types


%type <ival> expression term factor condition

%%
// Define the grammar rules

program:
statements
;

statements:
statement SEMICOLON statements
| statement SEMICOLON
;

statement:
LET IDENTIFIER ASSIGN expression { setSymbolValue($2, $4);
printf("Assign %s = %d\n", $2, $4); }
| IF condition THEN statement ELSE statement { printf("Conditional
statement\n"); }
| PRINT expression { printf("Print %d\n",
$2); }
| PRINT STRING { printf("Print %s\n",
$2); }
;

condition:
expression GT expression { $$ = ($1 > $3); }
;

expression:
expression PLUS term { $$ = $1 + $3; }
| term { $$ = $1; }
;

term:
term MULT factor { $$ = $1 * $3; }
| factor { $$ = $1; }
;

factor:
NUMBER { $$ = $1; }
| IDENTIFIER { $$ =
getSymbolValue($1); }
;

%%

// Main function to initiate parsing


int main() {
return yyparse();
}
3) Run (gcc lex.yy.c y.tab.c -o MiniLangCompiler) to create execution file

4) Run ./MiniLangCompiler <input.txt in terminal

Input:

Output:

Practical-5
Aim: Develop a simple calculator using LEX and YACC tools.
Code:
1) Create and Compile Lex file (lex calc.l)

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

[0-9]+ {yylval=atoi(yytext); return NUMBER;}

">=" return GE;


"<=" return LE;
"!=" return NE;
"==" return EQ;
[\n] return 0;
[\t];

. return yytext[0];
%%

2) Create and Compiler Yacc file (yacc -d calc.y)

%{
#include<stdio.h>
%}

%token NAME NUMBER


%left GE LE NE EQ '<' '>' '%'
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%%

statement : NAME '=' exp


|exp {printf("=%d\n",$1);}
;

exp : NUMBER {$$ == $1;}


|exp '+' exp {$$ = $1 + $3 ;}
|exp '-' exp {$$ = $1 - $3 ;}
|exp '*' exp {$$ = $1 * $3 ;}
|exp '/' exp {$$ = $1 / $3 ;}
|exp '<' exp {$$ = $1 < $3 ;}
|exp '>' exp {$$ = $1 > $3 ;}
|exp '%' exp {$$ = $1 % $3 ;}
|exp GE exp {$$ = $1 >= $3 ;}
|exp LE exp {$$ = $1 <= $3 ;}
|exp EQ exp {$$ = $1 == $3 ;}
|exp NE exp {$$ = $1 != $3 ;}
|exp '-' exp %prec UMINUS {$$ = -$2 ;}
|'(' exp ')' {$$ = $2 ;}
;
%%
int main(){
yyparse();
}

int yyerror(){}

int yywrap(){
return 1;
}

3) Run (gcc lex.yy.c y.tab.c) to create execution file

4) Run ./a.out in terminal

Output:

Practical-6
Aim: Implement a program for symbol table using hashing.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Define the maximum number of slots in the hash table


#define TABLE_SIZE 10
// Define the symbol table entry structure
typedef struct Entry {
char key[100]; // symbol name
int value; // associated value
struct Entry* next; // pointer to the next entry in case of a collision
} Entry;

// Define the hash table structure


typedef struct {
Entry* table[TABLE_SIZE]; // an array of pointers to entry lists
} SymbolTable;

// Hash function to convert key into an index


unsigned int hash(char* key) {
unsigned int hashValue = 0;
while (*key) {
hashValue = (hashValue << 5) + *key; // simple hash function
key++;
}
return hashValue % TABLE_SIZE;
}

// Initialize a symbol table


void initSymbolTable(SymbolTable* symbolTable) {
for (int i = 0; i < TABLE_SIZE; i++) {
symbolTable->table[i] = NULL;
}
}

// Insert a new symbol into the table


void insert(SymbolTable* symbolTable, char* key, int value) {
unsigned int index = hash(key);
Entry* newEntry = (Entry*)malloc(sizeof(Entry));
strcpy(newEntry->key, key);
newEntry->value = value;
newEntry->next = symbolTable->table[index]; // link new entry to the
existing list
symbolTable->table[index] = newEntry;
}

// Search for a symbol by its key


int search(SymbolTable* symbolTable, char* key) {
unsigned int index = hash(key);
Entry* entry = symbolTable->table[index];
while (entry != NULL) {
if (strcmp(entry->key, key) == 0) {
return entry->value; // symbol found, return its value
}
entry = entry->next;
}
return -1; // symbol not found
}

// Delete a symbol from the table


void delete(SymbolTable* symbolTable, char* key) {
unsigned int index = hash(key);
Entry* entry = symbolTable->table[index];
Entry* prev = NULL;

// Traverse the linked list at the index


while (entry != NULL && strcmp(entry->key, key) != 0) {
prev = entry;
entry = entry->next;
}

// If the symbol is found


if (entry != NULL) {
if (prev == NULL) {
symbolTable->table[index] = entry->next;
} else {
prev->next = entry->next;
}
free(entry); // free the memory
}
}

// Display the symbol table with a clearer format


void display(SymbolTable* symbolTable) {
printf("\n----- Symbol Table -----\n");
for (int i = 0; i < TABLE_SIZE; i++) {
Entry* entry = symbolTable->table[i];
if (entry != NULL) {
printf("Index %d: ", i);
while (entry != NULL) {
printf("(%s, %d)", entry->key, entry->value);
entry = entry->next;
if (entry != NULL) printf(" -> ");
}
printf("\n");
}
}
printf("------------------------\n");
}

int main() {
SymbolTable symbolTable;
initSymbolTable(&symbolTable);
int choice, value;
char key[100];

do {
printf("\n------ Menu ------\n");
printf("1. Insert Symbol\n");
printf("2. Search Symbol\n");
printf("3. Delete Symbol\n");
printf("4. Display Symbol Table\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch(choice) {
case 1:
printf("Enter symbol name: ");
scanf("%s", key);
printf("Enter symbol value: ");
scanf("%d", &value);
insert(&symbolTable, key, value);
printf("Symbol inserted.\n");
break;

case 2:
printf("Enter symbol name to search: ");
scanf("%s", key);
value = search(&symbolTable, key);
if (value == -1)
printf("Symbol not found.\n");
else
printf("Symbol '%s' found with value: %d\n", key,
value);
break;

case 3:
printf("Enter symbol name to delete: ");
scanf("%s", key);
delete(&symbolTable, key);
printf("Symbol deleted (if it existed).\n");
break;

case 4:
display(&symbolTable);
break;

case 5:
printf("Exiting the program.\n");
break;

default:
printf("Invalid choice! Please try again.\n");
}
} while(choice != 5);

return 0;
}

Output:
Practical-7
Aim: Implement a two-pass assembler.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LABELS 100


#define MAX_CODE_LINES 100
#define MAX_LINE_LENGTH 100

typedef struct {
char label[MAX_LINE_LENGTH];
int address;
} Symbol;

Symbol symbolTable[MAX_LABELS];
int symbolCount = 0;
int currentAddress = 0;

char code[MAX_CODE_LINES][MAX_LINE_LENGTH];
int codeLineCount = 0;

void addSymbol(const char* label, int address) {


strcpy(symbolTable[symbolCount].label, label);
symbolTable[symbolCount].address = address;
symbolCount++;
}

int findSymbol(const char* label) {


for (int i = 0; i < symbolCount; i++) {
if (strcmp(symbolTable[i].label, label) == 0) {
return symbolTable[i].address;
}
}
return -1;
}

void firstPass(FILE *input) {


char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), input)) {
char label[MAX_LINE_LENGTH], instruction[MAX_LINE_LENGTH];

strcpy(code[codeLineCount++], line);

if (sscanf(line, "%s %s", label, instruction) == 2) {


if (label[strlen(label) - 1] == ':') {
label[strlen(label) - 1] = '\0';
addSymbol(label, currentAddress);
}
}
currentAddress++;
}

printf("Symbol Table:\n");
for (int i = 0; i < symbolCount; i++) {
printf("Label: %s, Address: %d\n", symbolTable[i].label,
symbolTable[i].address);
}
}

void secondPass() {
for (int i = 0; i < codeLineCount; i++) {
char label[MAX_LINE_LENGTH], instruction[MAX_LINE_LENGTH],
operand[MAX_LINE_LENGTH];

if (sscanf(code[i], "%s %s %s", label, instruction, operand) == 3) {


if (label[strlen(label) - 1] == ':') {
strcpy(instruction, operand);
sscanf(code[i], "%*s %s %s", instruction, operand);
}
} else if (sscanf(code[i], "%s %s", instruction, operand) == 2) {
if (strcmp(instruction, "JMP") == 0) {
int address = findSymbol(operand);
if (address != -1) {
printf("JMP %d\n", address);
} else {
printf("Undefined label %s\n", operand);
}
} else {
printf("%s %s\n", instruction, operand);
}
} else if (sscanf(code[i], "%s", instruction) == 1) {
printf("%s\n", instruction);
}
}
}

int main() {
FILE *input = fopen("assembly.txt", "r");
if (!input) {
perror("File opening failed");
return EXIT_FAILURE;
}

firstPass(input);
rewind(input);

secondPass();
fclose(input);
return 0;
}

Input:

Output:
Practical-8
Aim: Implement a bottom-up parser using YACC tool.
Code:
1) Create and Compile Lex file (lex lexer.l)

%{
#include <stdio.h>
#include "y.tab.h" // Include the header generated by YACC for token
definitions
%}

%%
[0-9]+ { yylval.dval = atof(yytext); return DIGIT; } // Recognize numbers
and convert to double
\n|. { return yytext[0]; } // Pass newline or any other character
%%

2) Create and Compiler Yacc file (yacc -d parser.y)

%{
#include <stdio.h>
%}

%union {
double dval; // Use a double to store numeric values
}

%token <dval> DIGIT // Define DIGIT as a token with a double value


%type <dval> expr term factor // Declare types for grammar symbols

%%
line: expr '\n' { printf("%g\n", $1); } // Print result of expression on
a new line
;

expr: expr '+' term { $$ = $1 + $3; } // Define addition


| term
;

term: term '*' factor { $$ = $1 * $3; } // Define multiplication


| factor
;

factor: '(' expr ')' { $$ = $2; } // Handle expressions within


parentheses
| DIGIT
;
%%

// Main and error-handling functions


int main() {
return yyparse();
}

void yyerror(char *s) {


printf("%s\n", s);
}

3) Run (gcc lex.yy.c y.tab.c) to create execution file

4) Run ./a.out in terminal

Output:
Practical-9
Aim: Represent ‘C’ language using Context Free Grammar.
Representation:
Practical-10
Aim: Write a code to generate the three address code for the given expression.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct three {
char data[10], temp[7];
} s[30];

void main() {
char d1[7], d2[7] = "t";
int i = 0, j = 1, len = 0;
FILE *f1;

// Open the file and check for errors


f1 = fopen("sum.txt", "r");
if (f1 == NULL) {
printf("Error opening sum.txt\n");
return;
}

// Read the input expression into the struct


while (fscanf(f1, "%s", s[len].data) != EOF) {
len++;
}

// Start processing the first operation


sprintf(d1, "%d", j); // Use sprintf for integer to string conversion
strcat(d2, d1);
strcpy(s[j].temp, d2);
strcpy(d1, "");
strcpy(d2, "t");

// Handle the first operator (+, -, *, /)


if (strcmp(s[3].data, "+") == 0) {
printf("%s=%s+%s\n", s[j].temp, s[i + 2].data, s[i + 4].data);
j++;
} else if (strcmp(s[3].data, "-") == 0) {
printf("%s=%s-%s\n", s[j].temp, s[i + 2].data, s[i + 4].data);
j++;
} else if (strcmp(s[3].data, "*") == 0) {
printf("%s=%s*%s\n", s[j].temp, s[i + 2].data, s[i + 4].data);
j++;
} else if (strcmp(s[3].data, "/") == 0) {
printf("%s=%s/%s\n", s[j].temp, s[i + 2].data, s[i + 4].data);
j++;
}

// Handle subsequent operations


for (i = 4; i < len - 2; i += 2) {
sprintf(d1, "%d", j);
strcat(d2, d1);
strcpy(s[j].temp, d2);

if (strcmp(s[i + 1].data, "+") == 0) {


printf("%s=%s+%s\n", s[j].temp, s[j - 1].temp, s[i + 2].data);
} else if (strcmp(s[i + 1].data, "-") == 0) {
printf("%s=%s-%s\n", s[j].temp, s[j - 1].temp, s[i + 2].data);
} else if (strcmp(s[i + 1].data, "*") == 0) {
printf("%s=%s*%s\n", s[j].temp, s[j - 1].temp, s[i + 2].data);
} else if (strcmp(s[i + 1].data, "/") == 0) {
printf("%s=%s/%s\n", s[j].temp, s[j - 1].temp, s[i + 2].data);
}

strcpy(d1, "");
strcpy(d2, "t");
j++;
}

// Print the final result


printf("%s=%s\n", s[0].data, s[j - 1].temp);

// Close the file


fclose(f1);
}

Input:

Output:

You might also like