void ParseModel(char cmt, ContentModel cm)
{
// Called when part of the model is made up of the contents of a parameter entity
int depth = cm.CurrentDepth;
char ch = this.m_current.Lastchar;
ch = this.m_current.SkipWhitespace();
while (ch != cmt || cm.CurrentDepth > depth) // the entity must terminate while inside the content model.
{
if (ch == Entity.EOF)
{
this.m_current.Error("Content Model was not closed");
}
if (ch == '%')
{
Entity e = ParseParameterEntity(SgmlDtd.cmterm);
PushEntity(this.m_current.ResolvedUri, e);
ParseModel(Entity.EOF, cm);
PopEntity();
ch = this.m_current.SkipWhitespace();
}
else if (ch == '(')
{
cm.PushGroup();
this.m_current.ReadChar();// consume '('
ch = this.m_current.SkipWhitespace();
}
else if (ch == ')')
{
ch = this.m_current.ReadChar();// consume ')'
if (ch == '*' || ch == '+' || ch == '?')
{
cm.AddOccurrence(ch);
ch = this.m_current.ReadChar();
}
if (cm.PopGroup() < depth)
{
this.m_current.Error("Parameter entity cannot close a paren outside it's own scope");
}
ch = this.m_current.SkipWhitespace();
}
else if (ch == ',' || ch == '|' || ch == '&')
{
cm.AddConnector(ch);
this.m_current.ReadChar(); // skip connector
ch = this.m_current.SkipWhitespace();
}
else
{
string token;
if (ch == '#')
{
ch = this.m_current.ReadChar();
token = "#" + this.m_current.ScanToken(this.m_sb, SgmlDtd.cmterm, true); // since '#' is not a valid name character.
}
else
{
token = this.m_current.ScanToken(this.m_sb, SgmlDtd.cmterm, true);
}
token = token.ToUpperInvariant();
ch = this.m_current.Lastchar;
if (ch == '?' || ch == '+' || ch == '*')
{
cm.PushGroup();
cm.AddSymbol(token);
cm.AddOccurrence(ch);
cm.PopGroup();
this.m_current.ReadChar(); // skip connector
ch = this.m_current.SkipWhitespace();
}
else
{
cm.AddSymbol(token);
ch = this.m_current.SkipWhitespace();
}
}
}
}