in cli/cparser.cpp [15:104]
void ConstraintsParser::GenerateSyntaxTrees()
{
// Walk through all tokens. There are three possible types of statements:
// 1. IF condition THEN term ELSE term2
// 2. IF condition THEN term
// 3. term
for( auto & tokenList : _tokenLists )
{
CTokenList::iterator token = tokenList.begin();
CTokenList::iterator tokenFirst, tokenLast;
if ( (*token)->Type == TokenType::KeywordIf )
{
CConstraint constraintThen;
CConstraint constraintElse;
// parse from first item past IF to last before THEN
tokenFirst = ++token;
while( TokenType::KeywordThen != (*token)->Type )
{
++token;
}
tokenLast = token;
constraintThen.Condition = constructSyntaxTreeItem( tokenFirst, tokenLast, false );
constraintElse.Condition = constructSyntaxTreeItem( tokenFirst, tokenLast, true );
// move the pointer past THEN
tokenFirst = ++tokenLast;
// look for ELSE
CTokenList::iterator elseKeyword = token;
while( elseKeyword != tokenList.end() )
{
if ( TokenType::KeywordElse == (*elseKeyword)->Type ) break;
++elseKeyword;
}
// evaluate THEN part; add first constraint to the collection
constraintThen.Term = constructSyntaxTreeItem( tokenFirst, elseKeyword, true );
_constraints.push_back( constraintThen );
// if ELSE part exists, construct the syntax tree, else: clean up
if ( elseKeyword != tokenList.end() )
{
constraintElse.Term = constructSyntaxTreeItem( ++elseKeyword, tokenList.end(), true );
_constraints.push_back( constraintElse );
}
else
{
delete( constraintElse.Condition );
}
}
else
{
// unconditional; only the Term side exists
CConstraint constraint;
constraint.Term = constructSyntaxTreeItem( tokenList.begin(), tokenList.end(), true );
_constraints.push_back( constraint );
}
}
// we want to get rid of all NOT nodes from the tree to simplify the work
removeNOTs();
// validate the constraints
CConstraints::iterator i_currentConstraint = _constraints.begin();
unsigned int constraintIndex = 0;
while( i_currentConstraint != _constraints.end() )
{
try
{
verifyConstraint( *i_currentConstraint );
++i_currentConstraint;
}
catch( CSemanticWarning w )
{
// add to warnings, remove constraint from collection being returned
w.ErrInConstraint = constraintIndex;
_warnings.push_back( w );
i_currentConstraint = _constraints.erase( i_currentConstraint );
}
catch( CErrValidation e )
{
// augment with a constraint index and re-throw for the caller to handle
e.ErrInConstraint = constraintIndex;
throw e;
}
++constraintIndex;
}
}