summaryrefslogtreecommitdiff
path: root/src/parser.prolog
blob: c9f97710b6f0a844019c562af509054421fa4e0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

:- module(parser, [prompt/1, readList/1, readLine/1, split/2, join/2, intercalate/3]).


% functions for dealing with lines of text
% eg obtaining one, parsing it into a list of words, and rejoining it

% prompt provides the user with a '>' prompt
% readList merely obtains and parses the input
% readLine obtains a raw line of input
% split parses a line of text into words
% join takes a list of words and joins them into one string


prompt(L) :-
    write('> '),
    readList(L).


readList(L) :-
    readLine(X),
    split(X,L).


readLine(L) :-
    get_char(C),
    readLine_tail(C,L).


readLine_tail('\n',[]) :- !.
readLine_tail(C,[C|X]) :-
    get_char(C2),
    readLine_tail(C2,X).


split(X,R) :-
    wordList(R,X,[]), !.


join([X|Y],R) :-
    join(Y,Rx),
    atom_concat(X,Rx,R).
join([X],R) :-
    R = X.


intercalate([X|Y], Spacer, Result) :-
    intercalate(Y, Spacer, Tail),
    atom_concat(X, Spacer, Head),
    atom_concat(Head, Tail, Result).
intercalate([X], _, Result) :- Result = X.


wordList(X) --> whitespace, wordList(X).
wordList([X]) --> word(X).
wordList([X]) --> word(X), whitespace.
wordList([X|Y]) --> word(X), whitespace, wordList(Y).


word(W) --> charList(X), {atom_chars(W,X)}.


charList([X|Xs]) --> char(X), charList(Xs).
charList([X]) --> char(X).


whitespace --> whsp, whitespace.
whitespace --> whsp.


whsp --> oneOf(_,[' ', '\r', '\n', '\t']).
char(X) --> noneOf(X,[' ', '\r', '\n', '\t']).


oneOf(X,L) --> [X], {member(X,L)}.
noneOf(X,L) --> [X], {not(member(X,L))}.