Axiom.RenderSystems.OpenGL.ATI.Compiler2Pass.ProcessRulePath C# (CSharp) Method

ProcessRulePath() protected method

Process input source text using rulepath to determine allowed tokens.
The method is reentrant and recursive. if a non-terminal token is encountered in the current rule path then the method is called using the new rule path referenced by the non-terminal token Tokens can have the following operation states which effects the flow path of the rule Rule: defines a rule path for the non-terminal token. And: the token is required for the rule to pass. Or: if the previous tokens failed then try these ones. Optional: the token is optional and does not cause the rule to fail if the token is not found. Repeat: the token is required but there can be more than one in a sequence. End: end of the rule path - the method returns the success of the rule.
protected ProcessRulePath ( int rulePathIdx ) : bool
rulePathIdx int Index into to array of Token Rules that define a rule path to be processed.
return bool
		protected bool ProcessRulePath( int rulePathIdx )
		{
			// rule path determines what tokens and therefore what symbols are acceptable from the source
			// it is assumed that the tokens with the longest similar symbols are arranged first so
			// if a match is found it is accepted and no further searching is done

			// record position of last token in container
			// to be used as the rollback position if a valid token is not found
			int tokenContainerOldSize = tokenInstructions.Count;
			int oldCharPos = charPos;
			int oldLinePos = currentLine;
			int oldConstantsSize = constants.Count;

			// keep track of what non-terminal token activated the rule
			Symbol activeNTTRule = rootRulePath[ rulePathIdx ].tokenID;

			// start rule path at next position for definition
			rulePathIdx++;

			// assume the rule will pass
			bool passed = true;
			bool endFound = false;

			// keep following rulepath until the end is reached
			while ( !endFound )
			{
				switch ( rootRulePath[ rulePathIdx ].operation )
				{

					case OperationType.And:
						// only validate if the previous rule passed
						if ( passed )
						{
							passed = ValidateToken( rulePathIdx, activeNTTRule );
						}
						break;

					case OperationType.Or:
						// only validate if the previous rule failed
						if ( !passed )
						{
							// clear previous tokens from entry and try again
							tokenInstructions.Resize( tokenContainerOldSize );
							passed = ValidateToken( rulePathIdx, activeNTTRule );
						}
						else
						{
							// path passed up to this point therefore finished so pretend end marker found
							endFound = true;
						}
						break;

					case OperationType.Optional:
						// if previous passed then try this rule but it does not effect succes of rule since its optional
						if ( passed )
						{
							ValidateToken( rulePathIdx, activeNTTRule );
						}
						break;

					case OperationType.Repeat:
						// repeat until no tokens of this type found 
						// at least one must be found
						if ( passed )
						{
							int tokensPassed = 0;
							// keep calling until failure
							while ( passed = ValidateToken( rulePathIdx, activeNTTRule ) )
							{
								// increment count for previous passed token
								tokensPassed++;
							}
							// defaults to Passed = fail
							// if at least one token found then return passed = true
							if ( tokensPassed > 0 )
							{
								passed = true;
							}
						}
						break;

					case OperationType.End:
						// end of rule found so time to return
						endFound = true;

						if ( !passed )
						{
							// the rule did not validate so get rid of tokens decoded
							// roll back the token container end position to what it was when rule started
							// this will get rid of all tokens that had been pushed on the container while
							// trying to validating this rule
							tokenInstructions.Resize( tokenContainerOldSize );
							constants.Resize( oldConstantsSize );
							charPos = oldCharPos;
							currentLine = oldLinePos;
						}
						break;

					default:
						// an exception should be raised since the code should never get here
						passed = false;
						endFound = true;
						break;
				}

				// move on to the next rule in the path
				rulePathIdx++;
			}

			return passed;
		}