使用treetop解析ruby中的tcl数组
我在(我认为是)tcl 数组中有一堆数据。基本上它的形式是{a {bc} d {ef} g}
。它只嵌套一层,但并不总是嵌套,也就是说,a
可能只是a
,也可能是{aa bb} 或可能
{}
,但绝不会 {aa {bb cc}}
。我想提取这个数组,以便我可以在 ruby 中使用它。
我的第一个想法是,“没问题,我会写一些语法来解析它。”我安装了treetop gem,并编写了一个解析器,它看起来工作得很好。当我尝试从解析树中提取数组时,我开始遇到问题。我想更好地了解问题的原因以及我做错了什么。
这是到目前为止我的解析器代码: (tcl_array.treetop)
grammar TCLArray
rule array
"{" [\s]* "}" {
def content
[]
end
}
/
"{" [\s]* array_element_list [\s]* "}" {
def content
array_element_list.content
end
}
end
rule array_element_list
array_element {
def content
[array_element.content]
end
}
/
array_element [\s]+ array_element_list {
def content
[array_element.content] + array_element_list.content
end
}
end
rule array_element
[^{}\s]+ {
def content
return text_value
end
}
/
array {
def content
array.content
end
}
end
end
调用 p.parse("{a}").content
产生 tcl_array.rb:99:in 'content': undefined local变量或方法 'array_element'
array_element_list (array_element) 中的第一项表示 array_element 是一个未定义的局部变量,但访问器方法应该根据树顶文档自动定义。
早些时候,我尝试了一种基于规则较少但稍微复杂的语法的解决方案:
grammar TCLArray
rule array
"{" ([\s]* array_element ([\s]+ array_element)* )? [\s]* "}"
end
rule array_element
[^{}\s]+ / array
end
end
但是使用这种语法时,我遇到了问题,解析器似乎为数组规则创建了几个不同的表达式,即使它没有使用任何替代方案表达式 (/)。结果是我无法弄清楚如何访问数组规则的各个位以将它们作为 ruby 数组返回。
I have a bunch of data in (what i think is) a tcl array. Basically it's in the form of {a {b c} d {e f} g}
. It's only nested one deep, but isn't always nested, that is to say, a
may just be a
or it may be {aa bb}
or possibly {}
, but never {aa {bb cc}}
. I want to extract this array so I can use it in ruby.
My first thought was, "No problem, I'll write a little grammar to parse this." I installed the treetop gem, and wrote up a parser, which seemed to work just fine. I started having problems when I tried to extract an array from the parsed tree. I would like to better understand the cause of the problems and what I am doing wrong.
Here is my parser code so far: (tcl_array.treetop)
grammar TCLArray
rule array
"{" [\s]* "}" {
def content
[]
end
}
/
"{" [\s]* array_element_list [\s]* "}" {
def content
array_element_list.content
end
}
end
rule array_element_list
array_element {
def content
[array_element.content]
end
}
/
array_element [\s]+ array_element_list {
def content
[array_element.content] + array_element_list.content
end
}
end
rule array_element
[^{}\s]+ {
def content
return text_value
end
}
/
array {
def content
array.content
end
}
end
end
Invoking p.parse("{a}").content
yields tcl_array.rb:99:in 'content': undefined local variable or method 'array_element'
The first term in array_element_list (array_element) says that array_element is an undefined local variable, but accessor methods are supposed to be automatically defined according to the treetop documentation.
Earlier, I tried a solution that was based off of a grammar with fewer but slightly more complicated rules:
grammar TCLArray
rule array
"{" ([\s]* array_element ([\s]+ array_element)* )? [\s]* "}"
end
rule array_element
[^{}\s]+ / array
end
end
But with this grammar I had issues where the parser seemed to be creating several different expressions for the array rule even though it did not use any alternative expressions (/). The result was that I couldn't figure out how to access the various bits of the array rule to return them as a ruby array.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这种情况下,解析器生成器可能有点过分了。 是一个简单的手动递归下降解析器,基于 James Edward Gray II 的 JSON 解析器:
这 测试套件:
Maybe a parser generator is overkill in this case. Here's a simple hand-rolled recursive-descent parser based on this JSON parser by James Edward Gray II:
Here's a testsuite:
注意到这一点仅供参考,但我刚刚发布了一个用于解析简单 TCL 的 gem。
https://github.com/julik/tickly
Noting this for reference, but I've just released a gem for parsing simple TCL.
https://github.com/julik/tickly