예제 #1
0
        //	Match must start at the beginning
        private PNode reduceSentenceFragmentStartingAtBeginning(PNode source, out bool didReduce)
        {
            //	Create a matcher
            //	While there are still "matchers in progress"
            //		Feed each PNode in the source to each matcher in progress.
            //		If the matcher indicats it is done then
            //			Ask for it's list of best matches.
            //			Add that list to the complete list of best matches.
            //			Remove the completed matcher from the list of matchers in progress.
            //		Otherwise,
            //			Add the list of child matchers it returns to the list of matchers in progress

            List <PatternMatcher> matches     = getSuccessfulMatchesStartingAtPNode(source);            //	Get the matches
            List <PatternMatcher> bestMatches = getStrongestMatchesFromMatchList(matches);              //	Select the winners

            //	Deal with ambiguity (too many matches)
            if (bestMatches.Count > 1 ||
                bestMatches.Count == 1 && bestMatches[0].MatchedPhrases.Count > 1)
            {
                didReduce = false;

                //	Make an ambiguity callback and throw an exception to bail out of this mess.
                if (OnAmbiguity != null)
                {
                    OnAmbiguity(this, source, bestMatches);
                    throw new RuntimeProseLanguageException("Sentence is ambiguous.", source);
                }
                else
                {
                    throw new RuntimeProseLanguageException("Sentence is ambiguous.", source);
                }
            }
            else if (bestMatches.Count == 0)
            {
                //	We couldn't reduce anything
                didReduce = false;
                return(source);
            }


            //	Apply the phrase
            PatternMatcher bestMatcher = bestMatches[0];
            Phrase         bestPhrase  = bestMatcher.MatchedPhrases[0];

            didReduce = true;

            //	Do any automatic casting necessary to make the arguments match the pattern.
            bestMatcher.autoCastArguments();

            if (BeforeReduction != null)
            {
                BeforeReduction(this, source);
            }

            //	REDUCE!
            PNode reducedSource = bestPhrase.evaluate(source, bestMatcher);

            if (AfterReduction != null)
            {
                AfterReduction(this, reducedSource);
            }

            return(reducedSource);
        }