'Generates a coarse AST for the router.'

def _generate_ast(self, nodes, parent, return_values, patterns, level=0, fast_return=True):

    if (not nodes):
        return
    outer_parent = _CxIfPathLength('>', level)
    parent.append_child(outer_parent)
    parent = outer_parent
    found_simple = False
    nodes = sorted(nodes, key=(lambda node: (node.is_var + (node.is_var and (not node.is_complex)))))
    if fast_return:
        if (len(nodes) > 1):
            var_nodes = [node for node in nodes if node.is_var]
            found_var_nodes = bool(var_nodes)
            fast_return = (not found_var_nodes)
    for node in nodes:
        if node.is_var:
            if node.is_complex:
                pattern_idx = len(patterns)
                patterns.append(node.var_pattern)
                construct = _CxIfPathSegmentPattern(level, pattern_idx, node.var_pattern.pattern)
                parent.append_child(construct)
                parent = construct
                if node.var_converter_map:
                    parent.append_child(_CxPrefetchGroupsFromPatternMatch())
                    parent = self._generate_conversion_ast(parent, node)
                else:
                    parent.append_child(_CxSetParamsFromPatternMatch())
            else:
                if node.var_converter_map:
                    assert (len(node.var_converter_map) == 1)
                    parent.append_child(_CxSetFragmentFromPath(level))
                    field_name = node.var_name
                    (__, converter_name, converter_argstr) = node.var_converter_map[0]
                    converter_class = self._converter_map[converter_name]
                    converter_obj = self._instantiate_converter(converter_class, converter_argstr)
                    converter_idx = len(self._converters)
                    self._converters.append(converter_obj)
                    construct = _CxIfConverterField(field_name, converter_idx)
                    parent.append_child(construct)
                    parent = construct
                else:
                    parent.append_child(_CxSetParam(node.var_name, level))
                assert (len([_node for _node in nodes if (_node.is_var and (not _node.is_complex))]) == 1)
                found_simple = True
        else:
            construct = _CxIfPathSegmentLiteral(level, node.raw_segment)
            parent.append_child(construct)
            parent = construct
        if (node.resource is not None):
            resource_idx = len(return_values)
            return_values.append(node)
        self._generate_ast(node.children, parent, return_values, patterns, (level + 1), fast_return)
        if (node.resource is None):
            if fast_return:
                parent.append_child(_CxReturnNone())
        else:
            construct = _CxIfPathLength('==', (level + 1))
            construct.append_child(_CxReturnValue(resource_idx))
            parent.append_child(construct)
            if fast_return:
                parent.append_child(_CxReturnNone())
        parent = outer_parent
    if ((not found_simple) and fast_return):
        parent.append_child(_CxReturnNone())
