Can I get help on one thing please? I’m trying to simulate python json.dumps()
which converts a python object to a json literal. So I’m trying to write a simple limited grammar that converts a prolog json term to json literal.
Here’s what I have so far
jsonpl_jsonspec(Json) --> ob, jsonify(Json), cb.
jsonify([K=@(V)]) --> dq(K), cl, [V].
jsonify([K=V]) --> { atom(V) }, dq(K), cl, dq(V).
jsonify([K=V]) --> { number(V) }, dq(K), cl, [V].
jsonify([K=@(V)|Js]) --> dq(K) ,cl, [V], cm, jsonify(Js).
jsonify([K=V|Js]) --> { atom(V) }, dq(K), cl, dq(V), cm, jsonify(Js).
jsonify([K=V|Js]) --> { number(V) }, dq(K), cl, [V], cm, jsonify(Js).
dq(A) --> ['"'],[A],['"'].
ob --> ['{'].
cb --> ['}'].
cm --> [','].
cl --> [':'].
A couple of questions:
First, when I try to load this I’m getting Syntax error: Operator expected
for the two lines with @(V)
. Why? What I’m trying to do is, if I have a prolog json term with foo=@(null)
then I want to convert it to "foo":null
.
Second, when I trace phrase(jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123]),X).
I’m not clear on why it’s is failing.
?- trace, phrase(jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123]),X).
^ Call: (13) phrase(jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123]), _17242) ? creep
Call: (16) jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123], _17242, []) ? creep
Call: (17) atom(foo) ? creep
Exit: (17) atom(foo) ? creep
Call: (17) _21334=_17242 ? creep
Exit: (17) _17242=_17242 ? creep
Call: (17) dq(a, _17242, _22956) ? creep
Call: (18) _23776=[a|_23782] ? creep
Exit: (18) [a|_23782]=[a|_23782] ? creep
Call: (18) _23782=['"'|_22956] ? creep
Exit: (18) ['"'|_22956]=['"'|_22956] ? creep
Exit: (17) dq(a, ['"', a, '"'|_22956], _22956) ? creep
Call: (17) cl(_22956, _27844) ? creep
Exit: (17) cl([:|_27844], _27844) ? creep
Call: (17) dq(foo, _27844, _29472) ? creep
Call: (18) _30292=[foo|_30298] ? creep
Exit: (18) [foo|_30298]=[foo|_30298] ? creep
Call: (18) _30298=['"'|_29472] ? creep
Exit: (18) ['"'|_29472]=['"'|_29472] ? creep
Exit: (17) dq(foo, ['"', foo, '"'|_29472], _29472) ? creep
Call: (17) cm(_29472, _34360) ? creep
Exit: (17) cm([','|_34360], _34360) ? creep
Call: (17) jsonify([b= @(null), c='Wow', d= @(true), e=123], _34360, []) ? creep
Call: (18) atom(@(null)) ? creep
Fail: (18) atom(@(null)) ? creep
Redo: (17) jsonify([b= @(null), c='Wow', d= @(true), e=123], _34360, []) ? creep
Call: (18) number(@(null)) ? creep
Fail: (18) number(@(null)) ? creep
Fail: (17) jsonify([b= @(null), c='Wow', d= @(true), e=123], _34360, []) ? creep
Redo: (16) jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123], _17242, []) ? creep
Call: (17) number(foo) ? creep
Fail: (17) number(foo) ? creep
Fail: (16) jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123], _17242, []) ? creep
^ Fail: (13) phrase(user:jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123]), _17242) ? creep
false.
So
Exit: (17) dq(a, ['"', a, '"'|_22956], _22956) ? creep
Exit: (17) dq(foo, ['"', foo, '"'|_29472], _29472) ? creep
a=foo
→ "a":"foo"
works correctly.
Then we go to b= @(null)
Fail: (18) atom(@(null))
is correct.
Fail: (18) number(@(null))
is correct.
but we skipped my jsonify([K=@(V)|Js])
clause, and also right here I’m confused
Fail: (17) jsonify([b= @(null), c='Wow', d= @(true), e=123], _34360, []) ? creep
Redo: (16) jsonify([a=foo, b= @(null), c='Wow', d= @(true), e=123], _17242, []) ? creep
Why are we backtracking to the start of the list? Why didn’t we try jsonify([K=@(V)|Js])
? I should be allowed to do that, no? We can do
| J = [a=foo, b= @(null), c='Wow', d= @(true), e=123],
| member(b=V,J),
| V = @(V_).
J = [a=foo, b= @(null), c='Wow', d= @(true), e=123],
V = @(null),
V_ = null .
Apologies in advance if I’m missing something obvious. Thanks.