4

更新 2

|**|原始问题:如果我不需要回溯,我可以避免使用 Ragel's吗?

()*更新的答案:是的,如果您不需要回溯,您可以编写一个简单的标记器。

更新 1

我意识到询问 XML 标记化是一个红鲱鱼,因为我所做的并不是特定于 XML。

结束更新

我有一个 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.rlhttps://github.com/seamusabshere/ruby_ragel_examples/blob/master/lib/simple_tokenizer看到读取/缓冲代码.rl

4

2 回答 2

3

您不必使用扫描仪来解析 XML。我在Ragel中实现了一个简单的 XML 解析器,没有扫描仪。是一篇博客文章,其中包含一些时间安排和更多信息。

编辑:您可以通过多种方式进行操作。你可以使用扫描仪。你可以解析单词,如果你看到STARTANIMAL你开始收集单词,直到你看到STOPANIMAL

于 2011-06-08T17:32:30.213 回答
1

改写奥卡姆:除非你需要它,否则你不需要扫描仪。如果没有扫描仪,您一次可以处理一个符号,可能从没有缓冲区的流中读取它。

于 2011-06-09T05:43:15.000 回答