2016-04-15 11 views
0

Ich habe einen Parser geschrieben, der treetop verwendet, der erfolgreich einen Syntaxbaum erzeugt, von dem ein Teil unten wiedergegeben wird.Wie verarbeite ich einen Treetop Parse Baum?

SyntaxNode offset=4043, " ": 
    SyntaxNode offset=4043, " " 
    SyntaxNode offset=4044, " " 
    SyntaxNode offset=4045, " " 
StringLiteral+StringLiteral1 offset=4046, "\"MS Sans Serif\"": 
    SyntaxNode offset=4046, "\"" 
    SyntaxNode offset=4047, "MS Sans Serif": 
    SyntaxNode+StringLiteral0 offset=4047, "M": 
     SyntaxNode offset=4047, "" 
     SyntaxNode offset=4047, "M" 
    SyntaxNode+StringLiteral0 offset=4048, "S": 
     SyntaxNode offset=4048, "" 
     SyntaxNode offset=4048, "S" 
    SyntaxNode+StringLiteral0 offset=4049, " ": 
     SyntaxNode offset=4049, "" 
     SyntaxNode offset=4049, " " 
    SyntaxNode+StringLiteral0 offset=4050, "S": 
     SyntaxNode offset=4050, "" 
     SyntaxNode offset=4050, "S" 
    SyntaxNode+StringLiteral0 offset=4051, "a": 
     SyntaxNode offset=4051, "" 
     SyntaxNode offset=4051, "a" 
    SyntaxNode+StringLiteral0 offset=4052, "n": 
     SyntaxNode offset=4052, "" 
     SyntaxNode offset=4052, "n" 
    SyntaxNode+StringLiteral0 offset=4053, "s": 
     SyntaxNode offset=4053, "" 
     SyntaxNode offset=4053, "s" 
    SyntaxNode+StringLiteral0 offset=4054, " ": 
     SyntaxNode offset=4054, "" 
     SyntaxNode offset=4054, " " 
    SyntaxNode+StringLiteral0 offset=4055, "S": 
     SyntaxNode offset=4055, "" 
     SyntaxNode offset=4055, "S" 
    SyntaxNode+StringLiteral0 offset=4056, "e": 
     SyntaxNode offset=4056, "" 
     SyntaxNode offset=4056, "e" 
    SyntaxNode+StringLiteral0 offset=4057, "r": 
     SyntaxNode offset=4057, "" 
     SyntaxNode offset=4057, "r" 
    SyntaxNode+StringLiteral0 offset=4058, "i": 
     SyntaxNode offset=4058, "" 
     SyntaxNode offset=4058, "i" 
    SyntaxNode+StringLiteral0 offset=4059, "f": 
     SyntaxNode offset=4059, "" 
     SyntaxNode offset=4059, "f" 
    SyntaxNode offset=4060, "\"" 

Nun, da ich diesen Baum habe, weiß ich nicht, wie es zu filtern, so dass ich nur bestimmten Knoten verarbeiten, die eine bestimmte Regel übereinstimmen.

Ich möchte String-Literale durch eine Kennung ersetzen, die auf die Zeichenfolge in einer Zeichenfolgedatei verweist.


cool_parser.treetop

rule string_literal 
    '"' (!'"' ./'""')* '"' 
end 

require 'treetop' 

# Load the grammar 
Treetop.load 'cool' 

class Parser 

    # Create the parser 
    @@parser = CoolParser.new 

    def self.parse(data) 

    # Pass the data over to the parser instance 
    tree = @@parser.parse(data) 

    if(tree.nil?) 
     raise Exception, "Parse error at offset: #{@@parser.index}" 
    end 

    return tree 
    end 

end 

tree = Parser.parse(File.open("myfile.txt").read) 

puts tree.inspect 
+0

dieses Beispiel Lesen eng: https://github.com/cjheath /treetop/blob/master/examples/lambda_calculus/arithmetic.treetop – cliffordheath

Antwort

1

Ich bin nicht sicher, was Sie unter "mit einer Kennung ersetzen"? Aber, hier ist ein Beispiel für die Rückgabe des Wertes der String-Knoten als Array.


cool_parser.treetop

rule start 
     (not_string_literal/string_literal)* 
     { 
     def value 
      elements.map {|e| e.value }.compact 
     end 
     } 
    end 

    rule string_literal 
     '"' (!'"' ./'""')* '"' 
     { 
     def value 
      text_value 
     end 
     } 
    end 

    rule not_string_literal 
     !string_literal . 
     { 
     def value 
     end 
     } 
    end 

dann auf den neu hinzugefügten value Methode des analysierten Objekts:

tree = Parser.parse(File.open("myfile.txt").read) 

puts tree.value.inspect 

# => ["\"strings\"", "\"sentences\""]