разбор stdin с dcg - PullRequest
       67

разбор stdin с dcg

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

У меня возникают некоторые трудности с пониманием того, как анализировать некоторый текст из stdin в нужные переменные с помощью DCG.

Игроки: player1 & player2

Доска: 3 хода

1A: player1
5D: player2
8Z: player1

Так что в игре есть два имени переменных игрока, а затем несколько ходов от каждого игрока, я хотел бы иметь предикат, что унифицирует Players = [player1,player2] , turn1 = [1A,8A] , turn2 = [5D].

Как мне сделать это с помощью DCG?

Я пробовал следующее:

main :-
    read_string(user_input,"\n","\r",_,FirstLine),
    phrase(readPlayers(Players),FirstLine),
    write(Players).

parsePlayers --> [Players].
parseColon --> [:].
parseSpace --> [ ].
readPlayers([P1,P2]) --> parsePlayers,parseColon,parseSpace,P1,parseSpace,[&], parseSpace,P2.   

Однако в SWI-Prolog это не работает, как мне этого добиться?

1 Ответ

2 голосов
/ 04 апреля 2020

Я бы использовал библиотеку ( dcg / basics ), которая предлагает некоторые утилиты относительно низкого уровня. Он может быть связан с библиотекой ( dcg / high_order ) для дальнейшего улучшения вашего синтаксического анализатора.

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

player(P) -->
    code(csymf,C),
    codes(csym,Cs),
    {atom_codes(P,[C|Cs])}.

players(Ps) -->
    "Players",
    sep(":"),
    sequence(player,sep("&"),Ps),
    blanks.

% my utilities
sep(S) --> whites, S, whites.
code(T,C) --> [C], {code_type(C,T)}.
codes(T,Cs) --> sequence(code(T),Cs).

Для проверки грамматики вы можете напрямую вызвать нетерминал. Обратите внимание, что грамматика допускает более двух игроков и правильно пропускает пробелы.

?- phrase(players(Ps),`Players: player1 & player2&  player3`).
Ps = [player1, player2, player3] ;
false.
...