Ex 06 LL
Ex 06 LL
Ex 06 LL
Theory :
LL(1) Parser :
LL(1) parsing is a top-down parsing method in the syntax analysis phase of compiler
design. Required components for LL(1) parsing are input string, a stack, parsing table
for given grammar, and parser. Here, we discuss a parser that determines whether a
given string can be generated from a given grammar(or parsing table) or not.
Let given grammar is G = (V, T, S, P)
where V-variable symbol set, T-terminal symbol set, S- start symbol, P- production set.
LL(1) Grammer :
The first ‘L’ in LL(1) stands for scanning the input from left to right, the second ‘L’ stands
for producing a leftmost derivation, and the ‘1’ for using one input symbol of lookahead
at each step to make parsing action decisions. LL(1) grammar follows the Top-down
parsing method. For a class of grammars called LL(1) we can construct a grammar
predictive parser. That works on the concept of recursive-descent parser not requiring
backtracking.
A → β A’
A’ → α A’ | ε
1
Left Factoring
Epsilon (ε) can never be present in the FOLLOW of any non-terminal symbol.
2
Parsing table :
After the construction of the parsing table, if for any non-terminal symbol in the table we
have more than one production rule for any terminal symbol in the table column the
grammar is not LL(1). Otherwise, then grammar is considered as LL(1).
Step 1 : For each production A → α , of the given grammar perform Step 2 and Step 3.
Step 2 : For each terminal symbol ‘a’ in FIRST(α), ADD A → α in table T[A,a], where ‘A’
determines row & ‘a’ determines column.
a. The LHS symbol of the First rule is considered as the start symbol.
b. ‘#’ represents the epsilon symbol.
Output- determines that given string can be produced by given grammar(parsing table)
or not, if not then it produces an error.
3
Steps :
// initially it is S
2. A = top symbol of stack;
4
Grammer:
S->ACB|CbB|Ba
A->da|BC
B->g|#
C->h|#
Program:
import re
ep = list()
fp = open("/content/grammer.txt","r") #read CFG from file
cfg=dict() #create dictionary to stored CFG
global non_terminal
def find_first(key):
value=cfg[key] #find RHS of key(LHS)
#print(key,value)
if ('#' in value): #if key directly derived epsilon
value.remove('#')
for item in value: #consider individual production rule
if item[0] in ep: #if that variable produve epsilon
epsilon(item)
#print("Epsilon called for ",item)
else:
if (item[0].islower()):
#print(non_terminal,"-->",item[0])
if item[0] not in temp:
temp.append(item[0])
else:
find_first(item[0])
def epsilon(item):
#print("From Epsilon ",item[0])
find_first(item[0]) #find first of that variable
length=len(item)
i=1
while(i<=length-1):
if item[i] in ep:
find_first(item[i])
i=i+1
if(i==length):
#print(non_terminal,"-->#")
if '#' not in temp:
temp.append('#')
break
else:
if (item[i].islower()):
#print(non_terminal,"-->",item[i])
5
if item[i] not in temp:
temp.append(item[i])
break
else:
find_first(item[i])
break
def find_follow(key):
for item in v:
6
if(i==len(item)): #if we reach at right most side of RHS
temp1=follow[k] #find follow[LHS]
for j in temp1:
temp.append(j) #append result
temp=list()
first=dict()
for key,value in cfg.items():
first[key]=[] #initialize value of key as list
#print("FIRST[",key,"]") #find first of all variable(non-terminal)
non_terminal=key
find_first(key)
if key in ep:
#print(non_terminal,"-->#")
if '#' not in temp: #if varaible produce epsilon
temp.append('#') #add epsilon to first[variable]
#print(temp)
for item in temp:
first[non_terminal].append(item) #add all results to first
#print(temp)
temp.clear()
7
#print(first)
#print("Follow() are as follow->")
follow=dict()
flag=0
temp=list()
#print(first)
for key,value in cfg.items():
follow[key]=[] #initialize value of key as list
if flag==0:
temp.append("$") #follow of start symbol is $
flag=1
find_follow(key)
#print("follow[",key,"]")
#print(temp)
for k in temp:
if( k not in follow[key]): # removed duplicate and add it to final
result
follow[key].append(k)
temp.clear()
#print(follow)
print(cfg)
8
Output:
Given Context Free Grammar is =
S -> ['ACB', 'CbB', 'Ba']
A -> ['da', 'BC']
B -> ['g', '#']
C -> ['h', '#']
Non Terminal First() Follow()
------------------------------------------------------
S ['d', 'g', 'h', '#', 'b', 'a'] ['$']
{'S': ['ACB', 'CbB', 'Ba'], 'A': ['da', 'BC'], 'B': ['g'], 'C': ['h']}
Conclusion:
Thus we have successfully implemented LL(1) Parser.