1:- module(dcg_tools,
2 [
3 any//1,
4 nl//0,
5 space//0,
6 space//1,
7 spaces//0,
8 sp//0,
9
10 optional//1,
11 optional//2,
12 constant//1,
13 '|'//3,
14 (//)//2,
15
16 uppercase//1,
17 lowercase//1,
18 letter//1,
19 word//1,
20 symbol//1,
21 digit//1,
22 natural//1,
23 integer//1,
24
25 list//1,
26 list//2,
27 list//3,
28 non_greedy//1,
29 non_greedy//2
30 ]). 31
32:- use_module(library(delay)). 33
34:- multifile delay:mode/1.
35delay:mode(lists:append(ground,_)).
36delay:mode(lists:append(_,ground)).
37delay:mode(dcg_tools:number_codes_(ground,_)).
38delay:mode(dcg_tools:number_codes_(_,ground)).
39
40
42optional(Dcg) --> optional(Dcg, _).
43optional(Dcg, Res) --> call(Dcg, Res) | {Res = ``}.
44constant(A) --> seq(A).
45'|'(Dcg1, Dcg2, X) --> call(Dcg1, X) | call(Dcg2, X).
46
47//(P1,P2,S1,S2) :- call_dcg(P1,S1,S2), call_dcg(P2,S1,S2).
48
49
50
51seq([]) --> [].
52seq([E|Es]) --> [E], seq(Es).
53
54any(X) --> [X].
55nl --> `\n`.
56space --> ` `.
57space(_) --> ` `.
58spaces --> list(space).
59sp --> list(space).
60
61digitCode(C) --> [C], {code_type(C, digit)}.
62symbolCode(C) --> [C], {code_type(C, punct)}.
63lowercaseCode(C) --> [C], {code_type(C, lower)}.
64uppercaseCode(C) --> [C], {code_type(C, upper)}.
65letterCode(C) --> lowercaseCode(C) | uppercaseCode(C).
66
67lowercase(L) --> {delay(atom_codes(L, [C]))}, lowercaseCode(C).
68uppercase(L) --> {delay(atom_codes(L, [C]))}, uppercaseCode(C).
69letter(L) --> lowercase(L) | uppercase(L).
70word(W) --> {delay(atom_codes(W, Cs))},
71 list(letter, Cs).
72symbol(S) --> {delay(atom_codes(S, [C]))}, symbolCode(C).
73
74
75number_codes_(A,B) :- catch(number_codes(A,B), _, false).
76
77digit(D) --> {delay(number_codes_(D, [C]))},
78 digitCode(C).
79natural(N) --> {delay(number_codes_(N, Ds))},
80 list(digitCode, Ds).
81integer(N) --> {delay(number_codes_(N, Codes)),
82 delay(append([Sign, Ds], Codes))},
83 optional(sign,Sign), list(digitCode, Ds).
84
85sign([0'-]) --> `-`.
86sign([0'+]) --> `+`.
87
88
90:- meta_predicate non_greedy(3,*,*). 91non_greedy(Goal) --> non_greedy(Goal,_).
92
93:- meta_predicate non_greedy(3,-,*,*). 94non_greedy(_Goal,[]) --> [].
95non_greedy(Goal,[X|Xs]) --> call(Goal,X), non_greedy(Goal,Xs).
96
97:- meta_predicate list(3,?,?,?). 98list(ElemDCG) -->
99 list(ElemDCG, _).
100
101:- meta_predicate list(3,?,?,?). 102list(ElemDCG, [Elem|Tail]) -->
103 call(ElemDCG, Elem),
104 list(ElemDCG, Tail).
105list(_, []) --> [].
106
107:- meta_predicate list(3,2,?,?,?). 108list(ElemDCG, SepDCG, [Elem|Tail]) -->
109 call(ElemDCG, Elem),
110 (call(SepDCG), list(ElemDCG, SepDCG, Tail) ; {Tail=[]})