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
A -> '#' '@' '=' '$' C       // to distinguish between the A and B
B -> '#' '@' '=' '$' D       // productions you need to look at 5 tokens
C -> 'whatever'
D -> 'stuff'