- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我正在尝试使用 Parslet 解析简单的缩进敏感语法Ruby 中的库。
以下是我尝试解析的语法示例:
level0child0
level0child1
level1child0
level1child1
level2child0
level1child2
生成的树看起来像这样:
[
{
:identifier => "level0child0",
:children => []
},
{
:identifier => "level0child1",
:children => [
{
:identifier => "level1child0",
:children => []
},
{
:identifier => "level1child1",
:children => [
{
:identifier => "level2child0",
:children => []
}
]
},
{
:identifier => "level1child2",
:children => []
},
]
}
]
我现在拥有的解析器可以解析嵌套级别 0 和 1 节点,但不能解析过去:
require 'parslet'
class IndentationSensitiveParser < Parslet::Parser
rule(:indent) { str(' ') }
rule(:newline) { str("\n") }
rule(:identifier) { match['A-Za-z0-9'].repeat.as(:identifier) }
rule(:node) { identifier >> newline >> (indent >> identifier >> newline.maybe).repeat.as(:children) }
rule(:document) { node.repeat }
root :document
end
require 'ap'
require 'pp'
begin
input = DATA.read
puts '', '----- input ----------------------------------------------------------------------', ''
ap input
tree = IndentationSensitiveParser.new.parse(input)
puts '', '----- tree -----------------------------------------------------------------------', ''
ap tree
rescue IndentationSensitiveParser::ParseFailed => failure
puts '', '----- error ----------------------------------------------------------------------', ''
puts failure.cause.ascii_tree
end
__END__
user
name
age
recipe
name
foo
bar
很明显,我需要一个动态计数器,它期望 3 个缩进节点与嵌套级别 3 上的标识符匹配。
如何使用 Parslet 以这种方式实现缩进敏感的语法解析器?可能吗?
最佳答案
有几种方法。
通过将每一行识别为缩进和标识符的集合来解析文档,然后应用转换以根据缩进数重建层次结构。
使用捕获来存储当前缩进并期望下一个节点包含该缩进加上更多以作为子节点匹配(我没有深入研究这种方法,因为我想到了下一个)
规则只是方法。所以你可以将'node'定义为一个方法,这意味着你可以传递参数! (如下)
这让您可以根据 node(depth+1)
定义 node(depth)
。然而,这种方法的问题是 node
方法不匹配字符串,它生成一个解析器。所以递归调用永远不会完成。
这就是 dynamic
存在的原因。它返回一个解析器,该解析器直到它尝试匹配它时才被解析,让您现在可以毫无问题地进行递归。
请看下面的代码:
require 'parslet'
class IndentationSensitiveParser < Parslet::Parser
def indent(depth)
str(' '*depth)
end
rule(:newline) { str("\n") }
rule(:identifier) { match['A-Za-z0-9'].repeat(1).as(:identifier) }
def node(depth)
indent(depth) >>
identifier >>
newline.maybe >>
(dynamic{|s,c| node(depth+1).repeat(0)}).as(:children)
end
rule(:document) { node(0).repeat }
root :document
end
这是我最喜欢的解决方案。
关于ruby - 在 Ruby 中使用 Parslet 的缩进敏感解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16504958/
我这里有一些(遗留)代码,似乎在LD_LIBRARY_PATH上调用setenv(其值在编译时未知,实际上它将从命令中获取)行),现在我必须将其移植到 Windows。我怀疑 setenv 只是出于历
我在 SSIS 包上有一个敏感字符串参数,用于存储远程服务器的密码。 但是,当字符串值包含花括号时,作业代理会在配置该步骤的包参数时抛出错误: Microsoft SQL Server Managem
我们都非常了解 strictfp 的工作原理。 像这样: package com.hk.basicjava.tests.strictfp; import java.util.*; public cla
我正在对我的博客进行简单搜索。我使用亚美尼亚语,当我搜索时,这些字母总是很敏感。这是我的代码的一部分。提前谢谢你。 search_query = get.get('search') query_lis
我正在对我的博客进行简单搜索。我使用亚美尼亚语,当我搜索时,这些字母总是很敏感。这是我的代码的一部分。提前谢谢你。 search_query = get.get('search') query_lis
想象一下这个非常基本的可拖放设置: #dropArea 是可放置的。 #itemBox > .item 是可拖动对象。 由于某种原因,droppable
我有这样的网址: http://quickstart.local/public/category1/product2 并且在 url (category1/product2) 数字是 id ,从数据库
我是一名优秀的程序员,十分优秀!