1

我想创建一个规则,要求非数字、非字母字符连续重复三次。规则看起来像这样:

# Note, this code does not do what I want! 

grammar ThreeCharacters

  rule threeConsecutiveCharacters
    (![a-zA-Z0-9] .) 3..3
  end

end

有没有办法要求它检测到的第一个字符重复三次?

之前有一个关于检测缩进数量的类似问题:PEG for Python style indentation

解决方案是首先初始化缩进堆栈:

&{|s| @indents = [-1] }

然后保存当前行的缩进:

&{|s|
  level = s[0].indentation.text_value.length
  @indents << level
  true
}

每当新行开始时,它都会像这样查看缩进:

!{|s|
  # Peek at the following indentation:
  save = index; i = _nt_indentation; index = save
  # We're closing if the indentation is less or the same as our enclosing block's:
  closing = i.text_value.length <= @indents.last
}

如果缩进更大,它会将新的缩进级别添加到堆栈中。

我可以为我的问题创建类似的东西,但这似乎是一种非常乏味的解决方法。还有其他方法可以创建我的规则吗?

4

1 回答 1

1

是的,您可以在 Treetop 中这样做。由于 Packrat 解析的工作方式,这种事情通常用 PEG 是不可能的;它是贪婪的,但您需要使用解析早期的语义信息来限制它的贪婪。只有在 Treetop 中添加了语义谓词 ( &{...}} 才使其成为可能。所以是的,这很乏味。您可以考虑使用 Rattler,因为除了 Treetop 中可用的功能之外,它还有很多功能。我不建议(作为 Treetop 的维护者,但不是 Rattler 的用户)但它的功能集给我留下了深刻的印象,我认为它会更好地处理这种情况。

如果您继续使用 Treetop,请记住每个语义谓词都应返回一个布尔值,指示成功或失败。这在上面的初始化中并不明确@indents

于 2019-07-29T10:17:00.350 回答