/* * SimpleEditorDocument.java * * Created on 23 novembre 2006, 17:03 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package simpleeditor; import antlr.LexerSharedInputState; import antlr.Token; import antlr.TokenStreamException; import com.sun.java_cup.internal.runtime.Scanner; import simpleeditor.lexer.JavaLexer; import java.io.IOException; import java.io.InputStream; import javax.swing.event.DocumentEvent; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.GapContent; import javax.swing.text.PlainDocument; import javax.swing.text.Segment; /** * * @author YVZOU */ public class SimpleEditorDocument extends PlainDocument { /** Creates a new instance of SimpleEditorDocument */ public SimpleEditorDocument() { super(new GapContent(1024)); } public SimpleEditorLexer createLexer() { try { return new SimpleEditorLexer(); } catch (IOException ex) { return null; } } public int getScannerStart(int p) { Element elem = getDefaultRootElement(); int lineNum = elem.getElementIndex(p); Element line = elem.getElement(lineNum); return line.getStartOffset(); } /** * Updates document structure as a result of text insertion. This * will happen within a write lock. The superclass behavior of * updating the line map is executed followed by marking any comment * areas that should backtracked before scanning. * * @param chng the change event * @param attr the set of attributes */ 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; } } } } /** * Updates any document structure as a result of text removal. * This will happen within a write lock. The superclass behavior of * updating the line map is executed followed by placing a lexical * update command on the analyzer queue. * * @param chng the change event */ protected void removeUpdate(DefaultDocumentEvent chng) { super.removeUpdate(chng); } class DocumentInputStream extends InputStream { Segment segment; int p0; // start position int p1; // end position int pos; // pos in document int index; // index into array of the segment public DocumentInputStream(int p0, int p1) { this.segment = new Segment(); this.p0 = p0; this.p1 = Math.min(getLength(), p1); pos = p0; try { loadSegment(); } catch (IOException ioe) { throw new Error("unexpected: " + ioe); } } /** * Reads the next byte of data from this input stream. The value * byte is returned as an int in the range * 0 to 255. If no byte is available * because the end of the stream has been reached, the value * -1 is returned. This method blocks until input data * is available, the end of the stream is detected, or an exception * is thrown. *

* A subclass must provide an implementation of this method. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. * @since JDK1.0 */ public int read() throws IOException { if (index >= (segment.offset + segment.count)) { if (pos >= p1) { // no more data return -1; } loadSegment(); } return segment.array[index++]; } void loadSegment() throws IOException { try { int n = Math.min(1024, p1 - pos); getText(pos, n, segment); pos += n; index = segment.offset; } catch (BadLocationException e) { throw new IOException("Bad location"); } } int getPosition() { return pos; } } public class SimpleEditorLexer { private JavaLexer lexer; private DocumentInputStream is; Token t; int p0; SimpleEditorLexer() throws IOException { is = new DocumentInputStream(0, getLength()); lexer = new JavaLexer(is); } /** * Sets the range of the scanner. This should be called * to reinitialize the scanner to the desired range of * coverage. */ public void setRange(int p0, int p1) throws IOException { is = new DocumentInputStream(p0, p1); lexer = new JavaLexer(is); this.p0 = p0; } /** * This fetches the starting location of the current * token in the document. */ public final int getStartOffset() { int begOffs = 0;//(int) (is.getPosition()); return p0 + begOffs; } /** * This fetches the ending location of the current * token in the document. */ public final int getEndOffset() { int endOffs = (int) (is.getPosition()); int end = p0 + endOffs; System.out.println("end:" + end); return end; } void scan() { try { // System.out.println("Lexer valide " + (lexer!=null)); t = lexer.nextToken(); } catch (TokenStreamException ex) { return; } } Token getCurrentToken() { return t; } } }