对于一种小语言,我想解析X
形式的表达式,其中Y
,Z
,V
,from pyparsing import *
class Y():
def __init__(self, ls):
self.ls = ls
def MakeCombinedList(tokens):
print(len(tokens)) # prints 4
print(tokens) # [5, 1, 2, 3]
clist = tokens[1]
clist.append(tokens[0]) # 'int' attribute object has no attribute 'append'
return clist
def MakeIntList(tokens):
nlist = tokens[0].split(",")
ilist = []
for n in nlist:
ilist.append(int(n))
return ilist
def MakeY(tokens):
Yobj = Y(tokens[0])
return Yobj
LEFT_BRACK = Suppress(Literal("["))
RIGHT_BRACK = Suppress(Literal("]"))
NATURAL = Word(nums).addParseAction(lambda n: int(n[0]))
NATURAL_LIST = delimitedList(NATURAL, combine = True)
NATURAL_VEC = LEFT_BRACK + NATURAL_LIST + RIGHT_BRACK
NATURAL_VEC.addParseAction(MakeIntList)
X = NATURAL + NATURAL_VEC
X.addParseAction(MakeCombinedList)
Y = X
Y.addParseAction(MakeY)
print(Y.parseString("5 [1,2,3]").ls)
是自然数。>
下面是我的尝试。
MakeIntList
"1,2,3"
应该将诸如[1,2,3]
之类的字符串转换为列表MakeCombinedList
。
tokens
将一个整数添加到此列表,但是MakeCombinedList
收到的MakeIntList
不是单个整数,也不是从tokens[1]
创建的整数列表,而是所有整数的列表,如我的评论所示。
如何使MakeCombinedList
中的MakeIntList
成为调用mypath='/Users/sachal/Desktop/data_raw/normal_1/images'
onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath,f)) ]
images = np.asarray(np.empty(len(onlyfiles), dtype=object))
for n in range(0, len(onlyfiles)):
images[n] = cv2.imread( join(mypath,onlyfiles[n]) )
#--------------------------------------------------------------------------------
resized = np.asarray(np.empty(len(onlyfiles), dtype=object))
img_f = np.asarray(np.empty(len(onlyfiles), dtype=object))
for n in range(0, len(onlyfiles)):
resized[n] = cv2.resize(images[n],(101,101))
img_f[n] = cv2.cvtColor(resized[n], cv2.COLOR_BGR2YUV)
train_img = np.asarray(img_f)
#--------------------------------------------------------------------------------
的结果?
答案 0 :(得分:2)
由于您使用第一行将单独的数字字符串解析为int,然后使用第二行将它们重新组合成一个逗号分隔的字符串,因此这两行是相互冲突的。
NATURAL = Word(nums).addParseAction(lambda n: int(n[0]))
NATURAL_LIST = delimitedList(NATURAL, combine=True)
您要查找的功能是Group
:
NATURAL = Word(nums).addParseAction(lambda n: int(n[0]))
NATURAL_LIST = Group(delimitedList(NATURAL))
NATURAL_VEC = LEFT_BRACK + NATURAL_LIST + RIGHT_BRACK
# no MakeIntList parse action required
现在,您不用创建新的字符串,而是在解析操作中重新解析它,而是使用Group
告诉pyparsing生成结果标记的子结构。
这里还有些混乱:
Y = X
Y.addParseAction(MakeY)
这会将Y
从顶部定义的类重新定义为pyparsing表达式,并且在尝试访问其ls
属性时会得到一些奇怪的回溯。
Y_expr = X
Y_expr.addParseAction(MakeY)
我编写了runTests
方法,以使其更容易进行简单的表情测试和打印,而不必处理Py2 / Py3的打印差异:
Y_expr.runTests("""\
5 [1,2,3]
""")
显示:
5 [1,2,3]
[<__main__.Y object at 0x00000241C57B7630>]
由于您的Y类仅使用默认的__repr__
行为,因此,如果您定义自己的类,则可以更好地查看内容:
class Y():
def __init__(self, ls):
self.ls = ls
def __repr__(self):
return "{}: {}".format(type(self).__name__, vars(self))
现在runTests显示:
5 [1,2,3]
[Y: {'ls': 5}]
如果Y类的目的只是为您提供已解析字段的属性名称,请考虑改用结果名称:
X = NATURAL('ls') + NATURAL_VEC
Y_expr = X
#~ Y_expr.addParseAction(MakeY)
# what you had written originally
print(Y_expr.parseString("5 [1,2,3]").ls)
只需打印:
5