我试着创建一个prolog JSON解析器,它有一个字符串和一个变量作为结果的输入,我写了这个程序:
:- use_module(library(dcg/basics)).
jsonparse(String, Value) :-
string_chars(String, Chars),
phrase(json_value(Value), Chars).
json_value(Value) -->
json_object(Value) ;
json_array(Value) ;
json_number(Value) ;
json_string(Value) ;
json_true(Value) ;
json_false(Value) ;
json_null(Value).
json_object(json(Members)) -->
"{", white, json_members(Members), white, "}".
json_members([Member|Members]) -->
json_pair(Member),
( ",", white,
json_members(Members)
; []
).
json_pair((Name,Value)) -->
json_string(Name), white, ":", white, json_value(Value).
json_array(json(Elements)) -->
"[", white, json_elements(Elements), white, "]".
json_elements([Element|Elements]) -->
json_value(Element),
( ",", white,
json_elements(Elements)
; []
).
json_number(number(Number)) -->
number(Number).
json_string(string(String)) -->
"\"", string_chars(String), "\"".
json_true(true) -->
"true".
json_false(false) -->
"false".
json_null(null) -->
"null".
number(Number) -->
float(Number) ;
integer(Number).
float(float(F)) -->
integer(I), ".", integer(Fraction),
{ atom_number(I, Int),
atom_number(Fraction, FractionInt),
F is Int + FractionInt / (10 ^ length(Fraction))
}.
integer(I) -->
digit(D), integer(D, I).
integer(I, I) -->
[].
integer(I0, I) -->
digit(D),
{ atom_concat(I0, D, I1) },
integer(I1, I).
digit(D) -->
[D],
{ code_type(D, digit) }.
white -->
[C], { code_type(C, white) }, white.
white -->
[].
string_chars([]) -->
[].
string_chars([C|Cs]) -->
string_char(C),
string_chars(Cs).
string_char(C) -->
[C],
{ C \= '"' }.
我就是不能让它工作,不管我输入什么,它总是返回false。有人能发现这个问题吗?我只想要解析后的字符串作为结果。另外,如果你能找到更优雅或更有效的方法来解决这个问题,那就太好了,因为我对prolog不是很熟悉
2条答案
按热度按时间yb3bgrhw1#
您应该使用库来执行此操作。
这里是链接,再次:https://www.swi-prolog.org/pldoc/man?section=json
mrwjdhj32#
我认为您的问题是“chars”(Prolog原子)和“codes”(Unicode字符代码点(ASCII表示基本的美国英语文本和符号))之间的不匹配。
您对
string_chars(String, Chars)
的定义需要是string_codes(String, Chars)
,以匹配DCG的运行方式,但是您需要将捕获的值从代码转换回文本:也许可以改变你的语法来处理一个原子列表,例如
'{' instead of "{"
,但是这需要一路修改,并且可能意味着你不能使用dcg/basics,我还没有尝试过,如果你这样做的话,你可能仍然需要将原子列表转换回字符串。