2016-04-15 2 views
0

Я написал парсер, используя treetop, который успешно создает дерево синтаксического разбора, часть которого воспроизводится ниже.Как обработать дерево разбора дерева?

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, "\"" 

Теперь у меня есть это дерево, я не знаю, как фильтровать его так, что я только обрабатывать конкретные узлы, которые соответствуют заданному правилу.

Я хочу заменить строковые литералы идентификатором, который ссылается на строку в строковом файле.


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

Прочитайте этот пример тесно: https://github.com/cjheath /treetop/blob/master/examples/lambda_calculus/arithmetic.treetop – cliffordheath

ответ

1

Я не уверен, что вы подразумеваете под "заменить идентификатором"? Но вот пример возврата значения строковых узлов в виде массива.


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 

Затем доступ вновь добавленный value метод разобранного объекта:

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

puts tree.value.inspect 

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