/* * EUGDocument.java * * Created on June 26, 2007, 12:01 PM */ package eug.syntax; import eug.parser.TokenScanner; import eug.parser.TokenType; import java.io.IOException; import java.io.InputStream; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.PlainDocument; import javax.swing.text.Segment; /** * * @author Michael Myers */ public class EUGDocument extends PlainDocument { private static final long serialVersionUID = 1L; /** Creates a new instance of EUGDocument */ public EUGDocument() { super(); } public Scanner createScanner() { return new Scanner(); } public int getScannerStart(int p) { Element elem = getDefaultRootElement(); int lineNum = elem.getElementIndex(p); Element line = elem.getElement(lineNum); // AttributeSet a = line.getAttributes(); // while (a.isDefined(CommentAttribute) && lineNum > 0) { // lineNum -= 1; // line = elem.getElement(lineNum); // a = line.getAttributes(); // } return line.getStartOffset(); } @Override protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr) { super.insertUpdate(chng, attr); // // update comment marks // Element root = getDefaultRootElement(); // DocumentEvent.ElementChange ec = chng.getChange(root); // if (ec != null) { // Element[] added = ec.getChildrenAdded(); // boolean inComment = false; // for (int i = 0; i < added.length; i++) { // Element elem = added[i]; // int p0 = elem.getStartOffset(); // int p1 = elem.getEndOffset(); // String s; // try { // s = getText(p0, p1 - p0); // } catch (BadLocationException bl) { // s = null; // } // if (inComment) { // MutableAttributeSet a = (MutableAttributeSet) elem.getAttributes(); // a.addAttribute(CommentAttribute, CommentAttribute); // int index = s.indexOf("*/"); // if (index >= 0) { // // found an end of comment, turn off marks // inComment = false; // } // } else { // // scan for multiline comment // int index = s.indexOf("/*"); // if (index >= 0) { // // found a start of comment, see if it spans lines // index = s.indexOf("*/", index); // if (index < 0) { // // it spans lines // inComment = true; // } // } // } // } // } } @Override protected void removeUpdate(DefaultDocumentEvent chng) { super.removeUpdate(chng); // update comment marks } public final class Scanner { private TokenScanner scanner; private int p0; Scanner() { scanner = new TokenScanner(new DocumentInputStream(0, getLength())); } public void setRange(int start, int end) { scanner.reset(new DocumentInputStream(start, end)); p0 = start; } public int getStartOffset() { return p0 + scanner.getTokenStart(); } public int getEndOffset() { return p0 + scanner.getTokenEnd(); } public void scan() { scanner.nextToken(); } public TokenType lastToken() { return scanner.lastToken(); } public String lastStr() { return scanner.lastStr(); } } private final class DocumentInputStream extends InputStream { private Segment text; // private int start; private int end; private int position; // in document private int index; // in segment private static final int MAX_SEGMENT_SIZE = 1024; DocumentInputStream(int p0, int p1) { text = new Segment(); // start = p0; end = Math.min(getLength(), p1); // to be safe position = p0; loadSegment(); } public int read() throws IOException { if (index >= text.offset + text.count) { // finished this segment if (position >= end) { // finished the stream return -1; } else { // stream isn't finished; get some more loadSegment(); } } return text.array[index++]; } private void loadSegment() { try { int n = Math.min(MAX_SEGMENT_SIZE, end - position); getText(position, n, text); position += n; index = text.offset; } catch (BadLocationException ex) { ex.printStackTrace(); } } } }