Как прочитать все предикаты Assembly в TXT-файле, используя предикат read в Prolog? - PullRequest
0 голосов
/ 04 декабря 2018

Это файл .txt с предикатом сборки:

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

Мы должны загрузить и прочитать файл .txt, удалить комментарии и создать список инструкций, например:

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

1 Ответ

0 голосов
/ 05 декабря 2018

На обычном языке, таком как Python, вы испытаете искушение решить эту проблему следующим образом:

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

В Prolog вместо этого вам будет проще написать полный DCG для вашего ввода, как если быэто была грамматика.Наличие в ядре более мощной структуры синтаксического анализа в некотором роде не позволило Прологу разработать большой и сложный набор функций преобразования строк и символов.Поэтому я ожидал бы, что , даже если вы выполните синтаксический анализ строк, вы снова застряли бы, если бы не было библиотеки регулярных выражений или способов нарезки и нарезки строк, которых просто нет.

Как и во всем в Прологе, это более многословно, чем вы, вероятно, привыкли, но есть преимущества, которые, вероятно, не очевидны с самого начала.Вот код, который я придумал для вашей проблемы с игрушкой (который занял у меня около 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//1 или instructions//1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...