0% found this document useful (0 votes)
18 views2 pages

First&follow

The document contains Python code for computing FIRST and FOLLOW sets in a context-free grammar. It defines two helper functions, `compute_first` and `compute_follow`, which recursively calculate the FIRST and FOLLOW sets for non-terminals in the grammar. An example grammar is provided, and the code outputs the computed FIRST and FOLLOW sets.

Uploaded by

gazalgg11
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views2 pages

First&follow

The document contains Python code for computing FIRST and FOLLOW sets in a context-free grammar. It defines two helper functions, `compute_first` and `compute_follow`, which recursively calculate the FIRST and FOLLOW sets for non-terminals in the grammar. An example grammar is provided, and the code outputs the computed FIRST and FOLLOW sets.

Uploaded by

gazalgg11
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 2

from collections import defaultdict

# Helper function to compute FIRST sets


def compute_first(grammar):
first = defaultdict(set) # Stores FIRST sets for each non-terminal

def first_of(symbol):
# If FIRST(symbol) is already computed, return it
if symbol in first and first[symbol]:
return first[symbol]
# If symbol is a terminal (e.g., 'a'), its FIRST is itself
if not symbol.isupper():
return {symbol}
# For non-terminals (e.g., 'A'), compute recursively
result = set()
for production in grammar[symbol]: # Loop through all productions of the
symbol
for char in production: # Check each character in the production
char_first = first_of(char) # Recursive call to compute FIRST of
the character
result.update(char_first - {'ε'}) # Add all except epsilon
if 'ε' not in char_first: # Stop if epsilon is not present
break
else: # If all characters can produce epsilon, add epsilon
result.add('ε')
first[symbol] = result
return result

# Compute FIRST for all non-terminals in the grammar


for non_terminal in grammar:
first_of(non_terminal)
return first

# Helper function to compute FOLLOW sets


def compute_follow(grammar, start_symbol, first_sets):
follow = defaultdict(set) # Stores FOLLOW sets
follow[start_symbol].add('$') # Rule 1: Start symbol has $ in FOLLOW

# Repeat until no changes occur


while True:
updated = False
# Loop through all productions (A -> α)
for non_terminal, productions in grammar.items():
for production in productions:
trailer = follow[non_terminal].copy() # Initialize trailer with
FOLLOW(A)
# Traverse the production from right to left
for i in reversed(range(len(production))):
symbol = production[i]
if symbol.isupper(): # Only process non-terminals
# If FOLLOW(symbol) changes, mark as updated
if trailer - follow[symbol]:
follow[symbol].update(trailer)
updated = True
# Update trailer based on FIRST of current symbol
if 'ε' in first_sets[symbol]:
trailer.update(first_sets[symbol] - {'ε'})
else:
trailer = first_sets[symbol].copy()
else: # Terminal symbol resets the trailer
trailer = {symbol}
if not updated:
break
return follow

# Example Grammar
grammar = {
'E': ['T+E', 'T'],
'T': ['F*T', 'F'],
'F': ['(E)', 'id']
}

# Compute FIRST and FOLLOW


first_sets = compute_first(grammar)
follow_sets = compute_follow(grammar, 'E', first_sets)

# Print results
print("FIRST Sets:")
for nt in grammar:
print(f"FIRST({nt}) = {first_sets[nt]}")

print("\nFOLLOW Sets:")
for nt in grammar:
print(f"FOLLOW({nt}) = {follow_sets[nt]}")

You might also like