【问题标题】:Transform a code tokens list into valid string code将代码标记列表转换为有效的字符串代码
【发布时间】:2021-07-02 03:29:58
【问题描述】:

我已经编写了将 Python 代码转换为列表以计算 BLEU score 的代码:

import re

def tokenize_for_bleu_eval(code):
    code = re.sub(r'([^A-Za-z0-9_])', r' \1 ', code)
    code = re.sub(r'([a-z])([A-Z])', r'\1 \2', code)
    code = re.sub(r'\s+', ' ', code)
    code = code.replace('"', '`')
    code = code.replace('\'', '`')
    tokens = [t for t in code.split(' ') if t]

    return tokens

感谢这个 sn-p 我的代码 struct.unpack('h', pS[0:2]) 被正确解析到列表 ['struct', '.', 'unpack', '(', 'h', ',', 'p', 'S', '[', '0', ':', '2', ']', ')'] 中。

最初,我以为我只需要使用 ' '.join(list_of_tokens),但它会像 struct . unpack ('h' , p S [ 0 : 2 ] ) 这样杀死我的变量名,并且我的代码不可执行。

我尝试使用正则表达式粘贴一些变量名,但我无法成功反转我的函数tokenize_for_bleu_eval 以在最后找到可执行代码。有人有想法吗,也许没有正则表达式,这似乎太复杂了?

编辑:我们不能只删除列表元素之间的所有空格,因为有像items = [item for item in container if item.attribute == value] 这样的示例,其中没有空格的回译结果将是itemforiteminaifitem[0]==1,这是无效的。

【问题讨论】:

  • 您能否举例说明您的样本列表的正确输出?
  • 我不确定你的意思。预期的输出是初始代码,即struct.unpack('h', pS[0:2])
  • Regex 在这里看起来像是一个非常不合适的工具。您是否考虑过 Python 代码解析器方法?我没试过,但是you might find some tips here.

标签: python python-3.x regex


【解决方案1】:

我正在尝试使用此脚本合并标记

import re

def tokenize_for_bleu_eval(code):
    code = re.sub(r'([^A-Za-z0-9_])', r' \1 ', code)
    code = re.sub(r'([a-z])([A-Z])', r'\1 \2', code)
    code = re.sub(r'\s+', ' ', code)
    code = code.replace('"', '`')
    code = code.replace('\'', '`')
    tokens = [t for t in code.split(' ') if t]

    return tokens

def merge_tokens(tokens):
    code = ''.join(tokens)
    code = code.replace('`', "'")
    code = code.replace(',', ", ")

    return code

tokenize = tokenize_for_bleu_eval("struct.unpack('h', pS[0:2])")
print(tokenize)  # ['struct', '.', 'unpack', '(', '`', 'h', '`', ',', 'p', 'S', '[', '0', ':', '2', ']', ')']
merge_result = merge_tokens(tokenize)
print(merge_result)  # struct.unpack('h', pS[0:2])

编辑:

我发现了这个有趣的想法来标记和合并。

import re

def tokenize_for_bleu_eval(code):
    tokens_list = []
    codes = code.split(' ')
    for i in range(len(codes)):
        code = codes[i]
        code = re.sub(r'([^A-Za-z0-9_])', r' \1 ', code)
        code = re.sub(r'([a-z])([A-Z])', r'\1 \2', code)
        code = re.sub(r'\s+', ' ', code)
        code = code.replace('"', '`')
        code = code.replace('\'', '`')
        tokens = [t for t in code.split(' ') if t]
        tokens_list.append(tokens)
        if i != len(codes) -1:
            tokens_list.append([' '])
    
    flatten_list = []

    for tokens in tokens_list:
        for token in tokens:
            flatten_list.append(token)

    return flatten_list

def merge_tokens(flatten_list):
    code = ''.join(flatten_list)
    code = code.replace('`', "'")

    return code

test1 ="struct.unpack('h', pS[0:2])"
test2 = "items = [item for item in container if item.attribute == value]"
tokenize = tokenize_for_bleu_eval(test1)
print(tokenize)  # ['struct', '.', 'unpack', '(', '`', 'h', '`', ',', ' ', 'p', 'S', '[', '0', ':', '2', ']', ')']
merge_result = merge_tokens(tokenize)
print(merge_result)  # struct.unpack('h', pS[0:2])

tokenize = tokenize_for_bleu_eval(test2)
print(tokenize)  # ['items', ' ', '=', ' ', '[', 'item', ' ', 'for', ' ', 'item', ' ', 'in', ' ', 'container', ' ', 'if', ' ', 'item', '.', 'attribute', ' ', '=', '=', ' ', 'value', ']']
merge_result = merge_tokens(tokenize)
print(merge_result)  # items = [item for item in container if item.attribute == value]

此脚本还将记住输入中的每个空格

【讨论】:

  • 对不起,我已经更新了我的答案以说明为什么它不起作用,我的例子不是最小的
  • 说的有道理,我会尝试另辟蹊径
猜你喜欢
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 2018-03-05
相关资源
最近更新 更多