1

我在 Treetop 中有一对有效的规则,我的完美主义者认为应该是一个且只有一个规则,或者至少是更漂亮的规则:

rule _
  crap
  /
  " "*
end

rule crap
  " "* "\\x0D\\x0A"* " "*
end

我正在解析一些不时以“\x0D\x0A”结尾的表达式。是的,不是“\r\n”而是“\x0D\x0A”。在某些时候,有些东西被双重逃脱了。很长的故事。

这条规则有效,但它很丑陋,而且让我很困扰。我试过这个:

rule _
  " "* "\\x0D\\x0A"* " "*
  /
  " "*
end

这导致

SyntaxError: (eval):1276:in `load_from_string': compile error
(eval):1161: class/module name must be CONSTANT
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:42:in `load_from_string'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:35:in `load'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:32:in `open'
    from /.../gems/treetop-1.4.9/lib/treetop/compiler/grammar_compiler.rb:32:in `load'

理想情况下,我想实际写一些类似的东西:

rule _
  (" " | "\\x0D\\x0A")*
end

但这不起作用,当我们这样做时,我还发现每个规则不能只有一个 *:

rule _
  " "*
  /
  "\n"*
end

这将匹配“”,但从不匹配\n。

4

2 回答 2

1

我看到您正在使用三个不同的OR字符:/,|\(其中只有第一个表示OR)。

这工作正常:

grammar Language

  rule crap
    (" " / "\\x0D\\x0A")* {
      def value
        text_value    
      end
    }
  end

end
#!/usr/bin/env ruby

require 'rubygems'
require 'treetop'
require 'polyglot'
require 'language'

parser = LanguageParser.new
value = parser.parse(' \\x0D\\x0A   \\x0D\\x0A   ').value
print '>' + value + '<'

印刷:

> \x0D\x0A   \x0D\x0A   <
于 2011-07-13T12:55:31.923 回答
1

你说“我还发现每条规则不能只有一个 *”(你的意思是:你可以有),“那将匹配”“,但永远不会 \n”。

当然; 该规则在匹配零个空格字符时成功。您可以只使用 + 代替:

rule _
  " "+
  /
  "\n"*
end

如果要匹配任意数量的空格或换行符,也可以将空格字符括起来:

rule _
  (" " / "\n")*
end

您的错误“类/模块名称必须是常量”是因为规则名称用作模块名称的前缀以包含附加到您的规则的任何方法。模块名称不能以下划线开头,因此您不能在名称以下划线开头的规则中使用方法。

于 2015-05-06T02:39:24.223 回答