It might help to try writing the grammar so that you read some complete term, then optionally try extending it in some way. For example, you might try something like this:
S → Term
Term → CoreTerm OptMore
CoreTerm → a | (Term)
OptMore → ε | Term | + Term | * OptMore
For example, you'd derive a(a+a)*a as
S
⇒ Term
⇒ CoreTerm OptMore
⇒ a OptMore
⇒ a Term
⇒ a CoreTerm OptMore
⇒ a(CoreTerm OptMore) OptMore
⇒ a(a OptMore) OptMore
⇒ a(a + Term) OptMore
⇒ a(a + CoreTerm OptMore) OptMore
⇒ a(a + a OptMore) OptMore
⇒ a(a + a) OptMore
⇒ a(a + a)* OptMore
⇒ a(a + a)* Term
⇒ a(a + a)* CoreTerm OptMore
⇒ a(a + a)* a OptMore
⇒ a(a + a)* a
To see that this is an LL(1) grammar, here's the FIRST sets:
- FIRST(S) = {
- FIRST(Term) = { a, ( }
- FIRST(CoreTerm) = { a, ( }
- FIRST(OptMore) = { ε, a, (, +, * }
Here's the FOLLOW sets:
- FOLLOW(S) = {$}
- FOLLOW(Term) = {$, )}
- FOLLOW(CoreTerm) = {a, (, +, *, $}
- FOLLOW(OptMore) = {$, )}
So now we can fill in the parse table:
| a | ( | + | * | ) | $
---------+------------------+------------------+--------+-----------+-----+------
S | Term | Term | | | |
Term | CoreTerm OptMore | CoreTerm OptMore | | | |
CoreTerm | a | (Term) | | | |
OptMore | Term | Term | + Term | * OptMore | eps | eps
So this grammar is indeed LL(1).