dcg 以随机顺序解析

dcg parsing in random order

我有一些要解析的文本文件,但是例如停止和开始的顺序可能不同。停止可能首先出现或最后出现,这是一个虚拟示例,因为有多个变量,如停止、开始...

Exemple1.txt

stop: 1

start: 2

exemple2.txt

start: 9

stop: 4

我知道如何解析开始和停止时的开始和停止,但是当它们以随机顺序排列时我将如何做。

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

我从 stdin 收到要解析的文件,所以我这样做
read_string 解析 1 行,将其转换为字符列表并执行 phrase(parseStart(Startint),line1),与第 2 行相同,但是我必须知道我不知道的顺序。

也许我可以做类似的事情

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

然后重复两次并检查两者是否统一?然而,这似乎是一个 hack,我想知道是否有更好的方法来做到这一点?

编辑:停止、开始只是众多示例中的一个,我有许多随机顺序的 dcg 表达式,我该怎么做,因为尝试每个顺序都意味着我必须写 6! 6 个可能的停止、开始、结束、时间...表达式的谓词

可能是这样的:

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).

问题编辑后更新

如果文本文件的所有行都采用 "keyword: integer" 格式,您可以使用:

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] .