Computer Science 301 - 2012 - Test on Week 24 - Solutions

Please answer all questions in the spaces provided (two sides). Max 10

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

1. Tell me often enough, and I will start to remember everything. What are your (initials) and surname?

( P. D. ) Terry       note the matching format!

2. You thought you had heard the last of Jacob and Julius, didn't you? Wrong again! Here is a version of the grammar for the SAFM schedules that was used as the basis for developing your ad-hoc scanner and recursive descent parser last week. Show how this grammar could be attributed so that it could report (using methods from the IO library) :

(a) the total number of times "zuma" was mentioned during the period analysed
(b) the length of the longest story that was used in any news bulletin during the day
(c) after each weather forecast, the name of the town that could expect the greatest range of temperature.

Hint: This is a non-recursive grammar, so that you will be able to use global/static variables to handle some of these problems if you wish. However, note that Story is to be parameterized.

   import library.*;
   COMPILER Radio
   CHARACTERS
     letter  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
     digit   = "0123456789" .
     control = CHR(0) .. CHR(31) .
   TOKENS
     word    = letter { letter } .
     number  = digit { digit } .
   COMMENTS FROM "{" TO "}" NESTED
   IGNORE control
   PRODUCTIONS
     Radio        = { TalkShow | "music" | "advert" [ NewsBulletin ] } EOF .
     NewsBulletin = NewsItem { NewsItem } [ Weather ] Filler .
     NewsItem     =   "zuma" [ "malema" ] | "malema" "zuma" | "zille"
                    | "corruption" | Story .
     Story        = word { ( word | "marikana" | "malema" | "zuma" ) } "." .
     Opinion      = Story .
     Weather      = "maxmin" "temperatures" OneTemp { "," OneTemp } .
     OneTemp      = word Number Number .
     Number       = number .
     TalkShow     = Host { Listener Host } .
     Host         = "host" Opinion .
     Listener     = "listener" Opinion .
     Filler       = "music" | "advert" .
   END Radio.

There were several common errors made by students here. Typically attributes were added in haphazard places, and too many or too few actions in critical places. I hope I have repeatedly stressed that they have to be placed very accurately after the syntactic elements have been recognized (parsed).

An error made by some people was to place a <parameter attribute> after the terminal "word" in the grammar below. Only non-terminals may have <parameter> attributes, as these correspond to method declarations or calls.

Another error was to try to have some methods declare two "out" parameters. You cannot do this in the Java version of Coco/R, and I have been careful not to use this feature in any of the code I have shown you, even for the C# versions.

Several people misunderstood the questions (I think). The system was supposed to report right at the end how many times Zuma had been encountered, and right at the end the very longest of any of the stories encountered in any news bulletin (stories that counted as "opinions" in talk shows did not count). But it was supposed to report the city with the greatest spread of temperatures for each weather report, not for the whole day!

Other comments are buried in the grammar below - read them and try to understand where you went wrong or could have improved your solution.

    import library.*;

    /* Analyse radio broadcasts (mostly using global variables) Java
       P.D. Terry, Rhodes University, 2012 */

    COMPILER Radio $CN

    /* The system is non-recursive, so we can declare static variables that work very well */

      static int zumaCount = 0;
      static int longestStory = 0;
      static int maxRange = 0;
      static String maxCity = "";

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

    TOKENS
      word    = letter { letter } .
      number  = digit { digit } .

    COMMENTS FROM "{" TO "}" NESTED

    IGNORE control

    PRODUCTIONS

    /* Notice that the output comes after the sequence has been parsed.  Some people put these actions
       at the beginning! */

      Radio
      = {   TalkShow
          | "music"
          | "advert"
          [ NewsBulletin
          ]
        }                             (. IO.writeLine("Zuma mentioned " + zumaCount + " times");
                                         IO.writeLine("Longest story : " + longestStory + " words"); .)
        EOF .

    /* We have to count Zuma every time he is mentioned - some people missed a few zumaCount++ actions.
       We can check for the longest Story overall within each NewsItem *.

      NewsItem                        (. int storyLength; .)
      =   "zuma"                      (. zumaCount++; .)
        [ "malema" ]
        | "malema" "zuma"             (. zumaCount++; .)
        | "zille"
        | "corruption"
        | Story<out storyLength>      (. if (storyLength > longestStory) longestStory = storyLength; .)
      .

    /* Story was parameterized.  The point is that not all stories had to be analysed to find the longest
       story in a news bulletin.  So it makes it easier not to use a global variable in this case. */

      Story<out int length>
      = word                          (. length = 1; .)
        { (   word      |  "marikana"
            | "malema"  |  "mangaung"
            | "zuma"                  (. zumaCount++; .)
          )                           (. length++; .)
        } "." .

    /* Stories that were Opinions in a Talk show had to be discarded, but the call to the Story method
       still requires a parameter, and there must be a corresponding local variable to provide this */

      Opinion                         (. int discarded; .)
      = Story<out discarded> .

    /* We need to print out the name of the city with the greatest range each time we have completed a
       weather report.  Note that we reset maxRange to zero at the start of the report. */

      Weather
      = "maxmin" "temperatures"       (. maxRange = 0; .)
      OneTemp { "," OneTemp }         (. IO.writeLine(maxCity + " has the most variable temperatures today"); .) .

    /* The Number method is parameterized - the actual input token representing a number is converted
       into a numeric value by this method and returned.  Some people may not have understood the
       significance of this.  Note also that we have to save the token.val representing the city at the
       point where it is parsed - and not try to do this a few tokens later. */

      OneTemp                         (. int min, max; .)
      = word                          (. String city = token.val; .)
        Number <out min>
        Number <out max>              (. if (max - min > maxRange) {
                                           maxCity = city;
                                           maxRange = max - min;
                                         } .) .

      Number<out int value>           /* convert a number-string to the equivalent integer */
      = number                        (. try {
                                         value = Integer.parseInt(token.val);
                                       } catch (NumberFormatException e) {
                                         value = 0; SemError("number out of range");
                                       } .) .

      NewsBulletin = NewsItem { NewsItem } [ Weather ] Filler .
      TalkShow     = Host { Listener Host } .
      Host         = "host" Opinion .
      Listener     = "listener" Opinion .
      Filler       = "music" | "advert" .

    END Radio.


Home  © P.D. Terry