35
36:- module(dcg_basics,
37 [ white//0, 38 whites//0, 39 blank//0, 40 blanks//0, 41 nonblank//1, 42 nonblanks//1, 43 blanks_to_nl//0, 44 string//1, 45 string_without//2, 46 47 alpha_to_lower//1, 48 49 digits//1, 50 digit//1, 51 integer//1, 52 float//1, 53 number//1, 54 55 xdigits//1, 56 xdigit//1, 57 xinteger//1, 58
59 prolog_var_name//1, 60
61 eos//0, 62 remainder//1, 63
64 65 atom//1 66 ]). 67:- use_module(library(lists)). 68:- use_module(library(error)).
102string_without(End, Codes) -->
103 { string(End), !,
104 string_codes(End, EndCodes)
105 },
106 list_string_without(EndCodes, Codes).
107string_without(End, Codes) -->
108 list_string_without(End, Codes).
109
110list_string_without(Not, [C|T]) -->
111 [C],
112 { \+ memberchk(C, Not)
113 }, !,
114 list_string_without(Not, T).
115list_string_without(_, []) -->
116 [].
132string([]) -->
133 [].
134string([H|T]) -->
135 [H],
136 string(T).
142blanks -->
143 blank, !,
144 blanks.
145blanks -->
146 [].
155blank -->
156 [C],
157 { nonvar(C),
158 code_type(C, space)
159 }.
165nonblanks([H|T]) -->
166 [H],
167 { code_type(H, graph)
168 }, !,
169 nonblanks(T).
170nonblanks([]) -->
171 [].
177nonblank(H) -->
178 [H],
179 { code_type(H, graph)
180 }.
187blanks_to_nl -->
188 "\n", !.
189blanks_to_nl -->
190 blank, !,
191 blanks_to_nl.
192blanks_to_nl -->
193 eos.
201whites -->
202 white, !,
203 whites.
204whites -->
205 [].
212white -->
213 [C],
214 { nonvar(C),
215 code_type(C, white)
216 }.
217
218
219
240alpha_to_lower(L) -->
241 [C],
242 { nonvar(C)
243 -> code_type(C, alpha),
244 code_type(C, to_upper(L))
245 ; L = C
246 }.
247
248
249
262digits([H|T]) -->
263 digit(H), !,
264 digits(T).
265digits([]) -->
266 [].
267
268digit(C) -->
269 [C],
270 { code_type(C, digit)
271 }.
272
273integer(I, Head, Tail) :-
274 nonvar(I), !,
275 format(codes(Head, Tail), '~d', [I]).
276integer(I) -->
277 int_codes(Codes),
278 { number_codes(I, Codes)
279 }.
280
281int_codes([C,D0|D]) -->
282 sign(C), !,
283 digit(D0),
284 digits(D).
285int_codes([D0|D]) -->
286 digit(D0),
287 digits(D).
295float(F, Head, Tail) :-
296 float(F), !,
297 with_output_to(codes(Head, Tail), write(F)).
298float(F) -->
299 number(F),
300 { float(F) }.
308number(N, Head, Tail) :-
309 number(N), !,
310 format(codes(Head, Tail), '~w', N).
311number(N) -->
312 int_codes(I),
313 ( dot,
314 digit(DF0),
315 digits(DF)
316 -> {F = [0'., DF0|DF]}
317 ; {F = []}
318 ),
319 ( exp
320 -> int_codes(DI),
321 {E=[0'e|DI]}
322 ; {E = []}
323 ),
324 { append([I, F, E], Codes),
325 number_codes(N, Codes)
326 }.
327
328sign(0'-) --> "-".
329sign(0'+) --> "+".
330
331dot --> ".".
332
333exp --> "e".
334exp --> "E".
335
336
346xinteger(Val, Head, Tail) :-
347 integer(Val),
348 format(codes(Head, Tail), '~16r', [Val]).
349xinteger(Val) -->
350 xdigit(D0),
351 xdigits(D),
352 { mkval([D0|D], 16, Val)
353 }.
360xdigit(D) -->
361 [C],
362 { code_type(C, xdigit(D))
363 }.
370xdigits([D0|D]) -->
371 xdigit(D0), !,
372 xdigits(D).
373xdigits([]) -->
374 [].
375
376mkval([W0|Weights], Base, Val) :-
377 mkval(Weights, Base, W0, Val).
378
379mkval([], _, W, W).
380mkval([H|T], Base, W0, W) :-
381 W1 is W0*Base+H,
382 mkval(T, Base, W1, W).
383
384
385
402eos([], []).
408remainder(List, List, []).
409
410
411
420prolog_var_name(Name) -->
421 [C0], { code_type(C0, prolog_var_start) }, !,
422 prolog_id_cont(CL),
423 { atom_codes(Name, [C0|CL]) }.
424
425prolog_id_cont([H|T]) -->
426 [H], { code_type(H, prolog_identifier_continue) }, !,
427 prolog_id_cont(T).
428prolog_id_cont([]) --> "".
429
430
431
440atom(Atom, Head, Tail) :-
441 must_be(ground, Atom),
442 format(codes(Head, Tail), '~w', [Atom])
Various general DCG utilities
This library provides various commonly used DCG primitives acting on list of character codes. Character classification is based on code_type/2.
This module started its life as
library(http/dcg_basics)
to support the HTTP protocol. Since then, it was increasingly used in code that has no relation to HTTP and therefore this library was moved to the core library.