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;
}