예제 #1
0
        //	Clone the pattern matcher and reconfigure it in a new state based on a word.
        private PatternMatcher makeCopyWithStateFromAtWord(ProseObject atWord)
        {
            PatternMatcher newMatcher = new PatternMatcher(runtime);

            newMatcher.patternComponentNodes.AddRange(patternComponentNodes);
            newMatcher.numObjectsMatched = numObjectsMatched;

            if (currPatternObject != null)
            {
                newMatcher.currPatternObject = currPatternObject.clone();
            }


            if (atWord == runtime.@prose)
            {
                newMatcher.switchToState_MATCHING_PROSE();
                if (parentheticalStack != null)
                {
                    //newMatcher.parentheticalStack = new Stack<ProseObject>(parentheticalStack);
                    newMatcher.parentheticalStack = new Stack <ProseObject>();
                    ProseObject[] objs = parentheticalStack.ToArray();
                    for (int i = objs.Length - 1; i >= 0; i--)
                    {
                        newMatcher.parentheticalStack.Push(objs[i]);
                    }
                }
                newMatcher.inText = inText;
            }
            else if (atWord == runtime.@text)
            {
                newMatcher.switchToState_MATCHING_TEXT();
                newMatcher.textMatchingQQcount = textMatchingQQcount;
            }
            else if (atWord == runtime.@pattern)
            {
                newMatcher.switchToState_MATCHING_PATTERN();
            }
            else
            {
                newMatcher.switchToState_MATCHING_OBJECT();
            }

            return(newMatcher);
        }
예제 #2
0
        List <PatternMatcher> while_MATCHING_PROSE_matchNextObject(PNode node)
        {
            ProseObject obj = node.value;

            //	Return this list of spawned matchers.
            List <PatternMatcher> babyMatchers = new List <PatternMatcher>();

            //	Possibly we can make this prose block longer (in addition to other options where we may leave it)
            bool canExtendThisProseBlock = false;
            //	If we want extend our prose block by adding a right parenthetical, remember to pop the left off the stack.
            bool shouldPopParentheticalStack = false;
            //	If we stay in this prose block, record if we are entering text or leaving text
            bool shouldToggleInText = false;
            //	Should we exit to a different mode?
            bool         shouldLeaveMatchingProse = false;
            MatcherState switchToThisState;


            //	Check for parentheticals
            //	No need to check for () because it's eliminated before we're ever called.
            if (obj == runtime.LeftCurlyBracket)
            {
                canExtendThisProseBlock = true;
                //	Do this in extend
                //parentheticalStack.Push(runtime.LeftCurlyBracket);
            }
            else if (obj == runtime.LeftSquareBracket)
            {
                canExtendThisProseBlock = true;
                //	Do this in extend
                //parentheticalStack.Push(runtime.LeftSquareBracket);
            }
            else if (obj == runtime.RightCurlyBracket)
            {
                ProseObject matchingParenthetical = tryPeekParenthetical();
                if (matchingParenthetical == null || matchingParenthetical != runtime.LeftCurlyBracket)
                {
                    throw new PatternMatcherException("Right curly bracket wihtout matching left curly bracket inside @prose block.", this);
                }
                //	At this point, we agree the curly bracket makes sense, so we pop it's counterpart off the stack.
                shouldPopParentheticalStack = true;
                canExtendThisProseBlock     = true;
            }
            else if (obj == runtime.RightSquareBracket)
            {
                ProseObject matchingParenthetical = tryPeekParenthetical();
                if (matchingParenthetical == null || matchingParenthetical != runtime.LeftSquareBracket)
                {
                    throw new PatternMatcherException("Right square bracket without matching left square bracket inside @prose block.", this);
                }
                //	At this point, we agree the square bracket makes sense, so we pop it's counterpart off the stack.
                shouldPopParentheticalStack = true;
                canExtendThisProseBlock     = true;
            }
            else if (obj == runtime.Quadquote)
            {
                //	In this case, we count that we are in a text block, but we don't "read it as text".  Instead, we just
                //	bundle the symbols in with our prose object and pass it along to be interpreted later.
                if (inText)
                {
                    ProseObject matchingParenthetical = tryPeekParenthetical();
                    if (matchingParenthetical == null || matchingParenthetical != runtime.Quadquote)
                    {
                        //	The "" didn't match up with a previous one!
                        throw new PatternMatcherException("Quadquote entagled with other parenthetical.", this);
                    }
                    else
                    {
                        canExtendThisProseBlock     = true;
                        shouldToggleInText          = true;                                     //	inText = false;
                        shouldPopParentheticalStack = true;                                     //	Pop off the left ""
                    }
                }
                else
                {
                    //	In this case, we treat this as an opening quadquote.
                    canExtendThisProseBlock = true;
                    parentheticalStack.Push(runtime.Quadquote);                                 //	Remember the left ""
                    shouldToggleInText = true;                                                  //	inText = true;
                }
            }

            //	When the parenthetical stack is empty, we are allowed to exit the prose block if
            //	we can match the next piece of the pattern.
            else if (parentheticalStack.Count == 0)
            {
//				if (obj == runtime.Period) {
//					//	A period ends a "prose" block unless it is protected by {} or [] or "" ""
//					//	The period does not appear in the block.  It is interpreted as ending the sentence.
//					//	So exit reading prose
//					shouldLeaveMatchingProse = true;
//					//switchToThisState = MatcherState.MATCHING_OBJECT;
//					//CURSOR
//				} else {
                //	Use inheritance to look for an exit!
                //	Look up words which would match if they were in a pattern.
                List <ProseObject> matchingPatternWords = getMatchingPatternWords(obj);
                //	Look these words up to see if actual patterns exist.
                canExtendThisProseBlock = (matchingPatternWords.Count != 0);
                foreach (ProseObject match in matchingPatternWords)
                {
                    //	If it's not a period and the attempt to extend @prose immediately failed,
                    //	then we continue matching @prose.  If the attempt didn't immediately fail then
                    //	the rules say we must leave @prose.
                    if (obj == runtime.Period)                     // && !babyMatcher.IsntFailed)
                    {
                        canExtendThisProseBlock = false;
                    }

                    if (match == runtime.@prose)
                    {
                        continue;                                               //	back to back @prose outlawed.
                    }
                    //	Look up the match
                    Trie <ProseObject, List <Phrase> > .Node matchNode = currNode.getChildNode(match);
                    if (matchNode == null)
                    {
                        continue;
                    }

                    //	If this pattern can be extended by leaving prose, then do it
                    //	Spawn a baby matcher to pursue this pattern
                    PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(match);                            //	Clone ourselves
                    babyMatcher.switchToState_MATCHING_OBJECT();                                                //	Move babyMatcher into the generic state (can accept anything)
                    babyMatcher.while_MATCHING_OBJECT_extendWith(node, matchNode);                              //	Append the new node
                    babyMatchers.Add(babyMatcher);                                                              //	Eventually return this baby matcher

                    //	If it's possible to exit an @prose block, the matcher MUST
                    canExtendThisProseBlock = false;
                }
            }

            //	In this case the parenthetical stack is not empty and we have some symbol that
            //	isn't parenthetical (or "").
            else
            {
                //	Add it to this prose block
                canExtendThisProseBlock = true;
            }


            //
            //	Perform updates according to flags
            //
            if (shouldToggleInText)
            {
                inText = !inText;
            }
            if (shouldPopParentheticalStack)
            {
                parentheticalStack.Pop();
            }
            if (canExtendThisProseBlock)
            {
                //	Extend ourselves!
                //	NOTE: We don't change the node we're using!
                PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(runtime.@prose);                       //	Clone ourselves
                babyMatcher.objectsInCurrentProseblock = objectsInCurrentProseblock;
                babyMatcher.while_MATCHING_PROSE_extendWith(node, currNode);
                babyMatchers.Add(babyMatcher);
            }
            else if (shouldLeaveMatchingProse)
            {
                throw new Exception("Failboat.");
//				PatternMatcher babyMatcher = makeCopyWithStateFromAtWord(obj);	//	Clone ourselves
//				//babyMatcher.switchToState_MATCHING_OBJECT();
//				babyMatcher.while_MATCHING_OBJECT_extendWith(node, );
//				babyMatchers.Add(babyMatcher);
            }

            return(babyMatchers);
        }
예제 #3
0
        //    Clone the pattern matcher and reconfigure it in a new state based on a word.
        private PatternMatcher makeCopyWithStateFromAtWord(ProseObject atWord)
        {
            PatternMatcher newMatcher = new PatternMatcher(runtime);
            newMatcher.patternComponentNodes.AddRange(patternComponentNodes);
            newMatcher.numObjectsMatched = numObjectsMatched;

            if (currPatternObject != null)
                newMatcher.currPatternObject = currPatternObject.clone();

            if (atWord == runtime.@prose) {
                newMatcher.switchToState_MATCHING_PROSE();
                if (parentheticalStack != null) {
                    //newMatcher.parentheticalStack = new Stack<ProseObject>(parentheticalStack);
                    newMatcher.parentheticalStack = new Stack<ProseObject>();
                    ProseObject[] objs = parentheticalStack.ToArray();
                    for (int i=objs.Length - 1; i >= 0; i--)
                        newMatcher.parentheticalStack.Push(objs[i]);

                }
                newMatcher.inText = inText;
            }
            else if (atWord == runtime.@text) {
                newMatcher.switchToState_MATCHING_TEXT();
                newMatcher.textMatchingQQcount = textMatchingQQcount;
            }
            else if (atWord == runtime.@pattern) {
                newMatcher.switchToState_MATCHING_PATTERN();
            }
            else {
                newMatcher.switchToState_MATCHING_OBJECT();
            }

            return newMatcher;
        }