package tirateima.gui.highlighting.pascal; /** * Analisador léxico para identificar tokens de pascal. * * @author Luciano */ public class Anlex { /** Buffer de caracteres interno.*/ private Buffer buffer; /**Contantes dos estados do analisador.*/ private static final int EST_COMENT_CHAVE_01 = 1; private static final int EST_COMENT_PAR_01 = 2; private static final int EST_COMENT_PAR_02 = 3; private static final int EST_COMENT_FIM_CH_01 = 4; private static final int EST_COMENT_FIM_PAR_01 = 5; private static final int EST_COMENT_FIM_PAR_02 = 6; private static final int EST_IDENT_01 = 7; private static final int EST_IDENT_02 = 8; private static final int EST_EOLINE_01 = 9; private static final int EST_OTHER_01 = 10; private static final int EST_LITERAL_01 = 11; private static final int EST_LITERAL_02 = 12; private static final int EST_NUM_01 = 13; private static final int EST_NUM_02 = 14; private static final int EST_NUM_03 = 15; private static final int EST_PONT_01 = 20; private static final int EST_EOB_01 = 21; /** * Construtor do analisador léxico. * * @param b Buffer de caracteres a ser utilizado pelo analisador. */ public Anlex(String b){ this.buffer = new Buffer(b); } /** * ALtera o estado de procura em caso de falha. * * Se não for possível encontrar o token procurado no estado atual, * este método redireciona o analisador para o próximo estado de procura. * * @param estado Estado atual do analisador. * * @return Novo estado de procura. */ private int falhar(int estado){ switch(estado){ case EST_COMENT_CHAVE_01: return EST_COMENT_PAR_01; case EST_COMENT_PAR_01: return EST_COMENT_FIM_CH_01; case EST_COMENT_FIM_CH_01: return EST_COMENT_FIM_PAR_01; case EST_COMENT_FIM_PAR_01: return EST_IDENT_01; case EST_IDENT_01: return EST_NUM_01; case EST_NUM_01: case EST_NUM_02: return EST_PONT_01; case EST_PONT_01: return EST_EOLINE_01; case EST_EOLINE_01: return EST_LITERAL_01; case EST_LITERAL_01: return EST_EOB_01; case EST_EOB_01: return EST_OTHER_01; } return 0; } public Token getToken(){ Token temp = new Token(); int estado = EST_COMENT_CHAVE_01; while(true){ int a = getchar(); switch(estado){ case EST_COMENT_CHAVE_01: if(a == '{'){ temp.setId(Token.BEGINCOMMENT_CH); temp.setValor("{"); return temp; } ungetchar(a); estado = falhar(estado); break; case EST_COMENT_PAR_01: if(a == '('){ temp.appendToValor((char) a); estado = EST_COMENT_PAR_02; }else{ ungetchar(a); estado = falhar(estado); } break; case EST_COMENT_PAR_02: if(a == '*'){ temp.setId(Token.BEGINCOMMENT_PAR); temp.setValor("(*"); }else{ ungetchar(a); temp.setId(Token.OTHER); } return temp; case EST_COMENT_FIM_CH_01: if(a == '}'){ temp.setId(Token.ENDCOMMENT_CH); temp.setValor("}"); return temp; } ungetchar(a); estado = falhar(estado); break; case EST_COMENT_FIM_PAR_01: if(a == '*'){ temp.appendToValor((char) a); estado = EST_COMENT_FIM_PAR_02; }else{ ungetchar(a); estado = falhar(estado); } break; case EST_COMENT_FIM_PAR_02: if(a == ')'){ temp.setId(Token.ENDCOMMENT_PAR); temp.setValor("*)"); }else{ ungetchar(a); temp.setId(Token.OTHER); } return temp; case EST_IDENT_01: if((Character.isLetter(a))||(a == '_')){ temp.appendToValor((char) a); estado = EST_IDENT_02; }else{ ungetchar(a); estado = falhar(estado); } break; case EST_IDENT_02: if((Character.isLetterOrDigit(a)) || (a == '_')){ temp.appendToValor((char) a); }else{ ungetchar(a); temp.setId(Token.IDENTIFIER); return temp; } break; case EST_NUM_01: if(Character.isDigit(a)){ do{ temp.appendToValor((char) a); a = getchar(); }while(Character.isDigit(a)); if((a == '.')){ estado = EST_NUM_02; }else if((a == 'e')||(a == 'E')){ estado = EST_NUM_03; }else{ ungetchar(a); temp.setId(Token.NUM); return temp; } }else if(a == '.'){ estado = EST_NUM_02; }else{ ungetchar(a); estado = falhar(estado); } break; case EST_NUM_02: if(Character.isDigit(a)){ temp.appendToValor('.'); do{ temp.appendToValor((char) a); a = getchar(); }while(Character.isDigit(a)); if((a == 'e')||(a == 'E')){ estado = EST_NUM_03; }else{ ungetchar(a); temp.setId(Token.NUM); return temp; } } else { ungetchar(a); ungetchar('.'); if(temp.getValor().length() > 0){ temp.setId(Token.NUM); return temp; }else{ estado = falhar(estado); } } break; case EST_NUM_03: if(Character.isDigit(a)){ do{ temp.appendToValor((char) a); a = getchar(); }while(Character.isDigit(a)); ungetchar(a); temp.setId(Token.NUM); return temp; }else if((a == '-')||(a == '+')){ a = getchar(); if(Character.isDigit(a)){ do{ temp.appendToValor((char) a); a = getchar(); }while(Character.isDigit(a)); ungetchar(a); temp.setId(Token.NUM); return temp; }else{ ungetchar(a); ungetchar('+'); ungetchar('e'); temp.setId(Token.NUM); return temp; } }else{ ungetchar(a); ungetchar('e'); temp.setId(Token.NUM); return temp; } case EST_PONT_01: switch(a){ case '.': temp.appendToValor('.'); a = getchar(); if (a != '.') { ungetchar(a); } else { temp.appendToValor('.'); } temp.setId(Token.PONT); return temp; case ':': case ';': case ',': case '[': case ']': temp.appendToValor((char) a); temp.setId(Token.PONT); return temp; default: ungetchar(a); estado = falhar(estado); } break; case EST_EOLINE_01: if(a == '\n'){ temp.setId(Token.EOLINE); temp.setValor("\n"); return temp; } ungetchar(a); estado = falhar(estado); break; case EST_LITERAL_01: if(a == '\''){ temp.appendToValor((char) a); estado = EST_LITERAL_02; }else{ ungetchar(a); estado = falhar(estado); } break; case EST_LITERAL_02: if(a == '\''){ temp.appendToValor((char) a); temp.setId(Token.STRING); return temp; }else if(a == '\n'){ ungetchar(a); temp.setId(Token.STRING); return temp; }else{ temp.appendToValor((char) a); } break; case EST_EOB_01: if(a == -1){ return new Token(Token.EOB, new String("")); }else{ ungetchar(a); estado = falhar(estado); } break; default: temp.appendToValor((char) a); temp.setId(Token.OTHER); return temp; } } } private int getchar(){ return buffer.getchar(); } private void ungetchar(int a){ buffer.ungetchar(); } }