diff --git a/compiler/Lexer.scala b/compiler/Lexer.scala index 6491a3b43274c0eec76f70349af870da177cc44d..84851b5039b442085de47d2f4158ab536b74b649 100755 --- a/compiler/Lexer.scala +++ b/compiler/Lexer.scala @@ -1,75 +1,32 @@ -#!/usr/bin/scala -!# -println("started...") -case class Token(val value:String, val func:String) -// Conjuntos -val palavrasReservadas = List("begin", "end", "function", "procedure", "var", "program") -val letras = List.concat('a' to 'z','A' to 'Z',"_") -val numeros = ('0' to '9').toList -val separadores = List(' ','\t','\n',';') - -//Funcoes booleanas -val num = (c:Char) => numeros.contains(c) -val op = (c:Char) => "+-*/=:".contains(c) -val letra = (c:Char) => letras.contains(c) -val espacoLinTab = (c:Char) => c==' ' || c=='\t' || c=='\n' -val separador = (c:Char) => separadores.contains(c) -val palavraReservada = (s:String) => palavrasReservadas.contains(s) - -//Verificadores -def verificaIdentificador(str:String) = if ( str.exists{(c) => !(num(c) || letra(c)) } ) erro(str+" nao eh identificador valido") -def verificaNumero(str:String) = if ( str.exists{(c) => !num(c)} ) erro(str+" nao eh numero") - -//Acoes -val erro = (msg:String) => {println("Erro: "+msg); sys.exit(1)} - - -def take(iter:BufferedIterator[Char]) = { - var acc="" - while (iter.hasNext && ! separador(iter.head) && ! op(iter.head)) - acc += iter.next - acc -} - -def atomo(str:String):List[Token] = { - var tokenList = List[Token]() - val iter = str.iterator.buffered - while (iter.hasNext) { - val c = iter.next - tokenList = (c match { - case c if num(c) => //NUMERO - val acc = c + take(iter) - verificaNumero(acc) - Token(acc,"numero") - - case c if op(c) => //OPERADOR - if ((c==':') && (iter.head == '=')) - Token(c+""+iter.next, "op") - else - Token(c+"", "op") - - case c if letra(c) => //IDENTIFICADOR - val acc = c + take(iter) - verificaIdentificador(acc) - if (palavraReservada(acc)) - Token(acc,"reservado") - else - Token(acc, "identificador") - - case c if espacoLinTab(c) => /*pula*/ - iter.dropWhile(espacoLinTab) - null;// continue - case c if c == ';' => - Token(";", "pontoevirgula") - case erroCh => erro(erroCh+"")//TODO:which line error occurred? - }) :: tokenList +package lexer + +import scala.annotation.tailrec + +case class Token(val valor: String, val func: String) + +class Lexer { + val h = new LexerHelper + + @tailrec + final def getTokens(input: List[Char], acc:List[Token] = Nil): List[Token] = input match { + case letra :: _ if h.ehLetra(letra) => + val token = h.casoLetra(input) + getTokens(input.drop(token.valor.size), token :: acc) + case op :: _ if h.ehOp(op) => + val token = h.casoOp(input) + getTokens(input.drop(token.valor.size), token :: acc) + case escape :: _ if h.ehEspacoLinTab(escape) => + getTokens( input.dropWhile{h.ehEspacoLinTab}, acc ) +// case comment :: rest if comment=="(" && rest.head == "*" => + //treat Comment + case other :: _ if "(),;.".contains(other) => + val token = Token(""+other, "controle") + getTokens(input.tail, token :: acc) + case Nil => + acc.reverse + case _ => + println("EMPTY? "+input.head.toInt + '\n'.toInt) + sys.exit() } - tokenList = tokenList.filterNot(_==null).reverse - println(tokenList) - tokenList -} - - -while (true) - atomo(readLine) +} \ No newline at end of file