Generating Software from Specifications WS 2013/14 - File CalendarSol7.fw
@=~ ~p maximum_input_line_length = infinity This file contains the specification of a calendar processor. It reads a sequence of appointments, represents them by a tree structure, and outputs the tree. The following file contains some input for the processor ~O~<cal.ok~>~{~- 1.11. 20:00 "Theater" Thu 14:15 "GSS lecture" Weekday 12:05 "Dinner in Palmengarten" Mon, Thu "Dean's office" 31.12. 23:59 "Jahresende" 12/31 23:59 "End of year" May 1 "Labour Day" -- end of file ~} TASK 1: Generate the processor and test it systematically. Make sure that you test for every construct of the language at least one correct and one erroneous example. Use several input files for the erroneous examples to avoid cluttered output. ~O~<cal1.err~>~{~- 1.11 20:00 "A" 1.11. 24:01 "B" 1.11. 20:00 "aa thu 20:00 "A" 33.12. 20:00 "A" ~} ~O~<cal2.err~>~{~- 12.13. 20:00 "A" 12/33 20:00 "A" 13/12 20:00 "A" Mai 1 "Labour Day" - ~} The following file specifies the concrete syntax: ~O~<Calendar.con~>~{ Calendar: Entry+. Entry: Date Event. Date: DayNum '.' MonNum '.' / MonNum '/' DayNum / Month DayNum / DayNames / GeneralPattern. DayNum: Integer. MonNum: Integer. DayNames: DayName / DayNames ',' DayName. DayName: Day. GeneralPattern: SimplePattern / SimplePattern Modifier. SimplePattern: 'Weekday' / 'Weekend'. Modifier: '+' DayNames / '-' DayNames. Event: When Description / Description. When: Time / Time '-' Time. ~} TASK 2: Check the meaning of the following token specifications. Extend the input language by comments. What kind of comments do you think fits best to the style of this language? Specify it and test the processor. The appointments of this language will usually be written one per line. So, line comments would fit best to the language. I specified Ada comments. ~O~<Calendar.gla~>~{ Description: C_STRING_LIT Integer: PASCAL_INTEGER Day: $Mon|Tue|Wed|Thu|Fri|Sat|Sun [mkDay] Time: $(([0-9]|1[0-9]|2[0-3]):[0-5][0-9]) [mkTime] ADA_COMMENT Month: $Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec [mkMonth] ~} TASK 3: The C module below implements the two token coding functions mkDay and mkTime. Understand what they compute. Then extend your language by a facility to write abbreviated names of months, too, e.g. May 1 "Labour Day" Which specification types do you need to change? A new alternative for Date is inserted in the concrete syntax (.con). The token specification for Month is added (.gla). The coding function is implemented in the C module (.h, .c) Correct and erroneous test cases are added. You can make the extensions according to the way the names of Days are specified. TASK 4: Change the specification of the token Time. (Keep the current specification, in order to undo this change after this experiment.) Make time to be a nonterminal which derives the hours and minutes separated by a colon. Any checks, whether the time is correct may be deferred to the semantic analysis phase. Check carefully how the notation of Time now differs from the previous version. Which one do you prefer? I inserted the productions Time: Hour ':' Minute. Hour: Integer. Minute: Integer. into the concrete syntax and deleted the token specification for Time. The check for correct time notations is then deferred to semantic analysis. Now it is possible to insert white space into time notations e.g. 10 : 25. I prefer the original notation. ~O~<Calendar.head~>==~{ #include "csm.h" #include "Calendar.h" ~} ~O~<Calendar.h~>==~{ extern void mkDay (char *, int, int *, int*); extern void mkTime (char *, int, int *, int*); extern void mkMonth (char *, int, int *, int*); ~} ~O~<Calendar.c~>==~{ #include <string.h> #include "Calendar.h" void mkDay (char *d, int l, int *c, int *i) { switch (d[0]) { case 'F': *i = 5; break; case 'M': *i = 1; break; case 'W': *i = 3; break; case 'S': *i = (d[1] == 'a'? 6 : 7); break; case 'T': *i = (d[1] == 'u' ? 2 : 4); break; } } void mkTime (char *t, int l, int *c, int *i) { char *colon = strchr (t, ':'); int hours, mins; *colon = '\0'; hours = atoi (t); mins = atoi (colon + 1); *colon = ':'; *i = hours*60 + mins; } void mkMonth (char *m, int l, int *c, int *i) { switch (m[0]) { case 'A': *i = (m[1] == 'p' ? 4 : 8); break; case 'D': *i = 12; break; case 'F': *i = 2; break; case 'J': *i = (m[1] == 'a' ? 1 : (m[2] == 'n' ? 6 : 7)); break; case 'M': *i = (m[2] == 'r' ? 3 : 5); break; case 'N': *i = 11; break; case 'O': *i = 10; break; case 'S': *i = 9; break; } } ~}
Generiert mit Camelot | Probleme mit Camelot? | Geändert am: 06.11.2013