Skip to content

Instantly share code, notes, and snippets.

@timgluz
Last active December 16, 2015 20:39
Show Gist options
  • Select an option

  • Save timgluz/5494080 to your computer and use it in GitHub Desktop.

Select an option

Save timgluz/5494080 to your computer and use it in GitHub Desktop.
Python Setup parser by using instaparser
(insta/parse parser "install_requires = ['argparse', 'requests>=1.1.0,<1.3.0', 'colorama>=0.9,!=1.1,!=1.2.1,<=1.4.1a3']")
[:PYTHON_SETUP_PARSER
"install_requires"
"="
"["
[:SEQ-OF-REQUIREMENT
[:REQUIREMENT "argparse"]
[:REQUIREMENT
"requests"
[:VERSION_RANGE
[:VERSION_TOKEN [:COMPARATOR ">="] "1.1.0"]
[:VERSION_TOKEN [:COMPARATOR "<"] "1.3.0"]]]
[:REQUIREMENT
"colorama"
[:VERSION_RANGE
[:VERSION_TOKEN [:COMPARATOR ">="] "0.9"]
[:VERSION_TOKEN [:COMPARATOR "!="] "1.1"]
[:VERSION_TOKEN [:COMPARATOR "!="] "1.2.1"]
[:VERSION_TOKEN [:COMPARATOR "<="] "1.4.1a3"]]]]
"]"]
(ns propar.python-setup
(:require [instaparse.core :as insta]))
(def test-data (slurp "resource/examples/setup.py"))
(insta/set-default-output-format! :hiccup)
;;atomic rules
(def whitespace "WHITESPACE = #'\\s*';")
;; rules for parser
(def parser-rules (str "
PYTHON_SETUP_PARSER = 'install_requires' <WHITESPACE> '=' <WHITESPACE> '[' SEQ-OF-REQUIREMENT ']';
SEQ-OF-REQUIREMENT = <WHITESPACE> *{REQUIREMENT ?[<SEQ_SEPARATOR>]};
REQUIREMENT = <APOSTROPHE> MODULE_NAME ?[VERSION_RANGE] <APOSTROPHE>;
MODULE_NAME = (LETTER+ | NUMBER+ | LITERAL_SYMBOL)*;
VERSION_RANGE = (VERSION_TOKEN ?[<SEQ_SEPARATOR>])+;
VERSION_TOKEN = COMPARATOR VERSION_LITERAL;
COMPARATOR = ('<' | '>' | '<=' | '>=' | '==' | '!=');
VERSION_LITERAL = (NUMBER+ | VERSION_SYMBOL)* ?[RELEASE_LITERAL];
RELEASE_LITERAL = (LETTER+ NUMBER*) | 'pre-release' ;
<LETTER> = #'[a-zA-Z]';
<NUMBER> = #'\\d';
<VERSION_SYMBOL> = '.';
<LITERAL_SYMBOL> = '_' | '.';
<SEQ_SEPARATOR> = WHITESPACE ',' WHITESPACE;
<APOSTROPHE> = '\\'' | #'\"' ;
<WHITESPACE> = #'\\s*';"
))
(def parser (insta/parser parser-rules))
(insta/parse parser "install_requires=[]")
(insta/parse parser "install_requires=['a']")
(insta/parse python-setup-parser "install_requires=[\"a\"]")
(insta/parse python-setup-parser "install_requires = ['a'] ")
(insta/parse python-setup-parser "install_requires=['a1']")
(insta/parse python-setup-parser "install_requires=['aa1']")
(insta/parse python-setup-parser "install_requires=['ab_12']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>0']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>=0.9']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>=0.9.1']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>=0.9.1a']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>=0.9.1a3']")
(insta/parse python-setup-parser "install_requires=['aba234.pdf>=0.9.1pre-release']")
(insta/parse python-setup-parser "install_requires = ['argparse', 'requests>=1.1.0,<1.3.0', 'colorama']")
(insta/parse parser "install_requires = ['argparse', 'requests>=1.1.0,<1.3.0', 'colorama>=0.9,!=1.1,!=1.2.1,<=1.4.1a3']")
(pprint (transform *1))
(def transformers {:MODULE_NAME str
:VERSION_LITERAL str
:RELEASE_LITERAL str})
(defn transform [parser-output]
(insta/transform transformers parser-output))
@reiz

reiz commented May 1, 2013

Copy link
Copy Markdown

Looks pretty clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment