使用phrase_from_file 读取文件的行

mos*_*ewe 5 prolog swi-prolog dcg

我一直在尝试使用phrase_from_file语法规则解析包含整数行的文件

line --> I,line,{integer(I)}.
line --> ['\n'].
Run Code Online (Sandbox Code Playgroud)

因此: phrase_from_file(line,'input.txt').

它失败了,我很快就迷路了,试图追踪它。我什至试图打印I,但它甚至没有到达那里。

编辑:: 由于以下解决方案都不能真正满足我的需求(使用read/1假设您正在阅读条款,有时编写 DCG 可能会花费太长时间),我蚕食了我在 google 上搜索到的这段代码,主要的变化是添加了:

read_rest(-1,[]):-!.

read_word(C,[],C) :- ( C=32 ;
                       C=(-1)
                     ) , !.
Run Code Online (Sandbox Code Playgroud)

fal*_*lse 5

如果您正在使用,phrase_from_file/2有一种非常简单的方法可以在读取实际文件之前测试您的程序。只需使用phrase/2. 因此,一个目标

phrase(line,"1\n2").
Run Code Online (Sandbox Code Playgroud)

与调用相同

phrase_from_file(line,fichier)
Run Code Online (Sandbox Code Playgroud)

当 fichier 是包含 3 个以上字符的文件时。因此,您可以使用phrase/2.

@Jan Burse 已经提到了其他问题。SWI 读取字符代码。所以你必须写

newline --> "\n".
Run Code Online (Sandbox Code Playgroud)

换行。然后你仍然需要自己解析整数。但是使用phrase/2. 好消息是,您可以在不更改实际 DCG 代码的情况下切换到读取文件。


小智 4

我想这里有一个概念问题。虽然我不知道phrase_from_file/2的详细信息,即您正在使用哪个Prolog系统,但我仍然假设它会产生字符代码。因此,对于文件中的整数 123,您将得到字符代码 0'1、0'2 和 0'3。这可能不是您想要的。

如果您想处理字符,则需要使用非终端而不是简单的变量 I 来获取它们。您需要字符测试,而不是整数测试,您可以提前进行测试:

line --> [I], {0'0=<I, I=<0'9}, line.
Run Code Online (Sandbox Code Playgroud)

此致

PS:您还可以使用术语读取操作,而不是采用 DCG 方式。另请参阅: 从序言中的文件读取数字并排序