コード例 #1
0
ファイル: Parser.cs プロジェクト: OlegBoulanov/MoreExtras
        protected bool _PartialMatch(AttrTree targ, int i_targ, string[] patt, int i_patt, List <string> result)
        {
            bool pend = patt.Length <= i_patt;

            if (targ.Count <= i_targ)
            {
                return(pend);
            }
            if (pend)
            {
                return(_Next(targ, i_targ, result));
            }
            AttrTree goal = (AttrTree)targ[i_targ++];
            string   word = patt[i_patt];

            // word
            if (goal.Node.Equals(word))
            {
                return(_PartialMatch(targ, i_targ, patt, i_patt + 1, result));
            }
            bool res = goal.IsOptional && _PartialMatch(targ, i_targ, patt, i_patt, result);

            // grammar
            if (!Grammars.ContainsKey(goal.Node))
            {
                return(false);
            }
            AttrTree grm = (AttrTree)Grammars[goal.Node];

            // parse all the alternatives
            foreach (AttrTree alt in grm)
            {
                // concatenate clause and the rest of target (after goal) to the new tree
                AttrTree temp_targ = new AttrTree(alt);
                for (int j = i_targ; j < targ.Count; j++)
                {
                    temp_targ.Add(targ[j]);
                }
                // try to match
                if (_PartialMatch(temp_targ, 0, patt, i_patt, result))
                {
                    res = true;
                }
            }
            return(res);
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: OlegBoulanov/MoreExtras
        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);
        }