Действия Bison в середине правила не работают

Это мой parser.y

stmt : type var { insertVar($2); cout<< "inserted"<<endl;} LCURL other RCURL {
             //other jobs
     }
     ;

и lex.l

"{"  { cout<<"after insertion"<<endl; return LCURL;} 

когда я запускаю их с файлом .c, вывод следующий:

 after insertion
 inserted

где мой ожидаемый результат:

 inserted
 after insertion

почему это происходит?


person Leolime    schedule 21.06.2018    source источник


Ответы (1)


Грамматики Yacc/bison используют один упреждающий токен (1 в LALR(1)), чтобы решить, какое действие синтаксического анализа предпринять. Таким образом, парсер и лексер не синхронизированы; действие лексера для упреждающей лексемы часто будет выполняться перед сокращением синтаксического анализатора, которое непосредственно предшествует ему.

Я написал «часто», а не «всегда», потому что Bison (но не yacc) иногда задерживает чтение упреждающей лексемы, если ему на самом деле не нужно ссылаться на нее в этот момент синтаксического анализа. Трудно предсказать, когда эта оптимизация может иметь место. Лучшее правило — не полагаться на последовательность выполнения действий между парсером и лексером.

person rici    schedule 21.06.2018