/* obtiene el siguiente token * a ser usado por el parser. */ public static Token Next() { //zzz // intenta formar un token de la entrada //linea=1, col=13 y apunta al blanco while ((ch == ' ') || (ch == LF) || (ch == CR)) // bloque que saltea los blancos { NextCh(); }; if (ch == EOF) return new Token(Token.EOF, line, col); Token t = new Token(line, col); //if ('A' <= ch && 'z' >= ch) System.Console.WriteLine(ch + " es letra "); //if ('0' <= ch && '9' >= ch) System.Console.WriteLine(ch + " es nro "); if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) //es Letra ReadName(t); else if ('0' <= ch && '9' >= ch) ReadNumber(t); else switch (ch){ // ----------------------- //| tokens simples | // ----------------------- case ';': t.kind = Token.SEMICOLON; t.str = ch.ToString(); NextCh(); break; case ',': t.str = ","; t.str = ch.ToString(); t.kind = Token.COMMA; NextCh(); break; case '.': t.kind = Token.PERIOD; t.str = ch.ToString(); NextCh(); break; case '*': t.kind = Token.TIMES; t.str = ch.ToString(); NextCh(); break; case '%': t.kind = Token.REM; t.str = ch.ToString(); NextCh(); break; case '(': t.kind = Token.LPAR; t.str = ch.ToString(); NextCh(); break; case ')': t.kind = Token.RPAR; t.str = ch.ToString(); NextCh(); break; case '[': t.kind = Token.LBRACK; t.str = ch.ToString(); NextCh(); break; case ']': t.kind = Token.RBRACK; t.str = ch.ToString(); NextCh(); break; case '{': t.kind = Token.LBRACE; t.str = ch.ToString(); NextCh(); break; case '}': t.kind = Token.RBRACE; t.str = ch.ToString(); NextCh(); break; case EOF: t.kind = Token.EOF; break; // ----------------------- //| tokens compuestos | // ----------------------- case '=':NextCh(); if (ch == '=') { NextCh(); t.kind = Token.EQ; t.str = "=="; } else { t.kind = Token.ASSIGN; t.str = "="; } break; case '!': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.NE; t.str = "!="; } else { t.kind = Token.NONE; //debe reportar error System.Console.WriteLine("Error:"+ch + " por el default despues del NextCh"); }; break; case '+': NextCh(); if (ch == '+'){ NextCh(); t.kind = Token.PPLUS; //detecta ++ t.str = "++"; } else t.kind = Token.PLUS; t.str = ch.ToString(); break; case '-': NextCh(); if (ch == '-') { NextCh(); t.kind = Token.MMINUS; //detecta -- t.str = "--"; } else { t.kind = Token.MINUS; t.str = ch.ToString(); } break; case '&': NextCh(); if (ch == '&') { NextCh(); t.kind = Token.AND; t.str = "&&"; } else t.kind = Token.NONE; break; case '|': NextCh(); if (ch == '|') { NextCh(); t.kind = Token.OR; t.str = "||"; } else t.kind = Token.NONE; break; case '>': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.GE; t.str = ">="; } else { t.kind = Token.GT; t.str = ">"; } break; case '<': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.LE; t.str = "<="; } else { NextCh(); t.kind = Token.LT; t.str = "<"; } break; case '\"': NextCh(); t.kind = Token.COMILLADOBLE; t.str = "comilla doble"; break; // -------------------- // | CONSTANTE CARACTER // -------------------- case '\'': NextCh(); // ' (comilla) if (ch == '\\') //=> '\ (se prepara para '\n','\r','\\') { t.val=0; NextCh(); switch (ch) { case 'n': t.val = '\n'; // idem a t.val = 10; // NextCh(); break; case 'r': t.val = '\r'; NextCh(); break; case '\'': t.val = '\\'; break; default: t.val = 0; // caracter escape no válido break; // solo 3 cosas pueden venir despues de '\ } } else //(comilla sola) (y char sig en ch) { Console.WriteLine("HA leido una comilla y el ch sig. es "+ch); //Console.ReadKey(); int inicio = 32; int fin = 126; //por ej 'c //seria '' if (((ch >= inicio) && (ch <= fin)) || (ch == '\'')) { t.val = ch;//si ch es una c => t.val = 99 t.str = ch.ToString(); System.Console.WriteLine("caracter:"+ch); } else t.val = 0; // caracter no válido NextCh(); //pasa al 3º char del token.str => ch debiera ser ' (o sea 'c') } if (ch != '\'') //si el 3º char no es comilla => error t.val = 0; // falta el caracter de fin de constante char else {NextCh(); //deja ch en el proximo char (por ej en blanco) //System.Console.WriteLine("reconoció el CHARCONST"); } t.kind = Token.CHARCONST; //era por ej un 'a' break; // ----------------------- //| comentarios | // ----------------------- case '/': NextCh(); if (ch == '*') { Form1.iniCommLine = line; Form1.iniCommCol = col; Pila aux = new Pila(50); aux.push("comentario"); //Boolean bandera = false; //while ((ch != EOF) && (!bandera)) while ((ch != EOF) && (!aux.estaVacia())) { NextCh(); if (ch == '*') { NextCh(); if ((ch == '/') && (!aux.estaVacia())) { Form1.finCommLin = line; Form1.finCommCol = col; aux.pop(); if (aux.estaVacia()) { //bandera = true; NextCh(); t = Next(); } } } else { if (ch == '/') { NextCh(); if (ch == '*') aux.push("comentario"); } } } } else { t.kind = Token.SLASH; } break; default: { t.str = ch.ToString(); //t.line = line; t.col = col; throw new ErrorMio(line, col, 1, "caracter " + ch.ToString() + " invalido"); } } return t; }
/* obtiene el siguiente token * a ser usado por el parser. */ public static Token Next() //zzz // intenta formar un token de la entrada //linea=1, col=13 y apunta al blanco { while ((ch == ' ') || (ch == LF) || (ch == CR)) // bloque que saltea los blancos { NextCh(); } ; if (ch == EOF) { return(new Token(Token.EOF, line, col)); } Token t = new Token(line, col); //if ('A' <= ch && 'z' >= ch) System.Console.WriteLine(ch + " es letra "); //if ('0' <= ch && '9' >= ch) System.Console.WriteLine(ch + " es nro "); if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) //es Letra { ReadName(t); } else if ('0' <= ch && '9' >= ch) { ReadNumber(t); } else { switch (ch) { // ----------------------- //| tokens simples | // ----------------------- case ';': t.kind = Token.SEMICOLON; t.str = ch.ToString(); NextCh(); break; case ',': t.str = ","; t.str = ch.ToString(); t.kind = Token.COMMA; NextCh(); break; case '.': t.kind = Token.PERIOD; t.str = ch.ToString(); NextCh(); break; case '*': t.kind = Token.TIMES; t.str = ch.ToString(); NextCh(); break; case '%': t.kind = Token.REM; t.str = ch.ToString(); NextCh(); break; case '(': t.kind = Token.LPAR; t.str = ch.ToString(); NextCh(); break; case ')': t.kind = Token.RPAR; t.str = ch.ToString(); NextCh(); break; case '[': t.kind = Token.LBRACK; t.str = ch.ToString(); NextCh(); break; case ']': t.kind = Token.RBRACK; t.str = ch.ToString(); NextCh(); break; case '{': t.kind = Token.LBRACE; t.str = ch.ToString(); NextCh(); break; case '}': t.kind = Token.RBRACE; t.str = ch.ToString(); NextCh(); break; case EOF: t.kind = Token.EOF; break; // ----------------------- //| tokens compuestos | // ----------------------- case '=': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.EQ; t.str = "=="; } else { t.kind = Token.ASSIGN; t.str = "="; } break; case '!': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.NE; t.str = "!="; } else { t.kind = Token.NONE; //debe reportar error System.Console.WriteLine("Error:" + ch + " por el default despues del NextCh"); }; break; case '+': NextCh(); if (ch == '+') { NextCh(); t.kind = Token.PPLUS; //detecta ++ t.str = "++"; } else { t.kind = Token.PLUS; } t.str = ch.ToString(); break; case '-': NextCh(); if (ch == '-') { NextCh(); t.kind = Token.MMINUS; //detecta -- t.str = "--"; } else { t.kind = Token.MINUS; t.str = ch.ToString(); } break; case '&': NextCh(); if (ch == '&') { NextCh(); t.kind = Token.AND; t.str = "&&"; } else { t.kind = Token.NONE; } break; case '|': NextCh(); if (ch == '|') { NextCh(); t.kind = Token.OR; t.str = "||"; } else { t.kind = Token.NONE; } break; case '>': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.GE; t.str = ">="; } else { t.kind = Token.GT; t.str = ">"; } break; case '<': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.LE; t.str = "<="; } else { NextCh(); t.kind = Token.LT; t.str = "<"; } break; case '\"': NextCh(); t.kind = Token.COMILLADOBLE; t.str = "comilla doble"; break; // -------------------- // | CONSTANTE CARACTER // -------------------- case '\'': NextCh(); // ' (comilla) if (ch == '\\') //=> '\ (se prepara para '\n','\r','\\') { t.val = 0; NextCh(); switch (ch) { case 'n': t.val = '\n'; // idem a t.val = 10; // NextCh(); break; case 'r': t.val = '\r'; NextCh(); break; case '\'': t.val = '\\'; break; default: t.val = 0; // caracter escape no válido break; // solo 3 cosas pueden venir despues de '\ } } else //(comilla sola) (y char sig en ch) { Console.WriteLine("HA leido una comilla y el ch sig. es " + ch); //Console.ReadKey(); int inicio = 32; int fin = 126; //por ej 'c //seria '' if (((ch >= inicio) && (ch <= fin)) || (ch == '\'')) { t.val = ch; //si ch es una c => t.val = 99 t.str = ch.ToString(); System.Console.WriteLine("caracter:" + ch); } else { t.val = 0; // caracter no válido } NextCh(); //pasa al 3º char del token.str => ch debiera ser ' (o sea 'c') } if (ch != '\'') //si el 3º char no es comilla => error { t.val = 0; // falta el caracter de fin de constante char } else { NextCh(); //deja ch en el proximo char (por ej en blanco) //System.Console.WriteLine("reconoció el CHARCONST"); } t.kind = Token.CHARCONST; //era por ej un 'a' break; // ----------------------- //| comentarios | // ----------------------- case '/': NextCh(); if (ch == '*') { Form1.iniCommLine = line; Form1.iniCommCol = col; Pila aux = new Pila(50); aux.push("comentario"); //Boolean bandera = false; //while ((ch != EOF) && (!bandera)) while ((ch != EOF) && (!aux.estaVacia())) { NextCh(); if (ch == '*') { NextCh(); if ((ch == '/') && (!aux.estaVacia())) { Form1.finCommLin = line; Form1.finCommCol = col; aux.pop(); if (aux.estaVacia()) { //bandera = true; NextCh(); t = Next(); } } } else { if (ch == '/') { NextCh(); if (ch == '*') { aux.push("comentario"); } } } } } else { t.kind = Token.SLASH; } break; default: { t.str = ch.ToString(); //t.line = line; t.col = col; throw new ErrorMio(line, col, 1, "caracter " + ch.ToString() + " invalido"); } } } return(t); }