Prolog 序言错误:`character';应为,找到“”;()"';(一串)
我的目标是以括号表示法打印具有N个节点的所有形式的树,可以根据上下文无关语法定义如下: T→ 树是空的 T→ (T.T)具有左右子节点的节点 例如,具有3个节点的所有树将如下所示: () ()(()) ().() (.(.) ()(()) 我用Prolog编写了以下代码Prolog 序言错误:`character';应为,找到“”;()"';(一串),prolog,dcg,Prolog,Dcg,我的目标是以括号表示法打印具有N个节点的所有形式的树,可以根据上下文无关语法定义如下: T→ 树是空的 T→ (T.T)具有左右子节点的节点 例如,具有3个节点的所有树将如下所示: () ()(()) ().() (.(.) ()(()) 我用Prolog编写了以下代码 form1(Prev, Next) :- string_concat("(", Prev, Inter), string_concat(Inter, ".)", Next). form2(Prev, Next
form1(Prev, Next) :-
string_concat("(", Prev, Inter),
string_concat(Inter, ".)", Next).
form2(Prev, Next) :-
string_concat("(.", Prev, Inter),
string_concat(Inter, ")", Next).
tree(1, ["(.)"]) :- !.
tree(N, Strings) :-
A is N - 1, tree(A, PrevStrings1),
maplist(form1 , PrevStrings1, List1),
maplist(form2 , PrevStrings1, List2),
append(List1, List2, Result),
Strings is Result.
但我得到了这个错误:
?- tree(2, L).
ERROR: Type error: `character' expected, found `"((.).)"' (a string)
ERROR: In:
ERROR: [9] _3182 is ["((.).)","(.(.))"]
ERROR: [7] <user>
?-树(2,L)。
错误:类型错误:应为'character',找到''(.)''(字符串)
错误:在:
错误:[9]_3182是[“()”,“()”]
错误:[7]
我的代码中没有引用字符。怎么了?解决此类问题的最佳方法是首先从抽象表示开始。抽象表示所有语法细节都已删除。你真正想要的是以下形式的树
is_tree(empty).
is_tree(node(Left, Right)) :-
is_tree(Left),
is_tree(Right).
然后,基于此表示,您可以使用您最喜欢的语法钟声和口哨来定义一个具体表示
:- set_prolog_flag(double_quotes, chars).
tree(empty) --> "".
tree(node(Left, Right)) -->
"(",
tree(Left),
".",
tree(Right),
")".
?- length(Text, N), phrase(tree(Tree), Text).
Text = [],
N = 0,
Tree = empty ;
Text = ['(','.',')'],
N = 3,
Tree = node(empty,empty) ;
Text = ['(','.','(','.',')',')'],
N = 6,
Tree = node(empty,node(empty,empty)) ;
Text = ['(','(','.',')','.',')'],
N = 6,
Tree = node(node(empty,empty),empty) ...
要提高答案的可读性,请使用[库(双引号)
表示和
最后,您现在可以完全跳过抽象语法树,因此:
tree --> "".
tree --> "(", tree, ".", tree, ")".
?- length(Text, N), phrase(tree, Text).
Text = [],
N = 0;
Text = "(.)",
N = 3;
Text = "(.(.))",
N = 6;
Text = "((.).)",
N = 6;
Text = "(.(.(.)))",
N = 9;
Text = "(.((.).))",
N = 9 ...
乍一看,这种简洁的语法似乎更可取,但在许多情况下,它是非常不方便的。特别是,如果你正在设计一种新的语法,而你不确定你的语法是否包含歧义。在前一个版本的帮助下,证明这些事情是非常简单的。当你你的意思是
=
is/2
严格用于算术计算,=
用于统一。用=
替换is
会产生错误:在本地堆栈外
反正你不需要那一行,只要将树(N,字符串)
更改为树(N,结果)
。堆栈溢出是不相关的;请使用跟踪
对其进行调试。
tree --> "".
tree --> "(", tree, ".", tree, ")".
?- length(Text, N), phrase(tree, Text).
Text = [],
N = 0;
Text = "(.)",
N = 3;
Text = "(.(.))",
N = 6;
Text = "((.).)",
N = 6;
Text = "(.(.(.)))",
N = 9;
Text = "(.((.).))",
N = 9 ...