gpt4 book ai didi

prolog - 试图在序言中理解解析器 DCG

转载 作者:行者123 更新时间:2023-12-01 15:08:48 27 4
gpt4 key购买 nike

最近我一直在 Prolog 中使用 DCG,但我一直面临一些关于它究竟如何工作的问题。例如,我有这个小语法:

<atom> :: <letter> <atom_part> | <letter>
<atom_part> :: <letter> | <digit> | <letter> <atom_part> | <digit> <atom_part>
<letter>:: 'a' | 'b' ... |'Z'
<digit> :: '0' |...|'9'

其中,如果我没记错的话,是任何必须以字母开头的字母或数字字符串。
无论如何,我试图解析它如下:
letter("a") --> "a".
number(X) --> number(X).
...
%etc
programme(I) --> atomm(I).
atomm(C) --> letter(Ch).
atomm(C) --> numb(Ch).
atomm((E)) --> atomm_part(E).
atomm_part(E1,E2) --> atomm(E1),!,atomm(E2).

在这里我认为很明显最后两行是错误的。那真的是因为我不确定如何进行“递归调用”,因此解析器再次检查字符串中的下一个字符是数字还是字符串。我该如何纠正?提前致谢!

顺便说一句,我正在使用 swi-prolog

最佳答案

您的语法似乎比需要的更复杂,您可以使用 'epsilon' 简化它(空产生式,在 DCG 中是 [] )。除此之外,您应该使“程序”更符合规范。

atom --> letter, atom_part | letter.
atom_part --> letter | digit | letter, atom_part | digit, atom_part.
letter --> "a" | "b" | /* omissis... */ "Z".
digit --> [D], {memberchk(D, "0123456789")}.

您可以看到与原始规范的相似程度。
接着就,随即
?- phrase(atom, "a").
true ;
false.

?- phrase(atom, "3a").
false.

?- phrase(atom, "a3").
true ;
false.
letterdigit 显示了匹配单个字符的不同方式。 digit 如果您需要从输入中捕获值,就像在代码中所做的那样,它会更简单。但是因为枚举 26*2 个字符很容易出错,请考虑使用 code_type/2
atom(A) --> letter(L), atom_part(P), {A=[L|P]} | letter(L), {A=[L]}.
atom_part(P) --> letter(L), {P=[L]} | digit(D), {P=[D]} | letter(L), atom_part(A), {P=[L|A]} | digit(D), atom_part(A), {P=[D|A]}.
letter(L) --> [L], {code_type(L, alpha)}.
digit(D) --> [D], {memberchk(D, "0123456789")}.

还要考虑到通常 Prolog 中的替代方案是这样编码的
atom([L|P]) --> letter(L), atom_part(P).
atom([L]) --> letter(L).

更简单的形式允许以头部模式移动“数据结构”。

关于prolog - 试图在序言中理解解析器 DCG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14182359/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com