Example grammars from a site on the Internet.

Remember that these grammars are pretty arbitrary and there are many correct answers.


Grammar #1:

Write a BNF grammar for the language of Canadian postal codes.

Example sentences:

  K1N 6N5
  M5W 2E4
  X0A 1A1

Solution 1 (simple):

  <postalcode> ::= <letter> <number> <letter> <number> <letter> <number>

Solution 2 (crazy):

  <postalcode>           ::= <forwardsortationarea> <space> <localdeliveryunit>
  <forwardsortationarea> ::= <provarea> <loctype> <letter>
  <localdeliveryunit>    ::= <digit> <letter> <digit>
  <provarea>             ::= A | B | C | E | G | H | J | K | L | M | N | 
                             P | R | S | T | V | X | Y
  <loctype>              ::= <rural> | <urban>
  <rural>                ::= 0
  <urban>                ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  <letter>               ::= A | B | C | E | G | H | J | K | L | M | N | 
                             P | R | S | T | V | W | X | Y | Z
  <digit>                ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Grammar #2:

Write a BNF grammar for the language of University of Ottawa course codes.

Example sentences:

  CSI3125
  MAT2743
  PHY1200
  EPI6581
  CSI9999

Solution:

  <coursecode>   ::= <acadunit> <coursenumber>
  <acadunit>     ::= <letter> <letter> <letter>
  <coursenumber> ::= <year> <semesters> <digit> <digit>
  <year>         ::= <ugrad> | <grad>
  <ugrad>        ::= 0 | 1 | 2 | 3 | 4
  <grad>         ::= 5 | 6 | 7 | 9
  <semesters>    ::= <onesemester> | <twosemesters>
  <onesemester>  ::= <frenchone> | <englishone> | <bilingual>
  <frenchone>    ::= 5 | 7
  <englishone>   ::= 1 | 3
  <bilingual>    ::= 9
  <twosemesters> ::= <frenchtwo> | <englishtwo>
  <frenchtwo>    ::= 6 | 8
  <englishtwo>   ::= 2 | 4
  <digit>        ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Grammar #3:

Write a BNF grammar for the language of palindromes.

Examples (spaces don't count!):

  aba
  pop
  pop a pop
  elu par cette crapule
  a man a plan a canal panama

Solution:

  <palindrome> ::= a <palindrome> a | b <palindrome> b |
                   c <palindrome> c | d <palindrome> d | 
                   e <palindrome> e | ...
                                    | z <palindrome> z
  <palindrome> ::= <letter>
  <letter>     ::= a | b | c | ... | y | z

Grammar #4:

Write a BNF grammar for the language of nonempty data files. A nonempty data file consists of one or more records, where each record is one or more fields. And let's say that each field is either integer (one or more digits) or string (one or more alphabetic or numeric characters enclosed in double quotes). Every record (including the last one) ends with a period. Every field (except the last one in a record) ends with a semicolon.

Solution #1 (repetitive):

  <datafile>    ::= <record> { <record> }
  <record>      ::= <field> { ; <field> } .
  <field>       ::= <integer>  |  <string>
  <integer>     ::= <digit> { <digit> }
  <string>      ::= " <char> { <char> } "
  <char>        ::= <letter>  |  <digit>
  <letter>      ::= the usual stuff
  <digit>       ::= the usual stuff

Solution #2 (recursive):

  <datafile>    ::= <record> . [ <datafile> ]
  <record>      ::= <field> [ ; <record> ]
  <field>       ::= <integer>  |  <string>
  <integer>     ::= <digit> [ <integer> ]
  <string>      ::= " <stringchars> "
  <stringchars> ::= <char> [ <stringchars> ]
  <char>        ::= <letter>  |  <digit>
  <letter>      ::= the usual stuff
  <digit>       ::= the usual stuff

Grammar #5

Write a BNF grammar for the language of Pascal variable declarations without defining user-defined types yet--they'll be defined in Grammar #6. (The funny treatment of the semicolon is required to be able to handle record types below in Grammar #6).

Examples:

  var i : integer;
  var b : boolean;
  var myfloat : real;
      mychar : char;
      x, y, z : integer;

Solution:

  <vardecl>     ::= var <vardecllist> ;
  <vardecllist> ::= <varandtype> { ; <varandtype> }
  <varandtype>  ::= <ident> { , <ident> } : <typespec>
  <ident>       ::= <letter> { <idchar> }
  <idchar>      ::= <letter>  |  <digit>  |  _

Grammar #6

Write a BNF grammar for the language of Pascal type declarations using, as needed, the variable definitions grammar above. (Of course, this doesn't cover all of Pascal type declarations, but it at least covers the examples).

Examples:

  type string20 = packed array[1..20] of char;
  type intptr = ^integer; 
       floatptr = ^real;
  type herb = (tarragon, rosemary, thyme, alpert);
       tinyint = 1..7;
       student = record
                    name, address : string20;
                    studentid : array[tinyint] of integer;
                    grade : char
                 end;

Solution:

  <typedecl>     ::= type <typedeflist>
  <typedeflist>  ::= <typedef> [ <typedeflist> ]
  <typedef>      ::= <typeid> = <typespec> ;
  <typespec>     ::= <typeid> |
                     <arraydef>  |  <ptrdef>  |  <rangedef>  | 
                     <enumdef>  |  <recdef>
  <typeid>       ::= <ident>

  <arraydef>     ::= [ packed ] array <lbrack> <rangedef> <rbrack> of <typeid>
  <lbrack>       ::= [
  <rbrack>       ::= ]

  <ptrdef>       ::= ^ <typeid>

  <rangedef>     ::= <number> .. <number>
  <number>       ::= <digit> [ <number> ]

  <enumdef>      ::= <lparen> <idlist> <rparen>
  <lparen>       ::= (
  <rparen>       ::= )
  <idlist>       ::= <ident> { , <ident> }

  <recdef>       ::= record <vardecllist> end ;