1 % (c) 2018-2019 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5 :- module(regexp, [regexp_init/0,
6 regexp_match/2,
7 is_regexp/1,
8 regexp_replace/4,
9 regexp_search_first/3,
10 regexp_search_first_detailed/4,
11 regexp_search_all/3]).
12
13
14 /* the interface to a heap global variable stored and maintained in C */
15
16
17 foreign(cpp_regex_match,cpp_regex_match(+string,+string,+integer,[-integer])).
18 foreign(cpp_regex_replace,cpp_regex_replace(+string,+string,+string,[-atom])).
19 foreign(cpp_regex_search_all_str,cpp_regex_search_all_str(+string,+string,[-term])).
20 foreign(cpp_regex_search_first_str,cpp_regex_search_first_str(+string,+string,[-atom])).
21 foreign(cpp_regex_search_first,cpp_regex_search_first(+string,+integer,+string,[-term])).
22 foreign_resource(regexp,
23 [
24 cpp_regex_match,
25 cpp_regex_replace,
26 cpp_regex_search_first_str,
27 cpp_regex_search_first,
28 cpp_regex_search_all_str
29 ]).
30
31 :- use_module(probsrc(error_manager)).
32
33 % match an atom agains a regular expression in ECMA syntax also represented as an atom
34 regexp_match(String,Pattern) :-
35 atom(String), atom(Pattern),
36 regexp_init,
37 !,
38 cpp_regex_match(String,Pattern,1,Res),
39 %format('String ~w for Pattern ~w: Result=~w~n',[String,Pattern,Res]),
40 (Res=1 -> true
41 ; Res>1
42 -> add_error(regexp,'Illegal Regular Expression Pattern (use ECMAScript syntax): ',Pattern),
43 fail).
44 regexp_match(String,Pattern) :-
45 format(user_error,'Illegal call: ',regepx_match(String,Pattern)),
46 fail.
47
48 % check if an atom is a valid regular expression pattern
49 is_regexp(Pattern) :- atom(Pattern),
50 regexp_init,
51 !,
52 cpp_regex_match('',Pattern,0,Res), % TO DO: will still print error messages
53 Res<2. % 0 or 1 means pattern was ok
54 is_regexp(Pattern) :-
55 format(user_error,'Illegal call: ',is_regexp(Pattern)),
56 fail.
57
58
59 % match an atom agains a regular expression in ECMA syntax also represented as an atom
60 regexp_replace(String,Pattern,ReplStr,Result) :-
61 atom(String), atom(Pattern), atom(ReplStr), regexp_init,
62 !,
63 cpp_regex_replace(String,Pattern,ReplStr,Result).
64 %,format('Replace ~w for Pattern ~w with ~w: Result=~w~n',[String,Pattern,ReplStr,Result]).
65 regexp_replace(String,Pattern,ReplStr,Result) :-
66 format(user_error,'Illegal call: ',regexp_replace(String,Pattern,ReplStr,Result)),
67 fail.
68
69 % search for a first match of a pattern; returns empty string if no match found
70 regexp_search_first(String,Pattern,Result) :-
71 atom(String), atom(Pattern), regexp_init,
72 !,
73 cpp_regex_search_first_str(String,Pattern,Result).
74 %,format('Search ~w for Pattern ~w: Result=~w~n',[String,Pattern,Result]).
75 regexp_search_first(String,Pattern,Result) :-
76 format(user_error,'Illegal call: ',regexp_search_first(String,Pattern,Result)),
77 fail.
78
79 % search for a first match of a pattern;
80 % returns either match(Pos,Len,[MatchAtom|SubMatches]) or no-match
81 regexp_search_first_detailed(String,FromPosition,Pattern,Result) :-
82 atom(String), atom(Pattern), FromPosition>0,
83 regexp_init,
84 !,
85 Offset is FromPosition-1,
86 cpp_regex_search_first(String,Offset,Pattern,Result).
87 %, format('Search ~w for Pattern ~w: Result=~w~n',[String,Pattern,Result]).
88 regexp_search_first_detailed(String,From,Pattern,Result) :-
89 format(user_error,'Illegal call: ',regexp_search_first_detailed(String,From,Pattern,Result)),
90 fail.
91
92 :- use_module(library(lists),[reverse/2]).
93 % search for a first match of a pattern; returns empty string if no match found
94 regexp_search_all(String,Pattern,Result) :-
95 atom(String), atom(Pattern), regexp_init,
96 !,
97 cpp_regex_search_all_str(String,Pattern,CRes),
98 reverse(CRes,Result).
99 %,format('Search ~w for Pattern ~w: Result=~w~n',[String,Pattern,Result]).
100 regexp_search_all(String,Pattern,Result) :-
101 format(user_error,'Illegal call: ',regexp_search_first(String,Pattern,Result)),
102 fail.
103
104 :- dynamic loaded/0.
105
106 regexp_init :-
107 (loaded -> true
108 ; (assert(loaded),
109 %assert_dir,
110 %assert(user:library_directory(prob_home('.'))),
111 %print(loading_foreign_resource(myheap)),nl,
112 load_foreign_resource(library(regexp)))
113 ).
114
115 assert_dir :- (user:library_directory('.') -> true ; assert(user:library_directory('.'))).
116