我想打开一个文本文件,从中读取(任意)行,并从提取的信息中构造程序状态。特别是,我想在处理文件时跟踪行号。我已经在下面编写了代码,但是我在序言方面的经验有限,非常感谢社区提出的任何意见或建议。
我在堆栈溢出和网络上研究了类似的问题,发现Daniel Lyons(https://stackoverflow.com/a/16096728/11542361)的详细答案非常有帮助,但它无法跟踪行号。我也看过Anne Ogborn的教程(在SWI-Prolog中使用定句从句;从https://stackoverflow.com/a/14015035/11542361引用),但是我要处理的文本基本上是非结构化的(没有明确的语法规则)。>
我写的代码是:
%% Text processing framework
%
% Idea is to open a file, read lines from it, and construct
% program state. The state below just counts the number of lines
% in the input file, along with the number of lines containing
% the substring "Added" [for illustrative purposes only].
source_file('logfile.txt').
main(_Argv) :-
source_file(Source_File),
open(Source_File, read, Input),
% Sample state: count # lines containing 'Added'
load_state(Input, state(added(0),lines(0)), State, 0),
!, % prohibit backtracking to load_state()
close(Input),
print(State). % process loaded information
%% load_state(+Input, +Old_State, -New_State, +Previous_Line_Number)
load_state(Input, Old_State, New_State, Previous_Line_Number) :-
Line_Number is Previous_Line_Number + 1,
read_line_to_string(Input, Line),
load_state_x(Input, Line, Old_State, New_State, Line_Number).
% load_state_x enforces termination at end_of_file, and also
% invokes recursion back to load_state() for the next line.
load_state_x(_, end_of_file, State, State, _).
load_state_x(Input, Line, Old_State, New_State, Line_Number) :-
process_line(Line, Old_State, Next_State, Line_Number),
load_state(Input, Next_State, New_State, Line_Number).
% process_line() has knowledge of the system state, and updates it.
process_line(Line, state(added(Count),lines(_)),
state(added(New_Count),lines(Line_Number)), Line_Number) :-
sub_string(Line,_,_,_,"Added"),
New_Count is Count + 1.
% "Added" not a substring of Line (per above)
process_line(_Line, state(added(Count),lines(_)),
state(added(Count),lines(Line_Number)), Line_Number).
上面的代码在SWI-Prolog中有效(在有限测试中);尚未在其他任何序言系统上尝试过。