PCC Lab File 2022uca1834
PCC Lab File 2022uca1834
UNIVERSITY OF
TECHNOLOGY
CACSC14:Principles Of
Compiler Construction
NAME:RAGHWENDRA
Ro no:2022UCA1834
BRANCH:CSAI-1
Page 1

ll
List of Practicals
5 Develop a Parser for ‘C’ using the LEX and YACC tools. 19
Page 2

Experiment 1
Code:
lexer.l :
%{
#include "[Link].h"
#include "symbol_table.h"
#include <string.h>
int yywrap(void);
%}
%%
"@"[a-zA-Z0-9]* { printf("Syntax error: Identi ers cannot start with
'@': %s\n", yytext); return ERROR; }
[a-zA-Z][a-zA-Z0-9]* { [Link] = strdup(yytext); return
IDENTIFIER; }
[0-9]+ { [Link] = atoi(yytext); return NUMBER; }
"=" { return '='; }
[ \t\n] { /* ignore whitespace */ }
. { /* handle other characters */ }
%%
int yywrap(void) {
return 1;
}
parser.y :
%{
#include <stdio.h>
#include "symbol_table.h"
int yylex(void);
void yyerror(const char *s);
void print_symbol_table(void); // Add this line
Page 3

fi
FILE *yyin;
%}
%union {
char *str;
int num;
}
%%
program:
declarations
{
printf("Symbol table after parsing:\n");
print_symbol_table();
}
;
declarations:
declaration
| declarations declaration
;
declaration:
IDENTIFIER '=' NUMBER { insert_symbol($1, $3); }
;
%%
int main(int argc, char *argv[]) {
if (argc > 1) {
FILE * le = fopen(argv[1], "r");
if (! le) {
perror(argv[1]);
return 1;
}
Page 4

fi
fi
yyin = le;
}
return yyparse();
}
symbol_table.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symbol_table.h"
Symbol *hash_table[TABLE_SIZE];
Page 5

fi
// Print the entire symbol table
void print_symbol_table(void)
{
for (int i = 0; i < TABLE_SIZE; i++)
{
Symbol *sym = hash_table[i];
if (sym != NULL)
{
printf("Bucket %d:\n", i);
while (sym != NULL)
{
printf(" Symbol: %s, Value: %d\n", sym->name, sym->value);
sym = sym->next;
}
}
}
}
symbol_table.h :
#ifndef SYMBOL_TABLE_H
#define SYMBOL_TABLE_H
#endif
Output:
Page 6

Experiment 2
Code:
two_pass.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct
{
char label[20];
int address;
} Symbol;
typedef struct
{
int opcode;
int operands[MAX_OPERANDS];
int operand_count;
} Instruction;
Symbol symbol_table[MAX_SYMBOLS];
int symbol_count = 0;
int location_counter = 0;
int pass = 1;
Instruction current_instruction;
Page 7

}
}
return -1;
}
void print_symbol_table()
{
printf("\nSymbol Table:\n");
printf("Label\tAddress\n");
printf("-----\t-------\n");
for (int i = 0; i < symbol_count; i++)
{
printf("%s\t0x%04X\n", symbol_table[i].label, symbol_table[i].address);
}
printf("\n");
}
Page 8

{
current_instruction.operands[current_instruction.operand_count++] = value;
}
}
void print_instruction()
{
if (current_instruction.opcode == 0)
return;
void reset_instruction()
{
current_instruction.opcode = 0;
current_instruction.operand_count = 0;
}
// Handle labels
if (strchr(token, ':') != NULL)
{
token[strlen(token) - 1] = '\0'; // Remove the colon
add_symbol(token, location_counter);
token = strtok(NULL, " ,\n\t");
if (!token)
return;
}
// Get instruction
char instruction[10];
strncpy(instruction, token, sizeof(instruction) - 1);
instruction[sizeof(instruction) - 1] = '\0';
for (int i = 0; instruction[i]; i++)
{
instruction[i] = toupper(instruction[i]);
}
current_instruction.opcode = opcode;
location_counter++;
Page 9

if (strcmp(instruction, "HLT") == 0)
{
return;
}
// Parse operands
int operand_limit = is_single_operand_instruction(instruction) ? 1 : 2;
int operand_count = 0;
while ((token = strtok(NULL, " ,\n\t")) != NULL && operand_count < operand_limit)
{
while (*token && isspace(*token))
token++;
if (!*token)
continue;
location_counter += current_instruction.operand_count;
}
printf("\nMachine Code:\n");
printf("Address Code\n");
Page 10

printf("------- ----\n");
printf("Two-Pass Assembler\n");
printf("=================\n");
first_pass(file);
print_symbol_table();
rewind(file);
second_pass(file);
fclose(file);
return 0;
}
[Link] :
START: MOV A, 05
MOV B, 01
MOV C, A
FACTORIAL: CMP C, 01
JZ END
MUL C
DCR C
JMP FACTORIAL
END: MOV B, A
HLT
Page 11

Output:
Page 12

Experiment 3
Code:
lexer.l :
%{
#include <stdio.h>
#include <stdlib.h>
void print_string(const char *str) {
printf("STRING: %s\n", str);
}
%}
%option noyywrap
%%
Page 13

fl
"," { printf("separater: %s\n", yytext); }
{WHITESPACE} { /* Ignored */ }
. {}
%%
[Link] :
#include <stdio.h>
#de ne PI 3.14
int main() {
char letter = 'A'; // Character literal
printf("Hello, World!"); // String literal
printf("Value of PI: %f", PI);
// Conditional statement
if (letter == 'A') {
printf("The letter is A.\n");
}
return 0;
}
Page 14
fi

fi
fi
fi
fi
Output:
Page 15

Experiment 4
Code:
%{
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
void yyerror(const char *s);
%}
program:
external_declaration_list
;
external_declaration_list:
external_declaration
| external_declaration_list external_declaration
;
external_declaration:
function_de nition
| declaration
;
function_de nition:
type_speci er declarator compound_statement
;
declaration:
type_speci er init_declarator_list SEMICOLON
;
type_speci er:
INT
| FLOAT
| CHAR
;
init_declarator_list:
init_declarator
| init_declarator_list COMMA init_declarator
;
init_declarator:
Page 16

fi
fi
fi
fi
fi
declarator
| declarator ASSIGN initializer
;
declarator:
IDENTIFIER
| IDENTIFIER LPAREN parameter_list RPAREN
;
parameter_list:
parameter_declaration
| parameter_list COMMA parameter_declaration
;
parameter_declaration:
type_speci er declarator
;
initializer:
assignment_expression
;
compound_statement:
LBRACE statement_list RBRACE
;
statement_list:
statement
| statement_list statement
;
statement:
expression_statement
| compound_statement
| selection_statement
| iteration_statement
| return_statement
;
expression_statement:
expression SEMICOLON
| SEMICOLON
;
selection_statement:
IF LPAREN expression RPAREN statement
| IF LPAREN expression RPAREN statement ELSE statement
;
iteration_statement:
WHILE LPAREN expression RPAREN statement
;
return_statement:
RETURN expression SEMICOLON
;
Page 17

fi
expression:
assignment_expression
| expression COMMA assignment_expression
;
assignment_expression:
IDENTIFIER ASSIGN assignment_expression
| additive_expression
;
additive_expression:
multiplicative_expression
| additive_expression PLUS multiplicative_expression
| additive_expression MINUS multiplicative_expression
;
multiplicative_expression:
primary_expression
| multiplicative_expression TIMES primary_expression
| multiplicative_expression DIVIDE primary_expression
;
primary_expression:
IDENTIFIER
| INTEGER_CONSTANT
| FLOAT_CONSTANT
| CHAR_CONSTANT
| LPAREN expression RPAREN
;
%%
int main(void) {
yyparse();
return 0;
}
Page 18

Experiment 5
Aim: Develop a Parser for ‘C’ using the LEX and YACC tools.
Code:
lex.l :
%{
#include "[Link].h"
#include <stdlib.h>
%}
%%
"int" { return INT; }
" oat" { return FLOAT; }
"char" { return CHAR; }
"if" { return IF; }
"else" { return ELSE; }
"while" { return WHILE; }
"return" { return RETURN; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/" { return DIVIDE; }
">" { return GREATER; }
"<" { return LESS; }
"=" { return ASSIGN; }
";" { return SEMICOLON; }
"," { return COMMA; }
"(" { return LPAREN; }
")" { return RPAREN; }
"{" { return LBRACE; }
"}" { return RBRACE; }
[0-9]+ { return INTEGER_CONSTANT; }
[0-9]+\.[0-9]+ { return FLOAT_CONSTANT; }
[a-zA-Z_][a-zA-Z0-9_]* { return IDENTIFIER; }
[ \t\n]+ ; /* ignore whitespace */
. { printf("Unknown character: %c\n", yytext[0]); }
%%
int yywrap(void) {
return 1;
}
Page 19
fl

parser.y :
%{
#include <stdio.h>
#include <stdlib.h>
void yyerror(const char *s);
int yylex(void);
%}
program
: external_declaration
| program external_declaration
;
external_declaration
: function_de nition
| declaration
;
function_de nition
: type_speci er IDENTIFIER LPAREN parameter_list_opt RPAREN compound_statement
;
parameter_list_opt
: parameter_list
| /* empty */
;
parameter_list
: parameter_declaration
| parameter_list COMMA parameter_declaration
;
parameter_declaration
: type_speci er IDENTIFIER
;
declaration
: type_speci er init_declarator_list SEMICOLON
;
init_declarator_list
: init_declarator
Page 20

fi
fi
fi
fi
fi
| init_declarator_list COMMA init_declarator
;
init_declarator
: IDENTIFIER
| IDENTIFIER ASSIGN expression
;
type_speci er
: INT
| FLOAT
| CHAR
;
compound_statement
: LBRACE statement_list RBRACE
| LBRACE RBRACE
;
statement_list
: statement
| statement_list statement
;
statement
: expression_statement
| compound_statement
| selection_statement
| iteration_statement
| return_statement
| declaration
;
expression_statement
: expression SEMICOLON
| SEMICOLON
;
selection_statement
: IF LPAREN expression RPAREN statement %prec LOWER_THAN_ELSE
| IF LPAREN expression RPAREN statement ELSE statement
;
iteration_statement
: WHILE LPAREN expression RPAREN statement
;
return_statement
: RETURN expression SEMICOLON
| RETURN SEMICOLON
;
expression
: assignment_expression
| expression COMMA assignment_expression
;
Page 21

fi
assignment_expression
: conditional_expression
| IDENTIFIER ASSIGN assignment_expression
;
conditional_expression
: logical_or_expression
;
logical_or_expression
: logical_and_expression
;
logical_and_expression
: equality_expression
;
equality_expression
: relational_expression
;
relational_expression
: additive_expression
| relational_expression GREATER additive_expression
| relational_expression LESS additive_expression
;
additive_expression
: multiplicative_expression
| additive_expression PLUS multiplicative_expression
| additive_expression MINUS multiplicative_expression
;
multiplicative_expression
: primary_expression
| multiplicative_expression TIMES primary_expression
| multiplicative_expression DIVIDE primary_expression
;
primary_expression
: IDENTIFIER
| INTEGER_CONSTANT
| FLOAT_CONSTANT
| LPAREN expression RPAREN
| IDENTIFIER LPAREN RPAREN
| IDENTIFIER LPAREN argument_list RPAREN
;
argument_list
: assignment_expression
| argument_list COMMA assignment_expression
;
%%
Page 22

void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
int main(void) {
if (yyparse() == 0) {
printf("Parsing successful\n");
}
return 0;
}
[Link] :
int main() {
int x = 10;
oat y = 5.5;
if (x > y) {
x = x - 1;
}
return x;
}
Output :
Page 23
fl

Experiment 6
Code:
miniLang.l:
%{
#include "[Link].h"
#include <stdlib.h>
#include <stdio.h>
%}
%option noyywrap
DIGIT [0-9]+
ID [a-zA-Z][a-zA-Z0-9]*
%%
%%
Page 24
fl

miniLang.y:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Symbol table
typedef struct {
char *name;
int value;
} Variable;
Variable vars[MAX_VARS];
int var_count = 0;
int label_count = 0;
%}
%union {
int ival;
char *sval;
}
%%
Page 25
fi

// Grammar rules
program: /* empty */
| program stmt
;
stmt: declaration
| assignment
| if_stmt
;
%%
int main() {
return yyparse();
}
vm.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char name[50];
int value;
} Variable;
Variable var_table[VAR_TABLE_SIZE];
int var_count = 0;
int stack[STACK_SIZE];
int sp = -1;
Page 27
fi
fi

fl
fl
// Store a value in the variable table
void store(char *name, int value)
{
for (int i = 0; i < var_count; i++)
{
if (strcmp(var_table[i].name, name) == 0)
{
var_table[i].value = value;
return;
}
}
strcpy(var_table[var_count].name, name);
var_table[var_count].value = value;
var_count++;
}
int main()
{
char line[100];
return 0;
}
[Link]:
int x = 5;
int y = 10;
int z = x + y;
Output :
Page 29

fi
Experiment 7
Aim: Develop a simple calculator using the LEX and YACC tools.
Code:
calc.l :
%{
#include "[Link].h"
#include <stdio.h>
#include <stdlib.h> // For atoi
extern int yylval;
%}
%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/"|"÷" { return DIVIDE; }
\n { return EOL; }
[ \t\r] {} // Ignore whitespaces
%%
int yywrap(void){
return 1;
}
calc.y :
%{
#include <stdio.h>
#include <stdlib.h> // For atoi
void yyerror(const char *s);
int yylex();
%}
Page 30

%%
%%
int main() {
return yyparse();
}
Output :
Page 31

Experiment 8
Aim: Add assignment statement, If then else statement and while loop to
the calculator and generate the three address code for the same.
Code:
calc.l :
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "[Link].h"
%%
[ \t] ;
[\n] { line_no++; }
"if" { return IF; }
"then" { return THEN; }
"else" { return ELSE; }
"while" { return WHILE; }
"do" { return DO; }
";" { return SEMICOLON; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULTIPLY; }
"/" { return DIVIDE; }
"=" { return ASSIGN; }
"==" { return EQ; }
"!=" { return NEQ; }
"<" { return LT; }
">" { return GT; }
"<=" { return LEQ; }
">=" { return GEQ; }
"(" { return LPAREN; }
")" { return RPAREN; }
"{" { return LBRACE; }
"}" { return RBRACE; }
[0-9]+ { [Link] = atoi(yytext); return NUMBER; }
[a-zA-Z][a-zA-Z0-9_]* { [Link] = strdup(yytext); return IDENTIFIER; }
. { printf("Unexpected character %s\n", yytext); }
%%
int yywrap(void) {
return 1;
}
Page 32

calc.y :
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* new_temp() {
char* temp = (char*)malloc(10);
sprintf(temp, "t%d", temp_count++);
return temp;
}
char* new_label() {
char* label = (char*)malloc(10);
sprintf(label, "L%d", label_count++);
return label;
}
%}
%union {
int num;
char* id;
struct {
char* code;
char* place;
char* true_label;
char* false_label;
} expr;
}
%type <expr> expr stmt stmt_list condition block while_stmt if_stmt assignment
%%
program:
stmt_list
;
stmt_list:
stmt { printf("%s", $[Link]); }
| stmt_list stmt { printf("%s", $[Link]); }
;
Page 33

stmt:
assignment SEMICOLON { $$ = $1; }
| if_stmt { $$ = $1; }
| while_stmt { $$ = $1; }
;
assignment:
IDENTIFIER ASSIGN expr {
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s = %s\n", $[Link], $1, $[Link]);
$$.place = $1;
}
;
if_stmt:
IF LPAREN condition RPAREN THEN block ELSE block {
char* label1 = new_label();
char* label2 = new_label();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s"
"if %s goto %s\n"
"goto %s\n"
"%s:\n"
"%s"
"goto %s\n"
"%s:\n"
"%s"
"%s:\n",
$[Link], $[Link], label1, label2,
label1, $[Link], $3.true_label,
label2, $[Link], $3.false_label);
}
;
while_stmt:
WHILE LPAREN condition RPAREN DO block {
char* start_label = new_label();
char* body_label = new_label();
char* end_label = new_label();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s:\n"
"%s"
"if %s goto %s\n"
"goto %s\n"
"%s:\n"
"%s"
"goto %s\n"
"%s:\n",
start_label, $[Link], $[Link], body_label, end_label,
body_label, $[Link], start_label, end_label);
}
;
block:
LBRACE stmt_list RBRACE { $$ = $2; }
;
Page 34

condition:
expr LT expr {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s < %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
$$.true_label = new_label();
$$.false_label = new_label();
}
| expr GT expr {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s > %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
$$.true_label = new_label();
$$.false_label = new_label();
}
;
expr:
NUMBER {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s = %d\n", temp, $1);
$$.place = temp;
}
| IDENTIFIER {
$$.code = strdup("");
$$.place = $1;
}
| expr PLUS expr {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s + %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
}
| expr MINUS expr {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s - %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
}
| expr MULTIPLY expr {
char* temp = new_temp();
$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s * %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
}
| expr DIVIDE expr {
char* temp = new_temp();
Page 35

$$.code = (char*)malloc(1000);
sprintf($$.code, "%s%s%s = %s / %s\n",
$[Link], $[Link], temp, $[Link], $[Link]);
$$.place = temp;
}
| LPAREN expr RPAREN {
$$ = $2;
}
;
%%
int main(void) {
yyparse();
return 0;
}
[Link] :
x = 5;
y = 10;
if (x < y) then {
max = y;
} else {
max = x;
}
while (x < 100) do {
x = x + 1;
}
Output :
Page 36

Page 37