Я пытаюсь реализовать простой синтаксический анализатор языка, подобный Java, в sablecc, хотя постоянно сталкиваюсь с проблемами shift-reduce
/ reduce-reduce
при реализации операторов if
, while
и block
.
Например, я рассмотрел следующее:
stmts
= stmt*
;
stmt
= if_stmt
|block_stmt
|while_stmt
;
block_stmt
= { stmts }
|;
;
while_stmt
= while
(
predicate
)
{
stmts
}
|while
(
predicate
)
;
Эта грамматика, например, вызовет проблему, когда у вас есть что-то вида
while (true) ;
синтаксический анализатор не сможет узнать, нужно ли уменьшить только ;
(с block_stmt
) или полное while (true);
(с while_stmt
).
Я везде читал о причинахshift-reduce
/ reduce-reduce
проблемы, и я думаю, что понимаю их.Но одно дело - знать, что их вызывает, а другое - знать, как структурировать грамматики так, чтобы я их избегал.Я попытался реализовать грамматику совершенно по-разному, и тем не менее у меня возникли проблемы.
Полагаю, что вместо того, чтобы просто пытаться запустить конкретную проблему ss
/ rr
, должен быть видпарадигма, чтобы следовать такому, чтобы избежать такого рода проблем?Я считаю, что мой подход к проблеме должен быть совершенно неправильным: (
Есть ли какие-либо ресурсы о том, как создать грамматику с нуля, не попадая во все эти ловушки? Ресурсы по этому вопросу, как правило, либо очень просты (с указанием очевидной проблемы if then else
) или полностью помеченных грамматик, которые являются своего рода непроницаемыми.