Защо моето правило yacc не може да намали тук?

Използвам YACC, за да направя моя проект за домашна работа на компилатора. Открих, че програмата ми не може да получи дървото на синтаксиса. Така че разпечатах всичко, за да видя какво се случва. Според моя резултат изглежда, че ClassDecl не се редуцира до ClassDeclList тук. Но не мога да разбера защо... може ли някой да ми помогне?

Примерният вход е:

   program ex11;
   class ab {
   }

Отпечата се като:

    programXXXX ex11ID
    semicon abID
    RBRACEnum 
    ClassBody ClassDecl ClassDecl1 Error!

Първите три реда са съобщения, които отпечатах от моя LEX файл, за да се уверя, че знаците са разпознати правилно.

Според информацията анализаторът успешно редуцира {} до ClassBody и class ab {} до ClassDecl. И тогава не се редуцира до ClassDeclList, дали е защото пиша ляво рекурсивна граматика тук?

Това е частта от моята база от правила на YACC за извода:

    Program: PROGRAMnum IDnum SEMInum ClassDeclList
{printf("program"); $$ = MakeTree(ProgramOp,$4, MakeLeaf(IDNode,$2)); printtree($$,0);};

   ClassDeclList: ClassDecl 
{printf("ClassDeclList1");$$ = MakeTree(ClassOp,NullExp(),$1); printf("ClassDeclListend");};
                  |ClassDecl ClassDeclList 
{printf("ClassDeclList2");$$ = MakeTree(ClassOp,$2,$1); printf("ClassDeclList");};

    ClassDecl: CLASSnum IDnum ClassBody
{printf("ClassDecl");$$=MakeTree(ClassDefOp,$3,MakeLeaf(IDNode,$2)); printf("ClassDecl1");};

person faz    schedule 13.03.2012    source източник
comment
Можете ли да покажете повече от кода, например частта, където отпечатвате Error!?   -  person Some programmer dude    schedule 13.03.2012
comment
Вашата граматика компилира ли се без конфликти shift-reduce или reduce-reduce или други съобщения за безполезни правила и други подобни?   -  person Kaz    schedule 13.03.2012


Отговори (1)


Опитахте ли

| ClassDeclList ClassDecl

вместо

| ClassDecl ClassDeclList

?

Спомням си, че това коригира много проблеми, когато използвах CUP.

person OmarOthman    schedule 13.03.2012
comment
да, проработи, но не мога да разбера защо? Мислех, че yacc ще бъде по-ефективен с помощта на лява рекурсивна граматика? - person faz; 13.03.2012
comment
Наистина няма да ви помогна тук, мина твърде много време, откакто изучавах курса за теоретични компилатори. Но това е свързано с механиката на LR парсерите. Преподавах курса по практически компилатори в университета, така че тази корекция е извън експертиза... не е действително разбиране :-D - person OmarOthman; 13.03.2012
comment
Това са глупости. (Първо @faz, вашата граматика е дясно рекурсивна, а не ляво.) Имам анализатор с десни рекурсивни правила по модела LIST : ATOM | ATOM LIST;. Те работят добре. Right recursive работи, защото моите действия правят нещо подобно LIST : ATOM { $$ = cons($1, nil); }; и LIST : ATOM LIST { $$ = cons($1, $2); }. Списъците, подобни на Lisp, са дясно-рекурсивни и затова граматиката следва. - person Kaz; 17.03.2012
comment
LALR(1) анализаторите могат да се справят добре с лява и дясна рекурсивна граматика. - person Kaz; 17.03.2012
comment
(Но трябва да спомена, че дълбочината на стека за анализиране е пропорционална на размера на конструкцията, когато имате правилно рекурсивно правило, тъй като първото намаление не се случва, докато не изместите цялата конструкция.) - person Kaz; 17.03.2012