Einrückungssensitiver Parser mit Parslet in Ruby?
Ich versuche, eine einfache einrückungssensitive Syntax mit der zu analysierenParslet Bibliothek in Ruby.
Das Folgende ist ein Beispiel für die Syntax, die ich zu analysieren versuche:
level0child0
level0child1
level1child0
level1child1
level2child0
level1child2
Der resultierende Baum würde so aussehen:
[
{
:identifier => "level0child0",
:children => []
},
{
:identifier => "level0child1",
:children => [
{
:identifier => "level1child0",
:children => []
},
{
:identifier => "level1child1",
:children => [
{
:identifier => "level2child0",
:children => []
}
]
},
{
:identifier => "level1child2",
:children => []
},
]
}
]
Der Parser, den ich jetzt habe, kann Knoten der Verschachtelungsebenen 0 und 1 analysieren, kann aber nicht darüber hinaus analysieren:
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
Es ist klar, dass ich einen dynamischen Zähler benötige, der erwartet, dass 3 Einrückungsknoten mit einem Bezeichner auf der Verschachtelungsebene 3 übereinstimmen.
Wie kann ich mit Parslet auf diese Weise einen einrückungssensitiven Syntaxparser implementieren? Ist es möglich?