Computer Science 301 - 2016 - Test on Week 6 - Solutions

Please answer this question directly on the computer. Max 20

This test is intended to check your ability to write attributed Cocol grammars. It should only take you about 45 minutes at the most. Textbooks may be used.

1. You thought you had heard the last of SAFM, didn't you? Wrong again! Here is a version of a grammar for the SAFM 104-107 schedules like the one you saw a few weeks ago.

     COMPILER Radio $CN
     /* The delights of SAFM 104 to 107
        P.D. Terry, Rhodes University, 2016
        Nearly LL(1) version */

     CHARACTERS
       letter  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
       digit   = "0123456789" .
       control = CHR(0) .. CHR(31) .

     TOKENS
       word    = letter { letter | digit } [ ',' ] .
       number  = [ "-" ] digit { digit } .

     COMMENTS FROM "{" TO "}" NESTED

     IGNORE control

     PRODUCTIONS
       Radio        = { TalkShow | "music" | "advert" [ NewsBulletin ] } EOF .
       NewsBulletin = NewsItem { NewsItem } [ Weather ] Filler .
       NewsItem     =   "Zuma" [ "Gordhan" ] | "Gordhan" "Zuma" | "Mugabe"
                      | "corruption" | Story .
       Story        = word { [ number ] word | "Gordhan" | "Mugabe" | "Zuma" }
                      ( "." | "?" | "..." | ":" ) .
       TalkShow     = Host { Listener Host } .
       Host         = "host" Opinion .
       Listener     = "listener" Caller Opinion .
       Opinion      = { Story } .
       Filler       = "music" | "advert" .
       Weather      = "maxmin" "temperatures" OneTemp { "," OneTemp } .
       OneTemp      = Town number number .
       Town         = word . /* a single word suffices for testing */
       Caller       = word .
     END Radio.

Show how this grammar could be attributed so that it could report (using methods from the IO library) :

(a) the length of the longest story that was used in any News Bulletin during the whole day. (b) a list of the callers to the Talk Shows, and the number of times each caller offered an opinion.

What I was looking for was something like this:

     using Library;
     using System.Collections.Generic;

     COMPILER Radio $CN
     /* The delights of SAFM 104 to 107
        P.D. Terry, Rhodes University, 2016
        Nearly LL(1) version */

       static int longestStory = 0;          // we can get away with a global variable in
                                             // this problem.  Be careful of global variables
                                             // but this grammar is non-recursive.

       class Callers {
         public string name;                 // all members public for ease of access
         public int    count = 0;

         public Callers(string name) {
           this.name  = name;
           this.count = 0;
         } / constructor
       } // class Callers
       static List<Callers> callers = new List<Callers>();

       static void AddToCallers(string name) {
       // Search callers to see if it is a known one or a new caller
       // and increment the corresponding opinion count
         int i = 0;
         while (i < callers.Count            // search for matching name
                && !callers[i].name.ToUpper().Equals(name.ToUpper()))
           i++;
         if (i >= callers.Count)             // then we didn't find, so must add
           callers.Add(new Callers(name));
                                             // i by now indexes the appropriate caller
         callers[i].count++;                 // so whether new or known, bump up the opinion count
       } // AddToCallers

       static void DisplayCallers() {
       // Simple display of names and counts for callers.  Note the use of the formatted Write
       // methods from the IO library that allow for easy output lined up in columns.
         foreach (Callers c in callers) {
           IO.Write(c.name, -20);
           IO.WriteLine(c.count, 4);
         }
       } // DisplayCallers

     CHARACTERS
       letter  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                 "abcdefghijklmnopqrstuvwxyz" .
       digit   = "0123456789" .
       control = CHR(0) .. CHR(31) .

     TOKENS
       word    = letter { letter | digit } [ ',' ] .
       number  = [ "-" ] digit { digit } .

     COMMENTS FROM "{" TO "}" NESTED

     IGNORE control

     PRODUCTIONS
       Radio
       = {   TalkShow | "music"
           | "advert" [ NewsBulletin ]
         }                               (. DisplayCallers();      // only at the end of the day
                                            IO.WriteLine("Longest story had " + longestStory + " words"); .)
         EOF .

       NewsBulletin
       = NewsItem { NewsItem } [ Weather ] Filler .

       NewsItem                           (. int length; .)
       =   "Zuma" [ "Gordhan" ]
         | "Gordhan" "Zuma"
         | "Mugabe" | "corruption"
         | Story<out length>              (. if (length > longestStory) longestStory = length; .) .

       Story<out int length>              (. length = 1; .)
       = word {
           (  [ number                    (. length++; .)          // a number counts as a "word"
              ] word
            | "Gordhan" | "Mugabe" | "Zuma"
           )                              (. length++; .)          // we only need to increment it
                                                                   // here because of the () grouping
         } ( "." | "?" | "..." | ":" ) .                           // These are punctuation, and don't
                                                                   // count as extra words

       TalkShow = Host { Listener Host } .

       Host     = "host" Opinion .

       Listener
       = "listener" Caller                 (. AddToCallers(token.val); .)  // add it to the list here
         Opinion .                                                         // and not here (why)

       Opinion                             (. int discard; .)      // these are not news stories so
       = { Story<out discard> } .                                  // we can throw the count away

       Filler   = "music" | "advert" .
       Weather  = "maxmin" "temperatures" OneTemp { "," OneTemp } .
       OneTemp  = Town number number .
       Town     = word .
       Caller   = word .
     END Radio.


Home  © P.D. Terry