使用Instaparse使用BNF解析序列化的PHP数据
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Instaparse使用BNF解析序列化的PHP数据,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2627字,纯文字阅读大概需要4分钟。
内容图文
![使用Instaparse使用BNF解析序列化的PHP数据](/upload/InfoBanner/zyjiaocheng/723/97d8ed3fe1a94055af5b199d90e4d0ea.jpg)
我有一个PHP序列化的值,我需要在Clojure中解码.我正在使用这个library来反序列化它;它使用Instaparse,它利用EBNF / ABNF表示法来定义语法.供参考,这是完整的定义:
<S> = expr
<expr> = (string | integer | double | boolean | null | array)+
<digit> = #'[0-9]'
<number> = negative* (decimal-num | integer-num)
<negative> = '-'
<integer-num> = digit+
<decimal-num> = integer-num '.' integer-num
<zero-or-one> = '0'|'1'
size = digit+
key = (string | integer)
<val> = expr
array = <'a:'> <size> <':{'> (key val)+ <'}'> <';'>?
boolean = <'b:'> zero-or-one <';'>
null = <'N;'>
integer = <'i:'> number <';'>
double = <'d:'> number <';'>
string = <'s:'> <size> <':\\\"'> #'([^\"]|\\.)*' <'\\\";'>
我在这个库中发现了一个错误 – 它无法处理包含“字符”的序列化字符串.
php > echo serialize('{"key":"value"}');
s:15:"{"key":"value"}";
使用库进行反序列化,当它找到第二个时它会爆炸“:
> (deserialize-php "s:15:\"{\"key\":\"value\"}\";")
[:index 7]
语法定义的这一行存在问题:
string = <'s:'> <size> <':\\\"'> #'([^\"]|\\.)*' <'\\\";'>
您会注意到字符串定义排除了“字符.但这不正确,我可以在该字符串中包含任何字符;大小是重要的.我不是BNF专家,所以我想弄明白什么我的选择是.
是否可以使用大小作为正确的字符数来抓取?如果那是不可能的,有人会看到一种方法我可以调整语法定义以启用正确的解析吗?
解决方法:
作为stated by Arthur Ulfeldt,这个语法是not context-free due to the bencoded strings.尽管如此,它是一个简单的解析,而不是A / EBNF.例如,使用Parse-EZ代替:
方便宏:
(defmacro tagged-sphp-expr [tag parser]
`(fn [] (between #(string ~(str tag ":")) #(~parser) #(string ";"))))
其余的部分:
(def sphp-integer (tagged-sphp-expr "i" integer))
(def sphp-decimal (tagged-sphp-expr "d" decimal))
(defn sphp-boolean []
(= \1 ((tagged-sphp-expr "b" #(chr-in "01")))))
(defn sphp-null [] (string "N;") :null)
(defn sphp-string []
(let [tag (string "s:")
size (integer)
open (no-trim #(string ":\""))
contents (read-n size)
close (string "\";")]
contents))
(declare sphp-array)
(defn sphp-expr []
(any #(sphp-integer) #(sphp-decimal) #(sphp-boolean) #(sphp-null) #(sphp-string) #(sphp-array)))
(defn sphp-key []
(any #(sphp-string) #(sphp-integer)))
(defn sphp-kv-pair []
(apply array-map (series #(sphp-key) #(sphp-expr))))
(defn sphp-array []
(let [size (between #(string "a:") #(integer) #(string ":{"))
contents (times size sphp-kv-pair)]
(chr \})
(attempt #(chr \;))
contents))
考试:
(def test-str "i:1;d:2;s:16:\"{\"key\": \"value\"}\";a:2:{s:3:\"php\";s:3:\"sux\";s:3:\"clj\";s:3:\"rox\";};b:1;")
(println test-str)
;=> i:1;d:2;s:16:"{"key": "value"}";a:2:{s:3:"php";s:3:"sux";s:3:"clj";s:3:"rox";};b:1;
(parse #(multi* sphp-expr) test-str)
;=> [1 2.0 "{\"key\": \"value\"}" [{"php" "sux"} {"clj" "rox"}] true]
内容总结
以上是互联网集市为您收集整理的使用Instaparse使用BNF解析序列化的PHP数据全部内容,希望文章能够帮你解决使用Instaparse使用BNF解析序列化的PHP数据所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。