回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我有一个python项目来解析一些汇编代码</p>
<pre><code>asm_parser/
- asm.py
- AST.py
- obj_code.py
...
</code></pre>
<p>在语法下面,我将这个解析操作类设置为成功匹配(init函数获取标记)</p>
<pre><code>self.dir_map_code_fp = pp.OneOrMore(...).setParseAction(Body)
</code></pre>
<p>在AST.py中,函数<code>Body.__init__()</code>标记正在接收</p>
<pre><code>class Body(Node):
def __init__(self, tokens):
super(Body,self).__init__()
self.code = tokens
</code></pre>
<p>然后我使用输入文件字符串对语法调用<code>parseString()</code></p>
<pre><code>self.parser_asm.parseString(string, parseAll=True)
</code></pre>
<p>为了隐藏源代码,我使用cythonize将这些python文件转换为.so文件。下面是我用来创建.so文件的<strong>setup.py</strong>文件</p>
<pre><code>class MyBuildExt(build_ext):
def run(self):
build_ext.run(self)
build_dir = Path(self.build_lib)
root_dir = Path(__file__).parent
target_dir = build_dir if not self.inplace else root_dir
self.copy_file(Path('assembler') / '__init__.py', root_dir, target_dir)
self.copy_file(Path('assembler') / '__main__.py', root_dir, target_dir)
def copy_file(self, path, source_dir, destination_dir):
if not (source_dir / path).exists():
return
shutil.copyfile(str(source_dir / path), str(destination_dir / path))
if __name__ == '__main__':
ext_modules = [
Extension(...) for f in files
]
setup(
name="myasm",
ext_modules=cythonize(ext_modules, nthreads=8),
cmdclass=dict(build_ext=MyBuildExt),
packages=["asm"]
)
</code></pre>
<p>创建so文件后,我创建了一个run_asm.py文件,以将asm代码作为包装运行。我将所有so文件模块导入此run_asm.py</p>
<pre><code>import argparse
from asm import Preprocessor
if __name__ == "__main__":
argParser = argparse.ArgumentParser(description='Assembler')
argParser.add_argument('-asm', '--asm', required=True, help="Assembly file")
argParser.add_argument('-outdir', '--outdir', required=False, default='.', help="default_img directory")
args = argParser.parse_args()
prep = Preprocessor()
</code></pre>
<p>在纯python形式下,项目正在运行。在cythonized.so表单Argparsing中,在调用<code>Body.__init__()</code>函数之前,读取所有内容的文件都在工作。init函数只取两个,这里给出了四个</p>
<pre><code>Traceback (most recent call last):
File "run_asm.py", line 30, in <module>
prep.generate_ast(f, args.outdir)
File "pkg/asm.py", line 145, in pkg.assembler.Preprocessor.generate_ast
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 1206, in parseString
loc, tokens = self._parse( instring, 0 )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 1072, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 2923, in parseImpl
loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 1072, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 2607, in parseImpl
return e._parse( instring, loc, doActions )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 1098, in _parseNoCache
tokens = fn( instring, tokensStart, retTokens )
File "/u/nalaka/intelpython2/lib/python2.7/site-packages/pyparsing.py", line 819, in wrapper
ret = func(*args[limit[0]:])
File "pkg/AST.py", line 28, in pkg.AST.Body.__init__
TypeError: __init__() takes exactly 2 positional arguments (4 given)
</code></pre>
<p>我查看了pyparsing.py代码,下面的<code>func</code>是<code>Body.__init__()</code>函数。在纯python版本<code>limit[0] = 2</code>中,但在cythonized版本<code>limit[0] = 0</code>中,参数计数在这两个版本中发生了变化。我无法获得更多关于这方面的信息</p>
<pre><code>def wrapper(*args):
while 1:
try:
ret = func(*args[limit[0]:])
foundArity[0] = True
return ret
</code></pre>
<p>我还发现<code>parseAction()</code>是具有0-3个参数的可调用方法<code>C{fn(s,loc,toks)}, C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}</code>。我想知道这是否与此有关(不知怎么搞砸了争论的重点)
谁能帮我解决这个问题。我使用的是Intelpython2.7、pyparsing-2.4.7和Cython'0.25.2'</p>