I am making a custom language as a project for a class called Compilers. The whole project is in Java, using JFlex as my lexical analyzer, and Cup as my syntactic analyzer.
I created a simple text editor for the language, which basically consists of a JTextPane, where the user can type the custom code that will be parsed. This JTextPane has a DefaultStyledDocument, used to set character attributes, e.g. change the color for keywords, comments, strings, numbers, etc., for the code (text) inside the JTextPane.
Here is the code I am using:
DefaultStyledDocument doc = new DefaultStyledDocument() {
@Override
public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { //cuando se insertan caracteres.
super.insertString(offset, str, a);
String text = getText(0, getLength());
syntax = new SyntaxHighlighter(new java.io.StringReader(text));
Token val;
try {
while ((val = syntax.yylex()) != null) {
switch (val.type) {
case TokenType.KEYWORD:
setCharacterAttributes(val.start, val.length, keyword, true);
break;
case TokenType.COMMENT:
setCharacterAttributes(val.start, val.length, comment, true);
break;
case TokenType.STRING:
setCharacterAttributes(val.start, val.length, string, true);
break;
case TokenType.FUNCTION:
setCharacterAttributes(val.start, val.length, function, true);
break;
case TokenType.NUMBER:
setCharacterAttributes(val.start, val.length, plain, true);
break;
case TokenType.OPERATOR:
setCharacterAttributes(val.start, val.length, operator, true);
break;
case TokenType.READ:
setCharacterAttributes(val.start, val.length, number, true);
break;
default:
setCharacterAttributes(val.start, val.length, plain, true);
break;
}
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(rootPane, "Oops! Exception triggered\n" + ex.getMessage());
}
}
@Override
//this is the method I want to optimize
public void remove(int offs, int len) throws BadLocationException {
super.remove(offs, len);
String text = getText(0, getLength());
syntax = new SyntaxHighlighter(new java.io.StringReader(text));
Token val;
try {
while ((val = syntax.yylex()) != null) {
switch (val.type) {
case TokenType.KEYWORD:
setCharacterAttributes(val.start, val.length, keyword, true);
break;
case TokenType.COMMENT:
setCharacterAttributes(val.start, val.length, comment, true);
break;
case TokenType.STRING:
setCharacterAttributes(val.start, val.length, string, true);
break;
case TokenType.FUNCTION:
setCharacterAttributes(val.start, val.length, function, true);
break;
case TokenType.NUMBER:
setCharacterAttributes(val.start, val.length, plain, true);
break;
case TokenType.OPERATOR:
setCharacterAttributes(val.start, val.length, operator, true);
break;
case TokenType.READ:
setCharacterAttributes(val.start, val.length, number, true);
break;
default:
setCharacterAttributes(val.start, val.length, plain, true);
break;
}
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(rootPane, "Oops! Exception triggered\n" + ex.getMessage());
}
}
};
this.codeTextPane.setStyledDocument(doc);
The SyntaxHighlighter class is basically a lexer (made with JFlex) used only as a way to search specific pieces of text (keywords, strings, etc). Everything works perfectly, but...
The problem:
When the JTextPane has a decent amount of text in it, holding down the backspace key to remove text makes the program lag pretty hard. The reason I think this happens is probably because the SyntaxHighlighter runs with every character being removed, because holding down the backspace key calls the remove() function for each character being deleted. Inserting text is not a problem really because you can either load the code from a file (where the whole text in that file will be analyzed by the SyntaxHighlighter as a whole), or you just can't type fast enough to notice the lag.
Is there a way I can optimize this? Thank you all!