Я хочу написать предикат DCG, который будет принимать буквенную метку, пробел, псевдометку, которая может содержать пробелы или буквы, другой пробел и другую буквенную метку, и, наконец, точку, например:
label_madness --> label(Table1), " ", label_with_spaces(Rel), " ", label(Table2), ".".
Вот код для меток:
label(A) --> letters(S), {string_to_atom(S, A)}, !.
label_with_spaces(A) --> letters_or_spaces(S), {string_to_atom(S, A)}, !.
letters([C|D]) --> letter(C), letters(D), !.
letters([C]) --> letter(C), !.
letters_or_spaces([C|D]) --> letter(C), letters_or_spaces(D), !.
letters_or_spaces([C|D]) --> spacehyphen(C), letters_or_spaces(D), !.
letters_or_spaces([C]) --> letter(C), !.
letters_or_spaces([C]) --> spacehyphen(C), !.
letter(C) --> [C], {"a"=<C, C=<"z"}, !.
letter(C) --> [C], {"A"=<C, C=<"Z"}, !.
spacehyphen(E) --> " ", {from_list("-", E)}, !. % spaces are replaced with hyphens in the pseudolabel
from_list([E], E).
Теперь, когда я передаю label_madness
строку типа "Alice is responsible for Bob."
, происходит сбой.По таинственным причинам trace
отказывается работать, но я предполагаю, что это не работает, потому что DCG соответствует целому is responsible for Bob
для Rel
.Я попытался с непропускными разделителями между метками, и он работает нормально.Как мне переписать предикат label_with_spaces
, чтобы он потреблял столько информации, сколько требуется?