DCG - 如何将原子拆分为列表以进行进一步的 DCG 规则处理



我有一个简单的语法,它需要 3 个列表项,并对每个列表项运行不同的 dcg 规则。

[debug]  ?- phrase(sentence(X), [sky, a, 1], []).
X = [bright, amber, on] .

法典:

sentence([A,C,R]) --> 
    analyse(A),
    colour(C),
    rating(R).
analyse(bright) --> [sky].
analyse(dark) --> [cave].
colour(red) --> [r]. 
colour(amber) --> [a]. 
colour(green) --> [g]. 
rating(on) --> [1].
rating(off) --> [0].

这工作正常。

我的

问题是我的输入列表需要有 2 个项目,而不是 3 个,第二个原子是颜色和评级的串联原子:

[sky, a1]

所以不知何故,我必须(?)将这个原子分成[a,1],然后颜色和评级规则将与简单的dcg规则一起使用。

我不知道该怎么做。.显然,对于普通的prolog,我只会使用atom_chars,但我无法弄清楚如何将其与语法交错。

在一个完美的世界里,感觉我不应该求助于使用atom_chars,我应该能够想出一个简单的 dcg 规则来拆分它,但我不确定这是否可能,因为我们解析的是列表,而不是原子。

正如你自己所说,你只需要使用像 atom_chars/2 这样的谓词。您可以将普通代码交错到 DCG 规则中,方法是将其包含在 {} 中。

但是你的问题定义有些可疑。正如你自己也说过的,你正在解析一个列表,而不是一个原子。您正在解析的列表应该已经正确标记化,否则您不能期望定义可以解析它的 DCG。还是我看错了?

换句话说:你接受你的输入,分成单个字符,使用 DCG 对其进行标记。根据您的输入,您可以在同一步骤中执行解析。

很明显,一个精致的DCG规则可以工作,但是,唉,我花了太多时间为您的问题制定解决方案。

在这里:

sentence([A,C,R]) --> 
    analyse(A),
    colour(C),
    rating(R).
analyse(bright) --> [sky].
analyse(dark) --> [cave].
colour(red) --> [r]. 
colour(amber) --> [a]. 
colour(green) --> [g]. 
colour(X), As --> [A], {
    atom_codes(A, Cs),
    maplist(char2atomic, Cs, L),
    phrase(colour(X), L, As)}.
rating(on) --> [1].
rating(off) --> [0].
char2atomic(C, A) :- code_type(C, digit) -> number_codes(A, [C]) ; atom_codes(A, [C]).

收益 率

?- phrase(sentence(X), [sky, a1], []).
X = [bright, amber, on] 

关键是使用"推回"(即 colour(X), As -->... )。在这里,我们拆分无法解析的输入,使用一个令牌,然后推回其余的......

像往常一样,大部分时间都需要时间来了解我第一次尝试失败的地方:我正在编写char2atomic(C, A) :- atom_codes(A, [C]).,但后来 rating//1 失败了......

相关内容

最新更新