Skip to content

Instantly share code, notes, and snippets.

@juzna
Created January 25, 2012 20:30
Show Gist options
  • Save juzna/1678538 to your computer and use it in GitHub Desktop.
Save juzna/1678538 to your computer and use it in GitHub Desktop.
2-layer lexer for IDEA
package cz.juzna.latte.lexer;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.LookAheadLexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
/**
* Uses base-lexer to get big chunks, and several of them (typesToLex) are then lexed into smaller tokens using sub-lexer.
*
* Useful in some templating languages, where you lex-out whole chunks of your language, which is then lexed by another lexer.
*
* @author Jan Dolecek <juzna.cz@gmail.com>
* @see http://devnet.jetbrains.net/message/5450157
*/
public class LayeredLexer extends LookAheadLexer {
protected Lexer subLexer;
protected TokenSet typesToLex;
/**
* @param baseLexer Lexer which creates big chunks
* @param subLexer Lexer which is applied to chunks from previous lexer
* @param typesToLex Only these chunks from base-lexer are processed
*/
public LayeredLexer(Lexer baseLexer, Lexer subLexer, TokenSet typesToLex) {
super(baseLexer);
this.subLexer = subLexer;
this.typesToLex = typesToLex;
}
@Override
protected void lookAhead(Lexer baseLexer) {
if(typesToLex.contains(baseLexer.getTokenType())) {
// Parse all sub tokens
IElementType subToken;
subLexer.start(baseLexer.getBufferSequence(), baseLexer.getTokenStart(), baseLexer.getTokenEnd());
while((subToken = subLexer.getTokenType()) != null) {
addToken(subLexer.getTokenEnd(), subToken);
subLexer.advance();
}
baseLexer.advance();
} else {
addToken(baseLexer.getTokenType());
baseLexer.advance();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment