4.48 Exercise 4.48

For this exercise, I’m going to be adding some support for adjectives and adverbs, as well as simple conjunctions of the two.

I’m going to be following a simple rule for parsing adverbs: The adverb must appear after the verb it modifies. In reality, placing adverbs is much more complicated than this, but I’m not going to be exploring that at this time.

In the simplest form, instead of parsing just a verb, we are either parsing a verb or a verb followed by an adverb. We’ll still label this a verb-phrase.

(define adverbs '(adverb quickly slowly immediately lazily))
 
(define (parse-verb-phrase-with-adverb)
  (list 'verb-phrase
        (parse-word verbs)
        (parse-word adverbs)))
 
(define (parse-verb-phrase)
  (define (maybe-extend verb-phrase)
    (amb verb-phrase
         (maybe-extend (list 'verb-phrase
                             verb-phrase
                             (parse-prepositional-phrase)))))
  (maybe-extend (amb (parse-word verbs)
                     (parse-verb-phrase-with-adverb))))

Adjectives, on the other hand, appear before the nouns they modify in English. A slight variant on the above will allow noun phrases to include adjectives:

(define adjectives '(adjective big small red green blue))
 
(define (parse-noun-phrase-with-adjective)
  (list 'noun-phrase
        (parse-word articles)
        (parse-word adjectives)
        (parse-word nouns)))
 
(define (parse-noun-phrase)
  (define (maybe-add-prep-phrase noun-phrase)
    (amb noun-phrase
         (maybe-add-prep-phrase (list 'noun-phrase
                                      noun-phrase
                                      (parse-prepositional-phrase)))))
  (maybe-add-prep-phrase (amb (parse-simple-noun-phrase)
                              (parse-noun-phrase-with-adjective))))

While there are multiple types of conjunctions in English, I’m going to focus on adding conjunctions to of adverbs onto adverbs and adjectives onto adjectives. I’ll allow the number of conjunctions to be unlimited (even though this probably won’t apply much in practice). We can write functions that are essentially similar to those which added prepositional phrases:

(define (parse-adverb-phrase)
  (define (maybe-add-conjunction adverb-phrase)
    (amb adverb-phrase
         (maybe-add-conjunction (list 'conjunction
                                      adverb-phrase
                                      (parse-word conjunctions)
                                      (parse-word adverbs)))))
  (maybe-add-conjunction (parse-word adverbs)))
 
(define (parse-adjective-phrase)
  (define (maybe-add-conjunction adjective-phrase)
    (amb adjective-phrase
         (maybe-add-conjunction (list 'conjunction
                                      adjective-phrase
                                      (parse-word conjunctions)
                                      (parse-word adjectives)))))
  (maybe-add-conjunction (parse-word adjectives)))

However, you’ll notice that adding a sequence of conjunctions of a single type of word is an essentially generic operation – in fact, these two procedures are almost identical. We can factor out the commonality by pulling out the parsing of the specific type of word into a thunk:

(define (parse-with-conjunctions parser)
  (define (maybe-add-conjunction acc)
    (amb acc
         (maybe-add-conjunction (list 'conjunction
                                      acc
                                      (parse-word conjunctions)
                                      (parser)))))
  (maybe-add-conjunction (parser)))
 
(define (parse-adjective-phrase)
  (parse-with-conjunctions (lambda () (parse-word adjectives))))
 
(define (parse-adverb-phrase)
  (parse-with-conjunctions (lambda () (parse-word adverbs))))

Even though it might have been less obvious, I’ve chosen to parametize the entire parser instead of just the word list to use.