All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.vergne.parsing.layer.impl.Suite Maven / Gradle / Ivy

There is a newer version: 3.2
Show newest version
package fr.vergne.parsing.layer.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fr.vergne.parsing.layer.Layer;
import fr.vergne.parsing.layer.exception.ParsingException;

/**
 * A {@link Suite} is a {@link Layer} representing an ordered sequence of
 * elements. This is particularly suited for structure templates like in
 * C/C++/Java/...:
 * 
    *
  1. "if ("
  2. *
  3. condition
  4. *
  5. ") {"
  6. *
  7. block
  8. *
  9. "}"
  10. *
* or in HTML: *
    *
  1. "<a href='"
  2. *
  3. url
  4. *
  5. "'>"
  6. *
  7. content
  8. *
  9. "</a>"
  10. *
* At a higher level, it also fits global structures like the architecture of a * scientific paper for instance: *
    *
  1. title
  2. *
  3. authors
  4. *
  5. abstract
  6. *
  7. introduction
  8. *
  9. problem
  10. *
  11. solution
  12. *
  13. discussion
  14. *
  15. conclusion
  16. *
* * @author Matthieu Vergne * */ public class Suite extends AbstractLayer { private final List sequence; public Suite(List sequence) { this.sequence = Collections.unmodifiableList(sequence); } public Suite(Layer... sequence) { this(Arrays.asList(sequence)); } @Override protected String buildRegex() { String regex = ""; for (Layer layer : sequence) { regex += "(?:" + layer.getRegex() + ")"; } return regex; } @Override public String getContent() { String content = ""; for (Layer layer : sequence) { content += layer.getContent(); } return content; } @Override protected void setInternalContent(String content) { Matcher matcher = Pattern.compile( "^" + buildCapturingRegex(sequence) + "$").matcher(content); if (matcher.find()) { int delta = 0; for (int i = 1; i <= matcher.groupCount(); i++) { String match = matcher.group(i); int subStart = delta; int subEnd = subStart + match.length(); sequence.get(i - 1).setContent( content.substring(subStart, subEnd)); delta += match.length(); } } else { LinkedList preOk = new LinkedList(sequence); LinkedList postKo = new LinkedList(); do { postKo.addFirst(preOk.removeLast()); String regex = buildCapturingRegex(preOk); matcher = Pattern.compile("^" + regex).matcher(content); } while (!matcher.find()); List fakeSequence = new LinkedList(preOk); Formula remaining = new Formula("[\\s\\S]*"); fakeSequence.add(remaining); new Suite(fakeSequence).setContent(content); String incompatible = remaining.getContent(); try { postKo.getFirst().setContent(incompatible); } catch (ParsingException e) { throw new ParsingException(this, postKo.getFirst(), content, content.length() - incompatible.length(), content.length(), e); } throw new IllegalStateException( "No exception thrown while it should not be parsable."); } } private String buildCapturingRegex(List sequence) { String regex; regex = ""; for (Layer layer : sequence) { regex += "(" + layer.getRegex() + ")"; } return regex; } @Override public String toString() { List suite = new LinkedList(); for (Layer layer : sequence) { suite.add(layer.getClass().getSimpleName()); } return getClass().getSimpleName() + suite; } @SuppressWarnings("unchecked") public CLayer get(int index) { return (CLayer) sequence.get(index); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy