Esempio n. 1
0
 public SemTree Parse(AttrTree g, string[] words)
 {
     if (g == null)
     {
         return(null);
     }
     if (words.Length == 0)
     {
         // empty word list should return empty tree
         SemTree st = new SemTree();
         st.Node = g.Node;
         return(st);
     }
     // enum clauses
     foreach (AttrTree c in g)
     {
         SemTree res = new SemTree();
         res.Node = g.Node;
         int i_patt = 0;
         if (_Match(c, 0, words, ref i_patt, ref res))
         {
             res.Attributes = c.Attributes;
             return(res);
         }
     }
     // no match = word list out of grammar
     return(null);
 }
Esempio n. 2
0
        protected bool _Match(AttrTree targ, int i_targ, string[] patt, ref int i_patt, ref SemTree result)
        {
            bool tend = i_targ >= targ.Count;
            bool pend = i_patt >= patt.Length;

            if (tend)
            {
                return(pend);
            }
            int tit = i_targ;

            if (pend)
            {
                // the rest must be optional
                while (tit < targ.Count)
                {
                    if (!((AttrTree)targ[tit++]).IsOptional)
                    {
                        return(false);
                    }
                }
                return(true);
            }
            AttrTree goal = (AttrTree)targ[tit++];

            if (goal.Node == Constants.Grammar.UNIVERSAL)
            {
                // consume all words
                while (i_patt < patt.Length)
                {
                    result.Add(new SemTree(patt[i_patt++], goal.Attributes));
                }
                return(true);
            }
            // word
            string word = patt[i_patt];

            if (goal.Node == word)
            {
                int pit = i_patt + 1;
                if (_Match(targ, tit, patt, ref pit, ref result))
                {
                    SemTree at = new SemTree(word, goal.Attributes);
                    result.Insert(0, at);
                    i_patt = pit;
                    return(true);
                }
            }
            // prefer to skip optionals
            if (goal.IsOptional && _Match(targ, tit, patt, ref i_patt, ref result))
            {
                return(true);
            }
            // find class
            if (!Grammars.ContainsKey(goal.Node))
            {
                return(false);
            }
            AttrTree cls = Grammars[goal.Node];

            // parse it
            foreach (AttrTree clause in cls)
            {
                // concatenate clause and the rest of target (after goal) to the new tree
                AttrTree temp_targ = new AttrTree(clause);
                for (int j = tit; j < targ.Count; j++)
                {
                    temp_targ.Add(targ[j]);
                }
                // try to match
                int temp_pit = i_patt;
                if (_Match(temp_targ, 0, patt, ref temp_pit, ref result))
                {
                    // create subtree
                    SemTree subtree = new SemTree(cls.Node, clause.Attributes);
                    // move nodes to subtree
                    foreach (var c in clause)
                    {
                        if (result.Count == 0)
                        {
                            break;
                        }
                        AttrTree p = result[0];
                        if (p.Node != c.Node)
                        {
                            continue;                                           // ignore skipped optionals
                        }
                        subtree.Add(p);
                        result.RemoveAt(0);
                    }
                    result.Insert(0, subtree);
                    i_patt = temp_pit;
                    return(true);
                }
            }
            return(false);
        }