Правило expr
является косвенной левой рекурсивной, поскольку оно содержит atomicExpr
, которое также использует expr
в левой части.Однако atomicExpr
- довольно бесполезное правило.Определив:
expr : relationName
| selection
| projection
| renaming
| union
| difference
| product
| naturalJoin;
selection : 'select' (condition) expr;
, вы получите точно такой же синтаксис, но без этой рекурсии.
condition
немного сложнее, поскольку левая рекурсия включает 3 правила (condition
использует conjunction
слева, который использует comparison
, который снова использует condition
).Вы можете решить это, объединив отдельные правила в одно:
condition:
comparison
| condition LOGICAL_AND condition
| condition LOGICAL_OR condition
;
comparison: operand (op operand)?
LOGICAL_OR: '||';
LOGICAL_AND: '&&';
Приоритет обеспечивается порядком альтернатив.Более поздние альты имеют меньший приоритет.А так как это правило рекурсивно и с правой стороны, вам здесь не нужны циклы.