更新2
原始问题:如果我不需要回溯,我可以避免使用Ragel的|**|
吗?
更新回答:是的,如果您不需要回溯,可以使用()*
编写一个简单的标记器。
更新1
我意识到询问XML标记化是一个红色的鲱鱼,因为我所做的并不是特定于XML。
END UPDATE
我有一个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
查看阅读/缓冲代码答案 0 :(得分:3)
您不必使用扫描程序来解析XML。我已经实现了simple XML parser in Ragel,没有扫描仪。 Here是一篇博客文章,其中包含一些时间和更多信息。
编辑:你可以做很多事。你可以使用扫描仪。您可以解析单词,如果看到STARTANIMAL
,则会开始收集单词,直至看到STOPANIMAL
。
答案 1 :(得分:1)
改写奥卡姆:除非你需要,否则你不需要扫描仪。 如果没有扫描仪,您可以一次处理一个符号,可能从流中读取它而没有缓冲区。