Ci-dessous, je suis désolé, mais je vais le laisser dans un état que je ne supporte pas de lire pendant un moment comme un article ...
Créez une classe appelée Utf32Iterator et une classe appelée IteratorInput pour analyser la chaîne. Je considérerai également des paires de substitution.
StringParser.java
public class StringParser {
//Itérateur qui traite la chaîne comme un point de code Unicode. Envisagez également des paires de substitution.
public static class Utf32Iterator implements Iterator<Integer> {
private int position, nextCodePoint = -1;
private final String source;
public Utf32Iterator(String source_) {source = source_; position = 0;}
@Override public boolean hasNext() {
nextCodePoint = -1;
return position <= source.length(); // position == source.length()Le cas est EOF. Renvoie null, puis crée EndOfInputException.
}
@Override public Integer next() {
if (position == source.length()) { //EOF si la longueur de la chaîne est exactement correcte. Renvoie null.
position ++;
return null;
}
if (nextCodePoint < 0) { //Si nextCodePoint n'est pas défini, utilisez codePointAt pour obtenir le caractère et définir la valeur une seule fois.
nextCodePoint = source.codePointAt(position);
position = source.offsetByCodePoints(position, 1);
}
return nextCodePoint;
}
}
//Classe d'entrée pour passer l'itérateur à l'analyseur
public static class IteratorInput<T> implements Input<T> {
private final Iterator<T> iterator;
private final int position;
private final T current;
public IteratorInput(Iterator<T> iterator_) {iterator = iterator_; position = 0; current = iterator.hasNext() ? iterator.next(): null;}
public IteratorInput(Iterator<T> iterator_, int position_) {iterator = iterator_; position = position_; current = iterator.hasNext() ? iterator.next() : null;}
@Override public T current() {return current;}
@Override public String positionDescription() {return "" + position;}
private IteratorInput<T> next = null; //Conservez le cache car next peut être demandé plusieurs fois en raison de ou.
@Override public Input<T> next() throws EndOfInputException {
if (next != null) return next;
if (iterator.hasNext()) return (next = new IteratorInput<T>(iterator, position + 1)); throw new EndOfInputException();
}
}
//Empilez la liste des points de code Unicode dans une chaîne
public static Parser<Integer, String> concat(Parser<Integer, List<Integer>> parser) {
return apply(reduce(parser, () -> new StringBuilder(), (sb, i) -> sb.appendCodePoint(i)), sb -> sb.toString());
}
public static Parser<Integer, String> concatStr(Parser<Integer, List<String>> parser) {
return apply(reduce(parser, () -> new StringBuilder(), (sb, i) -> sb.append(i)), sb -> sb.toString());
}
//analyseur qui ne transmet qu'un seul caractère contenu dans str
public static Parser<Integer, Integer> consistsOf(String str) {return satisfy(i -> str.indexOf(i) >= 0);}
//analyseur qui consomme la même chaîne que str
public static Parser<Integer, String> word(String str) {
List<Parser<Integer, Integer>> result = new ArrayList<>();
str.chars().forEach(i -> result.add(satisfy(j -> j == i)));
return concat(lst(result));
}
public static String codePointToString(int[] codePoint) {return new String(codePoint, 0, codePoint.length);}
public static String codePointToString(int codePoint) {return codePointToString(new int[] {codePoint});}
//analyseur qui consomme des entrées jusqu'à ce que la même chaîne que str apparaisse
public static Parser<Integer, String> until(String str) {
ParserMemoizer<Integer, String> result = new ParserMemoizer<Integer, String>();
result.defun(() -> or(word(str), apply(seq(satisfy(i -> true) /*Analyseur qui consomme un seul caractère*/ , result), tpl2 -> codePointToString(tpl2.car) + tpl2.cdr.car)));
return result;
}
}
Recommended Posts