[Python] Recursive parsing of flat list as nested structure

Discussão em 'Python' iniciado por Stack, Março 18, 2025.

  1. Stack

    Stack Membro Participativo

    This is sort of a follow up to How to parse a nested structure presented as a flat list?. Read it for the long explanation.

    My current code:

    def parse(code: list, top=True) -> tuple:
    print(code)
    result = []
    stack = []
    i = 0
    while i < len(code):
    nonzero_tokens = []
    for index, token in enumerate(code[i:], start=i):
    if not top or (token[0] != 0 or (len(code) <= index + 1 or code[index + 1][0] == 0)):
    nonzero_tokens.append((token, index))
    if len(nonzero_tokens) == 4:
    break
    key1, key2, key3, pos = nonzero_tokens
    if stack:
    if top and (len(code) > pos[1] + 1 and code[pos[1] + 1][0] == 0) and (len(code) <= pos[1] + 2 or code[pos[1] + 2][0] != 0):
    result[-1][-1].append(key1[0])
    i = key1[1] + 1
    elif pos[0][0] == 1:
    stack.append((key1[0][0], key2[0][0], key3[0][0]))
    result[-1][-1] += [key1[0], key2[0], key3[0], pos[0]]
    i = pos[1] + 1
    elif (key1[0][0], key2[0][0], key3[0][0]) == stack[-1]:
    if pos[0][0] == -1:
    if len(stack) > 1:
    result[-1][-1] += [key1[0], key2[0], key3[0], pos[0]]
    stack.pop()
    i = pos[1] + 1
    else:
    if len(stack) == 1:
    result[-1].append([pos[0]])
    else:
    result[-1][-1] += [key1[0], key2[0], key3[0], pos[0]]
    i = pos[1] + 1
    else:
    result[-1][-1].append(key1[0])
    i = key1[1] + 1
    else:
    if pos[0][0] == 1:
    result.append([(key1[0], key2[0], key3[0]), [1]])
    stack.append((key1[0][0], key2[0][0], key3[0][0]))
    i = pos[1] + 1
    else:
    raise SyntaxError(f'function {key1[0][0]}.{key2[0][0]}.{key3[0][0]} at line {key1[0][1][0]}, position {key1[0][1][1]} has no opening instruction {key1[0][0]}.{key2[0][0]}.{key3[0][0]}.1')
    for i, call in enumerate(result):
    new_call = [call[0], {}]
    for argument in call[1:]:
    try:
    new_call[1][argument[0]] = Parser.parse(argument[1:], top=False)[0]
    except:
    new_call[1][argument[0]] = argument[1:]
    result = new_call
    return result, stack


    Example input:

    [(3, (1, 1)), (2, (1, 3)), (1, (1, 5)), (1, (1, 7)), (5, (2, 2)), (3, (2, 4)), (1, (2, 6)), (1, (2, 8)), (72, (2, 12)), (101, (2, 16)), (108, (2, 21)), (108, (2, 26)), (111, (2, 31)), (44, (2, 36)), (32, (2, 40)), (87, (2, 44)), (111, (2, 48)), (114, (2, 53)), (108, (2, 58)), (109, (2, 63)), (33, (2, 68)), (5, (3, 2)), (3, (3, 4)), (1, (3, 6)), (0, (3, 8)), (-1, (3, 11)), (3, (4, 1)), (2, (4, 3)), (1, (4, 5)), (-1, (4, 8))]


    Source file for reference:

    3.2.1.1 = Start of print
    5.3.1.1 = 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 109, 33 Makes the string "Hello, World!"
    5.3.1.0.-1 End of string
    3.2.1.-1 ^ End of print
    # Escape characters so that 33.5.3.1 is not interpreted as a function call
    ^ Comment marker because the above comment contains numbers


    Expected output:

    [[((3, (1, 1)), (2, (1, 3)), (1, (1, 5))), {1: [[((5, (2, 2)), (3, (2, 4)), (1, (2, 6))), {1: (72, (2, 12)), (101, (2, 16)), (108, (2, 21)), (108, (2, 26)), (111, (2, 31)), (44, (2, 36)), (32, (2, 40)), (87, (2, 44)), (111, (2, 48)), (114, (2, 53)), (108, (2, 58)), (109, (2, 63)), (33, (2, 68)), (5, (3, 2)), (3, (3, 4)), (1, (3, 6)), (-1, (3, 11))}]]}]]


    Actual output:

    [[((3, (1, 1)), (2, (1, 3)), (1, (1, 5))), {1: [(5, (2, 2)), (3, (2, 4)), (1, (2, 6)), (1, (2, 8)), (72, (2, 12)), (101, (2, 16)), (108, (2, 21)), (108, (2, 26)), (111, (2, 31)), (44, (2, 36)), (32, (2, 40)), (87, (2, 44)), (111, (2, 48)), (114, (2, 53)), (108, (2, 58)), (109, (2, 63)), (33, (2, 68)), (5, (3, 2)), (3, (3, 4)), (1, (3, 6)), (-1, (3, 11))]}]]


    Basically, as you can see, there is a zero to escape 33.5.3.1, but that zero is not passed to the recursive call. I don't know how I can fix this. There are already several different fixes layered onto this overtly complex function. Please help.

    Continue reading...

Compartilhe esta Página