用 dcg 解析标准输入
parsing stdin with dcg
我在理解如何使用 DCG 将一些文本从标准输入解析为所需变量时遇到了一些困难。
Players: player1 & player2
Board : 3 moves
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 中不起作用,我该如何实现?
我会使用库 (dcg/basics), that offers some relatively low level utilities. It can be coupled with library(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).
要测试语法你可以直接调用非终结符。请注意,语法接受超过 2 个玩家,并以灵活的方式正确地跳过空格。
?- phrase(players(Ps),`Players: player1 & player2& player3`).
Ps = [player1, player2, player3] ;
false.
我在理解如何使用 DCG 将一些文本从标准输入解析为所需变量时遇到了一些困难。
Players: player1 & player2
Board : 3 moves
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 中不起作用,我该如何实现?
我会使用库 (dcg/basics), that offers some relatively low level utilities. It can be coupled with library(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).
要测试语法你可以直接调用非终结符。请注意,语法接受超过 2 个玩家,并以灵活的方式正确地跳过空格。
?- phrase(players(Ps),`Players: player1 & player2& player3`).
Ps = [player1, player2, player3] ;
false.