gpt4 book ai didi

ruby parslet : parsing multiple lines

转载 作者:数据小太阳 更新时间:2023-10-29 07:12:51 24 4
gpt4 key购买 nike

我正在寻找一种匹配多行 Parslet 的方法。代码如下所示:

rule(:line) { (match('$').absent? >> any).repeat >> match('$') }
rule(:lines) { line.repeat }

但是,lines 将始终以无限循环结束,这是因为 match('$') 将无休止地重复以匹配字符串的结尾。

是否可以匹配可以为空的多行?

irb(main)> lines.parse($stdin.read)
This
is

a
multiline

string^D

应该匹配成功。我错过了什么吗?我还尝试了 (match('$').absent? >> any.maybe).repeat(1) >> match('$') 但这不匹配空行。

问候,
丹尼尔。

最佳答案

我通常为 end_of_line 定义一个规则。这是基于 http://kschiess.github.io/parslet/tricks.html 中的技巧用于匹配 end_of_file。

class MyParser < Parslet::Parser
rule(:cr) { str("\n") }
rule(:eol?) { any.absent? | cr }
rule(:line_body) { (eol?.absent? >> any).repeat(1) }
rule(:line) { cr | line_body >> eol? }
rule(:lines?) { line.repeat (0)}
root(:lines?)
end

puts MyParser.new.parse(""" this is a line
so is this

that was too
This ends""").inspect

很明显,如果你想用解析器做的事情比你用 String::split("\n") 做的更多,你将用一些有用的东西替换 line_body :)


我很快就回答了这个问题,但把它搞砸了。我只是想解释一下我犯的错误,并告诉您如何避免此类错误。

这是我的第一个答案。

rule(:eol)   { str('\n') | any.absent?  }
rule(:line) { (eol.absent? >> any).repeat >> eol }
rule(:lines) { line.as(:line).repeat }

我没有遵守我通常的规则:

  • 始终明确重复计数
  • 任何可以匹配零长度字符串的规则的名称都应该以“?”结尾

所以让我们应用这些...

rule(:eol?)   { str('\n') | any.absent?  } 
# as the second option consumes nothing

rule(:line?) { (eol.absent? >> any).repeat(0) >> eol? }
# repeat(0) can consume nothing

rule(:lines?) { line.as(:line?).repeat(0) }
# We have a problem! We have a rule that can consume nothing inside a `repeat`!

这里看看为什么我们会得到一个无限循环。当输入被消耗时,您最终得到的只是 end of file,它匹配 eol?,因此 line?(作为行主体可以为空)。在 lines' repeat 内,它保持匹配而不消耗任何东西并永远循环。

我们需要更改行规则,使其始终消耗一些东西。

rule(:cr)         { str('\n') }
rule(:eol?) { cr | any.absent? }
rule(:line_body) { (eol.absent? >> any).repeat(1) }
rule(:line) { cr | line_body >> eol? }
rule(:lines?) { line.as(:line).repeat(0) }

现在 line 必须匹配某些内容,cr(用于空行),或者至少一个字符后跟可选的 eol?。所有 repeat 都有消耗某些东西的 body 。我们现在是金色的。

关于 ruby parslet : parsing multiple lines,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17730185/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com