忽略除了我为其创建解析器的位之外的所有内容

时间:2017-07-18 13:05:08

标签: antlr antlr4

我正在尝试从几千个库的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='tarek@ziade.org',
    maintainer='Ian Cordasco',
    maintainer_email='graffatcolmingov@gmail.com',
    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',
    ],
)

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

1 个答案:

答案 0 :(得分: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. 对每个输入文件重复。