Как мне написать простой токенайзер Ragel (без возврата)? - PullRequest
4 голосов
/ 08 июня 2011

ОБНОВЛЕНИЕ 2

Оригинальный вопрос: Могу ли я избежать использования Ragel's |**|, если мне не нужно возвращаться назад?

Обновленный ответ: Да, вы можете написатьпростой токенизатор с ()*, если вам не нужно возвращаться назад.

ОБНОВЛЕНИЕ 1

Я понял, что вопрос о XML-токенизации был красной сельдью, потому что яя делаю это не только для XML.

END UPDATES

У меня есть сканер / токенизатор Ragel, который просто ищет элементы FooBarEntity в таких файлах, как:

<ABC >
  <XYZ >
    <FooBarEntity>
      <Example >Hello world</Example >
    </FooBarEntity>
  </XYZ >
  <XYZ >
    <FooBarEntity>
      <Example >sdrastvui</Example >
    </FooBarEntity>
  </XYZ >
</ABC >

Версия сканера:

%%{
  machine simple_scanner;
  action Emit {
    emit data[(ts+14)..(te-15)].pack('c*')
  }
  foo = '<FooBarEntity>' any+ :>> '</FooBarEntity>';
  main := |*
    foo => Emit;
    any;
  *|;
}%%

Версия без сканера (т.е. использует ()* вместо |**|)

%%{
  machine simple_tokenizer;
  action MyTs {
    my_ts = p
  }
  action MyTe {
    my_te = p
  }
  action Emit {
    emit data[my_ts...my_te].pack('c*')
    my_ts = nil
    my_te = nil    
  }
  foo = '<FooBarEntity>' any+ >MyTs :>> '</FooBarEntity>' >MyTe %Emit;
  main := ( foo | any+ )*;
}%%

Я понял это и написалтесты для этого в https://github.com/seamusabshere/ruby_ragel_examples

Вы можете увидеть код чтения / буферизации в https://github.com/seamusabshere/ruby_ragel_examples/blob/master/lib/simple_scanner.rl и https://github.com/seamusabshere/ruby_ragel_examples/blob/master/lib/simple_tokenizer.rl

Ответы [ 2 ]

3 голосов
/ 08 июня 2011

Вам не нужно использовать сканер для разбора XML. Я реализовал простой анализатор XML в Ragel без сканера. Здесь - это запись в блоге с некоторыми таймингами и дополнительной информацией.

Редактировать: Вы можете сделать это многими способами. Вы могли бы использовать сканер. Вы можете анализировать слова, и если вы видите STARTANIMAL, вы начинаете собирать слова, пока не увидите STOPANIMAL.

1 голос
/ 09 июня 2011

Перефразируя Occam: вам не нужен сканер, если он вам не нужен.Без сканера вы можете обрабатывать один символ за раз, возможно, считывая его из потока без буфера.

...