Для примера, который вы предоставляете, я бы предпочел использовать синтаксический взгляд вперед, который в определенном смысле обязательно «положительный».
Производство для ExpressionStatement не является местом для решения проблемы, поскольку выбора нет.
void ExpressionStatement() : {} { Expression() ";" }
Проблема возникнет, когда есть выбор между утверждением выражения и блоком или между утверждением выражения и объявлением функции (или оба).
E.g. в Заявлении вы найдете
void Statement() :{} {
...
|
Block()
|
ExpressionStatement()
| ...
}
дает предупреждение, потому что оба варианта могут начинаться с символа "{". У вас есть два варианта. Один из них - игнорировать предупреждение. Первый выбор будет сделан, и все будет хорошо, пока Блок станет первым. Второй вариант - подавить предупреждение с помощью спецификации. как это:
void Statement() :{} {
...
|
LOOKAHEAD("{") Block()
|
ExpressionStatement()
| ...
}
синтаксический смотреть вперед, в некотором смысле положительный - «принять эту альтернативу, если X».
Если вы действительно хотите отрицательный --i.e., «Возьмите эту альтернативу, если не X» - смотрите вперед, она должна быть семантической.
В случае заявления вы могли бы написать
void Statement() :{} {
...
|
LOOKAHEAD({!(getToken(1)==LBRACE)}) ExpressionStatement()
|
Block()
}
Я убедился, что это последние две альтернативы, так как иначе вы должны были бы включать в себя более лексем в наборе лексем, которые блокируют ExpressionStatement(), например он не должен выбираться, если следующий токен является «если» или «в то время» или «для» и т. д.
В целом, вам лучше использовать синтаксический просмотр, когда сможете. Это обычно более прямолинейно и сложнее испортить.
Я поместил свое предложенное решение в синтаксический анализ ArrayLiteral в конце моего ответа на ваш второй вопрос, поэтому я считаю, что это не имеет значения. Но, может быть, кто-то придумает решение. – rici
@rici Да, я думаю, что моя непосредственная проблема с 'ArrayLiteral' будет решена, я переписал вопрос, чтобы сосредоточиться на отрицательном' LOOKAHEAD'. – lexicore