/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package ca.weblite.netbeans.mirah.lexer; import java.util.logging.Logger; import mirah.impl.MirahLexer.Input; import mirah.impl.MirahParser; import mirah.impl.Tokens; import org.netbeans.api.lexer.Token; import org.netbeans.spi.lexer.Lexer; import org.netbeans.spi.lexer.LexerInput; import org.netbeans.spi.lexer.LexerRestartInfo; /** * * @author shannah */ public class MirahLexer implements Lexer<MirahTokenId>{ private Object state; private mirah.impl.MirahLexer lexer; private LexerRestartInfo<MirahTokenId> info; private int lastPos = 0; private MirahParser parser; private boolean inClassDeclaration = false; private boolean inMethodDeclaration = false; private boolean inTypeHint = false; private int lastToken = -1; private int lastNonWhiteToken = -1; //private MirahLexerInput input; private static final Logger LOG = Logger.getLogger(MirahLexer.class.getCanonicalName()); private org.mirah.mmeta.BaseParser.Token<mirah.impl.Tokens> tok = null; /* public static class MirahLexerInput implements Input { private int pos = 0; private final LexerInput input; private boolean eof = false; public MirahLexerInput(LexerInput input) { this.input = input; } @Override public int pos() { return pos; } @Override public int read() { if ( eof ){ return -1; } int out = input.read(); eof = out == -1; if ( !eof ) pos++; return out; } @Override public boolean consume(char c) { if (read() == c) { return true; } backup(1); return false; } @Override public boolean consume(String s) { int len = s.length(); for (int i = 0; i < len; i++) { int c = read(); if (s.charAt(i) != (char) c) { if ( c == -1 ){ i--; } backup(i+1); return false; } } return true; } @Override public void backup(int amount) { input.backup(amount); pos -= amount; if ( amount > 0 ){ eof = false; } if (pos < 0) { pos = 0; } } @Override public void skip(int amount) { if ( !eof ){ for (int i = 0; i < amount; i++) { if (read() == -1) { eof = false; return; } } } } @Override public boolean hasNext() { System.out.println("Has next "); return !eof; } @Override public void consumeLine() { if ( !eof ){ System.out.println("In consumeLine"); int c; while ((c = read()) != -1) { if (((char) c) == '\n') { eof = false; return; } } System.out.println("No newline found"); } } @Override public int peek() { if ( eof ){ return -1; } else { int result = read(); backup(1); return result; } } @Override public int finishCodepoint() { backup(1); char c1 = (char) read(); int size = 1; int i2; if ((i2 = read()) != -1) { size++; } if (size == 1) { return String.valueOf(c1).codePointAt(0); } else { return String.valueOf(new char[]{c1, (char) i2}).codePointAt(0); } } @Override public CharSequence readBack(int length) { //System.out.println("readBack"); int p = pos; backup(length); int newP = pos; StringBuilder sb = new StringBuilder(); for (int i = newP; i < p; i++) { sb.append((char) read()); } return sb.toString(); } } */ MirahLexer (LexerRestartInfo<MirahTokenId> info, MirahParser parser) { this.info = info; this.parser = parser; //this.input = new MirahLexerInput(info.input()); //this.lexer = new mirah.impl.MirahLexer(this.input); this.lexer = null; } /* @Override public Token<MirahTokenId> nextToken() { System.out.println("In nextToken()"); int start = input.pos(); Tokens tokType = lexer.simpleLex(); if ( tokType.ordinal() == Tokens.tEOF.ordinal()){ System.out.println("EOF"); return null; } int end = input.pos(); int len = end-start; if ( len < 0 ){ System.out.println("Negative len at "+start+":"+end); } int ordinal = tokType.ordinal(); if ( inClassDeclaration && ordinal == Tokens.tCONSTANT.ordinal()){ inClassDeclaration = false; ordinal = MirahLanguageHierarchy.CLASS_DECLARATION; } else if ( ordinal == Tokens.tClass.ordinal() || ordinal == Tokens.tInterface.ordinal() ){ inClassDeclaration = true; } else if ( inMethodDeclaration && ordinal == Tokens.tIDENTIFIER.ordinal()){ inMethodDeclaration = false; ordinal = MirahLanguageHierarchy.METHOD_DECLARATION; } else if ( ordinal == Tokens.tDef.ordinal() ){ inMethodDeclaration = true; } if ( inTypeHint && (ordinal == Tokens.tCONSTANT.ordinal() || Tokens.tIDENTIFIER.ordinal() == ordinal) ){ inTypeHint = false; ordinal = MirahLanguageHierarchy.TYPE_HINT; } else if ( ordinal == Tokens.tColon.ordinal() && (lastNonWhiteToken == Tokens.tIDENTIFIER.ordinal() || lastNonWhiteToken == Tokens.tRParen.ordinal()) ){ inTypeHint = true; } MirahTokenId tokid = MirahLanguageHierarchy.getToken(ordinal); //int len = tok.endpos-tok.startpos; //lastPos = end; lastToken = tokType.ordinal(); if ( tokType.ordinal() < Tokens.tEOF.ordinal() ){ lastNonWhiteToken = tokType.ordinal(); } //if ( tokid == null ){ // System.out.println("Token id is null"); // System.out.println(tokType.name()); //} //if ( tokType == null ){ // System.out.println("Toktype is null"); //} //System.out.println("TOken "+tokType.name()+" tokid ordinal "+tokid); System.out.println("Exiting nextToken "+tokid.name()+" len "+len); if ( tokType.ordinal() == Tokens.tPartialComment.ordinal() ){ state = new Integer(-1); //len--; //input.backup(1); } else { state = null; } Token<MirahTokenId> out = info.tokenFactory().createToken(tokid,len); if ( out == null ){ System.out.println("It is a null token"); return out; } else { return out; } } */ @Override public org.netbeans.api.lexer.Token<MirahTokenId> nextToken () { if ( this.lexer == null ){ int c; StringBuilder sb = new StringBuilder(); while ( true ){ c = info.input().read(); if ( c == -1 ){ break; } else { sb.append((char)c); } } String str = sb.toString(); //System.out.println("Str is: "+str); lastPos = 0; //strLen = str.length(); lexer = new mirah.impl.MirahLexer(str, str.toCharArray(), parser); } boolean alreadyStarted = true; if ( tok == null ){ alreadyStarted = false; try { tok = lexer.lex(lastPos, false); } catch ( Exception npe ){ //npe.printStackTrace(); int len = 1; lastPos++; return info.tokenFactory().createToken(MirahLanguageHierarchy.getToken(Tokens.tWhitespace.ordinal()), len); } } if ( Tokens.tEOF.ordinal() == tok.type.ordinal()){ lexer = null; tok = null; return null; } if ( alreadyStarted || tok.startpos == tok.pos ){ int ordinal = tok.type.ordinal(); if ( inClassDeclaration && ordinal == Tokens.tCONSTANT.ordinal()){ inClassDeclaration = false; ordinal = MirahLanguageHierarchy.CLASS_DECLARATION; } else if ( ordinal == Tokens.tClass.ordinal() || ordinal == Tokens.tInterface.ordinal() ){ inClassDeclaration = true; } else if ( inMethodDeclaration && ordinal == Tokens.tIDENTIFIER.ordinal()){ inMethodDeclaration = false; ordinal = MirahLanguageHierarchy.METHOD_DECLARATION; } else if ( ordinal == Tokens.tDef.ordinal() ){ inMethodDeclaration = true; } if ( inTypeHint && (ordinal == Tokens.tCONSTANT.ordinal() || Tokens.tIDENTIFIER.ordinal() == ordinal) ){ inTypeHint = false; ordinal = MirahLanguageHierarchy.TYPE_HINT; } else if ( ordinal == Tokens.tColon.ordinal() && (lastNonWhiteToken == Tokens.tIDENTIFIER.ordinal() || lastNonWhiteToken == Tokens.tRParen.ordinal()) ){ inTypeHint = true; } MirahTokenId tokid = MirahLanguageHierarchy.getToken(ordinal); int len = tok.endpos-tok.startpos; lastPos = tok.endpos; lastToken = tok.type.ordinal(); if ( tok.type.ordinal() < Tokens.tEOF.ordinal() ){ lastNonWhiteToken = tok.type.ordinal(); } tok = null; //if ( lastPos == strLen ){ // len--; //} return info.tokenFactory().createToken(tokid,len); } else { int len = tok.startpos-tok.pos; lastPos = tok.startpos; return info.tokenFactory().createToken(MirahLanguageHierarchy.getToken(Tokens.tComment.ordinal()), len); } } public void release () { } @Override public Object state() { return state; } }