Simple Treetop based parser for converting a subset of data output by the php var_dump() function to ruby.
Based on the code from http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html
Simple Treetop based parser for converting a subset of data output by the php var_dump() function to ruby.
Based on the code from http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html
grammar PhpDump | |
rule value | |
(php_array / php_object / php_string / php_number / php_null) | |
end | |
rule php_array | |
"array(" [0-9]+ ")" os "{" os key_value_array_list "}" <PhpArray> | |
end | |
rule key_value_array_list | |
(key_value_pair os)* <PhpArrayList> | |
end | |
rule php_object | |
"object(" [a-zA-Z_0-9]+ ")" os "#" [0-9]+ os "(" integer ")" os "{" os | |
key_value_object_list | |
"}" <PhpObject> | |
end | |
rule key_value_object_list | |
(key_value_pair os)* <PhpObjectList> | |
end | |
rule key_value_pair | |
"[" keyvalue "]" os "=>" os value <PhpKeyValuePair> | |
end | |
rule keyvalue | |
string / integer | |
end | |
rule php_string | |
"string(" [0-9]+ ")" os string <PhpValueString> | |
end | |
rule php_number | |
php_int / php_float / php_float_nan | |
end | |
rule php_null | |
"NULL" <NullValue> | |
end | |
rule php_int | |
"int(" integer ")" <PhpValue> | |
end | |
rule php_float | |
"float(" float ")" <PhpValue> | |
end | |
rule php_float_nan | |
"float(NAN)" <PhpNaN> | |
end | |
rule integer | |
('+' / '-')? [0-9]+ <IntegerLiteral> | |
end | |
rule float | |
('+' / '-')? [0-9]+ (('.' [0-9]+) / ('e' [0-9]+))? <FloatLiteral> | |
end | |
rule string | |
'"' ([^"\\] / "\\" . )* '"' <StringLiteral> | |
end | |
rule ws | |
[\s]+ | |
end | |
rule os | |
[\s]* | |
end | |
end |
module PhpDump | |
class PhpArray < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements.select { |e| e.is_a?(PhpArrayList) }.inject([]) { |arr, x| arr + x.to_data } | |
end | |
end | |
class PhpArrayList < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements.map{|a|a.elements[0]}.select { |e| e.is_a?(PhpKeyValuePair) }.map { |x| x.to_data.values[0] } | |
end | |
end | |
class PhpObject < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements.select { |e| e.is_a?(PhpObjectList) }.inject({}) { |o, x| o.merge(x.to_data) } | |
end | |
end | |
class PhpObjectList < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements.map{|a|a.elements[0]}.select { |e| e.is_a?(PhpKeyValuePair) }.inject({}) { |o, x| o.merge(x.to_data) } | |
end | |
end | |
class PhpValue < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements[1].to_data | |
end | |
end | |
class PhpValueString < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.elements[4].to_data | |
end | |
end | |
class IntegerLiteral < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.text_value.to_i | |
end | |
end | |
class StringLiteral < Treetop::Runtime::SyntaxNode | |
def to_data | |
chars = self.text_value[1...-1].scan(/./) | |
buf = '' | |
until chars.empty? | |
c = chars.shift | |
if c == '\\' | |
c = chars.shift | |
case c | |
when "n" | |
buf << "\n" | |
when "r" | |
buf << "\r" | |
when "\\" | |
buf << "\\" | |
when "t" | |
buf << "\t" | |
else | |
buf << c | |
end | |
else | |
buf << c | |
end | |
end | |
buf | |
end | |
end | |
class FloatLiteral < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.text_value.to_f | |
end | |
end | |
class NullValue < Treetop::Runtime::SyntaxNode | |
def to_data | |
nil | |
end | |
end | |
class PhpNaN < Treetop::Runtime::SyntaxNode | |
def to_data | |
0.0/0.0 | |
end | |
end | |
class PhpInf < Treetop::Runtime::SyntaxNode | |
def to_data | |
1.0/0.0 | |
end | |
end | |
class PhpIntKey < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.text_value.to_i | |
end | |
end | |
class PhpStringKey < Treetop::Runtime::SyntaxNode | |
def to_data | |
self.text_value | |
end | |
end | |
class PhpKeyValuePair < Treetop::Runtime::SyntaxNode | |
def to_data | |
return { self.elements[1].to_data => self.elements[6].to_data } | |
end | |
end | |
end |