CS30 - Spring 2016 - Class 14
Example code in this lecture
cfg.py
Lecture notes
the
cfg.py code
shows one way of implementing the CFG we saw in the slides
- terminals are represented as strings
- each nonterminal is represented as a function, e.g. noun, verb, verb_phrase, etc.
- they return one of two things, representing the right hand side of the rule:
- a string
- a list of functions (could also be a list of functions and strings, though we don't utilize that option)
- if there are multiple options (i.e through |) then a random choice is made
- noun, verb, article, adjective and adverb all generate only terminals
- they randomly select between possible words (strings) using random.choice
- they each return a string
- pre_noun_phrase, noun_phrase, verb_phrase and sentence all generate more nonterminals (though they don't necessarily have to)
- they each return a list of functions, representing a rule that generates a nonterminal on the right hand side
the process function in
cfg.py code
takes in a cfg rule (either a string or a list of functions) and randomly generates a string in that language
- the function is recursive!
- this is not too surprising since CFG have a recursive feeling to them
- the base case is if we're dealing with a terminal (i.e a string)
- the recursive case is if we have a list of nonterminals (i.e. functions)
- for each item (function) in this list:
- call the function "item()"
- and then call process on whatever it give in return
- this will either be a string (in the case of a rule that generates a terminal)
- or another list of functions
- the results are then appended together into one string
- we can call the process function by getting it started with [sentence], i.e.
>>> process([sentence])
'the bagel eats intentionally'
- for this to happen, the recursion would be something like:
- top call: process([sentence])
- this would then make two recursive calls to return: process(noun_phrase()) + " " + process(verb_phrase())
- the call to noun_phrase returns [article, pre_noun_phrase]
- which then is passed to process
- article gives us 'the'
- and the pre_noun_phrase pics just [noun]
- the noun "bagel" is chosen
- ...
printing out lots of random derivations from the grammar
- if we put this call in a loop, we can get lots of random strings:
>>> for i in range(10):
... print process([sentence])
a milk eats
a bagel sleeps
a idea sleeps furiously
a green idea eats soothingly
a green cow sleeps intentionally
the colorless smelly cow sleeps
the colorless cow swims soothingly
the bagel swims intentionally
a idea sprints
the colorless colorless colorless green cow swims intentionally