Here are some silly languages that we can use for the purpose of seeing
how we write a recursive descent parser. These langauges are all vaguely
"expression" like.

-----------------------------------------------------------------------------


Language S1.

Notice that these productions are mutually recursive, but no production is recursive.

S1 -> A '+' B | B '+' A
A  -> 'a' '*' '(' S1 ')' | 'a'
B  -> 'b' '*' '(' S1 ')' | 'b'


We can use EBNF to rewrite this grammar.

S1 -> A '+' B | B '+' A
A  -> 'a' [ '*' '(' S1 ')' ]
B  -> 'b' [ '*' '(' S1 ')' ]

Some example strings are:
"a*(a+b)+b"
"b*(a*(b+a)+b)+a*(a+b*(b+a))"

-----------------------------------------------------------------------------


Language S2.

Notice that the two alternatives in the first production of this language
have the same first token.

S2 -> A '+' B | A '+' C
A  -> 'a' '*' '(' S2 ')' | 'a'
B  -> 'b' '*' '(' S2 ')' | 'b'
C  -> 'c' '*' '(' S2 ')' | 'c'


We can use EBNF to rewrite this grammar in a way that will work with a
recursive descent parser.

S2 -> A '+' [ B | C ]
A  -> 'a' [ '*' '(' S2 ')' ]
B  -> 'b' [ '*' '(' S2 ')' ]
C  -> 'c' [ '*' '(' S2 ')' ]


Some example strings are:
"a*(a+c)+b"
"a*(a*(a+b)+b)+c*(a+b*(a+c))"

-----------------------------------------------------------------------------


Language S3.

S3 -> A '+' B | B '+' A | A | B
A  -> 'a' '*' '(' S3 ')' | 'a'
B  -> 'b' '*' '(' S3 ')' | 'b'


We can use EBNF to rewrite this grammar.

S3 -> A [ '+' B ]  |  B [ '+' A ]
A  -> 'a' [ '*' '(' S3 ')' ]
B  -> 'b' [ '*' '(' S3 ')' ]

-----------------------------------------------------------------------------


Language S4.

Notice that the first production is right recursive..

S4 -> A '+' S4 | B '+' S4 | A | B
A  -> 'a' '*' '(' S4 ')' | 'a'
B  -> 'b' '*' '(' S4 ')' | 'b'


We can use EBNF to rewrite this grammar.

S4 -> [ A | B ] [ '+' S4 ]
A  -> 'a' [ '*' '(' S4 ')' ]
B  -> 'b' [ '*' '(' S4 ')' ]

-----------------------------------------------------------------------------


Language S5.

Notice that the first production is left recursive..

S5 -> S5 '+' A | S5 '+' B | A | B
A  -> 'a' '*' '(' S5 ')' | 'a'
B  -> 'b' '*' '(' S5 ')' | 'b'


We can use EBNF to rewrite this grammar.

S5 -> [ S5 '+' ] ( A | B )
A  -> 'a' [ '*' '(' S5 ')' ]
B  -> 'b' [ '*' '(' S5 ')' ]


We can use EBNF to rewrite this grammar again, without the recursion.

S5 -> ( A | B ) [ '+' ( A | B ) ]*
A  -> 'a' [ '*' '(' S5 ')' ]
B  -> 'b' [ '*' '(' S5 ')' ]


We can simplify the grammar a bit by using another non-terminal.

S5 -> C [ '+' C ]*
C  -> A | B
A  -> 'a' [ '*' '(' S5 ')' ]
B  -> 'b' [ '*' '(' S5 ')' ]

-----------------------------------------------------------------------------


Language S6.

Here is a silly language that could be used to force a recursive descent
parser to do an arbitrary amount of "look ahead".


S6 -> A [ '+' A ]* [ '+' B | '+'  C ]
A -> '#' '@' '=' '$' C                 // to distinguish between the A and B
B -> '#' '@' '=' '%' D                 // production you need to look at 5 tokens
C -> 'whatever'
D -> 'stuff'