CD Lab Manual
CD Lab Manual
LABORATORY MANUAL
Compiler Design (3170701)
B.E. SEM. VII (COMPUTER), Year 2024-25 (Odd Sem.)
CERTIFICATE
This is to certify that the work carried out by Mr. /Ms.
Date of Submission:
INDEX
PRACTICAL-1
Aim: Implementation of Finite Automata and String Validation.
defaccepts(transition, initial, accepting, s):
state = initial
for char in s:
state = transition[state].get(char, None) if
state is None:
return False
return state in accepting
#DFA transitions:
dfa = {
'q0': {'a': 'q1', 'b': 'q3'},
'q1': {'a': 'q3', 'b': 'q2'},
'q2': {'a': 'q1', 'b': 'q0'},
'q3': {'a': 'q3', 'b': 'q3'}
}
4
COMPILER DESIGN 211040107005
OUTPUT:
5
COMPILER DESIGN 211040107005
PRACTICAL-2
Aim: Introduction to Lex Tool
Lex is a tool or a computer program that generates Lexical Analysers (converts the stream of
characters into tokens). The Lex tool itself is a compiler. The Lex compiler takes the input
and transforms that input into input patterns. It is commonly used with YACC (Yet Another
Compiler Compiler). It was written by Mike Lesk and Eric Schmidt.
Function of Lex
1. In the first step the source code which is in the Lex language having the file name
‘File.l’ gives as input to the Lex Compiler commonly known as Lex to get the output
as lex.yy.c.
2. After that, the output lex.yy.c will be used as input to the C compiler which gives the
output in the form of an ‘a.out’ file, and finally, the output file a.out will take the
stream of character and generates tokens as output.
6
COMPILER DESIGN 211040107005
For example:
Declaration
Number[0-9]
%%
translation
if{return(IF);}
auxiliary function
intnumberSum()
7
COMPILER DESIGN 211040107005
/ rule section % %
// regex for valid identifiers
^[a - z A - Z _][a - z A - Z 0 - 9 _] * printf("Valid Identifier");
main()
{
yylex();
}
OUTPUT:
8
COMPILER DESIGN 211040107005
PRACTICAL-3
defis_comment(user_input):
user_input = user_input.strip() if
user_input.startswith("#"):
return True
if user_input.startswith("//"): return
True
return True
return False
if is_comment(user_input):
else:
9
COMPILER DESIGN 211040107005
OUTPUT:
10
COMPILER DESIGN 211040107005
PRACTICAL-4
Aim: Write a Python program to remove left recursion from given grammar.
def eliminate_left_recursion(grammar):
new_grammar = {}
new_productions = []
if production[0] == non_terminal:
[new_non_terminal]
new_productions.append(new_production)
else:
new_productions.append(production)
new_grammar[non_terminal] = new_productions
return new_grammar
grammar = {
11
COMPILER DESIGN 211040107005
new_grammar = eliminate_left_recursion(grammar)
my_dict = {'a':1,'b':2,'c':3}
print(f"{key}:{value}")
OUTPUT:
12
COMPILER DESIGN 211040107005
PRACTICAL-5
Aim: Write a python program to find the first set for given grammar.
def find_first_set(grammar):
first_set = {}
first_set[non_terminal] = set()
while True:
old_first_set = first_set.copy()
production in productions:
if production[0].islower():
first_set[non_terminal].add(production[0])
else:
first_set[non_terminal].update(first_set[production[0]])
if old_first_set == first_set:
break
13
COMPILER DESIGN 211040107005
return first_set
# Example usage:
grammar = {
'S': ['a'],
'A': ['c'],
first_set = find_first_set(grammar)
print("First set:")
14
COMPILER DESIGN 211040107005
OUTPUT:
15
COMPILER DESIGN 211040107005
PRACTICAL-6
Aim: Write a python program to find the follow set for given grammar.
deffind_follow_set(grammar, first_set):
follow_set = {}
follow_set[non_terminal] = set()
start_symbol = list(grammar.keys())[0]
follow_set[start_symbol].add('$')
while True:
old_follow_set = follow_set.copy()
production in productions:
if production[i].isupper():
next_symbol = production[i + 1]
if next_symbol.islower():
follow_set[production[i]].update({next_symbol})
else:
follow_set[production[i]].update(first_set[next_symbol])
16
COMPILER DESIGN 211040107005
if production[-1].isupper():
follow_set[production[-1]].update(follow_set[start_symbol])
if old_follow_set == follow_set:
break
return follow_set
# Example usage:
grammar = {
first_set = {
'S': {'a',
'b'},
17
COMPILER DESIGN 211040107005
print("Follow set:")
OUTPUT:
18
COMPILER DESIGN 211040107005
PRACTICAL-7
first_set={}
follow_set={}
self.grammar = grammar
self.first_set = self.compute_first_set()
self.follow_set = self.compute_follow_set()
defcompute_first_set(self):
first_set = {}
first_set[non_terminal] = set()
first_set[non_terminal].add(production[0])
first_set[non_terminal].update(self.compute_first_set_for_non_terminal(production[0]))
return first_set
defcompute_first_set_for_non_terminal(self, non_terminal):
19
COMPILER DESIGN 211040107005
self.first_set[non_terminal] = set()
self.first_set[non_terminal].add(production[0]) else:
# non-terminal symbol
self.first_set[non_terminal].update(self.compute_first_set_for_non_terminal(production[ 0]))
return self.first_set[non_terminal]
defcompute_follow_set(self):
follow_set = {}
follow_set[non_terminal] = set()
follow_set[self.get_start_symbol()] = {'$'} # add the end symbol to the follow set of the
start symbol
production in productions:
follow_set[production[i]].update(self.first_set[production[i + 1]])
follow_set[production[i]].update(follow_set[non_terminal])
20
COMPILER DESIGN 211040107005
return follow_set
defget_start_symbol(self):
return non_terminal
return None
def is_ll1(self):
i in range(len(productions)):
first_set_i = self.first_set[productions[i][0]]
first_set_j = self.first_set[productions[j][0]]
return False
if '' in first_set_i:
False
return True
# Example usage:
21
COMPILER DESIGN 211040107005
grammar = {
checker = LL1Checker(grammar)
if checker.is_ll1():
else:
OUTPUT:
22
COMPILER DESIGN 211040107005
PRACTICAL-8
23
COMPILER DESIGN 211040107005
elif(match("i")):
return True
else:
return False
defTx():
if(match("*")):
if(F()):
if(Tx()):
return True
else:
return False
else:
return False
else:
return True
defT():
if(F()):
if(Tx()):
return True
else:
return False
else:
return False
defEx():
if(match("+")):
if(T()):
if(Ex()):
return True
else:
24
COMPILER DESIGN 211040107005
return False
else:
return False
else:
return True
defE():
if(T()):
if(Ex()):
return True
else:
return False
else:
return False
if(E()):
if(i==len(s)):
print("String is accepted")
else:
print("String is not accepted")
else:
print("string is not accepted")
25
COMPILER DESIGN 211040107005
OUTPUT:
26
COMPILER DESIGN 211040107005
PRACTICAL-9
EXPRESSION_MAX = 100
def precedence(op):
if op == '+':
elif op == '*':
op == '(':
return 0 # No precedence
elif op == ')':
return 0 # No precedence
else:
defcreate_table(operators):
for i in range(len(operators)):
for j in range(len(operators)):
if i == j:
27
COMPILER DESIGN 211040107005
else:
if operators[i] in '+*':
else:
return table
defdisplay_table(operators, table):
for op in operators:
print()
for i in range(len(operators)):
for j in range(len(operators)):
if table[i][j] == 1:
elif table[i][j] == -
end='')
28
COMPILER DESIGN 211040107005
else:
print()
defparse_expression(expression, operators):
if char in operators:
defmain(): operators
= "+*()"
table = create_table(operators)
display_table(operators, table)
parse_expression(expression, operators)
main()
29
COMPILER DESIGN 211040107005
OUTPUT:
30
COMPILER DESIGN 211040107005
PRACTICAL-10
Aim: Write a python program to implement LALR(1) parser for the given
grammar.
class
ActionType:
SHIFT = 0
REDUCE = 1
ACCEPT = 2
ERROR = 3
class Action:
self.type = action_type
self.value = value
MAX_STATES = 4
MAX_SYMBOLS = 3
definitialize_parsing_table():
# State 0
# State 1
31
COMPILER DESIGN 211040107005
# State 2
# State 3
parsing_table[3][1] = Action(ActionType.REDUCE, 0) # A -
>aA
defprint_parsing_table():
print("Parsing Table:")
print("_" *30)
for i in range(MAX_STATES):
print(f"{i}\t\t", end="")
for j in
range(MAX_SYMBOLS):
action = parsing_table[i][j]
if action.type == ActionType.SHIFT:
print(f"S{action.value}\t\t", end="")
elifaction.type == ActionType.REDUCE:
print(f"R{action.value}\t\t", end="")
elifaction.type == ActionType.ACCEPT:
32
COMPILER DESIGN 211040107005
print("Accept\t\t", end="")
else:
print("-\t\t", end="")
else:
print("-\t\t", end="")
print()
": initialize_parsing_table()
print_parsing_table()
OUTPUT:
33