use of suite.text.Segment in project suite by stupidsing.
the class IndentationPreprocessor method apply.
@Override
public List<Run> apply(String in) {
List<Run> runs = new ArrayList<>();
int nLastIndents = 0;
String lastIndent = "";
int pos = 0;
int length = in.length();
while (pos < length) {
int pos0 = pos;
char ch;
while (pos0 < length && (ch = in.charAt(pos0)) != '\n' && Character.isWhitespace(ch)) pos0++;
Segment segment = ParseUtil.searchPosition(in.toCharArray(), Segment.of(pos0, length), "\n", Assoc.RIGHT, false);
int pos1 = segment != null ? segment.start : length;
// includes LF
int pos2 = segment != null ? segment.end : length;
String indent = in.substring(pos, pos0);
String line = in.substring(pos0, pos1);
int nIndents = pos0 - pos, lineLength = pos1 - pos0;
if (!lastIndent.startsWith(indent) && !indent.startsWith(lastIndent))
Fail.t("indent mismatch");
if (lineLength != 0) {
// ignore empty lines
int startPos = 0, endPos = lineLength;
lastIndent = indent;
// find operators at beginning and end of line
for (Operator operator : operators) {
String name = operator.getName().trim();
if (!name.isEmpty()) {
if (line.startsWith(name + " "))
startPos = max(startPos, name.length() + 1);
if (String_.equals(line, name))
startPos = max(startPos, name.length());
if (line.endsWith(name))
endPos = min(endPos, lineLength - name.length());
}
}
if (// when a line has only one operator
endPos < startPos)
startPos = 0;
// insert parentheses by line indentation
while (nIndents < nLastIndents) {
runs.add(new Run(") "));
nLastIndents--;
}
runs.add(new Run(pos0, pos0 + startPos));
while (nLastIndents < nIndents) {
runs.add(new Run(" ("));
nLastIndents++;
}
runs.add(new Run(pos0 + startPos, pos2));
nLastIndents = nIndents;
}
pos = pos2;
}
while (0 < nLastIndents--) runs.add(new Run(") "));
return runs;
}
use of suite.text.Segment in project suite by stupidsing.
the class ParseUtil method split.
public static Streamlet<String> split(String in, String name) {
char[] chars = in.toCharArray();
int length = chars.length;
return new Streamlet<>(() -> Outlet.of(new Source<String>() {
private int pos = 0;
public String source() {
if (pos < length) {
Segment segment = searchPosition(chars, Segment.of(pos, length), name, Assoc.LEFT, true);
int pos0 = pos;
int end;
if (segment != null) {
end = segment.start;
pos = segment.end;
} else
end = pos = length;
return new String(chars, pos0, end);
} else
return null;
}
}));
}
use of suite.text.Segment in project suite by stupidsing.
the class ParseUtil method search.
private static Pair<String, String> search(String s, Segment segment, String name, Assoc assoc, boolean isCheckDepth) {
Segment ops = searchPosition(s.toCharArray(), segment, name, assoc, isCheckDepth);
if (ops != null) {
String left = s.substring(segment.start, ops.start);
String right = s.substring(ops.end, segment.end);
return Pair.of(left, right);
} else
return null;
}
use of suite.text.Segment in project suite by stupidsing.
the class Lccs method lccs.
public Pair<Segment, Segment> lccs(Bytes bytes0, Bytes bytes1) {
int rollingSize = min(bytes0.size(), bytes1.size());
if (0 < rollingSize) {
IntObjMap<Segment> segments0 = hashSegments(bytes0, rollingSize);
IntObjMap<Segment> segments1 = hashSegments(bytes1, rollingSize);
while (true) {
Set<Integer> keys0 = segments0.streamlet().keys().toSet();
Set<Integer> keys1 = segments1.streamlet().keys().toSet();
Set<Integer> keys = Set_.intersect(keys0, keys1);
for (int key : keys) {
Segment segment0 = segments0.get(key);
Segment segment1 = segments1.get(key);
Bytes b0 = bytes0.range(segment0.start, segment0.end);
Bytes b1 = bytes1.range(segment1.start, segment1.end);
if (Objects.equals(b0, b1))
return Pair.of(segment0, segment1);
}
segments0 = reduceSegments(segments0, bytes0, rollingSize);
segments1 = reduceSegments(segments1, bytes1, rollingSize);
rollingSize--;
}
} else
return Pair.of(Segment.of(0, 0), Segment.of(0, 0));
}
use of suite.text.Segment in project suite by stupidsing.
the class RecursiveFactorizer method parse_.
private FactorizeResult parse_(Chars chars, int fromOp) {
Chars chars1 = chars.trim();
if (0 < chars1.size()) {
char first = chars1.get(0);
char last = chars1.get(-1);
for (int i = fromOp; i < operators.length; i++) {
Operator operator = operators[i];
Chars range = operator != TermOp.TUPLE_ ? chars : chars1;
Segment ops = ParseUtil.searchPosition(chars.cs, Segment.of(range.start, range.end), operator);
if (ops == null)
continue;
Chars left = Chars.of(chars.cs, chars.start, ops.start);
Chars middle = Chars.of(chars.cs, ops.start, ops.end);
Chars right = Chars.of(chars.cs, ops.end, chars.end);
Chars post = null;
int li, ri;
if (operator == TermOp.BRACES) {
if (chars1.end < ops.start || last != '}')
continue;
right = Chars.of(chars.cs, ops.end, chars1.end - 1);
post = Chars.of(chars.cs, chars1.end - 1, chars.end);
li = 0;
ri = 0;
} else {
if (operator == TermOp.TUPLE_)
if (left.isWhitespaces() || right.isWhitespaces())
continue;
boolean isLeftAssoc = operator.getAssoc() == Assoc.LEFT;
li = fromOp + (isLeftAssoc ? 0 : 1);
ri = fromOp + (isLeftAssoc ? 1 : 0);
}
List<FactorizeResult> list = new ArrayList<>(4);
list.add(parse_(left, li));
list.add(term(middle));
list.add(parse_(right, ri));
if (post != null)
list.add(term(post));
return FactorizeResult.merge(operator.toString(), list);
}
if (//
first == '(' && last == ')' || //
first == '[' && last == ']' || first == '`' && last == '`') {
Chars left = Chars.of(chars.cs, chars.start, chars1.start + 1);
Chars middle = Chars.of(chars.cs, chars1.start + 1, chars1.end - 1);
Chars right = Chars.of(chars.cs, chars1.end - 1, chars.end);
return FactorizeResult.merge("" + first, List.of(term(left), parse_(middle, 0), term(right)));
}
}
return term(chars);
}