У меня есть куча данных в (что я думаю, это) массив tcl. В основном это в форме {a {b c} d {e f} g}
. Он вложен только в одну глубину, но не всегда вложен, то есть a
может быть просто a
или {aa bb}
или {}
, но никогда {aa {bb cc}}
. Я хочу извлечь этот массив, чтобы использовать его в ruby.
Моей первой мыслью было: «Нет проблем, я напишу небольшую грамматику, чтобы разобрать это». Я установил древовидный гем и написал парсер, который, казалось, работал очень хорошо. У меня начались проблемы, когда я пытался извлечь массив из проанализированного дерева. Я хотел бы лучше понять причину проблем и что я делаю не так.
Вот мой код парсера: (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 variable or method '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.