gpt4 book ai didi

ruby - Parslet 替代品不解析整个字符串

转载 作者:数据小太阳 更新时间:2023-10-29 08:28:08 26 4
gpt4 key购买 nike

我有以下规范

  it "parses a document with only an expression" do
puts parser.document.should parse("[b]Hello World[/b]")
end
it "parses a document with only text" do
puts parser.document.should parse(" Hello World")
end
it "parses a document with both an expression and text" do
puts parser.document.should parse("[b]Hello World[/b] Yes hello")
end

对于下面的Parslet解析器

class Parser < Parslet::Parser

rule(:open_tag) do
parslet = str('[')
parslet = parslet >> (str(']').absent? >> match("[a-zA-Z]")).repeat(1).as(:open_tag_name)
parslet = parslet >> str(']')
parslet
end

rule(:close_tag) do
parslet = str('[/')
parslet = parslet >> (str(']').absent? >> match("[a-zA-Z]")).repeat(1).as(:close_tag_name)
parslet = parslet >> str(']')
parslet
end

rule(:text) { any.repeat(1).as(:text) }

rule(:expression) do
# [b]Hello World[/b]
# open tag, any text up until closing tag, closing tag
open_tag.present?
close_tag.present?
parslet = open_tag >> match("[a-zA-Z\s?]").repeat(1).as(:enclosed_text) >> close_tag
parslet
end

rule(:document) do
expression | text
end

前两个测试顺利通过,通过将它们放入到命令行,我可以看到原子的类型是正确的。但是,当我尝试解析包含表达式和纯文本的文档时,它无法解析纯文本,并出现以下错误

Parslet::UnconsumedInput: Don't know what to do with " Yes hello" at line 1 char 19.

我想我遗漏了一些有关定义 :document 规则的内容。我想要的是会消耗任意数量的序列表达式和纯文本的东西,虽然我的规则会消耗每个原子个体,但在同一个字符串中同时使用它们会导致失败。

最佳答案

你要找的是这样的东西......

require 'parslet'

class ExampleParser < Parslet::Parser
rule(:open_tag) do
str('[') >>
match["a-zA-Z"].repeat(1).as(:open_tag_name) >>
str(']')
end

open_tag 规则不需要排除 ']' 字符,因为匹配只允许字母。

  rule(:close_tag) do
str('[/') >>
match["a-zA-Z"].repeat(1).as(:close_tag_name) >>
str(']')
end

这里也一样

  rule(:text) do 
(open_tag.absent? >>
close_tag.absent? >>
any).repeat(1).as(:text)
end

如果您在此处排除打开和关闭标记..您知道您只处理文本。注意:我喜欢这种在排除不需要的东西后使用“any”的技术,但如果您以后要重构,请记住这一点,因为您的排除列表可能需要增长。注 2:您可以进一步简化,如下所示。

  rule(:text) do 
(str('[').absent? >> any).repeat(1).as(:text)
end

.. 如果您根本不想在文本中使用任何方括号。

  rule(:expression) do
# [b]Hello World[/b]
open_tag >> text.as(:enclosed_text) >> close_tag
end

这变得更加简单,因为文本不能包含 close_tag

  rule(:document) do
(expression | text).repeat
end

我已经添加了你错过的重复(正如马特指出的那样)

end

require 'rspec'
require 'parslet/rig/rspec'

describe 'example' do
let(:parser) { ExampleParser.new }
context 'document' do
it "parses a document with only an expression" do
parser.document.should parse("[b]Hello World[/b]")
end
it "parses a document with only text" do
parser.document.should parse(" Hello World")
end
it "parses a document with both an expression and text" do
parser.document.should parse("[b]Hello World[/b] Yes hello")
end
end
end


RSpec::Core::Runner.run([])

希望这能给您一些使用 Parslet 的技巧。 :)

关于ruby - Parslet 替代品不解析整个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13806220/

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