我尝试使用Prolog谓词read_command/1
读取字符串并将其转换为ASCII值。
以下代码有效。有人可以解释一下如何理解下面这段代码吗?
read_command(L) :- % read_command/1 get0(C), read_command(_, L, C). read_command(_, [], X) :- % auxiliary predicate read_command/3 member(X, `.\n\t`), !. read_command(X, [C|L], C) :- get0(C1), read_command(X, L, C1).
答案 0 :(得分:3)
read_command / 1读取当前输入流中可用的第一个字符,并将其用作 lookahead 。
read_command / 3只是在前瞻是空格或点时停止。 否则,将前瞻放在列表中,从流中获取新的前瞻,并递归。
我认为read_command / 3的第一个子句也应该处理当X为-1时的情况,意味着文件结束(例如,在按下Ctrl + D之后)
答案 1 :(得分:2)
TL; DR:请勿使用get0/1
!
get0/1
被视为已弃用 - 即使是实施它的Prolog处理器(如SWI)。
相反,使用get_char/1
并将字符串表示为字符列表 - 不作为代码列表!
read_command(Chars) :- get_char(Next), read_command_aux(Chars, Next). read_command_aux(Chars, Char) :- member(Char, ['.', '\t', '\n', end_of_file]), !, Chars = []. read_command_aux([Char|Chars], Char) :- get_char(Next), read_command_aux(Chars, Next).
以下是使用SWI-Prolog 7.3.15的一些示例查询:
?- read_command(Chars). |: abc Chars = [a, b, c]. ?- read_command(Chars). |: abc. Chars = [a, b, c]. ?- read_command(Chars). |: 123abc Chars = ['1', '2', '3', a, b, c].
为了进一步使用命令,您可能希望使用原子,如下所示:
?- read_command(Chars), atom_chars(Command, Chars). |: abcd. Chars = [a, b, c, d], Command = abcd.
请注意,不仅适用于SWI ,还适用于SICStus Prolog 4.3.2(和其他人)。