На самом деле нам нужно знать больше о Z
.Я предполагаю, что L (Z
) (то есть язык, сгенерированный Z
) не содержит пустой последовательности и не содержит последовательностей, начинающихся с ID
, bha
или bah
.Я также предполагаю, что первый токен после main
не может быть ID
, bha
или bah
.
В этой ситуации я почти наверняка использовал бы lookahead
void main() : {}
{
AsBs()
}
void AsBs() : {}
{
LOOKAHEAD( A() )
A() AsBs() ;
|
(B()*)
|
{/*nothing*/}
}
с A
, B
и C
, как в оригинальном сообщении.
Однако, постер хочет решения без использования опережающего взгляда.Вот один.Я сделал те же предположения, что и выше.
void main() : {}
{
AsBs()
}
void AsBs() : {}
{
C1() <ID> AsBs()
|
<ID> // This ID might be the start of either A or B
( <ID> AsBs() // That ID started an A
| Z() (B())* ) // That ID started a B.
|
{/*nothing*/}
}
void B() : {}
{
<ID> Z()
}
void C1() : {}
{
<bah>
| <bha>
}
Здесь нет необходимости A
или C
.