关于Prolog tokenizer

0 prolog lexer

我的一个任务要求我们构建一个prolog tokenizer.现在我写了一个可以改变空间并将其换成新行的谓词.但我不知道如何将其实施到主程序中.

替换部件如下所示:

replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]):- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).
Run Code Online (Sandbox Code Playgroud)

Main部分有一个谓词removewhite(list1 list2)

那我怎么能让removewhite执行替换呢?

Cap*_*liC 5

你对一个标记器有点'偏离':removewhite/2不会给你带来任何有用的功能.相反,考虑使用DCG(当然,如果您的Prolog提供此功能):

tokenize(String, Tokens) :- phrase(tokenize(Tokens), String).

tokenize([]) --> [].
tokenize(Tokens) --> skip_spaces, tokenize(Tokens).
tokenize([Number|Tokens]) --> number(Number), tokenize(Tokens).

skip_spaces --> code_types(white, [_|_]).
number(N) --> code_types(digit, [C|Cs]), {number_codes(N,[C|Cs])}.

code_types(Type, [C|Cs]) --> [C], {code_type(C,Type)}, !, code_types(Type, Cs).
code_types(_, []) --> [].
Run Code Online (Sandbox Code Playgroud)

尽管简单,但这是一个相当高效的扫描仪,易于扩展.在SWI-Prolog中,它具有(非ISO兼容)扩展以有效处理字符串,这可以从顶层调用,如:

?- tokenize(`123  4 567  `, L).
L = [123, 4, 567]
Run Code Online (Sandbox Code Playgroud)

要么

?- atom_codes('123  4 567  ',Cs), tokenize(Cs, L).
Cs = [49, 50, 51, 32, 32, 52, 32, 53, 54|...],
L = [123, 4, 567] 
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在SWI-Prolog中,数字// 1是预定义的(当然还有更多的功能)在库中(dcg/basics).

无论如何,关于你的问题

我怎样才能让removewhite执行replace?

我觉得你真的'吠叫错了树':删除一个空间 - 实际上一个分隔符 - 会搞砸你的输入......