анализ dcg в случайном порядке - PullRequest
1 голос
/ 12 апреля 2020

У меня есть несколько текстовых файлов, которые я хотел бы проанализировать, однако порядок остановки и запуска примера может быть другим. Стоп может появляться первым или последним, это фиктивный пример, так как есть несколько переменных, таких как stop, start ...

Exemple1.txt

stop: 1

начало: 2

emple2.txt

начало: 9

стоп: 4

Я знаю, как разбирать start и stop, когда start - первый, а stop - второй, однако, как бы я это сделал, когда они расположены в случайном порядке.

parseStart(D) --> "start: " , integer(D).
parseStop(D) --> "stop: " , integer(D).

Я получаю файл для анализа из stdin, поэтому я делаю
read_string, чтобы разобрать 1 строку, превратить ее в список символов и сделать фразу (parseStart (Startint), line1), то же самое для строки 2, однако мне нужно знать порядок, которого я не знаю.

Может быть Я мог бы сделать что-то вроде

parseBoth(StartInt,StopInt) --> parseStart(startInt) <|> parseStop(StopInt) 

И сделать это два раза и проверить, объединены ли оба? Однако это похоже на хак, и мне интересно, есть ли лучший способ сделать это?

Редактировать: стоп, старт - это только один из многих примеров, у меня есть много выражений dcg, которые находятся в случайном порядке, как бы я это сделал, так как пробуя каждый заказ, я должен написать 6 предикаты для 6 возможных остановок, начало, конец, время ... выражения

1 Ответ

1 голос
/ 12 апреля 2020

Может быть что-то вроде:

parse(start(Start), stop(Stop)) -->
    first(Token),
    rest(Token, Start, Stop).

first(start) --> "start: ".
first(stop)  --> "stop: ".

rest(start, Start, Stop) -->
    integer(Start), stop(Stop).
rest(stop, Start, Stop) -->
    integer(Stop), start(Start).

start(Start) --> "start: " , integer(Start).
stop(Stop)   --> "stop: " , integer(Stop).

Обновить после редактирования вопроса.

Если все строки ваших текстовых файлов имеют формат «ключевое слово: целое число», Вы можете использовать:

parse_pairs([]) -->
    eos.
parse_pairs([Pair| Pairs]) -->
    parse_pair(Pair),
    parse_pairs(Pairs).

parse_pair(Key-Value) -->
    string(String), ": ", integer(Value), blanks,
    {atom_string(Key, String)}.

Пример вызова:

?- phrase(parse_pairs(Pairs), "start: 1\nstop: 2").
Pairs = [start-1, stop-2] .
...