/* 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;
        }
예제 #2
0
        /* 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);
        }