0% found this document useful (0 votes)
12 views70 pages

SPCC 2203121

The document outlines multiple experiments related to programming concepts, including the implementation of a Lexical Analyzer, LEX and YACC tools, FIRST and FOLLOW sets for grammar, Parser implementation, Three Address Code (TAC), Code Optimization, and Multi-Pass Assembler. Each experiment includes code snippets and aims to demonstrate specific programming techniques and functionalities. The document serves as a comprehensive guide for understanding these programming principles through practical examples.

Uploaded by

sarthakkharka
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)
12 views70 pages

SPCC 2203121

The document outlines multiple experiments related to programming concepts, including the implementation of a Lexical Analyzer, LEX and YACC tools, FIRST and FOLLOW sets for grammar, Parser implementation, Three Address Code (TAC), Code Optimization, and Multi-Pass Assembler. Each experiment includes code snippets and aims to demonstrate specific programming techniques and functionalities. The document serves as a comprehensive guide for understanding these programming principles through practical examples.

Uploaded by

sarthakkharka
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/ 70

EXPERIMENT 1:

Aim: Write a program to implement a Lexical Analyzer.

Code:
import re
keywords = {"int", "float", "char", "continue", "for", "if", "break", "while",
"string", "double"}
operators = {"+", "-", "*", "%", "/", "<", ">", "="}
separators = {";", ",", ":", "(", ")", "[", "]", "{", "}"}
ans = {
"keywords": set(),
"operators": set(),
"separators": set(),
"constants": set(), "identifier": set()
}
def split_string(s): split = []
temp = '' i = 0
while i < len(s): ch = s[i]
if ch.isspace(): if temp:
split.append(temp) temp = ''
elif ch in separators: if temp:
split.append(temp) temp = ''
split.append(ch) else:
temp += ch i += 1
if temp:
split.append(temp) return split
n = int(input("Enter number of lines: ")) print("Enter your code line by line:")
for _ in range(n):
s = input()
split = split_string(s) for token in split:
if not token: continue
if token.isdigit(): ans["constants"].add(token)
elif token in keywords: ans["keywords"].add(token)
elif token in operators: ans["operators"].add(token)
elif token in separators: ans["separators"].add(token)
elif token.startswith('"') and token.endswith('"'):
ans["constants"].add(token[1:-1])
else:
if len(token) > 1 and token[1] in operators: ans["identifier"].add(token[0])
ans["operators"].add(token[1])
else:
ans["identifier"].add(token) for key, value in ans.items():
print(f"{key}: {' '.join(sorted(value))}")

Output:
EXPERIMENT 2:
Aim: To study and implement programs using LEX and YACC tool.
Exp 1: Code:
%{
#include <stdio.h>
int yywrap() { return 1; } %}
%%
\n { printf("\nHello world"); } %%
int main() { yylex();
return 0; }

Output:

Exp 2: Personalized Message Program Code:


%{
#include <stdio.h> char name[10];
int yywrap() { return 1; } // Avoid linker error
%}

%%
\n {
printf("\nHello %s.\n", name);
return 1;
}
%%

int main() { char opt; do {


printf("\nWhat is your name? "); scanf("%s", name);
getchar(); // Flush leftover newline yylex();
printf("\nPress y to continue: "); scanf(" %c", &opt);
} while(opt == 'y'); return 0;
}
Output:

1. Program to check whether string begins with a vowel or not.

Code:
%{
#include <stdio.h> void display(int flag);
int yywrap() { return 1; } // To avoid linker errors
%}

%%
[aeiouAEIOU][a-zA-Z]* { int flag = 1; display(flag);
return 1;
}
[a-zA-Z]+ {
int flag = 0; display(flag);
return 1;
}
.|\n ;
%%

void display(int flag) { if (flag == 0)


printf("\nThe given word is not beginning with a vowel\n"); else
printf("\nThe given word is beginning with a vowel\n");
}
int main() {
printf("Enter a word: "); yylex();
return 0;
}

Output:

4. Program to check whether input string is a character or number.


Code:
%{
#include <stdio.h>
#include
<stdlib.h> //
For atoi void
display(char[
], int);
int yywrap() { return 1; }
%}

%%
[a-
zA-
Z]+
\n {
int
flag
= 1;
displa
y(yyte
xt,
flag);
return
1;
}
[0-9]+\n {
int
flag
= 0;
dis
pla
y(y
yte
xt,
flag
);
retu
rn
1;
}
.+\n {
int flag = 2; // for
other symbols
display(yytext,
flag);
return 1;
}
%%

void display(char string[], int flag) {


if (string[strlen(string) - 1]
== '\n')
{ string[strlen(string) - 1]
= '\0';
}
if (flag == 1)
printf("\nThe given string \"%s\"
is a word\n", string); else if (flag ==
0)
printf("\nThe given string \"%d\" is a
digit\n", atoi(string)); else
printf("\nThe given string \"%s\" is neither a word nor a digit\n",
string);
}
int main() {
printf("\nE
nter a
string: ");
yylex();
return 0;
}

Output:
5. Program to count number of lines and words.

Code:
%{
#include <stdio.h>

int lc = 0, ch = 0;
%}

%%
\n { lc++; }
[^\n]+ { ch += yyleng; }
%%

int main(int argc, char* argv[]) {


printf("Enter the sentence (Ctrl+Z + Enter to stop on
Windows):\n"); yylex();
printf("\nNumber of
lines = %d\n", lc);
printf("Number of
characters = %d\n", ch);
return 0;
}
int
yy
wra
p()
{ re
turn
1;
}

Output:
Experiment 3:
EXPERIMENT 3:

Aim: Write a program to implement the FIRST and FOLLOW set for the given
grammar.

Code:
def split(init): productions = [] for curr in init:
index = -1 lhs = '' rhs_list = []
for j in range(len(curr)): if curr[j] == '-':
lhs = curr[j - 1] productions.append((lhs, [])) index = j + 1
continue
if j > index and curr[j] == '|': rhs_list = ''
for k in range(index + 1, j): rhs_list += curr[k]
productions[-1][1].append(rhs_list) index = j
elif j > index and j == len(curr) - 1: rhs_list = ''
for k in range(index + 1, j + 1): rhs_list += curr[k]
productions[-1][1].append(rhs_list) return productions

def compute_first(productions): first = {}

def insert_first(nonterm, val): if nonterm not in first:


first[nonterm] = set() size_before = len(first[nonterm]) first[nonterm].add(val)
return len(first[nonterm]) > size_before changed = True
while changed:
changed = False
for nonterm, rules in productions: for rule in rules:
epsilon_chain = True for sym in rule:
if sym.islower() or sym == '@': if insert_first(nonterm, sym):
changed = True epsilon_chain = (sym == '@') break
elif sym.isupper():
for c in first.get(sym, set()):
if c != '@' and insert_first(nonterm, c): changed = True
if '@' in first.get(sym, set()): continue
else:
epsilon_chain = False break
if epsilon_chain:
if insert_first(nonterm, '@'): changed = True
return first

def compute_follow(productions, first, start_symbol): follow = {start_symbol:


{'$'}}
first_str = {k: {str(c) for c in v} for k, v in first.items()}

for _ in range(5):
for lhs, rules in productions: for rhs in rules:
for i, B in enumerate(rhs): if B.isupper():
epsilon_chain = True
for j in range(i + 1, len(rhs)): next_sym = rhs[j]
if next_sym.islower():
follow.setdefault(B, set()).add(next_sym) epsilon_chain = False
break
elif next_sym.isupper():
for f in first_str.get(next_sym, set()): if f != '@':
follow.setdefault(B, set()).add(f) if '@' in first.get(next_sym, set()):
continue
else:
epsilon_chain = False break
if epsilon_chain:
follow.setdefault(B, set()).update(follow.get(lhs, set()))
return follow

n = int(input("Enter number of productions: ")) init = [input().strip() for _ in


range(n)]

productions = split(init)
first = compute_first(productions) start_symbol = productions[0][0]
follow = compute_follow(productions, first, start_symbol)

print("FIRST sets:") for nt in sorted(first):


print(f"{nt} : {' '.join(sorted(first[nt]))}")

print("\nFOLLOW sets:") for nt in sorted(follow):


print(f"{nt} : {' '.join(sorted(follow[nt]))}")

Output:
Exp 4:
EXPERIMENT 4:
Aim: Write a program to implement Parser.

Code:
def split(init, n): productions = [] for i in range(n):
curr = init[i] index = -1 prod = []
for j in range(len(curr)): if curr[j] == '-':
productions.append((c
urr[j - 1], [])) index = j
+1
continue
if j > index and curr[j] == '|':
productions[-1]
[1].append(curr[index + 1:j]) index
=j
continue
if j > index and j == len(curr) - 1:
productions[-1]
[1].append(curr[index + 1:j + 1])
index = j
return productions

def
inputF_F(pro
ductions):
firsttt = []
follo
w=
[]
term
inals
=
set()

for non_term, prods in


productions: for
prod in prods:
first_set = set(input(f"First({prod}):
").split(',')) firsttt.append((prod, first_set))

for non_term, _ in productions:


follow_set = set(input(f"Follow({non_term}):
").split(',')) follow.append((non_term,
follow_set))

print("\nFirst:")
for prod, f_set in firsttt:
print(f"{prod}: {',
'.join(f_set)}")
terminals.update(f_se
t - {'@'})

print("\nFollow:")
for non_term, f_set in follow:
print(f"{non_term}: {',
'.join(f_set)}")
terminals.update(f_set)

return firsttt, follow, terminals

def parse_table(productions, firsttt, follow,


terminals): mapping = {term: i for i, term in
enumerate(terminals)}

print(" ", '

'.join(terminals))

table = []
k=0
prod_index = 0

for non_term, prods in


productions: row =
[0] * len(terminals)
for _ in prods:
first_set
=
firsttt[k]
[1] if '@'
in
first_set:
follow_set =
follow[prod_index][1]
for term in follow_set:
row[mapping[term]] = k + 1
else:
for term in first_set:
row[mapping[term
]] = k + 1
k += 1
table.append((non_ter
m, row)) prod_index
+= 1

for non_term, row in table:


print(non_term, ' '.join(map(lambda x: '-' if x == 0 else
str(x), row))) return table

if name == " main ":


n = int(input("Enter number of productions: "))
init = [input(f"Production {i + 1}: ") for i in range(n)]

productions = split(init, n)
for non_term, prods in
productions: print(f"{non_term}
-> {' | '.join(prods)}")
firsttt, follow, terminals =
inputF_F(productions)
parse_table(productions, firsttt,
follow, terminals)

Output:
Exp 5:
EXPERIMENT 5:
Aim: Write a program to implement Three Address Code (TAC).

Code:
op_precedence = { '(': 5,
'*': 4,
'/': 3,
'+': 2,
'-': 1,
'$': 0
}

def is_variable(ch): return ch.isalpha()

def is_operator(ch):
return ch in op_precedence

def to_postfix(expression): stack = ['$']


postfix = ""

for ch in expression: if ch == '(':


stack.append(ch) elif ch == ')':
while stack[-1] != '(': postfix += stack.pop()
stack.pop()
elif is_variable(ch): postfix += ch
else:
while len(stack) > 1 and stack[-1] != '(' and op_precedence[stack[-1]] >=
op_precedence[ch]:
postfix += stack.pop() stack.append(ch)

while len(stack) > 1: postfix += stack.pop()


return postfix

def generate_TAC(expression): counter = ord('A')


new_input = "" i = 0

while i < len(expression):


if i == 0 and expression[i] == '-' and is_variable(expression[i + 1]):
print(f"{chr(counter)} = -{expression[i + 1]}")
new_input += chr(counter) counter += 1
i += 1
elif i + 2 < len(expression) and is_operator(expression[i]) and expression[i + 1] ==
'-' and is_variable(expression[i + 2]):
print(f"{chr(counter)} = -{expression[i + 2]}") new_input += expression[i] +
chr(counter) counter += 1
i += 2
else:
new_input += expression[i] i += 1
postfix = to_postfix(new_input) stack = []
for ch in postfix:
if is_variable(ch): stack.append(ch)
else:
operand2 = stack.pop() operand1 = stack.pop()
print(f"{chr(counter)} = {operand1} {ch} {operand2}") stack.append(chr(counter))
counter += 1 print(f"{stack[0]} = {postfix[0]}")
if name == " main ":
expression = input("Enter the expression: ") generate_TAC(expression)

Output:
Exp 6:
EXPERIMENT 6:

Aim: Write a program to implement Code Optimization.

Code:
data = [
't1=a+b',
't2=5',
't3=a+b', 't4=5+t3',
't5=a+b', 't6=a+t2',
]

def tempF(code, removed): for k, v in removed.items():


if k not in code: continue
else:
return [k, v] return []

def solve(data): temp = {} removed = {} for i in data:


index = i.find('=')
name = i[0:index].strip() code = i[index + 1:]

t = tempF(code, removed) if len(t) != 0:


code = code.replace(t[0], t[1])

if code not in temp.values(): temp[name] = code


else:
key = ""
for k, v in temp.items(): if v == code:
key = k
break removed[name] = key
return temp

ans = solve(data) count = int(0)


for k, v in ans.items(): print(f't{count + 1}=', end='') for k1, v1 in ans.items():
ans[k1] = ans[k1].replace(k, f't{count + 1}') count = count + 1
print(v)

Output:
Exp 7:
Caption
Caption
EXPERIMENT 7:
Aim: a) Write a program to implement Pass 1 of
Multi-Pass Assembler
b) Write a program to implement Pass 2 of Multi-Pass
Assembler

A.

Code:
opcode_table = { 'ADD': 100,
'SUB': 200,
'MUL': 300,
'DIV': 400,
'JUMP': 500
}

def parse_line(line):
parts = line.strip().split()

label = None opcode = None operands = []

if not parts:
return label, opcode, operands

if len(parts) >= 3 and


parts[1] in opcode_table:
label = parts[0]
opcode = parts[1]
operands = ' '.join(parts[2:]).split(',')

elif parts[0] in opcode_table or parts[0] in


['START', 'END', 'JUMP']: opcode = parts[0]
operands = ' '.join(parts[1:]).split(',') if len(parts) > 1 else []

elif len(parts) == 2: label = parts[0] opcode = parts[1]

elif len(parts) == 1:
if parts[0] not in opcode_table:
label = parts[0] else:
opcode = parts[0]

operands = [op.strip() for op in operands if op.strip()] return label, opcode,


operands

def pass1(assembly_code): symbol_table = {} location_counter = 0

for line in assembly_code:


label, opcode, operands = parse_line(line)

if opcode == 'START' and operands: try:


location_counter = int(operands[0]) except ValueError:
print(f"Invalid START address: {operands[0]}") return None
continue

if opcode == 'END': break

if label:
if label in symbol_table:
print(f"Error: Duplicate symbol {label}") return None
symbol_table[label] = location_counter

if opcode in opcode_table: location_counter += 1


elif opcode is not None:
print(f"Warning: Unknown opcode '{opcode}' at line: {line}") return
symbol_table
print("Enter assembly code (type 'END' to finish):") assembly_code = []
while True: line = input()
assembly_code.append(line) if line.strip() == "END":
break

symbol_table = pass1(assembly_code)
if symbol_table: print("\nSymbol Table:")
for symbol, address in symbol_table.items(): print(f"{symbol} : {address}")

Output:

B.
Code:

opc
ode
_ta
ble
=
{ 'A
DD'
:
100
,
'SU
B':
200
,
'MUL': 300,
'DIV': 400,
'JUMP': 500
}

def parse_line(line):
parts = line.strip().split()

label = None opcode = None operands = []

if not parts:
return label, opcode, operands

if len(parts) >= 3 and


parts[1] in opcode_table:
label = parts[0]
opcode = parts[1]
operands = ' '.join(parts[2:]).split(',')
elif parts[0] in opcode_table or parts[0] in
['START', 'END', 'JUMP']: opcode = parts[0]
operands = ' '.join(parts[1:]).split(',') if
len(parts) > 1 else [] elif len(parts) == 2:
lab
el =
part
s[0]
opc
ode
=
part
s[1]
elif len(parts) == 1:
if parts[0] not
in
opcode_tabl
e: label =
parts[0]
else:
opcode = parts[0]

operands = [op.strip() for op in


operands if op.strip()] return label,
opcode, operands

def pass1(assembly_code): symbol_table = {} location_counter = 0

for line in assembly_code:


label, opcode, operands = parse_line(line)

if opcode ==
'START' and
operands: try:
location_counte
r=
int(operands[0])
except ValueError:
print(f"Invalid START
address: {operands[0]}")
return None
continue

if
opc
ode
==
'EN
D':
bre
ak

if label:
if label in symbol_table:
print(f"Error: Duplicate
symbol {label}") return
None
symbol_table[label] = location_counter

if opcode in
opcode_tabl
e:
location_cou
nter += 1
elif opcode not in ['START', 'END', None]:
print(f"Warning: Unknown opcode '{opcode}'

in line: {line}") return symbol_table

def pass2(assembly_code,
symbol_table):
machine_code = []

for line in assembly_code:


label, opcode, operands = parse_line(line)

if opcode in ['START', 'END'] or


opcode is None: continue

if opcode not in opcode_table:


print(f"Error: Unknown opcode '{opcode}'
in line: {line}") return None

machine_opcode =

opcode_table[opcode]

resolved_operands = []
for operand in operands:
if operand in symbol_table:
resolved_operands.append(str(symbo
l_table[operand]))
else:
resolved_operands.append(operand)

instruction = str(machine_opcode) + ' ' + ','.join(resolved_operands)


machine_code.append(instruction)

return machine_code
print("Enter assembly code line-by-line. Type 'END' on a line by itself to

finish.\n") assembly_code = []

while True: line = input()


assembly_code.append(line) if line.strip() == 'END':
break
symbol_table = pass1(assembly_code) if symbol_table:
print("\nSymbol Table:")
for symbol, address in
symbol_table.items():
print(f"{symbol} :
{address}")

machine_code =

pass2(assembly_code,

symbol_table) if machine_code:
print("\nMachine Code:")
for instruction in
machine_code:
print(instruction)
Output:
Exp 8:
Caption
Caption
NAME: Tanmay Sarode

BATCH: C31
ROLL NUMBER: 2203145

EXPERIMENT 8:
Aim: Write a program to implement Multi-Pass Macroprocessor.

Code:
def split_string(s): return s.strip().split()

def calc_ala(code): ala = {}


index = 0
for line in code: for token in line:
if token.startswith('&'): token_clean = token.rstrip(',') if token_clean not in ala:
ala[tok
en_clea
n] =
index
index
+= 1
print("\nALA:")
for key, value in sorted(ala.items(),
key=lambda x: x[1]): print(f"{value}
{key}")
return ala

def calc_mdt_mnt(code, ala): mdt = {}


mnt = {} k = 1
i=0
while i < len(code): line = code[i]
if line[0] == "MACRO": i += 1
def_line = code[i] temp_str = ""
macro_name_added = False for token in def_line:
if not token.startswith('&') and not macro_name_added: mnt[k] = token
macro_name_added = True temp_str += token + " "
mdt[k] = temp_str.strip()
k += 1
i += 1
while i < len(code) and code[i]
[0] != "MEND": temp_line =
""
for token in
code[i]:
token_cle
an =
token.rstr
ip(',') if
token_cle
an in ala:
temp_line += f"#{ala[token_clean]} " else:
temp_line += token + " " mdt[k] = temp_line.strip()
k += 1
i += 1
mdt[k] = "MEND" k += 1
i += 1

print("\nMDT:")
for key in
sorted(mdt.k
eys()):
print(f"{key}
{mdt[key]}")

print("\nMNT:")
for key in
sorted(mnt.k
eys()):
print(f"{key}
{mnt[key]}")

def main():
n = int(input()) code = []
for _ in range(n): line = input()
split = split_string(line) code.append(split)

ala = calc_ala(code) calc_mdt_mnt(code, ala)

if name == " main ": main()


Output:
Exp 9:
Caption
EXPERIMENT 9:
Aim: Write a program to eliminate left recursion from the given grammar.

Code:
def
split_string(s,
grammar):
left, right =
s.split("->")
grammar[left.strip()] = [prod.strip() for prod in right.split("|")]

def
remove_left_recursion(grammar):
modifications = {}
for non_terminal, productions in
grammar.items(): alpha = []
beta = []
new_non_terminal = non_terminal + "'"

for production in productions:


if production.startswith(non_terminal):
alpha.append(production[len(non_terminal):] +
new_non_terminal)
else:
beta.append(production + new_non_terminal)

if alpha:
modifications[non_terminal] = beta
modifications[new_non_terminal] = alpha +
["@"]
else:
modifications[non_terminal] =
productions return modifications

def print_grammar(grammar):
for nt, prods in
grammar.items():
print(f"{nt} -> {' |
'.join(prods)}")

if name == " main ":


n = int(input("Enter the number of
productions: ")) grammar = {}
for _ in range(n):
s = input("Enter production:
").strip() split_string(s, grammar)

modified_grammar = remove_left_recursion(grammar)
print("\nGrammar after removing left
recursion:")
print_grammar(modified_grammar)

Output:
Exp 10:
EXPERIMENT 10:
Aim: Write a program to implement Code Generation.

Code:
def main():
n = int(input("Enter the number of
expressions: ")) expressions = {}
expr_registers = {} codeGen = [] count = 0
opcodes = { "+": "ADD",
"-": "SUB",
"*": "MUL",
"/": "DIV"
}

for i in range(n):
exp = input(f"Enter TAC expression {i + 1} (e.g., t1 = a
+ b): ").strip() lhs, rhs = exp.split('=')
lhs = lhs.strip() rhs = rhs.strip()

tokens = rhs.split() if len(tokens) != 3:


print(f"Invalid format in
expression: {exp}") continue

op1, op, op2 = tokens expressions[lhs] = rhs

if expr_registers.get(op1) is None and


expr_registers.get(op2) is None: reg = f"R{count}"
expr_registers[lhs] = reg
code = f"MOV {op1}, {reg}\n{opcodes[op]}
{op2}, {reg}" count += 1
elif expr_registers.get(op1) is not None and
expr_registers.get(op2) is None: reg = expr_registers[op1]
expr_registers[lhs] = reg
code = f"{opcodes[op]} {op2}, {reg}"
elif expr_registers.get(op1) is None and
expr_registers.get(op2) is not None: reg =
expr_registers[op2]
expr_registers[lhs] = reg
code = f"MOV {op1}, {reg}
\n{opcodes[op]} {op2}, {reg}" else:
reg =
expr_registe
rs[op1]
expr_registe
rs[lhs] = reg
code = f"{opcodes[op]}

{expr_registers[op2]}, {reg}"

codeGen.append(f"# {exp}\n{code}")

print("--" * 10) print("Generated Code is: ") print("--" * 10)


for code in codeGen: print(code)
print()

if name == " main ": main()

Output:
WRITTEN ASSIGNMENT 1:
Caption
Caption
Caption
Caption
Caption
Caption
Caption
Caption

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy