Как получить команды yacc / bison и / или lex / flex для возобновления сканирования после замены токена? - PullRequest
2 голосов
/ 22 апреля 2010

Есть ли способ заставить бизонов и / или flex перезапустить сканирование после того, как я заменил какой-нибудь токен чем-то другим?

Мой конкретный пример будет с заменой конкретного слова / строки. Если я хочу, чтобы слово hello было заменено на echo hello, как я могу заставить flex или bison заменить hello, а затем снова начать синтаксический анализ (подобрать 2 слова вместо одного). Так было бы как:

  • Получить токен WORD (тип строки)
  • Если hello, заменить значение токена на echo hello
  • Перезапустить анализ всего ввода (который теперь echo hello)
  • Получить токен WORD (echo)
  • Получить токен WORD (hello)

Я видел очень заманчивые функции, такие как yyrestart(), но я не совсем понимаю, что на самом деле выполняет эта функция. Спасибо за любую помощь, спасибо!

Обновление 4/23/2010

Одним из видов решения для взлома и слеша, которое я в итоге использовал, является то, что для каждого проходящего word я проверяю массив "псевдонимов". Если word имеет псевдоним, я заменяю значение слова (используя, например, strcopy($1,aliasval)) и отмечаю флаг aliasfound.

После того, как вся строка ввода анализируется один раз, если флаг aliasfound установлен в true, я использую yy_scan_string(), чтобы переключить состояние буфера на вход с расширенными псевдонимами, и вызываю YYACCEPT.

Итак, он выпрыгивает в основную функцию, и я снова вызываю yyparse() с буфером, все еще указывающим на мою строку. Это продолжается, пока псевдонимы не найдены. Когда все мои грамматические действия завершены, я звоню yyrestart(stdin), чтобы вернуться в «нормальный» режим.

Если кто-нибудь знает, как я могу эффективно расширить свои слова с их значениями псевдонимов, вставить в stdin (или каким-либо другим способом) и, в основном, развернуть все псевдонимы (даже вложенные), как это происходит, это было бы здорово. Я играл с yypush_buffer_state() и yypop_buffer_state(), наряду с yy_switch_to_buffer(), но я не мог получить "встроенную" замену с продолжением синтаксического анализа ...

Ответы [ 2 ]

1 голос
/ 25 апреля 2010

Мне кажется, что место, чтобы исправить это лексер.Я бы предложил использовать flex, который поддерживает конечный автомат (в документации по flex называется " Start Condition ").Вы изменяете состояния, используя BEGIN, и состояния должны быть определены в разделе определений.

Так, например, у вас может быть правило типа

<INITIAL>hello    BEGIN(in_echo); yyless(0); return (WORD_ECHO);
<in_echo>hello    BEGIN(0); return (WORD_HELLO);

yyless() усеченияyytext до заданного значения, поэтому все входные данные возвращаются в поток.

Я сам не пробовал это, но я думаю, что это структура решения, которое вы хотите.

0 голосов
/ 07 января 2012

Добавление «ответа» на основе того, что я в итоге сделал. Хотите пометить этот вопрос как ответивший.

Обновление 4/23/2010

Один вид решения для взлома и слеша, который я в конечном итоге использовал, заключается в том, что для каждого проходящего слова я проверяю массив "псевдонимов". Если слово имеет псевдоним, я заменяю значение слова (используя, например, strcopy ($ 1, aliasval)) и отмечаю флаг псевдонима.

После того, как вся строка ввода анализируется один раз, и если флаг aliasfound имеет значение true, я использую yy_scan_string (), чтобы переключить состояние буфера на вход с расширенными псевдонимами и вызвать YYACCEPT.

Итак, он выпрыгивает в основную функцию, и я снова вызываю yyparse () с буфером, все еще указывающим на мою строку. Это продолжается, пока псевдонимы не найдены. Когда все мои грамматические действия завершены, я вызываю yyrestart (stdin), чтобы вернуться в «нормальный» режим.

Если кто-нибудь знает, как я могу эффективно расширить свои слова с их значениями псевдонимов, внедрить их в стандартный ввод (или какой-либо другой метод) и в основном развернуть все псевдонимы (даже вложенные), как я, это было бы здорово. Я играл с yypush_buffer_state () и yypop_buffer_state (), вместе с yy_switch_to_buffer (), но я не смог получить «встроенную» замену с продолжением работы синтаксического анализа ...

...