36
37:- module(dcg_basics,
38 [ white//0, 39 whites//0, 40 blank//0, 41 blanks//0, 42 nonblank//1, 43 nonblanks//1, 44 blanks_to_nl//0, 45 string//1, 46 string_without//2, 47 48 alpha_to_lower//1, 49 50 digits//1, 51 digit//1, 52 integer//1, 53 float//1, 54 number//1, 55 56 xdigits//1, 57 xdigit//1, 58 xinteger//1, 59
60 prolog_var_name//1, 61
62 eol//0, 63 eos//0, 64 remainder//1, 65
66 67 atom//1 68 ]). 69:- use_module(library(lists)). 70:- use_module(library(error)).
104string_without(End, Codes) -->
105 { string(End), !,
106 string_codes(End, EndCodes)
107 },
108 list_string_without(EndCodes, Codes).
109string_without(End, Codes) -->
110 list_string_without(End, Codes).
111
112list_string_without(Not, [C|T]) -->
113 [C],
114 { \+ memberchk(C, Not)
115 }, !,
116 list_string_without(Not, T).
117list_string_without(_, []) -->
118 [].
134string([]) -->
135 [].
136string([H|T]) -->
137 [H],
138 string(T).
144blanks -->
145 blank, !,
146 blanks.
147blanks -->
148 [].
157blank -->
158 [C],
159 { nonvar(C),
160 code_type(C, space)
161 }.
167nonblanks([H|T]) -->
168 [H],
169 { code_type(H, graph)
170 }, !,
171 nonblanks(T).
172nonblanks([]) -->
173 [].
179nonblank(H) -->
180 [H],
181 { code_type(H, graph)
182 }.
189blanks_to_nl -->
190 "\n", !.
191blanks_to_nl -->
192 blank, !,
193 blanks_to_nl.
194blanks_to_nl -->
195 eos.
203whites -->
204 white, !,
205 whites.
206whites -->
207 [].
214white -->
215 [C],
216 { nonvar(C),
217 code_type(C, white)
218 }.
219
220
221
242alpha_to_lower(L) -->
243 [C],
244 { nonvar(C)
245 -> code_type(C, alpha),
246 code_type(C, to_upper(L))
247 ; L = C
248 }.
249
250
251
264digits([H|T]) -->
265 digit(H), !,
266 digits(T).
267digits([]) -->
268 [].
269
270digit(C) -->
271 [C],
272 { code_type(C, digit)
273 }.
274
275integer(I, Head, Tail) :-
276 nonvar(I), !,
277 format(codes(Head, Tail), '~d', [I]).
278integer(I) -->
279 int_codes(Codes),
280 { number_codes(I, Codes)
281 }.
282
283int_codes([C,D0|D]) -->
284 sign(C), !,
285 digit(D0),
286 digits(D).
287int_codes([D0|D]) -->
288 digit(D0),
289 digits(D).
297float(F, Head, Tail) :-
298 float(F), !,
299 with_output_to(codes(Head, Tail), write(F)).
300float(F) -->
301 number(F),
302 { float(F) }.
310number(N, Head, Tail) :-
311 number(N), !,
312 format(codes(Head, Tail), '~w', N).
313number(N) -->
314 { var(N)
315 },
316 !,
317 int_codes(I),
318 ( dot,
319 digit(DF0),
320 digits(DF)
321 -> {F = [0'., DF0|DF]}
322 ; {F = []}
323 ),
324 ( exp
325 -> int_codes(DI),
326 {E=[0'e|DI]}
327 ; {E = []}
328 ),
329 { append([I, F, E], Codes),
330 number_codes(N, Codes)
331 }.
332number(N) -->
333 { type_error(number, N) }.
334
335sign(0'-) --> "-".
336sign(0'+) --> "+".
337
338dot --> ".".
339
340exp --> "e".
341exp --> "E".
342
343
355xinteger(Val, Head, Tail) :-
356 integer(Val), !,
357 format(codes(Head, Tail), '~16r', [Val]).
358xinteger(Val) -->
359 sign(C), !,
360 xdigit(D0),
361 xdigits(D),
362 { mkval([D0|D], 16, Val0),
363 ( C == 0'-
364 -> Val is -Val0
365 ; Val = Val0
366 )
367 }.
368xinteger(Val) -->
369 xdigit(D0),
370 xdigits(D),
371 { mkval([D0|D], 16, Val)
372 }.
380xdigit(D) -->
381 [C],
382 { code_type(C, xdigit(D))
383 }.
391xdigits([D0|D]) -->
392 xdigit(D0), !,
393 xdigits(D).
394xdigits([]) -->
395 [].
396
397mkval([W0|Weights], Base, Val) :-
398 mkval(Weights, Base, W0, Val).
399
400mkval([], _, W, W).
401mkval([H|T], Base, W0, W) :-
402 W1 is W0*Base+H,
403 mkval(T, Base, W1, W).
404
405
406
414eol --> "\n", !.
415eol --> "\r\n", !.
416eol --> eos.
431eos([], []).
437remainder(List, List, []).
438
439
440
449prolog_var_name(Name) -->
450 [C0], { code_type(C0, prolog_var_start) }, !,
451 prolog_id_cont(CL),
452 { atom_codes(Name, [C0|CL]) }.
453
454prolog_id_cont([H|T]) -->
455 [H], { code_type(H, prolog_identifier_continue) }, !,
456 prolog_id_cont(T).
457prolog_id_cont([]) --> "".
458
459
460
469atom(Atom, Head, Tail) :-
470 must_be(ground, Atom),
471 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.