Example #1
0
 public static void initGrammar()
 {
     lambda     = new Terminal("lambda");
     identifier = new Identifier("identifier");
     constant   = new Constant("constant");
     myString   = new MyString("string");
     control    = new ControlType("control");
     selector   = new Selector("selector");
     myProperty = new MyProperty("property");
     all        = new All();
     program    = new NotTerminal("PROGRAM");
 }
        /**
         * pre: balise != null && balise.length > 2
         * @param balise
         * @return
         */
        private Symbol nextSymbol(String balise)
        {
            char c1 = balise[0];
            char cn = balise[balise.Length - 1];

            String name = balise.Substring(1, balise.Length - 2);

            //System.Console.WriteLine(name + " - " + c1 +"  - " + cn);
            // La balise est un terminal
            if (c1 == '\'' && cn == '\'')
            {
                Terminal symbol;
                // Si le symbole ne se trouve pas dans la map des terminal, on l'ajoute.
                if (!terminalMap.ContainsKey(name))
                {
                    symbol = new Terminal(name);
                    terminalMap.Add(name, symbol);
                }
                else
                {
                    symbol = terminalMap[name];
                }
                return(symbol);
            }
            // La balise est un non terminal
            else if (c1 == '<' && cn == '>')
            {
                NotTerminal symbol;
                // Si le symbole ne se trouve pas dans la map des non terminal, on l'ajoute.
                if (!notTerminalMap.ContainsKey(name))
                {
                    symbol = new NotTerminal(name);
                    notTerminalMap.Add(name, symbol);
                }
                else
                {
                    symbol = notTerminalMap[name];
                }
                return(symbol);
            }
            else
            {
                // La balise n'est pas contenue entre '' et <> donc est invalide
                throw new ParserException("Erreur dans la syntaxe de la grammaire: la balise '" + balise + "' n'est pas entre '' ou <>");
            }
        }
Example #3
0
        /**
         * Génère la table de parsing de la grammaire G
         * dans le tableau à deux dimensions ParsingTable
         *
         * @pre Les ensembles p1 de chaque symboles de la grammaire G doivent etre calculés
         * @pre Les ensembles s1 de chaque symbole de la grammaire G non étendue doivent etre calculés
         */
        public void GenerateParsingTable()
        {
            /*
             * Comme fait au cours, on va créer un tableau en deux dimensions
             * de taille NonTerminalList.size() et TerminalList.size().
             * Le but de ce tableau est de savoir quel règle choisir en fonction
             * du non terminal courant sur la stack et le symbol lu dans le code
             * source.
             *
             * Soit A -> alpha, pour chaque élément "a" de p1(alpha)
             * on définit table[A, a] : A -> alpha.
             *
             * Si lambda est contenu dans p1(alpha), on va aller voir AUSSI dans
             * l'ensemble s1(alpha) qui sont les terminaux pouvant se trouver après A
             * puisque p1(alpha) peut etre vide. On fera donc:
             * Pour tout b dans s1(A): table[A, b] : A -> alpha
             */

            //Rule[,] table = new Rule[G.NotTerminals().Count(), G.Terminals().Count()];
            //Console.WriteLine("Taille table: " + G.NotTerminals().Count() + " et " + G.Terminals().Count());
            Rule[,] table = new Rule[NotTerminal.NotTerminalIndex + 1, Terminal.TerminalIndex + 1];
            // Parcours des règles
            foreach (Rule r in G.Rules())
            {
                // On définit A -> alpha
                NotTerminal         A     = r.Left();
                LinkedList <Symbol> alpha = r.Right();

                // On récupère l'ensemble p1(alpha)
                // On est certain d'avoir un résultat car tous les ensembles
                // p1 ont été calculés précédement.
                bool isLambda = false;

                // Pour chaque "premier terminal" pouvant etre obtenu en dérivant A
                // On crée table[A, a] : A -> aplha sauf si "a" == Lambda
                foreach (Terminal a in G.MergeSets(alpha))
                {
                    if (a == Grammar.lambda)
                    {
                        isLambda = true;
                    }
                    else
                    {
                        //Console.WriteLine(A + " (" + A.Index() + ") - " + a+ " (" + a.Index() + ")");
                        table[A.Index(), a.Index()] = r;
                        //System.out.println("table[" + A.getText() + ", " + a.getText() + "] = " + r);
                    }
                }

                // Si on a découvert un lambda dans p1(alpha), on va aussi
                // ajouter les éléments de s1(A) à la liste.
                if (isLambda)
                {
                    // Pour tous les terminaux "b" suivant A on fait:
                    // table[A, b] : A -> alpha
                    foreach (Terminal b in A.S1())
                    {
                        table[A.Index(), b.Index()] = r;
                        //System.out.println("table[" + A.getText() + ", " + b.getText() + "] = " + r);
                    }
                }
            }

            parsingTable = table;
        }
Example #4
0
        /**
         * Vérifie que la première condition pour qu'une grammaire soit LL1
         * est correcte.
         *
         * @pre Les ensembles P1 de chaque symbole de la grammaire G doivent être calculés.
         */
        public void CheckCondition1()
        {
            /*
             * Cette méthode vérifie que la grammaire G respecte la première condition
             * LL1 à savoir pour chaque non terminal X, il ne peut pas exister de
             * dérivations différentes o et o' de X telle que l'intersection de
             * p1(o) et p1(o') est non vide. En pratique celà pose problème car
             * il y aura une incohérence lors de la génération de la table de parsing.
             *
             * Le principe est simple on crée une relation NotTerminal -> Set of Derivations
             * Ensuite, pour chaque non terminal, on vérifie qu'aucun
             * ensemble p1 de ses dérivations ne possède un meme terminal.
             */

            // Génération de la relation NotTerminal -> Ensemble de dérivations
            if (allLeftNotTerminals == null)
            {
                GenerateAllLeftNotTerminal();
            }

            // Soit x -> Y1 | Y2 | .. | Yn
            // Pour chaque dérivation Yi, on vérifie que l'intersection de p1(Yi) et p1(Yj),
            // où j>i, est vide.
            foreach (KeyValuePair <NotTerminal, HashSet <Rule> > entry in allLeftNotTerminals)
            {
                NotTerminal    x = entry.Key;
                HashSet <Rule> Y = entry.Value;
                //System.Console.WriteLine("NonTer: " + x);
                // Pour chaque Yi
                int i = 1;
                foreach (Rule r in Y)
                {
                    HashSet <Terminal> P1Yi = G.MergeSets(r.Right());
                    //System.Console.WriteLine("R1: " + r);
                    int j = 1;
                    foreach (Rule r2 in Y)
                    {
                        // Pour chaque Yj où j>i
                        if (j <= i)
                        {
                            j++;
                            continue;
                        }

                        //System.Console.WriteLine("R2: " + r2);
                        HashSet <Terminal> P1Yj = G.MergeSets(r2.Right());

                        // Intersection de p1(Bi) et p1(Bj) vide ?
                        foreach (Terminal t in P1Yj)
                        {
                            if (P1Yi.Contains(t))
                            {
                                throw new ParserException("Le non terminal '" + x + "' possède deux dérivations ayant des éléments de p1 identiques: "
                                                          + " " + t);
                            }
                        }
                    }
                    i++;
                }
            }
        }
Example #5
0
 public Rule(NotTerminal left, LinkedList <Symbol> right)
 {
     this.left  = left;
     this.right = right;
 }
Example #6
0
        public void ComputeExtendedRules()
        {
            Dictionary <String, NotTerminal> notTerminalNames = new Dictionary <String, NotTerminal>();

            // Program' -> lambda
            LinkedList <Symbol> right = new LinkedList <Symbol>();

            right.AddLast(lambda);
            NotTerminal program2 = new NotTerminal(Grammar.program.GetText() + "'");

            extendedRules = new LinkedList <Rule>(rules);
            extendedRules.AddLast(new Rule(program2, right));
            // Program est son propre symbole étendu
            extendedSymbols.Add(program, program2);


            // Pour chaque règle, on va créer un symbole étendu
            // du symbole de gauche.
            // Y  -> alpha X beta
            // X2 -> beta Y2
            foreach (Rule p in rules)
            {
                right = new LinkedList <Symbol>(p.Right());
                NotTerminal left = p.Left();
                //System.Console.WriteLine("Rule - " + p);
                while (right.Count() > 0)
                {
                    Symbol symbol = right.First();
                    right.RemoveFirst();

                    if (symbol is NotTerminal)
                    {
                        NotTerminal X = (NotTerminal)symbol;

                        // Si on a une règle du style X' -> X', on ne l'ajoute pas
                        if (X == left && right.Count() < 1)
                        {
                            continue;
                        }

                        String X2_Name = X.GetText() + "'";
                        String Y2_Name = left.GetText() + "'";

                        NotTerminal X2;
                        if (!notTerminalNames.ContainsKey(X2_Name))
                        {
                            // Le non terminal étendu X' n'existe pas, on le crée
                            X2 = new NotTerminal(X2_Name);
                            // On l'ajoute à la map qui établit la relation name <--> symbole
                            notTerminalNames.Add(X2_Name, X2);
                            // On ajoute ce nouveau non terminal à la liste des non terminaux
                            notTerminalList.AddLast(X2);
                        }
                        else
                        {
                            X2 = notTerminalNames[X2_Name];
                        }

                        NotTerminal Y2;
                        if (!notTerminalNames.ContainsKey(Y2_Name))
                        {
                            // Le non terminal étendu X' n'existe pas, on le crée
                            Y2 = new NotTerminal(Y2_Name);
                            // On l'ajoute à la map qui établit la relation name --> symbole
                            notTerminalNames.Add(Y2_Name, Y2);
                            // On ajoute ce nouveau non terminal à la liste des non terminaux
                            notTerminalList.AddLast(Y2);
                        }
                        else
                        {
                            Y2 = notTerminalNames[Y2_Name];
                        }

                        // On crée la partie de droite de la règle définissant X2
                        LinkedList <Symbol> X2_Right = new LinkedList <Symbol>(right);
                        X2_Right.AddLast(Y2);
                        // On ajoute enfin la nouvelle règle créée
                        extendedRules.AddLast(new Rule(X2, X2_Right));
                        // On définit la relation Symbole --> Symbole étendu
                        //System.Console.WriteLine("NewRule - " + new Rule(X2, X2_Right));
                        //System.Console.WriteLine("Sym --> SymEtend - " + X + " -> " + X2);
                        if (!extendedSymbols.ContainsKey(X))
                        {
                            extendedSymbols.Add(X, X2);
                        }
                    }
                }
            }
        }