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 |