Parsing 用于解析转义序列的Prolog-DCG

Parsing 用于解析转义序列的Prolog-DCG,parsing,prolog,swi-prolog,dcg,Parsing,Prolog,Swi Prolog,Dcg,我需要将字符串^borrow$^\$500$解析到列表[borrow,$500]中。到目前为止我写的语法是 :- use_module(library(dcg/basics)). write_list([]). write_list([H|T]) :- atom_codes(S, H), write(S), nl, write_list(T). % Grammar. tags([Tag|Rest]) --> string(_), tag(Tag), tags(Rest). tags([

我需要将字符串
^borrow$^\$500$
解析到列表
[borrow,$500]
中。到目前为止我写的语法是

:- use_module(library(dcg/basics)).

write_list([]).
write_list([H|T]) :- atom_codes(S, H), write(S), nl, write_list(T).

% Grammar.
tags([Tag|Rest]) --> string(_), tag(Tag), tags(Rest).
tags([]) --> string(_).
tag(Tag) --> "^", tag_contents(Tag), "$".
tag_contents(Tag) --> string(Tag).
当令牌中没有
\$
时,该选项有效:

?- phrase(tags(T), "^pisica$ ^catel$"), write_list(T).
pisica
catel
?- phrase(tags(T), "^borrow$ ^\\$500$"), write_list(T).
borrow
\

使用Prolog DCGs解析此类转义序列的最佳实践是什么?

问题在于标记内容//1只捕获反斜杠,然后$在父调用中充当标记停止符

下面是一个关于这个问题的丑陋的破解:

tag(Tag1) -->
   "^", tag_contents(Tag), [C], "$", {C \= 0'\\, append(Tag, [C], Tag1) }.
编辑

稍微好一点的:

tag(Tag) --> "^", tag_contents(Tag), "$", {\+last(Tag, 0'\\)}.
编辑

“最佳实践”当然是使用上下文规则处理嵌套内容。你需要更多的代码

tag(Tag) --> "^", tag_contents(Tag).

tag_contents([0'\\,C|Cs]) --> "\\", [C], !, tag_contents(Cs).
tag_contents([]) --> "$".
tag_contents([C|Cs]) --> [C], tag_contents(Cs).

很抱歉破坏了此功能,但是使用标记//1的标记//1不正确。