一种可移植的方式是使用 write/1 而不是 writeq/1,并在使用 write/1 之前转换原子本身。转换代码可以使用 ISO 核心标准 atom_codes/2 如下:
% escape_atom(+Atom, -Atom)
escape_atom(X, Y) :-
atom_codes(X, L),
escape_codes(L, R, [0'"]),
atom_codes(Y, [0'"|R]).
谓词 escape_codes/2 本身可以很容易地用 DCG 实现,它也可用于许多 Prolog 系统。使用标准算术可以如下提取代理对:
% high_surrogate(+Integer, -Integer)
high_surrogate(X, Y) :- Y is (X >> 10) + 0xD7C0.
% low_surrogate(+Integer, -Integer)
low_surrogate(X, Y) :- Y is (X /\ 0x3FF) + 0xDC00.
以下是例程运行的示例:
?- escape_atom('abc\x1000c\def', X), write(X), nl.
"abc\ud800\udc0cdef"
X = '"abc\\ud800\\udc0cdef"'
?- escape_atom('abc\x1000b\def', X), write(X), nl.
"abc?def"
X = '"abc?def"'
唯一缺少的部分是内置的 code_type/2,它应该提供代码点的 unicode 通用类别。然后用于识别控制代码和无效代码,
只有这些被转义。
开源:Prolog escape.pl
https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-escape-pl