예제 #1
0
def parse_raw_sql(sql):
    result = raw_sql_cache.get(sql)
    if result is not None: return result
    assert isinstance(sql, basestring) and len(sql) > 0
    items = []
    codes = []
    pos = 0
    while True:
        try:
            i = sql.index('$', pos)
        except ValueError:
            items.append(sql[pos:])
            break
        items.append(sql[pos:i])
        if sql[i + 1] == '$':
            items.append('$')
            pos = i + 2
        else:
            try:
                expr, _ = parse_expr(sql, i + 1)
            except ValueError:
                raise ValueError(sql[i:])
            pos = i + 1 + len(expr)
            if expr.endswith(';'): expr = expr[:-1]
            code = compile(expr, '<?>', 'eval')  # expr correction check
            codes.append(code)
            items.append((expr, code))
    result = tuple(items), tuple(codes)
    raw_sql_cache[sql] = result
    return result
예제 #2
0
def parse_markup(source, start_pos=0, nested=False):
    text = source[0]

    def remove_spaces(tree):
        for i in range(3, len(tree)):
            item = tree[i]
            prev = tree[i - 1]
            if isinstance(item, basestring) and isinstance(prev, tuple):
                prev_markups = prev[4]
                if prev_markups: tree[i] = newline_re.sub('', item)
        if not nested or len(tree) == 2: return tree
        assert text[start_pos - 1] == '{'
        start = tree[2]
        if text[start_pos - 2] != '\\':
            if isinstance(start, basestring):
                tree[2] = newline_re.sub('', start)
            return tree
        if isinstance(start, basestring): tree[2] = start.lstrip()
        end = tree[-1]
        if isinstance(end, basestring): tree[-1] = end.rstrip()
        return tree

    pos = start_pos
    result = [pos, None]
    brace_counter = 0
    while True:
        match = main_re.search(text, pos)
        if not match:
            if nested or brace_counter:
                raise ParseError('Unexpected end of text', source, len(text))
            result.append(text[pos:])
            end = len(text)
            result[1] = end - 1
            return remove_spaces(joinstrings(result)), end
        start, end = match.span()
        i = match.lastindex
        if start != pos: result.append(text[pos:start])
        if i == 1:  # {
            brace_counter += 1
            result.append('{')
        elif i == 2:  # }
            if not brace_counter:
                if nested:
                    result[1] = end - 1
                    return remove_spaces(joinstrings(result)), end
                raise ParseError("Unexpected symbol '}'", source, end)
            brace_counter -= 1
            result.append('}')
        elif i == 3:  # @@
            result.append('@')
        elif i == 4:  # @/* comment */ or @// comment
            pass
        elif i in (5, 6):  # @(expression) or @{i18n markup}
            command, end = parse_command(source, start, end - 1, None)
            result.append(command)
        elif i >= 7:
            cmd_name = match.group(7)
            if cmd_name is not None and cmd_name.startswith('+'):
                if not is_ident(cmd_name[1:]):
                    raise ParseError('Invalid method call', source, start)
            if i == 7:  # @expression
                try:
                    expr, _ = utils.parse_expr(text, start + 1)
                except ValueError:
                    raise ParseError('Invalid Python expression', source,
                                     start + 1)
                end = start + 1 + len(expr)
                if expr.endswith(';'): expr = expr[:-1]
                result.append((start, end, None, expr, None))
            elif i == 8:  # @function.call(...)
                command, end = parse_command(source, match.start(), end - 1,
                                             cmd_name)
                result.append(command)
        pos = end
def parse_markup(source, start_pos=0, nested=False):
    text = source[0]
    def remove_spaces(tree):
        for i in range(3, len(tree)):
            item = tree[i]
            prev = tree[i-1]
            if isinstance(item, basestring) and isinstance(prev, tuple):
                prev_markups = prev[4]
                if prev_markups: tree[i] = newline_re.sub('', item)
        if not nested or len(tree) == 2: return tree
        assert text[start_pos-1] == '{'
        start = tree[2]
        if text[start_pos-2] != '\\':
            if isinstance(start, basestring): tree[2] = newline_re.sub('', start)
            return tree
        if isinstance(start, basestring): tree[2] = start.lstrip()
        end = tree[-1]
        if isinstance(end, basestring): tree[-1] = end.rstrip()
        return tree
    pos = start_pos
    result = [pos, None]
    brace_counter = 0
    while True:
        match = main_re.search(text, pos)
        if not match:
            if nested or brace_counter:
                raise ParseError('Unexpected end of text', source, len(text))
            result.append(text[pos:])
            end = len(text)
            result[1] = end-1
            return remove_spaces(joinstrings(result)), end
        start, end = match.span()
        i = match.lastindex
        if start != pos: result.append(text[pos:start])
        if i == 1:  # {
            brace_counter += 1
            result.append('{')
        elif i == 2:  # }
            if not brace_counter:
                if nested:
                    result[1] = end-1
                    return remove_spaces(joinstrings(result)), end
                raise ParseError("Unexpected symbol '}'", source, end)
            brace_counter -= 1
            result.append('}')
        elif i == 3: # @@
            result.append('@')
        elif i == 4: # @/* comment */ or @// comment
            pass
        elif i in (5, 6): # @(expression) or @{i18n markup}
            command, end = parse_command(source, start, end-1, None)
            result.append(command)
        elif i >= 7:
            cmd_name = match.group(7)
            if cmd_name is not None and cmd_name.startswith('+'):
                if not is_ident(cmd_name[1:]): raise ParseError('Invalid method call', source, start)
            if i == 7: # @expression
                try: expr, _ = utils.parse_expr(text, start+1)
                except ValueError: raise ParseError('Invalid Python expression', source, start+1)
                end = start+1 + len(expr)
                if expr.endswith(';'): expr = expr[:-1]
                result.append((start, end, None, expr, None))
            elif i == 8: # @function.call(...)
                command, end = parse_command(source, match.start(), end-1, cmd_name)
                result.append(command)
        pos = end