Versuchen Sie Treetop. Es ist ein Ruby-ähnliches DSL, um Grammatiken zu beschreiben. Das Analysieren der Zeichenfolge, die Sie angegeben haben, sollte ziemlich einfach sein, und mit einem echten Parser können Sie Ihre Grammatik später leicht erweitern.
Ein Beispiel Grammatik für die Art der Zeichenfolge, die Sie analysieren wollen (speichern als sentences.treetop
):
grammar Sentences
rule sentence
# A sentence is a combination of one or more expressions.
expression* <Sentence>
end
rule expression
# An expression is either a literal or a parenthesised expression.
parenthesised/literal
end
rule parenthesised
# A parenthesised expression contains one or more sentences.
"(" (multiple/sentence) ")" <Parenthesised>
end
rule multiple
# Multiple sentences are delimited by a pipe.
sentence "|" (multiple/sentence) <Multiple>
end
rule literal
# A literal string contains of word characters (a-z) and/or spaces.
# Expand the character class to allow other characters too.
[a-zA-Z ]+ <Literal>
end
end
Die Grammatik eine begleitende Datei oben benötigt, die die Klassen definiert, die uns die Knotenwerte erlauben den Zugriff auf (speichern unter sentence_nodes.rb
).
class Sentence < Treetop::Runtime::SyntaxNode
def combine(a, b)
return b if a.empty?
a.inject([]) do |values, val_a|
values + b.collect { |val_b| val_a + val_b }
end
end
def values
elements.inject([]) do |values, element|
combine(values, element.values)
end
end
end
class Parenthesised < Treetop::Runtime::SyntaxNode
def values
elements[1].values
end
end
class Multiple < Treetop::Runtime::SyntaxNode
def values
elements[0].values + elements[2].values
end
end
class Literal < Treetop::Runtime::SyntaxNode
def values
[text_value]
end
end
Das folgende Beispielprogramm zeigt, dass es sehr einfach ist, den von Ihnen angegebenen Beispielsatz zu analysieren.
require "rubygems"
require "treetop"
require "sentence_nodes"
str = 'maybe (this is|that was) some' +
' ((nice|ugly) (day|night)|(strange (weather|time)))'
Treetop.load "sentences"
if sentence = SentencesParser.new.parse(str)
puts sentence.values
else
puts "Parse error"
end
Die Ausgabe dieses Programms ist:
maybe this is some nice day
maybe this is some nice night
maybe this is some ugly day
maybe this is some ugly night
maybe this is some strange weather
maybe this is some strange time
maybe that was some nice day
maybe that was some nice night
maybe that was some ugly day
maybe that was some ugly night
maybe that was some strange weather
maybe that was some strange time
Sie können auch den Syntaxbaum zugreifen:
p sentence
The output is here.
Da haben Sie es: eine skalierbare Parsing-Lösung, die in etwa 50 Zeilen Code ziemlich nahe an das kommen soll, was Sie tun möchten. Hilft das?
Danke, ich habe die Beispiele im Netz gelesen, aber ich verstehe nicht, wie ich verschachtelte Klammern lesen kann ... – astropanic
Danke Man! Du bist mein Held :) – astropanic
http://www.bestechvideos.com/2008/07/18/rubyconf-2007-treetop-syntactic-analysis-with-ruby, schönes Video – astropanic