Match stmt against the spec.

    Return None | spec'
    spec' is an updated spec with the matching spec consumed

def _match_stmt(ctx, stmt, specs, canonical):
    """Match stmt against the spec.

    Return None | spec'
    spec' is an updated spec with the matching spec consumed
    """
    (spec, canspec) = specs
    i = 0
    while i < len(spec):
        (keywd, occurance) = spec[i]
        if keywd == '$any':
            return (spec, canspec)
        if keywd == '$1.1':
            (keywd, occurance) = occurance
            if (stmt.i_module.i_version == '1' and
                keywd == stmt.keyword):
                return None
        if keywd == stmt.keyword:
            if occurance == '1' or occurance == '?':
                # consume this match
                if canonical == True:
                    return (spec[i+1:], spec_del_kwd(keywd, canspec))
                else:
                    return (spec[:i] + spec[i+1:], canspec)
            if occurance == '+':
                # mark that we have found the one that was needed
                c = (keywd, '*')
                if canonical == True:
                    return ([c] + spec[i+1:], canspec)
                else:
                    return (spec[:i] + [c] + spec[i+1:], canspec)
            else:
                # occurane == '*'
                if canonical == True:
                    return (spec[i:], canspec)
                else:
                    return (spec, canspec)
        elif keywd == '$choice':
            cases = occurance
            j = 0
            while j < len(cases):
                # check if this alternative matches - check for a
                # match with each optional keyword
                save_errors = copy.copy(ctx.errors)
                if spec == top_stmts:
                    match_res = _match_stmt(ctx, stmt, (cases[j],[]), False)
                else:
                    match_res = _match_stmt(ctx, stmt, (cases[j],cases[j]),
                                            canonical)
                if match_res != None:
                    # this case branch matched, use it.
                    # remove the choice and add res to the spec.
                    nspec = spec[:i] + match_res[0] + spec[i+1:]
                    return (nspec, canspec)
                # we must not report errors on non-matching branches
                ctx.errors = save_errors
                j += 1
        elif keywd == '$interleave':
            cspec = occurance
            match_res = _match_stmt(ctx, stmt, (cspec, cspec), canonical)
            if match_res != None:
                # we got a match
                return (spec, canspec)
        elif util.is_prefixed(stmt.keyword):
            # allow extension statements mixed with these
            # set canonical to False in this call to just remove the
            # matching stmt from the spec
            match_res = _match_stmt(ctx, stmt, (spec[i+1:], canspec), False)
            if match_res != None:
                return (spec[:i+1] + match_res[0], canspec)
            else:
                return None
        elif keywd == '$cut':
            # any non-optional statements left are errors
            for (keywd, occurance) in spec[:i]:
                if occurance == '1' or occurance == '+':
                    error.err_add(ctx.errors, stmt.pos, 'UNEXPECTED_KEYWORD_1',
                                  (util.keyword_to_str(stmt.raw_keyword),
                                   util.keyword_to_str(keywd)))
            # consume them so we don't report the same error again
            spec = spec[i:]
            i = 0
        elif canonical == True:
            if occurance == '1' or occurance == '+':
                error.err_add(ctx.errors, stmt.pos,
                              'UNEXPECTED_KEYWORD_CANONICAL_1',
                              (util.keyword_to_str(stmt.raw_keyword),
                               util.keyword_to_str(keywd)))
                # consume it so we don't report the same error again
                spec = spec[i:]
                i = 0
        # check next in spec
        i += 1
    return None