Хорошо, мои приключения с моим генератором парсеров продолжаются. На этот раз я получил классическую c грамматику, которая, как говорят, является грамматикой LALR:
start -> a a
a -> "A" a
a -> "B"
Когда я помещаю ее в свой генератор парсера, он дает мне такой результат:
LIST OF STATES:
-----------------------
<0: S' -> . start , $
start -> . a a , $
a -> . "A" a , "A" / "B"
a -> . "B" , "A" / "B"
{NTerm(start): 1, Term(A): 2, Term(B): 3, NTerm(a): 4}>(3104365621624877555)
--------------------
<1: S' -> start . , $
{}>(3969511602615904846)
--------------------
<2: a -> "A" . a , "A" / "B"
a -> . "A" a , "A" / "B"
a -> . "B" , "A" / "B"
{Term(A): 2, Term(B): 3, NTerm(a): 5}>(5490562805113673592)
--------------------
<3: a -> "B" . , "A" / "B"
{}>(-4845209343945471034)
--------------------
<4: start -> a . a , $
a -> . "A" a , $
a -> . "B" , $
{Term(A): 6, Term(B): 7, NTerm(a): 8}>(598157158659875896)
--------------------
<5: a -> "A" a . , "A" / "B"
{}>(436327415052220213)
--------------------
<6: a -> "A" . a , $
a -> . "A" a , $
a -> . "B" , $
{Term(A): 6, Term(B): 7, NTerm(a): 9}>(5490562805113673592)
--------------------
<7: a -> "B" . , $
{}>(-4845209343945471034)
--------------------
<8: start -> a a . , $
{}>(5795088700656730485)
--------------------
<9: a -> "A" a . , $
{}>(436327415052220213)
POSSIBLE STATES TO JOIN: (2, 6), (3, 7), (5, 9)
ATTEMPTING CONVERSION TO LALR GRAMMAR...FAILED
CONTINUING WITH CLR(1)...
Эти состояния соответствуют тому, что я могу прочитать в других источниках о компиляции грамматик LALR - этот шаг выглядит нормально, он производит правильные состояния, как если бы я делал это вручную. Генератор предлагает - опять же, это то, что говорят другие источники о преобразовании грамматики CLR (1) в LALR, - в котором говорится, что (2,6)
, (3,7)
, (5,9)
можно объединить, но он не может этого сделать. Когда я смотрю на созданные таблицы action и goto , я понимаю, почему:
Как вы можете см. состояния 2 и 6 не могут быть объединены, потому что есть несовместимые элементы s2 <> s6
, s3 <> s7
и так далее.
Но больше всего меня поражает то, что генератор закончил свою работу и создал работающую программу. Когда я запускаю эту программу на тестовых данных, она принимает данные! Итак, мой генератор создал правильные таблицы.
Означает ли это, что эта классическая c "LALR" грамматика является LALR только тогда, когда человек делает компиляцию вручную? Что мой генератор парсеров делает иначе?