ОБНОВЛЕНИЕ 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