2017-07-18 47 views
1

我试图从几千个库的setup.py中提取setup_requirestest_requires值。我有这个语法忽略除了我创建解析器的位

grammar SetupPy ; 

file_input: (ignore setupRequires | ignore testRequires)* EOF; 

setupRequires : SETUPDEC '[' dependencyValue* (',' dependencyValue)* ']'; 
testRequires : TESTDEC '[' dependencyValue* (',' dependencyValue)* ']'; 
ignore: UNKNOWN_CHAR; 
dependencyValue: LISTVAL; 

//ignore : UNKNOWN_CHAR? ; 

LISTVAL: SHORT_STRING; 
SETUPDEC: 'setup_requires' '='; 
TESTDEC: 'tests_require' '='; 
UNKNOWN_CHAR: . -> channel(HIDDEN); 

fragment SHORT_STRING: '\'' (STRING_ESCAPE_SEQ | ~[\\\r\n\f'])* '\'' 
| '"' (STRING_ESCAPE_SEQ | ~[\\\r\n\f"])* '"'; 

fragment STRING_ESCAPE_SEQ 
: '\\' . 
| '\\' 
; 

它是一个非常简单的例子。但是,当我把它放在一个完整的文件中时,令牌就会被绊倒在文件中的其他东西上。

# -*- coding: utf-8 -*- 
from __future__ import with_statement 

from setuptools import setup 


def get_version(fname='mccabe.py'): 
    with open(fname) as f: 
     for line in f: 
      if line.startswith('__version__'): 
       return eval(line.split('=')[-1]) 


def get_long_description(): 
    descr = [] 
    for fname in ('README.rst',): 
     with open(fname) as f: 
      descr.append(f.read()) 
    return '\n\n'.join(descr) 


setup(
    name='mccabe', 
    version=get_version(), 
    description="McCabe checker, plugin for flake8", 
    long_description=get_long_description(), 
    keywords='flake8 mccabe', 
    author='Tarek Ziade', 
    author_email='[email protected]', 
    maintainer='Ian Cordasco', 
    maintainer_email='[email protected]', 
    url='https://github.com/pycqa/mccabe', 
    license='Expat license', 
    py_modules=['mccabe'], 
    zip_safe=False, 
    setup_requires=['pytest-runner'], 
    tests_require=['pytest'], 
    entry_points={ 
     'flake8.extension': [ 
      'C90 = mccabe:McCabeChecker', 
     ], 
    }, 
    classifiers=[ 
     'Development Status :: 5 - Production/Stable', 
     'Environment :: Console', 
     'Intended Audience :: Developers', 
     'License :: OSI Approved :: MIT License', 
     'Operating System :: OS Independent', 
     'Programming Language :: Python', 
     'Programming Language :: Python :: 2', 
     'Programming Language :: Python :: 2.7', 
     'Programming Language :: Python :: 3', 
     'Programming Language :: Python :: 3.3', 
     'Programming Language :: Python :: 3.4', 
     'Programming Language :: Python :: 3.5', 
     'Programming Language :: Python :: 3.6', 
     'Topic :: Software Development :: Libraries :: Python Modules', 
     'Topic :: Software Development :: Quality Assurance', 
    ], 
) 

如何设置此语法忽略除了指定的两个值之外的所有内容?

+0

我认为你正处在正确的轨道上。我很乐意很快看到它。 – TomServo

回答

0

看过你以前的问题和解析简化输入的简易性后,我认为最快的方法是对这些文件进行简单的文本预处理,丢弃所有你不需要的东西并保留这两个文件您感兴趣的零件。 示例:

  1. 打开每个文件。
  2. 将整个文件读入字符串变量。
  3. 查找令牌的起始位置setup_requires
  4. 从那个位置开始,由于它们是数组,所以查找下一个出现]的位置,这将表示setup_requires数组定义的结束。
  5. 使用这些索引,将完整句子setup_requires=['pytest-runner']写入输出文件。
  6. 遵循类似的方法为标记tests_require,附加到输出文件。
  7. 现在使用我在other answer which worked on the simple input中提出的语法解析极其简化的输出文件。通过这种方式,您可以避免解析所有其他问题,并且可以利用我之前做的正确答案。
  8. 对每个输入文件重复。
+0

那么,这当然是可行的。我给它一个镜头。所以antlr没有设置为“搜索和解析”它的真正设置来解析完整的文件hu。 – scphantm

+0

@scphantm是的,它旨在解析完整的输入流。所以我的方法基本上是使用一些简单的文本处理来提供一个输入流,我已经帮助你获得了正确的语法。语言是你的选择,文本处理很容易。你可以做到,而且很快,我想! – TomServo

+0

我有这个东西在抽搐。在语法上快速一个。使用列表值片段,它返回引号和双引号。我如何修改该过滤出来,只给我的文字? – scphantm