Python AST-检测表达式中的非法标记

Python AST-检测表达式中的非法标记,python,algorithm,recursion,abstract-syntax-tree,Python,Algorithm,Recursion,Abstract Syntax Tree,我应该如何优化compile()函数(解析器)以: 仅接受标记:'numeric string(integer),ADD,SUB,MUL和DIV 检测非法令牌/表达式并显示错误(立即停止): 错误:#4处出现意外令牌 ADD、SUB、MUL和DIV必须预期正好两个令牌: ['numeric string(integer)或ADD或SUB或MUL或DIV] 及 ['numeric string(integer)或ADD或SUB或MUL或DIV] 函数应该从最内向的表达式开始计算表达式 代码

我应该如何优化
compile()
函数(解析器)以:

  • 仅接受标记:
    'numeric string(integer)
    ADD
    SUB
    MUL
    DIV

  • 检测非法令牌/表达式并显示错误(立即停止):

    错误:#4处出现意外令牌

  • ADD
    SUB
    MUL
    DIV
    必须预期正好两个令牌:

  • [
    'numeric string(integer)
    ADD
    SUB
    MUL
    DIV
    ]

    [
    'numeric string(integer)
    ADD
    SUB
    MUL
    DIV
    ]

  • 函数应该从最内向的表达式开始计算表达式

  • 代码:

    def is_operator(token):
        return (token in ['ADD', 'SUB', 'MUL', 'DIV'] or token.isnumeric())
    
    
    # Compiles a list of tokens
    # into an abstract syntax tree (AST). 
    # 
    # A token represents either a number (e.g. "42") 
    # or an operator ("ADD", "SUB", "MUL" or "DIV"). 
    # 
    # A node of the returned AST is either a string 
    # that represents a number (e.g. "42") 
    # or a tuple in the form of (operator, child1, child2) 
    # where child1 and child2 are the subtrees of the AST. 
    # 
    # This function returns (ast, unprocessed_tokens) 
    # where unprocessed_tokens are the tokens yet to compile. 
    # 
    def compile(tokens):
        if len(tokens) == 0:
            return ('NOOP',)
        token = tokens[0]
        if is_operator(token):
            child1, unprocessed = compile(tokens[1:])
            child2, unprocessed = compile(unprocessed)
            return (token, child1, child2), unprocessed
        else:
            return token, tokens[1:]
    
    
    line = ['ADD', 'SUB', '2', '2', 'MUL', '6', 'DIV', '10', '2']
    print(compile(line)[0])
    # => ('ADD', ('SUB', '2', '2'), ('MUL', '6', ('DIV', '10', '2')))
    

    样本#1:

    def is_operator(token):
        return (token in ['ADD', 'SUB', 'MUL', 'DIV'] or token.isnumeric())
    
    
    # Compiles a list of tokens
    # into an abstract syntax tree (AST). 
    # 
    # A token represents either a number (e.g. "42") 
    # or an operator ("ADD", "SUB", "MUL" or "DIV"). 
    # 
    # A node of the returned AST is either a string 
    # that represents a number (e.g. "42") 
    # or a tuple in the form of (operator, child1, child2) 
    # where child1 and child2 are the subtrees of the AST. 
    # 
    # This function returns (ast, unprocessed_tokens) 
    # where unprocessed_tokens are the tokens yet to compile. 
    # 
    def compile(tokens):
        if len(tokens) == 0:
            return ('NOOP',)
        token = tokens[0]
        if is_operator(token):
            child1, unprocessed = compile(tokens[1:])
            child2, unprocessed = compile(unprocessed)
            return (token, child1, child2), unprocessed
        else:
            return token, tokens[1:]
    
    
    line = ['ADD', 'SUB', '2', '2', 'MUL', '6', 'DIV', '10', '2']
    print(compile(line)[0])
    # => ('ADD', ('SUB', '2', '2'), ('MUL', '6', ('DIV', '10', '2')))
    
    输入:

    line = ['ADD', 'SUB', '3', '2', 'MUL', '6', 'DIV', '10', '2']
    
    line = ['ADD', '3', '2', '1']
    
    预期产出:

    AST: ('ADD', ('SUB', '3', '2'), ('MUL', '6', ('DIV', '10', '2')))
    
    ANSWER: 31
    
    ERROR: Unexpected token at # 4
    

    样本#2:

    def is_operator(token):
        return (token in ['ADD', 'SUB', 'MUL', 'DIV'] or token.isnumeric())
    
    
    # Compiles a list of tokens
    # into an abstract syntax tree (AST). 
    # 
    # A token represents either a number (e.g. "42") 
    # or an operator ("ADD", "SUB", "MUL" or "DIV"). 
    # 
    # A node of the returned AST is either a string 
    # that represents a number (e.g. "42") 
    # or a tuple in the form of (operator, child1, child2) 
    # where child1 and child2 are the subtrees of the AST. 
    # 
    # This function returns (ast, unprocessed_tokens) 
    # where unprocessed_tokens are the tokens yet to compile. 
    # 
    def compile(tokens):
        if len(tokens) == 0:
            return ('NOOP',)
        token = tokens[0]
        if is_operator(token):
            child1, unprocessed = compile(tokens[1:])
            child2, unprocessed = compile(unprocessed)
            return (token, child1, child2), unprocessed
        else:
            return token, tokens[1:]
    
    
    line = ['ADD', 'SUB', '2', '2', 'MUL', '6', 'DIV', '10', '2']
    print(compile(line)[0])
    # => ('ADD', ('SUB', '2', '2'), ('MUL', '6', ('DIV', '10', '2')))
    
    输入:

    line = ['ADD', 'SUB', '3', '2', 'MUL', '6', 'DIV', '10', '2']
    
    line = ['ADD', '3', '2', '1']
    
    预期产出:

    AST: ('ADD', ('SUB', '3', '2'), ('MUL', '6', ('DIV', '10', '2')))
    
    ANSWER: 31
    
    ERROR: Unexpected token at # 4
    

    PS:

    def is_operator(token):
        return (token in ['ADD', 'SUB', 'MUL', 'DIV'] or token.isnumeric())
    
    
    # Compiles a list of tokens
    # into an abstract syntax tree (AST). 
    # 
    # A token represents either a number (e.g. "42") 
    # or an operator ("ADD", "SUB", "MUL" or "DIV"). 
    # 
    # A node of the returned AST is either a string 
    # that represents a number (e.g. "42") 
    # or a tuple in the form of (operator, child1, child2) 
    # where child1 and child2 are the subtrees of the AST. 
    # 
    # This function returns (ast, unprocessed_tokens) 
    # where unprocessed_tokens are the tokens yet to compile. 
    # 
    def compile(tokens):
        if len(tokens) == 0:
            return ('NOOP',)
        token = tokens[0]
        if is_operator(token):
            child1, unprocessed = compile(tokens[1:])
            child2, unprocessed = compile(unprocessed)
            return (token, child1, child2), unprocessed
        else:
            return token, tokens[1:]
    
    
    line = ['ADD', 'SUB', '2', '2', 'MUL', '6', 'DIV', '10', '2']
    print(compile(line)[0])
    # => ('ADD', ('SUB', '2', '2'), ('MUL', '6', ('DIV', '10', '2')))
    
    我知道解析库,我不会朝这个方向走。我需要通过使用本地python代码来解决这个问题


    我已经编写了
    lexer()
    函数。

    你的问题到底是什么?问题更新了。你的问题到底是什么?问题更新了。