Use the function given below to, first, help you to convert a multiline CFG string representation of the form expected into a dictionary represention. Then write the function being asked. def cfg_str_to_dict(cfg_str): """Converts a multiline CFG string representation of the form required into a dictionary represention, e.g. "S=ab|bA|BB|_" becomes {"S": ["ab", "bA", "BB", ""]} """ nonterminals = {char for char in cfg_str if char.isupper()}.union({'S'}) result = {nt: [] for nt in nonterminals} productions = cfg_str.splitlines() for production in productions: nt, rhs = production.split("=") rhs = rhs.replace("_", "") # Use "" for epsilon rhs_list = rhs.split("|") result[nt] = result.get(nt) + rhs_list return result
Use the function given below to, first, help you to convert a multiline CFG string representation of the form expected into a dictionary represention. Then write the function being asked.
def cfg_str_to_dict(cfg_str):
"""Converts a multiline CFG string representation
of the form required into a dictionary represention, e.g.
"S=ab|bA|BB|_" becomes {"S": ["ab", "bA", "BB", ""]}
"""
nonterminals = {char for char in cfg_str if char.isupper()}.union({'S'})
result = {nt: [] for nt in nonterminals}
productions = cfg_str.splitlines()
for production in productions:
nt, rhs = production.split("=")
rhs = rhs.replace("_", "") # Use "" for epsilon
rhs_list = rhs.split("|")
result[nt] = result.get(nt) + rhs_list
return result
![A non-terminal A is reachable if S ⇒* uAv for some u, v E (ΣUN)*. That is:
• S is reachable.
• If A → w EP and A is reachable, then every non-terminal in w is reachable.
Write a function reachable_nts (cfg_str) that returns a set containing all the reachable non-terminals in the given CFG, where
cfg_str is a multi-line string representing a CFG in the format described in the info panel before Question 6.
Notes:
Study the examples below carefully. Make sure you understand why each non-terminal is or is not reachable.
• Your answer may contain helper functions.
• You may find it convenient to use the helper function provided in the answer box to convert cfg_str into a dictionary. However, you
are also welcome to discard it and write your own code for processing cfg_str.
• The string method str.isupper may be useful for identifying non-terminals. (Remember that terminals may be numeric, so
str.islower is probably not useful for identifying terminals.)
For example:
Test
# The CFG G1 above, in which all NTs are reachable.
cfg = """S=BA
A=a | BA | BB
B=b | AA"""
print (sorted (reachable_nts (cfg)))
# C looks reachable at first but isn't. Can you see why?
cfg = """S=aB | bA
A=aS | bAA
B=bS | aBB |_
C=abc | SC""'"
print (sorted (reachable_nts(cfg)))
Result
['A', 'B', 'S']
cfg
print (sorted (reachable_nts (cfg)))
['A', 'B', 'S']
# A tricky case: S is not in any productions but still reachable. ['S']
# By definition, S is reachable from S using 0 derivation steps
# (so no productions are needed).
= "A=0A1"](/v2/_next/image?url=https%3A%2F%2Fcontent.bartleby.com%2Fqna-images%2Fquestion%2F09c2f836-a777-444b-9271-94b360db7692%2F7897a607-7660-439f-a068-6bd9bd87b761%2Fib8ujz_processed.png&w=3840&q=75)

Step by step
Solved in 3 steps with 1 images









