Ejemplo n.º 1
0
        /**
         * Cette méthode renvoie le prochain symbole lexical du code
         * source contenu dans le fichier manipulé par pointer.
         *
         * L'algorithme de cette méthode utilise le principe de
         * "machine à états". La représentation graphique des états
         * peut etre consultée dans le rapport.
         *
         * @pre pointeur est différent de null
         *
         * @post La position du pointeur de pointer a avancé d'autant
         * de caractères que la taille du symbole lexical renvoyé ou
         * il ne s'est rien passé si la position du pointeur de pointer
         * est à la fin du fichier.
         *
         * @return un objet Terminal correspondant au prochain Terminal
         * lu dans le fichier manipulé par pointer ou le Terminal EOF
         * si on a parcouru tout le fichier manipulé par pointer.
         *
         */
        public Terminal NextTerminal()
        {
            StringBuilder res = new StringBuilder();
            char          c;

            try
            {
                while (pointer.HasNext())
                {
                    switch (state)
                    {
                    case STATE_BEGIN:

                        RemoveSpaces();
                        Terminal t;
                        c = pointer.Remove();
                        res.Append(c);

                        switch (c)
                        {
                        // Symbole // ou /
                        case '/':
                            if (pointer.GetChar() == '/')
                            {
                                pointer.Remove();
                                res   = new StringBuilder();
                                state = STATE_CATCH_COMMENT;
                            }
                            else
                            {
                                throw new ParserException("Caractère inconnu: " + c);
                            }
                            break;

                        // Symbole -x
                        case '-':
                            if (Char.IsDigit(pointer.GetChar()))
                            {
                                state = STATE_CATCH_DIGIT;
                            }
                            else if (pointer.GetChar() == '>')
                            {
                                state = STATE_CATCH_PROPERTY;
                                res.Clear();
                                pointer.Remove();
                                res.Append(pointer.Remove());
                            }
                            else
                            {
                                throw new ParserException("Caractère '-' non suivi d'un nombre.");
                            }
                            break;


                        // Symbole identifier
                        case '#':
                            state = STATE_CATCH_IDENTIFIER;
                            res.Clear();
                            res.Append(pointer.Remove());
                            break;

                        // Symbole control
                        case '@':
                            state = STATE_CATCH_CONTROL;
                            res.Clear();
                            res.Append(pointer.Remove());
                            break;

                        // Symbole selector
                        case '%':
                            state = STATE_CATCH_SELECTOR;
                            res.Clear();
                            res.Append(pointer.Remove());
                            break;

                        // Symbole ;
                        case ';':
                        case '.':
                        case ',':
                        case '(':
                        case ')':
                            state = STATE_BEGIN;
                            return(SpecialChar.Terminal(c));

                        // String
                        case '"':
                            state = STATE_CATCH_STRING;
                            res.Clear();
                            res.Append(pointer.Remove());
                            break;

                        // Identifier, Constant
                        default:
                            if (Char.IsDigit(c))
                            {
                                state = STATE_CATCH_DIGIT;
                            }
                            else if (Char.IsLetter(c))
                            {
                                state = STATE_CATCH_ALL;
                            }
                            else
                            {
                                // Apparement le dernier caractère (qui n'a pas de rapport avec le code)
                                // de mes fichiers provoque une erreur. J'ai utilisé le
                                // système D après avoir passer une heure sur le problème ..
                                if (pointer.HasNext())
                                {
                                    throw new ParserException("Caractère inconnu: " + c);
                                }
                            }
                            break;
                        }
                        break;

                    case STATE_CATCH_STRING:
                        if (pointer.GetChar() == '"')
                        {
                            state = STATE_BEGIN;
                            pointer.Remove();
                            //Console.Write("return string: " + res.ToString());
                            return(new MyString(res.ToString()));
                        }
                        else if (pointer.GetChar() == '\\')
                        {
                            pointer.Remove();
                            if (pointer.GetChar() == '"')
                            {
                                res.Append('"');
                                pointer.Remove();
                            }
                            else
                            {
                                res.Append('\\');
                            }
                        }
                        else
                        {
                            res.Append(pointer.GetChar());
                            pointer.Remove();
                        }
                        break;

                    case STATE_CATCH_COMMENT:
                        if (pointer.GetChar() == '\n')
                        {
                            state = STATE_BEGIN;
                        }
                        else
                        {
                            pointer.Remove();
                        }
                        break;

                    case STATE_CATCH_DIGIT:
                        if (Char.IsDigit(pointer.GetChar()) /*|| pointer.GetChar() == '.'*/)                            // pas de float
                        {
                            res.Append(pointer.Remove());
                        }
                        else
                        {
                            state = STATE_BEGIN;
                            return(new Constant(res.ToString()));
                        }
                        break;

                    case STATE_CATCH_IDENTIFIER:
                    case STATE_CATCH_CONTROL:
                    case STATE_CATCH_ALL:
                    case STATE_CATCH_SELECTOR:
                    case STATE_CATCH_PROPERTY:
                        if (Char.IsLetterOrDigit(pointer.GetChar()) || pointer.GetChar() == '_')
                        {
                            res.Append(pointer.Remove());
                        }
                        else
                        {
                            Terminal rw = ReservedWord.Terminal(res.ToString());
                            if (rw != null)
                            {
                                state = STATE_BEGIN;
                                return(rw);
                            }
                            else if (state == STATE_CATCH_CONTROL)
                            {
                                state = STATE_BEGIN;
                                return(new ControlType(res.ToString()));
                            }
                            else if (state == STATE_CATCH_SELECTOR)
                            {
                                state = STATE_BEGIN;
                                return(new Selector(res.ToString()));
                            }
                            else if (state == STATE_CATCH_PROPERTY)
                            {
                                state = STATE_BEGIN;
                                return(new MyProperty(res.ToString()));
                            }
                            else if (state == STATE_CATCH_IDENTIFIER)
                            {
                                state = STATE_BEGIN;
                                return(new Identifier(res.ToString()));
                            }
                            else if (state == STATE_CATCH_ALL)
                            {
                                state = STATE_BEGIN;
                                if (res.ToString().Equals("All"))
                                {
                                    return(new All());
                                }
                                else
                                {
                                    throw new ParserException("String 'All' attendu. String trouvée: " + res.ToString());
                                }
                            }
                            else
                            {
                                throw new ParserException("Erreur inconnue.");
                            }
                        }
                        break;
                    }
                }
            }catch (IOException e)
            {
                throw new ParserException("Exception lors de l'analyse lexicale du fichier source: " + e);
                //return SpecialChar.EOF;
            }

            pointer.Close();

            return(SpecialChar.EOF);
        }
Ejemplo n.º 2
0
        /**
         * Cette méthode renvoie le prochain symbole lexical du code
         * source contenu dans le fichier manipulé par pointer.
         *
         * L'algorithme de cette méthode utilise le principe de
         * "machine à états". La représentation graphique des états
         * peut etre consultée dans le rapport.
         *
         * @pre pointeur est différent de null
         *
         * @post La position du pointeur de pointer a avancé d'autant
         * de caractères que la taille du symbole lexical renvoyé ou
         * il ne s'est rien passé si la position du pointeur de pointer
         * est à la fin du fichier.
         *
         * @return un objet Terminal correspondant au prochain Terminal
         * lu dans le fichier manipulé par pointer ou le Terminal EOF
         * si on a parcouru tout le fichier manipulé par pointer.
         *
         */
        public Terminal nextTerminal()
        {
            int           state = STATE_BEGIN;
            StringBuilder res   = new StringBuilder();
            char          c;

            try
            {
                while (pointer.HasNext())
                {
                    switch (state)
                    {
                    case STATE_BEGIN:

                        removeSpaces();
                        Terminal t;
                        c = pointer.Remove();
                        res.Append(c);

                        switch (c)
                        {
                        // Symbole // ou /
                        case '/':
                            if (pointer.GetChar() == '/')
                            {
                                pointer.Remove();
                                res   = new StringBuilder();
                                state = STATE_CATCH_COMMENT;
                            }
                            else
                            {
                                throw new Exception("Caractère inconnu: " + c);
                            }
                            break;

                        // Symbole -x
                        case '-':
                            if (Char.IsDigit(pointer.GetChar()))
                            {
                                state = STATE_CATCH_DIGIT;
                            }
                            else
                            {
                                throw new Exception("Caractère '-' non suivi d'un nombre.");
                            }
                            break;


                        // Symbole x.y
                        case '#':
                            state = STATE_CATCH_CONTROL;
                            break;

                        // Symbole ;
                        case ';':
                            return(new SpecialChar(";"));

                            break;

                        // String
                        case '"':
                            state = STATE_CATCH_STRING;
                            break;

                        // Identifier, Constant
                        default:
                            if (Char.IsDigit(c))
                            {
                                state = STATE_CATCH_DIGIT;
                            }
                            else if (Char.IsLetter(c))
                            {
                                state = STATE_CATCH_IDENTIFIER;
                            }
                            else
                            {
                                // Apparement le dernier caractère (qui n'a pas de rapport avec le code)
                                // de mes fichiers provoque une erreur. J'ai utilisé le
                                // système D après avoir passer une heure sur le problème ..
                                if (pointer.HasNext())
                                {
                                    throw new Exception("Caractère inconnu: " + c);
                                }
                            }
                            break;
                        }
                        break;

                    case STATE_CATCH_STRING:
                        if (pointer.GetChar() == '"')
                        {
                            state = STATE_BEGIN;
                            return(new MyString(res.ToString()));
                        }
                        else if (pointer.GetChar() == '\\')
                        {
                            pointer.Remove();
                            if (pointer.GetChar() == '"')
                            {
                                res.Append('"');
                                pointer.Remove();
                            }
                            else
                            {
                                res.Append('\\');
                            }
                        }
                        break;

                    case STATE_CATCH_COMMENT:
                        if (pointer.GetChar() == '\n')
                        {
                            state = STATE_BEGIN;
                        }
                        else
                        {
                            pointer.Remove();
                        }
                        break;

                    case STATE_CATCH_DIGIT:
                        if (Char.IsDigit(pointer.GetChar()) || pointer.GetChar() == '.')
                        {
                            res.Append(pointer.Remove());
                        }
                        else
                        {
                            state = STATE_BEGIN;
                            return(new Constant(res.ToString()));
                        }
                        break;

                    case STATE_CATCH_IDENTIFIER:
                    case STATE_CATCH_CONTROL:
                        if (Char.IsLetterOrDigit(pointer.GetChar()))
                        {
                            res.Append(pointer.Remove());
                        }
                        else
                        {
                            state = STATE_BEGIN;
                            Terminal rw = ReservedWord.Terminal(res.ToString());
                            if (rw != null)
                            {
                                return(rw);
                            }
                            else if (state == STATE_CATCH_IDENTIFIER)
                            {
                                return(new Identifier(res.ToString()));
                            }
                            else
                            {
                                return(new Control(res.ToString()));
                            }
                        }
                        break;
                    }
                }
            }catch (IOException e)
            {
                System.Console.WriteLine("Exception lors de l'analyse lexciale du fichier source: " + e);
                return(SpecialChar.EOF);
            }

            pointer.close();

            return(SpecialChar.EOF);
        }