summaryrefslogtreecommitdiff
path: root/test/racc/assets/php_serialization.y
diff options
context:
space:
mode:
Diffstat (limited to 'test/racc/assets/php_serialization.y')
-rw-r--r--test/racc/assets/php_serialization.y98
1 files changed, 98 insertions, 0 deletions
diff --git a/test/racc/assets/php_serialization.y b/test/racc/assets/php_serialization.y
new file mode 100644
index 0000000000..99f78f2081
--- /dev/null
+++ b/test/racc/assets/php_serialization.y
@@ -0,0 +1,98 @@
+# MIT License
+# See https://github.com/divoxx/ruby-php-serialization/blob/master/LICENSE.txt
+
+class PhpSerialization::Unserializer
+rule
+
+ data : null ';' { @object = val[0] }
+ | bool ';' { @object = val[0] }
+ | integer ';' { @object = val[0] }
+ | double ';' { @object = val[0] }
+ | string ';' { @object = val[0] }
+ | assoc_array { @object = val[0] }
+ | object { @object = val[0] }
+ ;
+
+ null : 'N' { result = nil }
+ ;
+
+ bool : 'b' ':' NUMBER { result = Integer(val[2]) > 0 }
+ ;
+
+ integer : 'i' ':' NUMBER { result = Integer(val[2]) }
+ ;
+
+ double : 'd' ':' NUMBER { result = Float(val[2]) }
+ ;
+
+ string : 's' ':' NUMBER ':' STRING { result = val[4] }
+ ;
+
+ object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}'
+ {
+ if eval("defined?(#{val[4]})")
+ result = Object.const_get(val[4]).new
+
+ val[9].each do |(attr_name, value)|
+ # Protected and private attributes will have a \0..\0 prefix
+ attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
+ result.instance_variable_set("@#{attr_name}", value)
+ end
+ else
+ klass_name = val[4].gsub(/^Struct::/, '')
+ attr_names, values = [], []
+
+ val[9].each do |(attr_name, value)|
+ # Protected and private attributes will have a \0..\0 prefix
+ attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
+ values << value
+ end
+
+ result = Struct.new(klass_name, *attr_names).new(*values)
+ result.instance_variable_set("@_php_class", klass_name)
+ end
+ }
+ ;
+
+ attribute_list : attribute_list attribute { result = val[0] << val[1] }
+ | { result = [] }
+ ;
+
+ attribute : data data { result = val }
+ ;
+
+ assoc_array : 'a' ':' NUMBER ':' '{' attribute_list '}'
+ {
+ # Checks if the keys are a sequence of integers
+ idx = -1
+ arr = val[5].all? { |(k,v)| k == (idx += 1) }
+
+ if arr
+ result = val[5].map { |(k,v)| v }
+ else
+ result = Hash[val[5]]
+ end
+ }
+ ;
+
+end
+
+---- header ----
+require 'php_serialization/tokenizer'
+
+---- inner ----
+ def initialize(tokenizer_klass = Tokenizer)
+ @tokenizer_klass = tokenizer_klass
+ end
+
+ def run(string)
+ @tokenizer = @tokenizer_klass.new(string)
+ yyparse(@tokenizer, :each)
+ return @object
+ ensure
+ @tokenizer = nil
+ end
+
+ def next_token
+ @tokenizer.next_token
+ end