【问题标题】:How to read all the Assembly predicate in a .txt file using read predicate in Prolog?如何使用 Prolog 中的读取谓词读取 .txt 文件中的所有组装谓词?
【发布时间】:2018-12-04 17:11:26
【问题描述】:

这是带有汇编谓词的 .txt 文件:

brz END //comment
sub ONE
sta SECOND
lda RESULT //comment
add FIRST
bra LOOP

我们必须加载和读取 .txt 文件,我们必须删除 cmets 并创建一个指令列表,如下所示:

L=[brz END,sub ONE,...]

【问题讨论】:

  • 您查看过文件 I/O 的 SWI Prolog 文档吗?
  • @TessellatingHeckler 您的计划可能是将输入分成几行,然后每行执行一些单独的步骤来解析它们。但事实证明,在 Prolog 中一直采用 DCG 方法并将文件直接解析为目标表示形式要容易得多,而不是分两步完成。 (几年前我开始学习 Prolog 时遇到了同样的问题。)
  • @TessellatingHeckler 我正忙着写一个答案。 (虽然你不是 OP,所以你评论的好像你是很奇怪。)但你应该明白,从其他语言中对你有意义的东西在 Prolog 中可能并不简单,在其他简单的东西中作为初学者,Prolog 对您来说可能并不简单。但这不是 Prolog 的错。 :)
  • @TessellatingHeckler 是的,Prolog I/O 相当原始。您可以使用各种其他解决方案来阅读行(例如,this one on SO)。看起来你还想解析你的 asm cmets(?) 你必须单独处理但不会有太多代码。

标签: prolog


【解决方案1】:

在像 Python 这样的传统语言中,您可能会想用这样的方式来解决这个问题:

result = []
for line in open('file.txt'):
   line = re.replace(line, '//.*', '')
   result.append(line)

在 Prolog 中,您会发现为您的输入编写一个完整的 DCG 会更简单,就像它是一个语法一样。在核心中拥有一个更强大的解析框架在某种程度上阻止了 Prolog 开发一个庞大而复杂的字符串和字符碰撞函数套件。因此,我希望 即使您确实 解析为字符串,您也会再次被卡住,但是由于缺少正则表达式库或对字符串进行切片和切块的方法,而这些方法并不存在。

与 Prolog 中的所有内容一样,它比您可能习惯的要冗长,但有一些优势可能从一开始就并不明显。这是我为你的玩具问题想出的代码(我花了大约 15 分钟。)

:- use_module(library(pio)).
:- use_module(library(dcg/basics)).

comment --> "//", string_without("\n", _).
comment --> [].

optarget(A) --> string(S), { atom_codes(A, S) }.

instruction(inst(Op, Target)) --> optarget(Op), " ", whites, 
                                  optarget(Target), whites, comment, "\n".

instructions([Inst|Rest]) --> instruction(Inst), instructions(Rest).
instructions([]) --> [].

这会将您的示例解析为如下内容:

?- phrase_from_file(instructions(Inst), "test.txt").
Inst = [inst(brz, 'END'), inst(sub, 'ONE'), inst(sta, 'SECOND'), 
        inst(lda, 'RESULT'), inst(add, 'FIRST'), inst(bra, 'LOOP')] .

您不应该将 dcg/basics 用于与 HTTP 无关的事情,从而感到自己在“滥用”它。该库是在一段时间前提取的,因为它具有一般用途。

  • 我在这里使用whites 来丢弃空格,但因为它会成功,所以你需要在两个 optarget 调用之间显式空格
  • 除了optarget//1,您还可以做更多有趣的事情,例如仅解析您的真实指令或仅解析您的真实参数,但我不知道它们是什么,所以您在这里得到了原子
  • 当您的指令需要更多参数时,您可以添加额外的instruction//1 规则来单独处理它们。无论如何,这可能就是我会做的事情
  • 如果您意识到不同的表示将更有利于下游处理,通过更改instruction//1instructions//1 应该很容易实现

【讨论】:

  • 谢谢你的回答,但我不能在我的项目中使用这个库。我知道这是一个玩具问题,但我一周前开始学习 prolog。
  • DCGs 不是库,它们是 Prolog 的基本特征。它们与 Prolog 的区别就像字典与 Python 的区别一样。 dcg/basics 和 pio 库是分开的,但它们的代码是开源的。将我在此处使用的 dcg/basics 部分复制到您的代码中需要大约四行的手工劳动。 pio 可能是另一个故事,但即使在那里,添加一个小谓词来读取整个文件并将其传递给phrase/2 也不是很困难。
  • @TessellatingHeckler 我指的是字符串正则表达式库。我理解你的沮丧,但它并不能帮助你学习 Prolog,因为它不是 Perl 而生气。 Prolog 确实与其他语言完全不同。如果你想精通它,你必须按照它自己的条件来处理它。由于这个确切的原因,我曾经对 Prolog 感到沮丧。很难在评论中解释发生了什么变化,但这与 Prolog 的整体性有关。总的来说,你需要的力量在那里,而且很优雅。但是你必须扩大你的视角才能理解它。
  • 对不起,我道歉。
  • @TessellatingHeckler 谢谢
猜你喜欢
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多