1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.functions;
22
23 import org.millscript.commons.util.list.IDynamicList;
24 import org.millscript.commons.util.list.IEmptyList;
25 import org.millscript.commons.util.list.IDynamicList.ListEntry;
26 import org.millscript.millscript.datatypes.Binding;
27 import org.millscript.millscript.tools.CastLibrary;
28
29 import java.util.regex.Matcher;
30
31 /**
32 * This class implements the MillScript <code>findSuccessiveMatches</code>
33 * function.
34 */
35 public final class FindSuccessiveMatchesFunction extends BinaryFunction {
36
37 /**
38 * This class implements a dynamic list entry for a binding list.
39 */
40 private static final class BindingListEntry extends IDynamicList.ListEntry< Binding > {
41
42 /**
43 * This is the ID from the release 10.2.0 for future compatibility.
44 */
45 private static final long serialVersionUID = -5309136978073166788L;
46
47 /**
48 * The matcher used to construct this binding.
49 */
50 private Matcher matcher;
51
52 /**
53 * The original string the regular expression was matched against.
54 */
55 private final String originalString;
56
57 /**
58 * Constructs a new binding list entry for the specified binding, which
59 * will use the specified matcher and string for calculating successive
60 * bindings.
61 *
62 * @param m the matcher to find successive bindings from
63 * @param s the original string that was matched against
64 * @param val the binding for this entry in the list
65 */
66 public BindingListEntry( final Matcher m, final String s, final Binding val ) {
67 super( val );
68 this.matcher = m;
69 this.originalString = s;
70 }
71
72 /**
73 * @see org.millscript.commons.util.list.IDynamicList.ListEntry#calculateNext()
74 */
75 @Override
76 public ListEntry< Binding > calculateNext() {
77
78 if ( matcher != null ) {
79 if ( matcher.find() ) {
80
81 return new BindingListEntry(
82 this.matcher,
83 this.originalString,
84 Binding.newBinding( originalString, matcher )
85 );
86 } else {
87
88
89
90
91 matcher = null;
92 }
93 }
94 return null;
95 }
96
97 }
98
99 /**
100 * @see org.millscript.millscript.functions.BinaryFunction#apply2(java.lang.Object, java.lang.Object)
101 */
102 @Override
103 public Object apply2( final Object a1, final Object a2 ) {
104
105 final String input = CastLibrary.toString( a2 );
106
107
108 final Matcher matcher = CastLibrary.toPattern( a1 ).matcher( input );
109
110 if ( matcher.find() ) {
111
112
113 return new IDynamicList< Binding >(
114 new BindingListEntry(
115 matcher,
116 input,
117 Binding.newBinding( input, matcher )
118 )
119 );
120 } else {
121
122 return IEmptyList.EMPTY_LIST;
123 }
124 }
125
126 }