void ConstraintsParser::GenerateSyntaxTrees()

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