这个用于json解析器的prolog程序有什么问题?

rbpvctlc  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(150)

我试着创建一个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不是很熟悉

yb3bgrhw

yb3bgrhw1#

您应该使用库来执行此操作。

?- atom_json_term('{ "name" : "foo"}', T, []).
T = json([name=foo]).

这里是链接,再次:https://www.swi-prolog.org/pldoc/man?section=json

mrwjdhj3

mrwjdhj32#

我认为您的问题是“chars”(Prolog原子)和“codes”(Unicode字符代码点(ASCII表示基本的美国英语文本和符号))之间的不匹配。
您对string_chars(String, Chars)的定义需要是string_codes(String, Chars),以匹配DCG的运行方式,但是您需要将捕获的值从代码转换回文本:

?- jsonparse('{"name" : "foo"}', Result).

Result = json([(string([110, 97, 109, 101]),string([102, 111, 111]))|_1688])

也许可以改变你的语法来处理一个原子列表,例如'{' instead of "{",但是这需要一路修改,并且可能意味着你不能使用dcg/basics,我还没有尝试过,如果你这样做的话,你可能仍然需要将原子列表转换回字符串。

相关问题