Predictive parser you selected (LL(k)) means you will have to solve left-recursion problems. Algorithm for solving direct and indirect recursions is clearly described on wikipedia:
http://en.wikipedia.org/wiki/Left_recursion
Some info can be found in posts here on StackOverflow:
http://stackoverflow.com/questions/2652060/removing-left-recursionhttps://stackoverflow.com/questions/2652060/removing-left-recursion http://stackoverflow.com/questions/2999755/removing-left-recursion-in-antlrhttps://stackoverflow.com/questions/2999755/removing-left-recursion-in-antlr http://stackoverflow.com/questions/4994036/left-recursion-eliminationhttps://stackoverflow.com/questions/4994036/left-recursion-elimination
In human language (non-scientific :) "left-recursion problem" means you can't endlessly go into recursion with non-terminal (A -> Ab) again and again. At some time you HAVE TO feed parser algorithm with a terminal to breake a loop.
In BNF this could look like:
Recursion Problem:
NT: NT T
NT: T
One solution:
NT: T NT2
NT2: T NT2
NT2:
For your grammar this could look like:
DataType:
PrimitiveDataType ArrayDimensions
| ComplexDataType ArrayDimensions
ArrayDimensions:
[] ArrayDimensions
|
If your parser generator doesn't allow empty productions and/or if you want to process array types separately, try something like this:
DataType:
DataTypeName
| ArrayDataType
ArrayDataType:
DataTypeName ArrayDimensions
DataTypeName:
PrimitiveDataType
| ComplexDataType
ArrayDimensions:
[]
| [] ArrayDimensions