/*
* 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;
}
}
}