Experiment - 4: Aim: Write A Program To Determine The First Set of The Given Grammar-Theory
Experiment - 4: Aim: Write A Program To Determine The First Set of The Given Grammar-Theory
Aim: Write a program to determine the First Set of the given grammar-
Theory: If the compiler would have come to know in advance, that what is the “first
character of the string produced when a production rule is applied”, and comparing it
to the current character or token in the input string it sees, it can wisely take decision
on which production rule to apply.
S -> cAd
A -> bc|a
And the input string is “cad”.
Thus, in the example above, if it knew that after reading character ‘c’ in the input
string and applying S->cAd, next character in the input string is ‘a’, then it would
have ignored the production rule A->bc, and directly use the production rule A->a.
Hence it is validated that if the compiler/parser knows about first character of the
string that can be obtained by applying a production rule, then it can wisely apply the
correct production rule to get the correct syntax tree for the given input string.
Code:
"""
Created on Sun Mar 31 18:58:56 2019
@author: harjeet
"""
class Rule:
nextId = 0
class Grammar:
def __init__ (self, rules):
self.rules = {rule.id: rule for rule in rules}
self.symbols = set (symbol for rule in rules for symbol in [rule.left] + rule.right)
self.nonTerminals = set (rule.left for rule in rules)
self.terminals = self.symbols - self.nonTerminals
self.calculateFirst ()
first = set ()
for rule in (rule for rule in self.rules.values () if rule.left == symbol):
prefix = rule.right [0]
if prefix == symbol: continue
if prefix in self.terminals: first.add (prefix)
else: first |= self.getFirst (prefix)
return first
rules = [Rule ('S', ['E'] ), Rule ('E', ['T'] ), Rule ('E', ['(', 'E', ')'] ), Rule ('T', ['n'] ), Rule
('T', ['+', 'n'] ), Rule ('T', ['T', '+', 'n'] ) ]
g = Grammar (rules)
print ('Rules:')
for rule in g.rules.values (): print ('\t{}'.format (rule) )
for nonTerminal in g.nonTerminals:
print ('First ({}) = {}'.format (nonTerminal, g.first [nonTerminal] ) )
Output :