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 { var(N)
313 },
314 !,
315 int_codes(I),
316 ( dot,
317 digit(DF0),
318 digits(DF)
319 -> {F = [0'., DF0|DF]}
320 ; {F = []}
321 ),
322 ( exp
323 -> int_codes(DI),
324 {E=[0'e|DI]}
325 ; {E = []}
326 ),
327 { append([I, F, E], Codes),
328 number_codes(N, Codes)
329 }.
330number(N) -->
331 { type_error(number, N) }.
332
333sign(0'-) --> "-".
334sign(0'+) --> "+".
335
336dot --> ".".
337
338exp --> "e".
339exp --> "E".
340
341
353xinteger(Val, Head, Tail) :-
354 integer(Val), !,
355 format(codes(Head, Tail), '~16r', [Val]).
356xinteger(Val) -->
357 sign(C), !,
358 xdigit(D0),
359 xdigits(D),
360 { mkval([D0|D], 16, Val0),
361 ( C == 0'-
362 -> Val is -Val0
363 ; Val = Val0
364 )
365 }.
366xinteger(Val) -->
367 xdigit(D0),
368 xdigits(D),
369 { mkval([D0|D], 16, Val)
370 }.
378xdigit(D) -->
379 [C],
380 { code_type(C, xdigit(D))
381 }.
389xdigits([D0|D]) -->
390 xdigit(D0), !,
391 xdigits(D).
392xdigits([]) -->
393 [].
394
395mkval([W0|Weights], Base, Val) :-
396 mkval(Weights, Base, W0, Val).
397
398mkval([], _, W, W).
399mkval([H|T], Base, W0, W) :-
400 W1 is W0*Base+H,
401 mkval(T, Base, W1, W).
402
403
404
421eos([], []).
427remainder(List, List, []).
428
429
430
439prolog_var_name(Name) -->
440 [C0], { code_type(C0, prolog_var_start) }, !,
441 prolog_id_cont(CL),
442 { atom_codes(Name, [C0|CL]) }.
443
444prolog_id_cont([H|T]) -->
445 [H], { code_type(H, prolog_identifier_continue) }, !,
446 prolog_id_cont(T).
447prolog_id_cont([]) --> "".
448
449
450
459atom(Atom, Head, Tail) :-
460 must_be(ground, Atom),
461 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.