private void ParseElementOnlyContent(ParticleContentValidator pcv, int startParenEntityId)
{
Stack<ParseElementOnlyContent_LocalFrame> localFrames = new Stack<ParseElementOnlyContent_LocalFrame>();
ParseElementOnlyContent_LocalFrame currentFrame = new ParseElementOnlyContent_LocalFrame(startParenEntityId);
localFrames.Push(currentFrame);
RecursiveCall:
Loop:
switch (GetToken(false))
{
case Token.QName:
pcv.AddName(GetNameQualified(true), null);
ParseHowMany(pcv);
break;
case Token.LeftParen:
pcv.OpenGroup();
// We could just do this:
// ParseElementOnlyContent( pcv, currentEntityId );
//
// But that would be recursion - so we will simulate the call using our localFrames stack
// instead.
currentFrame =
new ParseElementOnlyContent_LocalFrame(_currentEntityId);
localFrames.Push(currentFrame);
goto RecursiveCall;
// And we should return here when we return from recursion call
// but it's the same as returning after the switch statement
case Token.GreaterThan:
Throw(_curPos, SR.Xml_InvalidContentModel);
goto Return;
default:
goto UnexpectedError;
}
ReturnFromRecursiveCall:
switch (GetToken(false))
{
case Token.Comma:
if (currentFrame.parsingSchema == Token.Or)
{
Throw(_curPos, SR.Xml_InvalidContentModel);
}
pcv.AddSequence();
currentFrame.parsingSchema = Token.Comma;
break;
case Token.Or:
if (currentFrame.parsingSchema == Token.Comma)
{
Throw(_curPos, SR.Xml_InvalidContentModel);
}
pcv.AddChoice();
currentFrame.parsingSchema = Token.Or;
break;
case Token.RightParen:
pcv.CloseGroup();
if (_validate && _currentEntityId != currentFrame.startParenEntityId)
{
SendValidationEvent(_curPos, XmlSeverityType.Error, SR.Sch_ParEntityRefNesting, string.Empty);
}
ParseHowMany(pcv);
goto Return;
case Token.GreaterThan:
Throw(_curPos, SR.Xml_InvalidContentModel);
goto Return;
default:
goto UnexpectedError;
}
goto Loop;
UnexpectedError:
OnUnexpectedError();
Return:
// This is equivalent to return; statement
// we simlate it using our localFrames stack
localFrames.Pop();
if (localFrames.Count > 0)
{
currentFrame = (ParseElementOnlyContent_LocalFrame)localFrames.Peek();
goto ReturnFromRecursiveCall;
}
else
{
return;
}
}