diff --git a/uno/.gitrepo b/uno/.gitrepo index 0c0079bd..12b8bb7d 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 7ab861e71a9b1ceea91630a678fa70d34dc54c53 - parent = 5f7c7ac41f570dfba548edf6382659489dc1bf2e + commit = a2c4f2e226b9b557738468062e1b832cadf13bd3 + parent = 9f26fa0c585e5892ffba2df651237b55ed240186 method = merge cmdver = 0.4.3 diff --git a/uno/lib/python/_cffi_backend.cp38-win32.pyd b/uno/lib/python/_cffi_backend.cp38-win32.pyd new file mode 100644 index 00000000..acd4ce49 Binary files /dev/null and b/uno/lib/python/_cffi_backend.cp38-win32.pyd differ diff --git a/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd b/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd new file mode 100644 index 00000000..8af17814 Binary files /dev/null and b/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd differ diff --git a/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so new file mode 100755 index 00000000..d1a1cf98 Binary files /dev/null and b/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so differ diff --git a/uno/lib/python/_distutils_hack/__init__.py b/uno/lib/python/_distutils_hack/__init__.py new file mode 100644 index 00000000..b951c2de --- /dev/null +++ b/uno/lib/python/_distutils_hack/__init__.py @@ -0,0 +1,227 @@ +# don't import any costly modules +import sys +import os + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +def warn_distutils_present(): + if 'distutils' not in sys.modules: + return + if is_pypy and sys.version_info < (3, 7): + # PyPy for 3.6 unconditionally imports distutils, so bypass the warning + # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 + return + import warnings + + warnings.warn( + "Distutils was imported before Setuptools, but importing Setuptools " + "also replaces the `distutils` module in `sys.modules`. This may lead " + "to undesirable behaviors or errors. To avoid these issues, avoid " + "using distutils directly, ensure that setuptools is installed in the " + "traditional way (e.g. not an editable install), and/or make sure " + "that setuptools is always imported before distutils." + ) + + +def clear_distutils(): + if 'distutils' not in sys.modules: + return + import warnings + + warnings.warn("Setuptools is replacing distutils.") + mods = [ + name + for name in sys.modules + if name == "distutils" or name.startswith("distutils.") + ] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local') + return which == 'local' + + +def ensure_local_distutils(): + import importlib + + clear_distutils() + + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + with shim(): + importlib.import_module('distutils') + + # check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + assert 'setuptools._distutils.log' not in sys.modules + + +def do_override(): + """ + Ensure that the local copy of distutils is preferred over stdlib. + + See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 + for more motivation. + """ + if enabled(): + warn_distutils_present() + ensure_local_distutils() + + +class _TrivialRe: + def __init__(self, *patterns): + self._patterns = patterns + + def match(self, string): + return all(pat in string for pat in self._patterns) + + +class DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + # optimization: only consider top level modules and those + # found in the CPython test suite. + if path is not None and not fullname.startswith('test.'): + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + if self.is_cpython(): + return + + import importlib + import importlib.abc + import importlib.util + + try: + mod = importlib.import_module('setuptools._distutils') + except Exception: + # There are a couple of cases where setuptools._distutils + # may not be present: + # - An older Setuptools without a local distutils is + # taking precedence. Ref #2957. + # - Path manipulation during sitecustomize removes + # setuptools from the path but only after the hook + # has been loaded. Ref #2980. + # In either case, fall back to stdlib behavior. + return + + class DistutilsLoader(importlib.abc.Loader): + def create_module(self, spec): + mod.__name__ = 'distutils' + return mod + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader( + 'distutils', DistutilsLoader(), origin=mod.__file__ + ) + + @staticmethod + def is_cpython(): + """ + Suppress supplying distutils for CPython (build and tests). + Ref #2965 and #3007. + """ + return os.path.isfile('pybuilddir.txt') + + def spec_for_pip(self): + """ + Ensure stdlib distutils when running under pip. + See pypa/pip#8761 for rationale. + """ + if sys.version_info >= (3, 12) or self.pip_imported_during_build(): + return + clear_distutils() + self.spec_for_distutils = lambda: None + + @classmethod + def pip_imported_during_build(cls): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + + return any( + cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None) + ) + + @staticmethod + def frame_file_is_setup(frame): + """ + Return True if the indicated frame suggests a setup.py file. + """ + # some frames may not have __file__ (#2940) + return frame.f_globals.get('__file__', '').endswith('setup.py') + + def spec_for_sensitive_tests(self): + """ + Ensure stdlib distutils when running select tests under CPython. + + python/cpython#91169 + """ + clear_distutils() + self.spec_for_distutils = lambda: None + + sensitive_tests = ( + [ + 'test.test_distutils', + 'test.test_peg_generator', + 'test.test_importlib', + ] + if sys.version_info < (3, 10) + else [ + 'test.test_distutils', + ] + ) + + +for name in DistutilsMetaFinder.sensitive_tests: + setattr( + DistutilsMetaFinder, + f'spec_for_{name}', + DistutilsMetaFinder.spec_for_sensitive_tests, + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + DISTUTILS_FINDER in sys.meta_path or insert_shim() + + +class shim: + def __enter__(self): + insert_shim() + + def __exit__(self, exc, value, tb): + _remove_shim() + + +def insert_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def _remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass + + +if sys.version_info < (3, 12): + # DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632) + remove_shim = _remove_shim diff --git a/uno/lib/python/_distutils_hack/override.py b/uno/lib/python/_distutils_hack/override.py new file mode 100644 index 00000000..2cc433a4 --- /dev/null +++ b/uno/lib/python/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/uno/lib/python/attr/__init__.py b/uno/lib/python/attr/__init__.py index 7cfa792f..7251ac41 100644 --- a/uno/lib/python/attr/__init__.py +++ b/uno/lib/python/attr/__init__.py @@ -78,55 +78,26 @@ def _make_getattr(mod_name: str) -> Callable: """ def __getattr__(name: str) -> str: - dunder_to_metadata = { - "__title__": "Name", - "__copyright__": "", - "__version__": "version", - "__version_info__": "version", - "__description__": "summary", - "__uri__": "", - "__url__": "", - "__author__": "", - "__email__": "", - "__license__": "license", - } - if name not in dunder_to_metadata.keys(): - raise AttributeError(f"module {mod_name} has no attribute {name}") - - import sys - import warnings - - if sys.version_info < (3, 8): - from importlib_metadata import metadata - else: - from importlib.metadata import metadata - - if name != "__version_info__": - warnings.warn( - f"Accessing {mod_name}.{name} is deprecated and will be " - "removed in a future release. Use importlib.metadata directly " - "to query for attrs's packaging metadata.", - DeprecationWarning, - stacklevel=2, - ) - meta = metadata("attrs") if name == "__license__": return "MIT" elif name == "__copyright__": return "Copyright (c) 2015 Hynek Schlawack" elif name in ("__uri__", "__url__"): - return meta["Project-URL"].split(" ", 1)[-1] - elif name == "__version_info__": - return VersionInfo._from_version_string(meta["version"]) + return "https://github.com/denis-ryzhkov/attr" + elif name in ("__version__", "__version_info__"): + return "23.1.0" elif name == "__author__": - return meta["Author-email"].rsplit(" ", 1)[0] + return "Denis Ryzhkov" elif name == "__email__": - return meta["Author-email"].rsplit("<", 1)[1][:-1] - - return meta[dunder_to_metadata[name]] + return "denisr@denisr.com" + elif name == "__title__": + return "attr" + elif name == "__description__": + return "Simple decorator to set attributes of target function or class in a DRY way." + else: + raise AttributeError(f"module {mod_name} has no attribute {name}") return __getattr__ - __getattr__ = _make_getattr(__name__) diff --git a/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_10.py b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_10.py new file mode 100644 index 00000000..a35577e3 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_10.py @@ -0,0 +1,10 @@ +# lextab_es5_py3_ply3_10.py. This file automatically created by PLY (version 3.10). Don't edit! +_tabversion = '3.10' +_lextokens = set(('NULL', 'FINALLY', 'BLOCK_COMMENT', 'LINE_TERMINATOR', 'OREQUAL', 'EQEQ', 'IN', 'IF', 'TRUE', 'RSHIFT', 'GETPROP', 'URSHIFT', 'CATCH', 'ENUM', 'INSTANCEOF', 'NEW', 'BOR', 'STRING', 'EQ', 'DIVEQUAL', 'WHILE', 'MULT', 'LT', 'DEFAULT', 'SUPER', 'SEMI', 'STRNEQ', 'TYPEOF', 'EXPORT', 'NE', 'ID', 'REGEX', 'OR', 'ELSE', 'CONDOP', 'ANDEQUAL', 'STREQ', 'LSHIFT', 'BREAK', 'LBRACKET', 'PLUS', 'BXOR', 'MINUSMINUS', 'PLUSPLUS', 'BAND', 'RBRACKET', 'LSHIFTEQUAL', 'GT', 'RBRACE', 'DELETE', 'RETURN', 'IMPORT', 'LINE_COMMENT', 'COMMA', 'NUMBER', 'LE', 'TRY', 'CONTINUE', 'BNOT', 'LBRACE', 'AUTOSEMI', 'MOD', 'PLUSEQUAL', 'AND', 'RPAREN', 'MINUS', 'VOID', 'CLASS', 'DIV', 'CASE', 'URSHIFTEQUAL', 'SETPROP', 'PERIOD', 'CONST', 'THIS', 'DO', 'VAR', 'THROW', 'WITH', 'MULTEQUAL', 'DEBUGGER', 'FALSE', 'LPAREN', 'MODEQUAL', 'SWITCH', 'EXTENDS', 'COLON', 'FUNCTION', 'RSHIFTEQUAL', 'NOT', 'XOREQUAL', 'GE', 'FOR', 'MINUSEQUAL')) +_lexreflags = 64 +_lexliterals = '' +_lexstateinfo = {'INITIAL': 'inclusive', 'regex': 'exclusive'} +_lexstatere = {'INITIAL': [('(?P\n (?:\n # double quoted string\n (?:" # opening double quote\n (?: [^"\\\\\\n\\r\\u2028\\u2029] # not ", \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n ") # must have closing double quote\n |\n # single quoted string\n (?:\' # opening single quote\n (?: [^\'\\\\\\n\\r\\u2028\\u2029] # not \', \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n \') # must have closing single quote\n )\n )|(?Pget(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?Pset(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?P(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*)|(?P\n (?:\n 0[xX][0-9a-fA-F]+ # hex_integer_literal\n | 0[0-7]+ # or octal_integer_literal\n | (?: # or decimal_literal\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n \\. # dot\n [0-9]* # decimal_digits_opt\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n \\. # dot\n [0-9]+ # decimal_digits\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n )\n )\n )|(?P(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n))|(?P/\\*[^*]*\\*+([^/*][^*]*\\*+)*/)|(?P//[^\\r\\n\\u2028\\u2029]*)|(?P\\|\\|)|(?P\\+\\+)|(?P>>>=)|(?P<<=)|(?P\\*=)|(?P\\|=)|(?P\\+=)|(?P>>=)|(?P===)|(?P!==)|(?P>>>)|(?P\\^=)|(?P&&)|(?P&=)|(?P\\|)|(?P\\^)|(?P\\?)|(?P/=)|(?P==)|(?P>=)|(?P\\[)|(?P<=)|(?P\\()|(?P<<)|(?P-=)|(?P--)|(?P%=)|(?P\\*)|(?P!=)|(?P\\.)|(?P\\+)|(?P\\])|(?P\\))|(?P>>)|(?P&)|(?P~)|(?P:)|(?P,)|(?P/)|(?P=)|(?P>)|(?P{)|(?P<)|(?P-)|(?P%)|(?P!)|(?P})|(?P;)', [None, ('t_STRING', 'STRING'), None, None, ('t_GETPROP', 'GETPROP'), ('t_SETPROP', 'SETPROP'), ('t_ID', 'ID'), (None, 'NUMBER'), (None, 'LINE_TERMINATOR'), None, (None, 'BLOCK_COMMENT'), None, (None, 'LINE_COMMENT'), (None, 'OR'), (None, 'PLUSPLUS'), (None, 'URSHIFTEQUAL'), (None, 'LSHIFTEQUAL'), (None, 'MULTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'STREQ'), (None, 'STRNEQ'), (None, 'URSHIFT'), (None, 'XOREQUAL'), (None, 'AND'), (None, 'ANDEQUAL'), (None, 'BOR'), (None, 'BXOR'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQEQ'), (None, 'GE'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'MULT'), (None, 'NE'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'BAND'), (None, 'BNOT'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIV'), (None, 'EQ'), (None, 'GT'), (None, 'LBRACE'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'RBRACE'), (None, 'SEMI')])], 'regex': [('(?P(?:\n / # opening slash\n # First character is..\n (?: [^*\\\\/[] # anything but * \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )\n # Following characters are same, except for excluding a star\n (?: [^\\\\/[] # anything but \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )* # many times\n / # closing slash\n [a-zA-Z0-9]* # trailing flags\n )\n )', [None, (None, 'REGEX')])]} +_lexstateignore = {'INITIAL': ' \t\x0b\x0c\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff', 'regex': ' \t'} +_lexstateerrorf = {'INITIAL': 't_error', 'regex': 't_regex_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_11.py b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_11.py new file mode 100644 index 00000000..446e1b39 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_11.py @@ -0,0 +1,10 @@ +# lextab_es5_py3_ply3_11.py. This file automatically created by PLY (version 3.11). Don't edit! +_tabversion = '3.10' +_lextokens = set(('AND', 'ANDEQUAL', 'AUTOSEMI', 'BAND', 'BLOCK_COMMENT', 'BNOT', 'BOR', 'BREAK', 'BXOR', 'CASE', 'CATCH', 'CLASS', 'COLON', 'COMMA', 'CONDOP', 'CONST', 'CONTINUE', 'DEBUGGER', 'DEFAULT', 'DELETE', 'DIV', 'DIVEQUAL', 'DO', 'ELSE', 'ENUM', 'EQ', 'EQEQ', 'EXPORT', 'EXTENDS', 'FALSE', 'FINALLY', 'FOR', 'FUNCTION', 'GE', 'GETPROP', 'GT', 'ID', 'IF', 'IMPORT', 'IN', 'INSTANCEOF', 'LBRACE', 'LBRACKET', 'LE', 'LINE_COMMENT', 'LINE_TERMINATOR', 'LPAREN', 'LSHIFT', 'LSHIFTEQUAL', 'LT', 'MINUS', 'MINUSEQUAL', 'MINUSMINUS', 'MOD', 'MODEQUAL', 'MULT', 'MULTEQUAL', 'NE', 'NEW', 'NOT', 'NULL', 'NUMBER', 'OR', 'OREQUAL', 'PERIOD', 'PLUS', 'PLUSEQUAL', 'PLUSPLUS', 'RBRACE', 'RBRACKET', 'REGEX', 'RETURN', 'RPAREN', 'RSHIFT', 'RSHIFTEQUAL', 'SEMI', 'SETPROP', 'STREQ', 'STRING', 'STRNEQ', 'SUPER', 'SWITCH', 'THIS', 'THROW', 'TRUE', 'TRY', 'TYPEOF', 'URSHIFT', 'URSHIFTEQUAL', 'VAR', 'VOID', 'WHILE', 'WITH', 'XOREQUAL')) +_lexreflags = 64 +_lexliterals = '' +_lexstateinfo = {'INITIAL': 'inclusive', 'regex': 'exclusive'} +_lexstatere = {'INITIAL': [('(?P\n (?:\n # double quoted string\n (?:" # opening double quote\n (?: [^"\\\\\\n\\r\\u2028\\u2029] # not ", \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n ") # must have closing double quote\n |\n # single quoted string\n (?:\' # opening single quote\n (?: [^\'\\\\\\n\\r\\u2028\\u2029] # not \', \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n \') # must have closing single quote\n )\n )|(?Pget(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?Pset(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?P(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*)|(?P\n (?:\n 0[xX][0-9a-fA-F]+ # hex_integer_literal\n | 0[0-7]+ # or octal_integer_literal\n | (?: # or decimal_literal\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n \\. # dot\n [0-9]* # decimal_digits_opt\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n \\. # dot\n [0-9]+ # decimal_digits\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n )\n )\n )|(?P(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n))|(?P/\\*[^*]*\\*+([^/*][^*]*\\*+)*/)|(?P//[^\\r\\n\\u2028\\u2029]*)|(?P\\|\\|)|(?P\\+\\+)|(?P>>>=)|(?P<<=)|(?P\\*=)|(?P\\|=)|(?P\\+=)|(?P>>=)|(?P===)|(?P!==)|(?P>>>)|(?P\\^=)|(?P&&)|(?P&=)|(?P\\|)|(?P\\^)|(?P\\?)|(?P/=)|(?P==)|(?P>=)|(?P\\[)|(?P<=)|(?P\\()|(?P<<)|(?P-=)|(?P--)|(?P%=)|(?P\\*)|(?P!=)|(?P\\.)|(?P\\+)|(?P\\])|(?P\\))|(?P>>)|(?P&)|(?P~)|(?P:)|(?P,)|(?P/)|(?P=)|(?P>)|(?P{)|(?P<)|(?P-)|(?P%)|(?P!)|(?P})|(?P;)', [None, ('t_STRING', 'STRING'), None, None, ('t_GETPROP', 'GETPROP'), ('t_SETPROP', 'SETPROP'), ('t_ID', 'ID'), (None, 'NUMBER'), (None, 'LINE_TERMINATOR'), None, (None, 'BLOCK_COMMENT'), None, (None, 'LINE_COMMENT'), (None, 'OR'), (None, 'PLUSPLUS'), (None, 'URSHIFTEQUAL'), (None, 'LSHIFTEQUAL'), (None, 'MULTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'STREQ'), (None, 'STRNEQ'), (None, 'URSHIFT'), (None, 'XOREQUAL'), (None, 'AND'), (None, 'ANDEQUAL'), (None, 'BOR'), (None, 'BXOR'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQEQ'), (None, 'GE'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'MULT'), (None, 'NE'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'BAND'), (None, 'BNOT'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIV'), (None, 'EQ'), (None, 'GT'), (None, 'LBRACE'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'RBRACE'), (None, 'SEMI')])], 'regex': [('(?P(?:\n / # opening slash\n # First character is..\n (?: [^*\\\\/[] # anything but * \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )\n # Following characters are same, except for excluding a star\n (?: [^\\\\/[] # anything but \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )* # many times\n / # closing slash\n [a-zA-Z0-9]* # trailing flags\n )\n )', [None, (None, 'REGEX')])]} +_lexstateignore = {'INITIAL': ' \t\x0b\x0c\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff', 'regex': ' \t'} +_lexstateerrorf = {'INITIAL': 't_error', 'regex': 't_regex_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_6.py b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_6.py new file mode 100644 index 00000000..b6ed8211 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_6.py @@ -0,0 +1,10 @@ +# lextab_es5_py3_ply3_6.py. This file automatically created by PLY (version 3.6). Don't edit! +_tabversion = '3.5' +_lextokens = {'MOD', 'IN', 'URSHIFT', 'NULL', 'FOR', 'MULTEQUAL', 'RBRACKET', 'LSHIFTEQUAL', 'RSHIFTEQUAL', 'GETPROP', 'INSTANCEOF', 'LE', 'LSHIFT', 'URSHIFTEQUAL', 'FALSE', 'MODEQUAL', 'BNOT', 'MINUS', 'ID', 'CONST', 'ENUM', 'SUPER', 'SETPROP', 'CLASS', 'PLUS', 'PLUSPLUS', 'XOREQUAL', 'BLOCK_COMMENT', 'ELSE', 'IMPORT', 'VOID', 'MINUSMINUS', 'SWITCH', 'WITH', 'AUTOSEMI', 'NOT', 'DIV', 'BREAK', 'FUNCTION', 'EXTENDS', 'STRNEQ', 'BAND', 'RPAREN', 'EQ', 'PERIOD', 'CASE', 'LBRACKET', 'BXOR', 'IF', 'RETURN', 'BOR', 'LBRACE', 'DIVEQUAL', 'NE', 'VAR', 'TRY', 'FINALLY', 'AND', 'LINE_TERMINATOR', 'CATCH', 'COMMA', 'THIS', 'STRING', 'DELETE', 'REGEX', 'OR', 'CONDOP', 'MULT', 'LINE_COMMENT', 'CONTINUE', 'ANDEQUAL', 'THROW', 'COLON', 'PLUSEQUAL', 'OREQUAL', 'RBRACE', 'MINUSEQUAL', 'TRUE', 'STREQ', 'WHILE', 'RSHIFT', 'EXPORT', 'DEFAULT', 'EQEQ', 'LPAREN', 'SEMI', 'GE', 'NUMBER', 'TYPEOF', 'GT', 'DEBUGGER', 'LT', 'NEW', 'DO'} +_lexreflags = 0 +_lexliterals = '' +_lexstateinfo = {'INITIAL': 'inclusive', 'regex': 'exclusive'} +_lexstatere = {'INITIAL': [('(?P\n (?:\n # double quoted string\n (?:" # opening double quote\n (?: [^"\\\\\\n\\r\\u2028\\u2029] # not ", \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n ") # must have closing double quote\n |\n # single quoted string\n (?:\' # opening single quote\n (?: [^\'\\\\\\n\\r\\u2028\\u2029] # not \', \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n \') # must have closing single quote\n )\n )|(?Pget(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?Pset(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?P(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*)|(?P\n (?:\n 0[xX][0-9a-fA-F]+ # hex_integer_literal\n | 0[0-7]+ # or octal_integer_literal\n | (?: # or decimal_literal\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n \\. # dot\n [0-9]* # decimal_digits_opt\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n \\. # dot\n [0-9]+ # decimal_digits\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n )\n )\n )|(?P(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n))|(?P/\\*[^*]*\\*+([^/*][^*]*\\*+)*/)|(?P//[^\\r\\n\\u2028\\u2029]*)|(?P\\|\\|)|(?P\\+\\+)|(?P>>>=)|(?P<<=)|(?P\\*=)|(?P\\|=)|(?P\\+=)|(?P>>=)|(?P===)|(?P!==)|(?P>>>)|(?P\\^=)|(?P&&)|(?P&=)|(?P\\|)|(?P\\^)|(?P\\?)|(?P/=)|(?P==)|(?P>=)|(?P\\[)|(?P<=)|(?P\\()|(?P<<)|(?P-=)|(?P--)|(?P%=)|(?P\\*)|(?P!=)|(?P\\.)|(?P\\+)|(?P\\])|(?P\\))|(?P>>)|(?P&)|(?P~)|(?P:)|(?P,)|(?P/)|(?P=)|(?P>)|(?P{)|(?P<)|(?P-)|(?P%)|(?P!)|(?P})|(?P;)', [None, ('t_STRING', 'STRING'), None, None, ('t_GETPROP', 'GETPROP'), ('t_SETPROP', 'SETPROP'), ('t_ID', 'ID'), (None, 'NUMBER'), (None, 'LINE_TERMINATOR'), None, (None, 'BLOCK_COMMENT'), None, (None, 'LINE_COMMENT'), (None, 'OR'), (None, 'PLUSPLUS'), (None, 'URSHIFTEQUAL'), (None, 'LSHIFTEQUAL'), (None, 'MULTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'STREQ'), (None, 'STRNEQ'), (None, 'URSHIFT'), (None, 'XOREQUAL'), (None, 'AND'), (None, 'ANDEQUAL'), (None, 'BOR'), (None, 'BXOR'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQEQ'), (None, 'GE'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'MULT'), (None, 'NE'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'BAND'), (None, 'BNOT'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIV'), (None, 'EQ'), (None, 'GT'), (None, 'LBRACE'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'RBRACE'), (None, 'SEMI')])], 'regex': [('(?P(?:\n / # opening slash\n # First character is..\n (?: [^*\\\\/[] # anything but * \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )\n # Following characters are same, except for excluding a star\n (?: [^\\\\/[] # anything but \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )* # many times\n / # closing slash\n [a-zA-Z0-9]* # trailing flags\n )\n )', [None, (None, 'REGEX')])]} +_lexstateignore = {'INITIAL': ' \t\x0b\x0c\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff', 'regex': ' \t'} +_lexstateerrorf = {'INITIAL': 't_error', 'regex': 't_regex_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_8.py b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_8.py new file mode 100644 index 00000000..16a77746 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_8.py @@ -0,0 +1,10 @@ +# lextab_es5_py3_ply3_8.py. This file automatically created by PLY (version 3.8). Don't edit! +_tabversion = '3.8' +_lextokens = {'SWITCH', 'EQEQ', 'EXTENDS', 'EXPORT', 'XOREQUAL', 'MINUS', 'LT', 'STRNEQ', 'RBRACKET', 'MODEQUAL', 'MINUSEQUAL', 'FOR', 'NEW', 'EQ', 'OREQUAL', 'DEBUGGER', 'THROW', 'PLUSPLUS', 'IF', 'FALSE', 'CONTINUE', 'GE', 'STREQ', 'RBRACE', 'SETPROP', 'MINUSMINUS', 'ENUM', 'URSHIFTEQUAL', 'RSHIFT', 'CONST', 'BNOT', 'LPAREN', 'DEFAULT', 'ELSE', 'IN', 'MOD', 'COMMA', 'WHILE', 'LINE_TERMINATOR', 'BLOCK_COMMENT', 'FINALLY', 'TRY', 'SUPER', 'AND', 'AUTOSEMI', 'BXOR', 'NOT', 'STRING', 'RSHIFTEQUAL', 'MULT', 'LSHIFT', 'BAND', 'PERIOD', 'NULL', 'DIV', 'BOR', 'INSTANCEOF', 'GETPROP', 'LBRACKET', 'MULTEQUAL', 'SEMI', 'NE', 'IMPORT', 'LBRACE', 'CLASS', 'VOID', 'NUMBER', 'CATCH', 'BREAK', 'URSHIFT', 'FUNCTION', 'TYPEOF', 'THIS', 'PLUS', 'DO', 'VAR', 'RPAREN', 'GT', 'OR', 'WITH', 'REGEX', 'PLUSEQUAL', 'LINE_COMMENT', 'ANDEQUAL', 'TRUE', 'RETURN', 'CASE', 'DELETE', 'COLON', 'LE', 'LSHIFTEQUAL', 'CONDOP', 'ID', 'DIVEQUAL'} +_lexreflags = 0 +_lexliterals = '' +_lexstateinfo = {'INITIAL': 'inclusive', 'regex': 'exclusive'} +_lexstatere = {'INITIAL': [('(?P\n (?:\n # double quoted string\n (?:" # opening double quote\n (?: [^"\\\\\\n\\r\\u2028\\u2029] # not ", \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n ") # must have closing double quote\n |\n # single quoted string\n (?:\' # opening single quote\n (?: [^\'\\\\\\n\\r\\u2028\\u2029] # not \', \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n \') # must have closing single quote\n )\n )|(?Pget(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?Pset(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?P(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*)|(?P\n (?:\n 0[xX][0-9a-fA-F]+ # hex_integer_literal\n | 0[0-7]+ # or octal_integer_literal\n | (?: # or decimal_literal\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n \\. # dot\n [0-9]* # decimal_digits_opt\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n \\. # dot\n [0-9]+ # decimal_digits\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n )\n )\n )|(?P(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n))|(?P/\\*[^*]*\\*+([^/*][^*]*\\*+)*/)|(?P//[^\\r\\n\\u2028\\u2029]*)|(?P\\|\\|)|(?P\\+\\+)|(?P>>>=)|(?P<<=)|(?P\\*=)|(?P\\|=)|(?P\\+=)|(?P>>=)|(?P===)|(?P!==)|(?P>>>)|(?P\\^=)|(?P&&)|(?P&=)|(?P\\|)|(?P\\^)|(?P\\?)|(?P/=)|(?P==)|(?P>=)|(?P\\[)|(?P<=)|(?P\\()|(?P<<)|(?P-=)|(?P--)|(?P%=)|(?P\\*)|(?P!=)|(?P\\.)|(?P\\+)|(?P\\])|(?P\\))|(?P>>)|(?P&)|(?P~)|(?P:)|(?P,)|(?P/)|(?P=)|(?P>)|(?P{)|(?P<)|(?P-)|(?P%)|(?P!)|(?P})|(?P;)', [None, ('t_STRING', 'STRING'), None, None, ('t_GETPROP', 'GETPROP'), ('t_SETPROP', 'SETPROP'), ('t_ID', 'ID'), (None, 'NUMBER'), (None, 'LINE_TERMINATOR'), None, (None, 'BLOCK_COMMENT'), None, (None, 'LINE_COMMENT'), (None, 'OR'), (None, 'PLUSPLUS'), (None, 'URSHIFTEQUAL'), (None, 'LSHIFTEQUAL'), (None, 'MULTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'STREQ'), (None, 'STRNEQ'), (None, 'URSHIFT'), (None, 'XOREQUAL'), (None, 'AND'), (None, 'ANDEQUAL'), (None, 'BOR'), (None, 'BXOR'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQEQ'), (None, 'GE'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'MULT'), (None, 'NE'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'BAND'), (None, 'BNOT'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIV'), (None, 'EQ'), (None, 'GT'), (None, 'LBRACE'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'RBRACE'), (None, 'SEMI')])], 'regex': [('(?P(?:\n / # opening slash\n # First character is..\n (?: [^*\\\\/[] # anything but * \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )\n # Following characters are same, except for excluding a star\n (?: [^\\\\/[] # anything but \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )* # many times\n / # closing slash\n [a-zA-Z0-9]* # trailing flags\n )\n )', [None, (None, 'REGEX')])]} +_lexstateignore = {'INITIAL': ' \t\x0b\x0c\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff', 'regex': ' \t'} +_lexstateerrorf = {'INITIAL': 't_error', 'regex': 't_regex_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_9.py b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_9.py new file mode 100644 index 00000000..e6baee65 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/lextab_es5_py3_ply3_9.py @@ -0,0 +1,10 @@ +# lextab_es5_py3_ply3_9.py. This file automatically created by PLY (version 3.9). Don't edit! +_tabversion = '3.8' +_lextokens = set(('RPAREN', 'AUTOSEMI', 'MULTEQUAL', 'LT', 'TRY', 'IMPORT', 'LSHIFTEQUAL', 'NULL', 'WHILE', 'BXOR', 'GT', 'CLASS', 'BNOT', 'MODEQUAL', 'PERIOD', 'GE', 'REGEX', 'OREQUAL', 'DO', 'FOR', 'THIS', 'EQ', 'XOREQUAL', 'MOD', 'LPAREN', 'VAR', 'CATCH', 'BLOCK_COMMENT', 'EXPORT', 'ENUM', 'MINUSEQUAL', 'NUMBER', 'TRUE', 'GETPROP', 'ELSE', 'STRNEQ', 'URSHIFTEQUAL', 'BAND', 'PLUSPLUS', 'LE', 'DIV', 'ID', 'PLUS', 'DELETE', 'NOT', 'DEBUGGER', 'RBRACKET', 'NE', 'PLUSEQUAL', 'SETPROP', 'LINE_TERMINATOR', 'NEW', 'COMMA', 'SUPER', 'INSTANCEOF', 'SEMI', 'CONST', 'MINUSMINUS', 'THROW', 'IN', 'AND', 'CONTINUE', 'CONDOP', 'COLON', 'BOR', 'DEFAULT', 'DIVEQUAL', 'STRING', 'RSHIFTEQUAL', 'IF', 'RBRACE', 'LINE_COMMENT', 'LBRACKET', 'VOID', 'MINUS', 'CASE', 'MULT', 'SWITCH', 'RSHIFT', 'EQEQ', 'LSHIFT', 'URSHIFT', 'FINALLY', 'OR', 'STREQ', 'LBRACE', 'FALSE', 'EXTENDS', 'BREAK', 'FUNCTION', 'TYPEOF', 'ANDEQUAL', 'RETURN', 'WITH')) +_lexreflags = 0 +_lexliterals = '' +_lexstateinfo = {'INITIAL': 'inclusive', 'regex': 'exclusive'} +_lexstatere = {'INITIAL': [('(?P\n (?:\n # double quoted string\n (?:" # opening double quote\n (?: [^"\\\\\\n\\r\\u2028\\u2029] # not ", \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n ") # must have closing double quote\n |\n # single quoted string\n (?:\' # opening single quote\n (?: [^\'\\\\\\n\\r\\u2028\\u2029] # not \', \\, line terminators; allow\n | \\\\(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n) # line continuation\n | \\\\[a-tvwyzA-TVWYZ!-\\/:-@\\[-`{-~] # escaped chars\n | \\\\x[0-9a-fA-F]{2} # hex_escape_sequence\n | \\\\u[0-9a-fA-F]{4} # unicode_escape_sequence\n | \\\\(?:[1-7][0-7]{0,2}|[0-7]{2,3}) # octal_escape_sequence\n | \\\\0 # (15.10.2.11)\n )*? # zero or many times\n \') # must have closing single quote\n )\n )|(?Pget(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?Pset(?=\\s(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*))|(?P(?:[a-zA-Z_$]|[A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԣԱ-Ֆՙա-ևא-תװ-ײء-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺऄ-हऽॐक़-ॡॱॲॻ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡഅ-ഌഎ-ഐഒ-നപ-ഹഽൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜໝༀཀ-ཇཉ-ཬྈ-ྋက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-Ⴥა-ჺჼᄀ-ᅙᅟ-ᆢᆨ-ᇹሀ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙶᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦩᧁ-ᧇᨀ-ᨖᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᰀ-ᰣᱍ-ᱏᱚ-ᱽᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₔℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-Ɐⱱ-ⱽⲀ-ⳤⴀ-ⴥⴰ-ⵥⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆷㇰ-ㇿ㐀䶵一鿃ꀀ-ꒌꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙟꙢ-ꙮꙿ-ꚗꜗ-ꜟꜢ-ꞈꞋꞌꟻ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꤊ-ꤥꤰ-ꥆꨀ-ꨨꩀ-ꩂꩄ-ꩋ가힣豈-鶴侮-頻並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])+(?:[̀-ͯ҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٞۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࠭ऀ-ं़ु-ै्॑-ॕॢॣঁ়ু-ৄ্ৢৣਁਂ਼ੁੂੇੈੋ-੍ੑੰੱੵઁં઼ુ-ૅેૈ્ૢૣଁ଼ିୁ-ୄ୍ୖୢୣஂீ்ా-ీె-ైొ-్ౕౖౢౣ಼ಿೆೌ್ೢೣു-ൄ്ൢൣ්ි-ුූัิ-ฺ็-๎ັິ-ູົຼ່-ໍཱ༹༘༙༵༷-ཾྀ-྄྆྇ྐ-ྗྙ-ྼ࿆ိ-ူဲ-့္်ွှၘၙၞ-ၠၱ-ၴႂႅႆႍႝ፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳិ-ួំ៉-៓៝᠋-᠍ᢩᤠ-ᤢᤧᤨᤲ᤹-᤻ᨘᨗᩖᩘ-ᩞ᩠ᩢᩥ-ᩬᩳ-᩿᩼ᬀ-ᬃ᬴ᬶ-ᬺᬼᭂ᭫-᭳ᮀᮁᮢ-ᮥᮨᮩᰬ-ᰳᰶ᰷᳐-᳔᳒-᳢᳠-᳨᳭᷀-᷽ᷦ-᷿⃐-⃥⃜⃡-⃰⳯-⳱ⷠ-〪ⷿ-゙゚〯꙯꙼꙽꛰꛱ꠂ꠆ꠋꠥꠦ꣄꣠-꣱ꤦ-꤭ꥇ-ꥑꦀ-ꦂ꦳ꦶ-ꦹꦼꨩ-ꨮꨱꨲꨵꨶꩃꩌꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꯥꯨ꯭ﬞ︀-️︠-︦]|[ःा-ीॉ-ौॎংঃা-ীেৈোৌৗਃਾ-ੀઃા-ીૉોૌଂଃାୀେୈୋୌୗாிுூெ-ைொ-ௌௗఁ-ఃు-ౄಂಃಾೀ-ೄೇೈೊೋೕೖംഃാ-ീെ-ൈൊ-ൌൗංඃා-ෑෘ-ෟෲෳ༾༿ཿါာေးျြၖၗၢ-ၤၧ-ၭႃႄႇ-ႌႏႚ-ႜាើ-ៅះៈᤣ-ᤦᤩ-ᤫᤰᤱᤳ-ᤸᦰ-ᧀᧈᧉᨙ-ᨛᩕᩗᩡᩣᩤᩭ-ᩲᬄᬵᬻᬽ-ᭁᭃ᭄ᮂᮡᮦᮧ᮪ᰤ-ᰫᰴᰵ᳡ᳲꠣꠤꠧꢀꢁꢴ-ꣃꥒ꥓ꦃꦴꦵꦺꦻꦽ-꧀ꨯꨰꨳꨴꩍꩻꯣꯤꯦꯧꯩꯪ꯬]|[0-9a-zA-Z_$]|[0-9٠-٩۰-۹߀-߉०-९০-৯੦-੯૦-૯୦-୯௦-௯౦-౯೦-೯൦-൯๐-๙໐-໙༠-༩၀-၉႐-႙០-៩᠐-᠙᥆-᥏᧐-᧚᪀-᪉᪐-᪙᭐-᭙᮰-᮹᱀-᱉᱐-᱙꘠-꘩꣐-꣙꤀-꤉꧐-꧙꩐-꩙꯰-꯹0-9]|[_‿⁀⁔︳︴﹍-﹏_])*)|(?P\n (?:\n 0[xX][0-9a-fA-F]+ # hex_integer_literal\n | 0[0-7]+ # or octal_integer_literal\n | (?: # or decimal_literal\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n \\. # dot\n [0-9]* # decimal_digits_opt\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n \\. # dot\n [0-9]+ # decimal_digits\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n |\n (?:0|[1-9][0-9]*) # decimal_integer_literal\n (?:[eE][+-]?[0-9]+)? # exponent_part_opt\n )\n )\n )|(?P(\\n|\\r(?!\\n)|\\u2028|\\u2029|\\r\\n))|(?P/\\*[^*]*\\*+([^/*][^*]*\\*+)*/)|(?P//[^\\r\\n\\u2028\\u2029]*)|(?P\\|\\|)|(?P\\+\\+)|(?P>>>=)|(?P<<=)|(?P\\*=)|(?P\\|=)|(?P\\+=)|(?P>>=)|(?P===)|(?P!==)|(?P>>>)|(?P\\^=)|(?P&&)|(?P&=)|(?P\\|)|(?P\\^)|(?P\\?)|(?P/=)|(?P==)|(?P>=)|(?P\\[)|(?P<=)|(?P\\()|(?P<<)|(?P-=)|(?P--)|(?P%=)|(?P\\*)|(?P!=)|(?P\\.)|(?P\\+)|(?P\\])|(?P\\))|(?P>>)|(?P&)|(?P~)|(?P:)|(?P,)|(?P/)|(?P=)|(?P>)|(?P{)|(?P<)|(?P-)|(?P%)|(?P!)|(?P})|(?P;)', [None, ('t_STRING', 'STRING'), None, None, ('t_GETPROP', 'GETPROP'), ('t_SETPROP', 'SETPROP'), ('t_ID', 'ID'), (None, 'NUMBER'), (None, 'LINE_TERMINATOR'), None, (None, 'BLOCK_COMMENT'), None, (None, 'LINE_COMMENT'), (None, 'OR'), (None, 'PLUSPLUS'), (None, 'URSHIFTEQUAL'), (None, 'LSHIFTEQUAL'), (None, 'MULTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'STREQ'), (None, 'STRNEQ'), (None, 'URSHIFT'), (None, 'XOREQUAL'), (None, 'AND'), (None, 'ANDEQUAL'), (None, 'BOR'), (None, 'BXOR'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQEQ'), (None, 'GE'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'MULT'), (None, 'NE'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'BAND'), (None, 'BNOT'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIV'), (None, 'EQ'), (None, 'GT'), (None, 'LBRACE'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'RBRACE'), (None, 'SEMI')])], 'regex': [('(?P(?:\n / # opening slash\n # First character is..\n (?: [^*\\\\/[] # anything but * \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )\n # Following characters are same, except for excluding a star\n (?: [^\\\\/[] # anything but \\ / or [\n | \\\\. # or an escape sequence\n | \\[ # or a class, which has\n (?: [^\\]\\\\] # anything but \\ or ]\n | \\\\. # or an escape sequence\n )* # many times\n \\]\n )* # many times\n / # closing slash\n [a-zA-Z0-9]* # trailing flags\n )\n )', [None, (None, 'REGEX')])]} +_lexstateignore = {'INITIAL': ' \t\x0b\x0c\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\ufeff', 'regex': ' \t'} +_lexstateerrorf = {'INITIAL': 't_error', 'regex': 't_regex_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_10.py b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_10.py new file mode 100644 index 00000000..e359eccb --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_10.py @@ -0,0 +1,369 @@ + +# yacctab_es5_py3_ply3_10.py +# This file is automatically generated. Do not edit. +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'programPERIOD COMMA SEMI COLON AUTOSEMI PLUS MINUS MULT DIV MOD BAND BOR BXOR BNOT CONDOP NOT LPAREN RPAREN LBRACE RBRACE LBRACKET RBRACKET EQ EQEQ NE STREQ STRNEQ LT GT LE GE OR AND PLUSPLUS MINUSMINUS LSHIFT RSHIFT URSHIFT PLUSEQUAL MINUSEQUAL MULTEQUAL DIVEQUAL LSHIFTEQUAL RSHIFTEQUAL URSHIFTEQUAL ANDEQUAL MODEQUAL XOREQUAL OREQUAL NUMBER STRING ID REGEX GETPROP SETPROP LINE_COMMENT BLOCK_COMMENT LINE_TERMINATOR BREAK CASE CATCH CONTINUE DEBUGGER DEFAULT DELETE DO ELSE FINALLY FOR FUNCTION IF IN INSTANCEOF NEW RETURN SWITCH THIS THROW TRY TYPEOF VAR VOID WHILE WITH NULL TRUE FALSE CLASS CONST ENUM EXPORT EXTENDS IMPORT SUPERempty :program : source_elementssource_elements : empty\n | source_element_list\n source_element_list : source_element\n | source_element_list source_element\n source_element : statement\n | function_declaration\n statement : block\n | variable_statement\n | empty_statement\n | expr_statement\n | if_statement\n | iteration_statement\n | continue_statement\n | break_statement\n | return_statement\n | with_statement\n | switch_statement\n | labelled_statement\n | throw_statement\n | try_statement\n | debugger_statement\n | function_declaration\n block : LBRACE source_elements RBRACEliteral : null_literal\n | boolean_literal\n | numeric_literal\n | string_literal\n | regex_literal\n boolean_literal : TRUE\n | FALSE\n null_literal : NULLnumeric_literal : NUMBERstring_literal : STRINGregex_literal : REGEXidentifier : IDreserved_word : BREAK\n | CASE\n | CATCH\n | CONTINUE\n | DEBUGGER\n | DEFAULT\n | DELETE\n | DO\n | ELSE\n | FINALLY\n | FOR\n | FUNCTION\n | IF\n | IN\n | INSTANCEOF\n | NEW\n | RETURN\n | SWITCH\n | THIS\n | THROW\n | TRY\n | TYPEOF\n | VAR\n | VOID\n | WHILE\n | WITH\n | NULL\n | TRUE\n | FALSE\n | CLASS\n | CONST\n | ENUM\n | EXPORT\n | EXTENDS\n | IMPORT\n | SUPER\n identifier_name : identifier\n | reserved_word\n primary_expr : primary_expr_no_brace\n | object_literal\n primary_expr_no_brace : identifierprimary_expr_no_brace : THISprimary_expr_no_brace : literal\n | array_literal\n primary_expr_no_brace : LPAREN expr RPARENarray_literal : LBRACKET elision_opt RBRACKETarray_literal : LBRACKET element_list RBRACKET\n | LBRACKET element_list COMMA elision_opt RBRACKET\n element_list : elision_opt assignment_expr\n | element_list COMMA elision_opt assignment_expr\n elision_opt : emptyelision_opt : elisionelision : COMMA\n | elision COMMA\n object_literal : LBRACE RBRACE\n | LBRACE property_list RBRACE\n | LBRACE property_list COMMA RBRACE\n property_list : property_assignment\n | property_list COMMA property_assignment\n property_assignment : property_name COLON assignment_expr\n | GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE\n | SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE\n identifier_name_string : identifier_name\n property_name : identifier_name_string\n | string_literal\n | numeric_literal\n property_set_parameter_list : identifier\n member_expr : primary_expr\n | function_expr\n | member_expr LBRACKET expr RBRACKET\n | member_expr PERIOD identifier_name_string\n | NEW member_expr arguments\n member_expr_nobf : primary_expr_no_brace\n | function_expr\n | member_expr_nobf LBRACKET expr RBRACKET\n | member_expr_nobf PERIOD identifier_name_string\n | NEW member_expr arguments\n new_expr : member_expr\n | NEW new_expr\n new_expr_nobf : member_expr_nobf\n | NEW new_expr\n call_expr : member_expr arguments\n | call_expr arguments\n | call_expr LBRACKET expr RBRACKET\n | call_expr PERIOD identifier_name_string\n call_expr_nobf : member_expr_nobf arguments\n | call_expr_nobf arguments\n | call_expr_nobf LBRACKET expr RBRACKET\n | call_expr_nobf PERIOD identifier_name_string\n arguments : LPAREN RPAREN\n | LPAREN argument_list RPAREN\n argument_list : assignment_expr\n | argument_list COMMA assignment_expr\n left_hand_side_expr : new_expr\n | call_expr\n left_hand_side_expr_nobf : new_expr_nobf\n | call_expr_nobf\n postfix_expr : left_hand_side_expr\n | left_hand_side_expr PLUSPLUS\n | left_hand_side_expr MINUSMINUS\n postfix_expr_nobf : left_hand_side_expr_nobf\n | left_hand_side_expr_nobf PLUSPLUS\n | left_hand_side_expr_nobf MINUSMINUS\n unary_expr : postfix_expr\n | unary_expr_common\n unary_expr_nobf : postfix_expr_nobf\n | unary_expr_common\n unary_expr_common : DELETE unary_expr\n | VOID unary_expr\n | TYPEOF unary_expr\n | PLUSPLUS unary_expr\n | MINUSMINUS unary_expr\n | PLUS unary_expr\n | MINUS unary_expr\n | BNOT unary_expr\n | NOT unary_expr\n multiplicative_expr : unary_expr\n | multiplicative_expr MULT unary_expr\n | multiplicative_expr DIV unary_expr\n | multiplicative_expr MOD unary_expr\n multiplicative_expr_nobf : unary_expr_nobf\n | multiplicative_expr_nobf MULT unary_expr\n | multiplicative_expr_nobf DIV unary_expr\n | multiplicative_expr_nobf MOD unary_expr\n additive_expr : multiplicative_expr\n | additive_expr PLUS multiplicative_expr\n | additive_expr MINUS multiplicative_expr\n additive_expr_nobf : multiplicative_expr_nobf\n | additive_expr_nobf PLUS multiplicative_expr\n | additive_expr_nobf MINUS multiplicative_expr\n shift_expr : additive_expr\n | shift_expr LSHIFT additive_expr\n | shift_expr RSHIFT additive_expr\n | shift_expr URSHIFT additive_expr\n shift_expr_nobf : additive_expr_nobf\n | shift_expr_nobf LSHIFT additive_expr\n | shift_expr_nobf RSHIFT additive_expr\n | shift_expr_nobf URSHIFT additive_expr\n relational_expr : shift_expr\n | relational_expr LT shift_expr\n | relational_expr GT shift_expr\n | relational_expr LE shift_expr\n | relational_expr GE shift_expr\n | relational_expr INSTANCEOF shift_expr\n | relational_expr IN shift_expr\n relational_expr_noin : shift_expr\n | relational_expr_noin LT shift_expr\n | relational_expr_noin GT shift_expr\n | relational_expr_noin LE shift_expr\n | relational_expr_noin GE shift_expr\n | relational_expr_noin INSTANCEOF shift_expr\n relational_expr_nobf : shift_expr_nobf\n | relational_expr_nobf LT shift_expr\n | relational_expr_nobf GT shift_expr\n | relational_expr_nobf LE shift_expr\n | relational_expr_nobf GE shift_expr\n | relational_expr_nobf INSTANCEOF shift_expr\n | relational_expr_nobf IN shift_expr\n equality_expr : relational_expr\n | equality_expr EQEQ relational_expr\n | equality_expr NE relational_expr\n | equality_expr STREQ relational_expr\n | equality_expr STRNEQ relational_expr\n equality_expr_noin : relational_expr_noin\n | equality_expr_noin EQEQ relational_expr\n | equality_expr_noin NE relational_expr\n | equality_expr_noin STREQ relational_expr\n | equality_expr_noin STRNEQ relational_expr\n equality_expr_nobf : relational_expr_nobf\n | equality_expr_nobf EQEQ relational_expr\n | equality_expr_nobf NE relational_expr\n | equality_expr_nobf STREQ relational_expr\n | equality_expr_nobf STRNEQ relational_expr\n bitwise_and_expr : equality_expr\n | bitwise_and_expr BAND equality_expr\n bitwise_and_expr_noin : equality_expr_noin\n | bitwise_and_expr_noin BAND equality_expr_noin\n bitwise_and_expr_nobf : equality_expr_nobf\n | bitwise_and_expr_nobf BAND equality_expr_nobf\n bitwise_xor_expr : bitwise_and_expr\n | bitwise_xor_expr BXOR bitwise_and_expr\n \n bitwise_xor_expr_noin : bitwise_and_expr_noin\n | bitwise_xor_expr_noin BXOR bitwise_and_expr_noin\n \n bitwise_xor_expr_nobf : bitwise_and_expr_nobf\n | bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf\n bitwise_or_expr : bitwise_xor_expr\n | bitwise_or_expr BOR bitwise_xor_expr\n \n bitwise_or_expr_noin : bitwise_xor_expr_noin\n | bitwise_or_expr_noin BOR bitwise_xor_expr_noin\n \n bitwise_or_expr_nobf : bitwise_xor_expr_nobf\n | bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf\n logical_and_expr : bitwise_or_expr\n | logical_and_expr AND bitwise_or_expr\n \n logical_and_expr_noin : bitwise_or_expr_noin\n | logical_and_expr_noin AND bitwise_or_expr_noin\n \n logical_and_expr_nobf : bitwise_or_expr_nobf\n | logical_and_expr_nobf AND bitwise_or_expr_nobf\n logical_or_expr : logical_and_expr\n | logical_or_expr OR logical_and_expr\n logical_or_expr_noin : logical_and_expr_noin\n | logical_or_expr_noin OR logical_and_expr_noin\n logical_or_expr_nobf : logical_and_expr_nobf\n | logical_or_expr_nobf OR logical_and_expr_nobf\n \n conditional_expr : logical_or_expr\n | logical_or_expr CONDOP assignment_expr COLON assignment_expr\n \n conditional_expr_noin : logical_or_expr_noin\n | logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin\n \n conditional_expr_nobf : logical_or_expr_nobf\n | logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr\n \n assignment_expr : conditional_expr\n | left_hand_side_expr assignment_operator assignment_expr\n \n assignment_expr_noin : conditional_expr_noin\n | left_hand_side_expr assignment_operator assignment_expr_noin\n \n assignment_expr_nobf : conditional_expr_nobf\n | left_hand_side_expr_nobf assignment_operator assignment_expr\n assignment_operator : EQ\n | MULTEQUAL\n | DIVEQUAL\n | MODEQUAL\n | PLUSEQUAL\n | MINUSEQUAL\n | LSHIFTEQUAL\n | RSHIFTEQUAL\n | URSHIFTEQUAL\n | ANDEQUAL\n | XOREQUAL\n | OREQUAL\n expr : assignment_expr\n | expr COMMA assignment_expr\n expr_noin : assignment_expr_noin\n | expr_noin COMMA assignment_expr_noin\n expr_nobf : assignment_expr_nobf\n | expr_nobf COMMA assignment_expr\n variable_statement : VAR variable_declaration_list SEMI\n | VAR variable_declaration_list AUTOSEMI\n \n variable_declaration_list : variable_declaration\n | variable_declaration_list COMMA variable_declaration\n \n variable_declaration_list_noin : variable_declaration_noin\n | variable_declaration_list_noin COMMA variable_declaration_noin\n variable_declaration : identifier\n | identifier initializer\n variable_declaration_noin : identifier\n | identifier initializer_noin\n initializer : EQ assignment_exprinitializer_noin : EQ assignment_expr_noinempty_statement : SEMIexpr_statement : expr_nobf SEMI\n | expr_nobf AUTOSEMI\n if_statement : IF LPAREN expr RPAREN statementif_statement : IF LPAREN expr RPAREN statement ELSE statement\n iteration_statement : DO statement WHILE LPAREN expr RPAREN SEMI\n | DO statement WHILE LPAREN expr RPAREN AUTOSEMI\n iteration_statement : WHILE LPAREN expr RPAREN statement\n iteration_statement : FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement\n | FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement\n \n iteration_statement : FOR LPAREN left_hand_side_expr IN expr RPAREN statement\n \n iteration_statement : FOR LPAREN VAR identifier IN expr RPAREN statement\n \n iteration_statement : FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement\n expr_opt : empty\n | expr\n expr_noin_opt : empty\n | expr_noin\n continue_statement : CONTINUE SEMI\n | CONTINUE AUTOSEMI\n continue_statement : CONTINUE identifier SEMI\n | CONTINUE identifier AUTOSEMI\n break_statement : BREAK SEMI\n | BREAK AUTOSEMI\n break_statement : BREAK identifier SEMI\n | BREAK identifier AUTOSEMI\n return_statement : RETURN SEMI\n | RETURN AUTOSEMI\n return_statement : RETURN expr SEMI\n | RETURN expr AUTOSEMI\n with_statement : WITH LPAREN expr RPAREN statementswitch_statement : SWITCH LPAREN expr RPAREN case_block\n case_block : LBRACE case_clauses_opt RBRACE\n | LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE\n case_clauses_opt : empty\n | case_clauses\n case_clauses : case_clause\n | case_clauses case_clause\n case_clause : CASE expr COLON source_elementsdefault_clause : DEFAULT COLON source_elementslabelled_statement : identifier COLON statementthrow_statement : THROW expr SEMI\n | THROW expr AUTOSEMI\n try_statement : TRY block catchtry_statement : TRY block finallytry_statement : TRY block catch finallycatch : CATCH LPAREN identifier RPAREN blockfinally : FINALLY blockdebugger_statement : DEBUGGER SEMI\n | DEBUGGER AUTOSEMI\n \n function_declaration : FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n \n function_expr : FUNCTION LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n \n function_expr : FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n formal_parameter_list : identifier\n | formal_parameter_list COMMA identifier\n function_body : source_elements' + +_lr_action_items = {'$end':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,125,126,130,133,134,136,137,139,140,146,147,215,302,303,304,327,328,329,330,331,332,335,336,337,338,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-1,0,-2,-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-322,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-327,-329,-286,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'FUNCTION':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[23,23,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,109,23,-283,23,109,109,109,-1,109,109,109,109,109,109,109,109,109,-6,23,109,258,-284,-285,109,109,-24,109,109,-300,-301,-304,-305,-308,-309,109,109,-330,-331,109,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,109,109,109,258,109,109,109,258,109,-90,-88,-89,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-322,109,109,109,109,109,258,109,109,258,109,109,258,258,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-25,-271,-272,109,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,23,258,109,23,109,23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,23,-327,-329,109,109,109,23,23,109,-286,-290,109,109,109,-312,-313,23,23,23,109,109,23,109,109,-332,23,23,-287,-288,-289,109,23,-293,-314,-328,-333,23,23,-294,23,23,23,-291,23,-295,-315,-292,]),'LBRACE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,40,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,166,168,171,175,177,178,179,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,212,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,340,357,358,380,382,383,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,453,454,457,459,460,461,464,466,469,476,478,482,484,486,506,507,515,519,520,521,524,526,531,533,534,539,540,541,545,546,547,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[26,26,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,110,26,-283,26,110,110,26,110,-1,110,110,110,110,110,110,110,110,110,-6,26,110,-284,-285,110,110,-24,110,110,-300,-301,-304,-305,-308,-309,110,110,-330,-331,110,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,110,110,110,110,110,-90,-88,-89,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,382,-322,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-25,-271,-272,110,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,26,-1,-91,460,26,464,110,26,110,26,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,26,508,-327,-329,110,110,110,26,515,26,110,519,-286,-290,110,110,110,-312,-313,26,26,545,546,26,110,110,26,110,110,26,-332,26,26,568,-287,-288,-289,110,26,-293,-314,-328,-333,26,26,-294,26,26,26,-291,26,-295,-315,-292,]),'VAR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,132,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[27,27,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,27,-283,27,-6,27,269,-284,-285,-24,313,-300,-301,-304,-305,-308,-309,-330,-331,269,269,-322,269,269,269,269,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,27,269,27,27,27,-327,-329,27,27,-286,-290,-312,-313,27,27,27,27,-332,27,27,-287,-288,-289,27,-293,-314,-328,-333,27,27,-294,27,27,27,-291,27,-295,-315,-292,]),'SEMI':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,28,29,31,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,89,92,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,125,126,130,132,133,134,135,136,137,138,139,140,141,144,146,147,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,306,308,312,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,335,336,337,338,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,382,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,429,430,449,451,453,455,456,458,460,464,467,468,471,476,478,479,480,481,482,485,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,510,512,515,516,518,519,524,525,527,528,529,532,533,541,543,545,546,548,549,550,553,554,556,557,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[28,28,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,28,-283,125,28,133,136,139,146,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-6,28,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,303,-273,-277,-284,-285,-24,-1,-300,-301,327,-304,-305,329,-308,-309,331,335,-330,-331,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-278,-270,427,-135,-298,-299,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,28,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,28,28,-1,482,-279,-275,28,-327,-329,-125,-128,-112,28,28,-121,-107,-94,-286,-290,526,-296,-297,-1,-280,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-312,-313,-246,-85,28,-334,-242,28,28,549,552,-276,-279,-282,28,-332,-335,28,28,-287,-288,-289,-280,28,-293,-244,-314,-328,-333,-336,28,28,-294,28,28,28,-337,-291,28,-295,-315,-292,]),'IF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[30,30,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,30,-283,30,-6,30,259,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,259,259,-322,259,259,259,259,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,30,259,30,30,30,-327,-329,30,30,-286,-290,-312,-313,30,30,30,30,-332,30,30,-287,-288,-289,30,-293,-314,-328,-333,30,30,-294,30,30,30,-291,30,-295,-315,-292,]),'DO':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[31,31,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,-283,31,-6,31,254,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,254,254,-322,254,254,254,254,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,31,254,31,31,31,-327,-329,31,31,-286,-290,-312,-313,31,31,31,31,-332,31,31,-287,-288,-289,31,-293,-314,-328,-333,31,31,-294,31,31,31,-291,31,-295,-315,-292,]),'WHILE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,129,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[32,32,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,32,-283,32,-6,32,271,-284,-285,310,-24,-300,-301,-304,-305,-308,-309,-330,-331,271,271,-322,271,271,271,271,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,32,271,32,32,32,-327,-329,32,32,-286,-290,-312,-313,32,32,32,32,-332,32,32,-287,-288,-289,32,-293,-314,-328,-333,32,32,-294,32,32,32,-291,32,-295,-315,-292,]),'FOR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[33,33,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,33,-283,33,-6,33,257,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,257,257,-322,257,257,257,257,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,33,257,33,33,33,-327,-329,33,33,-286,-290,-312,-313,33,33,33,33,-332,33,33,-287,-288,-289,33,-293,-314,-328,-333,33,33,-294,33,33,33,-291,33,-295,-315,-292,]),'CONTINUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[34,34,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,34,-283,34,-6,34,250,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,250,250,-322,250,250,250,250,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,34,250,34,34,34,-327,-329,34,34,-286,-290,-312,-313,34,34,34,34,-332,34,34,-287,-288,-289,34,-293,-314,-328,-333,34,34,-294,34,34,34,-291,34,-295,-315,-292,]),'BREAK':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[35,35,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,35,-283,35,-6,35,247,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,247,247,-322,247,247,247,247,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,35,247,35,35,35,-327,-329,35,35,-286,-290,-312,-313,35,35,35,35,-332,35,35,-287,-288,-289,35,-293,-314,-328,-333,35,35,-294,35,35,35,-291,35,-295,-315,-292,]),'RETURN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[36,36,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,36,-283,36,-6,36,263,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,263,263,-322,263,263,263,263,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,36,263,36,36,36,-327,-329,36,36,-286,-290,-312,-313,36,36,36,36,-332,36,36,-287,-288,-289,36,-293,-314,-328,-333,36,36,-294,36,36,36,-291,36,-295,-315,-292,]),'WITH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[37,37,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,37,-283,37,-6,37,272,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,272,272,-322,272,272,272,272,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,37,272,37,37,37,-327,-329,37,37,-286,-290,-312,-313,37,37,37,37,-332,37,37,-287,-288,-289,37,-293,-314,-328,-333,37,37,-294,37,37,37,-291,37,-295,-315,-292,]),'SWITCH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[38,38,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,38,-283,38,-6,38,264,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,264,264,-322,264,264,264,264,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,38,264,38,38,38,-327,-329,38,38,-286,-290,-312,-313,38,38,38,38,-332,38,38,-287,-288,-289,38,-293,-314,-328,-333,38,38,-294,38,38,38,-291,38,-295,-315,-292,]),'THROW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[39,39,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,39,-283,39,-6,39,266,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,266,266,-322,266,266,266,266,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,39,266,39,39,39,-327,-329,39,39,-286,-290,-312,-313,39,39,39,39,-332,39,39,-287,-288,-289,39,-293,-314,-328,-333,39,39,-294,39,39,39,-291,39,-295,-315,-292,]),'TRY':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[40,40,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,40,-283,40,-6,40,267,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,267,267,-322,267,267,267,267,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,40,267,40,40,40,-327,-329,40,40,-286,-290,-312,-313,40,40,40,40,-332,40,40,-287,-288,-289,40,-293,-314,-328,-333,40,40,-294,40,40,40,-291,40,-295,-315,-292,]),'DEBUGGER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[41,41,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,41,-283,41,-6,41,251,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,251,251,-322,251,251,251,251,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,41,251,41,41,41,-327,-329,41,41,-286,-290,-312,-313,41,41,41,41,-332,41,41,-287,-288,-289,41,-293,-314,-328,-333,41,41,-294,41,41,41,-291,41,-295,-315,-292,]),'ID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,31,34,35,36,39,51,52,77,78,82,83,84,85,86,87,88,89,91,92,102,109,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,307,313,327,328,329,330,331,332,335,336,337,338,357,358,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,452,453,454,457,459,460,464,466,475,476,478,482,483,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[43,43,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,43,43,43,43,-283,43,43,43,43,43,43,-1,43,43,43,43,43,43,43,43,43,-6,43,43,43,43,43,-284,-285,43,43,-24,43,43,-300,-301,-304,-305,-308,-309,43,43,-330,-331,43,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,43,43,43,43,43,43,43,43,43,-90,-88,-89,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-322,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-25,-271,-272,43,43,43,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-327,43,-329,43,43,43,43,43,43,43,-286,-290,43,43,43,43,-312,-313,43,43,43,43,43,43,43,43,-332,43,43,-287,-288,-289,43,43,-293,-314,-328,-333,43,43,-294,43,43,43,-291,43,-295,-315,-292,]),'NEW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[51,51,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,102,51,-283,51,102,102,102,-1,102,102,102,102,102,102,102,102,102,-6,51,102,262,-284,-285,102,102,-24,102,102,-300,-301,-304,-305,-308,-309,102,102,-330,-331,102,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,102,51,102,262,102,51,102,262,102,-90,-88,-89,51,51,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-322,102,102,102,102,102,262,102,102,262,102,102,262,262,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-25,-271,-272,102,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,51,262,102,51,102,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,51,-327,-329,102,102,102,51,51,102,-286,-290,102,102,102,-312,-313,51,51,51,102,102,51,102,102,-332,51,51,-287,-288,-289,102,51,-293,-314,-328,-333,51,51,-294,51,51,51,-291,51,-295,-315,-292,]),'THIS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[57,57,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,57,57,-283,57,57,57,57,-1,57,57,57,57,57,57,57,57,57,-6,57,57,265,-284,-285,57,57,-24,57,57,-300,-301,-304,-305,-308,-309,57,57,-330,-331,57,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,57,57,57,265,57,57,57,265,57,-90,-88,-89,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-322,57,57,57,57,57,265,57,57,265,57,57,265,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-25,-271,-272,57,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,57,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-327,-329,57,57,57,57,57,57,-286,-290,57,57,57,-312,-313,57,57,57,57,57,57,57,57,-332,57,57,-287,-288,-289,57,57,-293,-314,-328,-333,57,57,-294,57,57,57,-291,57,-295,-315,-292,]),'LPAREN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,31,32,33,36,37,38,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,90,92,99,101,102,104,105,107,108,109,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,234,235,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,310,327,328,329,330,331,332,335,336,337,338,339,346,347,352,353,354,356,357,358,382,390,393,394,398,400,401,402,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[25,25,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,91,-78,25,25,-283,128,25,131,132,25,142,143,25,-37,168,168,25,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,25,25,25,25,25,25,25,25,25,-6,211,25,168,168,25,-105,-106,-76,-77,91,-78,-284,-285,25,25,-24,25,25,-300,-301,-304,-305,-308,-309,25,25,-330,-331,25,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,25,25,-124,25,25,25,-123,25,168,25,-90,-88,-89,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-322,-82,25,25,25,25,-120,25,25,-119,25,168,25,25,397,-92,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-25,-271,-272,25,425,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,452,-126,-127,-113,-114,-83,-84,-1,-91,25,-122,-108,-109,-93,25,474,475,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-327,-329,25,-125,-128,25,-112,25,25,25,25,-121,-107,-94,-286,-290,25,25,25,-312,-313,-85,25,-334,25,25,25,25,25,25,25,-332,-335,25,25,-287,-288,-289,25,25,-293,-314,-328,-333,-336,25,25,-294,25,25,25,-337,-291,25,-295,-315,-292,]),'LBRACKET':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,99,101,102,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[52,52,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,52,52,-283,52,52,52,-37,166,171,52,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,52,52,52,52,52,52,52,52,52,-6,52,224,228,52,-105,-106,-76,-77,-78,-284,-285,52,52,-24,52,52,-300,-301,-304,-305,-308,-309,52,52,-330,-331,52,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,52,52,-124,52,52,52,-123,52,228,52,-90,-88,-89,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-322,-82,52,52,52,52,-120,52,52,-119,52,228,52,52,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-25,-271,-272,52,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-126,-127,-113,-114,-83,-84,-1,-91,52,-122,-108,-109,-93,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-327,-329,52,-125,-128,52,-112,52,52,52,52,-121,-107,-94,-286,-290,52,52,52,-312,-313,-85,52,-334,52,52,52,52,52,52,52,-332,-335,52,52,-287,-288,-289,52,52,-293,-314,-328,-333,-336,52,52,-294,52,52,52,-337,-291,52,-295,-315,-292,]),'NULL':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[67,67,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,67,67,-283,67,67,67,67,-1,67,67,67,67,67,67,67,67,67,-6,67,67,273,-284,-285,67,67,-24,67,67,-300,-301,-304,-305,-308,-309,67,67,-330,-331,67,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,67,67,67,273,67,67,67,273,67,-90,-88,-89,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-322,67,67,67,67,67,273,67,67,273,67,67,273,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-25,-271,-272,67,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,67,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-327,-329,67,67,67,67,67,67,-286,-290,67,67,67,-312,-313,67,67,67,67,67,67,67,67,-332,67,67,-287,-288,-289,67,67,-293,-314,-328,-333,67,67,-294,67,67,67,-291,67,-295,-315,-292,]),'TRUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[68,68,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,68,68,-283,68,68,68,68,-1,68,68,68,68,68,68,68,68,68,-6,68,68,274,-284,-285,68,68,-24,68,68,-300,-301,-304,-305,-308,-309,68,68,-330,-331,68,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,68,68,68,274,68,68,68,274,68,-90,-88,-89,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-322,68,68,68,68,68,274,68,68,274,68,68,274,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-25,-271,-272,68,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,68,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-327,-329,68,68,68,68,68,68,-286,-290,68,68,68,-312,-313,68,68,68,68,68,68,68,68,-332,68,68,-287,-288,-289,68,68,-293,-314,-328,-333,68,68,-294,68,68,68,-291,68,-295,-315,-292,]),'FALSE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[69,69,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,69,69,-283,69,69,69,69,-1,69,69,69,69,69,69,69,69,69,-6,69,69,275,-284,-285,69,69,-24,69,69,-300,-301,-304,-305,-308,-309,69,69,-330,-331,69,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,69,69,69,275,69,69,69,275,69,-90,-88,-89,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-322,69,69,69,69,69,275,69,69,275,69,69,275,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-25,-271,-272,69,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,69,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-327,-329,69,69,69,69,69,69,-286,-290,69,69,69,-312,-313,69,69,69,69,69,69,69,69,-332,69,69,-287,-288,-289,69,69,-293,-314,-328,-333,69,69,-294,69,69,69,-291,69,-295,-315,-292,]),'NUMBER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[70,70,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,70,70,-283,70,70,70,70,-1,70,70,70,70,70,70,70,70,70,-6,70,70,70,-284,-285,70,70,-24,70,70,-300,-301,-304,-305,-308,-309,70,70,-330,-331,70,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,70,70,70,70,70,70,70,-90,-88,-89,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-322,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-25,-271,-272,70,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-327,-329,70,70,70,70,70,70,-286,-290,70,70,70,-312,-313,70,70,70,70,70,70,70,70,-332,70,70,-287,-288,-289,70,70,-293,-314,-328,-333,70,70,-294,70,70,70,-291,70,-295,-315,-292,]),'STRING':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[71,71,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,71,71,-283,71,71,71,71,-1,71,71,71,71,71,71,71,71,71,-6,71,71,71,-284,-285,71,71,-24,71,71,-300,-301,-304,-305,-308,-309,71,71,-330,-331,71,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,71,71,71,71,71,71,71,-90,-88,-89,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-322,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-25,-271,-272,71,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-327,-329,71,71,71,71,71,71,-286,-290,71,71,71,-312,-313,71,71,71,71,71,71,71,71,-332,71,71,-287,-288,-289,71,71,-293,-314,-328,-333,71,71,-294,71,71,71,-291,71,-295,-315,-292,]),'REGEX':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[72,72,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,72,72,-283,72,72,72,72,-1,72,72,72,72,72,72,72,72,72,-6,72,72,-284,-285,72,72,-24,72,72,-300,-301,-304,-305,-308,-309,72,72,-330,-331,72,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,72,72,72,72,72,72,72,-90,-88,-89,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-322,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-25,-271,-272,72,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-327,-329,72,72,72,72,72,72,-286,-290,72,72,72,-312,-313,72,72,72,72,72,72,72,72,-332,72,72,-287,-288,-289,72,72,-293,-314,-328,-333,72,72,-294,72,72,72,-291,72,-295,-315,-292,]),'DELETE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[84,84,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,84,84,-283,84,84,84,-1,84,84,84,84,84,84,84,84,84,-6,84,253,-284,-285,84,84,-24,84,84,-300,-301,-304,-305,-308,-309,84,84,-330,-331,84,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,84,84,84,253,84,84,84,253,84,-90,-88,-89,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-322,84,84,84,84,84,253,84,84,253,84,84,253,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-25,-271,-272,84,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,84,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-327,-329,84,84,84,84,84,84,-286,-290,84,84,84,-312,-313,84,84,84,84,84,84,84,84,-332,84,84,-287,-288,-289,84,84,-293,-314,-328,-333,84,84,-294,84,84,84,-291,84,-295,-315,-292,]),'VOID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[85,85,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,85,85,-283,85,85,85,-1,85,85,85,85,85,85,85,85,85,-6,85,270,-284,-285,85,85,-24,85,85,-300,-301,-304,-305,-308,-309,85,85,-330,-331,85,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,85,85,85,270,85,85,85,270,85,-90,-88,-89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-322,85,85,85,85,85,270,85,85,270,85,85,270,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-25,-271,-272,85,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,85,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-327,-329,85,85,85,85,85,85,-286,-290,85,85,85,-312,-313,85,85,85,85,85,85,85,85,-332,85,85,-287,-288,-289,85,85,-293,-314,-328,-333,85,85,-294,85,85,85,-291,85,-295,-315,-292,]),'TYPEOF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[86,86,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,86,86,-283,86,86,86,-1,86,86,86,86,86,86,86,86,86,-6,86,268,-284,-285,86,86,-24,86,86,-300,-301,-304,-305,-308,-309,86,86,-330,-331,86,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,86,86,86,268,86,86,86,268,86,-90,-88,-89,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-322,86,86,86,86,86,268,86,86,268,86,86,268,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-25,-271,-272,86,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,86,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-327,-329,86,86,86,86,86,86,-286,-290,86,86,86,-312,-313,86,86,86,86,86,86,86,86,-332,86,86,-287,-288,-289,86,86,-293,-314,-328,-333,86,86,-294,86,86,86,-291,86,-295,-315,-292,]),'PLUSPLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[82,82,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,82,82,-283,82,82,82,-37,149,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,82,82,82,82,82,82,82,82,82,-6,82,219,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,82,82,-24,82,82,-300,-301,-304,-305,-308,-309,82,82,-330,-331,82,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,82,82,-124,82,82,82,-123,82,-118,-115,82,-90,-88,-89,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,219,-322,-82,82,82,82,82,-120,82,82,-119,82,-116,-115,82,82,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-25,-271,-272,82,219,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,149,-126,-127,-113,-114,-83,-84,-1,-91,82,-122,-108,-109,-93,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-327,-329,82,-125,-128,82,-112,82,82,82,82,-121,-107,-94,-286,-290,82,82,82,219,-312,-313,-85,82,-334,82,82,82,82,82,82,82,-332,-335,82,82,-287,-288,-289,82,82,-293,-314,-328,-333,-336,82,82,-294,82,82,82,-337,-291,82,-295,-315,-292,]),'MINUSMINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[83,83,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,83,83,-283,83,83,83,-37,150,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,83,83,83,83,83,83,83,83,83,-6,83,220,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,83,83,-24,83,83,-300,-301,-304,-305,-308,-309,83,83,-330,-331,83,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,83,83,-124,83,83,83,-123,83,-118,-115,83,-90,-88,-89,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,220,-322,-82,83,83,83,83,-120,83,83,-119,83,-116,-115,83,83,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-25,-271,-272,83,220,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,150,-126,-127,-113,-114,-83,-84,-1,-91,83,-122,-108,-109,-93,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-327,-329,83,-125,-128,83,-112,83,83,83,83,-121,-107,-94,-286,-290,83,83,83,220,-312,-313,-85,83,-334,83,83,83,83,83,83,83,-332,-335,83,83,-287,-288,-289,83,83,-293,-314,-328,-333,-336,83,83,-294,83,83,83,-337,-291,83,-295,-315,-292,]),'PLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[77,77,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,77,77,-283,77,77,77,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,196,-165,77,77,-158,-143,-144,77,77,77,77,77,77,77,-6,77,-135,-131,-132,-115,-105,-106,-76,-77,-78,297,-162,-154,-141,-142,-284,-285,77,77,-24,77,77,-300,-301,-304,-305,-308,-309,77,77,-330,-331,77,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,77,77,-124,77,77,77,-123,77,-118,-115,77,-90,-88,-89,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,77,77,-136,-137,77,77,-120,77,77,-119,77,-116,-115,77,77,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-25,-271,-272,77,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,297,297,297,-166,-167,-159,-160,-161,77,-122,-108,-109,-93,77,297,297,297,-163,-164,-155,-156,-157,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-327,-329,77,-125,-128,77,-112,77,77,77,77,-121,-107,-94,-286,-290,77,77,77,-135,-312,-313,-85,77,-334,77,77,77,77,77,77,77,-332,-335,77,77,-287,-288,-289,77,77,-293,-314,-328,-333,-336,77,77,-294,77,77,77,-337,-291,77,-295,-315,-292,]),'MINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[78,78,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,78,78,-283,78,78,78,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,197,-165,78,78,-158,-143,-144,78,78,78,78,78,78,78,-6,78,-135,-131,-132,-115,-105,-106,-76,-77,-78,298,-162,-154,-141,-142,-284,-285,78,78,-24,78,78,-300,-301,-304,-305,-308,-309,78,78,-330,-331,78,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,78,78,-124,78,78,78,-123,78,-118,-115,78,-90,-88,-89,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,78,78,-136,-137,78,78,-120,78,78,-119,78,-116,-115,78,78,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-25,-271,-272,78,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,298,298,298,-166,-167,-159,-160,-161,78,-122,-108,-109,-93,78,298,298,298,-163,-164,-155,-156,-157,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-327,-329,78,-125,-128,78,-112,78,78,78,78,-121,-107,-94,-286,-290,78,78,78,-135,-312,-313,-85,78,-334,78,78,78,78,78,78,78,-332,-335,78,78,-287,-288,-289,78,78,-293,-314,-328,-333,-336,78,78,-294,78,78,78,-337,-291,78,-295,-315,-292,]),'BNOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[87,87,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,87,87,-283,87,87,87,-1,87,87,87,87,87,87,87,87,87,-6,87,-284,-285,87,87,-24,87,87,-300,-301,-304,-305,-308,-309,87,87,-330,-331,87,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,87,87,87,87,87,87,87,-90,-88,-89,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-322,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-25,-271,-272,87,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-327,-329,87,87,87,87,87,87,-286,-290,87,87,87,-312,-313,87,87,87,87,87,87,87,87,-332,87,87,-287,-288,-289,87,87,-293,-314,-328,-333,87,87,-294,87,87,87,-291,87,-295,-315,-292,]),'NOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[88,88,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,88,88,-283,88,88,88,-1,88,88,88,88,88,88,88,88,88,-6,88,-284,-285,88,88,-24,88,88,-300,-301,-304,-305,-308,-309,88,88,-330,-331,88,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,88,88,88,88,88,88,88,-90,-88,-89,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-322,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-25,-271,-272,88,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-327,-329,88,88,88,88,88,88,-286,-290,88,88,88,-312,-313,88,88,88,88,88,88,88,88,-332,88,88,-287,-288,-289,88,88,-293,-314,-328,-333,88,88,-294,88,88,88,-291,88,-295,-315,-292,]),'RBRACE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,89,95,96,97,98,99,100,101,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,125,126,130,133,134,136,137,139,140,146,147,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,327,328,329,330,331,332,335,336,337,338,347,354,356,382,386,388,390,391,393,394,395,396,398,399,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,451,453,456,460,462,463,464,467,468,471,472,473,476,478,506,507,508,512,514,515,516,517,518,519,535,536,537,538,541,542,543,544,545,546,548,549,550,556,558,559,561,563,564,565,566,567,568,571,573,574,575,576,577,578,579,581,582,583,584,585,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-1,-283,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-6,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,235,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,302,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,398,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-127,-83,-84,-1,-248,-236,-122,-230,-108,-109,-224,-218,-93,471,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-327,-329,-128,-1,516,-340,-1,-121,-107,-94,-96,-97,-286,-290,-312,-313,-1,-85,541,-1,-334,543,-242,-1,558,-316,-317,-318,-332,564,-335,565,-1,-1,-287,-288,-289,-293,-314,-1,-319,-328,-333,-336,576,577,-1,-294,582,-1,-1,-337,-98,585,-291,-295,-315,-321,-320,-99,-292,]),'CASE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,537,538,541,548,549,550,556,558,559,561,563,564,571,574,575,579,581,582,583,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,248,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,248,248,-322,248,248,248,248,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,248,-327,-329,-286,-290,-312,-313,539,539,-318,-332,-287,-288,-289,-293,-314,539,-319,-328,-333,-294,-1,-1,-291,-295,-315,-321,-320,-292,]),'DEFAULT':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,535,536,537,538,541,548,549,550,556,558,561,563,564,571,575,579,581,582,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,252,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,252,252,-322,252,252,252,252,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,252,-327,-329,-286,-290,-312,-313,-1,560,-316,-317,-318,-332,-287,-288,-289,-293,-314,-319,-328,-333,-294,-1,-291,-295,-315,-320,-292,]),'ELSE':([8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,255,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,255,255,-322,255,255,255,255,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,255,-327,-329,524,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'COLON':([24,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,238,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,318,319,320,321,322,323,324,325,326,342,347,354,356,385,386,387,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,467,468,471,488,489,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,518,543,557,560,562,565,576,],[92,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,400,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-249,-243,-237,-231,-225,-219,-213,-201,-183,454,-127,-83,-84,-266,-248,466,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-121,-107,-94,-135,-250,534,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-242,-335,-244,574,575,-336,-337,]),'PERIOD':([24,43,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,99,101,104,105,107,108,111,165,170,174,216,223,227,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,512,516,541,543,564,565,576,],[-78,-37,167,172,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,225,229,-105,-106,-76,-77,-78,-124,-123,229,-82,-120,-119,229,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,-85,-334,-336,-335,-337,-336,-337,]),'EQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,124,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,429,455,456,458,467,468,471,488,512,516,529,541,543,564,565,576,],[-78,-37,151,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,151,-131,-132,-115,-105,-106,-76,-77,-78,307,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,151,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,486,-125,-128,-112,-121,-107,-94,151,-85,-334,486,-336,-335,-337,-336,-337,]),'MULTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,152,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,152,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,152,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,152,-85,-334,-336,-335,-337,-336,-337,]),'DIVEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,153,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,153,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,153,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,153,-85,-334,-336,-335,-337,-336,-337,]),'MODEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,154,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,154,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,154,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,154,-85,-334,-336,-335,-337,-336,-337,]),'PLUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,155,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,155,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,155,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,155,-85,-334,-336,-335,-337,-336,-337,]),'MINUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,156,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,156,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,156,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,156,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,157,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,157,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,157,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,157,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,158,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,158,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,158,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,158,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,159,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,159,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,159,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,159,-85,-334,-336,-335,-337,-336,-337,]),'ANDEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,160,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,160,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,160,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,160,-85,-334,-336,-335,-337,-336,-337,]),'XOREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,161,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,161,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,161,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,161,-85,-334,-336,-335,-337,-336,-337,]),'OREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,162,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,162,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,162,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,162,-85,-334,-336,-335,-337,-336,-337,]),'MULT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,198,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,299,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,299,299,-159,-160,-161,-122,-108,-109,-93,299,299,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'DIV':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,199,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,300,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,300,300,-159,-160,-161,-122,-108,-109,-93,300,300,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'MOD':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,200,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,301,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,301,301,-159,-160,-161,-122,-108,-109,-93,301,301,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,193,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,294,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,294,-138,-126,-127,-113,-114,-83,-84,294,294,294,294,294,294,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,294,294,294,294,294,294,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,294,294,294,294,294,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,194,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,295,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,295,-138,-126,-127,-113,-114,-83,-84,295,295,295,295,295,295,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,295,295,295,295,295,295,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,295,295,295,295,295,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,195,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,296,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,296,-138,-126,-127,-113,-114,-83,-84,296,296,296,296,296,296,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,296,296,296,296,296,296,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,296,296,296,296,296,-85,-334,-336,-335,-337,-336,-337,]),'LT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,187,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,288,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,444,-183,-138,-126,-127,-113,-114,-83,-84,288,288,288,288,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,288,288,288,288,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,288,288,288,288,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,188,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,289,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,445,-183,-138,-126,-127,-113,-114,-83,-84,289,289,289,289,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,289,289,289,289,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,289,289,289,289,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'LE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,189,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,290,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,446,-183,-138,-126,-127,-113,-114,-83,-84,290,290,290,290,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,290,290,290,290,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,290,290,290,290,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,190,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,291,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,447,-183,-138,-126,-127,-113,-114,-83,-84,291,291,291,291,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,291,291,291,291,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,291,291,291,291,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'INSTANCEOF':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,191,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,261,-78,292,-176,-168,-162,-154,-141,-142,-139,-140,-124,261,-123,261,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,261,-119,261,-116,-115,-92,261,261,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,448,-183,-138,-126,-127,-113,-114,-83,-84,292,292,292,292,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,261,292,292,292,292,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,292,292,292,292,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'IN':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,318,319,320,321,322,323,324,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,429,455,456,458,467,468,471,485,488,489,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,532,541,543,557,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,192,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,260,-78,293,-176,-168,-162,-154,-141,-142,-139,-140,-124,260,-123,260,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,260,-119,260,-116,-115,-92,260,260,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,431,-249,-243,-237,-231,-225,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,293,293,293,293,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,260,293,293,293,293,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,484,-125,-128,-112,-121,-107,-94,531,-135,-250,-238,-232,-226,-220,-214,293,293,293,293,-184,-185,-186,-187,-188,-85,-334,-282,-336,-335,-244,-337,-336,-337,]),'EQEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,183,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,284,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,440,-201,-183,-138,-126,-127,-113,-114,-83,-84,183,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,284,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,440,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'NE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,184,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,285,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,441,-201,-183,-138,-126,-127,-113,-114,-83,-84,184,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,285,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,441,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STREQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,185,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,286,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,442,-201,-183,-138,-126,-127,-113,-114,-83,-84,185,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,286,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,442,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STRNEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,186,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,287,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,443,-201,-183,-138,-126,-127,-113,-114,-83,-84,186,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,287,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,443,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BAND':([24,43,45,47,48,50,54,55,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,323,324,325,326,344,346,347,352,353,354,356,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,182,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,283,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,439,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,182,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,283,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,439,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BXOR':([24,43,45,47,48,50,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,322,323,324,325,326,344,346,347,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,181,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,233,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,438,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,181,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,233,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,438,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BOR':([24,43,45,47,48,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,321,322,323,324,325,326,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,180,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,232,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,437,-225,-219,-213,-201,-183,-138,-126,-127,180,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,232,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,437,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AND':([24,43,45,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,169,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,226,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,436,-231,-225,-219,-213,-201,-183,169,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,226,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,436,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'CONDOP':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,163,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,221,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,434,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'OR':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,164,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,222,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,435,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AUTOSEMI':([24,29,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,135,138,141,144,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,455,456,458,467,468,471,510,512,516,518,525,541,543,564,565,576,],[-78,126,134,137,140,147,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,304,-273,-277,328,330,332,336,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,-125,-128,-112,-121,-107,-94,-246,-85,-334,-242,550,-336,-335,-337,-336,-337,]),'COMMA':([24,29,42,43,44,45,46,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,141,144,149,150,165,170,173,174,176,177,179,201,202,203,204,205,206,207,208,209,210,213,214,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,309,311,314,316,317,318,319,320,321,322,323,324,325,326,333,334,341,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,381,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,428,429,430,455,456,458,465,467,468,470,471,472,473,477,481,485,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,510,511,512,513,516,518,528,529,530,532,541,543,553,555,557,562,564,565,576,577,585,],[-78,127,-269,-37,-251,-138,-245,-133,-134,-239,-117,177,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,217,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,305,-273,-277,217,217,-139,-140,-124,-123,-118,-115,357,-90,358,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,384,-338,-82,-136,-137,-120,-119,-116,-115,-92,399,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,217,217,-135,433,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,217,217,-252,-240,-138,217,-126,-127,457,-129,-234,217,-113,-114,-83,-86,-84,177,-91,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,384,-266,-248,-236,217,-122,-230,217,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,483,-279,-275,-125,-128,-112,-339,-121,-107,384,-94,-96,-97,217,217,-280,217,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-246,-130,-85,-87,-334,-242,-276,-279,217,-282,-336,-335,-280,217,-244,217,-337,-336,-337,-98,-99,]),'RPAREN':([43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,91,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,168,201,202,203,204,205,206,207,208,209,210,211,213,214,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,309,311,333,334,347,348,349,354,356,381,385,386,388,390,391,393,394,395,396,397,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,465,467,468,470,471,474,477,480,481,487,509,511,512,516,518,522,523,526,530,543,551,552,555,565,570,576,],[-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,212,216,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,347,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,380,383,-338,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,424,426,449,450,-127,456,-129,-83,-84,461,-266,-248,-236,-122,-230,-108,-109,-224,-218,469,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-339,-121,-107,520,-94,521,525,-296,-297,533,540,-130,-85,-334,-242,547,-104,-1,554,-335,569,-1,572,-336,580,-337,]),'RBRACKET':([43,52,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,175,176,177,178,179,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,345,347,351,354,355,356,357,358,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,459,467,468,471,512,513,516,518,543,565,576,],[-37,-1,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,354,356,-90,-88,-89,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,455,-127,458,-83,-86,-84,-1,-91,-266,-248,-236,467,-122,-230,468,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,512,-121,-107,-94,-85,-87,-334,-242,-335,-336,-337,]),'GETPROP':([110,399,],[239,239,]),'SETPROP':([110,399,],[240,240,]),'CATCH':([110,145,167,172,225,229,239,240,302,399,],[249,339,249,249,249,249,249,249,-25,249,]),'FINALLY':([110,145,167,172,225,229,239,240,302,337,399,563,],[256,340,256,256,256,256,256,256,-25,340,256,-328,]),'CLASS':([110,167,172,225,229,239,240,399,],[276,276,276,276,276,276,276,276,]),'CONST':([110,167,172,225,229,239,240,399,],[277,277,277,277,277,277,277,277,]),'ENUM':([110,167,172,225,229,239,240,399,],[278,278,278,278,278,278,278,278,]),'EXPORT':([110,167,172,225,229,239,240,399,],[279,279,279,279,279,279,279,279,]),'EXTENDS':([110,167,172,225,229,239,240,399,],[280,280,280,280,280,280,280,280,]),'IMPORT':([110,167,172,225,229,239,240,399,],[281,281,281,281,281,281,281,281,]),'SUPER':([110,167,172,225,229,239,240,399,],[282,282,282,282,282,282,282,282,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'source_elements':([0,26,382,460,464,515,519,545,546,568,574,575,],[2,121,463,463,463,463,463,463,463,463,583,584,]),'empty':([0,26,52,132,357,382,427,460,464,482,508,515,519,526,545,546,552,559,568,574,575,],[3,3,178,315,178,3,480,3,3,480,536,3,3,480,3,3,480,536,3,3,3,]),'source_element_list':([0,26,382,460,464,515,519,545,546,568,574,575,],[4,4,4,4,4,4,4,4,4,4,4,4,]),'source_element':([0,4,26,382,460,464,515,519,545,546,568,574,575,],[5,89,5,5,5,5,5,5,5,5,5,5,5,]),'statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[6,6,6,129,215,6,476,478,506,6,6,6,6,548,556,6,6,571,6,579,581,6,6,586,]),'function_declaration':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[7,7,7,130,130,7,130,130,130,7,7,7,7,130,130,7,7,130,7,130,130,7,7,130,]),'block':([0,4,26,31,40,92,340,382,424,426,449,460,464,515,519,524,533,540,545,546,554,568,569,572,574,575,580,],[8,8,8,8,145,8,453,8,8,8,8,8,8,8,8,8,8,563,8,8,8,8,8,8,8,8,8,]),'variable_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'empty_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'expr_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'if_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'iteration_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'continue_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'break_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'return_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'with_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'switch_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,]),'labelled_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'throw_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,]),'try_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,]),'debugger_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,]),'identifier':([0,4,23,25,26,27,31,34,35,36,39,51,77,78,82,83,84,85,86,87,88,91,92,102,109,110,127,128,131,132,142,143,148,163,164,166,167,168,169,171,172,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,305,307,313,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,452,454,457,459,460,464,466,475,482,483,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[24,24,90,111,24,124,24,135,138,111,111,111,111,111,111,111,111,111,111,111,111,214,24,111,234,245,111,111,111,111,111,111,111,111,111,111,245,111,111,111,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,214,111,111,111,111,111,245,111,111,245,111,111,245,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,124,111,429,24,465,214,245,111,24,111,24,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,24,509,111,111,111,24,24,111,523,111,529,111,111,24,24,24,111,111,24,111,111,24,24,111,24,24,24,24,24,24,24,]),'expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,]),'assignment_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'conditional_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,]),'left_hand_side_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[45,45,45,45,45,344,344,344,344,344,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'logical_or_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,]),'new_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'call_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,]),'logical_and_expr_nobf':([0,4,26,31,92,164,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[49,49,49,49,49,343,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'member_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,]),'bitwise_or_expr_nobf':([0,4,26,31,92,164,169,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[53,53,53,53,53,53,350,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,]),'primary_expr_no_brace':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[54,54,107,54,54,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,107,107,107,107,107,107,54,107,107,54,107,107,54,54,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,54,107,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,54,54,107,107,107,107,54,54,54,107,107,54,107,107,54,54,107,54,54,54,54,54,54,54,]),'function_expr':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[55,55,105,55,55,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,105,105,105,105,105,105,55,105,105,55,105,105,55,55,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,55,105,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,55,55,105,105,105,105,55,55,55,105,105,55,105,105,55,55,105,55,55,55,55,55,55,55,]),'bitwise_xor_expr_nobf':([0,4,26,31,92,164,169,180,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[56,56,56,56,56,56,56,359,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,]),'literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,]),'array_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,]),'bitwise_and_expr_nobf':([0,4,26,31,92,164,169,180,181,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[60,60,60,60,60,60,60,60,360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,]),'null_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,]),'boolean_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,]),'numeric_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,]),'string_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,]),'regex_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,]),'equality_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[66,66,66,66,66,66,66,66,66,361,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,]),'relational_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,]),'shift_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,]),'additive_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,]),'multiplicative_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,]),'unary_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,]),'postfix_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,]),'unary_expr_common':([0,4,25,26,31,36,39,77,78,82,83,84,85,86,87,88,92,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[81,81,120,81,81,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,120,120,120,120,120,81,120,120,81,120,120,81,81,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,81,120,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,81,81,120,120,120,120,81,81,81,120,120,81,120,120,81,81,120,81,81,81,81,81,81,81,]),'expr':([25,36,39,128,131,142,143,166,171,224,228,425,427,431,482,484,526,531,539,552,],[93,141,144,309,311,333,334,345,351,389,392,477,481,487,481,530,481,555,562,481,]),'assignment_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[94,94,94,308,94,94,94,94,341,342,94,349,94,355,385,386,387,94,94,423,473,94,94,94,510,511,513,518,94,94,94,94,94,94,]),'conditional_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'left_hand_side_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[96,96,96,202,202,202,202,202,202,202,202,202,96,96,96,314,96,96,96,96,96,96,96,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,202,96,202,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,488,488,488,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,96,488,96,96,488,96,96,]),'logical_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'new_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[98,98,98,173,98,98,98,98,98,98,98,98,98,230,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'call_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'logical_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,388,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'member_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[101,101,101,174,101,101,101,101,101,101,101,101,101,231,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'bitwise_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,391,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'primary_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'bitwise_xor_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,395,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,]),'object_literal':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,]),'bitwise_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,396,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,]),'equality_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,283,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,403,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,]),'relational_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,183,184,185,186,217,218,221,222,224,226,228,232,233,283,284,285,286,287,307,400,425,427,431,440,441,442,443,454,457,459,466,482,484,526,531,539,552,],[114,114,114,114,114,114,114,114,114,114,114,114,114,114,362,363,364,365,114,114,114,114,114,114,114,114,114,114,404,405,406,407,114,114,114,114,114,497,498,499,500,114,114,114,114,114,114,114,114,114,114,]),'shift_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[115,115,115,115,115,115,326,115,115,115,115,115,115,115,115,115,115,115,115,366,367,368,369,370,371,115,115,115,115,115,115,115,115,115,115,115,115,115,115,408,409,410,411,412,413,115,115,115,115,115,326,326,326,326,326,326,326,326,115,115,115,115,501,502,503,504,505,115,115,115,115,115,115,326,115,115,326,115,115,]),'additive_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,372,373,374,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,414,415,416,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,]),'multiplicative_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,375,376,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,417,418,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,]),'unary_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[118,118,118,201,203,204,205,206,207,208,209,210,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,377,378,379,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,419,420,421,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,]),'postfix_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,]),'variable_declaration_list':([27,],[122,]),'variable_declaration':([27,305,],[123,422,]),'assignment_operator':([45,96,314,488,],[148,218,432,432,]),'arguments':([48,50,99,101,174,231,],[165,170,223,227,353,394,]),'elision_opt':([52,357,],[175,459,]),'element_list':([52,],[176,]),'elision':([52,357,],[179,179,]),'formal_parameter_list':([91,211,397,],[213,381,470,]),'property_list':([110,],[236,]),'property_assignment':([110,399,],[237,472,]),'property_name':([110,239,240,399,],[238,401,402,238,]),'identifier_name_string':([110,167,172,225,229,239,240,399,],[241,346,352,390,393,241,241,241,]),'identifier_name':([110,167,172,225,229,239,240,399,],[244,244,244,244,244,244,244,244,]),'reserved_word':([110,167,172,225,229,239,240,399,],[246,246,246,246,246,246,246,246,]),'initializer':([124,],[306,]),'expr_noin_opt':([132,],[312,]),'expr_noin':([132,],[316,]),'assignment_expr_noin':([132,432,433,434,486,534,],[317,489,490,491,532,557,]),'conditional_expr_noin':([132,432,433,434,486,534,],[318,318,318,318,318,318,]),'logical_or_expr_noin':([132,432,433,434,486,534,],[319,319,319,319,319,319,]),'logical_and_expr_noin':([132,432,433,434,435,486,534,],[320,320,320,320,492,320,320,]),'bitwise_or_expr_noin':([132,432,433,434,435,436,486,534,],[321,321,321,321,321,493,321,321,]),'bitwise_xor_expr_noin':([132,432,433,434,435,436,437,486,534,],[322,322,322,322,322,322,494,322,322,]),'bitwise_and_expr_noin':([132,432,433,434,435,436,437,438,486,534,],[323,323,323,323,323,323,323,495,323,323,]),'equality_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[324,324,324,324,324,324,324,324,496,324,324,]),'relational_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[325,325,325,325,325,325,325,325,325,325,325,]),'catch':([145,],[337,]),'finally':([145,337,],[338,451,]),'argument_list':([168,],[348,]),'variable_declaration_list_noin':([313,],[428,]),'variable_declaration_noin':([313,483,],[430,528,]),'function_body':([382,460,464,515,519,545,546,568,],[462,514,517,542,544,566,567,578,]),'expr_opt':([427,482,526,552,],[479,527,551,570,]),'initializer_noin':([429,529,],[485,553,]),'case_block':([450,],[507,]),'property_set_parameter_list':([475,],[522,]),'case_clauses_opt':([508,559,],[535,573,]),'case_clauses':([508,559,],[537,537,]),'case_clause':([508,537,559,],[538,561,538,]),'default_clause':([535,],[559,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('empty -> ','empty',0,'p_empty','es5.py',122), + ('program -> source_elements','program',1,'p_program','es5.py',157), + ('source_elements -> empty','source_elements',1,'p_source_elements','es5.py',164), + ('source_elements -> source_element_list','source_elements',1,'p_source_elements','es5.py',165), + ('source_element_list -> source_element','source_element_list',1,'p_source_element_list','es5.py',170), + ('source_element_list -> source_element_list source_element','source_element_list',2,'p_source_element_list','es5.py',171), + ('source_element -> statement','source_element',1,'p_source_element','es5.py',180), + ('source_element -> function_declaration','source_element',1,'p_source_element','es5.py',181), + ('statement -> block','statement',1,'p_statement','es5.py',186), + ('statement -> variable_statement','statement',1,'p_statement','es5.py',187), + ('statement -> empty_statement','statement',1,'p_statement','es5.py',188), + ('statement -> expr_statement','statement',1,'p_statement','es5.py',189), + ('statement -> if_statement','statement',1,'p_statement','es5.py',190), + ('statement -> iteration_statement','statement',1,'p_statement','es5.py',191), + ('statement -> continue_statement','statement',1,'p_statement','es5.py',192), + ('statement -> break_statement','statement',1,'p_statement','es5.py',193), + ('statement -> return_statement','statement',1,'p_statement','es5.py',194), + ('statement -> with_statement','statement',1,'p_statement','es5.py',195), + ('statement -> switch_statement','statement',1,'p_statement','es5.py',196), + ('statement -> labelled_statement','statement',1,'p_statement','es5.py',197), + ('statement -> throw_statement','statement',1,'p_statement','es5.py',198), + ('statement -> try_statement','statement',1,'p_statement','es5.py',199), + ('statement -> debugger_statement','statement',1,'p_statement','es5.py',200), + ('statement -> function_declaration','statement',1,'p_statement','es5.py',201), + ('block -> LBRACE source_elements RBRACE','block',3,'p_block','es5.py',208), + ('literal -> null_literal','literal',1,'p_literal','es5.py',213), + ('literal -> boolean_literal','literal',1,'p_literal','es5.py',214), + ('literal -> numeric_literal','literal',1,'p_literal','es5.py',215), + ('literal -> string_literal','literal',1,'p_literal','es5.py',216), + ('literal -> regex_literal','literal',1,'p_literal','es5.py',217), + ('boolean_literal -> TRUE','boolean_literal',1,'p_boolean_literal','es5.py',222), + ('boolean_literal -> FALSE','boolean_literal',1,'p_boolean_literal','es5.py',223), + ('null_literal -> NULL','null_literal',1,'p_null_literal','es5.py',229), + ('numeric_literal -> NUMBER','numeric_literal',1,'p_numeric_literal','es5.py',234), + ('string_literal -> STRING','string_literal',1,'p_string_literal','es5.py',239), + ('regex_literal -> REGEX','regex_literal',1,'p_regex_literal','es5.py',244), + ('identifier -> ID','identifier',1,'p_identifier','es5.py',249), + ('reserved_word -> BREAK','reserved_word',1,'p_reserved_word','es5.py',256), + ('reserved_word -> CASE','reserved_word',1,'p_reserved_word','es5.py',257), + ('reserved_word -> CATCH','reserved_word',1,'p_reserved_word','es5.py',258), + ('reserved_word -> CONTINUE','reserved_word',1,'p_reserved_word','es5.py',259), + ('reserved_word -> DEBUGGER','reserved_word',1,'p_reserved_word','es5.py',260), + ('reserved_word -> DEFAULT','reserved_word',1,'p_reserved_word','es5.py',261), + ('reserved_word -> DELETE','reserved_word',1,'p_reserved_word','es5.py',262), + ('reserved_word -> DO','reserved_word',1,'p_reserved_word','es5.py',263), + ('reserved_word -> ELSE','reserved_word',1,'p_reserved_word','es5.py',264), + ('reserved_word -> FINALLY','reserved_word',1,'p_reserved_word','es5.py',265), + ('reserved_word -> FOR','reserved_word',1,'p_reserved_word','es5.py',266), + ('reserved_word -> FUNCTION','reserved_word',1,'p_reserved_word','es5.py',267), + ('reserved_word -> IF','reserved_word',1,'p_reserved_word','es5.py',268), + ('reserved_word -> IN','reserved_word',1,'p_reserved_word','es5.py',269), + ('reserved_word -> INSTANCEOF','reserved_word',1,'p_reserved_word','es5.py',270), + ('reserved_word -> NEW','reserved_word',1,'p_reserved_word','es5.py',271), + ('reserved_word -> RETURN','reserved_word',1,'p_reserved_word','es5.py',272), + ('reserved_word -> SWITCH','reserved_word',1,'p_reserved_word','es5.py',273), + ('reserved_word -> THIS','reserved_word',1,'p_reserved_word','es5.py',274), + ('reserved_word -> THROW','reserved_word',1,'p_reserved_word','es5.py',275), + ('reserved_word -> TRY','reserved_word',1,'p_reserved_word','es5.py',276), + ('reserved_word -> TYPEOF','reserved_word',1,'p_reserved_word','es5.py',277), + ('reserved_word -> VAR','reserved_word',1,'p_reserved_word','es5.py',278), + ('reserved_word -> VOID','reserved_word',1,'p_reserved_word','es5.py',279), + ('reserved_word -> WHILE','reserved_word',1,'p_reserved_word','es5.py',280), + ('reserved_word -> WITH','reserved_word',1,'p_reserved_word','es5.py',281), + ('reserved_word -> NULL','reserved_word',1,'p_reserved_word','es5.py',282), + ('reserved_word -> TRUE','reserved_word',1,'p_reserved_word','es5.py',283), + ('reserved_word -> FALSE','reserved_word',1,'p_reserved_word','es5.py',284), + ('reserved_word -> CLASS','reserved_word',1,'p_reserved_word','es5.py',285), + ('reserved_word -> CONST','reserved_word',1,'p_reserved_word','es5.py',286), + ('reserved_word -> ENUM','reserved_word',1,'p_reserved_word','es5.py',287), + ('reserved_word -> EXPORT','reserved_word',1,'p_reserved_word','es5.py',288), + ('reserved_word -> EXTENDS','reserved_word',1,'p_reserved_word','es5.py',289), + ('reserved_word -> IMPORT','reserved_word',1,'p_reserved_word','es5.py',290), + ('reserved_word -> SUPER','reserved_word',1,'p_reserved_word','es5.py',291), + ('identifier_name -> identifier','identifier_name',1,'p_identifier_name','es5.py',297), + ('identifier_name -> reserved_word','identifier_name',1,'p_identifier_name','es5.py',298), + ('primary_expr -> primary_expr_no_brace','primary_expr',1,'p_primary_expr','es5.py',306), + ('primary_expr -> object_literal','primary_expr',1,'p_primary_expr','es5.py',307), + ('primary_expr_no_brace -> identifier','primary_expr_no_brace',1,'p_primary_expr_no_brace_1','es5.py',312), + ('primary_expr_no_brace -> THIS','primary_expr_no_brace',1,'p_primary_expr_no_brace_2','es5.py',316), + ('primary_expr_no_brace -> literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',321), + ('primary_expr_no_brace -> array_literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',322), + ('primary_expr_no_brace -> LPAREN expr RPAREN','primary_expr_no_brace',3,'p_primary_expr_no_brace_4','es5.py',327), + ('array_literal -> LBRACKET elision_opt RBRACKET','array_literal',3,'p_array_literal_1','es5.py',336), + ('array_literal -> LBRACKET element_list RBRACKET','array_literal',3,'p_array_literal_2','es5.py',341), + ('array_literal -> LBRACKET element_list COMMA elision_opt RBRACKET','array_literal',5,'p_array_literal_2','es5.py',342), + ('element_list -> elision_opt assignment_expr','element_list',2,'p_element_list','es5.py',351), + ('element_list -> element_list COMMA elision_opt assignment_expr','element_list',4,'p_element_list','es5.py',352), + ('elision_opt -> empty','elision_opt',1,'p_elision_opt_1','es5.py',362), + ('elision_opt -> elision','elision_opt',1,'p_elision_opt_2','es5.py',366), + ('elision -> COMMA','elision',1,'p_elision','es5.py',370), + ('elision -> elision COMMA','elision',2,'p_elision','es5.py',371), + ('object_literal -> LBRACE RBRACE','object_literal',2,'p_object_literal','es5.py',387), + ('object_literal -> LBRACE property_list RBRACE','object_literal',3,'p_object_literal','es5.py',388), + ('object_literal -> LBRACE property_list COMMA RBRACE','object_literal',4,'p_object_literal','es5.py',389), + ('property_list -> property_assignment','property_list',1,'p_property_list','es5.py',398), + ('property_list -> property_list COMMA property_assignment','property_list',3,'p_property_list','es5.py',399), + ('property_assignment -> property_name COLON assignment_expr','property_assignment',3,'p_property_assignment','es5.py',409), + ('property_assignment -> GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE','property_assignment',7,'p_property_assignment','es5.py',410), + ('property_assignment -> SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE','property_assignment',8,'p_property_assignment','es5.py',411), + ('identifier_name_string -> identifier_name','identifier_name_string',1,'p_identifier_name_string','es5.py',432), + ('property_name -> identifier_name_string','property_name',1,'p_property_name','es5.py',441), + ('property_name -> string_literal','property_name',1,'p_property_name','es5.py',442), + ('property_name -> numeric_literal','property_name',1,'p_property_name','es5.py',443), + ('property_set_parameter_list -> identifier','property_set_parameter_list',1,'p_property_set_parameter_list','es5.py',448), + ('member_expr -> primary_expr','member_expr',1,'p_member_expr','es5.py',457), + ('member_expr -> function_expr','member_expr',1,'p_member_expr','es5.py',458), + ('member_expr -> member_expr LBRACKET expr RBRACKET','member_expr',4,'p_member_expr','es5.py',459), + ('member_expr -> member_expr PERIOD identifier_name_string','member_expr',3,'p_member_expr','es5.py',460), + ('member_expr -> NEW member_expr arguments','member_expr',3,'p_member_expr','es5.py',461), + ('member_expr_nobf -> primary_expr_no_brace','member_expr_nobf',1,'p_member_expr_nobf','es5.py',478), + ('member_expr_nobf -> function_expr','member_expr_nobf',1,'p_member_expr_nobf','es5.py',479), + ('member_expr_nobf -> member_expr_nobf LBRACKET expr RBRACKET','member_expr_nobf',4,'p_member_expr_nobf','es5.py',480), + ('member_expr_nobf -> member_expr_nobf PERIOD identifier_name_string','member_expr_nobf',3,'p_member_expr_nobf','es5.py',481), + ('member_expr_nobf -> NEW member_expr arguments','member_expr_nobf',3,'p_member_expr_nobf','es5.py',482), + ('new_expr -> member_expr','new_expr',1,'p_new_expr','es5.py',499), + ('new_expr -> NEW new_expr','new_expr',2,'p_new_expr','es5.py',500), + ('new_expr_nobf -> member_expr_nobf','new_expr_nobf',1,'p_new_expr_nobf','es5.py',509), + ('new_expr_nobf -> NEW new_expr','new_expr_nobf',2,'p_new_expr_nobf','es5.py',510), + ('call_expr -> member_expr arguments','call_expr',2,'p_call_expr','es5.py',519), + ('call_expr -> call_expr arguments','call_expr',2,'p_call_expr','es5.py',520), + ('call_expr -> call_expr LBRACKET expr RBRACKET','call_expr',4,'p_call_expr','es5.py',521), + ('call_expr -> call_expr PERIOD identifier_name_string','call_expr',3,'p_call_expr','es5.py',522), + ('call_expr_nobf -> member_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',535), + ('call_expr_nobf -> call_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',536), + ('call_expr_nobf -> call_expr_nobf LBRACKET expr RBRACKET','call_expr_nobf',4,'p_call_expr_nobf','es5.py',537), + ('call_expr_nobf -> call_expr_nobf PERIOD identifier_name_string','call_expr_nobf',3,'p_call_expr_nobf','es5.py',538), + ('arguments -> LPAREN RPAREN','arguments',2,'p_arguments','es5.py',551), + ('arguments -> LPAREN argument_list RPAREN','arguments',3,'p_arguments','es5.py',552), + ('argument_list -> assignment_expr','argument_list',1,'p_argument_list','es5.py',561), + ('argument_list -> argument_list COMMA assignment_expr','argument_list',3,'p_argument_list','es5.py',562), + ('left_hand_side_expr -> new_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',571), + ('left_hand_side_expr -> call_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',572), + ('left_hand_side_expr_nobf -> new_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',577), + ('left_hand_side_expr_nobf -> call_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',578), + ('postfix_expr -> left_hand_side_expr','postfix_expr',1,'p_postfix_expr','es5.py',584), + ('postfix_expr -> left_hand_side_expr PLUSPLUS','postfix_expr',2,'p_postfix_expr','es5.py',585), + ('postfix_expr -> left_hand_side_expr MINUSMINUS','postfix_expr',2,'p_postfix_expr','es5.py',586), + ('postfix_expr_nobf -> left_hand_side_expr_nobf','postfix_expr_nobf',1,'p_postfix_expr_nobf','es5.py',595), + ('postfix_expr_nobf -> left_hand_side_expr_nobf PLUSPLUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',596), + ('postfix_expr_nobf -> left_hand_side_expr_nobf MINUSMINUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',597), + ('unary_expr -> postfix_expr','unary_expr',1,'p_unary_expr','es5.py',607), + ('unary_expr -> unary_expr_common','unary_expr',1,'p_unary_expr','es5.py',608), + ('unary_expr_nobf -> postfix_expr_nobf','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',613), + ('unary_expr_nobf -> unary_expr_common','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',614), + ('unary_expr_common -> DELETE unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',619), + ('unary_expr_common -> VOID unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',620), + ('unary_expr_common -> TYPEOF unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',621), + ('unary_expr_common -> PLUSPLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',622), + ('unary_expr_common -> MINUSMINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',623), + ('unary_expr_common -> PLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',624), + ('unary_expr_common -> MINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',625), + ('unary_expr_common -> BNOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',626), + ('unary_expr_common -> NOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',627), + ('multiplicative_expr -> unary_expr','multiplicative_expr',1,'p_multiplicative_expr','es5.py',634), + ('multiplicative_expr -> multiplicative_expr MULT unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',635), + ('multiplicative_expr -> multiplicative_expr DIV unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',636), + ('multiplicative_expr -> multiplicative_expr MOD unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',637), + ('multiplicative_expr_nobf -> unary_expr_nobf','multiplicative_expr_nobf',1,'p_multiplicative_expr_nobf','es5.py',646), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MULT unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',647), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf DIV unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',648), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MOD unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',649), + ('additive_expr -> multiplicative_expr','additive_expr',1,'p_additive_expr','es5.py',659), + ('additive_expr -> additive_expr PLUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',660), + ('additive_expr -> additive_expr MINUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',661), + ('additive_expr_nobf -> multiplicative_expr_nobf','additive_expr_nobf',1,'p_additive_expr_nobf','es5.py',670), + ('additive_expr_nobf -> additive_expr_nobf PLUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',671), + ('additive_expr_nobf -> additive_expr_nobf MINUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',672), + ('shift_expr -> additive_expr','shift_expr',1,'p_shift_expr','es5.py',682), + ('shift_expr -> shift_expr LSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',683), + ('shift_expr -> shift_expr RSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',684), + ('shift_expr -> shift_expr URSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',685), + ('shift_expr_nobf -> additive_expr_nobf','shift_expr_nobf',1,'p_shift_expr_nobf','es5.py',694), + ('shift_expr_nobf -> shift_expr_nobf LSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',695), + ('shift_expr_nobf -> shift_expr_nobf RSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',696), + ('shift_expr_nobf -> shift_expr_nobf URSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',697), + ('relational_expr -> shift_expr','relational_expr',1,'p_relational_expr','es5.py',707), + ('relational_expr -> relational_expr LT shift_expr','relational_expr',3,'p_relational_expr','es5.py',708), + ('relational_expr -> relational_expr GT shift_expr','relational_expr',3,'p_relational_expr','es5.py',709), + ('relational_expr -> relational_expr LE shift_expr','relational_expr',3,'p_relational_expr','es5.py',710), + ('relational_expr -> relational_expr GE shift_expr','relational_expr',3,'p_relational_expr','es5.py',711), + ('relational_expr -> relational_expr INSTANCEOF shift_expr','relational_expr',3,'p_relational_expr','es5.py',712), + ('relational_expr -> relational_expr IN shift_expr','relational_expr',3,'p_relational_expr','es5.py',713), + ('relational_expr_noin -> shift_expr','relational_expr_noin',1,'p_relational_expr_noin','es5.py',722), + ('relational_expr_noin -> relational_expr_noin LT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',723), + ('relational_expr_noin -> relational_expr_noin GT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',724), + ('relational_expr_noin -> relational_expr_noin LE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',725), + ('relational_expr_noin -> relational_expr_noin GE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',726), + ('relational_expr_noin -> relational_expr_noin INSTANCEOF shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',727), + ('relational_expr_nobf -> shift_expr_nobf','relational_expr_nobf',1,'p_relational_expr_nobf','es5.py',736), + ('relational_expr_nobf -> relational_expr_nobf LT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',737), + ('relational_expr_nobf -> relational_expr_nobf GT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',738), + ('relational_expr_nobf -> relational_expr_nobf LE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',739), + ('relational_expr_nobf -> relational_expr_nobf GE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',740), + ('relational_expr_nobf -> relational_expr_nobf INSTANCEOF shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',741), + ('relational_expr_nobf -> relational_expr_nobf IN shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',742), + ('equality_expr -> relational_expr','equality_expr',1,'p_equality_expr','es5.py',752), + ('equality_expr -> equality_expr EQEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',753), + ('equality_expr -> equality_expr NE relational_expr','equality_expr',3,'p_equality_expr','es5.py',754), + ('equality_expr -> equality_expr STREQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',755), + ('equality_expr -> equality_expr STRNEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',756), + ('equality_expr_noin -> relational_expr_noin','equality_expr_noin',1,'p_equality_expr_noin','es5.py',765), + ('equality_expr_noin -> equality_expr_noin EQEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',766), + ('equality_expr_noin -> equality_expr_noin NE relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',767), + ('equality_expr_noin -> equality_expr_noin STREQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',768), + ('equality_expr_noin -> equality_expr_noin STRNEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',769), + ('equality_expr_nobf -> relational_expr_nobf','equality_expr_nobf',1,'p_equality_expr_nobf','es5.py',778), + ('equality_expr_nobf -> equality_expr_nobf EQEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',779), + ('equality_expr_nobf -> equality_expr_nobf NE relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',780), + ('equality_expr_nobf -> equality_expr_nobf STREQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',781), + ('equality_expr_nobf -> equality_expr_nobf STRNEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',782), + ('bitwise_and_expr -> equality_expr','bitwise_and_expr',1,'p_bitwise_and_expr','es5.py',792), + ('bitwise_and_expr -> bitwise_and_expr BAND equality_expr','bitwise_and_expr',3,'p_bitwise_and_expr','es5.py',793), + ('bitwise_and_expr_noin -> equality_expr_noin','bitwise_and_expr_noin',1,'p_bitwise_and_expr_noin','es5.py',802), + ('bitwise_and_expr_noin -> bitwise_and_expr_noin BAND equality_expr_noin','bitwise_and_expr_noin',3,'p_bitwise_and_expr_noin','es5.py',803), + ('bitwise_and_expr_nobf -> equality_expr_nobf','bitwise_and_expr_nobf',1,'p_bitwise_and_expr_nobf','es5.py',813), + ('bitwise_and_expr_nobf -> bitwise_and_expr_nobf BAND equality_expr_nobf','bitwise_and_expr_nobf',3,'p_bitwise_and_expr_nobf','es5.py',814), + ('bitwise_xor_expr -> bitwise_and_expr','bitwise_xor_expr',1,'p_bitwise_xor_expr','es5.py',824), + ('bitwise_xor_expr -> bitwise_xor_expr BXOR bitwise_and_expr','bitwise_xor_expr',3,'p_bitwise_xor_expr','es5.py',825), + ('bitwise_xor_expr_noin -> bitwise_and_expr_noin','bitwise_xor_expr_noin',1,'p_bitwise_xor_expr_noin','es5.py',835), + ('bitwise_xor_expr_noin -> bitwise_xor_expr_noin BXOR bitwise_and_expr_noin','bitwise_xor_expr_noin',3,'p_bitwise_xor_expr_noin','es5.py',836), + ('bitwise_xor_expr_nobf -> bitwise_and_expr_nobf','bitwise_xor_expr_nobf',1,'p_bitwise_xor_expr_nobf','es5.py',847), + ('bitwise_xor_expr_nobf -> bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf','bitwise_xor_expr_nobf',3,'p_bitwise_xor_expr_nobf','es5.py',848), + ('bitwise_or_expr -> bitwise_xor_expr','bitwise_or_expr',1,'p_bitwise_or_expr','es5.py',858), + ('bitwise_or_expr -> bitwise_or_expr BOR bitwise_xor_expr','bitwise_or_expr',3,'p_bitwise_or_expr','es5.py',859), + ('bitwise_or_expr_noin -> bitwise_xor_expr_noin','bitwise_or_expr_noin',1,'p_bitwise_or_expr_noin','es5.py',869), + ('bitwise_or_expr_noin -> bitwise_or_expr_noin BOR bitwise_xor_expr_noin','bitwise_or_expr_noin',3,'p_bitwise_or_expr_noin','es5.py',870), + ('bitwise_or_expr_nobf -> bitwise_xor_expr_nobf','bitwise_or_expr_nobf',1,'p_bitwise_or_expr_nobf','es5.py',881), + ('bitwise_or_expr_nobf -> bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf','bitwise_or_expr_nobf',3,'p_bitwise_or_expr_nobf','es5.py',882), + ('logical_and_expr -> bitwise_or_expr','logical_and_expr',1,'p_logical_and_expr','es5.py',893), + ('logical_and_expr -> logical_and_expr AND bitwise_or_expr','logical_and_expr',3,'p_logical_and_expr','es5.py',894), + ('logical_and_expr_noin -> bitwise_or_expr_noin','logical_and_expr_noin',1,'p_logical_and_expr_noin','es5.py',904), + ('logical_and_expr_noin -> logical_and_expr_noin AND bitwise_or_expr_noin','logical_and_expr_noin',3,'p_logical_and_expr_noin','es5.py',905), + ('logical_and_expr_nobf -> bitwise_or_expr_nobf','logical_and_expr_nobf',1,'p_logical_and_expr_nobf','es5.py',915), + ('logical_and_expr_nobf -> logical_and_expr_nobf AND bitwise_or_expr_nobf','logical_and_expr_nobf',3,'p_logical_and_expr_nobf','es5.py',916), + ('logical_or_expr -> logical_and_expr','logical_or_expr',1,'p_logical_or_expr','es5.py',925), + ('logical_or_expr -> logical_or_expr OR logical_and_expr','logical_or_expr',3,'p_logical_or_expr','es5.py',926), + ('logical_or_expr_noin -> logical_and_expr_noin','logical_or_expr_noin',1,'p_logical_or_expr_noin','es5.py',935), + ('logical_or_expr_noin -> logical_or_expr_noin OR logical_and_expr_noin','logical_or_expr_noin',3,'p_logical_or_expr_noin','es5.py',936), + ('logical_or_expr_nobf -> logical_and_expr_nobf','logical_or_expr_nobf',1,'p_logical_or_expr_nobf','es5.py',945), + ('logical_or_expr_nobf -> logical_or_expr_nobf OR logical_and_expr_nobf','logical_or_expr_nobf',3,'p_logical_or_expr_nobf','es5.py',946), + ('conditional_expr -> logical_or_expr','conditional_expr',1,'p_conditional_expr','es5.py',957), + ('conditional_expr -> logical_or_expr CONDOP assignment_expr COLON assignment_expr','conditional_expr',5,'p_conditional_expr','es5.py',958), + ('conditional_expr_noin -> logical_or_expr_noin','conditional_expr_noin',1,'p_conditional_expr_noin','es5.py',970), + ('conditional_expr_noin -> logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin','conditional_expr_noin',5,'p_conditional_expr_noin','es5.py',971), + ('conditional_expr_nobf -> logical_or_expr_nobf','conditional_expr_nobf',1,'p_conditional_expr_nobf','es5.py',984), + ('conditional_expr_nobf -> logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr','conditional_expr_nobf',5,'p_conditional_expr_nobf','es5.py',985), + ('assignment_expr -> conditional_expr','assignment_expr',1,'p_assignment_expr','es5.py',998), + ('assignment_expr -> left_hand_side_expr assignment_operator assignment_expr','assignment_expr',3,'p_assignment_expr','es5.py',999), + ('assignment_expr_noin -> conditional_expr_noin','assignment_expr_noin',1,'p_assignment_expr_noin','es5.py',1010), + ('assignment_expr_noin -> left_hand_side_expr assignment_operator assignment_expr_noin','assignment_expr_noin',3,'p_assignment_expr_noin','es5.py',1011), + ('assignment_expr_nobf -> conditional_expr_nobf','assignment_expr_nobf',1,'p_assignment_expr_nobf','es5.py',1022), + ('assignment_expr_nobf -> left_hand_side_expr_nobf assignment_operator assignment_expr','assignment_expr_nobf',3,'p_assignment_expr_nobf','es5.py',1023), + ('assignment_operator -> EQ','assignment_operator',1,'p_assignment_operator','es5.py',1033), + ('assignment_operator -> MULTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1034), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1035), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1036), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1037), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1038), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1039), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1040), + ('assignment_operator -> URSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1041), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1042), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1043), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1044), + ('expr -> assignment_expr','expr',1,'p_expr','es5.py',1050), + ('expr -> expr COMMA assignment_expr','expr',3,'p_expr','es5.py',1051), + ('expr_noin -> assignment_expr_noin','expr_noin',1,'p_expr_noin','es5.py',1060), + ('expr_noin -> expr_noin COMMA assignment_expr_noin','expr_noin',3,'p_expr_noin','es5.py',1061), + ('expr_nobf -> assignment_expr_nobf','expr_nobf',1,'p_expr_nobf','es5.py',1070), + ('expr_nobf -> expr_nobf COMMA assignment_expr','expr_nobf',3,'p_expr_nobf','es5.py',1071), + ('variable_statement -> VAR variable_declaration_list SEMI','variable_statement',3,'p_variable_statement','es5.py',1081), + ('variable_statement -> VAR variable_declaration_list AUTOSEMI','variable_statement',3,'p_variable_statement','es5.py',1082), + ('variable_declaration_list -> variable_declaration','variable_declaration_list',1,'p_variable_declaration_list','es5.py',1089), + ('variable_declaration_list -> variable_declaration_list COMMA variable_declaration','variable_declaration_list',3,'p_variable_declaration_list','es5.py',1090), + ('variable_declaration_list_noin -> variable_declaration_noin','variable_declaration_list_noin',1,'p_variable_declaration_list_noin','es5.py',1101), + ('variable_declaration_list_noin -> variable_declaration_list_noin COMMA variable_declaration_noin','variable_declaration_list_noin',3,'p_variable_declaration_list_noin','es5.py',1102), + ('variable_declaration -> identifier','variable_declaration',1,'p_variable_declaration','es5.py',1112), + ('variable_declaration -> identifier initializer','variable_declaration',2,'p_variable_declaration','es5.py',1113), + ('variable_declaration_noin -> identifier','variable_declaration_noin',1,'p_variable_declaration_noin','es5.py',1123), + ('variable_declaration_noin -> identifier initializer_noin','variable_declaration_noin',2,'p_variable_declaration_noin','es5.py',1124), + ('initializer -> EQ assignment_expr','initializer',2,'p_initializer','es5.py',1134), + ('initializer_noin -> EQ assignment_expr_noin','initializer_noin',2,'p_initializer_noin','es5.py',1138), + ('empty_statement -> SEMI','empty_statement',1,'p_empty_statement','es5.py',1143), + ('expr_statement -> expr_nobf SEMI','expr_statement',2,'p_expr_statement','es5.py',1149), + ('expr_statement -> expr_nobf AUTOSEMI','expr_statement',2,'p_expr_statement','es5.py',1150), + ('if_statement -> IF LPAREN expr RPAREN statement','if_statement',5,'p_if_statement_1','es5.py',1173), + ('if_statement -> IF LPAREN expr RPAREN statement ELSE statement','if_statement',7,'p_if_statement_2','es5.py',1178), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN SEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1186), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN AUTOSEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1187), + ('iteration_statement -> WHILE LPAREN expr RPAREN statement','iteration_statement',5,'p_iteration_statement_2','es5.py',1194), + ('iteration_statement -> FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','es5.py',1200), + ('iteration_statement -> FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',10,'p_iteration_statement_3','es5.py',1201), + ('iteration_statement -> FOR LPAREN left_hand_side_expr IN expr RPAREN statement','iteration_statement',7,'p_iteration_statement_4','es5.py',1233), + ('iteration_statement -> FOR LPAREN VAR identifier IN expr RPAREN statement','iteration_statement',8,'p_iteration_statement_5','es5.py',1241), + ('iteration_statement -> FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement','iteration_statement',9,'p_iteration_statement_6','es5.py',1251), + ('expr_opt -> empty','expr_opt',1,'p_expr_opt','es5.py',1261), + ('expr_opt -> expr','expr_opt',1,'p_expr_opt','es5.py',1262), + ('expr_noin_opt -> empty','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1267), + ('expr_noin_opt -> expr_noin','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1268), + ('continue_statement -> CONTINUE SEMI','continue_statement',2,'p_continue_statement_1','es5.py',1274), + ('continue_statement -> CONTINUE AUTOSEMI','continue_statement',2,'p_continue_statement_1','es5.py',1275), + ('continue_statement -> CONTINUE identifier SEMI','continue_statement',3,'p_continue_statement_2','es5.py',1281), + ('continue_statement -> CONTINUE identifier AUTOSEMI','continue_statement',3,'p_continue_statement_2','es5.py',1282), + ('break_statement -> BREAK SEMI','break_statement',2,'p_break_statement_1','es5.py',1289), + ('break_statement -> BREAK AUTOSEMI','break_statement',2,'p_break_statement_1','es5.py',1290), + ('break_statement -> BREAK identifier SEMI','break_statement',3,'p_break_statement_2','es5.py',1296), + ('break_statement -> BREAK identifier AUTOSEMI','break_statement',3,'p_break_statement_2','es5.py',1297), + ('return_statement -> RETURN SEMI','return_statement',2,'p_return_statement_1','es5.py',1304), + ('return_statement -> RETURN AUTOSEMI','return_statement',2,'p_return_statement_1','es5.py',1305), + ('return_statement -> RETURN expr SEMI','return_statement',3,'p_return_statement_2','es5.py',1311), + ('return_statement -> RETURN expr AUTOSEMI','return_statement',3,'p_return_statement_2','es5.py',1312), + ('with_statement -> WITH LPAREN expr RPAREN statement','with_statement',5,'p_with_statement','es5.py',1319), + ('switch_statement -> SWITCH LPAREN expr RPAREN case_block','switch_statement',5,'p_switch_statement','es5.py',1325), + ('case_block -> LBRACE case_clauses_opt RBRACE','case_block',3,'p_case_block','es5.py',1335), + ('case_block -> LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE','case_block',5,'p_case_block','es5.py',1336), + ('case_clauses_opt -> empty','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1350), + ('case_clauses_opt -> case_clauses','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1351), + ('case_clauses -> case_clause','case_clauses',1,'p_case_clauses','es5.py',1356), + ('case_clauses -> case_clauses case_clause','case_clauses',2,'p_case_clauses','es5.py',1357), + ('case_clause -> CASE expr COLON source_elements','case_clause',4,'p_case_clause','es5.py',1366), + ('default_clause -> DEFAULT COLON source_elements','default_clause',3,'p_default_clause','es5.py',1371), + ('labelled_statement -> identifier COLON statement','labelled_statement',3,'p_labelled_statement','es5.py',1377), + ('throw_statement -> THROW expr SEMI','throw_statement',3,'p_throw_statement','es5.py',1383), + ('throw_statement -> THROW expr AUTOSEMI','throw_statement',3,'p_throw_statement','es5.py',1384), + ('try_statement -> TRY block catch','try_statement',3,'p_try_statement_1','es5.py',1391), + ('try_statement -> TRY block finally','try_statement',3,'p_try_statement_2','es5.py',1396), + ('try_statement -> TRY block catch finally','try_statement',4,'p_try_statement_3','es5.py',1401), + ('catch -> CATCH LPAREN identifier RPAREN block','catch',5,'p_catch','es5.py',1406), + ('finally -> FINALLY block','finally',2,'p_finally','es5.py',1411), + ('debugger_statement -> DEBUGGER SEMI','debugger_statement',2,'p_debugger_statement','es5.py',1417), + ('debugger_statement -> DEBUGGER AUTOSEMI','debugger_statement',2,'p_debugger_statement','es5.py',1418), + ('function_declaration -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_declaration',7,'p_function_declaration','es5.py',1426), + ('function_declaration -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_declaration',8,'p_function_declaration','es5.py',1427), + ('function_expr -> FUNCTION LPAREN RPAREN LBRACE function_body RBRACE','function_expr',6,'p_function_expr_1','es5.py',1441), + ('function_expr -> FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_1','es5.py',1442), + ('function_expr -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_2','es5.py',1456), + ('function_expr -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',8,'p_function_expr_2','es5.py',1457), + ('formal_parameter_list -> identifier','formal_parameter_list',1,'p_formal_parameter_list','es5.py',1470), + ('formal_parameter_list -> formal_parameter_list COMMA identifier','formal_parameter_list',3,'p_formal_parameter_list','es5.py',1471), + ('function_body -> source_elements','function_body',1,'p_function_body','es5.py',1480), +] diff --git a/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_11.py b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_11.py new file mode 100644 index 00000000..dbb1bfed --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_11.py @@ -0,0 +1,370 @@ + +# yacctab_es5_py3_ply3_11.py +# This file is automatically generated. Do not edit. +# pylint: disable=W,C,R +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'programAND ANDEQUAL AUTOSEMI BAND BLOCK_COMMENT BNOT BOR BREAK BXOR CASE CATCH CLASS COLON COMMA CONDOP CONST CONTINUE DEBUGGER DEFAULT DELETE DIV DIVEQUAL DO ELSE ENUM EQ EQEQ EXPORT EXTENDS FALSE FINALLY FOR FUNCTION GE GETPROP GT ID IF IMPORT IN INSTANCEOF LBRACE LBRACKET LE LINE_COMMENT LINE_TERMINATOR LPAREN LSHIFT LSHIFTEQUAL LT MINUS MINUSEQUAL MINUSMINUS MOD MODEQUAL MULT MULTEQUAL NE NEW NOT NULL NUMBER OR OREQUAL PERIOD PLUS PLUSEQUAL PLUSPLUS RBRACE RBRACKET REGEX RETURN RPAREN RSHIFT RSHIFTEQUAL SEMI SETPROP STREQ STRING STRNEQ SUPER SWITCH THIS THROW TRUE TRY TYPEOF URSHIFT URSHIFTEQUAL VAR VOID WHILE WITH XOREQUALempty :program : source_elementssource_elements : empty\n | source_element_list\n source_element_list : source_element\n | source_element_list source_element\n source_element : statement\n | function_declaration\n statement : block\n | variable_statement\n | empty_statement\n | expr_statement\n | if_statement\n | iteration_statement\n | continue_statement\n | break_statement\n | return_statement\n | with_statement\n | switch_statement\n | labelled_statement\n | throw_statement\n | try_statement\n | debugger_statement\n | function_declaration\n block : LBRACE source_elements RBRACEliteral : null_literal\n | boolean_literal\n | numeric_literal\n | string_literal\n | regex_literal\n boolean_literal : TRUE\n | FALSE\n null_literal : NULLnumeric_literal : NUMBERstring_literal : STRINGregex_literal : REGEXidentifier : IDreserved_word : BREAK\n | CASE\n | CATCH\n | CONTINUE\n | DEBUGGER\n | DEFAULT\n | DELETE\n | DO\n | ELSE\n | FINALLY\n | FOR\n | FUNCTION\n | IF\n | IN\n | INSTANCEOF\n | NEW\n | RETURN\n | SWITCH\n | THIS\n | THROW\n | TRY\n | TYPEOF\n | VAR\n | VOID\n | WHILE\n | WITH\n | NULL\n | TRUE\n | FALSE\n | CLASS\n | CONST\n | ENUM\n | EXPORT\n | EXTENDS\n | IMPORT\n | SUPER\n identifier_name : identifier\n | reserved_word\n primary_expr : primary_expr_no_brace\n | object_literal\n primary_expr_no_brace : identifierprimary_expr_no_brace : THISprimary_expr_no_brace : literal\n | array_literal\n primary_expr_no_brace : LPAREN expr RPARENarray_literal : LBRACKET elision_opt RBRACKETarray_literal : LBRACKET element_list RBRACKET\n | LBRACKET element_list COMMA elision_opt RBRACKET\n element_list : elision_opt assignment_expr\n | element_list COMMA elision_opt assignment_expr\n elision_opt : emptyelision_opt : elisionelision : COMMA\n | elision COMMA\n object_literal : LBRACE RBRACE\n | LBRACE property_list RBRACE\n | LBRACE property_list COMMA RBRACE\n property_list : property_assignment\n | property_list COMMA property_assignment\n property_assignment : property_name COLON assignment_expr\n | GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE\n | SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE\n identifier_name_string : identifier_name\n property_name : identifier_name_string\n | string_literal\n | numeric_literal\n property_set_parameter_list : identifier\n member_expr : primary_expr\n | function_expr\n | member_expr LBRACKET expr RBRACKET\n | member_expr PERIOD identifier_name_string\n | NEW member_expr arguments\n member_expr_nobf : primary_expr_no_brace\n | function_expr\n | member_expr_nobf LBRACKET expr RBRACKET\n | member_expr_nobf PERIOD identifier_name_string\n | NEW member_expr arguments\n new_expr : member_expr\n | NEW new_expr\n new_expr_nobf : member_expr_nobf\n | NEW new_expr\n call_expr : member_expr arguments\n | call_expr arguments\n | call_expr LBRACKET expr RBRACKET\n | call_expr PERIOD identifier_name_string\n call_expr_nobf : member_expr_nobf arguments\n | call_expr_nobf arguments\n | call_expr_nobf LBRACKET expr RBRACKET\n | call_expr_nobf PERIOD identifier_name_string\n arguments : LPAREN RPAREN\n | LPAREN argument_list RPAREN\n argument_list : assignment_expr\n | argument_list COMMA assignment_expr\n left_hand_side_expr : new_expr\n | call_expr\n left_hand_side_expr_nobf : new_expr_nobf\n | call_expr_nobf\n postfix_expr : left_hand_side_expr\n | left_hand_side_expr PLUSPLUS\n | left_hand_side_expr MINUSMINUS\n postfix_expr_nobf : left_hand_side_expr_nobf\n | left_hand_side_expr_nobf PLUSPLUS\n | left_hand_side_expr_nobf MINUSMINUS\n unary_expr : postfix_expr\n | unary_expr_common\n unary_expr_nobf : postfix_expr_nobf\n | unary_expr_common\n unary_expr_common : DELETE unary_expr\n | VOID unary_expr\n | TYPEOF unary_expr\n | PLUSPLUS unary_expr\n | MINUSMINUS unary_expr\n | PLUS unary_expr\n | MINUS unary_expr\n | BNOT unary_expr\n | NOT unary_expr\n multiplicative_expr : unary_expr\n | multiplicative_expr MULT unary_expr\n | multiplicative_expr DIV unary_expr\n | multiplicative_expr MOD unary_expr\n multiplicative_expr_nobf : unary_expr_nobf\n | multiplicative_expr_nobf MULT unary_expr\n | multiplicative_expr_nobf DIV unary_expr\n | multiplicative_expr_nobf MOD unary_expr\n additive_expr : multiplicative_expr\n | additive_expr PLUS multiplicative_expr\n | additive_expr MINUS multiplicative_expr\n additive_expr_nobf : multiplicative_expr_nobf\n | additive_expr_nobf PLUS multiplicative_expr\n | additive_expr_nobf MINUS multiplicative_expr\n shift_expr : additive_expr\n | shift_expr LSHIFT additive_expr\n | shift_expr RSHIFT additive_expr\n | shift_expr URSHIFT additive_expr\n shift_expr_nobf : additive_expr_nobf\n | shift_expr_nobf LSHIFT additive_expr\n | shift_expr_nobf RSHIFT additive_expr\n | shift_expr_nobf URSHIFT additive_expr\n relational_expr : shift_expr\n | relational_expr LT shift_expr\n | relational_expr GT shift_expr\n | relational_expr LE shift_expr\n | relational_expr GE shift_expr\n | relational_expr INSTANCEOF shift_expr\n | relational_expr IN shift_expr\n relational_expr_noin : shift_expr\n | relational_expr_noin LT shift_expr\n | relational_expr_noin GT shift_expr\n | relational_expr_noin LE shift_expr\n | relational_expr_noin GE shift_expr\n | relational_expr_noin INSTANCEOF shift_expr\n relational_expr_nobf : shift_expr_nobf\n | relational_expr_nobf LT shift_expr\n | relational_expr_nobf GT shift_expr\n | relational_expr_nobf LE shift_expr\n | relational_expr_nobf GE shift_expr\n | relational_expr_nobf INSTANCEOF shift_expr\n | relational_expr_nobf IN shift_expr\n equality_expr : relational_expr\n | equality_expr EQEQ relational_expr\n | equality_expr NE relational_expr\n | equality_expr STREQ relational_expr\n | equality_expr STRNEQ relational_expr\n equality_expr_noin : relational_expr_noin\n | equality_expr_noin EQEQ relational_expr\n | equality_expr_noin NE relational_expr\n | equality_expr_noin STREQ relational_expr\n | equality_expr_noin STRNEQ relational_expr\n equality_expr_nobf : relational_expr_nobf\n | equality_expr_nobf EQEQ relational_expr\n | equality_expr_nobf NE relational_expr\n | equality_expr_nobf STREQ relational_expr\n | equality_expr_nobf STRNEQ relational_expr\n bitwise_and_expr : equality_expr\n | bitwise_and_expr BAND equality_expr\n bitwise_and_expr_noin : equality_expr_noin\n | bitwise_and_expr_noin BAND equality_expr_noin\n bitwise_and_expr_nobf : equality_expr_nobf\n | bitwise_and_expr_nobf BAND equality_expr_nobf\n bitwise_xor_expr : bitwise_and_expr\n | bitwise_xor_expr BXOR bitwise_and_expr\n \n bitwise_xor_expr_noin : bitwise_and_expr_noin\n | bitwise_xor_expr_noin BXOR bitwise_and_expr_noin\n \n bitwise_xor_expr_nobf : bitwise_and_expr_nobf\n | bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf\n bitwise_or_expr : bitwise_xor_expr\n | bitwise_or_expr BOR bitwise_xor_expr\n \n bitwise_or_expr_noin : bitwise_xor_expr_noin\n | bitwise_or_expr_noin BOR bitwise_xor_expr_noin\n \n bitwise_or_expr_nobf : bitwise_xor_expr_nobf\n | bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf\n logical_and_expr : bitwise_or_expr\n | logical_and_expr AND bitwise_or_expr\n \n logical_and_expr_noin : bitwise_or_expr_noin\n | logical_and_expr_noin AND bitwise_or_expr_noin\n \n logical_and_expr_nobf : bitwise_or_expr_nobf\n | logical_and_expr_nobf AND bitwise_or_expr_nobf\n logical_or_expr : logical_and_expr\n | logical_or_expr OR logical_and_expr\n logical_or_expr_noin : logical_and_expr_noin\n | logical_or_expr_noin OR logical_and_expr_noin\n logical_or_expr_nobf : logical_and_expr_nobf\n | logical_or_expr_nobf OR logical_and_expr_nobf\n \n conditional_expr : logical_or_expr\n | logical_or_expr CONDOP assignment_expr COLON assignment_expr\n \n conditional_expr_noin : logical_or_expr_noin\n | logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin\n \n conditional_expr_nobf : logical_or_expr_nobf\n | logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr\n \n assignment_expr : conditional_expr\n | left_hand_side_expr assignment_operator assignment_expr\n \n assignment_expr_noin : conditional_expr_noin\n | left_hand_side_expr assignment_operator assignment_expr_noin\n \n assignment_expr_nobf : conditional_expr_nobf\n | left_hand_side_expr_nobf assignment_operator assignment_expr\n assignment_operator : EQ\n | MULTEQUAL\n | DIVEQUAL\n | MODEQUAL\n | PLUSEQUAL\n | MINUSEQUAL\n | LSHIFTEQUAL\n | RSHIFTEQUAL\n | URSHIFTEQUAL\n | ANDEQUAL\n | XOREQUAL\n | OREQUAL\n expr : assignment_expr\n | expr COMMA assignment_expr\n expr_noin : assignment_expr_noin\n | expr_noin COMMA assignment_expr_noin\n expr_nobf : assignment_expr_nobf\n | expr_nobf COMMA assignment_expr\n variable_statement : VAR variable_declaration_list SEMI\n | VAR variable_declaration_list AUTOSEMI\n \n variable_declaration_list : variable_declaration\n | variable_declaration_list COMMA variable_declaration\n \n variable_declaration_list_noin : variable_declaration_noin\n | variable_declaration_list_noin COMMA variable_declaration_noin\n variable_declaration : identifier\n | identifier initializer\n variable_declaration_noin : identifier\n | identifier initializer_noin\n initializer : EQ assignment_exprinitializer_noin : EQ assignment_expr_noinempty_statement : SEMIexpr_statement : expr_nobf SEMI\n | expr_nobf AUTOSEMI\n if_statement : IF LPAREN expr RPAREN statementif_statement : IF LPAREN expr RPAREN statement ELSE statement\n iteration_statement : DO statement WHILE LPAREN expr RPAREN SEMI\n | DO statement WHILE LPAREN expr RPAREN AUTOSEMI\n iteration_statement : WHILE LPAREN expr RPAREN statement\n iteration_statement : FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement\n | FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement\n \n iteration_statement : FOR LPAREN left_hand_side_expr IN expr RPAREN statement\n \n iteration_statement : FOR LPAREN VAR identifier IN expr RPAREN statement\n \n iteration_statement : FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement\n expr_opt : empty\n | expr\n expr_noin_opt : empty\n | expr_noin\n continue_statement : CONTINUE SEMI\n | CONTINUE AUTOSEMI\n continue_statement : CONTINUE identifier SEMI\n | CONTINUE identifier AUTOSEMI\n break_statement : BREAK SEMI\n | BREAK AUTOSEMI\n break_statement : BREAK identifier SEMI\n | BREAK identifier AUTOSEMI\n return_statement : RETURN SEMI\n | RETURN AUTOSEMI\n return_statement : RETURN expr SEMI\n | RETURN expr AUTOSEMI\n with_statement : WITH LPAREN expr RPAREN statementswitch_statement : SWITCH LPAREN expr RPAREN case_block\n case_block : LBRACE case_clauses_opt RBRACE\n | LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE\n case_clauses_opt : empty\n | case_clauses\n case_clauses : case_clause\n | case_clauses case_clause\n case_clause : CASE expr COLON source_elementsdefault_clause : DEFAULT COLON source_elementslabelled_statement : identifier COLON statementthrow_statement : THROW expr SEMI\n | THROW expr AUTOSEMI\n try_statement : TRY block catchtry_statement : TRY block finallytry_statement : TRY block catch finallycatch : CATCH LPAREN identifier RPAREN blockfinally : FINALLY blockdebugger_statement : DEBUGGER SEMI\n | DEBUGGER AUTOSEMI\n \n function_declaration : FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n \n function_expr : FUNCTION LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n \n function_expr : FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE\n | FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE\n formal_parameter_list : identifier\n | formal_parameter_list COMMA identifier\n function_body : source_elements' + +_lr_action_items = {'$end':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,125,126,130,133,134,136,137,139,140,146,147,215,302,303,304,327,328,329,330,331,332,335,336,337,338,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-1,0,-2,-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-322,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-327,-329,-286,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'FUNCTION':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[23,23,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,109,23,-283,23,109,109,109,-1,109,109,109,109,109,109,109,109,109,-6,23,109,258,-284,-285,109,109,-24,109,109,-300,-301,-304,-305,-308,-309,109,109,-330,-331,109,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,109,109,109,258,109,109,109,258,109,-90,-88,-89,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-322,109,109,109,109,109,258,109,109,258,109,109,258,258,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-25,-271,-272,109,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,23,258,109,23,109,23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,23,-327,-329,109,109,109,23,23,109,-286,-290,109,109,109,-312,-313,23,23,23,109,109,23,109,109,-332,23,23,-287,-288,-289,109,23,-293,-314,-328,-333,23,23,-294,23,23,23,-291,23,-295,-315,-292,]),'LBRACE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,40,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,166,168,171,175,177,178,179,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,212,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,340,357,358,380,382,383,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,453,454,457,459,460,461,464,466,469,476,478,482,484,486,506,507,515,519,520,521,524,526,531,533,534,539,540,541,545,546,547,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[26,26,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,110,26,-283,26,110,110,26,110,-1,110,110,110,110,110,110,110,110,110,-6,26,110,-284,-285,110,110,-24,110,110,-300,-301,-304,-305,-308,-309,110,110,-330,-331,110,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,110,110,110,110,110,-90,-88,-89,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,382,-322,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-25,-271,-272,110,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,26,-1,-91,460,26,464,110,26,110,26,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,26,508,-327,-329,110,110,110,26,515,26,110,519,-286,-290,110,110,110,-312,-313,26,26,545,546,26,110,110,26,110,110,26,-332,26,26,568,-287,-288,-289,110,26,-293,-314,-328,-333,26,26,-294,26,26,26,-291,26,-295,-315,-292,]),'VAR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,132,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[27,27,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,27,-283,27,-6,27,269,-284,-285,-24,313,-300,-301,-304,-305,-308,-309,-330,-331,269,269,-322,269,269,269,269,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,27,269,27,27,27,-327,-329,27,27,-286,-290,-312,-313,27,27,27,27,-332,27,27,-287,-288,-289,27,-293,-314,-328,-333,27,27,-294,27,27,27,-291,27,-295,-315,-292,]),'SEMI':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,28,29,31,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,89,92,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,125,126,130,132,133,134,135,136,137,138,139,140,141,144,146,147,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,306,308,312,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,335,336,337,338,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,382,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,429,430,449,451,453,455,456,458,460,464,467,468,471,476,478,479,480,481,482,485,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,510,512,515,516,518,519,524,525,527,528,529,532,533,541,543,545,546,548,549,550,553,554,556,557,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[28,28,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,28,-283,125,28,133,136,139,146,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-6,28,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,303,-273,-277,-284,-285,-24,-1,-300,-301,327,-304,-305,329,-308,-309,331,335,-330,-331,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-278,-270,427,-135,-298,-299,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,28,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,28,28,-1,482,-279,-275,28,-327,-329,-125,-128,-112,28,28,-121,-107,-94,-286,-290,526,-296,-297,-1,-280,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-312,-313,-246,-85,28,-334,-242,28,28,549,552,-276,-279,-282,28,-332,-335,28,28,-287,-288,-289,-280,28,-293,-244,-314,-328,-333,-336,28,28,-294,28,28,28,-337,-291,28,-295,-315,-292,]),'IF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[30,30,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,30,-283,30,-6,30,259,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,259,259,-322,259,259,259,259,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,30,259,30,30,30,-327,-329,30,30,-286,-290,-312,-313,30,30,30,30,-332,30,30,-287,-288,-289,30,-293,-314,-328,-333,30,30,-294,30,30,30,-291,30,-295,-315,-292,]),'DO':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[31,31,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,-283,31,-6,31,254,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,254,254,-322,254,254,254,254,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,31,254,31,31,31,-327,-329,31,31,-286,-290,-312,-313,31,31,31,31,-332,31,31,-287,-288,-289,31,-293,-314,-328,-333,31,31,-294,31,31,31,-291,31,-295,-315,-292,]),'WHILE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,129,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[32,32,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,32,-283,32,-6,32,271,-284,-285,310,-24,-300,-301,-304,-305,-308,-309,-330,-331,271,271,-322,271,271,271,271,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,32,271,32,32,32,-327,-329,32,32,-286,-290,-312,-313,32,32,32,32,-332,32,32,-287,-288,-289,32,-293,-314,-328,-333,32,32,-294,32,32,32,-291,32,-295,-315,-292,]),'FOR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[33,33,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,33,-283,33,-6,33,257,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,257,257,-322,257,257,257,257,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,33,257,33,33,33,-327,-329,33,33,-286,-290,-312,-313,33,33,33,33,-332,33,33,-287,-288,-289,33,-293,-314,-328,-333,33,33,-294,33,33,33,-291,33,-295,-315,-292,]),'CONTINUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[34,34,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,34,-283,34,-6,34,250,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,250,250,-322,250,250,250,250,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,34,250,34,34,34,-327,-329,34,34,-286,-290,-312,-313,34,34,34,34,-332,34,34,-287,-288,-289,34,-293,-314,-328,-333,34,34,-294,34,34,34,-291,34,-295,-315,-292,]),'BREAK':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[35,35,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,35,-283,35,-6,35,247,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,247,247,-322,247,247,247,247,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,35,247,35,35,35,-327,-329,35,35,-286,-290,-312,-313,35,35,35,35,-332,35,35,-287,-288,-289,35,-293,-314,-328,-333,35,35,-294,35,35,35,-291,35,-295,-315,-292,]),'RETURN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[36,36,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,36,-283,36,-6,36,263,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,263,263,-322,263,263,263,263,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,36,263,36,36,36,-327,-329,36,36,-286,-290,-312,-313,36,36,36,36,-332,36,36,-287,-288,-289,36,-293,-314,-328,-333,36,36,-294,36,36,36,-291,36,-295,-315,-292,]),'WITH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[37,37,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,37,-283,37,-6,37,272,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,272,272,-322,272,272,272,272,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,37,272,37,37,37,-327,-329,37,37,-286,-290,-312,-313,37,37,37,37,-332,37,37,-287,-288,-289,37,-293,-314,-328,-333,37,37,-294,37,37,37,-291,37,-295,-315,-292,]),'SWITCH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[38,38,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,38,-283,38,-6,38,264,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,264,264,-322,264,264,264,264,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,38,264,38,38,38,-327,-329,38,38,-286,-290,-312,-313,38,38,38,38,-332,38,38,-287,-288,-289,38,-293,-314,-328,-333,38,38,-294,38,38,38,-291,38,-295,-315,-292,]),'THROW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[39,39,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,39,-283,39,-6,39,266,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,266,266,-322,266,266,266,266,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,39,266,39,39,39,-327,-329,39,39,-286,-290,-312,-313,39,39,39,39,-332,39,39,-287,-288,-289,39,-293,-314,-328,-333,39,39,-294,39,39,39,-291,39,-295,-315,-292,]),'TRY':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[40,40,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,40,-283,40,-6,40,267,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,267,267,-322,267,267,267,267,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,40,267,40,40,40,-327,-329,40,40,-286,-290,-312,-313,40,40,40,40,-332,40,40,-287,-288,-289,40,-293,-314,-328,-333,40,40,-294,40,40,40,-291,40,-295,-315,-292,]),'DEBUGGER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[41,41,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,41,-283,41,-6,41,251,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,251,251,-322,251,251,251,251,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,41,251,41,41,41,-327,-329,41,41,-286,-290,-312,-313,41,41,41,41,-332,41,41,-287,-288,-289,41,-293,-314,-328,-333,41,41,-294,41,41,41,-291,41,-295,-315,-292,]),'ID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,31,34,35,36,39,51,52,77,78,82,83,84,85,86,87,88,89,91,92,102,109,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,307,313,327,328,329,330,331,332,335,336,337,338,357,358,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,452,453,454,457,459,460,464,466,475,476,478,482,483,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[43,43,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,43,43,43,43,-283,43,43,43,43,43,43,-1,43,43,43,43,43,43,43,43,43,-6,43,43,43,43,43,-284,-285,43,43,-24,43,43,-300,-301,-304,-305,-308,-309,43,43,-330,-331,43,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,43,43,43,43,43,43,43,43,43,-90,-88,-89,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-322,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-25,-271,-272,43,43,43,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-327,43,-329,43,43,43,43,43,43,43,-286,-290,43,43,43,43,-312,-313,43,43,43,43,43,43,43,43,-332,43,43,-287,-288,-289,43,43,-293,-314,-328,-333,43,43,-294,43,43,43,-291,43,-295,-315,-292,]),'NEW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[51,51,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,102,51,-283,51,102,102,102,-1,102,102,102,102,102,102,102,102,102,-6,51,102,262,-284,-285,102,102,-24,102,102,-300,-301,-304,-305,-308,-309,102,102,-330,-331,102,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,102,51,102,262,102,51,102,262,102,-90,-88,-89,51,51,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-322,102,102,102,102,102,262,102,102,262,102,102,262,262,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-25,-271,-272,102,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,51,262,102,51,102,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,51,-327,-329,102,102,102,51,51,102,-286,-290,102,102,102,-312,-313,51,51,51,102,102,51,102,102,-332,51,51,-287,-288,-289,102,51,-293,-314,-328,-333,51,51,-294,51,51,51,-291,51,-295,-315,-292,]),'THIS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[57,57,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,57,57,-283,57,57,57,57,-1,57,57,57,57,57,57,57,57,57,-6,57,57,265,-284,-285,57,57,-24,57,57,-300,-301,-304,-305,-308,-309,57,57,-330,-331,57,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,57,57,57,265,57,57,57,265,57,-90,-88,-89,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-322,57,57,57,57,57,265,57,57,265,57,57,265,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-25,-271,-272,57,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,57,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-327,-329,57,57,57,57,57,57,-286,-290,57,57,57,-312,-313,57,57,57,57,57,57,57,57,-332,57,57,-287,-288,-289,57,57,-293,-314,-328,-333,57,57,-294,57,57,57,-291,57,-295,-315,-292,]),'LPAREN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,31,32,33,36,37,38,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,90,92,99,101,102,104,105,107,108,109,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,234,235,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,310,327,328,329,330,331,332,335,336,337,338,339,346,347,352,353,354,356,357,358,382,390,393,394,398,400,401,402,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[25,25,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,91,-78,25,25,-283,128,25,131,132,25,142,143,25,-37,168,168,25,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,25,25,25,25,25,25,25,25,25,-6,211,25,168,168,25,-105,-106,-76,-77,91,-78,-284,-285,25,25,-24,25,25,-300,-301,-304,-305,-308,-309,25,25,-330,-331,25,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,25,25,-124,25,25,25,-123,25,168,25,-90,-88,-89,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-322,-82,25,25,25,25,-120,25,25,-119,25,168,25,25,397,-92,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-25,-271,-272,25,425,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,452,-126,-127,-113,-114,-83,-84,-1,-91,25,-122,-108,-109,-93,25,474,475,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-327,-329,25,-125,-128,25,-112,25,25,25,25,-121,-107,-94,-286,-290,25,25,25,-312,-313,-85,25,-334,25,25,25,25,25,25,25,-332,-335,25,25,-287,-288,-289,25,25,-293,-314,-328,-333,-336,25,25,-294,25,25,25,-337,-291,25,-295,-315,-292,]),'LBRACKET':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,99,101,102,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[52,52,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,52,52,-283,52,52,52,-37,166,171,52,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,52,52,52,52,52,52,52,52,52,-6,52,224,228,52,-105,-106,-76,-77,-78,-284,-285,52,52,-24,52,52,-300,-301,-304,-305,-308,-309,52,52,-330,-331,52,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,52,52,-124,52,52,52,-123,52,228,52,-90,-88,-89,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-322,-82,52,52,52,52,-120,52,52,-119,52,228,52,52,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-25,-271,-272,52,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-126,-127,-113,-114,-83,-84,-1,-91,52,-122,-108,-109,-93,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-327,-329,52,-125,-128,52,-112,52,52,52,52,-121,-107,-94,-286,-290,52,52,52,-312,-313,-85,52,-334,52,52,52,52,52,52,52,-332,-335,52,52,-287,-288,-289,52,52,-293,-314,-328,-333,-336,52,52,-294,52,52,52,-337,-291,52,-295,-315,-292,]),'NULL':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[67,67,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,67,67,-283,67,67,67,67,-1,67,67,67,67,67,67,67,67,67,-6,67,67,273,-284,-285,67,67,-24,67,67,-300,-301,-304,-305,-308,-309,67,67,-330,-331,67,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,67,67,67,273,67,67,67,273,67,-90,-88,-89,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-322,67,67,67,67,67,273,67,67,273,67,67,273,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-25,-271,-272,67,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,67,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-327,-329,67,67,67,67,67,67,-286,-290,67,67,67,-312,-313,67,67,67,67,67,67,67,67,-332,67,67,-287,-288,-289,67,67,-293,-314,-328,-333,67,67,-294,67,67,67,-291,67,-295,-315,-292,]),'TRUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[68,68,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,68,68,-283,68,68,68,68,-1,68,68,68,68,68,68,68,68,68,-6,68,68,274,-284,-285,68,68,-24,68,68,-300,-301,-304,-305,-308,-309,68,68,-330,-331,68,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,68,68,68,274,68,68,68,274,68,-90,-88,-89,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-322,68,68,68,68,68,274,68,68,274,68,68,274,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-25,-271,-272,68,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,68,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-327,-329,68,68,68,68,68,68,-286,-290,68,68,68,-312,-313,68,68,68,68,68,68,68,68,-332,68,68,-287,-288,-289,68,68,-293,-314,-328,-333,68,68,-294,68,68,68,-291,68,-295,-315,-292,]),'FALSE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[69,69,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,69,69,-283,69,69,69,69,-1,69,69,69,69,69,69,69,69,69,-6,69,69,275,-284,-285,69,69,-24,69,69,-300,-301,-304,-305,-308,-309,69,69,-330,-331,69,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,69,69,69,275,69,69,69,275,69,-90,-88,-89,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-322,69,69,69,69,69,275,69,69,275,69,69,275,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-25,-271,-272,69,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,69,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-327,-329,69,69,69,69,69,69,-286,-290,69,69,69,-312,-313,69,69,69,69,69,69,69,69,-332,69,69,-287,-288,-289,69,69,-293,-314,-328,-333,69,69,-294,69,69,69,-291,69,-295,-315,-292,]),'NUMBER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[70,70,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,70,70,-283,70,70,70,70,-1,70,70,70,70,70,70,70,70,70,-6,70,70,70,-284,-285,70,70,-24,70,70,-300,-301,-304,-305,-308,-309,70,70,-330,-331,70,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,70,70,70,70,70,70,70,-90,-88,-89,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-322,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-25,-271,-272,70,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-327,-329,70,70,70,70,70,70,-286,-290,70,70,70,-312,-313,70,70,70,70,70,70,70,70,-332,70,70,-287,-288,-289,70,70,-293,-314,-328,-333,70,70,-294,70,70,70,-291,70,-295,-315,-292,]),'STRING':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[71,71,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,71,71,-283,71,71,71,71,-1,71,71,71,71,71,71,71,71,71,-6,71,71,71,-284,-285,71,71,-24,71,71,-300,-301,-304,-305,-308,-309,71,71,-330,-331,71,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,71,71,71,71,71,71,71,-90,-88,-89,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-322,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-25,-271,-272,71,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-327,-329,71,71,71,71,71,71,-286,-290,71,71,71,-312,-313,71,71,71,71,71,71,71,71,-332,71,71,-287,-288,-289,71,71,-293,-314,-328,-333,71,71,-294,71,71,71,-291,71,-295,-315,-292,]),'REGEX':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[72,72,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,72,72,-283,72,72,72,72,-1,72,72,72,72,72,72,72,72,72,-6,72,72,-284,-285,72,72,-24,72,72,-300,-301,-304,-305,-308,-309,72,72,-330,-331,72,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,72,72,72,72,72,72,72,-90,-88,-89,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-322,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-25,-271,-272,72,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-327,-329,72,72,72,72,72,72,-286,-290,72,72,72,-312,-313,72,72,72,72,72,72,72,72,-332,72,72,-287,-288,-289,72,72,-293,-314,-328,-333,72,72,-294,72,72,72,-291,72,-295,-315,-292,]),'DELETE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[84,84,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,84,84,-283,84,84,84,-1,84,84,84,84,84,84,84,84,84,-6,84,253,-284,-285,84,84,-24,84,84,-300,-301,-304,-305,-308,-309,84,84,-330,-331,84,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,84,84,84,253,84,84,84,253,84,-90,-88,-89,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-322,84,84,84,84,84,253,84,84,253,84,84,253,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-25,-271,-272,84,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,84,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-327,-329,84,84,84,84,84,84,-286,-290,84,84,84,-312,-313,84,84,84,84,84,84,84,84,-332,84,84,-287,-288,-289,84,84,-293,-314,-328,-333,84,84,-294,84,84,84,-291,84,-295,-315,-292,]),'VOID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[85,85,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,85,85,-283,85,85,85,-1,85,85,85,85,85,85,85,85,85,-6,85,270,-284,-285,85,85,-24,85,85,-300,-301,-304,-305,-308,-309,85,85,-330,-331,85,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,85,85,85,270,85,85,85,270,85,-90,-88,-89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-322,85,85,85,85,85,270,85,85,270,85,85,270,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-25,-271,-272,85,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,85,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-327,-329,85,85,85,85,85,85,-286,-290,85,85,85,-312,-313,85,85,85,85,85,85,85,85,-332,85,85,-287,-288,-289,85,85,-293,-314,-328,-333,85,85,-294,85,85,85,-291,85,-295,-315,-292,]),'TYPEOF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[86,86,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,86,86,-283,86,86,86,-1,86,86,86,86,86,86,86,86,86,-6,86,268,-284,-285,86,86,-24,86,86,-300,-301,-304,-305,-308,-309,86,86,-330,-331,86,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,86,86,86,268,86,86,86,268,86,-90,-88,-89,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-322,86,86,86,86,86,268,86,86,268,86,86,268,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-25,-271,-272,86,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,86,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-327,-329,86,86,86,86,86,86,-286,-290,86,86,86,-312,-313,86,86,86,86,86,86,86,86,-332,86,86,-287,-288,-289,86,86,-293,-314,-328,-333,86,86,-294,86,86,86,-291,86,-295,-315,-292,]),'PLUSPLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[82,82,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,82,82,-283,82,82,82,-37,149,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,82,82,82,82,82,82,82,82,82,-6,82,219,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,82,82,-24,82,82,-300,-301,-304,-305,-308,-309,82,82,-330,-331,82,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,82,82,-124,82,82,82,-123,82,-118,-115,82,-90,-88,-89,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,219,-322,-82,82,82,82,82,-120,82,82,-119,82,-116,-115,82,82,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-25,-271,-272,82,219,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,149,-126,-127,-113,-114,-83,-84,-1,-91,82,-122,-108,-109,-93,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-327,-329,82,-125,-128,82,-112,82,82,82,82,-121,-107,-94,-286,-290,82,82,82,219,-312,-313,-85,82,-334,82,82,82,82,82,82,82,-332,-335,82,82,-287,-288,-289,82,82,-293,-314,-328,-333,-336,82,82,-294,82,82,82,-337,-291,82,-295,-315,-292,]),'MINUSMINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[83,83,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,83,83,-283,83,83,83,-37,150,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,83,83,83,83,83,83,83,83,83,-6,83,220,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,83,83,-24,83,83,-300,-301,-304,-305,-308,-309,83,83,-330,-331,83,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,83,83,-124,83,83,83,-123,83,-118,-115,83,-90,-88,-89,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,220,-322,-82,83,83,83,83,-120,83,83,-119,83,-116,-115,83,83,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-25,-271,-272,83,220,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,150,-126,-127,-113,-114,-83,-84,-1,-91,83,-122,-108,-109,-93,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-327,-329,83,-125,-128,83,-112,83,83,83,83,-121,-107,-94,-286,-290,83,83,83,220,-312,-313,-85,83,-334,83,83,83,83,83,83,83,-332,-335,83,83,-287,-288,-289,83,83,-293,-314,-328,-333,-336,83,83,-294,83,83,83,-337,-291,83,-295,-315,-292,]),'PLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[77,77,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,77,77,-283,77,77,77,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,196,-165,77,77,-158,-143,-144,77,77,77,77,77,77,77,-6,77,-135,-131,-132,-115,-105,-106,-76,-77,-78,297,-162,-154,-141,-142,-284,-285,77,77,-24,77,77,-300,-301,-304,-305,-308,-309,77,77,-330,-331,77,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,77,77,-124,77,77,77,-123,77,-118,-115,77,-90,-88,-89,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,77,77,-136,-137,77,77,-120,77,77,-119,77,-116,-115,77,77,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-25,-271,-272,77,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,297,297,297,-166,-167,-159,-160,-161,77,-122,-108,-109,-93,77,297,297,297,-163,-164,-155,-156,-157,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-327,-329,77,-125,-128,77,-112,77,77,77,77,-121,-107,-94,-286,-290,77,77,77,-135,-312,-313,-85,77,-334,77,77,77,77,77,77,77,-332,-335,77,77,-287,-288,-289,77,77,-293,-314,-328,-333,-336,77,77,-294,77,77,77,-337,-291,77,-295,-315,-292,]),'MINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[78,78,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,78,78,-283,78,78,78,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,197,-165,78,78,-158,-143,-144,78,78,78,78,78,78,78,-6,78,-135,-131,-132,-115,-105,-106,-76,-77,-78,298,-162,-154,-141,-142,-284,-285,78,78,-24,78,78,-300,-301,-304,-305,-308,-309,78,78,-330,-331,78,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,78,78,-124,78,78,78,-123,78,-118,-115,78,-90,-88,-89,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,78,78,-136,-137,78,78,-120,78,78,-119,78,-116,-115,78,78,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-25,-271,-272,78,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,298,298,298,-166,-167,-159,-160,-161,78,-122,-108,-109,-93,78,298,298,298,-163,-164,-155,-156,-157,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-327,-329,78,-125,-128,78,-112,78,78,78,78,-121,-107,-94,-286,-290,78,78,78,-135,-312,-313,-85,78,-334,78,78,78,78,78,78,78,-332,-335,78,78,-287,-288,-289,78,78,-293,-314,-328,-333,-336,78,78,-294,78,78,78,-337,-291,78,-295,-315,-292,]),'BNOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[87,87,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,87,87,-283,87,87,87,-1,87,87,87,87,87,87,87,87,87,-6,87,-284,-285,87,87,-24,87,87,-300,-301,-304,-305,-308,-309,87,87,-330,-331,87,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,87,87,87,87,87,87,87,-90,-88,-89,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-322,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-25,-271,-272,87,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-327,-329,87,87,87,87,87,87,-286,-290,87,87,87,-312,-313,87,87,87,87,87,87,87,87,-332,87,87,-287,-288,-289,87,87,-293,-314,-328,-333,87,87,-294,87,87,87,-291,87,-295,-315,-292,]),'NOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[88,88,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,88,88,-283,88,88,88,-1,88,88,88,88,88,88,88,88,88,-6,88,-284,-285,88,88,-24,88,88,-300,-301,-304,-305,-308,-309,88,88,-330,-331,88,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,88,88,88,88,88,88,88,-90,-88,-89,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-322,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-25,-271,-272,88,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-327,-329,88,88,88,88,88,88,-286,-290,88,88,88,-312,-313,88,88,88,88,88,88,88,88,-332,88,88,-287,-288,-289,88,88,-293,-314,-328,-333,88,88,-294,88,88,88,-291,88,-295,-315,-292,]),'RBRACE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,89,95,96,97,98,99,100,101,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,125,126,130,133,134,136,137,139,140,146,147,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,327,328,329,330,331,332,335,336,337,338,347,354,356,382,386,388,390,391,393,394,395,396,398,399,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,451,453,456,460,462,463,464,467,468,471,472,473,476,478,506,507,508,512,514,515,516,517,518,519,535,536,537,538,541,542,543,544,545,546,548,549,550,556,558,559,561,563,564,565,566,567,568,571,573,574,575,576,577,578,579,581,582,583,584,585,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-1,-283,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-6,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,235,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,302,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,398,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-127,-83,-84,-1,-248,-236,-122,-230,-108,-109,-224,-218,-93,471,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-327,-329,-128,-1,516,-340,-1,-121,-107,-94,-96,-97,-286,-290,-312,-313,-1,-85,541,-1,-334,543,-242,-1,558,-316,-317,-318,-332,564,-335,565,-1,-1,-287,-288,-289,-293,-314,-1,-319,-328,-333,-336,576,577,-1,-294,582,-1,-1,-337,-98,585,-291,-295,-315,-321,-320,-99,-292,]),'CASE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,537,538,541,548,549,550,556,558,559,561,563,564,571,574,575,579,581,582,583,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,248,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,248,248,-322,248,248,248,248,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,248,-327,-329,-286,-290,-312,-313,539,539,-318,-332,-287,-288,-289,-293,-314,539,-319,-328,-333,-294,-1,-1,-291,-295,-315,-321,-320,-292,]),'DEFAULT':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,535,536,537,538,541,548,549,550,556,558,561,563,564,571,575,579,581,582,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,252,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,252,252,-322,252,252,252,252,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,252,-327,-329,-286,-290,-312,-313,-1,560,-316,-317,-318,-332,-287,-288,-289,-293,-314,-319,-328,-333,-294,-1,-291,-295,-315,-320,-292,]),'ELSE':([8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,255,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,255,255,-322,255,255,255,255,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,255,-327,-329,524,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'COLON':([24,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,238,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,318,319,320,321,322,323,324,325,326,342,347,354,356,385,386,387,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,467,468,471,488,489,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,518,543,557,560,562,565,576,],[92,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,400,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-249,-243,-237,-231,-225,-219,-213,-201,-183,454,-127,-83,-84,-266,-248,466,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-121,-107,-94,-135,-250,534,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-242,-335,-244,574,575,-336,-337,]),'PERIOD':([24,43,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,99,101,104,105,107,108,111,165,170,174,216,223,227,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,512,516,541,543,564,565,576,],[-78,-37,167,172,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,225,229,-105,-106,-76,-77,-78,-124,-123,229,-82,-120,-119,229,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,-85,-334,-336,-335,-337,-336,-337,]),'EQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,124,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,429,455,456,458,467,468,471,488,512,516,529,541,543,564,565,576,],[-78,-37,151,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,151,-131,-132,-115,-105,-106,-76,-77,-78,307,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,151,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,486,-125,-128,-112,-121,-107,-94,151,-85,-334,486,-336,-335,-337,-336,-337,]),'MULTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,152,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,152,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,152,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,152,-85,-334,-336,-335,-337,-336,-337,]),'DIVEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,153,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,153,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,153,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,153,-85,-334,-336,-335,-337,-336,-337,]),'MODEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,154,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,154,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,154,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,154,-85,-334,-336,-335,-337,-336,-337,]),'PLUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,155,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,155,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,155,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,155,-85,-334,-336,-335,-337,-336,-337,]),'MINUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,156,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,156,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,156,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,156,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,157,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,157,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,157,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,157,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,158,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,158,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,158,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,158,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,159,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,159,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,159,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,159,-85,-334,-336,-335,-337,-336,-337,]),'ANDEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,160,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,160,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,160,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,160,-85,-334,-336,-335,-337,-336,-337,]),'XOREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,161,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,161,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,161,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,161,-85,-334,-336,-335,-337,-336,-337,]),'OREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,162,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,162,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,162,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,162,-85,-334,-336,-335,-337,-336,-337,]),'MULT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,198,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,299,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,299,299,-159,-160,-161,-122,-108,-109,-93,299,299,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'DIV':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,199,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,300,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,300,300,-159,-160,-161,-122,-108,-109,-93,300,300,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'MOD':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,200,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,301,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,301,301,-159,-160,-161,-122,-108,-109,-93,301,301,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,193,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,294,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,294,-138,-126,-127,-113,-114,-83,-84,294,294,294,294,294,294,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,294,294,294,294,294,294,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,294,294,294,294,294,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,194,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,295,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,295,-138,-126,-127,-113,-114,-83,-84,295,295,295,295,295,295,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,295,295,295,295,295,295,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,295,295,295,295,295,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,195,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,296,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,296,-138,-126,-127,-113,-114,-83,-84,296,296,296,296,296,296,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,296,296,296,296,296,296,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,296,296,296,296,296,-85,-334,-336,-335,-337,-336,-337,]),'LT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,187,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,288,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,444,-183,-138,-126,-127,-113,-114,-83,-84,288,288,288,288,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,288,288,288,288,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,288,288,288,288,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,188,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,289,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,445,-183,-138,-126,-127,-113,-114,-83,-84,289,289,289,289,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,289,289,289,289,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,289,289,289,289,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'LE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,189,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,290,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,446,-183,-138,-126,-127,-113,-114,-83,-84,290,290,290,290,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,290,290,290,290,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,290,290,290,290,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,190,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,291,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,447,-183,-138,-126,-127,-113,-114,-83,-84,291,291,291,291,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,291,291,291,291,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,291,291,291,291,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'INSTANCEOF':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,191,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,261,-78,292,-176,-168,-162,-154,-141,-142,-139,-140,-124,261,-123,261,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,261,-119,261,-116,-115,-92,261,261,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,448,-183,-138,-126,-127,-113,-114,-83,-84,292,292,292,292,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,261,292,292,292,292,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,292,292,292,292,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'IN':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,318,319,320,321,322,323,324,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,429,455,456,458,467,468,471,485,488,489,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,532,541,543,557,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,192,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,260,-78,293,-176,-168,-162,-154,-141,-142,-139,-140,-124,260,-123,260,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,260,-119,260,-116,-115,-92,260,260,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,431,-249,-243,-237,-231,-225,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,293,293,293,293,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,260,293,293,293,293,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,484,-125,-128,-112,-121,-107,-94,531,-135,-250,-238,-232,-226,-220,-214,293,293,293,293,-184,-185,-186,-187,-188,-85,-334,-282,-336,-335,-244,-337,-336,-337,]),'EQEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,183,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,284,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,440,-201,-183,-138,-126,-127,-113,-114,-83,-84,183,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,284,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,440,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'NE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,184,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,285,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,441,-201,-183,-138,-126,-127,-113,-114,-83,-84,184,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,285,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,441,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STREQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,185,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,286,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,442,-201,-183,-138,-126,-127,-113,-114,-83,-84,185,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,286,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,442,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STRNEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,186,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,287,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,443,-201,-183,-138,-126,-127,-113,-114,-83,-84,186,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,287,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,443,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BAND':([24,43,45,47,48,50,54,55,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,323,324,325,326,344,346,347,352,353,354,356,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,182,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,283,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,439,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,182,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,283,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,439,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BXOR':([24,43,45,47,48,50,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,322,323,324,325,326,344,346,347,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,181,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,233,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,438,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,181,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,233,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,438,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BOR':([24,43,45,47,48,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,321,322,323,324,325,326,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,180,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,232,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,437,-225,-219,-213,-201,-183,-138,-126,-127,180,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,232,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,437,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AND':([24,43,45,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,169,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,226,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,436,-231,-225,-219,-213,-201,-183,169,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,226,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,436,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'CONDOP':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,163,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,221,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,434,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'OR':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,164,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,222,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,435,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AUTOSEMI':([24,29,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,135,138,141,144,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,455,456,458,467,468,471,510,512,516,518,525,541,543,564,565,576,],[-78,126,134,137,140,147,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,304,-273,-277,328,330,332,336,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,-125,-128,-112,-121,-107,-94,-246,-85,-334,-242,550,-336,-335,-337,-336,-337,]),'COMMA':([24,29,42,43,44,45,46,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,141,144,149,150,165,170,173,174,176,177,179,201,202,203,204,205,206,207,208,209,210,213,214,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,309,311,314,316,317,318,319,320,321,322,323,324,325,326,333,334,341,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,381,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,428,429,430,455,456,458,465,467,468,470,471,472,473,477,481,485,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,510,511,512,513,516,518,528,529,530,532,541,543,553,555,557,562,564,565,576,577,585,],[-78,127,-269,-37,-251,-138,-245,-133,-134,-239,-117,177,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,217,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,305,-273,-277,217,217,-139,-140,-124,-123,-118,-115,357,-90,358,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,384,-338,-82,-136,-137,-120,-119,-116,-115,-92,399,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,217,217,-135,433,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,217,217,-252,-240,-138,217,-126,-127,457,-129,-234,217,-113,-114,-83,-86,-84,177,-91,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,384,-266,-248,-236,217,-122,-230,217,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,483,-279,-275,-125,-128,-112,-339,-121,-107,384,-94,-96,-97,217,217,-280,217,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-246,-130,-85,-87,-334,-242,-276,-279,217,-282,-336,-335,-280,217,-244,217,-337,-336,-337,-98,-99,]),'RPAREN':([43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,91,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,168,201,202,203,204,205,206,207,208,209,210,211,213,214,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,309,311,333,334,347,348,349,354,356,381,385,386,388,390,391,393,394,395,396,397,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,465,467,468,470,471,474,477,480,481,487,509,511,512,516,518,522,523,526,530,543,551,552,555,565,570,576,],[-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,212,216,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,347,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,380,383,-338,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,424,426,449,450,-127,456,-129,-83,-84,461,-266,-248,-236,-122,-230,-108,-109,-224,-218,469,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-339,-121,-107,520,-94,521,525,-296,-297,533,540,-130,-85,-334,-242,547,-104,-1,554,-335,569,-1,572,-336,580,-337,]),'RBRACKET':([43,52,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,175,176,177,178,179,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,345,347,351,354,355,356,357,358,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,459,467,468,471,512,513,516,518,543,565,576,],[-37,-1,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,354,356,-90,-88,-89,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,455,-127,458,-83,-86,-84,-1,-91,-266,-248,-236,467,-122,-230,468,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,512,-121,-107,-94,-85,-87,-334,-242,-335,-336,-337,]),'GETPROP':([110,399,],[239,239,]),'SETPROP':([110,399,],[240,240,]),'CATCH':([110,145,167,172,225,229,239,240,302,399,],[249,339,249,249,249,249,249,249,-25,249,]),'FINALLY':([110,145,167,172,225,229,239,240,302,337,399,563,],[256,340,256,256,256,256,256,256,-25,340,256,-328,]),'CLASS':([110,167,172,225,229,239,240,399,],[276,276,276,276,276,276,276,276,]),'CONST':([110,167,172,225,229,239,240,399,],[277,277,277,277,277,277,277,277,]),'ENUM':([110,167,172,225,229,239,240,399,],[278,278,278,278,278,278,278,278,]),'EXPORT':([110,167,172,225,229,239,240,399,],[279,279,279,279,279,279,279,279,]),'EXTENDS':([110,167,172,225,229,239,240,399,],[280,280,280,280,280,280,280,280,]),'IMPORT':([110,167,172,225,229,239,240,399,],[281,281,281,281,281,281,281,281,]),'SUPER':([110,167,172,225,229,239,240,399,],[282,282,282,282,282,282,282,282,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'source_elements':([0,26,382,460,464,515,519,545,546,568,574,575,],[2,121,463,463,463,463,463,463,463,463,583,584,]),'empty':([0,26,52,132,357,382,427,460,464,482,508,515,519,526,545,546,552,559,568,574,575,],[3,3,178,315,178,3,480,3,3,480,536,3,3,480,3,3,480,536,3,3,3,]),'source_element_list':([0,26,382,460,464,515,519,545,546,568,574,575,],[4,4,4,4,4,4,4,4,4,4,4,4,]),'source_element':([0,4,26,382,460,464,515,519,545,546,568,574,575,],[5,89,5,5,5,5,5,5,5,5,5,5,5,]),'statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[6,6,6,129,215,6,476,478,506,6,6,6,6,548,556,6,6,571,6,579,581,6,6,586,]),'function_declaration':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[7,7,7,130,130,7,130,130,130,7,7,7,7,130,130,7,7,130,7,130,130,7,7,130,]),'block':([0,4,26,31,40,92,340,382,424,426,449,460,464,515,519,524,533,540,545,546,554,568,569,572,574,575,580,],[8,8,8,8,145,8,453,8,8,8,8,8,8,8,8,8,8,563,8,8,8,8,8,8,8,8,8,]),'variable_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'empty_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'expr_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'if_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'iteration_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'continue_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'break_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'return_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'with_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'switch_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,]),'labelled_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'throw_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,]),'try_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,]),'debugger_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,]),'identifier':([0,4,23,25,26,27,31,34,35,36,39,51,77,78,82,83,84,85,86,87,88,91,92,102,109,110,127,128,131,132,142,143,148,163,164,166,167,168,169,171,172,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,305,307,313,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,452,454,457,459,460,464,466,475,482,483,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[24,24,90,111,24,124,24,135,138,111,111,111,111,111,111,111,111,111,111,111,111,214,24,111,234,245,111,111,111,111,111,111,111,111,111,111,245,111,111,111,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,214,111,111,111,111,111,245,111,111,245,111,111,245,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,124,111,429,24,465,214,245,111,24,111,24,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,24,509,111,111,111,24,24,111,523,111,529,111,111,24,24,24,111,111,24,111,111,24,24,111,24,24,24,24,24,24,24,]),'expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,]),'assignment_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'conditional_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,]),'left_hand_side_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[45,45,45,45,45,344,344,344,344,344,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'logical_or_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,]),'new_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'call_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,]),'logical_and_expr_nobf':([0,4,26,31,92,164,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[49,49,49,49,49,343,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'member_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,]),'bitwise_or_expr_nobf':([0,4,26,31,92,164,169,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[53,53,53,53,53,53,350,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,]),'primary_expr_no_brace':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[54,54,107,54,54,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,107,107,107,107,107,107,54,107,107,54,107,107,54,54,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,54,107,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,54,54,107,107,107,107,54,54,54,107,107,54,107,107,54,54,107,54,54,54,54,54,54,54,]),'function_expr':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[55,55,105,55,55,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,105,105,105,105,105,105,55,105,105,55,105,105,55,55,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,55,105,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,55,55,105,105,105,105,55,55,55,105,105,55,105,105,55,55,105,55,55,55,55,55,55,55,]),'bitwise_xor_expr_nobf':([0,4,26,31,92,164,169,180,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[56,56,56,56,56,56,56,359,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,]),'literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,]),'array_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,]),'bitwise_and_expr_nobf':([0,4,26,31,92,164,169,180,181,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[60,60,60,60,60,60,60,60,360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,]),'null_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,]),'boolean_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,]),'numeric_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,]),'string_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,]),'regex_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,]),'equality_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[66,66,66,66,66,66,66,66,66,361,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,]),'relational_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,]),'shift_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,]),'additive_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,]),'multiplicative_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,]),'unary_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,]),'postfix_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,]),'unary_expr_common':([0,4,25,26,31,36,39,77,78,82,83,84,85,86,87,88,92,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[81,81,120,81,81,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,120,120,120,120,120,81,120,120,81,120,120,81,81,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,81,120,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,81,81,120,120,120,120,81,81,81,120,120,81,120,120,81,81,120,81,81,81,81,81,81,81,]),'expr':([25,36,39,128,131,142,143,166,171,224,228,425,427,431,482,484,526,531,539,552,],[93,141,144,309,311,333,334,345,351,389,392,477,481,487,481,530,481,555,562,481,]),'assignment_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[94,94,94,308,94,94,94,94,341,342,94,349,94,355,385,386,387,94,94,423,473,94,94,94,510,511,513,518,94,94,94,94,94,94,]),'conditional_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'left_hand_side_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[96,96,96,202,202,202,202,202,202,202,202,202,96,96,96,314,96,96,96,96,96,96,96,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,202,96,202,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,488,488,488,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,96,488,96,96,488,96,96,]),'logical_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'new_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[98,98,98,173,98,98,98,98,98,98,98,98,98,230,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'call_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'logical_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,388,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'member_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[101,101,101,174,101,101,101,101,101,101,101,101,101,231,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'bitwise_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,391,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'primary_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'bitwise_xor_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,395,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,]),'object_literal':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,]),'bitwise_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,396,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,]),'equality_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,283,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,403,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,]),'relational_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,183,184,185,186,217,218,221,222,224,226,228,232,233,283,284,285,286,287,307,400,425,427,431,440,441,442,443,454,457,459,466,482,484,526,531,539,552,],[114,114,114,114,114,114,114,114,114,114,114,114,114,114,362,363,364,365,114,114,114,114,114,114,114,114,114,114,404,405,406,407,114,114,114,114,114,497,498,499,500,114,114,114,114,114,114,114,114,114,114,]),'shift_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[115,115,115,115,115,115,326,115,115,115,115,115,115,115,115,115,115,115,115,366,367,368,369,370,371,115,115,115,115,115,115,115,115,115,115,115,115,115,115,408,409,410,411,412,413,115,115,115,115,115,326,326,326,326,326,326,326,326,115,115,115,115,501,502,503,504,505,115,115,115,115,115,115,326,115,115,326,115,115,]),'additive_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,372,373,374,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,414,415,416,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,]),'multiplicative_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,375,376,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,417,418,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,]),'unary_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[118,118,118,201,203,204,205,206,207,208,209,210,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,377,378,379,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,419,420,421,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,]),'postfix_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,]),'variable_declaration_list':([27,],[122,]),'variable_declaration':([27,305,],[123,422,]),'assignment_operator':([45,96,314,488,],[148,218,432,432,]),'arguments':([48,50,99,101,174,231,],[165,170,223,227,353,394,]),'elision_opt':([52,357,],[175,459,]),'element_list':([52,],[176,]),'elision':([52,357,],[179,179,]),'formal_parameter_list':([91,211,397,],[213,381,470,]),'property_list':([110,],[236,]),'property_assignment':([110,399,],[237,472,]),'property_name':([110,239,240,399,],[238,401,402,238,]),'identifier_name_string':([110,167,172,225,229,239,240,399,],[241,346,352,390,393,241,241,241,]),'identifier_name':([110,167,172,225,229,239,240,399,],[244,244,244,244,244,244,244,244,]),'reserved_word':([110,167,172,225,229,239,240,399,],[246,246,246,246,246,246,246,246,]),'initializer':([124,],[306,]),'expr_noin_opt':([132,],[312,]),'expr_noin':([132,],[316,]),'assignment_expr_noin':([132,432,433,434,486,534,],[317,489,490,491,532,557,]),'conditional_expr_noin':([132,432,433,434,486,534,],[318,318,318,318,318,318,]),'logical_or_expr_noin':([132,432,433,434,486,534,],[319,319,319,319,319,319,]),'logical_and_expr_noin':([132,432,433,434,435,486,534,],[320,320,320,320,492,320,320,]),'bitwise_or_expr_noin':([132,432,433,434,435,436,486,534,],[321,321,321,321,321,493,321,321,]),'bitwise_xor_expr_noin':([132,432,433,434,435,436,437,486,534,],[322,322,322,322,322,322,494,322,322,]),'bitwise_and_expr_noin':([132,432,433,434,435,436,437,438,486,534,],[323,323,323,323,323,323,323,495,323,323,]),'equality_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[324,324,324,324,324,324,324,324,496,324,324,]),'relational_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[325,325,325,325,325,325,325,325,325,325,325,]),'catch':([145,],[337,]),'finally':([145,337,],[338,451,]),'argument_list':([168,],[348,]),'variable_declaration_list_noin':([313,],[428,]),'variable_declaration_noin':([313,483,],[430,528,]),'function_body':([382,460,464,515,519,545,546,568,],[462,514,517,542,544,566,567,578,]),'expr_opt':([427,482,526,552,],[479,527,551,570,]),'initializer_noin':([429,529,],[485,553,]),'case_block':([450,],[507,]),'property_set_parameter_list':([475,],[522,]),'case_clauses_opt':([508,559,],[535,573,]),'case_clauses':([508,559,],[537,537,]),'case_clause':([508,537,559,],[538,561,538,]),'default_clause':([535,],[559,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('empty -> ','empty',0,'p_empty','es5.py',122), + ('program -> source_elements','program',1,'p_program','es5.py',157), + ('source_elements -> empty','source_elements',1,'p_source_elements','es5.py',164), + ('source_elements -> source_element_list','source_elements',1,'p_source_elements','es5.py',165), + ('source_element_list -> source_element','source_element_list',1,'p_source_element_list','es5.py',170), + ('source_element_list -> source_element_list source_element','source_element_list',2,'p_source_element_list','es5.py',171), + ('source_element -> statement','source_element',1,'p_source_element','es5.py',180), + ('source_element -> function_declaration','source_element',1,'p_source_element','es5.py',181), + ('statement -> block','statement',1,'p_statement','es5.py',186), + ('statement -> variable_statement','statement',1,'p_statement','es5.py',187), + ('statement -> empty_statement','statement',1,'p_statement','es5.py',188), + ('statement -> expr_statement','statement',1,'p_statement','es5.py',189), + ('statement -> if_statement','statement',1,'p_statement','es5.py',190), + ('statement -> iteration_statement','statement',1,'p_statement','es5.py',191), + ('statement -> continue_statement','statement',1,'p_statement','es5.py',192), + ('statement -> break_statement','statement',1,'p_statement','es5.py',193), + ('statement -> return_statement','statement',1,'p_statement','es5.py',194), + ('statement -> with_statement','statement',1,'p_statement','es5.py',195), + ('statement -> switch_statement','statement',1,'p_statement','es5.py',196), + ('statement -> labelled_statement','statement',1,'p_statement','es5.py',197), + ('statement -> throw_statement','statement',1,'p_statement','es5.py',198), + ('statement -> try_statement','statement',1,'p_statement','es5.py',199), + ('statement -> debugger_statement','statement',1,'p_statement','es5.py',200), + ('statement -> function_declaration','statement',1,'p_statement','es5.py',201), + ('block -> LBRACE source_elements RBRACE','block',3,'p_block','es5.py',208), + ('literal -> null_literal','literal',1,'p_literal','es5.py',213), + ('literal -> boolean_literal','literal',1,'p_literal','es5.py',214), + ('literal -> numeric_literal','literal',1,'p_literal','es5.py',215), + ('literal -> string_literal','literal',1,'p_literal','es5.py',216), + ('literal -> regex_literal','literal',1,'p_literal','es5.py',217), + ('boolean_literal -> TRUE','boolean_literal',1,'p_boolean_literal','es5.py',222), + ('boolean_literal -> FALSE','boolean_literal',1,'p_boolean_literal','es5.py',223), + ('null_literal -> NULL','null_literal',1,'p_null_literal','es5.py',229), + ('numeric_literal -> NUMBER','numeric_literal',1,'p_numeric_literal','es5.py',234), + ('string_literal -> STRING','string_literal',1,'p_string_literal','es5.py',239), + ('regex_literal -> REGEX','regex_literal',1,'p_regex_literal','es5.py',244), + ('identifier -> ID','identifier',1,'p_identifier','es5.py',249), + ('reserved_word -> BREAK','reserved_word',1,'p_reserved_word','es5.py',256), + ('reserved_word -> CASE','reserved_word',1,'p_reserved_word','es5.py',257), + ('reserved_word -> CATCH','reserved_word',1,'p_reserved_word','es5.py',258), + ('reserved_word -> CONTINUE','reserved_word',1,'p_reserved_word','es5.py',259), + ('reserved_word -> DEBUGGER','reserved_word',1,'p_reserved_word','es5.py',260), + ('reserved_word -> DEFAULT','reserved_word',1,'p_reserved_word','es5.py',261), + ('reserved_word -> DELETE','reserved_word',1,'p_reserved_word','es5.py',262), + ('reserved_word -> DO','reserved_word',1,'p_reserved_word','es5.py',263), + ('reserved_word -> ELSE','reserved_word',1,'p_reserved_word','es5.py',264), + ('reserved_word -> FINALLY','reserved_word',1,'p_reserved_word','es5.py',265), + ('reserved_word -> FOR','reserved_word',1,'p_reserved_word','es5.py',266), + ('reserved_word -> FUNCTION','reserved_word',1,'p_reserved_word','es5.py',267), + ('reserved_word -> IF','reserved_word',1,'p_reserved_word','es5.py',268), + ('reserved_word -> IN','reserved_word',1,'p_reserved_word','es5.py',269), + ('reserved_word -> INSTANCEOF','reserved_word',1,'p_reserved_word','es5.py',270), + ('reserved_word -> NEW','reserved_word',1,'p_reserved_word','es5.py',271), + ('reserved_word -> RETURN','reserved_word',1,'p_reserved_word','es5.py',272), + ('reserved_word -> SWITCH','reserved_word',1,'p_reserved_word','es5.py',273), + ('reserved_word -> THIS','reserved_word',1,'p_reserved_word','es5.py',274), + ('reserved_word -> THROW','reserved_word',1,'p_reserved_word','es5.py',275), + ('reserved_word -> TRY','reserved_word',1,'p_reserved_word','es5.py',276), + ('reserved_word -> TYPEOF','reserved_word',1,'p_reserved_word','es5.py',277), + ('reserved_word -> VAR','reserved_word',1,'p_reserved_word','es5.py',278), + ('reserved_word -> VOID','reserved_word',1,'p_reserved_word','es5.py',279), + ('reserved_word -> WHILE','reserved_word',1,'p_reserved_word','es5.py',280), + ('reserved_word -> WITH','reserved_word',1,'p_reserved_word','es5.py',281), + ('reserved_word -> NULL','reserved_word',1,'p_reserved_word','es5.py',282), + ('reserved_word -> TRUE','reserved_word',1,'p_reserved_word','es5.py',283), + ('reserved_word -> FALSE','reserved_word',1,'p_reserved_word','es5.py',284), + ('reserved_word -> CLASS','reserved_word',1,'p_reserved_word','es5.py',285), + ('reserved_word -> CONST','reserved_word',1,'p_reserved_word','es5.py',286), + ('reserved_word -> ENUM','reserved_word',1,'p_reserved_word','es5.py',287), + ('reserved_word -> EXPORT','reserved_word',1,'p_reserved_word','es5.py',288), + ('reserved_word -> EXTENDS','reserved_word',1,'p_reserved_word','es5.py',289), + ('reserved_word -> IMPORT','reserved_word',1,'p_reserved_word','es5.py',290), + ('reserved_word -> SUPER','reserved_word',1,'p_reserved_word','es5.py',291), + ('identifier_name -> identifier','identifier_name',1,'p_identifier_name','es5.py',297), + ('identifier_name -> reserved_word','identifier_name',1,'p_identifier_name','es5.py',298), + ('primary_expr -> primary_expr_no_brace','primary_expr',1,'p_primary_expr','es5.py',306), + ('primary_expr -> object_literal','primary_expr',1,'p_primary_expr','es5.py',307), + ('primary_expr_no_brace -> identifier','primary_expr_no_brace',1,'p_primary_expr_no_brace_1','es5.py',312), + ('primary_expr_no_brace -> THIS','primary_expr_no_brace',1,'p_primary_expr_no_brace_2','es5.py',316), + ('primary_expr_no_brace -> literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',321), + ('primary_expr_no_brace -> array_literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',322), + ('primary_expr_no_brace -> LPAREN expr RPAREN','primary_expr_no_brace',3,'p_primary_expr_no_brace_4','es5.py',327), + ('array_literal -> LBRACKET elision_opt RBRACKET','array_literal',3,'p_array_literal_1','es5.py',336), + ('array_literal -> LBRACKET element_list RBRACKET','array_literal',3,'p_array_literal_2','es5.py',341), + ('array_literal -> LBRACKET element_list COMMA elision_opt RBRACKET','array_literal',5,'p_array_literal_2','es5.py',342), + ('element_list -> elision_opt assignment_expr','element_list',2,'p_element_list','es5.py',351), + ('element_list -> element_list COMMA elision_opt assignment_expr','element_list',4,'p_element_list','es5.py',352), + ('elision_opt -> empty','elision_opt',1,'p_elision_opt_1','es5.py',362), + ('elision_opt -> elision','elision_opt',1,'p_elision_opt_2','es5.py',366), + ('elision -> COMMA','elision',1,'p_elision','es5.py',370), + ('elision -> elision COMMA','elision',2,'p_elision','es5.py',371), + ('object_literal -> LBRACE RBRACE','object_literal',2,'p_object_literal','es5.py',387), + ('object_literal -> LBRACE property_list RBRACE','object_literal',3,'p_object_literal','es5.py',388), + ('object_literal -> LBRACE property_list COMMA RBRACE','object_literal',4,'p_object_literal','es5.py',389), + ('property_list -> property_assignment','property_list',1,'p_property_list','es5.py',398), + ('property_list -> property_list COMMA property_assignment','property_list',3,'p_property_list','es5.py',399), + ('property_assignment -> property_name COLON assignment_expr','property_assignment',3,'p_property_assignment','es5.py',409), + ('property_assignment -> GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE','property_assignment',7,'p_property_assignment','es5.py',410), + ('property_assignment -> SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE','property_assignment',8,'p_property_assignment','es5.py',411), + ('identifier_name_string -> identifier_name','identifier_name_string',1,'p_identifier_name_string','es5.py',432), + ('property_name -> identifier_name_string','property_name',1,'p_property_name','es5.py',441), + ('property_name -> string_literal','property_name',1,'p_property_name','es5.py',442), + ('property_name -> numeric_literal','property_name',1,'p_property_name','es5.py',443), + ('property_set_parameter_list -> identifier','property_set_parameter_list',1,'p_property_set_parameter_list','es5.py',448), + ('member_expr -> primary_expr','member_expr',1,'p_member_expr','es5.py',457), + ('member_expr -> function_expr','member_expr',1,'p_member_expr','es5.py',458), + ('member_expr -> member_expr LBRACKET expr RBRACKET','member_expr',4,'p_member_expr','es5.py',459), + ('member_expr -> member_expr PERIOD identifier_name_string','member_expr',3,'p_member_expr','es5.py',460), + ('member_expr -> NEW member_expr arguments','member_expr',3,'p_member_expr','es5.py',461), + ('member_expr_nobf -> primary_expr_no_brace','member_expr_nobf',1,'p_member_expr_nobf','es5.py',478), + ('member_expr_nobf -> function_expr','member_expr_nobf',1,'p_member_expr_nobf','es5.py',479), + ('member_expr_nobf -> member_expr_nobf LBRACKET expr RBRACKET','member_expr_nobf',4,'p_member_expr_nobf','es5.py',480), + ('member_expr_nobf -> member_expr_nobf PERIOD identifier_name_string','member_expr_nobf',3,'p_member_expr_nobf','es5.py',481), + ('member_expr_nobf -> NEW member_expr arguments','member_expr_nobf',3,'p_member_expr_nobf','es5.py',482), + ('new_expr -> member_expr','new_expr',1,'p_new_expr','es5.py',499), + ('new_expr -> NEW new_expr','new_expr',2,'p_new_expr','es5.py',500), + ('new_expr_nobf -> member_expr_nobf','new_expr_nobf',1,'p_new_expr_nobf','es5.py',509), + ('new_expr_nobf -> NEW new_expr','new_expr_nobf',2,'p_new_expr_nobf','es5.py',510), + ('call_expr -> member_expr arguments','call_expr',2,'p_call_expr','es5.py',519), + ('call_expr -> call_expr arguments','call_expr',2,'p_call_expr','es5.py',520), + ('call_expr -> call_expr LBRACKET expr RBRACKET','call_expr',4,'p_call_expr','es5.py',521), + ('call_expr -> call_expr PERIOD identifier_name_string','call_expr',3,'p_call_expr','es5.py',522), + ('call_expr_nobf -> member_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',535), + ('call_expr_nobf -> call_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',536), + ('call_expr_nobf -> call_expr_nobf LBRACKET expr RBRACKET','call_expr_nobf',4,'p_call_expr_nobf','es5.py',537), + ('call_expr_nobf -> call_expr_nobf PERIOD identifier_name_string','call_expr_nobf',3,'p_call_expr_nobf','es5.py',538), + ('arguments -> LPAREN RPAREN','arguments',2,'p_arguments','es5.py',551), + ('arguments -> LPAREN argument_list RPAREN','arguments',3,'p_arguments','es5.py',552), + ('argument_list -> assignment_expr','argument_list',1,'p_argument_list','es5.py',561), + ('argument_list -> argument_list COMMA assignment_expr','argument_list',3,'p_argument_list','es5.py',562), + ('left_hand_side_expr -> new_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',571), + ('left_hand_side_expr -> call_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',572), + ('left_hand_side_expr_nobf -> new_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',577), + ('left_hand_side_expr_nobf -> call_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',578), + ('postfix_expr -> left_hand_side_expr','postfix_expr',1,'p_postfix_expr','es5.py',584), + ('postfix_expr -> left_hand_side_expr PLUSPLUS','postfix_expr',2,'p_postfix_expr','es5.py',585), + ('postfix_expr -> left_hand_side_expr MINUSMINUS','postfix_expr',2,'p_postfix_expr','es5.py',586), + ('postfix_expr_nobf -> left_hand_side_expr_nobf','postfix_expr_nobf',1,'p_postfix_expr_nobf','es5.py',595), + ('postfix_expr_nobf -> left_hand_side_expr_nobf PLUSPLUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',596), + ('postfix_expr_nobf -> left_hand_side_expr_nobf MINUSMINUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',597), + ('unary_expr -> postfix_expr','unary_expr',1,'p_unary_expr','es5.py',607), + ('unary_expr -> unary_expr_common','unary_expr',1,'p_unary_expr','es5.py',608), + ('unary_expr_nobf -> postfix_expr_nobf','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',613), + ('unary_expr_nobf -> unary_expr_common','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',614), + ('unary_expr_common -> DELETE unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',619), + ('unary_expr_common -> VOID unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',620), + ('unary_expr_common -> TYPEOF unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',621), + ('unary_expr_common -> PLUSPLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',622), + ('unary_expr_common -> MINUSMINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',623), + ('unary_expr_common -> PLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',624), + ('unary_expr_common -> MINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',625), + ('unary_expr_common -> BNOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',626), + ('unary_expr_common -> NOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',627), + ('multiplicative_expr -> unary_expr','multiplicative_expr',1,'p_multiplicative_expr','es5.py',634), + ('multiplicative_expr -> multiplicative_expr MULT unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',635), + ('multiplicative_expr -> multiplicative_expr DIV unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',636), + ('multiplicative_expr -> multiplicative_expr MOD unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',637), + ('multiplicative_expr_nobf -> unary_expr_nobf','multiplicative_expr_nobf',1,'p_multiplicative_expr_nobf','es5.py',646), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MULT unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',647), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf DIV unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',648), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MOD unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',649), + ('additive_expr -> multiplicative_expr','additive_expr',1,'p_additive_expr','es5.py',659), + ('additive_expr -> additive_expr PLUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',660), + ('additive_expr -> additive_expr MINUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',661), + ('additive_expr_nobf -> multiplicative_expr_nobf','additive_expr_nobf',1,'p_additive_expr_nobf','es5.py',670), + ('additive_expr_nobf -> additive_expr_nobf PLUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',671), + ('additive_expr_nobf -> additive_expr_nobf MINUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',672), + ('shift_expr -> additive_expr','shift_expr',1,'p_shift_expr','es5.py',682), + ('shift_expr -> shift_expr LSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',683), + ('shift_expr -> shift_expr RSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',684), + ('shift_expr -> shift_expr URSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',685), + ('shift_expr_nobf -> additive_expr_nobf','shift_expr_nobf',1,'p_shift_expr_nobf','es5.py',694), + ('shift_expr_nobf -> shift_expr_nobf LSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',695), + ('shift_expr_nobf -> shift_expr_nobf RSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',696), + ('shift_expr_nobf -> shift_expr_nobf URSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',697), + ('relational_expr -> shift_expr','relational_expr',1,'p_relational_expr','es5.py',707), + ('relational_expr -> relational_expr LT shift_expr','relational_expr',3,'p_relational_expr','es5.py',708), + ('relational_expr -> relational_expr GT shift_expr','relational_expr',3,'p_relational_expr','es5.py',709), + ('relational_expr -> relational_expr LE shift_expr','relational_expr',3,'p_relational_expr','es5.py',710), + ('relational_expr -> relational_expr GE shift_expr','relational_expr',3,'p_relational_expr','es5.py',711), + ('relational_expr -> relational_expr INSTANCEOF shift_expr','relational_expr',3,'p_relational_expr','es5.py',712), + ('relational_expr -> relational_expr IN shift_expr','relational_expr',3,'p_relational_expr','es5.py',713), + ('relational_expr_noin -> shift_expr','relational_expr_noin',1,'p_relational_expr_noin','es5.py',722), + ('relational_expr_noin -> relational_expr_noin LT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',723), + ('relational_expr_noin -> relational_expr_noin GT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',724), + ('relational_expr_noin -> relational_expr_noin LE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',725), + ('relational_expr_noin -> relational_expr_noin GE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',726), + ('relational_expr_noin -> relational_expr_noin INSTANCEOF shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',727), + ('relational_expr_nobf -> shift_expr_nobf','relational_expr_nobf',1,'p_relational_expr_nobf','es5.py',736), + ('relational_expr_nobf -> relational_expr_nobf LT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',737), + ('relational_expr_nobf -> relational_expr_nobf GT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',738), + ('relational_expr_nobf -> relational_expr_nobf LE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',739), + ('relational_expr_nobf -> relational_expr_nobf GE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',740), + ('relational_expr_nobf -> relational_expr_nobf INSTANCEOF shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',741), + ('relational_expr_nobf -> relational_expr_nobf IN shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',742), + ('equality_expr -> relational_expr','equality_expr',1,'p_equality_expr','es5.py',752), + ('equality_expr -> equality_expr EQEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',753), + ('equality_expr -> equality_expr NE relational_expr','equality_expr',3,'p_equality_expr','es5.py',754), + ('equality_expr -> equality_expr STREQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',755), + ('equality_expr -> equality_expr STRNEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',756), + ('equality_expr_noin -> relational_expr_noin','equality_expr_noin',1,'p_equality_expr_noin','es5.py',765), + ('equality_expr_noin -> equality_expr_noin EQEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',766), + ('equality_expr_noin -> equality_expr_noin NE relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',767), + ('equality_expr_noin -> equality_expr_noin STREQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',768), + ('equality_expr_noin -> equality_expr_noin STRNEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',769), + ('equality_expr_nobf -> relational_expr_nobf','equality_expr_nobf',1,'p_equality_expr_nobf','es5.py',778), + ('equality_expr_nobf -> equality_expr_nobf EQEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',779), + ('equality_expr_nobf -> equality_expr_nobf NE relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',780), + ('equality_expr_nobf -> equality_expr_nobf STREQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',781), + ('equality_expr_nobf -> equality_expr_nobf STRNEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',782), + ('bitwise_and_expr -> equality_expr','bitwise_and_expr',1,'p_bitwise_and_expr','es5.py',792), + ('bitwise_and_expr -> bitwise_and_expr BAND equality_expr','bitwise_and_expr',3,'p_bitwise_and_expr','es5.py',793), + ('bitwise_and_expr_noin -> equality_expr_noin','bitwise_and_expr_noin',1,'p_bitwise_and_expr_noin','es5.py',802), + ('bitwise_and_expr_noin -> bitwise_and_expr_noin BAND equality_expr_noin','bitwise_and_expr_noin',3,'p_bitwise_and_expr_noin','es5.py',803), + ('bitwise_and_expr_nobf -> equality_expr_nobf','bitwise_and_expr_nobf',1,'p_bitwise_and_expr_nobf','es5.py',813), + ('bitwise_and_expr_nobf -> bitwise_and_expr_nobf BAND equality_expr_nobf','bitwise_and_expr_nobf',3,'p_bitwise_and_expr_nobf','es5.py',814), + ('bitwise_xor_expr -> bitwise_and_expr','bitwise_xor_expr',1,'p_bitwise_xor_expr','es5.py',824), + ('bitwise_xor_expr -> bitwise_xor_expr BXOR bitwise_and_expr','bitwise_xor_expr',3,'p_bitwise_xor_expr','es5.py',825), + ('bitwise_xor_expr_noin -> bitwise_and_expr_noin','bitwise_xor_expr_noin',1,'p_bitwise_xor_expr_noin','es5.py',835), + ('bitwise_xor_expr_noin -> bitwise_xor_expr_noin BXOR bitwise_and_expr_noin','bitwise_xor_expr_noin',3,'p_bitwise_xor_expr_noin','es5.py',836), + ('bitwise_xor_expr_nobf -> bitwise_and_expr_nobf','bitwise_xor_expr_nobf',1,'p_bitwise_xor_expr_nobf','es5.py',847), + ('bitwise_xor_expr_nobf -> bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf','bitwise_xor_expr_nobf',3,'p_bitwise_xor_expr_nobf','es5.py',848), + ('bitwise_or_expr -> bitwise_xor_expr','bitwise_or_expr',1,'p_bitwise_or_expr','es5.py',858), + ('bitwise_or_expr -> bitwise_or_expr BOR bitwise_xor_expr','bitwise_or_expr',3,'p_bitwise_or_expr','es5.py',859), + ('bitwise_or_expr_noin -> bitwise_xor_expr_noin','bitwise_or_expr_noin',1,'p_bitwise_or_expr_noin','es5.py',869), + ('bitwise_or_expr_noin -> bitwise_or_expr_noin BOR bitwise_xor_expr_noin','bitwise_or_expr_noin',3,'p_bitwise_or_expr_noin','es5.py',870), + ('bitwise_or_expr_nobf -> bitwise_xor_expr_nobf','bitwise_or_expr_nobf',1,'p_bitwise_or_expr_nobf','es5.py',881), + ('bitwise_or_expr_nobf -> bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf','bitwise_or_expr_nobf',3,'p_bitwise_or_expr_nobf','es5.py',882), + ('logical_and_expr -> bitwise_or_expr','logical_and_expr',1,'p_logical_and_expr','es5.py',893), + ('logical_and_expr -> logical_and_expr AND bitwise_or_expr','logical_and_expr',3,'p_logical_and_expr','es5.py',894), + ('logical_and_expr_noin -> bitwise_or_expr_noin','logical_and_expr_noin',1,'p_logical_and_expr_noin','es5.py',904), + ('logical_and_expr_noin -> logical_and_expr_noin AND bitwise_or_expr_noin','logical_and_expr_noin',3,'p_logical_and_expr_noin','es5.py',905), + ('logical_and_expr_nobf -> bitwise_or_expr_nobf','logical_and_expr_nobf',1,'p_logical_and_expr_nobf','es5.py',915), + ('logical_and_expr_nobf -> logical_and_expr_nobf AND bitwise_or_expr_nobf','logical_and_expr_nobf',3,'p_logical_and_expr_nobf','es5.py',916), + ('logical_or_expr -> logical_and_expr','logical_or_expr',1,'p_logical_or_expr','es5.py',925), + ('logical_or_expr -> logical_or_expr OR logical_and_expr','logical_or_expr',3,'p_logical_or_expr','es5.py',926), + ('logical_or_expr_noin -> logical_and_expr_noin','logical_or_expr_noin',1,'p_logical_or_expr_noin','es5.py',935), + ('logical_or_expr_noin -> logical_or_expr_noin OR logical_and_expr_noin','logical_or_expr_noin',3,'p_logical_or_expr_noin','es5.py',936), + ('logical_or_expr_nobf -> logical_and_expr_nobf','logical_or_expr_nobf',1,'p_logical_or_expr_nobf','es5.py',945), + ('logical_or_expr_nobf -> logical_or_expr_nobf OR logical_and_expr_nobf','logical_or_expr_nobf',3,'p_logical_or_expr_nobf','es5.py',946), + ('conditional_expr -> logical_or_expr','conditional_expr',1,'p_conditional_expr','es5.py',957), + ('conditional_expr -> logical_or_expr CONDOP assignment_expr COLON assignment_expr','conditional_expr',5,'p_conditional_expr','es5.py',958), + ('conditional_expr_noin -> logical_or_expr_noin','conditional_expr_noin',1,'p_conditional_expr_noin','es5.py',970), + ('conditional_expr_noin -> logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin','conditional_expr_noin',5,'p_conditional_expr_noin','es5.py',971), + ('conditional_expr_nobf -> logical_or_expr_nobf','conditional_expr_nobf',1,'p_conditional_expr_nobf','es5.py',984), + ('conditional_expr_nobf -> logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr','conditional_expr_nobf',5,'p_conditional_expr_nobf','es5.py',985), + ('assignment_expr -> conditional_expr','assignment_expr',1,'p_assignment_expr','es5.py',998), + ('assignment_expr -> left_hand_side_expr assignment_operator assignment_expr','assignment_expr',3,'p_assignment_expr','es5.py',999), + ('assignment_expr_noin -> conditional_expr_noin','assignment_expr_noin',1,'p_assignment_expr_noin','es5.py',1010), + ('assignment_expr_noin -> left_hand_side_expr assignment_operator assignment_expr_noin','assignment_expr_noin',3,'p_assignment_expr_noin','es5.py',1011), + ('assignment_expr_nobf -> conditional_expr_nobf','assignment_expr_nobf',1,'p_assignment_expr_nobf','es5.py',1022), + ('assignment_expr_nobf -> left_hand_side_expr_nobf assignment_operator assignment_expr','assignment_expr_nobf',3,'p_assignment_expr_nobf','es5.py',1023), + ('assignment_operator -> EQ','assignment_operator',1,'p_assignment_operator','es5.py',1033), + ('assignment_operator -> MULTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1034), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1035), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1036), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1037), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1038), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1039), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1040), + ('assignment_operator -> URSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1041), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1042), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1043), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1044), + ('expr -> assignment_expr','expr',1,'p_expr','es5.py',1050), + ('expr -> expr COMMA assignment_expr','expr',3,'p_expr','es5.py',1051), + ('expr_noin -> assignment_expr_noin','expr_noin',1,'p_expr_noin','es5.py',1060), + ('expr_noin -> expr_noin COMMA assignment_expr_noin','expr_noin',3,'p_expr_noin','es5.py',1061), + ('expr_nobf -> assignment_expr_nobf','expr_nobf',1,'p_expr_nobf','es5.py',1070), + ('expr_nobf -> expr_nobf COMMA assignment_expr','expr_nobf',3,'p_expr_nobf','es5.py',1071), + ('variable_statement -> VAR variable_declaration_list SEMI','variable_statement',3,'p_variable_statement','es5.py',1081), + ('variable_statement -> VAR variable_declaration_list AUTOSEMI','variable_statement',3,'p_variable_statement','es5.py',1082), + ('variable_declaration_list -> variable_declaration','variable_declaration_list',1,'p_variable_declaration_list','es5.py',1089), + ('variable_declaration_list -> variable_declaration_list COMMA variable_declaration','variable_declaration_list',3,'p_variable_declaration_list','es5.py',1090), + ('variable_declaration_list_noin -> variable_declaration_noin','variable_declaration_list_noin',1,'p_variable_declaration_list_noin','es5.py',1101), + ('variable_declaration_list_noin -> variable_declaration_list_noin COMMA variable_declaration_noin','variable_declaration_list_noin',3,'p_variable_declaration_list_noin','es5.py',1102), + ('variable_declaration -> identifier','variable_declaration',1,'p_variable_declaration','es5.py',1112), + ('variable_declaration -> identifier initializer','variable_declaration',2,'p_variable_declaration','es5.py',1113), + ('variable_declaration_noin -> identifier','variable_declaration_noin',1,'p_variable_declaration_noin','es5.py',1123), + ('variable_declaration_noin -> identifier initializer_noin','variable_declaration_noin',2,'p_variable_declaration_noin','es5.py',1124), + ('initializer -> EQ assignment_expr','initializer',2,'p_initializer','es5.py',1134), + ('initializer_noin -> EQ assignment_expr_noin','initializer_noin',2,'p_initializer_noin','es5.py',1138), + ('empty_statement -> SEMI','empty_statement',1,'p_empty_statement','es5.py',1143), + ('expr_statement -> expr_nobf SEMI','expr_statement',2,'p_expr_statement','es5.py',1149), + ('expr_statement -> expr_nobf AUTOSEMI','expr_statement',2,'p_expr_statement','es5.py',1150), + ('if_statement -> IF LPAREN expr RPAREN statement','if_statement',5,'p_if_statement_1','es5.py',1173), + ('if_statement -> IF LPAREN expr RPAREN statement ELSE statement','if_statement',7,'p_if_statement_2','es5.py',1178), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN SEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1186), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN AUTOSEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1187), + ('iteration_statement -> WHILE LPAREN expr RPAREN statement','iteration_statement',5,'p_iteration_statement_2','es5.py',1194), + ('iteration_statement -> FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','es5.py',1200), + ('iteration_statement -> FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',10,'p_iteration_statement_3','es5.py',1201), + ('iteration_statement -> FOR LPAREN left_hand_side_expr IN expr RPAREN statement','iteration_statement',7,'p_iteration_statement_4','es5.py',1233), + ('iteration_statement -> FOR LPAREN VAR identifier IN expr RPAREN statement','iteration_statement',8,'p_iteration_statement_5','es5.py',1241), + ('iteration_statement -> FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement','iteration_statement',9,'p_iteration_statement_6','es5.py',1251), + ('expr_opt -> empty','expr_opt',1,'p_expr_opt','es5.py',1261), + ('expr_opt -> expr','expr_opt',1,'p_expr_opt','es5.py',1262), + ('expr_noin_opt -> empty','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1267), + ('expr_noin_opt -> expr_noin','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1268), + ('continue_statement -> CONTINUE SEMI','continue_statement',2,'p_continue_statement_1','es5.py',1274), + ('continue_statement -> CONTINUE AUTOSEMI','continue_statement',2,'p_continue_statement_1','es5.py',1275), + ('continue_statement -> CONTINUE identifier SEMI','continue_statement',3,'p_continue_statement_2','es5.py',1281), + ('continue_statement -> CONTINUE identifier AUTOSEMI','continue_statement',3,'p_continue_statement_2','es5.py',1282), + ('break_statement -> BREAK SEMI','break_statement',2,'p_break_statement_1','es5.py',1289), + ('break_statement -> BREAK AUTOSEMI','break_statement',2,'p_break_statement_1','es5.py',1290), + ('break_statement -> BREAK identifier SEMI','break_statement',3,'p_break_statement_2','es5.py',1296), + ('break_statement -> BREAK identifier AUTOSEMI','break_statement',3,'p_break_statement_2','es5.py',1297), + ('return_statement -> RETURN SEMI','return_statement',2,'p_return_statement_1','es5.py',1304), + ('return_statement -> RETURN AUTOSEMI','return_statement',2,'p_return_statement_1','es5.py',1305), + ('return_statement -> RETURN expr SEMI','return_statement',3,'p_return_statement_2','es5.py',1311), + ('return_statement -> RETURN expr AUTOSEMI','return_statement',3,'p_return_statement_2','es5.py',1312), + ('with_statement -> WITH LPAREN expr RPAREN statement','with_statement',5,'p_with_statement','es5.py',1319), + ('switch_statement -> SWITCH LPAREN expr RPAREN case_block','switch_statement',5,'p_switch_statement','es5.py',1325), + ('case_block -> LBRACE case_clauses_opt RBRACE','case_block',3,'p_case_block','es5.py',1335), + ('case_block -> LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE','case_block',5,'p_case_block','es5.py',1336), + ('case_clauses_opt -> empty','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1350), + ('case_clauses_opt -> case_clauses','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1351), + ('case_clauses -> case_clause','case_clauses',1,'p_case_clauses','es5.py',1356), + ('case_clauses -> case_clauses case_clause','case_clauses',2,'p_case_clauses','es5.py',1357), + ('case_clause -> CASE expr COLON source_elements','case_clause',4,'p_case_clause','es5.py',1366), + ('default_clause -> DEFAULT COLON source_elements','default_clause',3,'p_default_clause','es5.py',1371), + ('labelled_statement -> identifier COLON statement','labelled_statement',3,'p_labelled_statement','es5.py',1377), + ('throw_statement -> THROW expr SEMI','throw_statement',3,'p_throw_statement','es5.py',1383), + ('throw_statement -> THROW expr AUTOSEMI','throw_statement',3,'p_throw_statement','es5.py',1384), + ('try_statement -> TRY block catch','try_statement',3,'p_try_statement_1','es5.py',1391), + ('try_statement -> TRY block finally','try_statement',3,'p_try_statement_2','es5.py',1396), + ('try_statement -> TRY block catch finally','try_statement',4,'p_try_statement_3','es5.py',1401), + ('catch -> CATCH LPAREN identifier RPAREN block','catch',5,'p_catch','es5.py',1406), + ('finally -> FINALLY block','finally',2,'p_finally','es5.py',1411), + ('debugger_statement -> DEBUGGER SEMI','debugger_statement',2,'p_debugger_statement','es5.py',1417), + ('debugger_statement -> DEBUGGER AUTOSEMI','debugger_statement',2,'p_debugger_statement','es5.py',1418), + ('function_declaration -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_declaration',7,'p_function_declaration','es5.py',1426), + ('function_declaration -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_declaration',8,'p_function_declaration','es5.py',1427), + ('function_expr -> FUNCTION LPAREN RPAREN LBRACE function_body RBRACE','function_expr',6,'p_function_expr_1','es5.py',1441), + ('function_expr -> FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_1','es5.py',1442), + ('function_expr -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_2','es5.py',1456), + ('function_expr -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',8,'p_function_expr_2','es5.py',1457), + ('formal_parameter_list -> identifier','formal_parameter_list',1,'p_formal_parameter_list','es5.py',1470), + ('formal_parameter_list -> formal_parameter_list COMMA identifier','formal_parameter_list',3,'p_formal_parameter_list','es5.py',1471), + ('function_body -> source_elements','function_body',1,'p_function_body','es5.py',1480), +] diff --git a/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_6.py b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_6.py new file mode 100644 index 00000000..beeb45e6 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_6.py @@ -0,0 +1,369 @@ + +# /home/toaster/work/calmjs.parse/src/calmjs/parse/parsers/yacctab_es5_py3_ply3_6.py +# This file is automatically generated. Do not edit. +_tabversion = '3.5' + +_lr_method = 'LALR' + +_lr_signature = '9825587DAB8F9D419DD9E432175955D6' + +_lr_action_items = {'$end':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,125,126,130,133,134,136,137,139,140,146,147,215,302,303,304,327,328,329,330,331,332,335,336,337,338,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-1,0,-2,-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-322,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-327,-329,-286,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'FUNCTION':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[23,23,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,109,23,-283,23,109,109,109,-1,109,109,109,109,109,109,109,109,109,-6,23,109,258,-284,-285,109,109,-24,109,109,-300,-301,-304,-305,-308,-309,109,109,-330,-331,109,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,109,109,109,258,109,109,109,258,109,-90,-88,-89,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-322,109,109,109,109,109,258,109,109,258,109,109,258,258,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-25,-271,-272,109,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,23,258,109,23,109,23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,23,-327,-329,109,109,109,23,23,109,-286,-290,109,109,109,-312,-313,23,23,23,109,109,23,109,109,-332,23,23,-287,-288,-289,109,23,-293,-314,-328,-333,23,23,-294,23,23,23,-291,23,-295,-315,-292,]),'LBRACE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,40,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,166,168,171,175,177,178,179,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,212,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,340,357,358,380,382,383,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,453,454,457,459,460,461,464,466,469,476,478,482,484,486,506,507,515,519,520,521,524,526,531,533,534,539,540,541,545,546,547,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[26,26,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,110,26,-283,26,110,110,26,110,-1,110,110,110,110,110,110,110,110,110,-6,26,110,-284,-285,110,110,-24,110,110,-300,-301,-304,-305,-308,-309,110,110,-330,-331,110,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,110,110,110,110,110,-90,-88,-89,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,382,-322,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-25,-271,-272,110,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,26,-1,-91,460,26,464,110,26,110,26,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,26,508,-327,-329,110,110,110,26,515,26,110,519,-286,-290,110,110,110,-312,-313,26,26,545,546,26,110,110,26,110,110,26,-332,26,26,568,-287,-288,-289,110,26,-293,-314,-328,-333,26,26,-294,26,26,26,-291,26,-295,-315,-292,]),'VAR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,132,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[27,27,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,27,-283,27,-6,27,269,-284,-285,-24,313,-300,-301,-304,-305,-308,-309,-330,-331,269,269,-322,269,269,269,269,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,27,269,27,27,27,-327,-329,27,27,-286,-290,-312,-313,27,27,27,27,-332,27,27,-287,-288,-289,27,-293,-314,-328,-333,27,27,-294,27,27,27,-291,27,-295,-315,-292,]),'SEMI':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,28,29,31,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,89,92,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,125,126,130,132,133,134,135,136,137,138,139,140,141,144,146,147,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,306,308,312,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,335,336,337,338,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,382,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,429,430,449,451,453,455,456,458,460,464,467,468,471,476,478,479,480,481,482,485,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,510,512,515,516,518,519,524,525,527,528,529,532,533,541,543,545,546,548,549,550,553,554,556,557,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[28,28,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,28,-283,125,28,133,136,139,146,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-6,28,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,303,-273,-277,-284,-285,-24,-1,-300,-301,327,-304,-305,329,-308,-309,331,335,-330,-331,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-278,-270,427,-135,-298,-299,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,28,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,28,28,-1,482,-279,-275,28,-327,-329,-125,-128,-112,28,28,-121,-107,-94,-286,-290,526,-296,-297,-1,-280,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-312,-313,-246,-85,28,-334,-242,28,28,549,552,-276,-279,-282,28,-332,-335,28,28,-287,-288,-289,-280,28,-293,-244,-314,-328,-333,-336,28,28,-294,28,28,28,-337,-291,28,-295,-315,-292,]),'IF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[30,30,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,30,-283,30,-6,30,259,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,259,259,-322,259,259,259,259,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,30,259,30,30,30,-327,-329,30,30,-286,-290,-312,-313,30,30,30,30,-332,30,30,-287,-288,-289,30,-293,-314,-328,-333,30,30,-294,30,30,30,-291,30,-295,-315,-292,]),'DO':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[31,31,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,-283,31,-6,31,254,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,254,254,-322,254,254,254,254,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,31,254,31,31,31,-327,-329,31,31,-286,-290,-312,-313,31,31,31,31,-332,31,31,-287,-288,-289,31,-293,-314,-328,-333,31,31,-294,31,31,31,-291,31,-295,-315,-292,]),'WHILE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,129,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[32,32,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,32,-283,32,-6,32,271,-284,-285,310,-24,-300,-301,-304,-305,-308,-309,-330,-331,271,271,-322,271,271,271,271,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,32,271,32,32,32,-327,-329,32,32,-286,-290,-312,-313,32,32,32,32,-332,32,32,-287,-288,-289,32,-293,-314,-328,-333,32,32,-294,32,32,32,-291,32,-295,-315,-292,]),'FOR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[33,33,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,33,-283,33,-6,33,257,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,257,257,-322,257,257,257,257,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,33,257,33,33,33,-327,-329,33,33,-286,-290,-312,-313,33,33,33,33,-332,33,33,-287,-288,-289,33,-293,-314,-328,-333,33,33,-294,33,33,33,-291,33,-295,-315,-292,]),'CONTINUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[34,34,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,34,-283,34,-6,34,250,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,250,250,-322,250,250,250,250,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,34,250,34,34,34,-327,-329,34,34,-286,-290,-312,-313,34,34,34,34,-332,34,34,-287,-288,-289,34,-293,-314,-328,-333,34,34,-294,34,34,34,-291,34,-295,-315,-292,]),'BREAK':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[35,35,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,35,-283,35,-6,35,247,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,247,247,-322,247,247,247,247,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,35,247,35,35,35,-327,-329,35,35,-286,-290,-312,-313,35,35,35,35,-332,35,35,-287,-288,-289,35,-293,-314,-328,-333,35,35,-294,35,35,35,-291,35,-295,-315,-292,]),'RETURN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[36,36,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,36,-283,36,-6,36,263,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,263,263,-322,263,263,263,263,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,36,263,36,36,36,-327,-329,36,36,-286,-290,-312,-313,36,36,36,36,-332,36,36,-287,-288,-289,36,-293,-314,-328,-333,36,36,-294,36,36,36,-291,36,-295,-315,-292,]),'WITH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[37,37,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,37,-283,37,-6,37,272,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,272,272,-322,272,272,272,272,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,37,272,37,37,37,-327,-329,37,37,-286,-290,-312,-313,37,37,37,37,-332,37,37,-287,-288,-289,37,-293,-314,-328,-333,37,37,-294,37,37,37,-291,37,-295,-315,-292,]),'SWITCH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[38,38,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,38,-283,38,-6,38,264,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,264,264,-322,264,264,264,264,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,38,264,38,38,38,-327,-329,38,38,-286,-290,-312,-313,38,38,38,38,-332,38,38,-287,-288,-289,38,-293,-314,-328,-333,38,38,-294,38,38,38,-291,38,-295,-315,-292,]),'THROW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[39,39,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,39,-283,39,-6,39,266,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,266,266,-322,266,266,266,266,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,39,266,39,39,39,-327,-329,39,39,-286,-290,-312,-313,39,39,39,39,-332,39,39,-287,-288,-289,39,-293,-314,-328,-333,39,39,-294,39,39,39,-291,39,-295,-315,-292,]),'TRY':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[40,40,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,40,-283,40,-6,40,267,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,267,267,-322,267,267,267,267,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,40,267,40,40,40,-327,-329,40,40,-286,-290,-312,-313,40,40,40,40,-332,40,40,-287,-288,-289,40,-293,-314,-328,-333,40,40,-294,40,40,40,-291,40,-295,-315,-292,]),'DEBUGGER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[41,41,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,41,-283,41,-6,41,251,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,251,251,-322,251,251,251,251,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,41,251,41,41,41,-327,-329,41,41,-286,-290,-312,-313,41,41,41,41,-332,41,41,-287,-288,-289,41,-293,-314,-328,-333,41,41,-294,41,41,41,-291,41,-295,-315,-292,]),'ID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,31,34,35,36,39,51,52,77,78,82,83,84,85,86,87,88,89,91,92,102,109,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,307,313,327,328,329,330,331,332,335,336,337,338,357,358,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,452,453,454,457,459,460,464,466,475,476,478,482,483,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[43,43,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,43,43,43,43,-283,43,43,43,43,43,43,-1,43,43,43,43,43,43,43,43,43,-6,43,43,43,43,43,-284,-285,43,43,-24,43,43,-300,-301,-304,-305,-308,-309,43,43,-330,-331,43,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,43,43,43,43,43,43,43,43,43,-90,-88,-89,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-322,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-25,-271,-272,43,43,43,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-327,43,-329,43,43,43,43,43,43,43,-286,-290,43,43,43,43,-312,-313,43,43,43,43,43,43,43,43,-332,43,43,-287,-288,-289,43,43,-293,-314,-328,-333,43,43,-294,43,43,43,-291,43,-295,-315,-292,]),'NEW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[51,51,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,102,51,-283,51,102,102,102,-1,102,102,102,102,102,102,102,102,102,-6,51,102,262,-284,-285,102,102,-24,102,102,-300,-301,-304,-305,-308,-309,102,102,-330,-331,102,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,102,51,102,262,102,51,102,262,102,-90,-88,-89,51,51,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-322,102,102,102,102,102,262,102,102,262,102,102,262,262,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-25,-271,-272,102,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,51,262,102,51,102,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,51,-327,-329,102,102,102,51,51,102,-286,-290,102,102,102,-312,-313,51,51,51,102,102,51,102,102,-332,51,51,-287,-288,-289,102,51,-293,-314,-328,-333,51,51,-294,51,51,51,-291,51,-295,-315,-292,]),'THIS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[57,57,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,57,57,-283,57,57,57,57,-1,57,57,57,57,57,57,57,57,57,-6,57,57,265,-284,-285,57,57,-24,57,57,-300,-301,-304,-305,-308,-309,57,57,-330,-331,57,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,57,57,57,265,57,57,57,265,57,-90,-88,-89,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-322,57,57,57,57,57,265,57,57,265,57,57,265,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-25,-271,-272,57,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,57,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-327,-329,57,57,57,57,57,57,-286,-290,57,57,57,-312,-313,57,57,57,57,57,57,57,57,-332,57,57,-287,-288,-289,57,57,-293,-314,-328,-333,57,57,-294,57,57,57,-291,57,-295,-315,-292,]),'LPAREN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,31,32,33,36,37,38,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,90,92,99,101,102,104,105,107,108,109,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,234,235,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,310,327,328,329,330,331,332,335,336,337,338,339,346,347,352,353,354,356,357,358,382,390,393,394,398,400,401,402,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[25,25,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,91,-78,25,25,-283,128,25,131,132,25,142,143,25,-37,168,168,25,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,25,25,25,25,25,25,25,25,25,-6,211,25,168,168,25,-105,-106,-76,-77,91,-78,-284,-285,25,25,-24,25,25,-300,-301,-304,-305,-308,-309,25,25,-330,-331,25,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,25,25,-124,25,25,25,-123,25,168,25,-90,-88,-89,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-322,-82,25,25,25,25,-120,25,25,-119,25,168,25,25,397,-92,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-25,-271,-272,25,425,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,452,-126,-127,-113,-114,-83,-84,-1,-91,25,-122,-108,-109,-93,25,474,475,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-327,-329,25,-125,-128,25,-112,25,25,25,25,-121,-107,-94,-286,-290,25,25,25,-312,-313,-85,25,-334,25,25,25,25,25,25,25,-332,-335,25,25,-287,-288,-289,25,25,-293,-314,-328,-333,-336,25,25,-294,25,25,25,-337,-291,25,-295,-315,-292,]),'LBRACKET':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,99,101,102,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[52,52,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,52,52,-283,52,52,52,-37,166,171,52,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,52,52,52,52,52,52,52,52,52,-6,52,224,228,52,-105,-106,-76,-77,-78,-284,-285,52,52,-24,52,52,-300,-301,-304,-305,-308,-309,52,52,-330,-331,52,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,52,52,-124,52,52,52,-123,52,228,52,-90,-88,-89,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-322,-82,52,52,52,52,-120,52,52,-119,52,228,52,52,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-25,-271,-272,52,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-126,-127,-113,-114,-83,-84,-1,-91,52,-122,-108,-109,-93,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-327,-329,52,-125,-128,52,-112,52,52,52,52,-121,-107,-94,-286,-290,52,52,52,-312,-313,-85,52,-334,52,52,52,52,52,52,52,-332,-335,52,52,-287,-288,-289,52,52,-293,-314,-328,-333,-336,52,52,-294,52,52,52,-337,-291,52,-295,-315,-292,]),'NULL':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[67,67,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,67,67,-283,67,67,67,67,-1,67,67,67,67,67,67,67,67,67,-6,67,67,273,-284,-285,67,67,-24,67,67,-300,-301,-304,-305,-308,-309,67,67,-330,-331,67,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,67,67,67,273,67,67,67,273,67,-90,-88,-89,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-322,67,67,67,67,67,273,67,67,273,67,67,273,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-25,-271,-272,67,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,67,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-327,-329,67,67,67,67,67,67,-286,-290,67,67,67,-312,-313,67,67,67,67,67,67,67,67,-332,67,67,-287,-288,-289,67,67,-293,-314,-328,-333,67,67,-294,67,67,67,-291,67,-295,-315,-292,]),'TRUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[68,68,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,68,68,-283,68,68,68,68,-1,68,68,68,68,68,68,68,68,68,-6,68,68,274,-284,-285,68,68,-24,68,68,-300,-301,-304,-305,-308,-309,68,68,-330,-331,68,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,68,68,68,274,68,68,68,274,68,-90,-88,-89,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-322,68,68,68,68,68,274,68,68,274,68,68,274,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-25,-271,-272,68,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,68,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-327,-329,68,68,68,68,68,68,-286,-290,68,68,68,-312,-313,68,68,68,68,68,68,68,68,-332,68,68,-287,-288,-289,68,68,-293,-314,-328,-333,68,68,-294,68,68,68,-291,68,-295,-315,-292,]),'FALSE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[69,69,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,69,69,-283,69,69,69,69,-1,69,69,69,69,69,69,69,69,69,-6,69,69,275,-284,-285,69,69,-24,69,69,-300,-301,-304,-305,-308,-309,69,69,-330,-331,69,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,69,69,69,275,69,69,69,275,69,-90,-88,-89,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-322,69,69,69,69,69,275,69,69,275,69,69,275,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-25,-271,-272,69,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,69,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-327,-329,69,69,69,69,69,69,-286,-290,69,69,69,-312,-313,69,69,69,69,69,69,69,69,-332,69,69,-287,-288,-289,69,69,-293,-314,-328,-333,69,69,-294,69,69,69,-291,69,-295,-315,-292,]),'NUMBER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[70,70,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,70,70,-283,70,70,70,70,-1,70,70,70,70,70,70,70,70,70,-6,70,70,70,-284,-285,70,70,-24,70,70,-300,-301,-304,-305,-308,-309,70,70,-330,-331,70,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,70,70,70,70,70,70,70,-90,-88,-89,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-322,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-25,-271,-272,70,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-327,-329,70,70,70,70,70,70,-286,-290,70,70,70,-312,-313,70,70,70,70,70,70,70,70,-332,70,70,-287,-288,-289,70,70,-293,-314,-328,-333,70,70,-294,70,70,70,-291,70,-295,-315,-292,]),'STRING':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[71,71,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,71,71,-283,71,71,71,71,-1,71,71,71,71,71,71,71,71,71,-6,71,71,71,-284,-285,71,71,-24,71,71,-300,-301,-304,-305,-308,-309,71,71,-330,-331,71,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,71,71,71,71,71,71,71,-90,-88,-89,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-322,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-25,-271,-272,71,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-327,-329,71,71,71,71,71,71,-286,-290,71,71,71,-312,-313,71,71,71,71,71,71,71,71,-332,71,71,-287,-288,-289,71,71,-293,-314,-328,-333,71,71,-294,71,71,71,-291,71,-295,-315,-292,]),'REGEX':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[72,72,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,72,72,-283,72,72,72,72,-1,72,72,72,72,72,72,72,72,72,-6,72,72,-284,-285,72,72,-24,72,72,-300,-301,-304,-305,-308,-309,72,72,-330,-331,72,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,72,72,72,72,72,72,72,-90,-88,-89,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-322,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-25,-271,-272,72,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-327,-329,72,72,72,72,72,72,-286,-290,72,72,72,-312,-313,72,72,72,72,72,72,72,72,-332,72,72,-287,-288,-289,72,72,-293,-314,-328,-333,72,72,-294,72,72,72,-291,72,-295,-315,-292,]),'DELETE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[84,84,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,84,84,-283,84,84,84,-1,84,84,84,84,84,84,84,84,84,-6,84,253,-284,-285,84,84,-24,84,84,-300,-301,-304,-305,-308,-309,84,84,-330,-331,84,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,84,84,84,253,84,84,84,253,84,-90,-88,-89,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-322,84,84,84,84,84,253,84,84,253,84,84,253,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-25,-271,-272,84,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,84,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-327,-329,84,84,84,84,84,84,-286,-290,84,84,84,-312,-313,84,84,84,84,84,84,84,84,-332,84,84,-287,-288,-289,84,84,-293,-314,-328,-333,84,84,-294,84,84,84,-291,84,-295,-315,-292,]),'VOID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[85,85,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,85,85,-283,85,85,85,-1,85,85,85,85,85,85,85,85,85,-6,85,270,-284,-285,85,85,-24,85,85,-300,-301,-304,-305,-308,-309,85,85,-330,-331,85,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,85,85,85,270,85,85,85,270,85,-90,-88,-89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-322,85,85,85,85,85,270,85,85,270,85,85,270,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-25,-271,-272,85,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,85,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-327,-329,85,85,85,85,85,85,-286,-290,85,85,85,-312,-313,85,85,85,85,85,85,85,85,-332,85,85,-287,-288,-289,85,85,-293,-314,-328,-333,85,85,-294,85,85,85,-291,85,-295,-315,-292,]),'TYPEOF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[86,86,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,86,86,-283,86,86,86,-1,86,86,86,86,86,86,86,86,86,-6,86,268,-284,-285,86,86,-24,86,86,-300,-301,-304,-305,-308,-309,86,86,-330,-331,86,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,86,86,86,268,86,86,86,268,86,-90,-88,-89,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-322,86,86,86,86,86,268,86,86,268,86,86,268,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-25,-271,-272,86,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,86,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-327,-329,86,86,86,86,86,86,-286,-290,86,86,86,-312,-313,86,86,86,86,86,86,86,86,-332,86,86,-287,-288,-289,86,86,-293,-314,-328,-333,86,86,-294,86,86,86,-291,86,-295,-315,-292,]),'PLUSPLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[82,82,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,82,82,-283,82,82,82,-37,149,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,82,82,82,82,82,82,82,82,82,-6,82,219,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,82,82,-24,82,82,-300,-301,-304,-305,-308,-309,82,82,-330,-331,82,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,82,82,-124,82,82,82,-123,82,-118,-115,82,-90,-88,-89,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,219,-322,-82,82,82,82,82,-120,82,82,-119,82,-116,-115,82,82,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-25,-271,-272,82,219,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,149,-126,-127,-113,-114,-83,-84,-1,-91,82,-122,-108,-109,-93,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-327,-329,82,-125,-128,82,-112,82,82,82,82,-121,-107,-94,-286,-290,82,82,82,219,-312,-313,-85,82,-334,82,82,82,82,82,82,82,-332,-335,82,82,-287,-288,-289,82,82,-293,-314,-328,-333,-336,82,82,-294,82,82,82,-337,-291,82,-295,-315,-292,]),'MINUSMINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[83,83,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,83,83,-283,83,83,83,-37,150,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,83,83,83,83,83,83,83,83,83,-6,83,220,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,83,83,-24,83,83,-300,-301,-304,-305,-308,-309,83,83,-330,-331,83,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,83,83,-124,83,83,83,-123,83,-118,-115,83,-90,-88,-89,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,220,-322,-82,83,83,83,83,-120,83,83,-119,83,-116,-115,83,83,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-25,-271,-272,83,220,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,150,-126,-127,-113,-114,-83,-84,-1,-91,83,-122,-108,-109,-93,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-327,-329,83,-125,-128,83,-112,83,83,83,83,-121,-107,-94,-286,-290,83,83,83,220,-312,-313,-85,83,-334,83,83,83,83,83,83,83,-332,-335,83,83,-287,-288,-289,83,83,-293,-314,-328,-333,-336,83,83,-294,83,83,83,-337,-291,83,-295,-315,-292,]),'PLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[77,77,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,77,77,-283,77,77,77,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,196,-165,77,77,-158,-143,-144,77,77,77,77,77,77,77,-6,77,-135,-131,-132,-115,-105,-106,-76,-77,-78,297,-162,-154,-141,-142,-284,-285,77,77,-24,77,77,-300,-301,-304,-305,-308,-309,77,77,-330,-331,77,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,77,77,-124,77,77,77,-123,77,-118,-115,77,-90,-88,-89,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,77,77,-136,-137,77,77,-120,77,77,-119,77,-116,-115,77,77,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-25,-271,-272,77,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,297,297,297,-166,-167,-159,-160,-161,77,-122,-108,-109,-93,77,297,297,297,-163,-164,-155,-156,-157,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-327,-329,77,-125,-128,77,-112,77,77,77,77,-121,-107,-94,-286,-290,77,77,77,-135,-312,-313,-85,77,-334,77,77,77,77,77,77,77,-332,-335,77,77,-287,-288,-289,77,77,-293,-314,-328,-333,-336,77,77,-294,77,77,77,-337,-291,77,-295,-315,-292,]),'MINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[78,78,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,78,78,-283,78,78,78,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,197,-165,78,78,-158,-143,-144,78,78,78,78,78,78,78,-6,78,-135,-131,-132,-115,-105,-106,-76,-77,-78,298,-162,-154,-141,-142,-284,-285,78,78,-24,78,78,-300,-301,-304,-305,-308,-309,78,78,-330,-331,78,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,78,78,-124,78,78,78,-123,78,-118,-115,78,-90,-88,-89,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,78,78,-136,-137,78,78,-120,78,78,-119,78,-116,-115,78,78,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-25,-271,-272,78,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,298,298,298,-166,-167,-159,-160,-161,78,-122,-108,-109,-93,78,298,298,298,-163,-164,-155,-156,-157,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-327,-329,78,-125,-128,78,-112,78,78,78,78,-121,-107,-94,-286,-290,78,78,78,-135,-312,-313,-85,78,-334,78,78,78,78,78,78,78,-332,-335,78,78,-287,-288,-289,78,78,-293,-314,-328,-333,-336,78,78,-294,78,78,78,-337,-291,78,-295,-315,-292,]),'BNOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[87,87,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,87,87,-283,87,87,87,-1,87,87,87,87,87,87,87,87,87,-6,87,-284,-285,87,87,-24,87,87,-300,-301,-304,-305,-308,-309,87,87,-330,-331,87,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,87,87,87,87,87,87,87,-90,-88,-89,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-322,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-25,-271,-272,87,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-327,-329,87,87,87,87,87,87,-286,-290,87,87,87,-312,-313,87,87,87,87,87,87,87,87,-332,87,87,-287,-288,-289,87,87,-293,-314,-328,-333,87,87,-294,87,87,87,-291,87,-295,-315,-292,]),'NOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[88,88,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,88,88,-283,88,88,88,-1,88,88,88,88,88,88,88,88,88,-6,88,-284,-285,88,88,-24,88,88,-300,-301,-304,-305,-308,-309,88,88,-330,-331,88,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,88,88,88,88,88,88,88,-90,-88,-89,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-322,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-25,-271,-272,88,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-327,-329,88,88,88,88,88,88,-286,-290,88,88,88,-312,-313,88,88,88,88,88,88,88,88,-332,88,88,-287,-288,-289,88,88,-293,-314,-328,-333,88,88,-294,88,88,88,-291,88,-295,-315,-292,]),'RBRACE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,89,95,96,97,98,99,100,101,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,125,126,130,133,134,136,137,139,140,146,147,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,327,328,329,330,331,332,335,336,337,338,347,354,356,382,386,388,390,391,393,394,395,396,398,399,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,451,453,456,460,462,463,464,467,468,471,472,473,476,478,506,507,508,512,514,515,516,517,518,519,535,536,537,538,541,542,543,544,545,546,548,549,550,556,558,559,561,563,564,565,566,567,568,571,573,574,575,576,577,578,579,581,582,583,584,585,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-1,-283,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-6,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,235,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,302,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,398,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-127,-83,-84,-1,-248,-236,-122,-230,-108,-109,-224,-218,-93,471,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-327,-329,-128,-1,516,-340,-1,-121,-107,-94,-96,-97,-286,-290,-312,-313,-1,-85,541,-1,-334,543,-242,-1,558,-316,-317,-318,-332,564,-335,565,-1,-1,-287,-288,-289,-293,-314,-1,-319,-328,-333,-336,576,577,-1,-294,582,-1,-1,-337,-98,585,-291,-295,-315,-321,-320,-99,-292,]),'CASE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,537,538,541,548,549,550,556,558,559,561,563,564,571,574,575,579,581,582,583,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,248,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,248,248,-322,248,248,248,248,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,248,-327,-329,-286,-290,-312,-313,539,539,-318,-332,-287,-288,-289,-293,-314,539,-319,-328,-333,-294,-1,-1,-291,-295,-315,-321,-320,-292,]),'DEFAULT':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,535,536,537,538,541,548,549,550,556,558,561,563,564,571,575,579,581,582,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,252,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,252,252,-322,252,252,252,252,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,252,-327,-329,-286,-290,-312,-313,-1,560,-316,-317,-318,-332,-287,-288,-289,-293,-314,-319,-328,-333,-294,-1,-291,-295,-315,-320,-292,]),'ELSE':([8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,255,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,255,255,-322,255,255,255,255,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,255,-327,-329,524,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'COLON':([24,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,238,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,318,319,320,321,322,323,324,325,326,342,347,354,356,385,386,387,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,467,468,471,488,489,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,518,543,557,560,562,565,576,],[92,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,400,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-249,-243,-237,-231,-225,-219,-213,-201,-183,454,-127,-83,-84,-266,-248,466,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-121,-107,-94,-135,-250,534,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-242,-335,-244,574,575,-336,-337,]),'PERIOD':([24,43,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,99,101,104,105,107,108,111,165,170,174,216,223,227,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,512,516,541,543,564,565,576,],[-78,-37,167,172,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,225,229,-105,-106,-76,-77,-78,-124,-123,229,-82,-120,-119,229,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,-85,-334,-336,-335,-337,-336,-337,]),'EQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,124,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,429,455,456,458,467,468,471,488,512,516,529,541,543,564,565,576,],[-78,-37,151,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,151,-131,-132,-115,-105,-106,-76,-77,-78,307,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,151,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,486,-125,-128,-112,-121,-107,-94,151,-85,-334,486,-336,-335,-337,-336,-337,]),'MULTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,152,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,152,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,152,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,152,-85,-334,-336,-335,-337,-336,-337,]),'DIVEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,153,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,153,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,153,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,153,-85,-334,-336,-335,-337,-336,-337,]),'MODEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,154,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,154,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,154,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,154,-85,-334,-336,-335,-337,-336,-337,]),'PLUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,155,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,155,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,155,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,155,-85,-334,-336,-335,-337,-336,-337,]),'MINUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,156,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,156,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,156,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,156,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,157,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,157,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,157,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,157,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,158,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,158,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,158,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,158,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,159,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,159,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,159,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,159,-85,-334,-336,-335,-337,-336,-337,]),'ANDEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,160,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,160,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,160,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,160,-85,-334,-336,-335,-337,-336,-337,]),'XOREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,161,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,161,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,161,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,161,-85,-334,-336,-335,-337,-336,-337,]),'OREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,162,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,162,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,162,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,162,-85,-334,-336,-335,-337,-336,-337,]),'MULT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,198,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,299,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,299,299,-159,-160,-161,-122,-108,-109,-93,299,299,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'DIV':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,199,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,300,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,300,300,-159,-160,-161,-122,-108,-109,-93,300,300,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'MOD':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,200,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,301,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,301,301,-159,-160,-161,-122,-108,-109,-93,301,301,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,193,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,294,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,294,-138,-126,-127,-113,-114,-83,-84,294,294,294,294,294,294,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,294,294,294,294,294,294,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,294,294,294,294,294,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,194,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,295,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,295,-138,-126,-127,-113,-114,-83,-84,295,295,295,295,295,295,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,295,295,295,295,295,295,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,295,295,295,295,295,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,195,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,296,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,296,-138,-126,-127,-113,-114,-83,-84,296,296,296,296,296,296,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,296,296,296,296,296,296,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,296,296,296,296,296,-85,-334,-336,-335,-337,-336,-337,]),'LT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,187,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,288,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,444,-183,-138,-126,-127,-113,-114,-83,-84,288,288,288,288,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,288,288,288,288,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,288,288,288,288,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,188,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,289,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,445,-183,-138,-126,-127,-113,-114,-83,-84,289,289,289,289,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,289,289,289,289,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,289,289,289,289,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'LE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,189,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,290,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,446,-183,-138,-126,-127,-113,-114,-83,-84,290,290,290,290,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,290,290,290,290,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,290,290,290,290,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,190,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,291,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,447,-183,-138,-126,-127,-113,-114,-83,-84,291,291,291,291,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,291,291,291,291,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,291,291,291,291,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'INSTANCEOF':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,191,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,261,-78,292,-176,-168,-162,-154,-141,-142,-139,-140,-124,261,-123,261,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,261,-119,261,-116,-115,-92,261,261,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,448,-183,-138,-126,-127,-113,-114,-83,-84,292,292,292,292,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,261,292,292,292,292,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,292,292,292,292,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'IN':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,318,319,320,321,322,323,324,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,429,455,456,458,467,468,471,485,488,489,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,532,541,543,557,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,192,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,260,-78,293,-176,-168,-162,-154,-141,-142,-139,-140,-124,260,-123,260,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,260,-119,260,-116,-115,-92,260,260,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,431,-249,-243,-237,-231,-225,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,293,293,293,293,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,260,293,293,293,293,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,484,-125,-128,-112,-121,-107,-94,531,-135,-250,-238,-232,-226,-220,-214,293,293,293,293,-184,-185,-186,-187,-188,-85,-334,-282,-336,-335,-244,-337,-336,-337,]),'EQEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,183,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,284,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,440,-201,-183,-138,-126,-127,-113,-114,-83,-84,183,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,284,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,440,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'NE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,184,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,285,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,441,-201,-183,-138,-126,-127,-113,-114,-83,-84,184,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,285,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,441,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STREQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,185,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,286,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,442,-201,-183,-138,-126,-127,-113,-114,-83,-84,185,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,286,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,442,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STRNEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,186,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,287,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,443,-201,-183,-138,-126,-127,-113,-114,-83,-84,186,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,287,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,443,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BAND':([24,43,45,47,48,50,54,55,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,323,324,325,326,344,346,347,352,353,354,356,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,182,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,283,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,439,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,182,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,283,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,439,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BXOR':([24,43,45,47,48,50,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,322,323,324,325,326,344,346,347,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,181,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,233,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,438,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,181,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,233,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,438,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BOR':([24,43,45,47,48,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,321,322,323,324,325,326,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,180,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,232,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,437,-225,-219,-213,-201,-183,-138,-126,-127,180,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,232,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,437,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AND':([24,43,45,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,169,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,226,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,436,-231,-225,-219,-213,-201,-183,169,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,226,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,436,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'CONDOP':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,163,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,221,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,434,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'OR':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,164,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,222,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,435,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AUTOSEMI':([24,29,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,135,138,141,144,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,455,456,458,467,468,471,510,512,516,518,525,541,543,564,565,576,],[-78,126,134,137,140,147,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,304,-273,-277,328,330,332,336,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,-125,-128,-112,-121,-107,-94,-246,-85,-334,-242,550,-336,-335,-337,-336,-337,]),'COMMA':([24,29,42,43,44,45,46,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,141,144,149,150,165,170,173,174,176,177,179,201,202,203,204,205,206,207,208,209,210,213,214,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,309,311,314,316,317,318,319,320,321,322,323,324,325,326,333,334,341,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,381,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,428,429,430,455,456,458,465,467,468,470,471,472,473,477,481,485,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,510,511,512,513,516,518,528,529,530,532,541,543,553,555,557,562,564,565,576,577,585,],[-78,127,-269,-37,-251,-138,-245,-133,-134,-239,-117,177,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,217,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,305,-273,-277,217,217,-139,-140,-124,-123,-118,-115,357,-90,358,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,384,-338,-82,-136,-137,-120,-119,-116,-115,-92,399,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,217,217,-135,433,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,217,217,-252,-240,-138,217,-126,-127,457,-129,-234,217,-113,-114,-83,-86,-84,177,-91,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,384,-266,-248,-236,217,-122,-230,217,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,483,-279,-275,-125,-128,-112,-339,-121,-107,384,-94,-96,-97,217,217,-280,217,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-246,-130,-85,-87,-334,-242,-276,-279,217,-282,-336,-335,-280,217,-244,217,-337,-336,-337,-98,-99,]),'RPAREN':([43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,91,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,168,201,202,203,204,205,206,207,208,209,210,211,213,214,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,309,311,333,334,347,348,349,354,356,381,385,386,388,390,391,393,394,395,396,397,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,465,467,468,470,471,474,477,480,481,487,509,511,512,516,518,522,523,526,530,543,551,552,555,565,570,576,],[-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,212,216,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,347,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,380,383,-338,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,424,426,449,450,-127,456,-129,-83,-84,461,-266,-248,-236,-122,-230,-108,-109,-224,-218,469,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-339,-121,-107,520,-94,521,525,-296,-297,533,540,-130,-85,-334,-242,547,-104,-1,554,-335,569,-1,572,-336,580,-337,]),'RBRACKET':([43,52,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,175,176,177,178,179,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,345,347,351,354,355,356,357,358,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,459,467,468,471,512,513,516,518,543,565,576,],[-37,-1,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,354,356,-90,-88,-89,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,455,-127,458,-83,-86,-84,-1,-91,-266,-248,-236,467,-122,-230,468,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,512,-121,-107,-94,-85,-87,-334,-242,-335,-336,-337,]),'GETPROP':([110,399,],[239,239,]),'SETPROP':([110,399,],[240,240,]),'CATCH':([110,145,167,172,225,229,239,240,302,399,],[249,339,249,249,249,249,249,249,-25,249,]),'FINALLY':([110,145,167,172,225,229,239,240,302,337,399,563,],[256,340,256,256,256,256,256,256,-25,340,256,-328,]),'CLASS':([110,167,172,225,229,239,240,399,],[276,276,276,276,276,276,276,276,]),'CONST':([110,167,172,225,229,239,240,399,],[277,277,277,277,277,277,277,277,]),'ENUM':([110,167,172,225,229,239,240,399,],[278,278,278,278,278,278,278,278,]),'EXPORT':([110,167,172,225,229,239,240,399,],[279,279,279,279,279,279,279,279,]),'EXTENDS':([110,167,172,225,229,239,240,399,],[280,280,280,280,280,280,280,280,]),'IMPORT':([110,167,172,225,229,239,240,399,],[281,281,281,281,281,281,281,281,]),'SUPER':([110,167,172,225,229,239,240,399,],[282,282,282,282,282,282,282,282,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'source_elements':([0,26,382,460,464,515,519,545,546,568,574,575,],[2,121,463,463,463,463,463,463,463,463,583,584,]),'empty':([0,26,52,132,357,382,427,460,464,482,508,515,519,526,545,546,552,559,568,574,575,],[3,3,178,315,178,3,480,3,3,480,536,3,3,480,3,3,480,536,3,3,3,]),'source_element_list':([0,26,382,460,464,515,519,545,546,568,574,575,],[4,4,4,4,4,4,4,4,4,4,4,4,]),'source_element':([0,4,26,382,460,464,515,519,545,546,568,574,575,],[5,89,5,5,5,5,5,5,5,5,5,5,5,]),'statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[6,6,6,129,215,6,476,478,506,6,6,6,6,548,556,6,6,571,6,579,581,6,6,586,]),'function_declaration':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[7,7,7,130,130,7,130,130,130,7,7,7,7,130,130,7,7,130,7,130,130,7,7,130,]),'block':([0,4,26,31,40,92,340,382,424,426,449,460,464,515,519,524,533,540,545,546,554,568,569,572,574,575,580,],[8,8,8,8,145,8,453,8,8,8,8,8,8,8,8,8,8,563,8,8,8,8,8,8,8,8,8,]),'variable_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'empty_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'expr_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'if_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'iteration_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'continue_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'break_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'return_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'with_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'switch_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,]),'labelled_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'throw_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,]),'try_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,]),'debugger_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,]),'identifier':([0,4,23,25,26,27,31,34,35,36,39,51,77,78,82,83,84,85,86,87,88,91,92,102,109,110,127,128,131,132,142,143,148,163,164,166,167,168,169,171,172,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,305,307,313,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,452,454,457,459,460,464,466,475,482,483,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[24,24,90,111,24,124,24,135,138,111,111,111,111,111,111,111,111,111,111,111,111,214,24,111,234,245,111,111,111,111,111,111,111,111,111,111,245,111,111,111,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,214,111,111,111,111,111,245,111,111,245,111,111,245,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,124,111,429,24,465,214,245,111,24,111,24,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,24,509,111,111,111,24,24,111,523,111,529,111,111,24,24,24,111,111,24,111,111,24,24,111,24,24,24,24,24,24,24,]),'expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,]),'assignment_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'conditional_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,]),'left_hand_side_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[45,45,45,45,45,344,344,344,344,344,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'logical_or_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,]),'new_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'call_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,]),'logical_and_expr_nobf':([0,4,26,31,92,164,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[49,49,49,49,49,343,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'member_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,]),'bitwise_or_expr_nobf':([0,4,26,31,92,164,169,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[53,53,53,53,53,53,350,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,]),'primary_expr_no_brace':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[54,54,107,54,54,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,107,107,107,107,107,107,54,107,107,54,107,107,54,54,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,54,107,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,54,54,107,107,107,107,54,54,54,107,107,54,107,107,54,54,107,54,54,54,54,54,54,54,]),'function_expr':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[55,55,105,55,55,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,105,105,105,105,105,105,55,105,105,55,105,105,55,55,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,55,105,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,55,55,105,105,105,105,55,55,55,105,105,55,105,105,55,55,105,55,55,55,55,55,55,55,]),'bitwise_xor_expr_nobf':([0,4,26,31,92,164,169,180,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[56,56,56,56,56,56,56,359,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,]),'literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,]),'array_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,]),'bitwise_and_expr_nobf':([0,4,26,31,92,164,169,180,181,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[60,60,60,60,60,60,60,60,360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,]),'null_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,]),'boolean_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,]),'numeric_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,]),'string_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,]),'regex_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,]),'equality_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[66,66,66,66,66,66,66,66,66,361,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,]),'relational_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,]),'shift_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,]),'additive_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,]),'multiplicative_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,]),'unary_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,]),'postfix_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,]),'unary_expr_common':([0,4,25,26,31,36,39,77,78,82,83,84,85,86,87,88,92,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[81,81,120,81,81,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,120,120,120,120,120,81,120,120,81,120,120,81,81,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,81,120,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,81,81,120,120,120,120,81,81,81,120,120,81,120,120,81,81,120,81,81,81,81,81,81,81,]),'expr':([25,36,39,128,131,142,143,166,171,224,228,425,427,431,482,484,526,531,539,552,],[93,141,144,309,311,333,334,345,351,389,392,477,481,487,481,530,481,555,562,481,]),'assignment_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[94,94,94,308,94,94,94,94,341,342,94,349,94,355,385,386,387,94,94,423,473,94,94,94,510,511,513,518,94,94,94,94,94,94,]),'conditional_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'left_hand_side_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[96,96,96,202,202,202,202,202,202,202,202,202,96,96,96,314,96,96,96,96,96,96,96,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,202,96,202,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,488,488,488,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,96,488,96,96,488,96,96,]),'logical_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'new_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[98,98,98,173,98,98,98,98,98,98,98,98,98,230,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'call_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'logical_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,388,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'member_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[101,101,101,174,101,101,101,101,101,101,101,101,101,231,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'bitwise_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,391,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'primary_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'bitwise_xor_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,395,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,]),'object_literal':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,]),'bitwise_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,396,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,]),'equality_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,283,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,403,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,]),'relational_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,183,184,185,186,217,218,221,222,224,226,228,232,233,283,284,285,286,287,307,400,425,427,431,440,441,442,443,454,457,459,466,482,484,526,531,539,552,],[114,114,114,114,114,114,114,114,114,114,114,114,114,114,362,363,364,365,114,114,114,114,114,114,114,114,114,114,404,405,406,407,114,114,114,114,114,497,498,499,500,114,114,114,114,114,114,114,114,114,114,]),'shift_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[115,115,115,115,115,115,326,115,115,115,115,115,115,115,115,115,115,115,115,366,367,368,369,370,371,115,115,115,115,115,115,115,115,115,115,115,115,115,115,408,409,410,411,412,413,115,115,115,115,115,326,326,326,326,326,326,326,326,115,115,115,115,501,502,503,504,505,115,115,115,115,115,115,326,115,115,326,115,115,]),'additive_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,372,373,374,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,414,415,416,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,]),'multiplicative_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,375,376,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,417,418,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,]),'unary_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[118,118,118,201,203,204,205,206,207,208,209,210,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,377,378,379,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,419,420,421,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,]),'postfix_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,]),'variable_declaration_list':([27,],[122,]),'variable_declaration':([27,305,],[123,422,]),'assignment_operator':([45,96,314,488,],[148,218,432,432,]),'arguments':([48,50,99,101,174,231,],[165,170,223,227,353,394,]),'elision_opt':([52,357,],[175,459,]),'element_list':([52,],[176,]),'elision':([52,357,],[179,179,]),'formal_parameter_list':([91,211,397,],[213,381,470,]),'property_list':([110,],[236,]),'property_assignment':([110,399,],[237,472,]),'property_name':([110,239,240,399,],[238,401,402,238,]),'identifier_name_string':([110,167,172,225,229,239,240,399,],[241,346,352,390,393,241,241,241,]),'identifier_name':([110,167,172,225,229,239,240,399,],[244,244,244,244,244,244,244,244,]),'reserved_word':([110,167,172,225,229,239,240,399,],[246,246,246,246,246,246,246,246,]),'initializer':([124,],[306,]),'expr_noin_opt':([132,],[312,]),'expr_noin':([132,],[316,]),'assignment_expr_noin':([132,432,433,434,486,534,],[317,489,490,491,532,557,]),'conditional_expr_noin':([132,432,433,434,486,534,],[318,318,318,318,318,318,]),'logical_or_expr_noin':([132,432,433,434,486,534,],[319,319,319,319,319,319,]),'logical_and_expr_noin':([132,432,433,434,435,486,534,],[320,320,320,320,492,320,320,]),'bitwise_or_expr_noin':([132,432,433,434,435,436,486,534,],[321,321,321,321,321,493,321,321,]),'bitwise_xor_expr_noin':([132,432,433,434,435,436,437,486,534,],[322,322,322,322,322,322,494,322,322,]),'bitwise_and_expr_noin':([132,432,433,434,435,436,437,438,486,534,],[323,323,323,323,323,323,323,495,323,323,]),'equality_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[324,324,324,324,324,324,324,324,496,324,324,]),'relational_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[325,325,325,325,325,325,325,325,325,325,325,]),'catch':([145,],[337,]),'finally':([145,337,],[338,451,]),'argument_list':([168,],[348,]),'variable_declaration_list_noin':([313,],[428,]),'variable_declaration_noin':([313,483,],[430,528,]),'function_body':([382,460,464,515,519,545,546,568,],[462,514,517,542,544,566,567,578,]),'expr_opt':([427,482,526,552,],[479,527,551,570,]),'initializer_noin':([429,529,],[485,553,]),'case_block':([450,],[507,]),'property_set_parameter_list':([475,],[522,]),'case_clauses_opt':([508,559,],[535,573,]),'case_clauses':([508,559,],[537,537,]),'case_clause':([508,537,559,],[538,561,538,]),'default_clause':([535,],[559,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('empty -> ','empty',0,'p_empty','es5.py',122), + ('program -> source_elements','program',1,'p_program','es5.py',157), + ('source_elements -> empty','source_elements',1,'p_source_elements','es5.py',164), + ('source_elements -> source_element_list','source_elements',1,'p_source_elements','es5.py',165), + ('source_element_list -> source_element','source_element_list',1,'p_source_element_list','es5.py',170), + ('source_element_list -> source_element_list source_element','source_element_list',2,'p_source_element_list','es5.py',171), + ('source_element -> statement','source_element',1,'p_source_element','es5.py',180), + ('source_element -> function_declaration','source_element',1,'p_source_element','es5.py',181), + ('statement -> block','statement',1,'p_statement','es5.py',186), + ('statement -> variable_statement','statement',1,'p_statement','es5.py',187), + ('statement -> empty_statement','statement',1,'p_statement','es5.py',188), + ('statement -> expr_statement','statement',1,'p_statement','es5.py',189), + ('statement -> if_statement','statement',1,'p_statement','es5.py',190), + ('statement -> iteration_statement','statement',1,'p_statement','es5.py',191), + ('statement -> continue_statement','statement',1,'p_statement','es5.py',192), + ('statement -> break_statement','statement',1,'p_statement','es5.py',193), + ('statement -> return_statement','statement',1,'p_statement','es5.py',194), + ('statement -> with_statement','statement',1,'p_statement','es5.py',195), + ('statement -> switch_statement','statement',1,'p_statement','es5.py',196), + ('statement -> labelled_statement','statement',1,'p_statement','es5.py',197), + ('statement -> throw_statement','statement',1,'p_statement','es5.py',198), + ('statement -> try_statement','statement',1,'p_statement','es5.py',199), + ('statement -> debugger_statement','statement',1,'p_statement','es5.py',200), + ('statement -> function_declaration','statement',1,'p_statement','es5.py',201), + ('block -> LBRACE source_elements RBRACE','block',3,'p_block','es5.py',208), + ('literal -> null_literal','literal',1,'p_literal','es5.py',213), + ('literal -> boolean_literal','literal',1,'p_literal','es5.py',214), + ('literal -> numeric_literal','literal',1,'p_literal','es5.py',215), + ('literal -> string_literal','literal',1,'p_literal','es5.py',216), + ('literal -> regex_literal','literal',1,'p_literal','es5.py',217), + ('boolean_literal -> TRUE','boolean_literal',1,'p_boolean_literal','es5.py',222), + ('boolean_literal -> FALSE','boolean_literal',1,'p_boolean_literal','es5.py',223), + ('null_literal -> NULL','null_literal',1,'p_null_literal','es5.py',229), + ('numeric_literal -> NUMBER','numeric_literal',1,'p_numeric_literal','es5.py',234), + ('string_literal -> STRING','string_literal',1,'p_string_literal','es5.py',239), + ('regex_literal -> REGEX','regex_literal',1,'p_regex_literal','es5.py',244), + ('identifier -> ID','identifier',1,'p_identifier','es5.py',249), + ('reserved_word -> BREAK','reserved_word',1,'p_reserved_word','es5.py',256), + ('reserved_word -> CASE','reserved_word',1,'p_reserved_word','es5.py',257), + ('reserved_word -> CATCH','reserved_word',1,'p_reserved_word','es5.py',258), + ('reserved_word -> CONTINUE','reserved_word',1,'p_reserved_word','es5.py',259), + ('reserved_word -> DEBUGGER','reserved_word',1,'p_reserved_word','es5.py',260), + ('reserved_word -> DEFAULT','reserved_word',1,'p_reserved_word','es5.py',261), + ('reserved_word -> DELETE','reserved_word',1,'p_reserved_word','es5.py',262), + ('reserved_word -> DO','reserved_word',1,'p_reserved_word','es5.py',263), + ('reserved_word -> ELSE','reserved_word',1,'p_reserved_word','es5.py',264), + ('reserved_word -> FINALLY','reserved_word',1,'p_reserved_word','es5.py',265), + ('reserved_word -> FOR','reserved_word',1,'p_reserved_word','es5.py',266), + ('reserved_word -> FUNCTION','reserved_word',1,'p_reserved_word','es5.py',267), + ('reserved_word -> IF','reserved_word',1,'p_reserved_word','es5.py',268), + ('reserved_word -> IN','reserved_word',1,'p_reserved_word','es5.py',269), + ('reserved_word -> INSTANCEOF','reserved_word',1,'p_reserved_word','es5.py',270), + ('reserved_word -> NEW','reserved_word',1,'p_reserved_word','es5.py',271), + ('reserved_word -> RETURN','reserved_word',1,'p_reserved_word','es5.py',272), + ('reserved_word -> SWITCH','reserved_word',1,'p_reserved_word','es5.py',273), + ('reserved_word -> THIS','reserved_word',1,'p_reserved_word','es5.py',274), + ('reserved_word -> THROW','reserved_word',1,'p_reserved_word','es5.py',275), + ('reserved_word -> TRY','reserved_word',1,'p_reserved_word','es5.py',276), + ('reserved_word -> TYPEOF','reserved_word',1,'p_reserved_word','es5.py',277), + ('reserved_word -> VAR','reserved_word',1,'p_reserved_word','es5.py',278), + ('reserved_word -> VOID','reserved_word',1,'p_reserved_word','es5.py',279), + ('reserved_word -> WHILE','reserved_word',1,'p_reserved_word','es5.py',280), + ('reserved_word -> WITH','reserved_word',1,'p_reserved_word','es5.py',281), + ('reserved_word -> NULL','reserved_word',1,'p_reserved_word','es5.py',282), + ('reserved_word -> TRUE','reserved_word',1,'p_reserved_word','es5.py',283), + ('reserved_word -> FALSE','reserved_word',1,'p_reserved_word','es5.py',284), + ('reserved_word -> CLASS','reserved_word',1,'p_reserved_word','es5.py',285), + ('reserved_word -> CONST','reserved_word',1,'p_reserved_word','es5.py',286), + ('reserved_word -> ENUM','reserved_word',1,'p_reserved_word','es5.py',287), + ('reserved_word -> EXPORT','reserved_word',1,'p_reserved_word','es5.py',288), + ('reserved_word -> EXTENDS','reserved_word',1,'p_reserved_word','es5.py',289), + ('reserved_word -> IMPORT','reserved_word',1,'p_reserved_word','es5.py',290), + ('reserved_word -> SUPER','reserved_word',1,'p_reserved_word','es5.py',291), + ('identifier_name -> identifier','identifier_name',1,'p_identifier_name','es5.py',297), + ('identifier_name -> reserved_word','identifier_name',1,'p_identifier_name','es5.py',298), + ('primary_expr -> primary_expr_no_brace','primary_expr',1,'p_primary_expr','es5.py',306), + ('primary_expr -> object_literal','primary_expr',1,'p_primary_expr','es5.py',307), + ('primary_expr_no_brace -> identifier','primary_expr_no_brace',1,'p_primary_expr_no_brace_1','es5.py',312), + ('primary_expr_no_brace -> THIS','primary_expr_no_brace',1,'p_primary_expr_no_brace_2','es5.py',316), + ('primary_expr_no_brace -> literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',321), + ('primary_expr_no_brace -> array_literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',322), + ('primary_expr_no_brace -> LPAREN expr RPAREN','primary_expr_no_brace',3,'p_primary_expr_no_brace_4','es5.py',327), + ('array_literal -> LBRACKET elision_opt RBRACKET','array_literal',3,'p_array_literal_1','es5.py',336), + ('array_literal -> LBRACKET element_list RBRACKET','array_literal',3,'p_array_literal_2','es5.py',341), + ('array_literal -> LBRACKET element_list COMMA elision_opt RBRACKET','array_literal',5,'p_array_literal_2','es5.py',342), + ('element_list -> elision_opt assignment_expr','element_list',2,'p_element_list','es5.py',351), + ('element_list -> element_list COMMA elision_opt assignment_expr','element_list',4,'p_element_list','es5.py',352), + ('elision_opt -> empty','elision_opt',1,'p_elision_opt_1','es5.py',362), + ('elision_opt -> elision','elision_opt',1,'p_elision_opt_2','es5.py',366), + ('elision -> COMMA','elision',1,'p_elision','es5.py',370), + ('elision -> elision COMMA','elision',2,'p_elision','es5.py',371), + ('object_literal -> LBRACE RBRACE','object_literal',2,'p_object_literal','es5.py',387), + ('object_literal -> LBRACE property_list RBRACE','object_literal',3,'p_object_literal','es5.py',388), + ('object_literal -> LBRACE property_list COMMA RBRACE','object_literal',4,'p_object_literal','es5.py',389), + ('property_list -> property_assignment','property_list',1,'p_property_list','es5.py',398), + ('property_list -> property_list COMMA property_assignment','property_list',3,'p_property_list','es5.py',399), + ('property_assignment -> property_name COLON assignment_expr','property_assignment',3,'p_property_assignment','es5.py',409), + ('property_assignment -> GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE','property_assignment',7,'p_property_assignment','es5.py',410), + ('property_assignment -> SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE','property_assignment',8,'p_property_assignment','es5.py',411), + ('identifier_name_string -> identifier_name','identifier_name_string',1,'p_identifier_name_string','es5.py',432), + ('property_name -> identifier_name_string','property_name',1,'p_property_name','es5.py',441), + ('property_name -> string_literal','property_name',1,'p_property_name','es5.py',442), + ('property_name -> numeric_literal','property_name',1,'p_property_name','es5.py',443), + ('property_set_parameter_list -> identifier','property_set_parameter_list',1,'p_property_set_parameter_list','es5.py',448), + ('member_expr -> primary_expr','member_expr',1,'p_member_expr','es5.py',457), + ('member_expr -> function_expr','member_expr',1,'p_member_expr','es5.py',458), + ('member_expr -> member_expr LBRACKET expr RBRACKET','member_expr',4,'p_member_expr','es5.py',459), + ('member_expr -> member_expr PERIOD identifier_name_string','member_expr',3,'p_member_expr','es5.py',460), + ('member_expr -> NEW member_expr arguments','member_expr',3,'p_member_expr','es5.py',461), + ('member_expr_nobf -> primary_expr_no_brace','member_expr_nobf',1,'p_member_expr_nobf','es5.py',478), + ('member_expr_nobf -> function_expr','member_expr_nobf',1,'p_member_expr_nobf','es5.py',479), + ('member_expr_nobf -> member_expr_nobf LBRACKET expr RBRACKET','member_expr_nobf',4,'p_member_expr_nobf','es5.py',480), + ('member_expr_nobf -> member_expr_nobf PERIOD identifier_name_string','member_expr_nobf',3,'p_member_expr_nobf','es5.py',481), + ('member_expr_nobf -> NEW member_expr arguments','member_expr_nobf',3,'p_member_expr_nobf','es5.py',482), + ('new_expr -> member_expr','new_expr',1,'p_new_expr','es5.py',499), + ('new_expr -> NEW new_expr','new_expr',2,'p_new_expr','es5.py',500), + ('new_expr_nobf -> member_expr_nobf','new_expr_nobf',1,'p_new_expr_nobf','es5.py',509), + ('new_expr_nobf -> NEW new_expr','new_expr_nobf',2,'p_new_expr_nobf','es5.py',510), + ('call_expr -> member_expr arguments','call_expr',2,'p_call_expr','es5.py',519), + ('call_expr -> call_expr arguments','call_expr',2,'p_call_expr','es5.py',520), + ('call_expr -> call_expr LBRACKET expr RBRACKET','call_expr',4,'p_call_expr','es5.py',521), + ('call_expr -> call_expr PERIOD identifier_name_string','call_expr',3,'p_call_expr','es5.py',522), + ('call_expr_nobf -> member_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',535), + ('call_expr_nobf -> call_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',536), + ('call_expr_nobf -> call_expr_nobf LBRACKET expr RBRACKET','call_expr_nobf',4,'p_call_expr_nobf','es5.py',537), + ('call_expr_nobf -> call_expr_nobf PERIOD identifier_name_string','call_expr_nobf',3,'p_call_expr_nobf','es5.py',538), + ('arguments -> LPAREN RPAREN','arguments',2,'p_arguments','es5.py',551), + ('arguments -> LPAREN argument_list RPAREN','arguments',3,'p_arguments','es5.py',552), + ('argument_list -> assignment_expr','argument_list',1,'p_argument_list','es5.py',561), + ('argument_list -> argument_list COMMA assignment_expr','argument_list',3,'p_argument_list','es5.py',562), + ('left_hand_side_expr -> new_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',571), + ('left_hand_side_expr -> call_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',572), + ('left_hand_side_expr_nobf -> new_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',577), + ('left_hand_side_expr_nobf -> call_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',578), + ('postfix_expr -> left_hand_side_expr','postfix_expr',1,'p_postfix_expr','es5.py',584), + ('postfix_expr -> left_hand_side_expr PLUSPLUS','postfix_expr',2,'p_postfix_expr','es5.py',585), + ('postfix_expr -> left_hand_side_expr MINUSMINUS','postfix_expr',2,'p_postfix_expr','es5.py',586), + ('postfix_expr_nobf -> left_hand_side_expr_nobf','postfix_expr_nobf',1,'p_postfix_expr_nobf','es5.py',595), + ('postfix_expr_nobf -> left_hand_side_expr_nobf PLUSPLUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',596), + ('postfix_expr_nobf -> left_hand_side_expr_nobf MINUSMINUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',597), + ('unary_expr -> postfix_expr','unary_expr',1,'p_unary_expr','es5.py',607), + ('unary_expr -> unary_expr_common','unary_expr',1,'p_unary_expr','es5.py',608), + ('unary_expr_nobf -> postfix_expr_nobf','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',613), + ('unary_expr_nobf -> unary_expr_common','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',614), + ('unary_expr_common -> DELETE unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',619), + ('unary_expr_common -> VOID unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',620), + ('unary_expr_common -> TYPEOF unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',621), + ('unary_expr_common -> PLUSPLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',622), + ('unary_expr_common -> MINUSMINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',623), + ('unary_expr_common -> PLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',624), + ('unary_expr_common -> MINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',625), + ('unary_expr_common -> BNOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',626), + ('unary_expr_common -> NOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',627), + ('multiplicative_expr -> unary_expr','multiplicative_expr',1,'p_multiplicative_expr','es5.py',634), + ('multiplicative_expr -> multiplicative_expr MULT unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',635), + ('multiplicative_expr -> multiplicative_expr DIV unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',636), + ('multiplicative_expr -> multiplicative_expr MOD unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',637), + ('multiplicative_expr_nobf -> unary_expr_nobf','multiplicative_expr_nobf',1,'p_multiplicative_expr_nobf','es5.py',646), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MULT unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',647), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf DIV unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',648), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MOD unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',649), + ('additive_expr -> multiplicative_expr','additive_expr',1,'p_additive_expr','es5.py',659), + ('additive_expr -> additive_expr PLUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',660), + ('additive_expr -> additive_expr MINUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',661), + ('additive_expr_nobf -> multiplicative_expr_nobf','additive_expr_nobf',1,'p_additive_expr_nobf','es5.py',670), + ('additive_expr_nobf -> additive_expr_nobf PLUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',671), + ('additive_expr_nobf -> additive_expr_nobf MINUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',672), + ('shift_expr -> additive_expr','shift_expr',1,'p_shift_expr','es5.py',682), + ('shift_expr -> shift_expr LSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',683), + ('shift_expr -> shift_expr RSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',684), + ('shift_expr -> shift_expr URSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',685), + ('shift_expr_nobf -> additive_expr_nobf','shift_expr_nobf',1,'p_shift_expr_nobf','es5.py',694), + ('shift_expr_nobf -> shift_expr_nobf LSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',695), + ('shift_expr_nobf -> shift_expr_nobf RSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',696), + ('shift_expr_nobf -> shift_expr_nobf URSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',697), + ('relational_expr -> shift_expr','relational_expr',1,'p_relational_expr','es5.py',707), + ('relational_expr -> relational_expr LT shift_expr','relational_expr',3,'p_relational_expr','es5.py',708), + ('relational_expr -> relational_expr GT shift_expr','relational_expr',3,'p_relational_expr','es5.py',709), + ('relational_expr -> relational_expr LE shift_expr','relational_expr',3,'p_relational_expr','es5.py',710), + ('relational_expr -> relational_expr GE shift_expr','relational_expr',3,'p_relational_expr','es5.py',711), + ('relational_expr -> relational_expr INSTANCEOF shift_expr','relational_expr',3,'p_relational_expr','es5.py',712), + ('relational_expr -> relational_expr IN shift_expr','relational_expr',3,'p_relational_expr','es5.py',713), + ('relational_expr_noin -> shift_expr','relational_expr_noin',1,'p_relational_expr_noin','es5.py',722), + ('relational_expr_noin -> relational_expr_noin LT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',723), + ('relational_expr_noin -> relational_expr_noin GT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',724), + ('relational_expr_noin -> relational_expr_noin LE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',725), + ('relational_expr_noin -> relational_expr_noin GE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',726), + ('relational_expr_noin -> relational_expr_noin INSTANCEOF shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',727), + ('relational_expr_nobf -> shift_expr_nobf','relational_expr_nobf',1,'p_relational_expr_nobf','es5.py',736), + ('relational_expr_nobf -> relational_expr_nobf LT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',737), + ('relational_expr_nobf -> relational_expr_nobf GT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',738), + ('relational_expr_nobf -> relational_expr_nobf LE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',739), + ('relational_expr_nobf -> relational_expr_nobf GE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',740), + ('relational_expr_nobf -> relational_expr_nobf INSTANCEOF shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',741), + ('relational_expr_nobf -> relational_expr_nobf IN shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',742), + ('equality_expr -> relational_expr','equality_expr',1,'p_equality_expr','es5.py',752), + ('equality_expr -> equality_expr EQEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',753), + ('equality_expr -> equality_expr NE relational_expr','equality_expr',3,'p_equality_expr','es5.py',754), + ('equality_expr -> equality_expr STREQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',755), + ('equality_expr -> equality_expr STRNEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',756), + ('equality_expr_noin -> relational_expr_noin','equality_expr_noin',1,'p_equality_expr_noin','es5.py',765), + ('equality_expr_noin -> equality_expr_noin EQEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',766), + ('equality_expr_noin -> equality_expr_noin NE relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',767), + ('equality_expr_noin -> equality_expr_noin STREQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',768), + ('equality_expr_noin -> equality_expr_noin STRNEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',769), + ('equality_expr_nobf -> relational_expr_nobf','equality_expr_nobf',1,'p_equality_expr_nobf','es5.py',778), + ('equality_expr_nobf -> equality_expr_nobf EQEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',779), + ('equality_expr_nobf -> equality_expr_nobf NE relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',780), + ('equality_expr_nobf -> equality_expr_nobf STREQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',781), + ('equality_expr_nobf -> equality_expr_nobf STRNEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',782), + ('bitwise_and_expr -> equality_expr','bitwise_and_expr',1,'p_bitwise_and_expr','es5.py',792), + ('bitwise_and_expr -> bitwise_and_expr BAND equality_expr','bitwise_and_expr',3,'p_bitwise_and_expr','es5.py',793), + ('bitwise_and_expr_noin -> equality_expr_noin','bitwise_and_expr_noin',1,'p_bitwise_and_expr_noin','es5.py',802), + ('bitwise_and_expr_noin -> bitwise_and_expr_noin BAND equality_expr_noin','bitwise_and_expr_noin',3,'p_bitwise_and_expr_noin','es5.py',803), + ('bitwise_and_expr_nobf -> equality_expr_nobf','bitwise_and_expr_nobf',1,'p_bitwise_and_expr_nobf','es5.py',813), + ('bitwise_and_expr_nobf -> bitwise_and_expr_nobf BAND equality_expr_nobf','bitwise_and_expr_nobf',3,'p_bitwise_and_expr_nobf','es5.py',814), + ('bitwise_xor_expr -> bitwise_and_expr','bitwise_xor_expr',1,'p_bitwise_xor_expr','es5.py',824), + ('bitwise_xor_expr -> bitwise_xor_expr BXOR bitwise_and_expr','bitwise_xor_expr',3,'p_bitwise_xor_expr','es5.py',825), + ('bitwise_xor_expr_noin -> bitwise_and_expr_noin','bitwise_xor_expr_noin',1,'p_bitwise_xor_expr_noin','es5.py',835), + ('bitwise_xor_expr_noin -> bitwise_xor_expr_noin BXOR bitwise_and_expr_noin','bitwise_xor_expr_noin',3,'p_bitwise_xor_expr_noin','es5.py',836), + ('bitwise_xor_expr_nobf -> bitwise_and_expr_nobf','bitwise_xor_expr_nobf',1,'p_bitwise_xor_expr_nobf','es5.py',847), + ('bitwise_xor_expr_nobf -> bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf','bitwise_xor_expr_nobf',3,'p_bitwise_xor_expr_nobf','es5.py',848), + ('bitwise_or_expr -> bitwise_xor_expr','bitwise_or_expr',1,'p_bitwise_or_expr','es5.py',858), + ('bitwise_or_expr -> bitwise_or_expr BOR bitwise_xor_expr','bitwise_or_expr',3,'p_bitwise_or_expr','es5.py',859), + ('bitwise_or_expr_noin -> bitwise_xor_expr_noin','bitwise_or_expr_noin',1,'p_bitwise_or_expr_noin','es5.py',869), + ('bitwise_or_expr_noin -> bitwise_or_expr_noin BOR bitwise_xor_expr_noin','bitwise_or_expr_noin',3,'p_bitwise_or_expr_noin','es5.py',870), + ('bitwise_or_expr_nobf -> bitwise_xor_expr_nobf','bitwise_or_expr_nobf',1,'p_bitwise_or_expr_nobf','es5.py',881), + ('bitwise_or_expr_nobf -> bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf','bitwise_or_expr_nobf',3,'p_bitwise_or_expr_nobf','es5.py',882), + ('logical_and_expr -> bitwise_or_expr','logical_and_expr',1,'p_logical_and_expr','es5.py',893), + ('logical_and_expr -> logical_and_expr AND bitwise_or_expr','logical_and_expr',3,'p_logical_and_expr','es5.py',894), + ('logical_and_expr_noin -> bitwise_or_expr_noin','logical_and_expr_noin',1,'p_logical_and_expr_noin','es5.py',904), + ('logical_and_expr_noin -> logical_and_expr_noin AND bitwise_or_expr_noin','logical_and_expr_noin',3,'p_logical_and_expr_noin','es5.py',905), + ('logical_and_expr_nobf -> bitwise_or_expr_nobf','logical_and_expr_nobf',1,'p_logical_and_expr_nobf','es5.py',915), + ('logical_and_expr_nobf -> logical_and_expr_nobf AND bitwise_or_expr_nobf','logical_and_expr_nobf',3,'p_logical_and_expr_nobf','es5.py',916), + ('logical_or_expr -> logical_and_expr','logical_or_expr',1,'p_logical_or_expr','es5.py',925), + ('logical_or_expr -> logical_or_expr OR logical_and_expr','logical_or_expr',3,'p_logical_or_expr','es5.py',926), + ('logical_or_expr_noin -> logical_and_expr_noin','logical_or_expr_noin',1,'p_logical_or_expr_noin','es5.py',935), + ('logical_or_expr_noin -> logical_or_expr_noin OR logical_and_expr_noin','logical_or_expr_noin',3,'p_logical_or_expr_noin','es5.py',936), + ('logical_or_expr_nobf -> logical_and_expr_nobf','logical_or_expr_nobf',1,'p_logical_or_expr_nobf','es5.py',945), + ('logical_or_expr_nobf -> logical_or_expr_nobf OR logical_and_expr_nobf','logical_or_expr_nobf',3,'p_logical_or_expr_nobf','es5.py',946), + ('conditional_expr -> logical_or_expr','conditional_expr',1,'p_conditional_expr','es5.py',957), + ('conditional_expr -> logical_or_expr CONDOP assignment_expr COLON assignment_expr','conditional_expr',5,'p_conditional_expr','es5.py',958), + ('conditional_expr_noin -> logical_or_expr_noin','conditional_expr_noin',1,'p_conditional_expr_noin','es5.py',970), + ('conditional_expr_noin -> logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin','conditional_expr_noin',5,'p_conditional_expr_noin','es5.py',971), + ('conditional_expr_nobf -> logical_or_expr_nobf','conditional_expr_nobf',1,'p_conditional_expr_nobf','es5.py',984), + ('conditional_expr_nobf -> logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr','conditional_expr_nobf',5,'p_conditional_expr_nobf','es5.py',985), + ('assignment_expr -> conditional_expr','assignment_expr',1,'p_assignment_expr','es5.py',998), + ('assignment_expr -> left_hand_side_expr assignment_operator assignment_expr','assignment_expr',3,'p_assignment_expr','es5.py',999), + ('assignment_expr_noin -> conditional_expr_noin','assignment_expr_noin',1,'p_assignment_expr_noin','es5.py',1010), + ('assignment_expr_noin -> left_hand_side_expr assignment_operator assignment_expr_noin','assignment_expr_noin',3,'p_assignment_expr_noin','es5.py',1011), + ('assignment_expr_nobf -> conditional_expr_nobf','assignment_expr_nobf',1,'p_assignment_expr_nobf','es5.py',1022), + ('assignment_expr_nobf -> left_hand_side_expr_nobf assignment_operator assignment_expr','assignment_expr_nobf',3,'p_assignment_expr_nobf','es5.py',1023), + ('assignment_operator -> EQ','assignment_operator',1,'p_assignment_operator','es5.py',1033), + ('assignment_operator -> MULTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1034), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1035), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1036), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1037), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1038), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1039), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1040), + ('assignment_operator -> URSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1041), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1042), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1043), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1044), + ('expr -> assignment_expr','expr',1,'p_expr','es5.py',1050), + ('expr -> expr COMMA assignment_expr','expr',3,'p_expr','es5.py',1051), + ('expr_noin -> assignment_expr_noin','expr_noin',1,'p_expr_noin','es5.py',1060), + ('expr_noin -> expr_noin COMMA assignment_expr_noin','expr_noin',3,'p_expr_noin','es5.py',1061), + ('expr_nobf -> assignment_expr_nobf','expr_nobf',1,'p_expr_nobf','es5.py',1070), + ('expr_nobf -> expr_nobf COMMA assignment_expr','expr_nobf',3,'p_expr_nobf','es5.py',1071), + ('variable_statement -> VAR variable_declaration_list SEMI','variable_statement',3,'p_variable_statement','es5.py',1081), + ('variable_statement -> VAR variable_declaration_list AUTOSEMI','variable_statement',3,'p_variable_statement','es5.py',1082), + ('variable_declaration_list -> variable_declaration','variable_declaration_list',1,'p_variable_declaration_list','es5.py',1089), + ('variable_declaration_list -> variable_declaration_list COMMA variable_declaration','variable_declaration_list',3,'p_variable_declaration_list','es5.py',1090), + ('variable_declaration_list_noin -> variable_declaration_noin','variable_declaration_list_noin',1,'p_variable_declaration_list_noin','es5.py',1101), + ('variable_declaration_list_noin -> variable_declaration_list_noin COMMA variable_declaration_noin','variable_declaration_list_noin',3,'p_variable_declaration_list_noin','es5.py',1102), + ('variable_declaration -> identifier','variable_declaration',1,'p_variable_declaration','es5.py',1112), + ('variable_declaration -> identifier initializer','variable_declaration',2,'p_variable_declaration','es5.py',1113), + ('variable_declaration_noin -> identifier','variable_declaration_noin',1,'p_variable_declaration_noin','es5.py',1123), + ('variable_declaration_noin -> identifier initializer_noin','variable_declaration_noin',2,'p_variable_declaration_noin','es5.py',1124), + ('initializer -> EQ assignment_expr','initializer',2,'p_initializer','es5.py',1134), + ('initializer_noin -> EQ assignment_expr_noin','initializer_noin',2,'p_initializer_noin','es5.py',1138), + ('empty_statement -> SEMI','empty_statement',1,'p_empty_statement','es5.py',1143), + ('expr_statement -> expr_nobf SEMI','expr_statement',2,'p_expr_statement','es5.py',1149), + ('expr_statement -> expr_nobf AUTOSEMI','expr_statement',2,'p_expr_statement','es5.py',1150), + ('if_statement -> IF LPAREN expr RPAREN statement','if_statement',5,'p_if_statement_1','es5.py',1173), + ('if_statement -> IF LPAREN expr RPAREN statement ELSE statement','if_statement',7,'p_if_statement_2','es5.py',1178), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN SEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1186), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN AUTOSEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1187), + ('iteration_statement -> WHILE LPAREN expr RPAREN statement','iteration_statement',5,'p_iteration_statement_2','es5.py',1194), + ('iteration_statement -> FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','es5.py',1200), + ('iteration_statement -> FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',10,'p_iteration_statement_3','es5.py',1201), + ('iteration_statement -> FOR LPAREN left_hand_side_expr IN expr RPAREN statement','iteration_statement',7,'p_iteration_statement_4','es5.py',1233), + ('iteration_statement -> FOR LPAREN VAR identifier IN expr RPAREN statement','iteration_statement',8,'p_iteration_statement_5','es5.py',1241), + ('iteration_statement -> FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement','iteration_statement',9,'p_iteration_statement_6','es5.py',1251), + ('expr_opt -> empty','expr_opt',1,'p_expr_opt','es5.py',1261), + ('expr_opt -> expr','expr_opt',1,'p_expr_opt','es5.py',1262), + ('expr_noin_opt -> empty','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1267), + ('expr_noin_opt -> expr_noin','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1268), + ('continue_statement -> CONTINUE SEMI','continue_statement',2,'p_continue_statement_1','es5.py',1274), + ('continue_statement -> CONTINUE AUTOSEMI','continue_statement',2,'p_continue_statement_1','es5.py',1275), + ('continue_statement -> CONTINUE identifier SEMI','continue_statement',3,'p_continue_statement_2','es5.py',1281), + ('continue_statement -> CONTINUE identifier AUTOSEMI','continue_statement',3,'p_continue_statement_2','es5.py',1282), + ('break_statement -> BREAK SEMI','break_statement',2,'p_break_statement_1','es5.py',1289), + ('break_statement -> BREAK AUTOSEMI','break_statement',2,'p_break_statement_1','es5.py',1290), + ('break_statement -> BREAK identifier SEMI','break_statement',3,'p_break_statement_2','es5.py',1296), + ('break_statement -> BREAK identifier AUTOSEMI','break_statement',3,'p_break_statement_2','es5.py',1297), + ('return_statement -> RETURN SEMI','return_statement',2,'p_return_statement_1','es5.py',1304), + ('return_statement -> RETURN AUTOSEMI','return_statement',2,'p_return_statement_1','es5.py',1305), + ('return_statement -> RETURN expr SEMI','return_statement',3,'p_return_statement_2','es5.py',1311), + ('return_statement -> RETURN expr AUTOSEMI','return_statement',3,'p_return_statement_2','es5.py',1312), + ('with_statement -> WITH LPAREN expr RPAREN statement','with_statement',5,'p_with_statement','es5.py',1319), + ('switch_statement -> SWITCH LPAREN expr RPAREN case_block','switch_statement',5,'p_switch_statement','es5.py',1325), + ('case_block -> LBRACE case_clauses_opt RBRACE','case_block',3,'p_case_block','es5.py',1335), + ('case_block -> LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE','case_block',5,'p_case_block','es5.py',1336), + ('case_clauses_opt -> empty','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1350), + ('case_clauses_opt -> case_clauses','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1351), + ('case_clauses -> case_clause','case_clauses',1,'p_case_clauses','es5.py',1356), + ('case_clauses -> case_clauses case_clause','case_clauses',2,'p_case_clauses','es5.py',1357), + ('case_clause -> CASE expr COLON source_elements','case_clause',4,'p_case_clause','es5.py',1366), + ('default_clause -> DEFAULT COLON source_elements','default_clause',3,'p_default_clause','es5.py',1371), + ('labelled_statement -> identifier COLON statement','labelled_statement',3,'p_labelled_statement','es5.py',1377), + ('throw_statement -> THROW expr SEMI','throw_statement',3,'p_throw_statement','es5.py',1383), + ('throw_statement -> THROW expr AUTOSEMI','throw_statement',3,'p_throw_statement','es5.py',1384), + ('try_statement -> TRY block catch','try_statement',3,'p_try_statement_1','es5.py',1391), + ('try_statement -> TRY block finally','try_statement',3,'p_try_statement_2','es5.py',1396), + ('try_statement -> TRY block catch finally','try_statement',4,'p_try_statement_3','es5.py',1401), + ('catch -> CATCH LPAREN identifier RPAREN block','catch',5,'p_catch','es5.py',1406), + ('finally -> FINALLY block','finally',2,'p_finally','es5.py',1411), + ('debugger_statement -> DEBUGGER SEMI','debugger_statement',2,'p_debugger_statement','es5.py',1417), + ('debugger_statement -> DEBUGGER AUTOSEMI','debugger_statement',2,'p_debugger_statement','es5.py',1418), + ('function_declaration -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_declaration',7,'p_function_declaration','es5.py',1426), + ('function_declaration -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_declaration',8,'p_function_declaration','es5.py',1427), + ('function_expr -> FUNCTION LPAREN RPAREN LBRACE function_body RBRACE','function_expr',6,'p_function_expr_1','es5.py',1441), + ('function_expr -> FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_1','es5.py',1442), + ('function_expr -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_2','es5.py',1456), + ('function_expr -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',8,'p_function_expr_2','es5.py',1457), + ('formal_parameter_list -> identifier','formal_parameter_list',1,'p_formal_parameter_list','es5.py',1470), + ('formal_parameter_list -> formal_parameter_list COMMA identifier','formal_parameter_list',3,'p_formal_parameter_list','es5.py',1471), + ('function_body -> source_elements','function_body',1,'p_function_body','es5.py',1480), +] diff --git a/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_8.py b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_8.py new file mode 100644 index 00000000..c0634af0 --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_8.py @@ -0,0 +1,369 @@ + +# yacctab_es5_py3_ply3_8.py +# This file is automatically generated. Do not edit. +_tabversion = '3.8' + +_lr_method = 'LALR' + +_lr_signature = '9825587DAB8F9D419DD9E432175955D6' + +_lr_action_items = {'$end':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,125,126,130,133,134,136,137,139,140,146,147,215,302,303,304,327,328,329,330,331,332,335,336,337,338,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-1,0,-2,-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-322,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-327,-329,-286,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'FUNCTION':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[23,23,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,109,23,-283,23,109,109,109,-1,109,109,109,109,109,109,109,109,109,-6,23,109,258,-284,-285,109,109,-24,109,109,-300,-301,-304,-305,-308,-309,109,109,-330,-331,109,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,109,109,109,258,109,109,109,258,109,-90,-88,-89,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-322,109,109,109,109,109,258,109,109,258,109,109,258,258,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-25,-271,-272,109,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,23,258,109,23,109,23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,23,-327,-329,109,109,109,23,23,109,-286,-290,109,109,109,-312,-313,23,23,23,109,109,23,109,109,-332,23,23,-287,-288,-289,109,23,-293,-314,-328,-333,23,23,-294,23,23,23,-291,23,-295,-315,-292,]),'LBRACE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,40,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,166,168,171,175,177,178,179,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,212,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,340,357,358,380,382,383,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,453,454,457,459,460,461,464,466,469,476,478,482,484,486,506,507,515,519,520,521,524,526,531,533,534,539,540,541,545,546,547,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[26,26,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,110,26,-283,26,110,110,26,110,-1,110,110,110,110,110,110,110,110,110,-6,26,110,-284,-285,110,110,-24,110,110,-300,-301,-304,-305,-308,-309,110,110,-330,-331,110,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,110,110,110,110,110,-90,-88,-89,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,382,-322,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-25,-271,-272,110,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,26,-1,-91,460,26,464,110,26,110,26,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,26,508,-327,-329,110,110,110,26,515,26,110,519,-286,-290,110,110,110,-312,-313,26,26,545,546,26,110,110,26,110,110,26,-332,26,26,568,-287,-288,-289,110,26,-293,-314,-328,-333,26,26,-294,26,26,26,-291,26,-295,-315,-292,]),'VAR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,132,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[27,27,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,27,-283,27,-6,27,269,-284,-285,-24,313,-300,-301,-304,-305,-308,-309,-330,-331,269,269,-322,269,269,269,269,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,27,269,27,27,27,-327,-329,27,27,-286,-290,-312,-313,27,27,27,27,-332,27,27,-287,-288,-289,27,-293,-314,-328,-333,27,27,-294,27,27,27,-291,27,-295,-315,-292,]),'SEMI':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,28,29,31,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,89,92,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,125,126,130,132,133,134,135,136,137,138,139,140,141,144,146,147,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,306,308,312,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,335,336,337,338,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,382,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,429,430,449,451,453,455,456,458,460,464,467,468,471,476,478,479,480,481,482,485,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,510,512,515,516,518,519,524,525,527,528,529,532,533,541,543,545,546,548,549,550,553,554,556,557,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[28,28,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,28,-283,125,28,133,136,139,146,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-6,28,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,303,-273,-277,-284,-285,-24,-1,-300,-301,327,-304,-305,329,-308,-309,331,335,-330,-331,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-278,-270,427,-135,-298,-299,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,28,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,28,28,-1,482,-279,-275,28,-327,-329,-125,-128,-112,28,28,-121,-107,-94,-286,-290,526,-296,-297,-1,-280,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-312,-313,-246,-85,28,-334,-242,28,28,549,552,-276,-279,-282,28,-332,-335,28,28,-287,-288,-289,-280,28,-293,-244,-314,-328,-333,-336,28,28,-294,28,28,28,-337,-291,28,-295,-315,-292,]),'IF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[30,30,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,30,-283,30,-6,30,259,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,259,259,-322,259,259,259,259,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,30,259,30,30,30,-327,-329,30,30,-286,-290,-312,-313,30,30,30,30,-332,30,30,-287,-288,-289,30,-293,-314,-328,-333,30,30,-294,30,30,30,-291,30,-295,-315,-292,]),'DO':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[31,31,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,-283,31,-6,31,254,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,254,254,-322,254,254,254,254,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,31,254,31,31,31,-327,-329,31,31,-286,-290,-312,-313,31,31,31,31,-332,31,31,-287,-288,-289,31,-293,-314,-328,-333,31,31,-294,31,31,31,-291,31,-295,-315,-292,]),'WHILE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,129,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[32,32,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,32,-283,32,-6,32,271,-284,-285,310,-24,-300,-301,-304,-305,-308,-309,-330,-331,271,271,-322,271,271,271,271,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,32,271,32,32,32,-327,-329,32,32,-286,-290,-312,-313,32,32,32,32,-332,32,32,-287,-288,-289,32,-293,-314,-328,-333,32,32,-294,32,32,32,-291,32,-295,-315,-292,]),'FOR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[33,33,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,33,-283,33,-6,33,257,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,257,257,-322,257,257,257,257,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,33,257,33,33,33,-327,-329,33,33,-286,-290,-312,-313,33,33,33,33,-332,33,33,-287,-288,-289,33,-293,-314,-328,-333,33,33,-294,33,33,33,-291,33,-295,-315,-292,]),'CONTINUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[34,34,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,34,-283,34,-6,34,250,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,250,250,-322,250,250,250,250,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,34,250,34,34,34,-327,-329,34,34,-286,-290,-312,-313,34,34,34,34,-332,34,34,-287,-288,-289,34,-293,-314,-328,-333,34,34,-294,34,34,34,-291,34,-295,-315,-292,]),'BREAK':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[35,35,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,35,-283,35,-6,35,247,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,247,247,-322,247,247,247,247,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,35,247,35,35,35,-327,-329,35,35,-286,-290,-312,-313,35,35,35,35,-332,35,35,-287,-288,-289,35,-293,-314,-328,-333,35,35,-294,35,35,35,-291,35,-295,-315,-292,]),'RETURN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[36,36,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,36,-283,36,-6,36,263,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,263,263,-322,263,263,263,263,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,36,263,36,36,36,-327,-329,36,36,-286,-290,-312,-313,36,36,36,36,-332,36,36,-287,-288,-289,36,-293,-314,-328,-333,36,36,-294,36,36,36,-291,36,-295,-315,-292,]),'WITH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[37,37,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,37,-283,37,-6,37,272,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,272,272,-322,272,272,272,272,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,37,272,37,37,37,-327,-329,37,37,-286,-290,-312,-313,37,37,37,37,-332,37,37,-287,-288,-289,37,-293,-314,-328,-333,37,37,-294,37,37,37,-291,37,-295,-315,-292,]),'SWITCH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[38,38,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,38,-283,38,-6,38,264,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,264,264,-322,264,264,264,264,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,38,264,38,38,38,-327,-329,38,38,-286,-290,-312,-313,38,38,38,38,-332,38,38,-287,-288,-289,38,-293,-314,-328,-333,38,38,-294,38,38,38,-291,38,-295,-315,-292,]),'THROW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[39,39,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,39,-283,39,-6,39,266,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,266,266,-322,266,266,266,266,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,39,266,39,39,39,-327,-329,39,39,-286,-290,-312,-313,39,39,39,39,-332,39,39,-287,-288,-289,39,-293,-314,-328,-333,39,39,-294,39,39,39,-291,39,-295,-315,-292,]),'TRY':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[40,40,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,40,-283,40,-6,40,267,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,267,267,-322,267,267,267,267,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,40,267,40,40,40,-327,-329,40,40,-286,-290,-312,-313,40,40,40,40,-332,40,40,-287,-288,-289,40,-293,-314,-328,-333,40,40,-294,40,40,40,-291,40,-295,-315,-292,]),'DEBUGGER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[41,41,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,41,-283,41,-6,41,251,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,251,251,-322,251,251,251,251,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,41,251,41,41,41,-327,-329,41,41,-286,-290,-312,-313,41,41,41,41,-332,41,41,-287,-288,-289,41,-293,-314,-328,-333,41,41,-294,41,41,41,-291,41,-295,-315,-292,]),'ID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,31,34,35,36,39,51,52,77,78,82,83,84,85,86,87,88,89,91,92,102,109,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,307,313,327,328,329,330,331,332,335,336,337,338,357,358,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,452,453,454,457,459,460,464,466,475,476,478,482,483,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[43,43,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,43,43,43,43,-283,43,43,43,43,43,43,-1,43,43,43,43,43,43,43,43,43,-6,43,43,43,43,43,-284,-285,43,43,-24,43,43,-300,-301,-304,-305,-308,-309,43,43,-330,-331,43,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,43,43,43,43,43,43,43,43,43,-90,-88,-89,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-322,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-25,-271,-272,43,43,43,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-327,43,-329,43,43,43,43,43,43,43,-286,-290,43,43,43,43,-312,-313,43,43,43,43,43,43,43,43,-332,43,43,-287,-288,-289,43,43,-293,-314,-328,-333,43,43,-294,43,43,43,-291,43,-295,-315,-292,]),'NEW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[51,51,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,102,51,-283,51,102,102,102,-1,102,102,102,102,102,102,102,102,102,-6,51,102,262,-284,-285,102,102,-24,102,102,-300,-301,-304,-305,-308,-309,102,102,-330,-331,102,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,102,51,102,262,102,51,102,262,102,-90,-88,-89,51,51,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-322,102,102,102,102,102,262,102,102,262,102,102,262,262,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-25,-271,-272,102,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,51,262,102,51,102,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,51,-327,-329,102,102,102,51,51,102,-286,-290,102,102,102,-312,-313,51,51,51,102,102,51,102,102,-332,51,51,-287,-288,-289,102,51,-293,-314,-328,-333,51,51,-294,51,51,51,-291,51,-295,-315,-292,]),'THIS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[57,57,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,57,57,-283,57,57,57,57,-1,57,57,57,57,57,57,57,57,57,-6,57,57,265,-284,-285,57,57,-24,57,57,-300,-301,-304,-305,-308,-309,57,57,-330,-331,57,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,57,57,57,265,57,57,57,265,57,-90,-88,-89,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-322,57,57,57,57,57,265,57,57,265,57,57,265,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-25,-271,-272,57,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,57,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-327,-329,57,57,57,57,57,57,-286,-290,57,57,57,-312,-313,57,57,57,57,57,57,57,57,-332,57,57,-287,-288,-289,57,57,-293,-314,-328,-333,57,57,-294,57,57,57,-291,57,-295,-315,-292,]),'LPAREN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,31,32,33,36,37,38,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,90,92,99,101,102,104,105,107,108,109,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,234,235,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,310,327,328,329,330,331,332,335,336,337,338,339,346,347,352,353,354,356,357,358,382,390,393,394,398,400,401,402,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[25,25,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,91,-78,25,25,-283,128,25,131,132,25,142,143,25,-37,168,168,25,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,25,25,25,25,25,25,25,25,25,-6,211,25,168,168,25,-105,-106,-76,-77,91,-78,-284,-285,25,25,-24,25,25,-300,-301,-304,-305,-308,-309,25,25,-330,-331,25,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,25,25,-124,25,25,25,-123,25,168,25,-90,-88,-89,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-322,-82,25,25,25,25,-120,25,25,-119,25,168,25,25,397,-92,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-25,-271,-272,25,425,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,452,-126,-127,-113,-114,-83,-84,-1,-91,25,-122,-108,-109,-93,25,474,475,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-327,-329,25,-125,-128,25,-112,25,25,25,25,-121,-107,-94,-286,-290,25,25,25,-312,-313,-85,25,-334,25,25,25,25,25,25,25,-332,-335,25,25,-287,-288,-289,25,25,-293,-314,-328,-333,-336,25,25,-294,25,25,25,-337,-291,25,-295,-315,-292,]),'LBRACKET':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,99,101,102,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[52,52,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,52,52,-283,52,52,52,-37,166,171,52,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,52,52,52,52,52,52,52,52,52,-6,52,224,228,52,-105,-106,-76,-77,-78,-284,-285,52,52,-24,52,52,-300,-301,-304,-305,-308,-309,52,52,-330,-331,52,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,52,52,-124,52,52,52,-123,52,228,52,-90,-88,-89,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-322,-82,52,52,52,52,-120,52,52,-119,52,228,52,52,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-25,-271,-272,52,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-126,-127,-113,-114,-83,-84,-1,-91,52,-122,-108,-109,-93,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-327,-329,52,-125,-128,52,-112,52,52,52,52,-121,-107,-94,-286,-290,52,52,52,-312,-313,-85,52,-334,52,52,52,52,52,52,52,-332,-335,52,52,-287,-288,-289,52,52,-293,-314,-328,-333,-336,52,52,-294,52,52,52,-337,-291,52,-295,-315,-292,]),'NULL':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[67,67,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,67,67,-283,67,67,67,67,-1,67,67,67,67,67,67,67,67,67,-6,67,67,273,-284,-285,67,67,-24,67,67,-300,-301,-304,-305,-308,-309,67,67,-330,-331,67,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,67,67,67,273,67,67,67,273,67,-90,-88,-89,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-322,67,67,67,67,67,273,67,67,273,67,67,273,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-25,-271,-272,67,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,67,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-327,-329,67,67,67,67,67,67,-286,-290,67,67,67,-312,-313,67,67,67,67,67,67,67,67,-332,67,67,-287,-288,-289,67,67,-293,-314,-328,-333,67,67,-294,67,67,67,-291,67,-295,-315,-292,]),'TRUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[68,68,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,68,68,-283,68,68,68,68,-1,68,68,68,68,68,68,68,68,68,-6,68,68,274,-284,-285,68,68,-24,68,68,-300,-301,-304,-305,-308,-309,68,68,-330,-331,68,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,68,68,68,274,68,68,68,274,68,-90,-88,-89,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-322,68,68,68,68,68,274,68,68,274,68,68,274,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-25,-271,-272,68,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,68,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-327,-329,68,68,68,68,68,68,-286,-290,68,68,68,-312,-313,68,68,68,68,68,68,68,68,-332,68,68,-287,-288,-289,68,68,-293,-314,-328,-333,68,68,-294,68,68,68,-291,68,-295,-315,-292,]),'FALSE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[69,69,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,69,69,-283,69,69,69,69,-1,69,69,69,69,69,69,69,69,69,-6,69,69,275,-284,-285,69,69,-24,69,69,-300,-301,-304,-305,-308,-309,69,69,-330,-331,69,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,69,69,69,275,69,69,69,275,69,-90,-88,-89,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-322,69,69,69,69,69,275,69,69,275,69,69,275,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-25,-271,-272,69,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,69,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-327,-329,69,69,69,69,69,69,-286,-290,69,69,69,-312,-313,69,69,69,69,69,69,69,69,-332,69,69,-287,-288,-289,69,69,-293,-314,-328,-333,69,69,-294,69,69,69,-291,69,-295,-315,-292,]),'NUMBER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[70,70,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,70,70,-283,70,70,70,70,-1,70,70,70,70,70,70,70,70,70,-6,70,70,70,-284,-285,70,70,-24,70,70,-300,-301,-304,-305,-308,-309,70,70,-330,-331,70,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,70,70,70,70,70,70,70,-90,-88,-89,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-322,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-25,-271,-272,70,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-327,-329,70,70,70,70,70,70,-286,-290,70,70,70,-312,-313,70,70,70,70,70,70,70,70,-332,70,70,-287,-288,-289,70,70,-293,-314,-328,-333,70,70,-294,70,70,70,-291,70,-295,-315,-292,]),'STRING':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[71,71,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,71,71,-283,71,71,71,71,-1,71,71,71,71,71,71,71,71,71,-6,71,71,71,-284,-285,71,71,-24,71,71,-300,-301,-304,-305,-308,-309,71,71,-330,-331,71,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,71,71,71,71,71,71,71,-90,-88,-89,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-322,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-25,-271,-272,71,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-327,-329,71,71,71,71,71,71,-286,-290,71,71,71,-312,-313,71,71,71,71,71,71,71,71,-332,71,71,-287,-288,-289,71,71,-293,-314,-328,-333,71,71,-294,71,71,71,-291,71,-295,-315,-292,]),'REGEX':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[72,72,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,72,72,-283,72,72,72,72,-1,72,72,72,72,72,72,72,72,72,-6,72,72,-284,-285,72,72,-24,72,72,-300,-301,-304,-305,-308,-309,72,72,-330,-331,72,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,72,72,72,72,72,72,72,-90,-88,-89,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-322,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-25,-271,-272,72,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-327,-329,72,72,72,72,72,72,-286,-290,72,72,72,-312,-313,72,72,72,72,72,72,72,72,-332,72,72,-287,-288,-289,72,72,-293,-314,-328,-333,72,72,-294,72,72,72,-291,72,-295,-315,-292,]),'DELETE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[84,84,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,84,84,-283,84,84,84,-1,84,84,84,84,84,84,84,84,84,-6,84,253,-284,-285,84,84,-24,84,84,-300,-301,-304,-305,-308,-309,84,84,-330,-331,84,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,84,84,84,253,84,84,84,253,84,-90,-88,-89,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-322,84,84,84,84,84,253,84,84,253,84,84,253,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-25,-271,-272,84,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,84,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-327,-329,84,84,84,84,84,84,-286,-290,84,84,84,-312,-313,84,84,84,84,84,84,84,84,-332,84,84,-287,-288,-289,84,84,-293,-314,-328,-333,84,84,-294,84,84,84,-291,84,-295,-315,-292,]),'VOID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[85,85,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,85,85,-283,85,85,85,-1,85,85,85,85,85,85,85,85,85,-6,85,270,-284,-285,85,85,-24,85,85,-300,-301,-304,-305,-308,-309,85,85,-330,-331,85,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,85,85,85,270,85,85,85,270,85,-90,-88,-89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-322,85,85,85,85,85,270,85,85,270,85,85,270,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-25,-271,-272,85,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,85,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-327,-329,85,85,85,85,85,85,-286,-290,85,85,85,-312,-313,85,85,85,85,85,85,85,85,-332,85,85,-287,-288,-289,85,85,-293,-314,-328,-333,85,85,-294,85,85,85,-291,85,-295,-315,-292,]),'TYPEOF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[86,86,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,86,86,-283,86,86,86,-1,86,86,86,86,86,86,86,86,86,-6,86,268,-284,-285,86,86,-24,86,86,-300,-301,-304,-305,-308,-309,86,86,-330,-331,86,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,86,86,86,268,86,86,86,268,86,-90,-88,-89,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-322,86,86,86,86,86,268,86,86,268,86,86,268,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-25,-271,-272,86,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,86,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-327,-329,86,86,86,86,86,86,-286,-290,86,86,86,-312,-313,86,86,86,86,86,86,86,86,-332,86,86,-287,-288,-289,86,86,-293,-314,-328,-333,86,86,-294,86,86,86,-291,86,-295,-315,-292,]),'PLUSPLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[82,82,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,82,82,-283,82,82,82,-37,149,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,82,82,82,82,82,82,82,82,82,-6,82,219,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,82,82,-24,82,82,-300,-301,-304,-305,-308,-309,82,82,-330,-331,82,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,82,82,-124,82,82,82,-123,82,-118,-115,82,-90,-88,-89,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,219,-322,-82,82,82,82,82,-120,82,82,-119,82,-116,-115,82,82,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-25,-271,-272,82,219,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,149,-126,-127,-113,-114,-83,-84,-1,-91,82,-122,-108,-109,-93,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-327,-329,82,-125,-128,82,-112,82,82,82,82,-121,-107,-94,-286,-290,82,82,82,219,-312,-313,-85,82,-334,82,82,82,82,82,82,82,-332,-335,82,82,-287,-288,-289,82,82,-293,-314,-328,-333,-336,82,82,-294,82,82,82,-337,-291,82,-295,-315,-292,]),'MINUSMINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[83,83,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,83,83,-283,83,83,83,-37,150,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,83,83,83,83,83,83,83,83,83,-6,83,220,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,83,83,-24,83,83,-300,-301,-304,-305,-308,-309,83,83,-330,-331,83,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,83,83,-124,83,83,83,-123,83,-118,-115,83,-90,-88,-89,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,220,-322,-82,83,83,83,83,-120,83,83,-119,83,-116,-115,83,83,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-25,-271,-272,83,220,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,150,-126,-127,-113,-114,-83,-84,-1,-91,83,-122,-108,-109,-93,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-327,-329,83,-125,-128,83,-112,83,83,83,83,-121,-107,-94,-286,-290,83,83,83,220,-312,-313,-85,83,-334,83,83,83,83,83,83,83,-332,-335,83,83,-287,-288,-289,83,83,-293,-314,-328,-333,-336,83,83,-294,83,83,83,-337,-291,83,-295,-315,-292,]),'PLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[77,77,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,77,77,-283,77,77,77,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,196,-165,77,77,-158,-143,-144,77,77,77,77,77,77,77,-6,77,-135,-131,-132,-115,-105,-106,-76,-77,-78,297,-162,-154,-141,-142,-284,-285,77,77,-24,77,77,-300,-301,-304,-305,-308,-309,77,77,-330,-331,77,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,77,77,-124,77,77,77,-123,77,-118,-115,77,-90,-88,-89,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,77,77,-136,-137,77,77,-120,77,77,-119,77,-116,-115,77,77,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-25,-271,-272,77,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,297,297,297,-166,-167,-159,-160,-161,77,-122,-108,-109,-93,77,297,297,297,-163,-164,-155,-156,-157,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-327,-329,77,-125,-128,77,-112,77,77,77,77,-121,-107,-94,-286,-290,77,77,77,-135,-312,-313,-85,77,-334,77,77,77,77,77,77,77,-332,-335,77,77,-287,-288,-289,77,77,-293,-314,-328,-333,-336,77,77,-294,77,77,77,-337,-291,77,-295,-315,-292,]),'MINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[78,78,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,78,78,-283,78,78,78,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,197,-165,78,78,-158,-143,-144,78,78,78,78,78,78,78,-6,78,-135,-131,-132,-115,-105,-106,-76,-77,-78,298,-162,-154,-141,-142,-284,-285,78,78,-24,78,78,-300,-301,-304,-305,-308,-309,78,78,-330,-331,78,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,78,78,-124,78,78,78,-123,78,-118,-115,78,-90,-88,-89,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,78,78,-136,-137,78,78,-120,78,78,-119,78,-116,-115,78,78,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-25,-271,-272,78,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,298,298,298,-166,-167,-159,-160,-161,78,-122,-108,-109,-93,78,298,298,298,-163,-164,-155,-156,-157,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-327,-329,78,-125,-128,78,-112,78,78,78,78,-121,-107,-94,-286,-290,78,78,78,-135,-312,-313,-85,78,-334,78,78,78,78,78,78,78,-332,-335,78,78,-287,-288,-289,78,78,-293,-314,-328,-333,-336,78,78,-294,78,78,78,-337,-291,78,-295,-315,-292,]),'BNOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[87,87,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,87,87,-283,87,87,87,-1,87,87,87,87,87,87,87,87,87,-6,87,-284,-285,87,87,-24,87,87,-300,-301,-304,-305,-308,-309,87,87,-330,-331,87,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,87,87,87,87,87,87,87,-90,-88,-89,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-322,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-25,-271,-272,87,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-327,-329,87,87,87,87,87,87,-286,-290,87,87,87,-312,-313,87,87,87,87,87,87,87,87,-332,87,87,-287,-288,-289,87,87,-293,-314,-328,-333,87,87,-294,87,87,87,-291,87,-295,-315,-292,]),'NOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[88,88,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,88,88,-283,88,88,88,-1,88,88,88,88,88,88,88,88,88,-6,88,-284,-285,88,88,-24,88,88,-300,-301,-304,-305,-308,-309,88,88,-330,-331,88,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,88,88,88,88,88,88,88,-90,-88,-89,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-322,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-25,-271,-272,88,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-327,-329,88,88,88,88,88,88,-286,-290,88,88,88,-312,-313,88,88,88,88,88,88,88,88,-332,88,88,-287,-288,-289,88,88,-293,-314,-328,-333,88,88,-294,88,88,88,-291,88,-295,-315,-292,]),'RBRACE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,89,95,96,97,98,99,100,101,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,125,126,130,133,134,136,137,139,140,146,147,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,327,328,329,330,331,332,335,336,337,338,347,354,356,382,386,388,390,391,393,394,395,396,398,399,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,451,453,456,460,462,463,464,467,468,471,472,473,476,478,506,507,508,512,514,515,516,517,518,519,535,536,537,538,541,542,543,544,545,546,548,549,550,556,558,559,561,563,564,565,566,567,568,571,573,574,575,576,577,578,579,581,582,583,584,585,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-1,-283,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-6,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,235,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,302,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,398,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-127,-83,-84,-1,-248,-236,-122,-230,-108,-109,-224,-218,-93,471,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-327,-329,-128,-1,516,-340,-1,-121,-107,-94,-96,-97,-286,-290,-312,-313,-1,-85,541,-1,-334,543,-242,-1,558,-316,-317,-318,-332,564,-335,565,-1,-1,-287,-288,-289,-293,-314,-1,-319,-328,-333,-336,576,577,-1,-294,582,-1,-1,-337,-98,585,-291,-295,-315,-321,-320,-99,-292,]),'CASE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,537,538,541,548,549,550,556,558,559,561,563,564,571,574,575,579,581,582,583,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,248,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,248,248,-322,248,248,248,248,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,248,-327,-329,-286,-290,-312,-313,539,539,-318,-332,-287,-288,-289,-293,-314,539,-319,-328,-333,-294,-1,-1,-291,-295,-315,-321,-320,-292,]),'DEFAULT':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,535,536,537,538,541,548,549,550,556,558,561,563,564,571,575,579,581,582,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,252,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,252,252,-322,252,252,252,252,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,252,-327,-329,-286,-290,-312,-313,-1,560,-316,-317,-318,-332,-287,-288,-289,-293,-314,-319,-328,-333,-294,-1,-291,-295,-315,-320,-292,]),'ELSE':([8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,255,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,255,255,-322,255,255,255,255,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,255,-327,-329,524,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'COLON':([24,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,238,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,318,319,320,321,322,323,324,325,326,342,347,354,356,385,386,387,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,467,468,471,488,489,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,518,543,557,560,562,565,576,],[92,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,400,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-249,-243,-237,-231,-225,-219,-213,-201,-183,454,-127,-83,-84,-266,-248,466,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-121,-107,-94,-135,-250,534,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-242,-335,-244,574,575,-336,-337,]),'PERIOD':([24,43,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,99,101,104,105,107,108,111,165,170,174,216,223,227,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,512,516,541,543,564,565,576,],[-78,-37,167,172,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,225,229,-105,-106,-76,-77,-78,-124,-123,229,-82,-120,-119,229,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,-85,-334,-336,-335,-337,-336,-337,]),'EQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,124,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,429,455,456,458,467,468,471,488,512,516,529,541,543,564,565,576,],[-78,-37,151,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,151,-131,-132,-115,-105,-106,-76,-77,-78,307,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,151,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,486,-125,-128,-112,-121,-107,-94,151,-85,-334,486,-336,-335,-337,-336,-337,]),'MULTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,152,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,152,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,152,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,152,-85,-334,-336,-335,-337,-336,-337,]),'DIVEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,153,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,153,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,153,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,153,-85,-334,-336,-335,-337,-336,-337,]),'MODEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,154,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,154,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,154,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,154,-85,-334,-336,-335,-337,-336,-337,]),'PLUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,155,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,155,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,155,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,155,-85,-334,-336,-335,-337,-336,-337,]),'MINUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,156,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,156,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,156,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,156,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,157,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,157,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,157,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,157,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,158,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,158,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,158,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,158,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,159,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,159,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,159,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,159,-85,-334,-336,-335,-337,-336,-337,]),'ANDEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,160,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,160,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,160,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,160,-85,-334,-336,-335,-337,-336,-337,]),'XOREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,161,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,161,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,161,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,161,-85,-334,-336,-335,-337,-336,-337,]),'OREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,162,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,162,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,162,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,162,-85,-334,-336,-335,-337,-336,-337,]),'MULT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,198,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,299,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,299,299,-159,-160,-161,-122,-108,-109,-93,299,299,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'DIV':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,199,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,300,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,300,300,-159,-160,-161,-122,-108,-109,-93,300,300,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'MOD':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,200,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,301,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,301,301,-159,-160,-161,-122,-108,-109,-93,301,301,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,193,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,294,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,294,-138,-126,-127,-113,-114,-83,-84,294,294,294,294,294,294,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,294,294,294,294,294,294,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,294,294,294,294,294,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,194,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,295,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,295,-138,-126,-127,-113,-114,-83,-84,295,295,295,295,295,295,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,295,295,295,295,295,295,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,295,295,295,295,295,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,195,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,296,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,296,-138,-126,-127,-113,-114,-83,-84,296,296,296,296,296,296,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,296,296,296,296,296,296,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,296,296,296,296,296,-85,-334,-336,-335,-337,-336,-337,]),'LT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,187,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,288,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,444,-183,-138,-126,-127,-113,-114,-83,-84,288,288,288,288,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,288,288,288,288,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,288,288,288,288,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,188,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,289,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,445,-183,-138,-126,-127,-113,-114,-83,-84,289,289,289,289,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,289,289,289,289,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,289,289,289,289,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'LE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,189,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,290,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,446,-183,-138,-126,-127,-113,-114,-83,-84,290,290,290,290,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,290,290,290,290,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,290,290,290,290,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,190,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,291,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,447,-183,-138,-126,-127,-113,-114,-83,-84,291,291,291,291,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,291,291,291,291,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,291,291,291,291,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'INSTANCEOF':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,191,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,261,-78,292,-176,-168,-162,-154,-141,-142,-139,-140,-124,261,-123,261,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,261,-119,261,-116,-115,-92,261,261,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,448,-183,-138,-126,-127,-113,-114,-83,-84,292,292,292,292,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,261,292,292,292,292,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,292,292,292,292,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'IN':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,318,319,320,321,322,323,324,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,429,455,456,458,467,468,471,485,488,489,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,532,541,543,557,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,192,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,260,-78,293,-176,-168,-162,-154,-141,-142,-139,-140,-124,260,-123,260,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,260,-119,260,-116,-115,-92,260,260,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,431,-249,-243,-237,-231,-225,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,293,293,293,293,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,260,293,293,293,293,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,484,-125,-128,-112,-121,-107,-94,531,-135,-250,-238,-232,-226,-220,-214,293,293,293,293,-184,-185,-186,-187,-188,-85,-334,-282,-336,-335,-244,-337,-336,-337,]),'EQEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,183,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,284,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,440,-201,-183,-138,-126,-127,-113,-114,-83,-84,183,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,284,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,440,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'NE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,184,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,285,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,441,-201,-183,-138,-126,-127,-113,-114,-83,-84,184,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,285,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,441,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STREQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,185,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,286,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,442,-201,-183,-138,-126,-127,-113,-114,-83,-84,185,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,286,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,442,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STRNEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,186,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,287,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,443,-201,-183,-138,-126,-127,-113,-114,-83,-84,186,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,287,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,443,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BAND':([24,43,45,47,48,50,54,55,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,323,324,325,326,344,346,347,352,353,354,356,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,182,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,283,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,439,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,182,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,283,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,439,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BXOR':([24,43,45,47,48,50,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,322,323,324,325,326,344,346,347,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,181,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,233,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,438,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,181,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,233,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,438,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BOR':([24,43,45,47,48,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,321,322,323,324,325,326,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,180,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,232,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,437,-225,-219,-213,-201,-183,-138,-126,-127,180,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,232,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,437,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AND':([24,43,45,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,169,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,226,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,436,-231,-225,-219,-213,-201,-183,169,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,226,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,436,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'CONDOP':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,163,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,221,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,434,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'OR':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,164,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,222,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,435,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AUTOSEMI':([24,29,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,135,138,141,144,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,455,456,458,467,468,471,510,512,516,518,525,541,543,564,565,576,],[-78,126,134,137,140,147,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,304,-273,-277,328,330,332,336,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,-125,-128,-112,-121,-107,-94,-246,-85,-334,-242,550,-336,-335,-337,-336,-337,]),'COMMA':([24,29,42,43,44,45,46,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,141,144,149,150,165,170,173,174,176,177,179,201,202,203,204,205,206,207,208,209,210,213,214,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,309,311,314,316,317,318,319,320,321,322,323,324,325,326,333,334,341,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,381,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,428,429,430,455,456,458,465,467,468,470,471,472,473,477,481,485,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,510,511,512,513,516,518,528,529,530,532,541,543,553,555,557,562,564,565,576,577,585,],[-78,127,-269,-37,-251,-138,-245,-133,-134,-239,-117,177,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,217,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,305,-273,-277,217,217,-139,-140,-124,-123,-118,-115,357,-90,358,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,384,-338,-82,-136,-137,-120,-119,-116,-115,-92,399,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,217,217,-135,433,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,217,217,-252,-240,-138,217,-126,-127,457,-129,-234,217,-113,-114,-83,-86,-84,177,-91,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,384,-266,-248,-236,217,-122,-230,217,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,483,-279,-275,-125,-128,-112,-339,-121,-107,384,-94,-96,-97,217,217,-280,217,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-246,-130,-85,-87,-334,-242,-276,-279,217,-282,-336,-335,-280,217,-244,217,-337,-336,-337,-98,-99,]),'RPAREN':([43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,91,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,168,201,202,203,204,205,206,207,208,209,210,211,213,214,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,309,311,333,334,347,348,349,354,356,381,385,386,388,390,391,393,394,395,396,397,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,465,467,468,470,471,474,477,480,481,487,509,511,512,516,518,522,523,526,530,543,551,552,555,565,570,576,],[-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,212,216,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,347,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,380,383,-338,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,424,426,449,450,-127,456,-129,-83,-84,461,-266,-248,-236,-122,-230,-108,-109,-224,-218,469,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-339,-121,-107,520,-94,521,525,-296,-297,533,540,-130,-85,-334,-242,547,-104,-1,554,-335,569,-1,572,-336,580,-337,]),'RBRACKET':([43,52,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,175,176,177,178,179,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,345,347,351,354,355,356,357,358,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,459,467,468,471,512,513,516,518,543,565,576,],[-37,-1,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,354,356,-90,-88,-89,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,455,-127,458,-83,-86,-84,-1,-91,-266,-248,-236,467,-122,-230,468,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,512,-121,-107,-94,-85,-87,-334,-242,-335,-336,-337,]),'GETPROP':([110,399,],[239,239,]),'SETPROP':([110,399,],[240,240,]),'CATCH':([110,145,167,172,225,229,239,240,302,399,],[249,339,249,249,249,249,249,249,-25,249,]),'FINALLY':([110,145,167,172,225,229,239,240,302,337,399,563,],[256,340,256,256,256,256,256,256,-25,340,256,-328,]),'CLASS':([110,167,172,225,229,239,240,399,],[276,276,276,276,276,276,276,276,]),'CONST':([110,167,172,225,229,239,240,399,],[277,277,277,277,277,277,277,277,]),'ENUM':([110,167,172,225,229,239,240,399,],[278,278,278,278,278,278,278,278,]),'EXPORT':([110,167,172,225,229,239,240,399,],[279,279,279,279,279,279,279,279,]),'EXTENDS':([110,167,172,225,229,239,240,399,],[280,280,280,280,280,280,280,280,]),'IMPORT':([110,167,172,225,229,239,240,399,],[281,281,281,281,281,281,281,281,]),'SUPER':([110,167,172,225,229,239,240,399,],[282,282,282,282,282,282,282,282,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'source_elements':([0,26,382,460,464,515,519,545,546,568,574,575,],[2,121,463,463,463,463,463,463,463,463,583,584,]),'empty':([0,26,52,132,357,382,427,460,464,482,508,515,519,526,545,546,552,559,568,574,575,],[3,3,178,315,178,3,480,3,3,480,536,3,3,480,3,3,480,536,3,3,3,]),'source_element_list':([0,26,382,460,464,515,519,545,546,568,574,575,],[4,4,4,4,4,4,4,4,4,4,4,4,]),'source_element':([0,4,26,382,460,464,515,519,545,546,568,574,575,],[5,89,5,5,5,5,5,5,5,5,5,5,5,]),'statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[6,6,6,129,215,6,476,478,506,6,6,6,6,548,556,6,6,571,6,579,581,6,6,586,]),'function_declaration':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[7,7,7,130,130,7,130,130,130,7,7,7,7,130,130,7,7,130,7,130,130,7,7,130,]),'block':([0,4,26,31,40,92,340,382,424,426,449,460,464,515,519,524,533,540,545,546,554,568,569,572,574,575,580,],[8,8,8,8,145,8,453,8,8,8,8,8,8,8,8,8,8,563,8,8,8,8,8,8,8,8,8,]),'variable_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'empty_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'expr_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'if_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'iteration_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'continue_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'break_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'return_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'with_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'switch_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,]),'labelled_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'throw_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,]),'try_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,]),'debugger_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,]),'identifier':([0,4,23,25,26,27,31,34,35,36,39,51,77,78,82,83,84,85,86,87,88,91,92,102,109,110,127,128,131,132,142,143,148,163,164,166,167,168,169,171,172,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,305,307,313,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,452,454,457,459,460,464,466,475,482,483,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[24,24,90,111,24,124,24,135,138,111,111,111,111,111,111,111,111,111,111,111,111,214,24,111,234,245,111,111,111,111,111,111,111,111,111,111,245,111,111,111,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,214,111,111,111,111,111,245,111,111,245,111,111,245,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,124,111,429,24,465,214,245,111,24,111,24,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,24,509,111,111,111,24,24,111,523,111,529,111,111,24,24,24,111,111,24,111,111,24,24,111,24,24,24,24,24,24,24,]),'expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,]),'assignment_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'conditional_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,]),'left_hand_side_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[45,45,45,45,45,344,344,344,344,344,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'logical_or_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,]),'new_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'call_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,]),'logical_and_expr_nobf':([0,4,26,31,92,164,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[49,49,49,49,49,343,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'member_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,]),'bitwise_or_expr_nobf':([0,4,26,31,92,164,169,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[53,53,53,53,53,53,350,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,]),'primary_expr_no_brace':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[54,54,107,54,54,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,107,107,107,107,107,107,54,107,107,54,107,107,54,54,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,54,107,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,54,54,107,107,107,107,54,54,54,107,107,54,107,107,54,54,107,54,54,54,54,54,54,54,]),'function_expr':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[55,55,105,55,55,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,105,105,105,105,105,105,55,105,105,55,105,105,55,55,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,55,105,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,55,55,105,105,105,105,55,55,55,105,105,55,105,105,55,55,105,55,55,55,55,55,55,55,]),'bitwise_xor_expr_nobf':([0,4,26,31,92,164,169,180,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[56,56,56,56,56,56,56,359,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,]),'literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,]),'array_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,]),'bitwise_and_expr_nobf':([0,4,26,31,92,164,169,180,181,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[60,60,60,60,60,60,60,60,360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,]),'null_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,]),'boolean_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,]),'numeric_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,]),'string_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,]),'regex_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,]),'equality_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[66,66,66,66,66,66,66,66,66,361,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,]),'relational_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,]),'shift_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,]),'additive_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,]),'multiplicative_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,]),'unary_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,]),'postfix_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,]),'unary_expr_common':([0,4,25,26,31,36,39,77,78,82,83,84,85,86,87,88,92,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[81,81,120,81,81,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,120,120,120,120,120,81,120,120,81,120,120,81,81,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,81,120,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,81,81,120,120,120,120,81,81,81,120,120,81,120,120,81,81,120,81,81,81,81,81,81,81,]),'expr':([25,36,39,128,131,142,143,166,171,224,228,425,427,431,482,484,526,531,539,552,],[93,141,144,309,311,333,334,345,351,389,392,477,481,487,481,530,481,555,562,481,]),'assignment_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[94,94,94,308,94,94,94,94,341,342,94,349,94,355,385,386,387,94,94,423,473,94,94,94,510,511,513,518,94,94,94,94,94,94,]),'conditional_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'left_hand_side_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[96,96,96,202,202,202,202,202,202,202,202,202,96,96,96,314,96,96,96,96,96,96,96,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,202,96,202,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,488,488,488,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,96,488,96,96,488,96,96,]),'logical_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'new_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[98,98,98,173,98,98,98,98,98,98,98,98,98,230,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'call_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'logical_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,388,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'member_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[101,101,101,174,101,101,101,101,101,101,101,101,101,231,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'bitwise_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,391,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'primary_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'bitwise_xor_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,395,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,]),'object_literal':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,]),'bitwise_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,396,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,]),'equality_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,283,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,403,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,]),'relational_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,183,184,185,186,217,218,221,222,224,226,228,232,233,283,284,285,286,287,307,400,425,427,431,440,441,442,443,454,457,459,466,482,484,526,531,539,552,],[114,114,114,114,114,114,114,114,114,114,114,114,114,114,362,363,364,365,114,114,114,114,114,114,114,114,114,114,404,405,406,407,114,114,114,114,114,497,498,499,500,114,114,114,114,114,114,114,114,114,114,]),'shift_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[115,115,115,115,115,115,326,115,115,115,115,115,115,115,115,115,115,115,115,366,367,368,369,370,371,115,115,115,115,115,115,115,115,115,115,115,115,115,115,408,409,410,411,412,413,115,115,115,115,115,326,326,326,326,326,326,326,326,115,115,115,115,501,502,503,504,505,115,115,115,115,115,115,326,115,115,326,115,115,]),'additive_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,372,373,374,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,414,415,416,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,]),'multiplicative_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,375,376,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,417,418,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,]),'unary_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[118,118,118,201,203,204,205,206,207,208,209,210,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,377,378,379,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,419,420,421,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,]),'postfix_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,]),'variable_declaration_list':([27,],[122,]),'variable_declaration':([27,305,],[123,422,]),'assignment_operator':([45,96,314,488,],[148,218,432,432,]),'arguments':([48,50,99,101,174,231,],[165,170,223,227,353,394,]),'elision_opt':([52,357,],[175,459,]),'element_list':([52,],[176,]),'elision':([52,357,],[179,179,]),'formal_parameter_list':([91,211,397,],[213,381,470,]),'property_list':([110,],[236,]),'property_assignment':([110,399,],[237,472,]),'property_name':([110,239,240,399,],[238,401,402,238,]),'identifier_name_string':([110,167,172,225,229,239,240,399,],[241,346,352,390,393,241,241,241,]),'identifier_name':([110,167,172,225,229,239,240,399,],[244,244,244,244,244,244,244,244,]),'reserved_word':([110,167,172,225,229,239,240,399,],[246,246,246,246,246,246,246,246,]),'initializer':([124,],[306,]),'expr_noin_opt':([132,],[312,]),'expr_noin':([132,],[316,]),'assignment_expr_noin':([132,432,433,434,486,534,],[317,489,490,491,532,557,]),'conditional_expr_noin':([132,432,433,434,486,534,],[318,318,318,318,318,318,]),'logical_or_expr_noin':([132,432,433,434,486,534,],[319,319,319,319,319,319,]),'logical_and_expr_noin':([132,432,433,434,435,486,534,],[320,320,320,320,492,320,320,]),'bitwise_or_expr_noin':([132,432,433,434,435,436,486,534,],[321,321,321,321,321,493,321,321,]),'bitwise_xor_expr_noin':([132,432,433,434,435,436,437,486,534,],[322,322,322,322,322,322,494,322,322,]),'bitwise_and_expr_noin':([132,432,433,434,435,436,437,438,486,534,],[323,323,323,323,323,323,323,495,323,323,]),'equality_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[324,324,324,324,324,324,324,324,496,324,324,]),'relational_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[325,325,325,325,325,325,325,325,325,325,325,]),'catch':([145,],[337,]),'finally':([145,337,],[338,451,]),'argument_list':([168,],[348,]),'variable_declaration_list_noin':([313,],[428,]),'variable_declaration_noin':([313,483,],[430,528,]),'function_body':([382,460,464,515,519,545,546,568,],[462,514,517,542,544,566,567,578,]),'expr_opt':([427,482,526,552,],[479,527,551,570,]),'initializer_noin':([429,529,],[485,553,]),'case_block':([450,],[507,]),'property_set_parameter_list':([475,],[522,]),'case_clauses_opt':([508,559,],[535,573,]),'case_clauses':([508,559,],[537,537,]),'case_clause':([508,537,559,],[538,561,538,]),'default_clause':([535,],[559,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('empty -> ','empty',0,'p_empty','es5.py',122), + ('program -> source_elements','program',1,'p_program','es5.py',157), + ('source_elements -> empty','source_elements',1,'p_source_elements','es5.py',164), + ('source_elements -> source_element_list','source_elements',1,'p_source_elements','es5.py',165), + ('source_element_list -> source_element','source_element_list',1,'p_source_element_list','es5.py',170), + ('source_element_list -> source_element_list source_element','source_element_list',2,'p_source_element_list','es5.py',171), + ('source_element -> statement','source_element',1,'p_source_element','es5.py',180), + ('source_element -> function_declaration','source_element',1,'p_source_element','es5.py',181), + ('statement -> block','statement',1,'p_statement','es5.py',186), + ('statement -> variable_statement','statement',1,'p_statement','es5.py',187), + ('statement -> empty_statement','statement',1,'p_statement','es5.py',188), + ('statement -> expr_statement','statement',1,'p_statement','es5.py',189), + ('statement -> if_statement','statement',1,'p_statement','es5.py',190), + ('statement -> iteration_statement','statement',1,'p_statement','es5.py',191), + ('statement -> continue_statement','statement',1,'p_statement','es5.py',192), + ('statement -> break_statement','statement',1,'p_statement','es5.py',193), + ('statement -> return_statement','statement',1,'p_statement','es5.py',194), + ('statement -> with_statement','statement',1,'p_statement','es5.py',195), + ('statement -> switch_statement','statement',1,'p_statement','es5.py',196), + ('statement -> labelled_statement','statement',1,'p_statement','es5.py',197), + ('statement -> throw_statement','statement',1,'p_statement','es5.py',198), + ('statement -> try_statement','statement',1,'p_statement','es5.py',199), + ('statement -> debugger_statement','statement',1,'p_statement','es5.py',200), + ('statement -> function_declaration','statement',1,'p_statement','es5.py',201), + ('block -> LBRACE source_elements RBRACE','block',3,'p_block','es5.py',208), + ('literal -> null_literal','literal',1,'p_literal','es5.py',213), + ('literal -> boolean_literal','literal',1,'p_literal','es5.py',214), + ('literal -> numeric_literal','literal',1,'p_literal','es5.py',215), + ('literal -> string_literal','literal',1,'p_literal','es5.py',216), + ('literal -> regex_literal','literal',1,'p_literal','es5.py',217), + ('boolean_literal -> TRUE','boolean_literal',1,'p_boolean_literal','es5.py',222), + ('boolean_literal -> FALSE','boolean_literal',1,'p_boolean_literal','es5.py',223), + ('null_literal -> NULL','null_literal',1,'p_null_literal','es5.py',229), + ('numeric_literal -> NUMBER','numeric_literal',1,'p_numeric_literal','es5.py',234), + ('string_literal -> STRING','string_literal',1,'p_string_literal','es5.py',239), + ('regex_literal -> REGEX','regex_literal',1,'p_regex_literal','es5.py',244), + ('identifier -> ID','identifier',1,'p_identifier','es5.py',249), + ('reserved_word -> BREAK','reserved_word',1,'p_reserved_word','es5.py',256), + ('reserved_word -> CASE','reserved_word',1,'p_reserved_word','es5.py',257), + ('reserved_word -> CATCH','reserved_word',1,'p_reserved_word','es5.py',258), + ('reserved_word -> CONTINUE','reserved_word',1,'p_reserved_word','es5.py',259), + ('reserved_word -> DEBUGGER','reserved_word',1,'p_reserved_word','es5.py',260), + ('reserved_word -> DEFAULT','reserved_word',1,'p_reserved_word','es5.py',261), + ('reserved_word -> DELETE','reserved_word',1,'p_reserved_word','es5.py',262), + ('reserved_word -> DO','reserved_word',1,'p_reserved_word','es5.py',263), + ('reserved_word -> ELSE','reserved_word',1,'p_reserved_word','es5.py',264), + ('reserved_word -> FINALLY','reserved_word',1,'p_reserved_word','es5.py',265), + ('reserved_word -> FOR','reserved_word',1,'p_reserved_word','es5.py',266), + ('reserved_word -> FUNCTION','reserved_word',1,'p_reserved_word','es5.py',267), + ('reserved_word -> IF','reserved_word',1,'p_reserved_word','es5.py',268), + ('reserved_word -> IN','reserved_word',1,'p_reserved_word','es5.py',269), + ('reserved_word -> INSTANCEOF','reserved_word',1,'p_reserved_word','es5.py',270), + ('reserved_word -> NEW','reserved_word',1,'p_reserved_word','es5.py',271), + ('reserved_word -> RETURN','reserved_word',1,'p_reserved_word','es5.py',272), + ('reserved_word -> SWITCH','reserved_word',1,'p_reserved_word','es5.py',273), + ('reserved_word -> THIS','reserved_word',1,'p_reserved_word','es5.py',274), + ('reserved_word -> THROW','reserved_word',1,'p_reserved_word','es5.py',275), + ('reserved_word -> TRY','reserved_word',1,'p_reserved_word','es5.py',276), + ('reserved_word -> TYPEOF','reserved_word',1,'p_reserved_word','es5.py',277), + ('reserved_word -> VAR','reserved_word',1,'p_reserved_word','es5.py',278), + ('reserved_word -> VOID','reserved_word',1,'p_reserved_word','es5.py',279), + ('reserved_word -> WHILE','reserved_word',1,'p_reserved_word','es5.py',280), + ('reserved_word -> WITH','reserved_word',1,'p_reserved_word','es5.py',281), + ('reserved_word -> NULL','reserved_word',1,'p_reserved_word','es5.py',282), + ('reserved_word -> TRUE','reserved_word',1,'p_reserved_word','es5.py',283), + ('reserved_word -> FALSE','reserved_word',1,'p_reserved_word','es5.py',284), + ('reserved_word -> CLASS','reserved_word',1,'p_reserved_word','es5.py',285), + ('reserved_word -> CONST','reserved_word',1,'p_reserved_word','es5.py',286), + ('reserved_word -> ENUM','reserved_word',1,'p_reserved_word','es5.py',287), + ('reserved_word -> EXPORT','reserved_word',1,'p_reserved_word','es5.py',288), + ('reserved_word -> EXTENDS','reserved_word',1,'p_reserved_word','es5.py',289), + ('reserved_word -> IMPORT','reserved_word',1,'p_reserved_word','es5.py',290), + ('reserved_word -> SUPER','reserved_word',1,'p_reserved_word','es5.py',291), + ('identifier_name -> identifier','identifier_name',1,'p_identifier_name','es5.py',297), + ('identifier_name -> reserved_word','identifier_name',1,'p_identifier_name','es5.py',298), + ('primary_expr -> primary_expr_no_brace','primary_expr',1,'p_primary_expr','es5.py',306), + ('primary_expr -> object_literal','primary_expr',1,'p_primary_expr','es5.py',307), + ('primary_expr_no_brace -> identifier','primary_expr_no_brace',1,'p_primary_expr_no_brace_1','es5.py',312), + ('primary_expr_no_brace -> THIS','primary_expr_no_brace',1,'p_primary_expr_no_brace_2','es5.py',316), + ('primary_expr_no_brace -> literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',321), + ('primary_expr_no_brace -> array_literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',322), + ('primary_expr_no_brace -> LPAREN expr RPAREN','primary_expr_no_brace',3,'p_primary_expr_no_brace_4','es5.py',327), + ('array_literal -> LBRACKET elision_opt RBRACKET','array_literal',3,'p_array_literal_1','es5.py',336), + ('array_literal -> LBRACKET element_list RBRACKET','array_literal',3,'p_array_literal_2','es5.py',341), + ('array_literal -> LBRACKET element_list COMMA elision_opt RBRACKET','array_literal',5,'p_array_literal_2','es5.py',342), + ('element_list -> elision_opt assignment_expr','element_list',2,'p_element_list','es5.py',351), + ('element_list -> element_list COMMA elision_opt assignment_expr','element_list',4,'p_element_list','es5.py',352), + ('elision_opt -> empty','elision_opt',1,'p_elision_opt_1','es5.py',362), + ('elision_opt -> elision','elision_opt',1,'p_elision_opt_2','es5.py',366), + ('elision -> COMMA','elision',1,'p_elision','es5.py',370), + ('elision -> elision COMMA','elision',2,'p_elision','es5.py',371), + ('object_literal -> LBRACE RBRACE','object_literal',2,'p_object_literal','es5.py',387), + ('object_literal -> LBRACE property_list RBRACE','object_literal',3,'p_object_literal','es5.py',388), + ('object_literal -> LBRACE property_list COMMA RBRACE','object_literal',4,'p_object_literal','es5.py',389), + ('property_list -> property_assignment','property_list',1,'p_property_list','es5.py',398), + ('property_list -> property_list COMMA property_assignment','property_list',3,'p_property_list','es5.py',399), + ('property_assignment -> property_name COLON assignment_expr','property_assignment',3,'p_property_assignment','es5.py',409), + ('property_assignment -> GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE','property_assignment',7,'p_property_assignment','es5.py',410), + ('property_assignment -> SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE','property_assignment',8,'p_property_assignment','es5.py',411), + ('identifier_name_string -> identifier_name','identifier_name_string',1,'p_identifier_name_string','es5.py',432), + ('property_name -> identifier_name_string','property_name',1,'p_property_name','es5.py',441), + ('property_name -> string_literal','property_name',1,'p_property_name','es5.py',442), + ('property_name -> numeric_literal','property_name',1,'p_property_name','es5.py',443), + ('property_set_parameter_list -> identifier','property_set_parameter_list',1,'p_property_set_parameter_list','es5.py',448), + ('member_expr -> primary_expr','member_expr',1,'p_member_expr','es5.py',457), + ('member_expr -> function_expr','member_expr',1,'p_member_expr','es5.py',458), + ('member_expr -> member_expr LBRACKET expr RBRACKET','member_expr',4,'p_member_expr','es5.py',459), + ('member_expr -> member_expr PERIOD identifier_name_string','member_expr',3,'p_member_expr','es5.py',460), + ('member_expr -> NEW member_expr arguments','member_expr',3,'p_member_expr','es5.py',461), + ('member_expr_nobf -> primary_expr_no_brace','member_expr_nobf',1,'p_member_expr_nobf','es5.py',478), + ('member_expr_nobf -> function_expr','member_expr_nobf',1,'p_member_expr_nobf','es5.py',479), + ('member_expr_nobf -> member_expr_nobf LBRACKET expr RBRACKET','member_expr_nobf',4,'p_member_expr_nobf','es5.py',480), + ('member_expr_nobf -> member_expr_nobf PERIOD identifier_name_string','member_expr_nobf',3,'p_member_expr_nobf','es5.py',481), + ('member_expr_nobf -> NEW member_expr arguments','member_expr_nobf',3,'p_member_expr_nobf','es5.py',482), + ('new_expr -> member_expr','new_expr',1,'p_new_expr','es5.py',499), + ('new_expr -> NEW new_expr','new_expr',2,'p_new_expr','es5.py',500), + ('new_expr_nobf -> member_expr_nobf','new_expr_nobf',1,'p_new_expr_nobf','es5.py',509), + ('new_expr_nobf -> NEW new_expr','new_expr_nobf',2,'p_new_expr_nobf','es5.py',510), + ('call_expr -> member_expr arguments','call_expr',2,'p_call_expr','es5.py',519), + ('call_expr -> call_expr arguments','call_expr',2,'p_call_expr','es5.py',520), + ('call_expr -> call_expr LBRACKET expr RBRACKET','call_expr',4,'p_call_expr','es5.py',521), + ('call_expr -> call_expr PERIOD identifier_name_string','call_expr',3,'p_call_expr','es5.py',522), + ('call_expr_nobf -> member_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',535), + ('call_expr_nobf -> call_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',536), + ('call_expr_nobf -> call_expr_nobf LBRACKET expr RBRACKET','call_expr_nobf',4,'p_call_expr_nobf','es5.py',537), + ('call_expr_nobf -> call_expr_nobf PERIOD identifier_name_string','call_expr_nobf',3,'p_call_expr_nobf','es5.py',538), + ('arguments -> LPAREN RPAREN','arguments',2,'p_arguments','es5.py',551), + ('arguments -> LPAREN argument_list RPAREN','arguments',3,'p_arguments','es5.py',552), + ('argument_list -> assignment_expr','argument_list',1,'p_argument_list','es5.py',561), + ('argument_list -> argument_list COMMA assignment_expr','argument_list',3,'p_argument_list','es5.py',562), + ('left_hand_side_expr -> new_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',571), + ('left_hand_side_expr -> call_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',572), + ('left_hand_side_expr_nobf -> new_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',577), + ('left_hand_side_expr_nobf -> call_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',578), + ('postfix_expr -> left_hand_side_expr','postfix_expr',1,'p_postfix_expr','es5.py',584), + ('postfix_expr -> left_hand_side_expr PLUSPLUS','postfix_expr',2,'p_postfix_expr','es5.py',585), + ('postfix_expr -> left_hand_side_expr MINUSMINUS','postfix_expr',2,'p_postfix_expr','es5.py',586), + ('postfix_expr_nobf -> left_hand_side_expr_nobf','postfix_expr_nobf',1,'p_postfix_expr_nobf','es5.py',595), + ('postfix_expr_nobf -> left_hand_side_expr_nobf PLUSPLUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',596), + ('postfix_expr_nobf -> left_hand_side_expr_nobf MINUSMINUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',597), + ('unary_expr -> postfix_expr','unary_expr',1,'p_unary_expr','es5.py',607), + ('unary_expr -> unary_expr_common','unary_expr',1,'p_unary_expr','es5.py',608), + ('unary_expr_nobf -> postfix_expr_nobf','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',613), + ('unary_expr_nobf -> unary_expr_common','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',614), + ('unary_expr_common -> DELETE unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',619), + ('unary_expr_common -> VOID unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',620), + ('unary_expr_common -> TYPEOF unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',621), + ('unary_expr_common -> PLUSPLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',622), + ('unary_expr_common -> MINUSMINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',623), + ('unary_expr_common -> PLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',624), + ('unary_expr_common -> MINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',625), + ('unary_expr_common -> BNOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',626), + ('unary_expr_common -> NOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',627), + ('multiplicative_expr -> unary_expr','multiplicative_expr',1,'p_multiplicative_expr','es5.py',634), + ('multiplicative_expr -> multiplicative_expr MULT unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',635), + ('multiplicative_expr -> multiplicative_expr DIV unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',636), + ('multiplicative_expr -> multiplicative_expr MOD unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',637), + ('multiplicative_expr_nobf -> unary_expr_nobf','multiplicative_expr_nobf',1,'p_multiplicative_expr_nobf','es5.py',646), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MULT unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',647), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf DIV unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',648), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MOD unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',649), + ('additive_expr -> multiplicative_expr','additive_expr',1,'p_additive_expr','es5.py',659), + ('additive_expr -> additive_expr PLUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',660), + ('additive_expr -> additive_expr MINUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',661), + ('additive_expr_nobf -> multiplicative_expr_nobf','additive_expr_nobf',1,'p_additive_expr_nobf','es5.py',670), + ('additive_expr_nobf -> additive_expr_nobf PLUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',671), + ('additive_expr_nobf -> additive_expr_nobf MINUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',672), + ('shift_expr -> additive_expr','shift_expr',1,'p_shift_expr','es5.py',682), + ('shift_expr -> shift_expr LSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',683), + ('shift_expr -> shift_expr RSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',684), + ('shift_expr -> shift_expr URSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',685), + ('shift_expr_nobf -> additive_expr_nobf','shift_expr_nobf',1,'p_shift_expr_nobf','es5.py',694), + ('shift_expr_nobf -> shift_expr_nobf LSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',695), + ('shift_expr_nobf -> shift_expr_nobf RSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',696), + ('shift_expr_nobf -> shift_expr_nobf URSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',697), + ('relational_expr -> shift_expr','relational_expr',1,'p_relational_expr','es5.py',707), + ('relational_expr -> relational_expr LT shift_expr','relational_expr',3,'p_relational_expr','es5.py',708), + ('relational_expr -> relational_expr GT shift_expr','relational_expr',3,'p_relational_expr','es5.py',709), + ('relational_expr -> relational_expr LE shift_expr','relational_expr',3,'p_relational_expr','es5.py',710), + ('relational_expr -> relational_expr GE shift_expr','relational_expr',3,'p_relational_expr','es5.py',711), + ('relational_expr -> relational_expr INSTANCEOF shift_expr','relational_expr',3,'p_relational_expr','es5.py',712), + ('relational_expr -> relational_expr IN shift_expr','relational_expr',3,'p_relational_expr','es5.py',713), + ('relational_expr_noin -> shift_expr','relational_expr_noin',1,'p_relational_expr_noin','es5.py',722), + ('relational_expr_noin -> relational_expr_noin LT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',723), + ('relational_expr_noin -> relational_expr_noin GT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',724), + ('relational_expr_noin -> relational_expr_noin LE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',725), + ('relational_expr_noin -> relational_expr_noin GE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',726), + ('relational_expr_noin -> relational_expr_noin INSTANCEOF shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',727), + ('relational_expr_nobf -> shift_expr_nobf','relational_expr_nobf',1,'p_relational_expr_nobf','es5.py',736), + ('relational_expr_nobf -> relational_expr_nobf LT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',737), + ('relational_expr_nobf -> relational_expr_nobf GT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',738), + ('relational_expr_nobf -> relational_expr_nobf LE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',739), + ('relational_expr_nobf -> relational_expr_nobf GE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',740), + ('relational_expr_nobf -> relational_expr_nobf INSTANCEOF shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',741), + ('relational_expr_nobf -> relational_expr_nobf IN shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',742), + ('equality_expr -> relational_expr','equality_expr',1,'p_equality_expr','es5.py',752), + ('equality_expr -> equality_expr EQEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',753), + ('equality_expr -> equality_expr NE relational_expr','equality_expr',3,'p_equality_expr','es5.py',754), + ('equality_expr -> equality_expr STREQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',755), + ('equality_expr -> equality_expr STRNEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',756), + ('equality_expr_noin -> relational_expr_noin','equality_expr_noin',1,'p_equality_expr_noin','es5.py',765), + ('equality_expr_noin -> equality_expr_noin EQEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',766), + ('equality_expr_noin -> equality_expr_noin NE relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',767), + ('equality_expr_noin -> equality_expr_noin STREQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',768), + ('equality_expr_noin -> equality_expr_noin STRNEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',769), + ('equality_expr_nobf -> relational_expr_nobf','equality_expr_nobf',1,'p_equality_expr_nobf','es5.py',778), + ('equality_expr_nobf -> equality_expr_nobf EQEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',779), + ('equality_expr_nobf -> equality_expr_nobf NE relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',780), + ('equality_expr_nobf -> equality_expr_nobf STREQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',781), + ('equality_expr_nobf -> equality_expr_nobf STRNEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',782), + ('bitwise_and_expr -> equality_expr','bitwise_and_expr',1,'p_bitwise_and_expr','es5.py',792), + ('bitwise_and_expr -> bitwise_and_expr BAND equality_expr','bitwise_and_expr',3,'p_bitwise_and_expr','es5.py',793), + ('bitwise_and_expr_noin -> equality_expr_noin','bitwise_and_expr_noin',1,'p_bitwise_and_expr_noin','es5.py',802), + ('bitwise_and_expr_noin -> bitwise_and_expr_noin BAND equality_expr_noin','bitwise_and_expr_noin',3,'p_bitwise_and_expr_noin','es5.py',803), + ('bitwise_and_expr_nobf -> equality_expr_nobf','bitwise_and_expr_nobf',1,'p_bitwise_and_expr_nobf','es5.py',813), + ('bitwise_and_expr_nobf -> bitwise_and_expr_nobf BAND equality_expr_nobf','bitwise_and_expr_nobf',3,'p_bitwise_and_expr_nobf','es5.py',814), + ('bitwise_xor_expr -> bitwise_and_expr','bitwise_xor_expr',1,'p_bitwise_xor_expr','es5.py',824), + ('bitwise_xor_expr -> bitwise_xor_expr BXOR bitwise_and_expr','bitwise_xor_expr',3,'p_bitwise_xor_expr','es5.py',825), + ('bitwise_xor_expr_noin -> bitwise_and_expr_noin','bitwise_xor_expr_noin',1,'p_bitwise_xor_expr_noin','es5.py',835), + ('bitwise_xor_expr_noin -> bitwise_xor_expr_noin BXOR bitwise_and_expr_noin','bitwise_xor_expr_noin',3,'p_bitwise_xor_expr_noin','es5.py',836), + ('bitwise_xor_expr_nobf -> bitwise_and_expr_nobf','bitwise_xor_expr_nobf',1,'p_bitwise_xor_expr_nobf','es5.py',847), + ('bitwise_xor_expr_nobf -> bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf','bitwise_xor_expr_nobf',3,'p_bitwise_xor_expr_nobf','es5.py',848), + ('bitwise_or_expr -> bitwise_xor_expr','bitwise_or_expr',1,'p_bitwise_or_expr','es5.py',858), + ('bitwise_or_expr -> bitwise_or_expr BOR bitwise_xor_expr','bitwise_or_expr',3,'p_bitwise_or_expr','es5.py',859), + ('bitwise_or_expr_noin -> bitwise_xor_expr_noin','bitwise_or_expr_noin',1,'p_bitwise_or_expr_noin','es5.py',869), + ('bitwise_or_expr_noin -> bitwise_or_expr_noin BOR bitwise_xor_expr_noin','bitwise_or_expr_noin',3,'p_bitwise_or_expr_noin','es5.py',870), + ('bitwise_or_expr_nobf -> bitwise_xor_expr_nobf','bitwise_or_expr_nobf',1,'p_bitwise_or_expr_nobf','es5.py',881), + ('bitwise_or_expr_nobf -> bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf','bitwise_or_expr_nobf',3,'p_bitwise_or_expr_nobf','es5.py',882), + ('logical_and_expr -> bitwise_or_expr','logical_and_expr',1,'p_logical_and_expr','es5.py',893), + ('logical_and_expr -> logical_and_expr AND bitwise_or_expr','logical_and_expr',3,'p_logical_and_expr','es5.py',894), + ('logical_and_expr_noin -> bitwise_or_expr_noin','logical_and_expr_noin',1,'p_logical_and_expr_noin','es5.py',904), + ('logical_and_expr_noin -> logical_and_expr_noin AND bitwise_or_expr_noin','logical_and_expr_noin',3,'p_logical_and_expr_noin','es5.py',905), + ('logical_and_expr_nobf -> bitwise_or_expr_nobf','logical_and_expr_nobf',1,'p_logical_and_expr_nobf','es5.py',915), + ('logical_and_expr_nobf -> logical_and_expr_nobf AND bitwise_or_expr_nobf','logical_and_expr_nobf',3,'p_logical_and_expr_nobf','es5.py',916), + ('logical_or_expr -> logical_and_expr','logical_or_expr',1,'p_logical_or_expr','es5.py',925), + ('logical_or_expr -> logical_or_expr OR logical_and_expr','logical_or_expr',3,'p_logical_or_expr','es5.py',926), + ('logical_or_expr_noin -> logical_and_expr_noin','logical_or_expr_noin',1,'p_logical_or_expr_noin','es5.py',935), + ('logical_or_expr_noin -> logical_or_expr_noin OR logical_and_expr_noin','logical_or_expr_noin',3,'p_logical_or_expr_noin','es5.py',936), + ('logical_or_expr_nobf -> logical_and_expr_nobf','logical_or_expr_nobf',1,'p_logical_or_expr_nobf','es5.py',945), + ('logical_or_expr_nobf -> logical_or_expr_nobf OR logical_and_expr_nobf','logical_or_expr_nobf',3,'p_logical_or_expr_nobf','es5.py',946), + ('conditional_expr -> logical_or_expr','conditional_expr',1,'p_conditional_expr','es5.py',957), + ('conditional_expr -> logical_or_expr CONDOP assignment_expr COLON assignment_expr','conditional_expr',5,'p_conditional_expr','es5.py',958), + ('conditional_expr_noin -> logical_or_expr_noin','conditional_expr_noin',1,'p_conditional_expr_noin','es5.py',970), + ('conditional_expr_noin -> logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin','conditional_expr_noin',5,'p_conditional_expr_noin','es5.py',971), + ('conditional_expr_nobf -> logical_or_expr_nobf','conditional_expr_nobf',1,'p_conditional_expr_nobf','es5.py',984), + ('conditional_expr_nobf -> logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr','conditional_expr_nobf',5,'p_conditional_expr_nobf','es5.py',985), + ('assignment_expr -> conditional_expr','assignment_expr',1,'p_assignment_expr','es5.py',998), + ('assignment_expr -> left_hand_side_expr assignment_operator assignment_expr','assignment_expr',3,'p_assignment_expr','es5.py',999), + ('assignment_expr_noin -> conditional_expr_noin','assignment_expr_noin',1,'p_assignment_expr_noin','es5.py',1010), + ('assignment_expr_noin -> left_hand_side_expr assignment_operator assignment_expr_noin','assignment_expr_noin',3,'p_assignment_expr_noin','es5.py',1011), + ('assignment_expr_nobf -> conditional_expr_nobf','assignment_expr_nobf',1,'p_assignment_expr_nobf','es5.py',1022), + ('assignment_expr_nobf -> left_hand_side_expr_nobf assignment_operator assignment_expr','assignment_expr_nobf',3,'p_assignment_expr_nobf','es5.py',1023), + ('assignment_operator -> EQ','assignment_operator',1,'p_assignment_operator','es5.py',1033), + ('assignment_operator -> MULTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1034), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1035), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1036), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1037), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1038), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1039), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1040), + ('assignment_operator -> URSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1041), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1042), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1043), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1044), + ('expr -> assignment_expr','expr',1,'p_expr','es5.py',1050), + ('expr -> expr COMMA assignment_expr','expr',3,'p_expr','es5.py',1051), + ('expr_noin -> assignment_expr_noin','expr_noin',1,'p_expr_noin','es5.py',1060), + ('expr_noin -> expr_noin COMMA assignment_expr_noin','expr_noin',3,'p_expr_noin','es5.py',1061), + ('expr_nobf -> assignment_expr_nobf','expr_nobf',1,'p_expr_nobf','es5.py',1070), + ('expr_nobf -> expr_nobf COMMA assignment_expr','expr_nobf',3,'p_expr_nobf','es5.py',1071), + ('variable_statement -> VAR variable_declaration_list SEMI','variable_statement',3,'p_variable_statement','es5.py',1081), + ('variable_statement -> VAR variable_declaration_list AUTOSEMI','variable_statement',3,'p_variable_statement','es5.py',1082), + ('variable_declaration_list -> variable_declaration','variable_declaration_list',1,'p_variable_declaration_list','es5.py',1089), + ('variable_declaration_list -> variable_declaration_list COMMA variable_declaration','variable_declaration_list',3,'p_variable_declaration_list','es5.py',1090), + ('variable_declaration_list_noin -> variable_declaration_noin','variable_declaration_list_noin',1,'p_variable_declaration_list_noin','es5.py',1101), + ('variable_declaration_list_noin -> variable_declaration_list_noin COMMA variable_declaration_noin','variable_declaration_list_noin',3,'p_variable_declaration_list_noin','es5.py',1102), + ('variable_declaration -> identifier','variable_declaration',1,'p_variable_declaration','es5.py',1112), + ('variable_declaration -> identifier initializer','variable_declaration',2,'p_variable_declaration','es5.py',1113), + ('variable_declaration_noin -> identifier','variable_declaration_noin',1,'p_variable_declaration_noin','es5.py',1123), + ('variable_declaration_noin -> identifier initializer_noin','variable_declaration_noin',2,'p_variable_declaration_noin','es5.py',1124), + ('initializer -> EQ assignment_expr','initializer',2,'p_initializer','es5.py',1134), + ('initializer_noin -> EQ assignment_expr_noin','initializer_noin',2,'p_initializer_noin','es5.py',1138), + ('empty_statement -> SEMI','empty_statement',1,'p_empty_statement','es5.py',1143), + ('expr_statement -> expr_nobf SEMI','expr_statement',2,'p_expr_statement','es5.py',1149), + ('expr_statement -> expr_nobf AUTOSEMI','expr_statement',2,'p_expr_statement','es5.py',1150), + ('if_statement -> IF LPAREN expr RPAREN statement','if_statement',5,'p_if_statement_1','es5.py',1173), + ('if_statement -> IF LPAREN expr RPAREN statement ELSE statement','if_statement',7,'p_if_statement_2','es5.py',1178), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN SEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1186), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN AUTOSEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1187), + ('iteration_statement -> WHILE LPAREN expr RPAREN statement','iteration_statement',5,'p_iteration_statement_2','es5.py',1194), + ('iteration_statement -> FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','es5.py',1200), + ('iteration_statement -> FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',10,'p_iteration_statement_3','es5.py',1201), + ('iteration_statement -> FOR LPAREN left_hand_side_expr IN expr RPAREN statement','iteration_statement',7,'p_iteration_statement_4','es5.py',1233), + ('iteration_statement -> FOR LPAREN VAR identifier IN expr RPAREN statement','iteration_statement',8,'p_iteration_statement_5','es5.py',1241), + ('iteration_statement -> FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement','iteration_statement',9,'p_iteration_statement_6','es5.py',1251), + ('expr_opt -> empty','expr_opt',1,'p_expr_opt','es5.py',1261), + ('expr_opt -> expr','expr_opt',1,'p_expr_opt','es5.py',1262), + ('expr_noin_opt -> empty','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1267), + ('expr_noin_opt -> expr_noin','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1268), + ('continue_statement -> CONTINUE SEMI','continue_statement',2,'p_continue_statement_1','es5.py',1274), + ('continue_statement -> CONTINUE AUTOSEMI','continue_statement',2,'p_continue_statement_1','es5.py',1275), + ('continue_statement -> CONTINUE identifier SEMI','continue_statement',3,'p_continue_statement_2','es5.py',1281), + ('continue_statement -> CONTINUE identifier AUTOSEMI','continue_statement',3,'p_continue_statement_2','es5.py',1282), + ('break_statement -> BREAK SEMI','break_statement',2,'p_break_statement_1','es5.py',1289), + ('break_statement -> BREAK AUTOSEMI','break_statement',2,'p_break_statement_1','es5.py',1290), + ('break_statement -> BREAK identifier SEMI','break_statement',3,'p_break_statement_2','es5.py',1296), + ('break_statement -> BREAK identifier AUTOSEMI','break_statement',3,'p_break_statement_2','es5.py',1297), + ('return_statement -> RETURN SEMI','return_statement',2,'p_return_statement_1','es5.py',1304), + ('return_statement -> RETURN AUTOSEMI','return_statement',2,'p_return_statement_1','es5.py',1305), + ('return_statement -> RETURN expr SEMI','return_statement',3,'p_return_statement_2','es5.py',1311), + ('return_statement -> RETURN expr AUTOSEMI','return_statement',3,'p_return_statement_2','es5.py',1312), + ('with_statement -> WITH LPAREN expr RPAREN statement','with_statement',5,'p_with_statement','es5.py',1319), + ('switch_statement -> SWITCH LPAREN expr RPAREN case_block','switch_statement',5,'p_switch_statement','es5.py',1325), + ('case_block -> LBRACE case_clauses_opt RBRACE','case_block',3,'p_case_block','es5.py',1335), + ('case_block -> LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE','case_block',5,'p_case_block','es5.py',1336), + ('case_clauses_opt -> empty','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1350), + ('case_clauses_opt -> case_clauses','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1351), + ('case_clauses -> case_clause','case_clauses',1,'p_case_clauses','es5.py',1356), + ('case_clauses -> case_clauses case_clause','case_clauses',2,'p_case_clauses','es5.py',1357), + ('case_clause -> CASE expr COLON source_elements','case_clause',4,'p_case_clause','es5.py',1366), + ('default_clause -> DEFAULT COLON source_elements','default_clause',3,'p_default_clause','es5.py',1371), + ('labelled_statement -> identifier COLON statement','labelled_statement',3,'p_labelled_statement','es5.py',1377), + ('throw_statement -> THROW expr SEMI','throw_statement',3,'p_throw_statement','es5.py',1383), + ('throw_statement -> THROW expr AUTOSEMI','throw_statement',3,'p_throw_statement','es5.py',1384), + ('try_statement -> TRY block catch','try_statement',3,'p_try_statement_1','es5.py',1391), + ('try_statement -> TRY block finally','try_statement',3,'p_try_statement_2','es5.py',1396), + ('try_statement -> TRY block catch finally','try_statement',4,'p_try_statement_3','es5.py',1401), + ('catch -> CATCH LPAREN identifier RPAREN block','catch',5,'p_catch','es5.py',1406), + ('finally -> FINALLY block','finally',2,'p_finally','es5.py',1411), + ('debugger_statement -> DEBUGGER SEMI','debugger_statement',2,'p_debugger_statement','es5.py',1417), + ('debugger_statement -> DEBUGGER AUTOSEMI','debugger_statement',2,'p_debugger_statement','es5.py',1418), + ('function_declaration -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_declaration',7,'p_function_declaration','es5.py',1426), + ('function_declaration -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_declaration',8,'p_function_declaration','es5.py',1427), + ('function_expr -> FUNCTION LPAREN RPAREN LBRACE function_body RBRACE','function_expr',6,'p_function_expr_1','es5.py',1441), + ('function_expr -> FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_1','es5.py',1442), + ('function_expr -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_2','es5.py',1456), + ('function_expr -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',8,'p_function_expr_2','es5.py',1457), + ('formal_parameter_list -> identifier','formal_parameter_list',1,'p_formal_parameter_list','es5.py',1470), + ('formal_parameter_list -> formal_parameter_list COMMA identifier','formal_parameter_list',3,'p_formal_parameter_list','es5.py',1471), + ('function_body -> source_elements','function_body',1,'p_function_body','es5.py',1480), +] diff --git a/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_9.py b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_9.py new file mode 100644 index 00000000..9f8d01cd --- /dev/null +++ b/uno/lib/python/calmjs/parse/parsers/yacctab_es5_py3_ply3_9.py @@ -0,0 +1,369 @@ + +# yacctab_es5_py3_ply3_9.py +# This file is automatically generated. Do not edit. +_tabversion = '3.8' + +_lr_method = 'LALR' + +_lr_signature = '9825587DAB8F9D419DD9E432175955D6' + +_lr_action_items = {'$end':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,125,126,130,133,134,136,137,139,140,146,147,215,302,303,304,327,328,329,330,331,332,335,336,337,338,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-1,0,-2,-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-322,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-327,-329,-286,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'FUNCTION':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[23,23,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,109,23,-283,23,109,109,109,-1,109,109,109,109,109,109,109,109,109,-6,23,109,258,-284,-285,109,109,-24,109,109,-300,-301,-304,-305,-308,-309,109,109,-330,-331,109,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,109,109,109,258,109,109,109,258,109,-90,-88,-89,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-322,109,109,109,109,109,258,109,109,258,109,109,258,258,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,-25,-271,-272,109,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,23,258,109,23,109,23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,23,-327,-329,109,109,109,23,23,109,-286,-290,109,109,109,-312,-313,23,23,23,109,109,23,109,109,-332,23,23,-287,-288,-289,109,23,-293,-314,-328,-333,23,23,-294,23,23,23,-291,23,-295,-315,-292,]),'LBRACE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,40,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,166,168,171,175,177,178,179,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,212,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,340,357,358,380,382,383,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,453,454,457,459,460,461,464,466,469,476,478,482,484,486,506,507,515,519,520,521,524,526,531,533,534,539,540,541,545,546,547,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[26,26,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,110,26,-283,26,110,110,26,110,-1,110,110,110,110,110,110,110,110,110,-6,26,110,-284,-285,110,110,-24,110,110,-300,-301,-304,-305,-308,-309,110,110,-330,-331,110,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,110,110,110,110,110,-90,-88,-89,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,382,-322,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-25,-271,-272,110,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,26,-1,-91,460,26,464,110,26,110,26,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,26,508,-327,-329,110,110,110,26,515,26,110,519,-286,-290,110,110,110,-312,-313,26,26,545,546,26,110,110,26,110,110,26,-332,26,26,568,-287,-288,-289,110,26,-293,-314,-328,-333,26,26,-294,26,26,26,-291,26,-295,-315,-292,]),'VAR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,132,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[27,27,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,27,-283,27,-6,27,269,-284,-285,-24,313,-300,-301,-304,-305,-308,-309,-330,-331,269,269,-322,269,269,269,269,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,27,269,27,27,27,-327,-329,27,27,-286,-290,-312,-313,27,27,27,27,-332,27,27,-287,-288,-289,27,-293,-314,-328,-333,27,27,-294,27,27,27,-291,27,-295,-315,-292,]),'SEMI':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,28,29,31,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,89,92,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,125,126,130,132,133,134,135,136,137,138,139,140,141,144,146,147,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,306,308,312,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,335,336,337,338,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,382,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,429,430,449,451,453,455,456,458,460,464,467,468,471,476,478,479,480,481,482,485,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,510,512,515,516,518,519,524,525,527,528,529,532,533,541,543,545,546,548,549,550,553,554,556,557,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[28,28,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,28,-283,125,28,133,136,139,146,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-6,28,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,303,-273,-277,-284,-285,-24,-1,-300,-301,327,-304,-305,329,-308,-309,331,335,-330,-331,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-278,-270,427,-135,-298,-299,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,28,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,28,28,-1,482,-279,-275,28,-327,-329,-125,-128,-112,28,28,-121,-107,-94,-286,-290,526,-296,-297,-1,-280,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-312,-313,-246,-85,28,-334,-242,28,28,549,552,-276,-279,-282,28,-332,-335,28,28,-287,-288,-289,-280,28,-293,-244,-314,-328,-333,-336,28,28,-294,28,28,28,-337,-291,28,-295,-315,-292,]),'IF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[30,30,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,30,-283,30,-6,30,259,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,259,259,-322,259,259,259,259,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,30,259,30,30,30,-327,-329,30,30,-286,-290,-312,-313,30,30,30,30,-332,30,30,-287,-288,-289,30,-293,-314,-328,-333,30,30,-294,30,30,30,-291,30,-295,-315,-292,]),'DO':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[31,31,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,-283,31,-6,31,254,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,254,254,-322,254,254,254,254,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,31,254,31,31,31,-327,-329,31,31,-286,-290,-312,-313,31,31,31,31,-332,31,31,-287,-288,-289,31,-293,-314,-328,-333,31,31,-294,31,31,31,-291,31,-295,-315,-292,]),'WHILE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,129,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[32,32,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,32,-283,32,-6,32,271,-284,-285,310,-24,-300,-301,-304,-305,-308,-309,-330,-331,271,271,-322,271,271,271,271,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,32,271,32,32,32,-327,-329,32,32,-286,-290,-312,-313,32,32,32,32,-332,32,32,-287,-288,-289,32,-293,-314,-328,-333,32,32,-294,32,32,32,-291,32,-295,-315,-292,]),'FOR':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[33,33,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,33,-283,33,-6,33,257,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,257,257,-322,257,257,257,257,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,33,257,33,33,33,-327,-329,33,33,-286,-290,-312,-313,33,33,33,33,-332,33,33,-287,-288,-289,33,-293,-314,-328,-333,33,33,-294,33,33,33,-291,33,-295,-315,-292,]),'CONTINUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[34,34,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,34,-283,34,-6,34,250,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,250,250,-322,250,250,250,250,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,34,250,34,34,34,-327,-329,34,34,-286,-290,-312,-313,34,34,34,34,-332,34,34,-287,-288,-289,34,-293,-314,-328,-333,34,34,-294,34,34,34,-291,34,-295,-315,-292,]),'BREAK':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[35,35,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,35,-283,35,-6,35,247,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,247,247,-322,247,247,247,247,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,35,247,35,35,35,-327,-329,35,35,-286,-290,-312,-313,35,35,35,35,-332,35,35,-287,-288,-289,35,-293,-314,-328,-333,35,35,-294,35,35,35,-291,35,-295,-315,-292,]),'RETURN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[36,36,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,36,-283,36,-6,36,263,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,263,263,-322,263,263,263,263,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,36,263,36,36,36,-327,-329,36,36,-286,-290,-312,-313,36,36,36,36,-332,36,36,-287,-288,-289,36,-293,-314,-328,-333,36,36,-294,36,36,36,-291,36,-295,-315,-292,]),'WITH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[37,37,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,37,-283,37,-6,37,272,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,272,272,-322,272,272,272,272,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,37,272,37,37,37,-327,-329,37,37,-286,-290,-312,-313,37,37,37,37,-332,37,37,-287,-288,-289,37,-293,-314,-328,-333,37,37,-294,37,37,37,-291,37,-295,-315,-292,]),'SWITCH':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[38,38,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,38,-283,38,-6,38,264,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,264,264,-322,264,264,264,264,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,38,264,38,38,38,-327,-329,38,38,-286,-290,-312,-313,38,38,38,38,-332,38,38,-287,-288,-289,38,-293,-314,-328,-333,38,38,-294,38,38,38,-291,38,-295,-315,-292,]),'THROW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[39,39,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,39,-283,39,-6,39,266,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,266,266,-322,266,266,266,266,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,39,266,39,39,39,-327,-329,39,39,-286,-290,-312,-313,39,39,39,39,-332,39,39,-287,-288,-289,39,-293,-314,-328,-333,39,39,-294,39,39,39,-291,39,-295,-315,-292,]),'TRY':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[40,40,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,40,-283,40,-6,40,267,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,267,267,-322,267,267,267,267,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,40,267,40,40,40,-327,-329,40,40,-286,-290,-312,-313,40,40,40,40,-332,40,40,-287,-288,-289,40,-293,-314,-328,-333,40,40,-294,40,40,40,-291,40,-295,-315,-292,]),'DEBUGGER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,31,89,92,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,382,399,424,426,449,451,453,460,464,476,478,506,507,515,519,524,533,541,545,546,548,549,550,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[41,41,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,41,-283,41,-6,41,251,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,251,251,-322,251,251,251,251,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,41,251,41,41,41,-327,-329,41,41,-286,-290,-312,-313,41,41,41,41,-332,41,41,-287,-288,-289,41,-293,-314,-328,-333,41,41,-294,41,41,41,-291,41,-295,-315,-292,]),'ID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,31,34,35,36,39,51,52,77,78,82,83,84,85,86,87,88,89,91,92,102,109,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,307,313,327,328,329,330,331,332,335,336,337,338,357,358,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,452,453,454,457,459,460,464,466,475,476,478,482,483,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[43,43,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,43,43,43,43,-283,43,43,43,43,43,43,-1,43,43,43,43,43,43,43,43,43,-6,43,43,43,43,43,-284,-285,43,43,-24,43,43,-300,-301,-304,-305,-308,-309,43,43,-330,-331,43,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,43,43,43,43,43,43,43,43,43,-90,-88,-89,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-322,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-25,-271,-272,43,43,43,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,-327,43,-329,43,43,43,43,43,43,43,-286,-290,43,43,43,43,-312,-313,43,43,43,43,43,43,43,43,-332,43,43,-287,-288,-289,43,43,-293,-314,-328,-333,43,43,-294,43,43,43,-291,43,-295,-315,-292,]),'NEW':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[51,51,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,102,51,-283,51,102,102,102,-1,102,102,102,102,102,102,102,102,102,-6,51,102,262,-284,-285,102,102,-24,102,102,-300,-301,-304,-305,-308,-309,102,102,-330,-331,102,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,102,51,102,262,102,51,102,262,102,-90,-88,-89,51,51,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-322,102,102,102,102,102,262,102,102,262,102,102,262,262,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-25,-271,-272,102,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,51,262,102,51,102,51,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,51,-327,-329,102,102,102,51,51,102,-286,-290,102,102,102,-312,-313,51,51,51,102,102,51,102,102,-332,51,51,-287,-288,-289,102,51,-293,-314,-328,-333,51,51,-294,51,51,51,-291,51,-295,-315,-292,]),'THIS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[57,57,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,57,57,-283,57,57,57,57,-1,57,57,57,57,57,57,57,57,57,-6,57,57,265,-284,-285,57,57,-24,57,57,-300,-301,-304,-305,-308,-309,57,57,-330,-331,57,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,57,57,57,265,57,57,57,265,57,-90,-88,-89,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-322,57,57,57,57,57,265,57,57,265,57,57,265,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-25,-271,-272,57,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,57,265,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,-327,-329,57,57,57,57,57,57,-286,-290,57,57,57,-312,-313,57,57,57,57,57,57,57,57,-332,57,57,-287,-288,-289,57,57,-293,-314,-328,-333,57,57,-294,57,57,57,-291,57,-295,-315,-292,]),'LPAREN':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,31,32,33,36,37,38,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,90,92,99,101,102,104,105,107,108,109,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,234,235,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,310,327,328,329,330,331,332,335,336,337,338,339,346,347,352,353,354,356,357,358,382,390,393,394,398,400,401,402,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[25,25,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,91,-78,25,25,-283,128,25,131,132,25,142,143,25,-37,168,168,25,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,25,25,25,25,25,25,25,25,25,-6,211,25,168,168,25,-105,-106,-76,-77,91,-78,-284,-285,25,25,-24,25,25,-300,-301,-304,-305,-308,-309,25,25,-330,-331,25,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,25,25,-124,25,25,25,-123,25,168,25,-90,-88,-89,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-322,-82,25,25,25,25,-120,25,25,-119,25,168,25,25,397,-92,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-25,-271,-272,25,425,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,452,-126,-127,-113,-114,-83,-84,-1,-91,25,-122,-108,-109,-93,25,474,475,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,-327,-329,25,-125,-128,25,-112,25,25,25,25,-121,-107,-94,-286,-290,25,25,25,-312,-313,-85,25,-334,25,25,25,25,25,25,25,-332,-335,25,25,-287,-288,-289,25,25,-293,-314,-328,-333,-336,25,25,-294,25,25,25,-337,-291,25,-295,-315,-292,]),'LBRACKET':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,48,50,51,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,99,101,102,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,216,217,218,221,222,223,224,226,227,228,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[52,52,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,52,52,-283,52,52,52,-37,166,171,52,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,52,52,52,52,52,52,52,52,52,-6,52,224,228,52,-105,-106,-76,-77,-78,-284,-285,52,52,-24,52,52,-300,-301,-304,-305,-308,-309,52,52,-330,-331,52,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,52,52,-124,52,52,52,-123,52,228,52,-90,-88,-89,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-322,-82,52,52,52,52,-120,52,52,-119,52,228,52,52,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-25,-271,-272,52,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-126,-127,-113,-114,-83,-84,-1,-91,52,-122,-108,-109,-93,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,-327,-329,52,-125,-128,52,-112,52,52,52,52,-121,-107,-94,-286,-290,52,52,52,-312,-313,-85,52,-334,52,52,52,52,52,52,52,-332,-335,52,52,-287,-288,-289,52,52,-293,-314,-328,-333,-336,52,52,-294,52,52,52,-337,-291,52,-295,-315,-292,]),'NULL':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[67,67,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,67,67,-283,67,67,67,67,-1,67,67,67,67,67,67,67,67,67,-6,67,67,273,-284,-285,67,67,-24,67,67,-300,-301,-304,-305,-308,-309,67,67,-330,-331,67,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,67,67,67,273,67,67,67,273,67,-90,-88,-89,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-322,67,67,67,67,67,273,67,67,273,67,67,273,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-25,-271,-272,67,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,67,273,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,-327,-329,67,67,67,67,67,67,-286,-290,67,67,67,-312,-313,67,67,67,67,67,67,67,67,-332,67,67,-287,-288,-289,67,67,-293,-314,-328,-333,67,67,-294,67,67,67,-291,67,-295,-315,-292,]),'TRUE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[68,68,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,68,68,-283,68,68,68,68,-1,68,68,68,68,68,68,68,68,68,-6,68,68,274,-284,-285,68,68,-24,68,68,-300,-301,-304,-305,-308,-309,68,68,-330,-331,68,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,68,68,68,274,68,68,68,274,68,-90,-88,-89,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-322,68,68,68,68,68,274,68,68,274,68,68,274,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-25,-271,-272,68,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,68,274,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,-327,-329,68,68,68,68,68,68,-286,-290,68,68,68,-312,-313,68,68,68,68,68,68,68,68,-332,68,68,-287,-288,-289,68,68,-293,-314,-328,-333,68,68,-294,68,68,68,-291,68,-295,-315,-292,]),'FALSE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[69,69,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,69,69,-283,69,69,69,69,-1,69,69,69,69,69,69,69,69,69,-6,69,69,275,-284,-285,69,69,-24,69,69,-300,-301,-304,-305,-308,-309,69,69,-330,-331,69,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,69,69,69,275,69,69,69,275,69,-90,-88,-89,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-322,69,69,69,69,69,275,69,69,275,69,69,275,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-25,-271,-272,69,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,69,275,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,-327,-329,69,69,69,69,69,69,-286,-290,69,69,69,-312,-313,69,69,69,69,69,69,69,69,-332,69,69,-287,-288,-289,69,69,-293,-314,-328,-333,69,69,-294,69,69,69,-291,69,-295,-315,-292,]),'NUMBER':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[70,70,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,70,70,-283,70,70,70,70,-1,70,70,70,70,70,70,70,70,70,-6,70,70,70,-284,-285,70,70,-24,70,70,-300,-301,-304,-305,-308,-309,70,70,-330,-331,70,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,70,70,70,70,70,70,70,-90,-88,-89,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-322,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-25,-271,-272,70,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,-327,-329,70,70,70,70,70,70,-286,-290,70,70,70,-312,-313,70,70,70,70,70,70,70,70,-332,70,70,-287,-288,-289,70,70,-293,-314,-328,-333,70,70,-294,70,70,70,-291,70,-295,-315,-292,]),'STRING':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[71,71,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,71,71,-283,71,71,71,71,-1,71,71,71,71,71,71,71,71,71,-6,71,71,71,-284,-285,71,71,-24,71,71,-300,-301,-304,-305,-308,-309,71,71,-330,-331,71,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,71,71,71,71,71,71,71,-90,-88,-89,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-322,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-25,-271,-272,71,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,-327,-329,71,71,71,71,71,71,-286,-290,71,71,71,-312,-313,71,71,71,71,71,71,71,71,-332,71,71,-287,-288,-289,71,71,-293,-314,-328,-333,71,71,-294,71,71,71,-291,71,-295,-315,-292,]),'REGEX':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,51,52,77,78,82,83,84,85,86,87,88,89,92,102,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[72,72,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,72,72,-283,72,72,72,72,-1,72,72,72,72,72,72,72,72,72,-6,72,72,-284,-285,72,72,-24,72,72,-300,-301,-304,-305,-308,-309,72,72,-330,-331,72,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,72,72,72,72,72,72,72,-90,-88,-89,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-322,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-25,-271,-272,72,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-327,-329,72,72,72,72,72,72,-286,-290,72,72,72,-312,-313,72,72,72,72,72,72,72,72,-332,72,72,-287,-288,-289,72,72,-293,-314,-328,-333,72,72,-294,72,72,72,-291,72,-295,-315,-292,]),'DELETE':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[84,84,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,84,84,-283,84,84,84,-1,84,84,84,84,84,84,84,84,84,-6,84,253,-284,-285,84,84,-24,84,84,-300,-301,-304,-305,-308,-309,84,84,-330,-331,84,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,84,84,84,253,84,84,84,253,84,-90,-88,-89,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-322,84,84,84,84,84,253,84,84,253,84,84,253,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-25,-271,-272,84,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,84,253,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-327,-329,84,84,84,84,84,84,-286,-290,84,84,84,-312,-313,84,84,84,84,84,84,84,84,-332,84,84,-287,-288,-289,84,84,-293,-314,-328,-333,84,84,-294,84,84,84,-291,84,-295,-315,-292,]),'VOID':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[85,85,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,85,85,-283,85,85,85,-1,85,85,85,85,85,85,85,85,85,-6,85,270,-284,-285,85,85,-24,85,85,-300,-301,-304,-305,-308,-309,85,85,-330,-331,85,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,85,85,85,270,85,85,85,270,85,-90,-88,-89,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-322,85,85,85,85,85,270,85,85,270,85,85,270,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-25,-271,-272,85,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,85,270,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-327,-329,85,85,85,85,85,85,-286,-290,85,85,85,-312,-313,85,85,85,85,85,85,85,85,-332,85,85,-287,-288,-289,85,85,-293,-314,-328,-333,85,85,-294,85,85,85,-291,85,-295,-315,-292,]),'TYPEOF':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,110,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,167,168,169,171,172,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[86,86,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,86,86,-283,86,86,86,-1,86,86,86,86,86,86,86,86,86,-6,86,268,-284,-285,86,86,-24,86,86,-300,-301,-304,-305,-308,-309,86,86,-330,-331,86,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,86,86,86,268,86,86,86,268,86,-90,-88,-89,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-322,86,86,86,86,86,268,86,86,268,86,86,268,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-25,-271,-272,86,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,86,268,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-327,-329,86,86,86,86,86,86,-286,-290,86,86,86,-312,-313,86,86,86,86,86,86,86,86,-332,86,86,-287,-288,-289,86,86,-293,-314,-328,-333,86,86,-294,86,86,86,-291,86,-295,-315,-292,]),'PLUSPLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[82,82,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,82,82,-283,82,82,82,-37,149,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,82,82,82,82,82,82,82,82,82,-6,82,219,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,82,82,-24,82,82,-300,-301,-304,-305,-308,-309,82,82,-330,-331,82,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,82,82,-124,82,82,82,-123,82,-118,-115,82,-90,-88,-89,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,219,-322,-82,82,82,82,82,-120,82,82,-119,82,-116,-115,82,82,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-25,-271,-272,82,219,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,149,-126,-127,-113,-114,-83,-84,-1,-91,82,-122,-108,-109,-93,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,-327,-329,82,-125,-128,82,-112,82,82,82,82,-121,-107,-94,-286,-290,82,82,82,219,-312,-313,-85,82,-334,82,82,82,82,82,82,82,-332,-335,82,82,-287,-288,-289,82,82,-293,-314,-328,-333,-336,82,82,-294,82,82,82,-337,-291,82,-295,-315,-292,]),'MINUSMINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,77,78,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,202,215,216,217,218,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,382,390,393,394,398,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[83,83,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,83,83,-283,83,83,83,-37,150,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,83,83,83,83,83,83,83,83,83,-6,83,220,-131,-132,-115,-105,-106,-76,-77,-78,-284,-285,83,83,-24,83,83,-300,-301,-304,-305,-308,-309,83,83,-330,-331,83,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,83,83,-124,83,83,83,-123,83,-118,-115,83,-90,-88,-89,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,220,-322,-82,83,83,83,83,-120,83,83,-119,83,-116,-115,83,83,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-25,-271,-272,83,220,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,150,-126,-127,-113,-114,-83,-84,-1,-91,83,-122,-108,-109,-93,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-327,-329,83,-125,-128,83,-112,83,83,83,83,-121,-107,-94,-286,-290,83,83,83,220,-312,-313,-85,83,-334,83,83,83,83,83,83,83,-332,-335,83,83,-287,-288,-289,83,83,-293,-314,-328,-333,-336,83,83,-294,83,83,83,-337,-291,83,-295,-315,-292,]),'PLUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[77,77,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,77,77,-283,77,77,77,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,196,-165,77,77,-158,-143,-144,77,77,77,77,77,77,77,-6,77,-135,-131,-132,-115,-105,-106,-76,-77,-78,297,-162,-154,-141,-142,-284,-285,77,77,-24,77,77,-300,-301,-304,-305,-308,-309,77,77,-330,-331,77,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,77,77,-124,77,77,77,-123,77,-118,-115,77,-90,-88,-89,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,77,77,-136,-137,77,77,-120,77,77,-119,77,-116,-115,77,77,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-25,-271,-272,77,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,297,297,297,-166,-167,-159,-160,-161,77,-122,-108,-109,-93,77,297,297,297,-163,-164,-155,-156,-157,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,-327,-329,77,-125,-128,77,-112,77,77,77,77,-121,-107,-94,-286,-290,77,77,77,-135,-312,-313,-85,77,-334,77,77,77,77,77,77,77,-332,-335,77,77,-287,-288,-289,77,77,-293,-314,-328,-333,-336,77,77,-294,77,77,77,-337,-291,77,-295,-315,-292,]),'MINUS':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,28,31,36,39,43,45,47,48,50,52,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,96,98,99,101,104,105,107,108,111,116,117,118,119,120,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,168,169,170,171,173,174,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,215,216,217,218,219,220,221,222,223,224,226,227,228,230,231,232,233,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,314,327,328,329,330,331,332,335,336,337,338,344,346,347,352,353,354,356,357,358,372,373,374,375,376,377,378,379,382,390,393,394,398,400,414,415,416,417,418,419,420,421,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,455,456,457,458,459,460,464,466,467,468,471,476,478,482,484,486,488,506,507,512,515,516,519,524,526,531,533,534,539,541,543,545,546,548,549,550,552,554,556,558,563,564,565,568,569,571,572,574,575,576,579,580,581,582,586,],[78,78,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-78,78,78,-283,78,78,78,-37,-138,-133,-134,-117,-1,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,197,-165,78,78,-158,-143,-144,78,78,78,78,78,78,78,-6,78,-135,-131,-132,-115,-105,-106,-76,-77,-78,298,-162,-154,-141,-142,-284,-285,78,78,-24,78,78,-300,-301,-304,-305,-308,-309,78,78,-330,-331,78,-139,-140,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,78,78,-124,78,78,78,-123,78,-118,-115,78,-90,-88,-89,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,78,78,-136,-137,78,78,-120,78,78,-119,78,-116,-115,78,78,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-25,-271,-272,78,-135,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-138,-126,-127,-113,-114,-83,-84,-1,-91,298,298,298,-166,-167,-159,-160,-161,78,-122,-108,-109,-93,78,298,298,298,-163,-164,-155,-156,-157,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,-327,-329,78,-125,-128,78,-112,78,78,78,78,-121,-107,-94,-286,-290,78,78,78,-135,-312,-313,-85,78,-334,78,78,78,78,78,78,78,-332,-335,78,78,-287,-288,-289,78,78,-293,-314,-328,-333,-336,78,78,-294,78,78,78,-337,-291,78,-295,-315,-292,]),'BNOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[87,87,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,87,87,-283,87,87,87,-1,87,87,87,87,87,87,87,87,87,-6,87,-284,-285,87,87,-24,87,87,-300,-301,-304,-305,-308,-309,87,87,-330,-331,87,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,87,87,87,87,87,87,87,-90,-88,-89,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-322,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-25,-271,-272,87,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,-327,-329,87,87,87,87,87,87,-286,-290,87,87,87,-312,-313,87,87,87,87,87,87,87,87,-332,87,87,-287,-288,-289,87,87,-293,-314,-328,-333,87,87,-294,87,87,87,-291,87,-295,-315,-292,]),'NOT':([0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,26,28,31,36,39,52,77,78,82,83,84,85,86,87,88,89,92,125,126,127,128,130,131,132,133,134,136,137,139,140,142,143,146,147,148,151,152,153,154,155,156,157,158,159,160,161,162,163,164,166,168,169,171,175,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,215,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,307,327,328,329,330,331,332,335,336,337,338,357,358,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,451,453,454,457,459,460,464,466,476,478,482,484,486,506,507,515,519,524,526,531,533,534,539,541,545,546,548,549,550,552,554,556,558,563,564,568,569,571,572,574,575,579,580,581,582,586,],[88,88,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,88,88,-283,88,88,88,-1,88,88,88,88,88,88,88,88,88,-6,88,-284,-285,88,88,-24,88,88,-300,-301,-304,-305,-308,-309,88,88,-330,-331,88,-253,-254,-255,-256,-257,-258,-259,-260,-261,-262,-263,-264,88,88,88,88,88,88,88,-90,-88,-89,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-322,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-25,-271,-272,88,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-1,-91,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-327,-329,88,88,88,88,88,88,-286,-290,88,88,88,-312,-313,88,88,88,88,88,88,88,88,-332,88,88,-287,-288,-289,88,88,-293,-314,-328,-333,88,88,-294,88,88,88,-291,88,-295,-315,-292,]),'RBRACE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,89,95,96,97,98,99,100,101,103,104,105,106,107,108,110,111,112,113,114,115,116,117,118,119,120,121,125,126,130,133,134,136,137,139,140,146,147,201,202,203,204,205,206,207,208,209,210,215,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,302,303,304,327,328,329,330,331,332,335,336,337,338,347,354,356,382,386,388,390,391,393,394,395,396,398,399,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,451,453,456,460,462,463,464,467,468,471,472,473,476,478,506,507,508,512,514,515,516,517,518,519,535,536,537,538,541,542,543,544,545,546,548,549,550,556,558,559,561,563,564,565,566,567,568,571,573,574,575,576,577,578,579,581,582,583,584,585,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-1,-283,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-6,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,235,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,302,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-322,-82,-136,-137,-120,-119,-116,-115,-92,398,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,-127,-83,-84,-1,-248,-236,-122,-230,-108,-109,-224,-218,-93,471,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-327,-329,-128,-1,516,-340,-1,-121,-107,-94,-96,-97,-286,-290,-312,-313,-1,-85,541,-1,-334,543,-242,-1,558,-316,-317,-318,-332,564,-335,565,-1,-1,-287,-288,-289,-293,-314,-1,-319,-328,-333,-336,576,577,-1,-294,582,-1,-1,-337,-98,585,-291,-295,-315,-321,-320,-99,-292,]),'CASE':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,537,538,541,548,549,550,556,558,559,561,563,564,571,574,575,579,581,582,583,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,248,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,248,248,-322,248,248,248,248,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,248,-327,-329,-286,-290,-312,-313,539,539,-318,-332,-287,-288,-289,-293,-314,539,-319,-328,-333,-294,-1,-1,-291,-295,-315,-321,-320,-292,]),'DEFAULT':([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,89,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,508,535,536,537,538,541,548,549,550,556,558,561,563,564,571,575,579,581,582,584,586,],[-3,-4,-5,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,-6,252,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,252,252,-322,252,252,252,252,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,252,-327,-329,-286,-290,-312,-313,-1,560,-316,-317,-318,-332,-287,-288,-289,-293,-314,-319,-328,-333,-294,-1,-291,-295,-315,-320,-292,]),'ELSE':([8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,28,110,125,126,130,133,134,136,137,139,140,146,147,167,172,215,225,229,239,240,302,303,304,327,328,329,330,331,332,335,336,337,338,399,451,453,476,478,506,507,541,548,549,550,556,558,563,564,571,579,581,582,586,],[-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-283,255,-284,-285,-24,-300,-301,-304,-305,-308,-309,-330,-331,255,255,-322,255,255,255,255,-25,-271,-272,-302,-303,-306,-307,-310,-311,-323,-324,-325,-326,255,-327,-329,524,-290,-312,-313,-332,-287,-288,-289,-293,-314,-328,-333,-294,-291,-295,-315,-292,]),'COLON':([24,43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,238,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,318,319,320,321,322,323,324,325,326,342,347,354,356,385,386,387,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,467,468,471,488,489,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,518,543,557,560,562,565,576,],[92,-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,400,-101,-102,-103,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-249,-243,-237,-231,-225,-219,-213,-201,-183,454,-127,-83,-84,-266,-248,466,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-121,-107,-94,-135,-250,534,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-242,-335,-244,574,575,-336,-337,]),'PERIOD':([24,43,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,99,101,104,105,107,108,111,165,170,174,216,223,227,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,512,516,541,543,564,565,576,],[-78,-37,167,172,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,225,229,-105,-106,-76,-77,-78,-124,-123,229,-82,-120,-119,229,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,-85,-334,-336,-335,-337,-336,-337,]),'EQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,124,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,429,455,456,458,467,468,471,488,512,516,529,541,543,564,565,576,],[-78,-37,151,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,151,-131,-132,-115,-105,-106,-76,-77,-78,307,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,151,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,486,-125,-128,-112,-121,-107,-94,151,-85,-334,486,-336,-335,-337,-336,-337,]),'MULTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,152,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,152,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,152,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,152,-85,-334,-336,-335,-337,-336,-337,]),'DIVEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,153,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,153,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,153,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,153,-85,-334,-336,-335,-337,-336,-337,]),'MODEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,154,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,154,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,154,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,154,-85,-334,-336,-335,-337,-336,-337,]),'PLUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,155,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,155,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,155,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,155,-85,-334,-336,-335,-337,-336,-337,]),'MINUSEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,156,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,156,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,156,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,156,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,157,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,157,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,157,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,157,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,158,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,158,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,158,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,158,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFTEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,159,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,159,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,159,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,159,-85,-334,-336,-335,-337,-336,-337,]),'ANDEQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,160,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,160,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,160,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,160,-85,-334,-336,-335,-337,-336,-337,]),'XOREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,161,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,161,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,161,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,161,-85,-334,-336,-335,-337,-336,-337,]),'OREQUAL':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,96,98,99,101,104,105,107,108,111,165,170,173,174,216,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,346,347,352,353,354,356,390,393,394,398,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,162,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,162,-131,-132,-115,-105,-106,-76,-77,-78,-124,-123,-118,-115,-82,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,162,-126,-127,-113,-114,-83,-84,-122,-108,-109,-93,-125,-128,-112,-121,-107,-94,162,-85,-334,-336,-335,-337,-336,-337,]),'MULT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,198,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,299,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,299,299,-159,-160,-161,-122,-108,-109,-93,299,299,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'DIV':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,199,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,300,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,300,300,-159,-160,-161,-122,-108,-109,-93,300,300,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'MOD':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,76,79,80,81,96,98,99,101,104,105,107,108,111,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,344,346,347,352,353,354,356,375,376,377,378,379,390,393,394,398,417,418,419,420,421,455,456,458,467,468,471,488,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,200,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,301,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,-138,-126,-127,-113,-114,-83,-84,301,301,-159,-160,-161,-122,-108,-109,-93,301,301,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-85,-334,-336,-335,-337,-336,-337,]),'LSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,193,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,294,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,294,-138,-126,-127,-113,-114,-83,-84,294,294,294,294,294,294,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,294,294,294,294,294,294,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,294,294,294,294,294,-85,-334,-336,-335,-337,-336,-337,]),'RSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,194,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,295,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,295,-138,-126,-127,-113,-114,-83,-84,295,295,295,295,295,295,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,295,295,295,295,295,295,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,295,295,295,295,295,-85,-334,-336,-335,-337,-336,-337,]),'URSHIFT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,326,344,346,347,352,353,354,356,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,195,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,296,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,296,-138,-126,-127,-113,-114,-83,-84,296,296,296,296,296,296,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,296,296,296,296,296,296,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,296,296,296,296,296,-85,-334,-336,-335,-337,-336,-337,]),'LT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,187,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,288,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,444,-183,-138,-126,-127,-113,-114,-83,-84,288,288,288,288,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,288,288,288,288,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,288,288,288,288,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GT':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,188,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,289,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,445,-183,-138,-126,-127,-113,-114,-83,-84,289,289,289,289,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,289,289,289,289,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,289,289,289,289,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'LE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,189,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,290,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,446,-183,-138,-126,-127,-113,-114,-83,-84,290,290,290,290,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,290,290,290,290,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,290,290,290,290,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'GE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,190,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,291,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,447,-183,-138,-126,-127,-113,-114,-83,-84,291,291,291,291,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,291,291,291,291,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,291,291,291,291,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'INSTANCEOF':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,191,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,261,-78,292,-176,-168,-162,-154,-141,-142,-139,-140,-124,261,-123,261,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,261,-119,261,-116,-115,-92,261,261,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,448,-183,-138,-126,-127,-113,-114,-83,-84,292,292,292,292,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,261,292,292,292,292,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,292,292,292,292,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'IN':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,110,111,114,115,116,117,118,119,120,149,150,165,167,170,172,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,225,227,229,230,231,235,239,240,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,318,319,320,321,322,323,324,325,326,344,346,347,352,353,354,356,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,399,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,429,455,456,458,467,468,471,485,488,489,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,532,541,543,557,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,192,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,260,-78,293,-176,-168,-162,-154,-141,-142,-139,-140,-124,260,-123,260,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,260,-119,260,-116,-115,-92,260,260,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,431,-249,-243,-237,-231,-225,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,293,293,293,293,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,260,293,293,293,293,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,484,-125,-128,-112,-121,-107,-94,531,-135,-250,-238,-232,-226,-220,-214,293,293,293,293,-184,-185,-186,-187,-188,-85,-334,-282,-336,-335,-244,-337,-336,-337,]),'EQEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,183,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,284,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,440,-201,-183,-138,-126,-127,-113,-114,-83,-84,183,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,284,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,440,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'NE':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,184,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,285,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,441,-201,-183,-138,-126,-127,-113,-114,-83,-84,184,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,285,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,441,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STREQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,185,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,286,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,442,-201,-183,-138,-126,-127,-113,-114,-83,-84,185,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,286,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,442,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'STRNEQ':([24,43,45,47,48,50,54,55,57,58,59,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,324,325,326,344,346,347,352,353,354,356,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,-26,-27,-28,-29,-30,186,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,287,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,443,-201,-183,-138,-126,-127,-113,-114,-83,-84,186,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,-93,287,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,443,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BAND':([24,43,45,47,48,50,54,55,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,323,324,325,326,344,346,347,352,353,354,356,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,-79,-80,-81,182,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,-76,-77,-78,283,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,439,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,182,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,283,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,439,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BXOR':([24,43,45,47,48,50,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,322,323,324,325,326,344,346,347,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,-110,-111,181,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,-105,-106,233,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,438,-219,-213,-201,-183,-138,-126,-127,-113,-114,-83,-84,181,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,-108,-109,233,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,438,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'BOR':([24,43,45,47,48,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,321,322,323,324,325,326,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,-117,180,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,-115,232,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,437,-225,-219,-213,-201,-183,-138,-126,-127,180,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-122,232,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,437,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AND':([24,43,45,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,-133,-134,169,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,-131,-132,226,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,436,-231,-225,-219,-213,-201,-183,169,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,226,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,436,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'CONDOP':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,163,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,221,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,434,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'OR':([24,43,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,314,319,320,321,322,323,324,325,326,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,455,456,458,467,468,471,488,492,493,494,495,496,497,498,499,500,501,502,503,504,505,512,516,541,543,564,565,576,],[-78,-37,-138,164,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-135,222,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-135,435,-237,-231,-225,-219,-213,-201,-183,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-125,-128,-112,-121,-107,-94,-135,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-85,-334,-336,-335,-337,-336,-337,]),'AUTOSEMI':([24,29,34,35,36,41,42,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,135,138,141,144,149,150,165,170,173,174,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,341,343,344,346,347,350,352,353,354,356,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,385,386,388,390,391,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,455,456,458,467,468,471,510,512,516,518,525,541,543,564,565,576,],[-78,126,134,137,140,147,-269,-37,-251,-138,-245,-133,-134,-239,-117,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,304,-273,-277,328,330,332,336,-139,-140,-124,-123,-118,-115,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,-252,-240,-138,-126,-127,-234,-113,-114,-83,-84,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,-266,-248,-236,-122,-230,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,-125,-128,-112,-121,-107,-94,-246,-85,-334,-242,550,-336,-335,-337,-336,-337,]),'COMMA':([24,29,42,43,44,45,46,47,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,80,81,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,122,123,124,141,144,149,150,165,170,173,174,176,177,179,201,202,203,204,205,206,207,208,209,210,213,214,216,219,220,223,227,230,231,235,236,237,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,306,308,309,311,314,316,317,318,319,320,321,322,323,324,325,326,333,334,341,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,381,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,428,429,430,455,456,458,465,467,468,470,471,472,473,477,481,485,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,510,511,512,513,516,518,528,529,530,532,541,543,553,555,557,562,564,565,576,577,585,],[-78,127,-269,-37,-251,-138,-245,-133,-134,-239,-117,177,-233,-110,-111,-227,-79,-80,-81,-221,-26,-27,-28,-29,-30,-215,-33,-31,-32,-34,-35,-36,-206,-189,-172,-165,-158,-143,-144,217,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,305,-273,-277,217,217,-139,-140,-124,-123,-118,-115,357,-90,358,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,384,-338,-82,-136,-137,-120,-119,-116,-115,-92,399,-95,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-278,-270,217,217,-135,433,-267,-249,-243,-237,-231,-225,-219,-213,-201,-183,217,217,-252,-240,-138,217,-126,-127,457,-129,-234,217,-113,-114,-83,-86,-84,177,-91,-228,-222,-216,-207,-208,-209,-210,-190,-191,-192,-193,-194,-195,-173,-174,-175,-166,-167,-159,-160,-161,384,-266,-248,-236,217,-122,-230,217,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-274,-281,483,-279,-275,-125,-128,-112,-339,-121,-107,384,-94,-96,-97,217,217,-280,217,-135,-250,-268,-238,-232,-226,-220,-214,-202,-203,-204,-205,-184,-185,-186,-187,-188,-246,-130,-85,-87,-334,-242,-276,-279,217,-282,-336,-335,-280,217,-244,217,-337,-336,-337,-98,-99,]),'RPAREN':([43,57,58,59,61,62,63,64,65,67,68,69,70,71,72,91,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,168,201,202,203,204,205,206,207,208,209,210,211,213,214,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,309,311,333,334,347,348,349,354,356,381,385,386,388,390,391,393,394,395,396,397,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,465,467,468,470,471,474,477,480,481,487,509,511,512,516,518,522,523,526,530,543,551,552,555,565,570,576,],[-37,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,212,216,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,347,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,380,383,-338,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,424,426,449,450,-127,456,-129,-83,-84,461,-266,-248,-236,-122,-230,-108,-109,-224,-218,469,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,-339,-121,-107,520,-94,521,525,-296,-297,533,540,-130,-85,-334,-242,547,-104,-1,554,-335,569,-1,572,-336,580,-337,]),'RBRACKET':([43,52,57,58,59,61,62,63,64,65,67,68,69,70,71,72,94,95,96,97,98,99,100,101,103,104,105,106,107,108,111,112,113,114,115,116,117,118,119,120,175,176,177,178,179,201,202,203,204,205,206,207,208,209,210,216,219,220,223,227,230,231,235,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,345,347,351,354,355,356,357,358,385,386,388,389,390,391,392,393,394,395,396,398,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,456,459,467,468,471,512,513,516,518,543,565,576,],[-37,-1,-79,-80,-81,-26,-27,-28,-29,-30,-33,-31,-32,-34,-35,-36,-265,-247,-135,-241,-131,-132,-235,-115,-229,-105,-106,-223,-76,-77,-78,-217,-211,-196,-176,-168,-162,-154,-141,-142,354,356,-90,-88,-89,-150,-135,-151,-148,-149,-145,-146,-147,-152,-153,-82,-136,-137,-120,-119,-116,-115,-92,-100,-74,-75,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,455,-127,458,-83,-86,-84,-1,-91,-266,-248,-236,467,-122,-230,468,-108,-109,-224,-218,-93,-212,-197,-198,-199,-200,-177,-178,-179,-180,-181,-182,-169,-170,-171,-163,-164,-155,-156,-157,-128,512,-121,-107,-94,-85,-87,-334,-242,-335,-336,-337,]),'GETPROP':([110,399,],[239,239,]),'SETPROP':([110,399,],[240,240,]),'CATCH':([110,145,167,172,225,229,239,240,302,399,],[249,339,249,249,249,249,249,249,-25,249,]),'FINALLY':([110,145,167,172,225,229,239,240,302,337,399,563,],[256,340,256,256,256,256,256,256,-25,340,256,-328,]),'CLASS':([110,167,172,225,229,239,240,399,],[276,276,276,276,276,276,276,276,]),'CONST':([110,167,172,225,229,239,240,399,],[277,277,277,277,277,277,277,277,]),'ENUM':([110,167,172,225,229,239,240,399,],[278,278,278,278,278,278,278,278,]),'EXPORT':([110,167,172,225,229,239,240,399,],[279,279,279,279,279,279,279,279,]),'EXTENDS':([110,167,172,225,229,239,240,399,],[280,280,280,280,280,280,280,280,]),'IMPORT':([110,167,172,225,229,239,240,399,],[281,281,281,281,281,281,281,281,]),'SUPER':([110,167,172,225,229,239,240,399,],[282,282,282,282,282,282,282,282,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'source_elements':([0,26,382,460,464,515,519,545,546,568,574,575,],[2,121,463,463,463,463,463,463,463,463,583,584,]),'empty':([0,26,52,132,357,382,427,460,464,482,508,515,519,526,545,546,552,559,568,574,575,],[3,3,178,315,178,3,480,3,3,480,536,3,3,480,3,3,480,536,3,3,3,]),'source_element_list':([0,26,382,460,464,515,519,545,546,568,574,575,],[4,4,4,4,4,4,4,4,4,4,4,4,]),'source_element':([0,4,26,382,460,464,515,519,545,546,568,574,575,],[5,89,5,5,5,5,5,5,5,5,5,5,5,]),'statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[6,6,6,129,215,6,476,478,506,6,6,6,6,548,556,6,6,571,6,579,581,6,6,586,]),'function_declaration':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[7,7,7,130,130,7,130,130,130,7,7,7,7,130,130,7,7,130,7,130,130,7,7,130,]),'block':([0,4,26,31,40,92,340,382,424,426,449,460,464,515,519,524,533,540,545,546,554,568,569,572,574,575,580,],[8,8,8,8,145,8,453,8,8,8,8,8,8,8,8,8,8,563,8,8,8,8,8,8,8,8,8,]),'variable_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'empty_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'expr_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'if_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'iteration_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'continue_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'break_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'return_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'with_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'switch_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,]),'labelled_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'throw_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,]),'try_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,]),'debugger_statement':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,]),'identifier':([0,4,23,25,26,27,31,34,35,36,39,51,77,78,82,83,84,85,86,87,88,91,92,102,109,110,127,128,131,132,142,143,148,163,164,166,167,168,169,171,172,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,211,217,218,221,222,224,225,226,228,229,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,305,307,313,382,384,397,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,452,454,457,459,460,464,466,475,482,483,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[24,24,90,111,24,124,24,135,138,111,111,111,111,111,111,111,111,111,111,111,111,214,24,111,234,245,111,111,111,111,111,111,111,111,111,111,245,111,111,111,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,214,111,111,111,111,111,245,111,111,245,111,111,245,245,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,124,111,429,24,465,214,245,111,24,111,24,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,24,509,111,111,111,24,24,111,523,111,529,111,111,24,24,24,111,111,24,111,111,24,24,111,24,24,24,24,24,24,24,]),'expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,]),'assignment_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'conditional_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,]),'left_hand_side_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[45,45,45,45,45,344,344,344,344,344,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'logical_or_expr_nobf':([0,4,26,31,92,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,]),'new_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'call_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,]),'logical_and_expr_nobf':([0,4,26,31,92,164,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[49,49,49,49,49,343,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'member_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,]),'bitwise_or_expr_nobf':([0,4,26,31,92,164,169,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[53,53,53,53,53,53,350,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,]),'primary_expr_no_brace':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[54,54,107,54,54,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,107,107,107,107,107,107,54,107,107,54,107,107,54,54,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,54,107,54,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,54,107,107,107,54,54,107,107,107,107,54,54,54,107,107,54,107,107,54,54,107,54,54,54,54,54,54,54,]),'function_expr':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[55,55,105,55,55,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,105,105,105,105,105,105,55,105,105,55,105,105,55,55,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,55,105,55,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,55,105,105,105,55,55,105,105,105,105,55,55,55,105,105,55,105,105,55,55,105,55,55,55,55,55,55,55,]),'bitwise_xor_expr_nobf':([0,4,26,31,92,164,169,180,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[56,56,56,56,56,56,56,359,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,]),'literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,]),'array_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,]),'bitwise_and_expr_nobf':([0,4,26,31,92,164,169,180,181,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[60,60,60,60,60,60,60,60,360,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,]),'null_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,]),'boolean_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,]),'numeric_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,243,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,]),'string_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,110,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,239,240,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,399,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,242,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,]),'regex_literal':([0,4,25,26,31,36,39,51,77,78,82,83,84,85,86,87,88,92,102,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,]),'equality_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[66,66,66,66,66,66,66,66,66,361,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,]),'relational_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,]),'shift_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,]),'additive_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,]),'multiplicative_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,]),'unary_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,]),'postfix_expr_nobf':([0,4,26,31,92,164,169,180,181,182,382,424,426,449,460,464,515,519,524,533,545,546,554,568,569,572,574,575,580,],[80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,]),'unary_expr_common':([0,4,25,26,31,36,39,77,78,82,83,84,85,86,87,88,92,127,128,131,132,142,143,148,163,164,166,168,169,171,175,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,382,400,424,425,426,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,454,457,459,460,464,466,482,484,486,515,519,524,526,531,533,534,539,545,546,552,554,568,569,572,574,575,580,],[81,81,120,81,81,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,120,120,120,120,120,81,120,120,81,120,120,81,81,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,81,120,81,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,81,120,120,120,81,81,120,120,120,120,81,81,81,120,120,81,120,120,81,81,120,81,81,81,81,81,81,81,]),'expr':([25,36,39,128,131,142,143,166,171,224,228,425,427,431,482,484,526,531,539,552,],[93,141,144,309,311,333,334,345,351,389,392,477,481,487,481,530,481,555,562,481,]),'assignment_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[94,94,94,308,94,94,94,94,341,342,94,349,94,355,385,386,387,94,94,423,473,94,94,94,510,511,513,518,94,94,94,94,94,94,]),'conditional_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'left_hand_side_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[96,96,96,202,202,202,202,202,202,202,202,202,96,96,96,314,96,96,96,96,96,96,96,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,202,96,202,96,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,488,488,488,202,202,202,202,202,202,202,202,202,202,202,202,202,202,96,96,96,96,96,96,488,96,96,488,96,96,]),'logical_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'new_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[98,98,98,173,98,98,98,98,98,98,98,98,98,230,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'call_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'logical_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,388,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'member_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[101,101,101,174,101,101,101,101,101,101,101,101,101,231,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'bitwise_or_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,391,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'primary_expr':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'bitwise_xor_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,395,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,]),'object_literal':([25,36,39,51,77,78,82,83,84,85,86,87,88,102,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,]),'bitwise_and_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,396,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,]),'equality_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,217,218,221,222,224,226,228,232,233,283,307,400,425,427,431,454,457,459,466,482,484,526,531,539,552,],[113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,403,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,]),'relational_expr':([25,36,39,127,128,131,142,143,148,163,166,168,171,175,183,184,185,186,217,218,221,222,224,226,228,232,233,283,284,285,286,287,307,400,425,427,431,440,441,442,443,454,457,459,466,482,484,526,531,539,552,],[114,114,114,114,114,114,114,114,114,114,114,114,114,114,362,363,364,365,114,114,114,114,114,114,114,114,114,114,404,405,406,407,114,114,114,114,114,497,498,499,500,114,114,114,114,114,114,114,114,114,114,]),'shift_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[115,115,115,115,115,115,326,115,115,115,115,115,115,115,115,115,115,115,115,366,367,368,369,370,371,115,115,115,115,115,115,115,115,115,115,115,115,115,115,408,409,410,411,412,413,115,115,115,115,115,326,326,326,326,326,326,326,326,115,115,115,115,501,502,503,504,505,115,115,115,115,115,115,326,115,115,326,115,115,]),'additive_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,372,373,374,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,414,415,416,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,]),'multiplicative_expr':([25,36,39,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,375,376,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,417,418,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,]),'unary_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[118,118,118,201,203,204,205,206,207,208,209,210,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,377,378,379,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,419,420,421,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,]),'postfix_expr':([25,36,39,77,78,82,83,84,85,86,87,88,127,128,131,132,142,143,148,163,166,168,171,175,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,217,218,221,222,224,226,228,232,233,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,307,400,425,427,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,454,457,459,466,482,484,486,526,531,534,539,552,],[119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,]),'variable_declaration_list':([27,],[122,]),'variable_declaration':([27,305,],[123,422,]),'assignment_operator':([45,96,314,488,],[148,218,432,432,]),'arguments':([48,50,99,101,174,231,],[165,170,223,227,353,394,]),'elision_opt':([52,357,],[175,459,]),'element_list':([52,],[176,]),'elision':([52,357,],[179,179,]),'formal_parameter_list':([91,211,397,],[213,381,470,]),'property_list':([110,],[236,]),'property_assignment':([110,399,],[237,472,]),'property_name':([110,239,240,399,],[238,401,402,238,]),'identifier_name_string':([110,167,172,225,229,239,240,399,],[241,346,352,390,393,241,241,241,]),'identifier_name':([110,167,172,225,229,239,240,399,],[244,244,244,244,244,244,244,244,]),'reserved_word':([110,167,172,225,229,239,240,399,],[246,246,246,246,246,246,246,246,]),'initializer':([124,],[306,]),'expr_noin_opt':([132,],[312,]),'expr_noin':([132,],[316,]),'assignment_expr_noin':([132,432,433,434,486,534,],[317,489,490,491,532,557,]),'conditional_expr_noin':([132,432,433,434,486,534,],[318,318,318,318,318,318,]),'logical_or_expr_noin':([132,432,433,434,486,534,],[319,319,319,319,319,319,]),'logical_and_expr_noin':([132,432,433,434,435,486,534,],[320,320,320,320,492,320,320,]),'bitwise_or_expr_noin':([132,432,433,434,435,436,486,534,],[321,321,321,321,321,493,321,321,]),'bitwise_xor_expr_noin':([132,432,433,434,435,436,437,486,534,],[322,322,322,322,322,322,494,322,322,]),'bitwise_and_expr_noin':([132,432,433,434,435,436,437,438,486,534,],[323,323,323,323,323,323,323,495,323,323,]),'equality_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[324,324,324,324,324,324,324,324,496,324,324,]),'relational_expr_noin':([132,432,433,434,435,436,437,438,439,486,534,],[325,325,325,325,325,325,325,325,325,325,325,]),'catch':([145,],[337,]),'finally':([145,337,],[338,451,]),'argument_list':([168,],[348,]),'variable_declaration_list_noin':([313,],[428,]),'variable_declaration_noin':([313,483,],[430,528,]),'function_body':([382,460,464,515,519,545,546,568,],[462,514,517,542,544,566,567,578,]),'expr_opt':([427,482,526,552,],[479,527,551,570,]),'initializer_noin':([429,529,],[485,553,]),'case_block':([450,],[507,]),'property_set_parameter_list':([475,],[522,]),'case_clauses_opt':([508,559,],[535,573,]),'case_clauses':([508,559,],[537,537,]),'case_clause':([508,537,559,],[538,561,538,]),'default_clause':([535,],[559,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('empty -> ','empty',0,'p_empty','es5.py',122), + ('program -> source_elements','program',1,'p_program','es5.py',157), + ('source_elements -> empty','source_elements',1,'p_source_elements','es5.py',164), + ('source_elements -> source_element_list','source_elements',1,'p_source_elements','es5.py',165), + ('source_element_list -> source_element','source_element_list',1,'p_source_element_list','es5.py',170), + ('source_element_list -> source_element_list source_element','source_element_list',2,'p_source_element_list','es5.py',171), + ('source_element -> statement','source_element',1,'p_source_element','es5.py',180), + ('source_element -> function_declaration','source_element',1,'p_source_element','es5.py',181), + ('statement -> block','statement',1,'p_statement','es5.py',186), + ('statement -> variable_statement','statement',1,'p_statement','es5.py',187), + ('statement -> empty_statement','statement',1,'p_statement','es5.py',188), + ('statement -> expr_statement','statement',1,'p_statement','es5.py',189), + ('statement -> if_statement','statement',1,'p_statement','es5.py',190), + ('statement -> iteration_statement','statement',1,'p_statement','es5.py',191), + ('statement -> continue_statement','statement',1,'p_statement','es5.py',192), + ('statement -> break_statement','statement',1,'p_statement','es5.py',193), + ('statement -> return_statement','statement',1,'p_statement','es5.py',194), + ('statement -> with_statement','statement',1,'p_statement','es5.py',195), + ('statement -> switch_statement','statement',1,'p_statement','es5.py',196), + ('statement -> labelled_statement','statement',1,'p_statement','es5.py',197), + ('statement -> throw_statement','statement',1,'p_statement','es5.py',198), + ('statement -> try_statement','statement',1,'p_statement','es5.py',199), + ('statement -> debugger_statement','statement',1,'p_statement','es5.py',200), + ('statement -> function_declaration','statement',1,'p_statement','es5.py',201), + ('block -> LBRACE source_elements RBRACE','block',3,'p_block','es5.py',208), + ('literal -> null_literal','literal',1,'p_literal','es5.py',213), + ('literal -> boolean_literal','literal',1,'p_literal','es5.py',214), + ('literal -> numeric_literal','literal',1,'p_literal','es5.py',215), + ('literal -> string_literal','literal',1,'p_literal','es5.py',216), + ('literal -> regex_literal','literal',1,'p_literal','es5.py',217), + ('boolean_literal -> TRUE','boolean_literal',1,'p_boolean_literal','es5.py',222), + ('boolean_literal -> FALSE','boolean_literal',1,'p_boolean_literal','es5.py',223), + ('null_literal -> NULL','null_literal',1,'p_null_literal','es5.py',229), + ('numeric_literal -> NUMBER','numeric_literal',1,'p_numeric_literal','es5.py',234), + ('string_literal -> STRING','string_literal',1,'p_string_literal','es5.py',239), + ('regex_literal -> REGEX','regex_literal',1,'p_regex_literal','es5.py',244), + ('identifier -> ID','identifier',1,'p_identifier','es5.py',249), + ('reserved_word -> BREAK','reserved_word',1,'p_reserved_word','es5.py',256), + ('reserved_word -> CASE','reserved_word',1,'p_reserved_word','es5.py',257), + ('reserved_word -> CATCH','reserved_word',1,'p_reserved_word','es5.py',258), + ('reserved_word -> CONTINUE','reserved_word',1,'p_reserved_word','es5.py',259), + ('reserved_word -> DEBUGGER','reserved_word',1,'p_reserved_word','es5.py',260), + ('reserved_word -> DEFAULT','reserved_word',1,'p_reserved_word','es5.py',261), + ('reserved_word -> DELETE','reserved_word',1,'p_reserved_word','es5.py',262), + ('reserved_word -> DO','reserved_word',1,'p_reserved_word','es5.py',263), + ('reserved_word -> ELSE','reserved_word',1,'p_reserved_word','es5.py',264), + ('reserved_word -> FINALLY','reserved_word',1,'p_reserved_word','es5.py',265), + ('reserved_word -> FOR','reserved_word',1,'p_reserved_word','es5.py',266), + ('reserved_word -> FUNCTION','reserved_word',1,'p_reserved_word','es5.py',267), + ('reserved_word -> IF','reserved_word',1,'p_reserved_word','es5.py',268), + ('reserved_word -> IN','reserved_word',1,'p_reserved_word','es5.py',269), + ('reserved_word -> INSTANCEOF','reserved_word',1,'p_reserved_word','es5.py',270), + ('reserved_word -> NEW','reserved_word',1,'p_reserved_word','es5.py',271), + ('reserved_word -> RETURN','reserved_word',1,'p_reserved_word','es5.py',272), + ('reserved_word -> SWITCH','reserved_word',1,'p_reserved_word','es5.py',273), + ('reserved_word -> THIS','reserved_word',1,'p_reserved_word','es5.py',274), + ('reserved_word -> THROW','reserved_word',1,'p_reserved_word','es5.py',275), + ('reserved_word -> TRY','reserved_word',1,'p_reserved_word','es5.py',276), + ('reserved_word -> TYPEOF','reserved_word',1,'p_reserved_word','es5.py',277), + ('reserved_word -> VAR','reserved_word',1,'p_reserved_word','es5.py',278), + ('reserved_word -> VOID','reserved_word',1,'p_reserved_word','es5.py',279), + ('reserved_word -> WHILE','reserved_word',1,'p_reserved_word','es5.py',280), + ('reserved_word -> WITH','reserved_word',1,'p_reserved_word','es5.py',281), + ('reserved_word -> NULL','reserved_word',1,'p_reserved_word','es5.py',282), + ('reserved_word -> TRUE','reserved_word',1,'p_reserved_word','es5.py',283), + ('reserved_word -> FALSE','reserved_word',1,'p_reserved_word','es5.py',284), + ('reserved_word -> CLASS','reserved_word',1,'p_reserved_word','es5.py',285), + ('reserved_word -> CONST','reserved_word',1,'p_reserved_word','es5.py',286), + ('reserved_word -> ENUM','reserved_word',1,'p_reserved_word','es5.py',287), + ('reserved_word -> EXPORT','reserved_word',1,'p_reserved_word','es5.py',288), + ('reserved_word -> EXTENDS','reserved_word',1,'p_reserved_word','es5.py',289), + ('reserved_word -> IMPORT','reserved_word',1,'p_reserved_word','es5.py',290), + ('reserved_word -> SUPER','reserved_word',1,'p_reserved_word','es5.py',291), + ('identifier_name -> identifier','identifier_name',1,'p_identifier_name','es5.py',297), + ('identifier_name -> reserved_word','identifier_name',1,'p_identifier_name','es5.py',298), + ('primary_expr -> primary_expr_no_brace','primary_expr',1,'p_primary_expr','es5.py',306), + ('primary_expr -> object_literal','primary_expr',1,'p_primary_expr','es5.py',307), + ('primary_expr_no_brace -> identifier','primary_expr_no_brace',1,'p_primary_expr_no_brace_1','es5.py',312), + ('primary_expr_no_brace -> THIS','primary_expr_no_brace',1,'p_primary_expr_no_brace_2','es5.py',316), + ('primary_expr_no_brace -> literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',321), + ('primary_expr_no_brace -> array_literal','primary_expr_no_brace',1,'p_primary_expr_no_brace_3','es5.py',322), + ('primary_expr_no_brace -> LPAREN expr RPAREN','primary_expr_no_brace',3,'p_primary_expr_no_brace_4','es5.py',327), + ('array_literal -> LBRACKET elision_opt RBRACKET','array_literal',3,'p_array_literal_1','es5.py',336), + ('array_literal -> LBRACKET element_list RBRACKET','array_literal',3,'p_array_literal_2','es5.py',341), + ('array_literal -> LBRACKET element_list COMMA elision_opt RBRACKET','array_literal',5,'p_array_literal_2','es5.py',342), + ('element_list -> elision_opt assignment_expr','element_list',2,'p_element_list','es5.py',351), + ('element_list -> element_list COMMA elision_opt assignment_expr','element_list',4,'p_element_list','es5.py',352), + ('elision_opt -> empty','elision_opt',1,'p_elision_opt_1','es5.py',362), + ('elision_opt -> elision','elision_opt',1,'p_elision_opt_2','es5.py',366), + ('elision -> COMMA','elision',1,'p_elision','es5.py',370), + ('elision -> elision COMMA','elision',2,'p_elision','es5.py',371), + ('object_literal -> LBRACE RBRACE','object_literal',2,'p_object_literal','es5.py',387), + ('object_literal -> LBRACE property_list RBRACE','object_literal',3,'p_object_literal','es5.py',388), + ('object_literal -> LBRACE property_list COMMA RBRACE','object_literal',4,'p_object_literal','es5.py',389), + ('property_list -> property_assignment','property_list',1,'p_property_list','es5.py',398), + ('property_list -> property_list COMMA property_assignment','property_list',3,'p_property_list','es5.py',399), + ('property_assignment -> property_name COLON assignment_expr','property_assignment',3,'p_property_assignment','es5.py',409), + ('property_assignment -> GETPROP property_name LPAREN RPAREN LBRACE function_body RBRACE','property_assignment',7,'p_property_assignment','es5.py',410), + ('property_assignment -> SETPROP property_name LPAREN property_set_parameter_list RPAREN LBRACE function_body RBRACE','property_assignment',8,'p_property_assignment','es5.py',411), + ('identifier_name_string -> identifier_name','identifier_name_string',1,'p_identifier_name_string','es5.py',432), + ('property_name -> identifier_name_string','property_name',1,'p_property_name','es5.py',441), + ('property_name -> string_literal','property_name',1,'p_property_name','es5.py',442), + ('property_name -> numeric_literal','property_name',1,'p_property_name','es5.py',443), + ('property_set_parameter_list -> identifier','property_set_parameter_list',1,'p_property_set_parameter_list','es5.py',448), + ('member_expr -> primary_expr','member_expr',1,'p_member_expr','es5.py',457), + ('member_expr -> function_expr','member_expr',1,'p_member_expr','es5.py',458), + ('member_expr -> member_expr LBRACKET expr RBRACKET','member_expr',4,'p_member_expr','es5.py',459), + ('member_expr -> member_expr PERIOD identifier_name_string','member_expr',3,'p_member_expr','es5.py',460), + ('member_expr -> NEW member_expr arguments','member_expr',3,'p_member_expr','es5.py',461), + ('member_expr_nobf -> primary_expr_no_brace','member_expr_nobf',1,'p_member_expr_nobf','es5.py',478), + ('member_expr_nobf -> function_expr','member_expr_nobf',1,'p_member_expr_nobf','es5.py',479), + ('member_expr_nobf -> member_expr_nobf LBRACKET expr RBRACKET','member_expr_nobf',4,'p_member_expr_nobf','es5.py',480), + ('member_expr_nobf -> member_expr_nobf PERIOD identifier_name_string','member_expr_nobf',3,'p_member_expr_nobf','es5.py',481), + ('member_expr_nobf -> NEW member_expr arguments','member_expr_nobf',3,'p_member_expr_nobf','es5.py',482), + ('new_expr -> member_expr','new_expr',1,'p_new_expr','es5.py',499), + ('new_expr -> NEW new_expr','new_expr',2,'p_new_expr','es5.py',500), + ('new_expr_nobf -> member_expr_nobf','new_expr_nobf',1,'p_new_expr_nobf','es5.py',509), + ('new_expr_nobf -> NEW new_expr','new_expr_nobf',2,'p_new_expr_nobf','es5.py',510), + ('call_expr -> member_expr arguments','call_expr',2,'p_call_expr','es5.py',519), + ('call_expr -> call_expr arguments','call_expr',2,'p_call_expr','es5.py',520), + ('call_expr -> call_expr LBRACKET expr RBRACKET','call_expr',4,'p_call_expr','es5.py',521), + ('call_expr -> call_expr PERIOD identifier_name_string','call_expr',3,'p_call_expr','es5.py',522), + ('call_expr_nobf -> member_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',535), + ('call_expr_nobf -> call_expr_nobf arguments','call_expr_nobf',2,'p_call_expr_nobf','es5.py',536), + ('call_expr_nobf -> call_expr_nobf LBRACKET expr RBRACKET','call_expr_nobf',4,'p_call_expr_nobf','es5.py',537), + ('call_expr_nobf -> call_expr_nobf PERIOD identifier_name_string','call_expr_nobf',3,'p_call_expr_nobf','es5.py',538), + ('arguments -> LPAREN RPAREN','arguments',2,'p_arguments','es5.py',551), + ('arguments -> LPAREN argument_list RPAREN','arguments',3,'p_arguments','es5.py',552), + ('argument_list -> assignment_expr','argument_list',1,'p_argument_list','es5.py',561), + ('argument_list -> argument_list COMMA assignment_expr','argument_list',3,'p_argument_list','es5.py',562), + ('left_hand_side_expr -> new_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',571), + ('left_hand_side_expr -> call_expr','left_hand_side_expr',1,'p_lef_hand_side_expr','es5.py',572), + ('left_hand_side_expr_nobf -> new_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',577), + ('left_hand_side_expr_nobf -> call_expr_nobf','left_hand_side_expr_nobf',1,'p_lef_hand_side_expr_nobf','es5.py',578), + ('postfix_expr -> left_hand_side_expr','postfix_expr',1,'p_postfix_expr','es5.py',584), + ('postfix_expr -> left_hand_side_expr PLUSPLUS','postfix_expr',2,'p_postfix_expr','es5.py',585), + ('postfix_expr -> left_hand_side_expr MINUSMINUS','postfix_expr',2,'p_postfix_expr','es5.py',586), + ('postfix_expr_nobf -> left_hand_side_expr_nobf','postfix_expr_nobf',1,'p_postfix_expr_nobf','es5.py',595), + ('postfix_expr_nobf -> left_hand_side_expr_nobf PLUSPLUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',596), + ('postfix_expr_nobf -> left_hand_side_expr_nobf MINUSMINUS','postfix_expr_nobf',2,'p_postfix_expr_nobf','es5.py',597), + ('unary_expr -> postfix_expr','unary_expr',1,'p_unary_expr','es5.py',607), + ('unary_expr -> unary_expr_common','unary_expr',1,'p_unary_expr','es5.py',608), + ('unary_expr_nobf -> postfix_expr_nobf','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',613), + ('unary_expr_nobf -> unary_expr_common','unary_expr_nobf',1,'p_unary_expr_nobf','es5.py',614), + ('unary_expr_common -> DELETE unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',619), + ('unary_expr_common -> VOID unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',620), + ('unary_expr_common -> TYPEOF unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',621), + ('unary_expr_common -> PLUSPLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',622), + ('unary_expr_common -> MINUSMINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',623), + ('unary_expr_common -> PLUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',624), + ('unary_expr_common -> MINUS unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',625), + ('unary_expr_common -> BNOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',626), + ('unary_expr_common -> NOT unary_expr','unary_expr_common',2,'p_unary_expr_common','es5.py',627), + ('multiplicative_expr -> unary_expr','multiplicative_expr',1,'p_multiplicative_expr','es5.py',634), + ('multiplicative_expr -> multiplicative_expr MULT unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',635), + ('multiplicative_expr -> multiplicative_expr DIV unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',636), + ('multiplicative_expr -> multiplicative_expr MOD unary_expr','multiplicative_expr',3,'p_multiplicative_expr','es5.py',637), + ('multiplicative_expr_nobf -> unary_expr_nobf','multiplicative_expr_nobf',1,'p_multiplicative_expr_nobf','es5.py',646), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MULT unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',647), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf DIV unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',648), + ('multiplicative_expr_nobf -> multiplicative_expr_nobf MOD unary_expr','multiplicative_expr_nobf',3,'p_multiplicative_expr_nobf','es5.py',649), + ('additive_expr -> multiplicative_expr','additive_expr',1,'p_additive_expr','es5.py',659), + ('additive_expr -> additive_expr PLUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',660), + ('additive_expr -> additive_expr MINUS multiplicative_expr','additive_expr',3,'p_additive_expr','es5.py',661), + ('additive_expr_nobf -> multiplicative_expr_nobf','additive_expr_nobf',1,'p_additive_expr_nobf','es5.py',670), + ('additive_expr_nobf -> additive_expr_nobf PLUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',671), + ('additive_expr_nobf -> additive_expr_nobf MINUS multiplicative_expr','additive_expr_nobf',3,'p_additive_expr_nobf','es5.py',672), + ('shift_expr -> additive_expr','shift_expr',1,'p_shift_expr','es5.py',682), + ('shift_expr -> shift_expr LSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',683), + ('shift_expr -> shift_expr RSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',684), + ('shift_expr -> shift_expr URSHIFT additive_expr','shift_expr',3,'p_shift_expr','es5.py',685), + ('shift_expr_nobf -> additive_expr_nobf','shift_expr_nobf',1,'p_shift_expr_nobf','es5.py',694), + ('shift_expr_nobf -> shift_expr_nobf LSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',695), + ('shift_expr_nobf -> shift_expr_nobf RSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',696), + ('shift_expr_nobf -> shift_expr_nobf URSHIFT additive_expr','shift_expr_nobf',3,'p_shift_expr_nobf','es5.py',697), + ('relational_expr -> shift_expr','relational_expr',1,'p_relational_expr','es5.py',707), + ('relational_expr -> relational_expr LT shift_expr','relational_expr',3,'p_relational_expr','es5.py',708), + ('relational_expr -> relational_expr GT shift_expr','relational_expr',3,'p_relational_expr','es5.py',709), + ('relational_expr -> relational_expr LE shift_expr','relational_expr',3,'p_relational_expr','es5.py',710), + ('relational_expr -> relational_expr GE shift_expr','relational_expr',3,'p_relational_expr','es5.py',711), + ('relational_expr -> relational_expr INSTANCEOF shift_expr','relational_expr',3,'p_relational_expr','es5.py',712), + ('relational_expr -> relational_expr IN shift_expr','relational_expr',3,'p_relational_expr','es5.py',713), + ('relational_expr_noin -> shift_expr','relational_expr_noin',1,'p_relational_expr_noin','es5.py',722), + ('relational_expr_noin -> relational_expr_noin LT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',723), + ('relational_expr_noin -> relational_expr_noin GT shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',724), + ('relational_expr_noin -> relational_expr_noin LE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',725), + ('relational_expr_noin -> relational_expr_noin GE shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',726), + ('relational_expr_noin -> relational_expr_noin INSTANCEOF shift_expr','relational_expr_noin',3,'p_relational_expr_noin','es5.py',727), + ('relational_expr_nobf -> shift_expr_nobf','relational_expr_nobf',1,'p_relational_expr_nobf','es5.py',736), + ('relational_expr_nobf -> relational_expr_nobf LT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',737), + ('relational_expr_nobf -> relational_expr_nobf GT shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',738), + ('relational_expr_nobf -> relational_expr_nobf LE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',739), + ('relational_expr_nobf -> relational_expr_nobf GE shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',740), + ('relational_expr_nobf -> relational_expr_nobf INSTANCEOF shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',741), + ('relational_expr_nobf -> relational_expr_nobf IN shift_expr','relational_expr_nobf',3,'p_relational_expr_nobf','es5.py',742), + ('equality_expr -> relational_expr','equality_expr',1,'p_equality_expr','es5.py',752), + ('equality_expr -> equality_expr EQEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',753), + ('equality_expr -> equality_expr NE relational_expr','equality_expr',3,'p_equality_expr','es5.py',754), + ('equality_expr -> equality_expr STREQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',755), + ('equality_expr -> equality_expr STRNEQ relational_expr','equality_expr',3,'p_equality_expr','es5.py',756), + ('equality_expr_noin -> relational_expr_noin','equality_expr_noin',1,'p_equality_expr_noin','es5.py',765), + ('equality_expr_noin -> equality_expr_noin EQEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',766), + ('equality_expr_noin -> equality_expr_noin NE relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',767), + ('equality_expr_noin -> equality_expr_noin STREQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',768), + ('equality_expr_noin -> equality_expr_noin STRNEQ relational_expr','equality_expr_noin',3,'p_equality_expr_noin','es5.py',769), + ('equality_expr_nobf -> relational_expr_nobf','equality_expr_nobf',1,'p_equality_expr_nobf','es5.py',778), + ('equality_expr_nobf -> equality_expr_nobf EQEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',779), + ('equality_expr_nobf -> equality_expr_nobf NE relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',780), + ('equality_expr_nobf -> equality_expr_nobf STREQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',781), + ('equality_expr_nobf -> equality_expr_nobf STRNEQ relational_expr','equality_expr_nobf',3,'p_equality_expr_nobf','es5.py',782), + ('bitwise_and_expr -> equality_expr','bitwise_and_expr',1,'p_bitwise_and_expr','es5.py',792), + ('bitwise_and_expr -> bitwise_and_expr BAND equality_expr','bitwise_and_expr',3,'p_bitwise_and_expr','es5.py',793), + ('bitwise_and_expr_noin -> equality_expr_noin','bitwise_and_expr_noin',1,'p_bitwise_and_expr_noin','es5.py',802), + ('bitwise_and_expr_noin -> bitwise_and_expr_noin BAND equality_expr_noin','bitwise_and_expr_noin',3,'p_bitwise_and_expr_noin','es5.py',803), + ('bitwise_and_expr_nobf -> equality_expr_nobf','bitwise_and_expr_nobf',1,'p_bitwise_and_expr_nobf','es5.py',813), + ('bitwise_and_expr_nobf -> bitwise_and_expr_nobf BAND equality_expr_nobf','bitwise_and_expr_nobf',3,'p_bitwise_and_expr_nobf','es5.py',814), + ('bitwise_xor_expr -> bitwise_and_expr','bitwise_xor_expr',1,'p_bitwise_xor_expr','es5.py',824), + ('bitwise_xor_expr -> bitwise_xor_expr BXOR bitwise_and_expr','bitwise_xor_expr',3,'p_bitwise_xor_expr','es5.py',825), + ('bitwise_xor_expr_noin -> bitwise_and_expr_noin','bitwise_xor_expr_noin',1,'p_bitwise_xor_expr_noin','es5.py',835), + ('bitwise_xor_expr_noin -> bitwise_xor_expr_noin BXOR bitwise_and_expr_noin','bitwise_xor_expr_noin',3,'p_bitwise_xor_expr_noin','es5.py',836), + ('bitwise_xor_expr_nobf -> bitwise_and_expr_nobf','bitwise_xor_expr_nobf',1,'p_bitwise_xor_expr_nobf','es5.py',847), + ('bitwise_xor_expr_nobf -> bitwise_xor_expr_nobf BXOR bitwise_and_expr_nobf','bitwise_xor_expr_nobf',3,'p_bitwise_xor_expr_nobf','es5.py',848), + ('bitwise_or_expr -> bitwise_xor_expr','bitwise_or_expr',1,'p_bitwise_or_expr','es5.py',858), + ('bitwise_or_expr -> bitwise_or_expr BOR bitwise_xor_expr','bitwise_or_expr',3,'p_bitwise_or_expr','es5.py',859), + ('bitwise_or_expr_noin -> bitwise_xor_expr_noin','bitwise_or_expr_noin',1,'p_bitwise_or_expr_noin','es5.py',869), + ('bitwise_or_expr_noin -> bitwise_or_expr_noin BOR bitwise_xor_expr_noin','bitwise_or_expr_noin',3,'p_bitwise_or_expr_noin','es5.py',870), + ('bitwise_or_expr_nobf -> bitwise_xor_expr_nobf','bitwise_or_expr_nobf',1,'p_bitwise_or_expr_nobf','es5.py',881), + ('bitwise_or_expr_nobf -> bitwise_or_expr_nobf BOR bitwise_xor_expr_nobf','bitwise_or_expr_nobf',3,'p_bitwise_or_expr_nobf','es5.py',882), + ('logical_and_expr -> bitwise_or_expr','logical_and_expr',1,'p_logical_and_expr','es5.py',893), + ('logical_and_expr -> logical_and_expr AND bitwise_or_expr','logical_and_expr',3,'p_logical_and_expr','es5.py',894), + ('logical_and_expr_noin -> bitwise_or_expr_noin','logical_and_expr_noin',1,'p_logical_and_expr_noin','es5.py',904), + ('logical_and_expr_noin -> logical_and_expr_noin AND bitwise_or_expr_noin','logical_and_expr_noin',3,'p_logical_and_expr_noin','es5.py',905), + ('logical_and_expr_nobf -> bitwise_or_expr_nobf','logical_and_expr_nobf',1,'p_logical_and_expr_nobf','es5.py',915), + ('logical_and_expr_nobf -> logical_and_expr_nobf AND bitwise_or_expr_nobf','logical_and_expr_nobf',3,'p_logical_and_expr_nobf','es5.py',916), + ('logical_or_expr -> logical_and_expr','logical_or_expr',1,'p_logical_or_expr','es5.py',925), + ('logical_or_expr -> logical_or_expr OR logical_and_expr','logical_or_expr',3,'p_logical_or_expr','es5.py',926), + ('logical_or_expr_noin -> logical_and_expr_noin','logical_or_expr_noin',1,'p_logical_or_expr_noin','es5.py',935), + ('logical_or_expr_noin -> logical_or_expr_noin OR logical_and_expr_noin','logical_or_expr_noin',3,'p_logical_or_expr_noin','es5.py',936), + ('logical_or_expr_nobf -> logical_and_expr_nobf','logical_or_expr_nobf',1,'p_logical_or_expr_nobf','es5.py',945), + ('logical_or_expr_nobf -> logical_or_expr_nobf OR logical_and_expr_nobf','logical_or_expr_nobf',3,'p_logical_or_expr_nobf','es5.py',946), + ('conditional_expr -> logical_or_expr','conditional_expr',1,'p_conditional_expr','es5.py',957), + ('conditional_expr -> logical_or_expr CONDOP assignment_expr COLON assignment_expr','conditional_expr',5,'p_conditional_expr','es5.py',958), + ('conditional_expr_noin -> logical_or_expr_noin','conditional_expr_noin',1,'p_conditional_expr_noin','es5.py',970), + ('conditional_expr_noin -> logical_or_expr_noin CONDOP assignment_expr_noin COLON assignment_expr_noin','conditional_expr_noin',5,'p_conditional_expr_noin','es5.py',971), + ('conditional_expr_nobf -> logical_or_expr_nobf','conditional_expr_nobf',1,'p_conditional_expr_nobf','es5.py',984), + ('conditional_expr_nobf -> logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr','conditional_expr_nobf',5,'p_conditional_expr_nobf','es5.py',985), + ('assignment_expr -> conditional_expr','assignment_expr',1,'p_assignment_expr','es5.py',998), + ('assignment_expr -> left_hand_side_expr assignment_operator assignment_expr','assignment_expr',3,'p_assignment_expr','es5.py',999), + ('assignment_expr_noin -> conditional_expr_noin','assignment_expr_noin',1,'p_assignment_expr_noin','es5.py',1010), + ('assignment_expr_noin -> left_hand_side_expr assignment_operator assignment_expr_noin','assignment_expr_noin',3,'p_assignment_expr_noin','es5.py',1011), + ('assignment_expr_nobf -> conditional_expr_nobf','assignment_expr_nobf',1,'p_assignment_expr_nobf','es5.py',1022), + ('assignment_expr_nobf -> left_hand_side_expr_nobf assignment_operator assignment_expr','assignment_expr_nobf',3,'p_assignment_expr_nobf','es5.py',1023), + ('assignment_operator -> EQ','assignment_operator',1,'p_assignment_operator','es5.py',1033), + ('assignment_operator -> MULTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1034), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1035), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1036), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1037), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1038), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1039), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1040), + ('assignment_operator -> URSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1041), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1042), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1043), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','es5.py',1044), + ('expr -> assignment_expr','expr',1,'p_expr','es5.py',1050), + ('expr -> expr COMMA assignment_expr','expr',3,'p_expr','es5.py',1051), + ('expr_noin -> assignment_expr_noin','expr_noin',1,'p_expr_noin','es5.py',1060), + ('expr_noin -> expr_noin COMMA assignment_expr_noin','expr_noin',3,'p_expr_noin','es5.py',1061), + ('expr_nobf -> assignment_expr_nobf','expr_nobf',1,'p_expr_nobf','es5.py',1070), + ('expr_nobf -> expr_nobf COMMA assignment_expr','expr_nobf',3,'p_expr_nobf','es5.py',1071), + ('variable_statement -> VAR variable_declaration_list SEMI','variable_statement',3,'p_variable_statement','es5.py',1081), + ('variable_statement -> VAR variable_declaration_list AUTOSEMI','variable_statement',3,'p_variable_statement','es5.py',1082), + ('variable_declaration_list -> variable_declaration','variable_declaration_list',1,'p_variable_declaration_list','es5.py',1089), + ('variable_declaration_list -> variable_declaration_list COMMA variable_declaration','variable_declaration_list',3,'p_variable_declaration_list','es5.py',1090), + ('variable_declaration_list_noin -> variable_declaration_noin','variable_declaration_list_noin',1,'p_variable_declaration_list_noin','es5.py',1101), + ('variable_declaration_list_noin -> variable_declaration_list_noin COMMA variable_declaration_noin','variable_declaration_list_noin',3,'p_variable_declaration_list_noin','es5.py',1102), + ('variable_declaration -> identifier','variable_declaration',1,'p_variable_declaration','es5.py',1112), + ('variable_declaration -> identifier initializer','variable_declaration',2,'p_variable_declaration','es5.py',1113), + ('variable_declaration_noin -> identifier','variable_declaration_noin',1,'p_variable_declaration_noin','es5.py',1123), + ('variable_declaration_noin -> identifier initializer_noin','variable_declaration_noin',2,'p_variable_declaration_noin','es5.py',1124), + ('initializer -> EQ assignment_expr','initializer',2,'p_initializer','es5.py',1134), + ('initializer_noin -> EQ assignment_expr_noin','initializer_noin',2,'p_initializer_noin','es5.py',1138), + ('empty_statement -> SEMI','empty_statement',1,'p_empty_statement','es5.py',1143), + ('expr_statement -> expr_nobf SEMI','expr_statement',2,'p_expr_statement','es5.py',1149), + ('expr_statement -> expr_nobf AUTOSEMI','expr_statement',2,'p_expr_statement','es5.py',1150), + ('if_statement -> IF LPAREN expr RPAREN statement','if_statement',5,'p_if_statement_1','es5.py',1173), + ('if_statement -> IF LPAREN expr RPAREN statement ELSE statement','if_statement',7,'p_if_statement_2','es5.py',1178), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN SEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1186), + ('iteration_statement -> DO statement WHILE LPAREN expr RPAREN AUTOSEMI','iteration_statement',7,'p_iteration_statement_1','es5.py',1187), + ('iteration_statement -> WHILE LPAREN expr RPAREN statement','iteration_statement',5,'p_iteration_statement_2','es5.py',1194), + ('iteration_statement -> FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','es5.py',1200), + ('iteration_statement -> FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI expr_opt RPAREN statement','iteration_statement',10,'p_iteration_statement_3','es5.py',1201), + ('iteration_statement -> FOR LPAREN left_hand_side_expr IN expr RPAREN statement','iteration_statement',7,'p_iteration_statement_4','es5.py',1233), + ('iteration_statement -> FOR LPAREN VAR identifier IN expr RPAREN statement','iteration_statement',8,'p_iteration_statement_5','es5.py',1241), + ('iteration_statement -> FOR LPAREN VAR identifier initializer_noin IN expr RPAREN statement','iteration_statement',9,'p_iteration_statement_6','es5.py',1251), + ('expr_opt -> empty','expr_opt',1,'p_expr_opt','es5.py',1261), + ('expr_opt -> expr','expr_opt',1,'p_expr_opt','es5.py',1262), + ('expr_noin_opt -> empty','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1267), + ('expr_noin_opt -> expr_noin','expr_noin_opt',1,'p_expr_noin_opt','es5.py',1268), + ('continue_statement -> CONTINUE SEMI','continue_statement',2,'p_continue_statement_1','es5.py',1274), + ('continue_statement -> CONTINUE AUTOSEMI','continue_statement',2,'p_continue_statement_1','es5.py',1275), + ('continue_statement -> CONTINUE identifier SEMI','continue_statement',3,'p_continue_statement_2','es5.py',1281), + ('continue_statement -> CONTINUE identifier AUTOSEMI','continue_statement',3,'p_continue_statement_2','es5.py',1282), + ('break_statement -> BREAK SEMI','break_statement',2,'p_break_statement_1','es5.py',1289), + ('break_statement -> BREAK AUTOSEMI','break_statement',2,'p_break_statement_1','es5.py',1290), + ('break_statement -> BREAK identifier SEMI','break_statement',3,'p_break_statement_2','es5.py',1296), + ('break_statement -> BREAK identifier AUTOSEMI','break_statement',3,'p_break_statement_2','es5.py',1297), + ('return_statement -> RETURN SEMI','return_statement',2,'p_return_statement_1','es5.py',1304), + ('return_statement -> RETURN AUTOSEMI','return_statement',2,'p_return_statement_1','es5.py',1305), + ('return_statement -> RETURN expr SEMI','return_statement',3,'p_return_statement_2','es5.py',1311), + ('return_statement -> RETURN expr AUTOSEMI','return_statement',3,'p_return_statement_2','es5.py',1312), + ('with_statement -> WITH LPAREN expr RPAREN statement','with_statement',5,'p_with_statement','es5.py',1319), + ('switch_statement -> SWITCH LPAREN expr RPAREN case_block','switch_statement',5,'p_switch_statement','es5.py',1325), + ('case_block -> LBRACE case_clauses_opt RBRACE','case_block',3,'p_case_block','es5.py',1335), + ('case_block -> LBRACE case_clauses_opt default_clause case_clauses_opt RBRACE','case_block',5,'p_case_block','es5.py',1336), + ('case_clauses_opt -> empty','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1350), + ('case_clauses_opt -> case_clauses','case_clauses_opt',1,'p_case_clauses_opt','es5.py',1351), + ('case_clauses -> case_clause','case_clauses',1,'p_case_clauses','es5.py',1356), + ('case_clauses -> case_clauses case_clause','case_clauses',2,'p_case_clauses','es5.py',1357), + ('case_clause -> CASE expr COLON source_elements','case_clause',4,'p_case_clause','es5.py',1366), + ('default_clause -> DEFAULT COLON source_elements','default_clause',3,'p_default_clause','es5.py',1371), + ('labelled_statement -> identifier COLON statement','labelled_statement',3,'p_labelled_statement','es5.py',1377), + ('throw_statement -> THROW expr SEMI','throw_statement',3,'p_throw_statement','es5.py',1383), + ('throw_statement -> THROW expr AUTOSEMI','throw_statement',3,'p_throw_statement','es5.py',1384), + ('try_statement -> TRY block catch','try_statement',3,'p_try_statement_1','es5.py',1391), + ('try_statement -> TRY block finally','try_statement',3,'p_try_statement_2','es5.py',1396), + ('try_statement -> TRY block catch finally','try_statement',4,'p_try_statement_3','es5.py',1401), + ('catch -> CATCH LPAREN identifier RPAREN block','catch',5,'p_catch','es5.py',1406), + ('finally -> FINALLY block','finally',2,'p_finally','es5.py',1411), + ('debugger_statement -> DEBUGGER SEMI','debugger_statement',2,'p_debugger_statement','es5.py',1417), + ('debugger_statement -> DEBUGGER AUTOSEMI','debugger_statement',2,'p_debugger_statement','es5.py',1418), + ('function_declaration -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_declaration',7,'p_function_declaration','es5.py',1426), + ('function_declaration -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_declaration',8,'p_function_declaration','es5.py',1427), + ('function_expr -> FUNCTION LPAREN RPAREN LBRACE function_body RBRACE','function_expr',6,'p_function_expr_1','es5.py',1441), + ('function_expr -> FUNCTION LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_1','es5.py',1442), + ('function_expr -> FUNCTION identifier LPAREN RPAREN LBRACE function_body RBRACE','function_expr',7,'p_function_expr_2','es5.py',1456), + ('function_expr -> FUNCTION identifier LPAREN formal_parameter_list RPAREN LBRACE function_body RBRACE','function_expr',8,'p_function_expr_2','es5.py',1457), + ('formal_parameter_list -> identifier','formal_parameter_list',1,'p_formal_parameter_list','es5.py',1470), + ('formal_parameter_list -> formal_parameter_list COMMA identifier','formal_parameter_list',3,'p_formal_parameter_list','es5.py',1471), + ('function_body -> source_elements','function_body',1,'p_function_body','es5.py',1480), +] diff --git a/uno/lib/python/certifi/__init__.py b/uno/lib/python/certifi/__init__.py index 705f416d..b93bb49b 100644 --- a/uno/lib/python/certifi/__init__.py +++ b/uno/lib/python/certifi/__init__.py @@ -1,4 +1,4 @@ from .core import contents, where __all__ = ["contents", "where"] -__version__ = "2023.05.07" +__version__ = "2023.11.17" diff --git a/uno/lib/python/certifi/cacert.pem b/uno/lib/python/certifi/cacert.pem index 5183934b..f3094005 100644 --- a/uno/lib/python/certifi/cacert.pem +++ b/uno/lib/python/certifi/cacert.pem @@ -791,34 +791,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Label: "Hongkong Post Root CA 1" -# Serial: 1000 -# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca -# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 -# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- - # Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Label: "SecureSign RootCA11" @@ -909,49 +881,6 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- -# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" -# Serial: 6047274297262753887 -# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 -# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa -# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - # Issuer: CN=Izenpe.com O=IZENPE S.A. # Subject: CN=Izenpe.com O=IZENPE S.A. # Label: "Izenpe.com" @@ -1676,50 +1605,6 @@ HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Label: "E-Tugra Certification Authority" -# Serial: 7667447206703254355 -# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 -# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 -# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - # Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Label: "T-TeleSec GlobalRoot Class 2" @@ -4397,73 +4282,6 @@ ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA RSA v3" -# Serial: 75951268308633135324246244059508261641472512052 -# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 -# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 -# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL -BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt -VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw -JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw -OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG -QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD -QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7 -7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx -uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8 -7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/ -rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL -l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG -wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4 -znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO -M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK -5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH -nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo -DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy -tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL -BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ -6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18 -Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ -3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk -vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9 -9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ -mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA -VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF -9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM -moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8 -bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA ECC v3" -# Serial: 218504919822255052842371958738296604628416471745 -# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 -# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 -# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw -gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn -cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD -VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 -NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r -YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh -IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF -Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ -KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK -fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB -Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C -MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp -ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 -7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx -vmjkI6TZraE3 ------END CERTIFICATE----- - # Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. # Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. # Label: "Security Communication RootCA3" @@ -4587,3 +4405,374 @@ AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA 94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B 43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== -----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G3" +# Serial: 576386314500428537169965010905813481816650257167 +# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 +# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 +# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM +BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe +Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw +IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU +cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS +T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK +AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 +nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep +qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA +yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs +hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX +zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv +kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT +f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA +uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih +MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 +wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 +XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 +JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j +ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV +VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx +xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on +AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d +7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj +gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV ++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo +FGWsJwt0ivKH +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G4" +# Serial: 451799571007117016466790293371524403291602933463 +# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb +# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a +# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw +WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y +MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD +VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz +dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx +s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw +LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD +pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR +UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj +/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Label: "CommScope Public Trust ECC Root-01" +# Serial: 385011430473757362783587124273108818652468453534 +# MD5 Fingerprint: 3a:40:a7:fc:03:8c:9c:38:79:2f:3a:a2:6c:b6:0a:16 +# SHA1 Fingerprint: 07:86:c0:d8:dd:8e:c0:80:98:06:98:d0:58:7a:ef:de:a6:cc:a2:5d +# SHA256 Fingerprint: 11:43:7c:da:7b:b4:5e:41:36:5f:45:b3:9a:38:98:6b:0d:e0:0d:ef:34:8e:0c:7b:b0:87:36:33:80:0b:c3:8b +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa +Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C +flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE +hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq +hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg +2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS +Um9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Label: "CommScope Public Trust ECC Root-02" +# Serial: 234015080301808452132356021271193974922492992893 +# MD5 Fingerprint: 59:b0:44:d5:65:4d:b8:5c:55:19:92:02:b6:d1:94:b2 +# SHA1 Fingerprint: 3c:3f:ef:57:0f:fe:65:93:86:9e:a0:fe:b0:f6:ed:8e:d1:13:c7:e5 +# SHA256 Fingerprint: 2f:fb:7f:81:3b:bb:b3:c8:9a:b4:e8:16:2d:0f:16:d7:15:09:a8:30:cc:9d:73:c2:62:e5:14:08:75:d1:ad:4a +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa +Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL +j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU +v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq +hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n +ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV +mkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Label: "CommScope Public Trust RSA Root-01" +# Serial: 354030733275608256394402989253558293562031411421 +# MD5 Fingerprint: 0e:b4:15:bc:87:63:5d:5d:02:73:d4:26:38:68:73:d8 +# SHA1 Fingerprint: 6d:0a:5f:f7:b4:23:06:b4:85:b3:b7:97:64:fc:ac:75:f5:33:f2:93 +# SHA256 Fingerprint: 02:bd:f9:6e:2a:45:dd:9b:f1:8f:c7:e1:db:df:21:a0:37:9b:a3:c9:c2:61:03:44:cf:d8:d6:06:fe:c1:ed:81 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1 +NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk +YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh +suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al +DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj +WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl +P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547 +KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p +UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/ +kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO +Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB +Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U +CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ +KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ +nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+ +QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v +trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a +aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD +j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4 +Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w +lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn +YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc +icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Label: "CommScope Public Trust RSA Root-02" +# Serial: 480062499834624527752716769107743131258796508494 +# MD5 Fingerprint: e1:29:f9:62:7b:76:e2:96:6d:f3:d4:d7:0f:ae:1f:aa +# SHA1 Fingerprint: ea:b0:e2:52:1b:89:93:4c:11:68:f2:d8:9a:ac:22:4c:a3:8a:57:ae +# SHA256 Fingerprint: ff:e9:43:d7:93:42:4b:4f:7c:44:0c:1c:3d:64:8d:53:63:f3:4b:82:dc:87:aa:7a:9f:11:8f:c5:de:e1:01:f1 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2 +NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE +NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0 +kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C +rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz +hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2 +LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs +n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku +FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5 +kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3 +wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v +wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs +5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ +KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3 ++VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme +APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq +pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT +6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF +sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt +PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d +lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670 +v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O +rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- diff --git a/uno/lib/python/cffi/__init__.py b/uno/lib/python/cffi/__init__.py new file mode 100644 index 00000000..fbce76ec --- /dev/null +++ b/uno/lib/python/cffi/__init__.py @@ -0,0 +1,14 @@ +__all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', + 'FFIError'] + +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing +from .error import PkgConfigError + +__version__ = "1.16.0" +__version_info__ = (1, 16, 0) + +# The verifier module file names are based on the CRC32 of a string that +# contains the following version number. It may be older than __version__ +# if nothing is clearly incompatible. +__version_verifier_modules__ = "0.8.6" diff --git a/uno/lib/python/cffi/_cffi_errors.h b/uno/lib/python/cffi/_cffi_errors.h new file mode 100644 index 00000000..d9f7ad95 --- /dev/null +++ b/uno/lib/python/cffi/_cffi_errors.h @@ -0,0 +1,149 @@ +#ifndef CFFI_MESSAGEBOX +# ifdef _MSC_VER +# define CFFI_MESSAGEBOX 1 +# else +# define CFFI_MESSAGEBOX 0 +# endif +#endif + + +#if CFFI_MESSAGEBOX +/* Windows only: logic to take the Python-CFFI embedding logic + initialization errors and display them in a background thread + with MessageBox. The idea is that if the whole program closes + as a result of this problem, then likely it is already a console + program and you can read the stderr output in the console too. + If it is not a console program, then it will likely show its own + dialog to complain, or generally not abruptly close, and for this + case the background thread should stay alive. +*/ +static void *volatile _cffi_bootstrap_text; + +static PyObject *_cffi_start_error_capture(void) +{ + PyObject *result = NULL; + PyObject *x, *m, *bi; + + if (InterlockedCompareExchangePointer(&_cffi_bootstrap_text, + (void *)1, NULL) != NULL) + return (PyObject *)1; + + m = PyImport_AddModule("_cffi_error_capture"); + if (m == NULL) + goto error; + + result = PyModule_GetDict(m); + if (result == NULL) + goto error; + +#if PY_MAJOR_VERSION >= 3 + bi = PyImport_ImportModule("builtins"); +#else + bi = PyImport_ImportModule("__builtin__"); +#endif + if (bi == NULL) + goto error; + PyDict_SetItemString(result, "__builtins__", bi); + Py_DECREF(bi); + + x = PyRun_String( + "import sys\n" + "class FileLike:\n" + " def write(self, x):\n" + " try:\n" + " of.write(x)\n" + " except: pass\n" + " self.buf += x\n" + " def flush(self):\n" + " pass\n" + "fl = FileLike()\n" + "fl.buf = ''\n" + "of = sys.stderr\n" + "sys.stderr = fl\n" + "def done():\n" + " sys.stderr = of\n" + " return fl.buf\n", /* make sure the returned value stays alive */ + Py_file_input, + result, result); + Py_XDECREF(x); + + error: + if (PyErr_Occurred()) + { + PyErr_WriteUnraisable(Py_None); + PyErr_Clear(); + } + return result; +} + +#pragma comment(lib, "user32.lib") + +static DWORD WINAPI _cffi_bootstrap_dialog(LPVOID ignored) +{ + Sleep(666); /* may be interrupted if the whole process is closing */ +#if PY_MAJOR_VERSION >= 3 + MessageBoxW(NULL, (wchar_t *)_cffi_bootstrap_text, + L"Python-CFFI error", + MB_OK | MB_ICONERROR); +#else + MessageBoxA(NULL, (char *)_cffi_bootstrap_text, + "Python-CFFI error", + MB_OK | MB_ICONERROR); +#endif + _cffi_bootstrap_text = NULL; + return 0; +} + +static void _cffi_stop_error_capture(PyObject *ecap) +{ + PyObject *s; + void *text; + + if (ecap == (PyObject *)1) + return; + + if (ecap == NULL) + goto error; + + s = PyRun_String("done()", Py_eval_input, ecap, ecap); + if (s == NULL) + goto error; + + /* Show a dialog box, but in a background thread, and + never show multiple dialog boxes at once. */ +#if PY_MAJOR_VERSION >= 3 + text = PyUnicode_AsWideCharString(s, NULL); +#else + text = PyString_AsString(s); +#endif + + _cffi_bootstrap_text = text; + + if (text != NULL) + { + HANDLE h; + h = CreateThread(NULL, 0, _cffi_bootstrap_dialog, + NULL, 0, NULL); + if (h != NULL) + CloseHandle(h); + } + /* decref the string, but it should stay alive as 'fl.buf' + in the small module above. It will really be freed only if + we later get another similar error. So it's a leak of at + most one copy of the small module. That's fine for this + situation which is usually a "fatal error" anyway. */ + Py_DECREF(s); + PyErr_Clear(); + return; + + error: + _cffi_bootstrap_text = NULL; + PyErr_Clear(); +} + +#else + +static PyObject *_cffi_start_error_capture(void) { return NULL; } +static void _cffi_stop_error_capture(PyObject *ecap) { } + +#endif diff --git a/uno/lib/python/cffi/_cffi_include.h b/uno/lib/python/cffi/_cffi_include.h new file mode 100644 index 00000000..e0033e5f --- /dev/null +++ b/uno/lib/python/cffi/_cffi_include.h @@ -0,0 +1,385 @@ +#define _CFFI_ + +/* We try to define Py_LIMITED_API before including Python.h. + + Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and + Py_REF_DEBUG are not defined. This is a best-effort approximation: + we can learn about Py_DEBUG from pyconfig.h, but it is unclear if + the same works for the other two macros. Py_DEBUG implies them, + but not the other way around. + + The implementation is messy (issue #350): on Windows, with _MSC_VER, + we have to define Py_LIMITED_API even before including pyconfig.h. + In that case, we guess what pyconfig.h will do to the macros above, + and check our guess after the #include. + + Note that on Windows, with CPython 3.x, you need >= 3.5 and virtualenv + version >= 16.0.0. With older versions of either, you don't get a + copy of PYTHON3.DLL in the virtualenv. We can't check the version of + CPython *before* we even include pyconfig.h. ffi.set_source() puts + a ``#define _CFFI_NO_LIMITED_API'' at the start of this file if it is + running on Windows < 3.5, as an attempt at fixing it, but that's + arguably wrong because it may not be the target version of Python. + Still better than nothing I guess. As another workaround, you can + remove the definition of Py_LIMITED_API here. + + See also 'py_limited_api' in cffi/setuptools_ext.py. +*/ +#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API) +# ifdef _MSC_VER +# if !defined(_DEBUG) && !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif +# include + /* sanity-check: Py_LIMITED_API will cause crashes if any of these + are also defined. Normally, the Python file PC/pyconfig.h does not + cause any of these to be defined, with the exception that _DEBUG + causes Py_DEBUG. Double-check that. */ +# ifdef Py_LIMITED_API +# if defined(Py_DEBUG) +# error "pyconfig.h unexpectedly defines Py_DEBUG, but Py_LIMITED_API is set" +# endif +# if defined(Py_TRACE_REFS) +# error "pyconfig.h unexpectedly defines Py_TRACE_REFS, but Py_LIMITED_API is set" +# endif +# if defined(Py_REF_DEBUG) +# error "pyconfig.h unexpectedly defines Py_REF_DEBUG, but Py_LIMITED_API is set" +# endif +# endif +# else +# include +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif +# endif +#endif + +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "parse_c_type.h" + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#ifdef __GNUC__ +# define _CFFI_UNUSED_FN __attribute__((unused)) +#else +# define _CFFI_UNUSED_FN /* nothing */ +#endif + +#ifdef __cplusplus +# ifndef _Bool + typedef bool _Bool; /* semi-hackish: C++ has no _Bool; bool is builtin */ +# endif +#endif + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, struct _cffi_ctypedescr *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + not used any more +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((_cffi_wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(_cffi_wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(struct _cffi_ctypedescr *, \ + PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[24]) +#define _CFFI_CPIDX 25 +#define _cffi_call_python \ + ((void(*)(struct _cffi_externpy_s *, char *))_cffi_exports[_CFFI_CPIDX]) +#define _cffi_to_c_wchar3216_t \ + ((int(*)(PyObject *))_cffi_exports[26]) +#define _cffi_from_c_wchar3216_t \ + ((PyObject *(*)(int))_cffi_exports[27]) +#define _CFFI_NUM_EXPORTS 28 + +struct _cffi_ctypedescr; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; + +#define _cffi_type(index) ( \ + assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \ + (struct _cffi_ctypedescr *)_cffi_types[index]) + +static PyObject *_cffi_init(const char *module_name, Py_ssize_t version, + const struct _cffi_type_context_s *ctx) +{ + PyObject *module, *o_arg, *new_module; + void *raw[] = { + (void *)module_name, + (void *)version, + (void *)_cffi_exports, + (void *)ctx, + }; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + o_arg = PyLong_FromVoidPtr((void *)raw); + if (o_arg == NULL) + goto failure; + + new_module = PyObject_CallMethod( + module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg); + + Py_DECREF(o_arg); + Py_DECREF(module); + return new_module; + + failure: + Py_XDECREF(module); + return NULL; +} + + +#ifdef HAVE_WCHAR_H +typedef wchar_t _cffi_wchar_t; +#else +typedef uint16_t _cffi_wchar_t; /* same random pick as _cffi_backend.c */ +#endif + +_CFFI_UNUSED_FN static uint16_t _cffi_to_c_char16_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 2) + return (uint16_t)_cffi_to_c_wchar_t(o); + else + return (uint16_t)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char16_t(uint16_t x) +{ + if (sizeof(_cffi_wchar_t) == 2) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +_CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 4) + return (int)_cffi_to_c_wchar_t(o); + else + return (int)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(unsigned int x) +{ + if (sizeof(_cffi_wchar_t) == 4) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +_CFFI_UNUSED_FN static int +_cffi_convert_array_argument(struct _cffi_ctypedescr *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +_CFFI_UNUSED_FN static void +_cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} + +/********** end CPython-specific section **********/ +#else +_CFFI_UNUSED_FN +static void (*_cffi_call_python_org)(struct _cffi_externpy_s *, char *); +# define _cffi_call_python _cffi_call_python_org +#endif + + +#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0])) + +#define _cffi_prim_int(size, sign) \ + ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \ + (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \ + (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \ + (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \ + _CFFI__UNKNOWN_PRIM) + +#define _cffi_prim_float(size) \ + ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT : \ + (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE : \ + (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE : \ + _CFFI__UNKNOWN_FLOAT_PRIM) + +#define _cffi_check_int(got, got_nonpos, expected) \ + ((got_nonpos) == (expected <= 0) && \ + (got) == (unsigned long long)expected) + +#ifdef MS_WIN32 +# define _cffi_stdcall __stdcall +#else +# define _cffi_stdcall /* nothing */ +#endif + +#ifdef __cplusplus +} +#endif diff --git a/uno/lib/python/cffi/_embedding.h b/uno/lib/python/cffi/_embedding.h new file mode 100644 index 00000000..3c76757a --- /dev/null +++ b/uno/lib/python/cffi/_embedding.h @@ -0,0 +1,550 @@ + +/***** Support code for embedding *****/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(_WIN32) +# define CFFI_DLLEXPORT __declspec(dllexport) +#elif defined(__GNUC__) +# define CFFI_DLLEXPORT __attribute__((visibility("default"))) +#else +# define CFFI_DLLEXPORT /* nothing */ +#endif + + +/* There are two global variables of type _cffi_call_python_fnptr: + + * _cffi_call_python, which we declare just below, is the one called + by ``extern "Python"`` implementations. + + * _cffi_call_python_org, which on CPython is actually part of the + _cffi_exports[] array, is the function pointer copied from + _cffi_backend. If _cffi_start_python() fails, then this is set + to NULL; otherwise, it should never be NULL. + + After initialization is complete, both are equal. However, the + first one remains equal to &_cffi_start_and_call_python until the + very end of initialization, when we are (or should be) sure that + concurrent threads also see a completely initialized world, and + only then is it changed. +*/ +#undef _cffi_call_python +typedef void (*_cffi_call_python_fnptr)(struct _cffi_externpy_s *, char *); +static void _cffi_start_and_call_python(struct _cffi_externpy_s *, char *); +static _cffi_call_python_fnptr _cffi_call_python = &_cffi_start_and_call_python; + + +#ifndef _MSC_VER + /* --- Assuming a GCC not infinitely old --- */ +# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) +# define cffi_write_barrier() __sync_synchronize() +# if !defined(__amd64__) && !defined(__x86_64__) && \ + !defined(__i386__) && !defined(__i386) +# define cffi_read_barrier() __sync_synchronize() +# else +# define cffi_read_barrier() (void)0 +# endif +#else + /* --- Windows threads version --- */ +# include +# define cffi_compare_and_swap(l,o,n) \ + (InterlockedCompareExchangePointer(l,n,o) == (o)) +# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_read_barrier() (void)0 +static volatile LONG _cffi_dummy; +#endif + +#ifdef WITH_THREAD +# ifndef _MSC_VER +# include + static pthread_mutex_t _cffi_embed_startup_lock; +# else + static CRITICAL_SECTION _cffi_embed_startup_lock; +# endif + static char _cffi_embed_startup_lock_ready = 0; +#endif + +static void _cffi_acquire_reentrant_mutex(void) +{ + static void *volatile lock = NULL; + + while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) { + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: pthread_mutex_init() should be very fast, and + this is only run at start-up anyway. */ + } + +#ifdef WITH_THREAD + if (!_cffi_embed_startup_lock_ready) { +# ifndef _MSC_VER + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_cffi_embed_startup_lock, &attr); +# else + InitializeCriticalSection(&_cffi_embed_startup_lock); +# endif + _cffi_embed_startup_lock_ready = 1; + } +#endif + + while (!cffi_compare_and_swap(&lock, (void *)1, NULL)) + ; + +#ifndef _MSC_VER + pthread_mutex_lock(&_cffi_embed_startup_lock); +#else + EnterCriticalSection(&_cffi_embed_startup_lock); +#endif +} + +static void _cffi_release_reentrant_mutex(void) +{ +#ifndef _MSC_VER + pthread_mutex_unlock(&_cffi_embed_startup_lock); +#else + LeaveCriticalSection(&_cffi_embed_startup_lock); +#endif +} + + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + +#include "_cffi_errors.h" + + +#define _cffi_call_python_org _cffi_exports[_CFFI_CPIDX] + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(void); /* forward */ + +static void _cffi_py_initialize(void) +{ + /* XXX use initsigs=0, which "skips initialization registration of + signal handlers, which might be useful when Python is + embedded" according to the Python docs. But review and think + if it should be a user-controllable setting. + + XXX we should also give a way to write errors to a buffer + instead of to stderr. + + XXX if importing 'site' fails, CPython (any version) calls + exit(). Should we try to work around this behavior here? + */ + Py_InitializeEx(0); +} + +static int _cffi_initialize_python(void) +{ + /* This initializes Python, imports _cffi_backend, and then the + present .dll/.so is set up as a CPython C extension module. + */ + int result; + PyGILState_STATE state; + PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; + + state = PyGILState_Ensure(); + + /* Call the initxxx() function from the present module. It will + create and initialize us as a CPython extension module, instead + of letting the startup Python code do it---it might reimport + the same .dll/.so and get maybe confused on some platforms. + It might also have troubles locating the .dll/.so again for all + I know. + */ + (void)_CFFI_PYTHON_STARTUP_FUNC(); + if (PyErr_Occurred()) + goto error; + + /* Now run the Python code provided to ffi.embedding_init_code(). + */ + pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE, + "", + Py_file_input); + if (pycode == NULL) + goto error; + global_dict = PyDict_New(); + if (global_dict == NULL) + goto error; + builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) + goto error; + x = PyEval_EvalCode( +#if PY_MAJOR_VERSION < 3 + (PyCodeObject *) +#endif + pycode, global_dict, global_dict); + if (x == NULL) + goto error; + Py_DECREF(x); + + /* Done! Now if we've been called from + _cffi_start_and_call_python() in an ``extern "Python"``, we can + only hope that the Python code did correctly set up the + corresponding @ffi.def_extern() function. Otherwise, the + general logic of ``extern "Python"`` functions (inside the + _cffi_backend module) will find that the reference is still + missing and print an error. + */ + result = 0; + done: + Py_XDECREF(pycode); + Py_XDECREF(global_dict); + PyGILState_Release(state); + return result; + + error:; + { + /* Print as much information as potentially useful. + Debugging load-time failures with embedding is not fun + */ + PyObject *ecap; + PyObject *exception, *v, *tb, *f, *modules, *mod; + PyErr_Fetch(&exception, &v, &tb); + ecap = _cffi_start_error_capture(); + f = PySys_GetObject((char *)"stderr"); + if (f != NULL && f != Py_None) { + PyFile_WriteString( + "Failed to initialize the Python-CFFI embedding logic:\n\n", f); + } + + if (exception != NULL) { + PyErr_NormalizeException(&exception, &v, &tb); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); + + if (f != NULL && f != Py_None) { + PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME + "\ncompiled with cffi version: 1.16.0" + "\n_cffi_backend module: ", f); + modules = PyImport_GetModuleDict(); + mod = PyDict_GetItemString(modules, "_cffi_backend"); + if (mod == NULL) { + PyFile_WriteString("not loaded", f); + } + else { + v = PyObject_GetAttrString(mod, "__file__"); + PyFile_WriteObject(v, f, 0); + Py_XDECREF(v); + } + PyFile_WriteString("\nsys.path: ", f); + PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0); + PyFile_WriteString("\n\n", f); + } + _cffi_stop_error_capture(ecap); + } + result = -1; + goto done; +} + +#if PY_VERSION_HEX < 0x03080000 +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ +#endif + +static int _cffi_carefully_make_gil(void) +{ + /* This does the basic initialization of Python. It can be called + completely concurrently from unrelated threads. It assumes + that we don't hold the GIL before (if it exists), and we don't + hold it afterwards. + + (What it really does used to be completely different in Python 2 + and Python 3, with the Python 2 solution avoiding the spin-lock + around the Py_InitializeEx() call. However, after recent changes + to CPython 2.7 (issue #358) it no longer works. So we use the + Python 3 solution everywhere.) + + This initializes Python by calling Py_InitializeEx(). + Important: this must not be called concurrently at all. + So we use a global variable as a simple spin lock. This global + variable must be from 'libpythonX.Y.so', not from this + cffi-based extension module, because it must be shared from + different cffi-based extension modules. + + In Python < 3.8, we choose + _PyParser_TokenNames[0] as a completely arbitrary pointer value + that is never written to. The default is to point to the + string "ENDMARKER". We change it temporarily to point to the + next character in that string. (Yes, I know it's REALLY + obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. + + In Python >= 3.12, this stopped working because that particular + tp_version_tag gets modified during interpreter startup. It's + arguably a bad idea before 3.12 too, but again we can't change + that because someone might use a mixture of cffi embedded + modules, and no-one reported a bug so far. In Python >= 3.12 + we go instead for PyCapsuleType.tp_as_buffer, which is supposed + to always be NULL. We write to it temporarily a pointer to + a struct full of NULLs, which is semantically the same. + */ + +#ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 + char *volatile *lock = (char *volatile *)_PyParser_TokenNames; + char *old_value, *locked_value; + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = old_value + 1; + if (old_value[0] == 'E') { + assert(old_value[1] == 'N'); + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value[0] == 'N'); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# else +# if PY_VERSION_HEX < 0x030C0000 + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value = -42; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); +# else + static struct ebp_s { PyBufferProcs buf; int mark; } empty_buffer_procs; + empty_buffer_procs.mark = -42; + PyBufferProcs *volatile *lock = (PyBufferProcs *volatile *) + &PyCapsule_Type.tp_as_buffer; + PyBufferProcs *old_value, *locked_value = &empty_buffer_procs.buf; +# endif + + while (1) { /* spin loop */ + old_value = *lock; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { +# if PY_VERSION_HEX < 0x030C0000 + assert(old_value == locked_value); +# else + /* The pointer should point to a possibly different + empty_buffer_procs from another C extension module */ + assert(((struct ebp_s *)old_value)->mark == -42); +# endif + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif +#endif + + /* call Py_InitializeEx() */ + if (!Py_IsInitialized()) { + _cffi_py_initialize(); +#if PY_VERSION_HEX < 0x03070000 + PyEval_InitThreads(); +#endif + PyEval_SaveThread(); /* release the GIL */ + /* the returned tstate must be the one that has been stored into the + autoTLSkey by _PyGILState_Init() called from Py_Initialize(). */ + } + else { +#if PY_VERSION_HEX < 0x03070000 + /* PyEval_InitThreads() is always a no-op from CPython 3.7 */ + PyGILState_STATE state = PyGILState_Ensure(); + PyEval_InitThreads(); + PyGILState_Release(state); +#endif + } + +#ifdef WITH_THREAD + /* release the lock */ + while (!cffi_compare_and_swap(lock, locked_value, old_value)) + ; +#endif + + return 0; +} + +/********** end CPython-specific section **********/ + + +#else + + +/********** PyPy-specific section **********/ + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]); /* forward */ + +static struct _cffi_pypy_init_s { + const char *name; + void *func; /* function pointer */ + const char *code; +} _cffi_pypy_init = { + _CFFI_MODULE_NAME, + _CFFI_PYTHON_STARTUP_FUNC, + _CFFI_PYTHON_STARTUP_CODE, +}; + +extern int pypy_carefully_make_gil(const char *); +extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *); + +static int _cffi_carefully_make_gil(void) +{ + return pypy_carefully_make_gil(_CFFI_MODULE_NAME); +} + +static int _cffi_initialize_python(void) +{ + return pypy_init_embedded_cffi_module(0xB011, &_cffi_pypy_init); +} + +/********** end PyPy-specific section **********/ + + +#endif + + +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +static _cffi_call_python_fnptr _cffi_start_python(void) +{ + /* Delicate logic to initialize Python. This function can be + called multiple times concurrently, e.g. when the process calls + its first ``extern "Python"`` functions in multiple threads at + once. It can also be called recursively, in which case we must + ignore it. We also have to consider what occurs if several + different cffi-based extensions reach this code in parallel + threads---it is a different copy of the code, then, and we + can't have any shared global variable unless it comes from + 'libpythonX.Y.so'. + + Idea: + + * _cffi_carefully_make_gil(): "carefully" call + PyEval_InitThreads() (possibly with Py_InitializeEx() first). + + * then we use a (local) custom lock to make sure that a call to this + cffi-based extension will wait if another call to the *same* + extension is running the initialization in another thread. + It is reentrant, so that a recursive call will not block, but + only one from a different thread. + + * then we grab the GIL and (Python 2) we call Py_InitializeEx(). + At this point, concurrent calls to Py_InitializeEx() are not + possible: we have the GIL. + + * do the rest of the specific initialization, which may + temporarily release the GIL but not the custom lock. + Only release the custom lock when we are done. + */ + static char called = 0; + + if (_cffi_carefully_make_gil() != 0) + return NULL; + + _cffi_acquire_reentrant_mutex(); + + /* Here the GIL exists, but we don't have it. We're only protected + from concurrency by the reentrant mutex. */ + + /* This file only initializes the embedded module once, the first + time this is called, even if there are subinterpreters. */ + if (!called) { + called = 1; /* invoke _cffi_initialize_python() only once, + but don't set '_cffi_call_python' right now, + otherwise concurrent threads won't call + this function at all (we need them to wait) */ + if (_cffi_initialize_python() == 0) { + /* now initialization is finished. Switch to the fast-path. */ + + /* We would like nobody to see the new value of + '_cffi_call_python' without also seeing the rest of the + data initialized. However, this is not possible. But + the new value of '_cffi_call_python' is the function + 'cffi_call_python()' from _cffi_backend. So: */ + cffi_write_barrier(); + /* ^^^ we put a write barrier here, and a corresponding + read barrier at the start of cffi_call_python(). This + ensures that after that read barrier, we see everything + done here before the write barrier. + */ + + assert(_cffi_call_python_org != NULL); + _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; + } + else { + /* initialization failed. Reset this to NULL, even if it was + already set to some other value. Future calls to + _cffi_start_python() are still forced to occur, and will + always return NULL from now on. */ + _cffi_call_python_org = NULL; + } + } + + _cffi_release_reentrant_mutex(); + + return (_cffi_call_python_fnptr)_cffi_call_python_org; +} + +static +void _cffi_start_and_call_python(struct _cffi_externpy_s *externpy, char *args) +{ + _cffi_call_python_fnptr fnptr; + int current_err = errno; +#ifdef _MSC_VER + int current_lasterr = GetLastError(); +#endif + fnptr = _cffi_start_python(); + if (fnptr == NULL) { + fprintf(stderr, "function %s() called, but initialization code " + "failed. Returning 0.\n", externpy->name); + memset(args, 0, externpy->size_of_result); + } +#ifdef _MSC_VER + SetLastError(current_lasterr); +#endif + errno = current_err; + + if (fnptr != NULL) + fnptr(externpy, args); +} + + +/* The cffi_start_python() function makes sure Python is initialized + and our cffi module is set up. It can be called manually from the + user C code. The same effect is obtained automatically from any + dll-exported ``extern "Python"`` function. This function returns + -1 if initialization failed, 0 if all is OK. */ +_CFFI_UNUSED_FN +static int cffi_start_python(void) +{ + if (_cffi_call_python == &_cffi_start_and_call_python) { + if (_cffi_start_python() == NULL) + return -1; + } + cffi_read_barrier(); + return 0; +} + +#undef cffi_compare_and_swap +#undef cffi_write_barrier +#undef cffi_read_barrier + +#ifdef __cplusplus +} +#endif diff --git a/uno/lib/python/cffi/_imp_emulation.py b/uno/lib/python/cffi/_imp_emulation.py new file mode 100644 index 00000000..961d2c4f --- /dev/null +++ b/uno/lib/python/cffi/_imp_emulation.py @@ -0,0 +1,83 @@ + +try: + # this works on Python < 3.12 + from imp import * + +except ImportError: + # this is a limited emulation for Python >= 3.12. + # Note that this is used only for tests or for the old ffi.verify(). + # This is copied from the source code of Python 3.11. + + from _imp import (acquire_lock, release_lock, + is_builtin, is_frozen) + + from importlib._bootstrap import _load + + from importlib import machinery + import os + import sys + import tokenize + + SEARCH_ERROR = 0 + PY_SOURCE = 1 + PY_COMPILED = 2 + C_EXTENSION = 3 + PY_RESOURCE = 4 + PKG_DIRECTORY = 5 + C_BUILTIN = 6 + PY_FROZEN = 7 + PY_CODERESOURCE = 8 + IMP_HOOK = 9 + + def get_suffixes(): + extensions = [(s, 'rb', C_EXTENSION) + for s in machinery.EXTENSION_SUFFIXES] + source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] + bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES] + return extensions + source + bytecode + + def find_module(name, path=None): + if not isinstance(name, str): + raise TypeError("'name' must be a str, not {}".format(type(name))) + elif not isinstance(path, (type(None), list)): + # Backwards-compatibility + raise RuntimeError("'path' must be None or a list, " + "not {}".format(type(path))) + + if path is None: + if is_builtin(name): + return None, None, ('', '', C_BUILTIN) + elif is_frozen(name): + return None, None, ('', '', PY_FROZEN) + else: + path = sys.path + + for entry in path: + package_directory = os.path.join(entry, name) + for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]: + package_file_name = '__init__' + suffix + file_path = os.path.join(package_directory, package_file_name) + if os.path.isfile(file_path): + return None, package_directory, ('', '', PKG_DIRECTORY) + for suffix, mode, type_ in get_suffixes(): + file_name = name + suffix + file_path = os.path.join(entry, file_name) + if os.path.isfile(file_path): + break + else: + continue + break # Break out of outer loop when breaking out of inner loop. + else: + raise ImportError(name, name=name) + + encoding = None + if 'b' not in mode: + with open(file_path, 'rb') as file: + encoding = tokenize.detect_encoding(file.readline)[0] + file = open(file_path, mode, encoding=encoding) + return file, file_path, (suffix, mode, type_) + + def load_dynamic(name, path, file=None): + loader = machinery.ExtensionFileLoader(name, path) + spec = machinery.ModuleSpec(name=name, loader=loader, origin=path) + return _load(spec) diff --git a/uno/lib/python/cffi/_shimmed_dist_utils.py b/uno/lib/python/cffi/_shimmed_dist_utils.py new file mode 100644 index 00000000..28e5a70e --- /dev/null +++ b/uno/lib/python/cffi/_shimmed_dist_utils.py @@ -0,0 +1,41 @@ +""" +Temporary shim module to indirect the bits of distutils we need from setuptools/distutils while providing useful +error messages beyond `No module named 'distutils' on Python >= 3.12, or when setuptools' vendored distutils is broken. + +This is a compromise to avoid a hard-dep on setuptools for Python >= 3.12, since many users don't need runtime compilation support from CFFI. +""" +import sys + +try: + # import setuptools first; this is the most robust way to ensure its embedded distutils is available + # (the .pth shim should usually work, but this is even more robust) + import setuptools +except Exception as ex: + if sys.version_info >= (3, 12): + # Python 3.12 has no built-in distutils to fall back on, so any import problem is fatal + raise Exception("This CFFI feature requires setuptools on Python >= 3.12. The setuptools module is missing or non-functional.") from ex + + # silently ignore on older Pythons (support fallback to stdlib distutils where available) +else: + del setuptools + +try: + # bring in just the bits of distutils we need, whether they really came from setuptools or stdlib-embedded distutils + from distutils import log, sysconfig + from distutils.ccompiler import CCompiler + from distutils.command.build_ext import build_ext + from distutils.core import Distribution, Extension + from distutils.dir_util import mkpath + from distutils.errors import DistutilsSetupError, CompileError, LinkError + from distutils.log import set_threshold, set_verbosity + + if sys.platform == 'win32': + from distutils.msvc9compiler import MSVCCompiler +except Exception as ex: + if sys.version_info >= (3, 12): + raise Exception("This CFFI feature requires setuptools on Python >= 3.12. Please install the setuptools package.") from ex + + # anything older, just let the underlying distutils import error fly + raise Exception("This CFFI feature requires distutils. Please install the distutils or setuptools package.") from ex + +del sys diff --git a/uno/lib/python/cffi/api.py b/uno/lib/python/cffi/api.py new file mode 100644 index 00000000..62f79162 --- /dev/null +++ b/uno/lib/python/cffi/api.py @@ -0,0 +1,965 @@ +import sys, types +from .lock import allocate_lock +from .error import CDefError +from . import model + +try: + callable +except NameError: + # Python 3.1 + from collections import Callable + callable = lambda x: isinstance(x, Callable) + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +_unspecified = object() + + + +class FFI(object): + r''' + The main top-level class that you instantiate once, or once per module. + + Example usage: + + ffi = FFI() + ffi.cdef(""" + int printf(const char *, ...); + """) + + C = ffi.dlopen(None) # standard library + -or- + C = ffi.verify() # use a C compiler: verify the decl above is right + + C.printf("hello, %s!\n", ffi.new("char[]", "world")) + ''' + + def __init__(self, backend=None): + """Create an FFI instance. The 'backend' argument is used to + select a non-default backend, mostly for tests. + """ + if backend is None: + # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with + # _cffi_backend.so compiled. + import _cffi_backend as backend + from . import __version__ + if backend.__version__ != __version__: + # bad version! Try to be as explicit as possible. + if hasattr(backend, '__file__'): + # CPython + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( + __version__, __file__, + backend.__version__, backend.__file__)) + else: + # PyPy + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( + __version__, __file__, backend.__version__)) + # (If you insist you can also try to pass the option + # 'backend=backend_ctypes.CTypesBackend()', but don't + # rely on it! It's probably not going to work well.) + + from . import cparser + self._backend = backend + self._lock = allocate_lock() + self._parser = cparser.Parser() + self._cached_btypes = {} + self._parsed_types = types.ModuleType('parsed_types').__dict__ + self._new_types = types.ModuleType('new_types').__dict__ + self._function_caches = [] + self._libraries = [] + self._cdefsources = [] + self._included_ffis = [] + self._windows_unicode = None + self._init_once_cache = {} + self._cdef_version = None + self._embedding = None + self._typecache = model.get_typecache(backend) + if hasattr(backend, 'set_ffi'): + backend.set_ffi(self) + for name in list(backend.__dict__): + if name.startswith('RTLD_'): + setattr(self, name, getattr(backend, name)) + # + with self._lock: + self.BVoidP = self._get_cached_btype(model.voidp_type) + self.BCharA = self._get_cached_btype(model.char_array_type) + if isinstance(backend, types.ModuleType): + # _cffi_backend: attach these constants to the class + if not hasattr(FFI, 'NULL'): + FFI.NULL = self.cast(self.BVoidP, 0) + FFI.CData, FFI.CType = backend._get_types() + else: + # ctypes backend: attach these constants to the instance + self.NULL = self.cast(self.BVoidP, 0) + self.CData, self.CType = backend._get_types() + self.buffer = backend.buffer + + def cdef(self, csource, override=False, packed=False, pack=None): + """Parse the given C source. This registers all declared functions, + types, and global variables. The functions and global variables can + then be accessed via either 'ffi.dlopen()' or 'ffi.verify()'. + The types can be used in 'ffi.new()' and other functions. + If 'packed' is specified as True, all structs declared inside this + cdef are packed, i.e. laid out without any field alignment at all. + Alternatively, 'pack' can be a small integer, and requests for + alignment greater than that are ignored (pack=1 is equivalent to + packed=True). + """ + self._cdef(csource, override=override, packed=packed, pack=pack) + + def embedding_api(self, csource, packed=False, pack=None): + self._cdef(csource, packed=packed, pack=pack, dllexport=True) + if self._embedding is None: + self._embedding = '' + + def _cdef(self, csource, override=False, **options): + if not isinstance(csource, str): # unicode, on Python 2 + if not isinstance(csource, basestring): + raise TypeError("cdef() argument must be a string") + csource = csource.encode('ascii') + with self._lock: + self._cdef_version = object() + self._parser.parse(csource, override=override, **options) + self._cdefsources.append(csource) + if override: + for cache in self._function_caches: + cache.clear() + finishlist = self._parser._recomplete + if finishlist: + self._parser._recomplete = [] + for tp in finishlist: + tp.finish_backend_type(self, finishlist) + + def dlopen(self, name, flags=0): + """Load and return a dynamic library identified by 'name'. + The standard C library can be loaded by passing None. + Note that functions and types declared by 'ffi.cdef()' are not + linked to a particular library, just like C headers; in the + library we only look for the actual (untyped) symbols. + """ + if not (isinstance(name, basestring) or + name is None or + isinstance(name, self.CData)): + raise TypeError("dlopen(name): name must be a file name, None, " + "or an already-opened 'void *' handle") + with self._lock: + lib, function_cache = _make_ffi_library(self, name, flags) + self._function_caches.append(function_cache) + self._libraries.append(lib) + return lib + + def dlclose(self, lib): + """Close a library obtained with ffi.dlopen(). After this call, + access to functions or variables from the library will fail + (possibly with a segmentation fault). + """ + type(lib).__cffi_close__(lib) + + def _typeof_locked(self, cdecl): + # call me with the lock! + key = cdecl + if key in self._parsed_types: + return self._parsed_types[key] + # + if not isinstance(cdecl, str): # unicode, on Python 2 + cdecl = cdecl.encode('ascii') + # + type = self._parser.parse_type(cdecl) + really_a_function_type = type.is_raw_function + if really_a_function_type: + type = type.as_function_pointer() + btype = self._get_cached_btype(type) + result = btype, really_a_function_type + self._parsed_types[key] = result + return result + + def _typeof(self, cdecl, consider_function_as_funcptr=False): + # string -> ctype object + try: + result = self._parsed_types[cdecl] + except KeyError: + with self._lock: + result = self._typeof_locked(cdecl) + # + btype, really_a_function_type = result + if really_a_function_type and not consider_function_as_funcptr: + raise CDefError("the type %r is a function type, not a " + "pointer-to-function type" % (cdecl,)) + return btype + + def typeof(self, cdecl): + """Parse the C type given as a string and return the + corresponding object. + It can also be used on 'cdata' instance to get its C type. + """ + if isinstance(cdecl, basestring): + return self._typeof(cdecl) + if isinstance(cdecl, self.CData): + return self._backend.typeof(cdecl) + if isinstance(cdecl, types.BuiltinFunctionType): + res = _builtin_function_type(cdecl) + if res is not None: + return res + if (isinstance(cdecl, types.FunctionType) + and hasattr(cdecl, '_cffi_base_type')): + with self._lock: + return self._get_cached_btype(cdecl._cffi_base_type) + raise TypeError(type(cdecl)) + + def sizeof(self, cdecl): + """Return the size in bytes of the argument. It can be a + string naming a C type, or a 'cdata' instance. + """ + if isinstance(cdecl, basestring): + BType = self._typeof(cdecl) + return self._backend.sizeof(BType) + else: + return self._backend.sizeof(cdecl) + + def alignof(self, cdecl): + """Return the natural alignment size in bytes of the C type + given as a string. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.alignof(cdecl) + + def offsetof(self, cdecl, *fields_or_indexes): + """Return the offset of the named field inside the given + structure or array, which must be given as a C type name. + You can give several field names in case of nested structures. + You can also give numeric values which correspond to array + items, in case of an array type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._typeoffsetof(cdecl, *fields_or_indexes)[1] + + def new(self, cdecl, init=None): + """Allocate an instance according to the specified C type and + return a pointer to it. The specified C type must be either a + pointer or an array: ``new('X *')`` allocates an X and returns + a pointer to it, whereas ``new('X[n]')`` allocates an array of + n X'es and returns an array referencing it (which works + mostly like a pointer, like in C). You can also use + ``new('X[]', n)`` to allocate an array of a non-constant + length n. + + The memory is initialized following the rules of declaring a + global variable in C: by default it is zero-initialized, but + an explicit initializer can be given which can be used to + fill all or part of the memory. + + When the returned object goes out of scope, the memory + is freed. In other words the returned object has + ownership of the value of type 'cdecl' that it points to. This + means that the raw data can be used as long as this object is + kept alive, but must not be used for a longer time. Be careful + about that when copying the pointer to the memory somewhere + else, e.g. into another structure. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.newp(cdecl, init) + + def new_allocator(self, alloc=None, free=None, + should_clear_after_alloc=True): + """Return a new allocator, i.e. a function that behaves like ffi.new() + but uses the provided low-level 'alloc' and 'free' functions. + + 'alloc' is called with the size as argument. If it returns NULL, a + MemoryError is raised. 'free' is called with the result of 'alloc' + as argument. Both can be either Python function or directly C + functions. If 'free' is None, then no free function is called. + If both 'alloc' and 'free' are None, the default is used. + + If 'should_clear_after_alloc' is set to False, then the memory + returned by 'alloc' is assumed to be already cleared (or you are + fine with garbage); otherwise CFFI will clear it. + """ + compiled_ffi = self._backend.FFI() + allocator = compiled_ffi.new_allocator(alloc, free, + should_clear_after_alloc) + def allocate(cdecl, init=None): + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return allocator(cdecl, init) + return allocate + + def cast(self, cdecl, source): + """Similar to a C cast: returns an instance of the named C + type initialized with the given 'source'. The source is + casted between integers or pointers of any type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.cast(cdecl, source) + + def string(self, cdata, maxlen=-1): + """Return a Python string (or unicode string) from the 'cdata'. + If 'cdata' is a pointer or array of characters or bytes, returns + the null-terminated string. The returned string extends until + the first null character, or at most 'maxlen' characters. If + 'cdata' is an array then 'maxlen' defaults to its length. + + If 'cdata' is a pointer or array of wchar_t, returns a unicode + string following the same rules. + + If 'cdata' is a single character or byte or a wchar_t, returns + it as a string or unicode string. + + If 'cdata' is an enum, returns the value of the enumerator as a + string, or 'NUMBER' if the value is out of range. + """ + return self._backend.string(cdata, maxlen) + + def unpack(self, cdata, length): + """Unpack an array of C data of the given length, + returning a Python string/unicode/list. + + If 'cdata' is a pointer to 'char', returns a byte string. + It does not stop at the first null. This is equivalent to: + ffi.buffer(cdata, length)[:] + + If 'cdata' is a pointer to 'wchar_t', returns a unicode string. + 'length' is measured in wchar_t's; it is not the size in bytes. + + If 'cdata' is a pointer to anything else, returns a list of + 'length' items. This is a faster equivalent to: + [cdata[i] for i in range(length)] + """ + return self._backend.unpack(cdata, length) + + #def buffer(self, cdata, size=-1): + # """Return a read-write buffer object that references the raw C data + # pointed to by the given 'cdata'. The 'cdata' must be a pointer or + # an array. Can be passed to functions expecting a buffer, or directly + # manipulated with: + # + # buf[:] get a copy of it in a regular string, or + # buf[idx] as a single character + # buf[:] = ... + # buf[idx] = ... change the content + # """ + # note that 'buffer' is a type, set on this instance by __init__ + + def from_buffer(self, cdecl, python_buffer=_unspecified, + require_writable=False): + """Return a cdata of the given type pointing to the data of the + given Python object, which must support the buffer interface. + Note that this is not meant to be used on the built-in types + str or unicode (you can build 'char[]' arrays explicitly) + but only on objects containing large quantities of raw data + in some other format, like 'array.array' or numpy arrays. + + The first argument is optional and default to 'char[]'. + """ + if python_buffer is _unspecified: + cdecl, python_buffer = self.BCharA, cdecl + elif isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.from_buffer(cdecl, python_buffer, + require_writable) + + def memmove(self, dest, src, n): + """ffi.memmove(dest, src, n) copies n bytes of memory from src to dest. + + Like the C function memmove(), the memory areas may overlap; + apart from that it behaves like the C function memcpy(). + + 'src' can be any cdata ptr or array, or any Python buffer object. + 'dest' can be any cdata ptr or array, or a writable Python buffer + object. The size to copy, 'n', is always measured in bytes. + + Unlike other methods, this one supports all Python buffer including + byte strings and bytearrays---but it still does not support + non-contiguous buffers. + """ + return self._backend.memmove(dest, src, n) + + def callback(self, cdecl, python_callable=None, error=None, onerror=None): + """Return a callback object or a decorator making such a + callback object. 'cdecl' must name a C function pointer type. + The callback invokes the specified 'python_callable' (which may + be provided either directly or via a decorator). Important: the + callback object must be manually kept alive for as long as the + callback may be invoked from the C level. + """ + def callback_decorator_wrap(python_callable): + if not callable(python_callable): + raise TypeError("the 'python_callable' argument " + "is not callable") + return self._backend.callback(cdecl, python_callable, + error, onerror) + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) + if python_callable is None: + return callback_decorator_wrap # decorator mode + else: + return callback_decorator_wrap(python_callable) # direct mode + + def getctype(self, cdecl, replace_with=''): + """Return a string giving the C type 'cdecl', which may be itself + a string or a object. If 'replace_with' is given, it gives + extra text to append (or insert for more complicated C types), like + a variable name, or '*' to get actually the C type 'pointer-to-cdecl'. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + replace_with = replace_with.strip() + if (replace_with.startswith('*') + and '&[' in self._backend.getcname(cdecl, '&')): + replace_with = '(%s)' % replace_with + elif replace_with and not replace_with[0] in '[(': + replace_with = ' ' + replace_with + return self._backend.getcname(cdecl, replace_with) + + def gc(self, cdata, destructor, size=0): + """Return a new cdata object that points to the same + data. Later, when this new cdata object is garbage-collected, + 'destructor(old_cdata_object)' will be called. + + The optional 'size' gives an estimate of the size, used to + trigger the garbage collection more eagerly. So far only used + on PyPy. It tells the GC that the returned object keeps alive + roughly 'size' bytes of external memory. + """ + return self._backend.gcp(cdata, destructor, size) + + def _get_cached_btype(self, type): + assert self._lock.acquire(False) is False + # call me with the lock! + try: + BType = self._cached_btypes[type] + except KeyError: + finishlist = [] + BType = type.get_cached_btype(self, finishlist) + for type in finishlist: + type.finish_backend_type(self, finishlist) + return BType + + def verify(self, source='', tmpdir=None, **kwargs): + """Verify that the current ffi signatures compile on this + machine, and return a dynamic library object. The dynamic + library can be used to call functions and access global + variables declared in this 'ffi'. The library is compiled + by the C compiler: it gives you C-level API compatibility + (including calling macros). This is unlike 'ffi.dlopen()', + which requires binary compatibility in the signatures. + """ + from .verifier import Verifier, _caller_dir_pycache + # + # If set_unicode(True) was called, insert the UNICODE and + # _UNICODE macro declarations + if self._windows_unicode: + self._apply_windows_unicode(kwargs) + # + # Set the tmpdir here, and not in Verifier.__init__: it picks + # up the caller's directory, which we want to be the caller of + # ffi.verify(), as opposed to the caller of Veritier(). + tmpdir = tmpdir or _caller_dir_pycache() + # + # Make a Verifier() and use it to load the library. + self.verifier = Verifier(self, source, tmpdir, **kwargs) + lib = self.verifier.load_library() + # + # Save the loaded library for keep-alive purposes, even + # if the caller doesn't keep it alive itself (it should). + self._libraries.append(lib) + return lib + + def _get_errno(self): + return self._backend.get_errno() + def _set_errno(self, errno): + self._backend.set_errno(errno) + errno = property(_get_errno, _set_errno, None, + "the value of 'errno' from/to the C calls") + + def getwinerror(self, code=-1): + return self._backend.getwinerror(code) + + def _pointer_to(self, ctype): + with self._lock: + return model.pointer_cache(self, ctype) + + def addressof(self, cdata, *fields_or_indexes): + """Return the address of a . + If 'fields_or_indexes' are given, returns the address of that + field or array item in the structure or array, recursively in + case of nested structures. + """ + try: + ctype = self._backend.typeof(cdata) + except TypeError: + if '__addressof__' in type(cdata).__dict__: + return type(cdata).__addressof__(cdata, *fields_or_indexes) + raise + if fields_or_indexes: + ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes) + else: + if ctype.kind == "pointer": + raise TypeError("addressof(pointer)") + offset = 0 + ctypeptr = self._pointer_to(ctype) + return self._backend.rawaddressof(ctypeptr, cdata, offset) + + def _typeoffsetof(self, ctype, field_or_index, *fields_or_indexes): + ctype, offset = self._backend.typeoffsetof(ctype, field_or_index) + for field1 in fields_or_indexes: + ctype, offset1 = self._backend.typeoffsetof(ctype, field1, 1) + offset += offset1 + return ctype, offset + + def include(self, ffi_to_include): + """Includes the typedefs, structs, unions and enums defined + in another FFI instance. Usage is similar to a #include in C, + where a part of the program might include types defined in + another part for its own usage. Note that the include() + method has no effect on functions, constants and global + variables, which must anyway be accessed directly from the + lib object returned by the original FFI instance. + """ + if not isinstance(ffi_to_include, FFI): + raise TypeError("ffi.include() expects an argument that is also of" + " type cffi.FFI, not %r" % ( + type(ffi_to_include).__name__,)) + if ffi_to_include is self: + raise ValueError("self.include(self)") + with ffi_to_include._lock: + with self._lock: + self._parser.include(ffi_to_include._parser) + self._cdefsources.append('[') + self._cdefsources.extend(ffi_to_include._cdefsources) + self._cdefsources.append(']') + self._included_ffis.append(ffi_to_include) + + def new_handle(self, x): + return self._backend.newp_handle(self.BVoidP, x) + + def from_handle(self, x): + return self._backend.from_handle(x) + + def release(self, x): + self._backend.release(x) + + def set_unicode(self, enabled_flag): + """Windows: if 'enabled_flag' is True, enable the UNICODE and + _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR + to be (pointers to) wchar_t. If 'enabled_flag' is False, + declare these types to be (pointers to) plain 8-bit characters. + This is mostly for backward compatibility; you usually want True. + """ + if self._windows_unicode is not None: + raise ValueError("set_unicode() can only be called once") + enabled_flag = bool(enabled_flag) + if enabled_flag: + self.cdef("typedef wchar_t TBYTE;" + "typedef wchar_t TCHAR;" + "typedef const wchar_t *LPCTSTR;" + "typedef const wchar_t *PCTSTR;" + "typedef wchar_t *LPTSTR;" + "typedef wchar_t *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + else: + self.cdef("typedef char TBYTE;" + "typedef char TCHAR;" + "typedef const char *LPCTSTR;" + "typedef const char *PCTSTR;" + "typedef char *LPTSTR;" + "typedef char *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + self._windows_unicode = enabled_flag + + def _apply_windows_unicode(self, kwds): + defmacros = kwds.get('define_macros', ()) + if not isinstance(defmacros, (list, tuple)): + raise TypeError("'define_macros' must be a list or tuple") + defmacros = list(defmacros) + [('UNICODE', '1'), + ('_UNICODE', '1')] + kwds['define_macros'] = defmacros + + def _apply_embedding_fix(self, kwds): + # must include an argument like "-lpython2.7" for the compiler + def ensure(key, value): + lst = kwds.setdefault(key, []) + if value not in lst: + lst.append(value) + # + if '__pypy__' in sys.builtin_module_names: + import os + if sys.platform == "win32": + # we need 'libpypy-c.lib'. Current distributions of + # pypy (>= 4.1) contain it as 'libs/python27.lib'. + pythonlib = "python{0[0]}{0[1]}".format(sys.version_info) + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'libs')) + else: + # we need 'libpypy-c.{so,dylib}', which should be by + # default located in 'sys.prefix/bin' for installed + # systems. + if sys.version_info < (3,): + pythonlib = "pypy-c" + else: + pythonlib = "pypy3-c" + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'bin')) + # On uninstalled pypy's, the libpypy-c is typically found in + # .../pypy/goal/. + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'pypy', 'goal')) + else: + if sys.platform == "win32": + template = "python%d%d" + if hasattr(sys, 'gettotalrefcount'): + template += '_d' + else: + try: + import sysconfig + except ImportError: # 2.6 + from cffi._shimmed_dist_utils import sysconfig + template = "python%d.%d" + if sysconfig.get_config_var('DEBUG_EXT'): + template += sysconfig.get_config_var('DEBUG_EXT') + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + if hasattr(sys, 'abiflags'): + pythonlib += sys.abiflags + ensure('libraries', pythonlib) + if sys.platform == "win32": + ensure('extra_link_args', '/MANIFEST') + + def set_source(self, module_name, source, source_extension='.c', **kwds): + import os + if hasattr(self, '_assigned_source'): + raise ValueError("set_source() cannot be called several times " + "per ffi object") + if not isinstance(module_name, basestring): + raise TypeError("'module_name' must be a string") + if os.sep in module_name or (os.altsep and os.altsep in module_name): + raise ValueError("'module_name' must not contain '/': use a dotted " + "name to make a 'package.module' location") + self._assigned_source = (str(module_name), source, + source_extension, kwds) + + def set_source_pkgconfig(self, module_name, pkgconfig_libs, source, + source_extension='.c', **kwds): + from . import pkgconfig + if not isinstance(pkgconfig_libs, list): + raise TypeError("the pkgconfig_libs argument must be a list " + "of package names") + kwds2 = pkgconfig.flags_from_pkgconfig(pkgconfig_libs) + pkgconfig.merge_flags(kwds, kwds2) + self.set_source(module_name, source, source_extension, **kwds) + + def distutils_extension(self, tmpdir='build', verbose=True): + from cffi._shimmed_dist_utils import mkpath + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + if hasattr(self, 'verifier'): # fallback, 'tmpdir' ignored + return self.verifier.get_extension() + raise ValueError("set_source() must be called before" + " distutils_extension()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("distutils_extension() is only for C extension " + "modules, not for dlopen()-style pure Python " + "modules") + mkpath(tmpdir) + ext, updated = recompile(self, module_name, + source, tmpdir=tmpdir, extradir=tmpdir, + source_extension=source_extension, + call_c_compiler=False, **kwds) + if verbose: + if updated: + sys.stderr.write("regenerated: %r\n" % (ext.sources[0],)) + else: + sys.stderr.write("not modified: %r\n" % (ext.sources[0],)) + return ext + + def emit_c_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("emit_c_code() is only for C extension modules, " + "not for dlopen()-style pure Python modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def emit_python_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is not None: + raise TypeError("emit_python_code() is only for dlopen()-style " + "pure Python modules, not for C extension modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def compile(self, tmpdir='.', verbose=0, target=None, debug=None): + """The 'target' argument gives the final file name of the + compiled DLL. Use '*' to force distutils' choice, suitable for + regular CPython C API modules. Use a file name ending in '.*' + to ask for the system's default extension for dynamic libraries + (.so/.dll/.dylib). + + The default is '*' when building a non-embedded C API extension, + and (module_name + '.*') when building an embedded library. + """ + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before compile()") + module_name, source, source_extension, kwds = self._assigned_source + return recompile(self, module_name, source, tmpdir=tmpdir, + target=target, source_extension=source_extension, + compiler_verbose=verbose, debug=debug, **kwds) + + def init_once(self, func, tag): + # Read _init_once_cache[tag], which is either (False, lock) if + # we're calling the function now in some thread, or (True, result). + # Don't call setdefault() in most cases, to avoid allocating and + # immediately freeing a lock; but still use setdefaut() to avoid + # races. + try: + x = self._init_once_cache[tag] + except KeyError: + x = self._init_once_cache.setdefault(tag, (False, allocate_lock())) + # Common case: we got (True, result), so we return the result. + if x[0]: + return x[1] + # Else, it's a lock. Acquire it to serialize the following tests. + with x[1]: + # Read again from _init_once_cache the current status. + x = self._init_once_cache[tag] + if x[0]: + return x[1] + # Call the function and store the result back. + result = func() + self._init_once_cache[tag] = (True, result) + return result + + def embedding_init_code(self, pysource): + if self._embedding: + raise ValueError("embedding_init_code() can only be called once") + # fix 'pysource' before it gets dumped into the C file: + # - remove empty lines at the beginning, so it starts at "line 1" + # - dedent, if all non-empty lines are indented + # - check for SyntaxErrors + import re + match = re.match(r'\s*\n', pysource) + if match: + pysource = pysource[match.end():] + lines = pysource.splitlines() or [''] + prefix = re.match(r'\s*', lines[0]).group() + for i in range(1, len(lines)): + line = lines[i] + if line.rstrip(): + while not line.startswith(prefix): + prefix = prefix[:-1] + i = len(prefix) + lines = [line[i:]+'\n' for line in lines] + pysource = ''.join(lines) + # + compile(pysource, "cffi_init", "exec") + # + self._embedding = pysource + + def def_extern(self, *args, **kwds): + raise ValueError("ffi.def_extern() is only available on API-mode FFI " + "objects") + + def list_types(self): + """Returns the user type names known to this FFI instance. + This returns a tuple containing three lists of names: + (typedef_names, names_of_structs, names_of_unions) + """ + typedefs = [] + structs = [] + unions = [] + for key in self._parser._declarations: + if key.startswith('typedef '): + typedefs.append(key[8:]) + elif key.startswith('struct '): + structs.append(key[7:]) + elif key.startswith('union '): + unions.append(key[6:]) + typedefs.sort() + structs.sort() + unions.sort() + return (typedefs, structs, unions) + + +def _load_backend_lib(backend, name, flags): + import os + if not isinstance(name, basestring): + if sys.platform != "win32" or name is not None: + return backend.load_library(name, flags) + name = "c" # Windows: load_library(None) fails, but this works + # on Python 2 (backward compatibility hack only) + first_error = None + if '.' in name or '/' in name or os.sep in name: + try: + return backend.load_library(name, flags) + except OSError as e: + first_error = e + import ctypes.util + path = ctypes.util.find_library(name) + if path is None: + if name == "c" and sys.platform == "win32" and sys.version_info >= (3,): + raise OSError("dlopen(None) cannot work on Windows for Python 3 " + "(see http://bugs.python.org/issue23606)") + msg = ("ctypes.util.find_library() did not manage " + "to locate a library called %r" % (name,)) + if first_error is not None: + msg = "%s. Additionally, %s" % (first_error, msg) + raise OSError(msg) + return backend.load_library(path, flags) + +def _make_ffi_library(ffi, libname, flags): + backend = ffi._backend + backendlib = _load_backend_lib(backend, libname, flags) + # + def accessor_function(name): + key = 'function ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + value = backendlib.load_function(BType, name) + library.__dict__[name] = value + # + def accessor_variable(name): + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + read_variable = backendlib.read_variable + write_variable = backendlib.write_variable + setattr(FFILibrary, name, property( + lambda self: read_variable(BType, name), + lambda self, value: write_variable(BType, name, value))) + # + def addressof_var(name): + try: + return addr_variables[name] + except KeyError: + with ffi._lock: + if name not in addr_variables: + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + if BType.kind != 'array': + BType = model.pointer_cache(ffi, BType) + p = backendlib.load_function(BType, name) + addr_variables[name] = p + return addr_variables[name] + # + def accessor_constant(name): + raise NotImplementedError("non-integer constant '%s' cannot be " + "accessed from a dlopen() library" % (name,)) + # + def accessor_int_constant(name): + library.__dict__[name] = ffi._parser._int_constants[name] + # + accessors = {} + accessors_version = [False] + addr_variables = {} + # + def update_accessors(): + if accessors_version[0] is ffi._cdef_version: + return + # + for key, (tp, _) in ffi._parser._declarations.items(): + if not isinstance(tp, model.EnumType): + tag, name = key.split(' ', 1) + if tag == 'function': + accessors[name] = accessor_function + elif tag == 'variable': + accessors[name] = accessor_variable + elif tag == 'constant': + accessors[name] = accessor_constant + else: + for i, enumname in enumerate(tp.enumerators): + def accessor_enum(name, tp=tp, i=i): + tp.check_not_partial() + library.__dict__[name] = tp.enumvalues[i] + accessors[enumname] = accessor_enum + for name in ffi._parser._int_constants: + accessors.setdefault(name, accessor_int_constant) + accessors_version[0] = ffi._cdef_version + # + def make_accessor(name): + with ffi._lock: + if name in library.__dict__ or name in FFILibrary.__dict__: + return # added by another thread while waiting for the lock + if name not in accessors: + update_accessors() + if name not in accessors: + raise AttributeError(name) + accessors[name](name) + # + class FFILibrary(object): + def __getattr__(self, name): + make_accessor(name) + return getattr(self, name) + def __setattr__(self, name, value): + try: + property = getattr(self.__class__, name) + except AttributeError: + make_accessor(name) + setattr(self, name, value) + else: + property.__set__(self, value) + def __dir__(self): + with ffi._lock: + update_accessors() + return accessors.keys() + def __addressof__(self, name): + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + make_accessor(name) + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + raise AttributeError("cffi library has no function or " + "global variable named '%s'" % (name,)) + def __cffi_close__(self): + backendlib.close_lib() + self.__dict__.clear() + # + if isinstance(libname, basestring): + try: + if not isinstance(libname, str): # unicode, on Python 2 + libname = libname.encode('utf-8') + FFILibrary.__name__ = 'FFILibrary_%s' % libname + except UnicodeError: + pass + library = FFILibrary() + return library, library.__dict__ + +def _builtin_function_type(func): + # a hack to make at least ffi.typeof(builtin_function) work, + # if the builtin function was obtained by 'vengine_cpy'. + import sys + try: + module = sys.modules[func.__module__] + ffi = module._cffi_original_ffi + types_of_builtin_funcs = module._cffi_types_of_builtin_funcs + tp = types_of_builtin_funcs[func] + except (KeyError, AttributeError, TypeError): + return None + else: + with ffi._lock: + return ffi._get_cached_btype(tp) diff --git a/uno/lib/python/cffi/backend_ctypes.py b/uno/lib/python/cffi/backend_ctypes.py new file mode 100644 index 00000000..3368a2ac --- /dev/null +++ b/uno/lib/python/cffi/backend_ctypes.py @@ -0,0 +1,1121 @@ +import ctypes, ctypes.util, operator, sys +from . import model + +if sys.version_info < (3,): + bytechr = chr +else: + unicode = str + long = int + xrange = range + bytechr = lambda num: bytes([num]) + +class CTypesType(type): + pass + +class CTypesData(object): + __metaclass__ = CTypesType + __slots__ = ['__weakref__'] + __name__ = '' + + def __init__(self, *args): + raise TypeError("cannot instantiate %r" % (self.__class__,)) + + @classmethod + def _newp(cls, init): + raise TypeError("expected a pointer or array ctype, got '%s'" + % (cls._get_c_name(),)) + + @staticmethod + def _to_ctypes(value): + raise TypeError + + @classmethod + def _arg_to_ctypes(cls, *value): + try: + ctype = cls._ctype + except AttributeError: + raise TypeError("cannot create an instance of %r" % (cls,)) + if value: + res = cls._to_ctypes(*value) + if not isinstance(res, ctype): + res = cls._ctype(res) + else: + res = cls._ctype() + return res + + @classmethod + def _create_ctype_obj(cls, init): + if init is None: + return cls._arg_to_ctypes() + else: + return cls._arg_to_ctypes(init) + + @staticmethod + def _from_ctypes(ctypes_value): + raise TypeError + + @classmethod + def _get_c_name(cls, replace_with=''): + return cls._reftypename.replace(' &', replace_with) + + @classmethod + def _fix_class(cls): + cls.__name__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__qualname__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__module__ = 'ffi' + + def _get_own_repr(self): + raise NotImplementedError + + def _addr_repr(self, address): + if address == 0: + return 'NULL' + else: + if address < 0: + address += 1 << (8*ctypes.sizeof(ctypes.c_void_p)) + return '0x%x' % address + + def __repr__(self, c_name=None): + own = self._get_own_repr() + return '' % (c_name or self._get_c_name(), own) + + def _convert_to_address(self, BClass): + if BClass is None: + raise TypeError("cannot convert %r to an address" % ( + self._get_c_name(),)) + else: + raise TypeError("cannot convert %r to %r" % ( + self._get_c_name(), BClass._get_c_name())) + + @classmethod + def _get_size(cls): + return ctypes.sizeof(cls._ctype) + + def _get_size_of_instance(self): + return ctypes.sizeof(self._ctype) + + @classmethod + def _cast_from(cls, source): + raise TypeError("cannot cast to %r" % (cls._get_c_name(),)) + + def _cast_to_integer(self): + return self._convert_to_address(None) + + @classmethod + def _alignment(cls): + return ctypes.alignment(cls._ctype) + + def __iter__(self): + raise TypeError("cdata %r does not support iteration" % ( + self._get_c_name()),) + + def _make_cmp(name): + cmpfunc = getattr(operator, name) + def cmp(self, other): + v_is_ptr = not isinstance(self, CTypesGenericPrimitive) + w_is_ptr = (isinstance(other, CTypesData) and + not isinstance(other, CTypesGenericPrimitive)) + if v_is_ptr and w_is_ptr: + return cmpfunc(self._convert_to_address(None), + other._convert_to_address(None)) + elif v_is_ptr or w_is_ptr: + return NotImplemented + else: + if isinstance(self, CTypesGenericPrimitive): + self = self._value + if isinstance(other, CTypesGenericPrimitive): + other = other._value + return cmpfunc(self, other) + cmp.func_name = name + return cmp + + __eq__ = _make_cmp('__eq__') + __ne__ = _make_cmp('__ne__') + __lt__ = _make_cmp('__lt__') + __le__ = _make_cmp('__le__') + __gt__ = _make_cmp('__gt__') + __ge__ = _make_cmp('__ge__') + + def __hash__(self): + return hash(self._convert_to_address(None)) + + def _to_string(self, maxlen): + raise TypeError("string(): %r" % (self,)) + + +class CTypesGenericPrimitive(CTypesData): + __slots__ = [] + + def __hash__(self): + return hash(self._value) + + def _get_own_repr(self): + return repr(self._from_ctypes(self._value)) + + +class CTypesGenericArray(CTypesData): + __slots__ = [] + + @classmethod + def _newp(cls, init): + return cls(init) + + def __iter__(self): + for i in xrange(len(self)): + yield self[i] + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + +class CTypesGenericPtr(CTypesData): + __slots__ = ['_address', '_as_ctype_ptr'] + _automatic_casts = False + kind = "pointer" + + @classmethod + def _newp(cls, init): + return cls(init) + + @classmethod + def _cast_from(cls, source): + if source is None: + address = 0 + elif isinstance(source, CTypesData): + address = source._cast_to_integer() + elif isinstance(source, (int, long)): + address = source + else: + raise TypeError("bad type for cast to %r: %r" % + (cls, type(source).__name__)) + return cls._new_pointer_at(address) + + @classmethod + def _new_pointer_at(cls, address): + self = cls.__new__(cls) + self._address = address + self._as_ctype_ptr = ctypes.cast(address, cls._ctype) + return self + + def _get_own_repr(self): + try: + return self._addr_repr(self._address) + except AttributeError: + return '???' + + def _cast_to_integer(self): + return self._address + + def __nonzero__(self): + return bool(self._address) + __bool__ = __nonzero__ + + @classmethod + def _to_ctypes(cls, value): + if not isinstance(value, CTypesData): + raise TypeError("unexpected %s object" % type(value).__name__) + address = value._convert_to_address(cls) + return ctypes.cast(address, cls._ctype) + + @classmethod + def _from_ctypes(cls, ctypes_ptr): + address = ctypes.cast(ctypes_ptr, ctypes.c_void_p).value or 0 + return cls._new_pointer_at(address) + + @classmethod + def _initialize(cls, ctypes_ptr, value): + if value: + ctypes_ptr.contents = cls._to_ctypes(value).contents + + def _convert_to_address(self, BClass): + if (BClass in (self.__class__, None) or BClass._automatic_casts + or self._automatic_casts): + return self._address + else: + return CTypesData._convert_to_address(self, BClass) + + +class CTypesBaseStructOrUnion(CTypesData): + __slots__ = ['_blob'] + + @classmethod + def _create_ctype_obj(cls, init): + # may be overridden + raise TypeError("cannot instantiate opaque type %s" % (cls,)) + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + @classmethod + def _offsetof(cls, fieldname): + return getattr(cls._ctype, fieldname).offset + + def _convert_to_address(self, BClass): + if getattr(BClass, '_BItem', None) is self.__class__: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @classmethod + def _from_ctypes(cls, ctypes_struct_or_union): + self = cls.__new__(cls) + self._blob = ctypes_struct_or_union + return self + + @classmethod + def _to_ctypes(cls, value): + return value._blob + + def __repr__(self, c_name=None): + return CTypesData.__repr__(self, c_name or self._get_c_name(' &')) + + +class CTypesBackend(object): + + PRIMITIVE_TYPES = { + 'char': ctypes.c_char, + 'short': ctypes.c_short, + 'int': ctypes.c_int, + 'long': ctypes.c_long, + 'long long': ctypes.c_longlong, + 'signed char': ctypes.c_byte, + 'unsigned char': ctypes.c_ubyte, + 'unsigned short': ctypes.c_ushort, + 'unsigned int': ctypes.c_uint, + 'unsigned long': ctypes.c_ulong, + 'unsigned long long': ctypes.c_ulonglong, + 'float': ctypes.c_float, + 'double': ctypes.c_double, + '_Bool': ctypes.c_bool, + } + + for _name in ['unsigned long long', 'unsigned long', + 'unsigned int', 'unsigned short', 'unsigned char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['uint%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['uintptr_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['size_t'] = PRIMITIVE_TYPES[_name] + + for _name in ['long long', 'long', 'int', 'short', 'signed char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['int%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['intptr_t'] = PRIMITIVE_TYPES[_name] + PRIMITIVE_TYPES['ptrdiff_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['ssize_t'] = PRIMITIVE_TYPES[_name] + + + def __init__(self): + self.RTLD_LAZY = 0 # not supported anyway by ctypes + self.RTLD_NOW = 0 + self.RTLD_GLOBAL = ctypes.RTLD_GLOBAL + self.RTLD_LOCAL = ctypes.RTLD_LOCAL + + def set_ffi(self, ffi): + self.ffi = ffi + + def _get_types(self): + return CTypesData, CTypesType + + def load_library(self, path, flags=0): + cdll = ctypes.CDLL(path, flags) + return CTypesLibrary(self, cdll) + + def new_void_type(self): + class CTypesVoid(CTypesData): + __slots__ = [] + _reftypename = 'void &' + @staticmethod + def _from_ctypes(novalue): + return None + @staticmethod + def _to_ctypes(novalue): + if novalue is not None: + raise TypeError("None expected, got %s object" % + (type(novalue).__name__,)) + return None + CTypesVoid._fix_class() + return CTypesVoid + + def new_primitive_type(self, name): + if name == 'wchar_t': + raise NotImplementedError(name) + ctype = self.PRIMITIVE_TYPES[name] + if name == 'char': + kind = 'char' + elif name in ('float', 'double'): + kind = 'float' + else: + if name in ('signed char', 'unsigned char'): + kind = 'byte' + elif name == '_Bool': + kind = 'bool' + else: + kind = 'int' + is_signed = (ctype(-1).value == -1) + # + def _cast_source_to_int(source): + if isinstance(source, (int, long, float)): + source = int(source) + elif isinstance(source, CTypesData): + source = source._cast_to_integer() + elif isinstance(source, bytes): + source = ord(source) + elif source is None: + source = 0 + else: + raise TypeError("bad type for cast to %r: %r" % + (CTypesPrimitive, type(source).__name__)) + return source + # + kind1 = kind + class CTypesPrimitive(CTypesGenericPrimitive): + __slots__ = ['_value'] + _ctype = ctype + _reftypename = '%s &' % name + kind = kind1 + + def __init__(self, value): + self._value = value + + @staticmethod + def _create_ctype_obj(init): + if init is None: + return ctype() + return ctype(CTypesPrimitive._to_ctypes(init)) + + if kind == 'int' or kind == 'byte': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = ctype(source).value # cast within range + return cls(source) + def __int__(self): + return self._value + + if kind == 'bool': + @classmethod + def _cast_from(cls, source): + if not isinstance(source, (int, long, float)): + source = _cast_source_to_int(source) + return cls(bool(source)) + def __int__(self): + return int(self._value) + + if kind == 'char': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = bytechr(source & 0xFF) + return cls(source) + def __int__(self): + return ord(self._value) + + if kind == 'float': + @classmethod + def _cast_from(cls, source): + if isinstance(source, float): + pass + elif isinstance(source, CTypesGenericPrimitive): + if hasattr(source, '__float__'): + source = float(source) + else: + source = int(source) + else: + source = _cast_source_to_int(source) + source = ctype(source).value # fix precision + return cls(source) + def __int__(self): + return int(self._value) + def __float__(self): + return self._value + + _cast_to_integer = __int__ + + if kind == 'int' or kind == 'byte' or kind == 'bool': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long)): + if isinstance(x, CTypesData): + x = int(x) + else: + raise TypeError("integer expected, got %s" % + type(x).__name__) + if ctype(x).value != x: + if not is_signed and x < 0: + raise OverflowError("%s: negative integer" % name) + else: + raise OverflowError("%s: integer out of bounds" + % name) + return x + + if kind == 'char': + @staticmethod + def _to_ctypes(x): + if isinstance(x, bytes) and len(x) == 1: + return x + if isinstance(x, CTypesPrimitive): # > + return x._value + raise TypeError("character expected, got %s" % + type(x).__name__) + def __nonzero__(self): + return ord(self._value) != 0 + else: + def __nonzero__(self): + return self._value != 0 + __bool__ = __nonzero__ + + if kind == 'float': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long, float, CTypesData)): + raise TypeError("float expected, got %s" % + type(x).__name__) + return ctype(x).value + + @staticmethod + def _from_ctypes(value): + return getattr(value, 'value', value) + + @staticmethod + def _initialize(blob, init): + blob.value = CTypesPrimitive._to_ctypes(init) + + if kind == 'char': + def _to_string(self, maxlen): + return self._value + if kind == 'byte': + def _to_string(self, maxlen): + return chr(self._value & 0xff) + # + CTypesPrimitive._fix_class() + return CTypesPrimitive + + def new_pointer_type(self, BItem): + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'charp' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'bytep' + elif BItem is getbtype(model.void_type): + kind = 'voidp' + else: + kind = 'generic' + # + class CTypesPtr(CTypesGenericPtr): + __slots__ = ['_own'] + if kind == 'charp': + __slots__ += ['__as_strbuf'] + _BItem = BItem + if hasattr(BItem, '_ctype'): + _ctype = ctypes.POINTER(BItem._ctype) + _bitem_size = ctypes.sizeof(BItem._ctype) + else: + _ctype = ctypes.c_void_p + if issubclass(BItem, CTypesGenericArray): + _reftypename = BItem._get_c_name('(* &)') + else: + _reftypename = BItem._get_c_name(' * &') + + def __init__(self, init): + ctypeobj = BItem._create_ctype_obj(init) + if kind == 'charp': + self.__as_strbuf = ctypes.create_string_buffer( + ctypeobj.value + b'\x00') + self._as_ctype_ptr = ctypes.cast( + self.__as_strbuf, self._ctype) + else: + self._as_ctype_ptr = ctypes.pointer(ctypeobj) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own = True + + def __add__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address + + other * self._bitem_size) + else: + return NotImplemented + + def __sub__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address - + other * self._bitem_size) + elif type(self) is type(other): + return (self._address - other._address) // self._bitem_size + else: + return NotImplemented + + def __getitem__(self, index): + if getattr(self, '_own', False) and index != 0: + raise IndexError + return BItem._from_ctypes(self._as_ctype_ptr[index]) + + def __setitem__(self, index, value): + self._as_ctype_ptr[index] = BItem._to_ctypes(value) + + if kind == 'charp' or kind == 'voidp': + @classmethod + def _arg_to_ctypes(cls, *value): + if value and isinstance(value[0], bytes): + return ctypes.c_char_p(value[0]) + else: + return super(CTypesPtr, cls)._arg_to_ctypes(*value) + + if kind == 'charp' or kind == 'bytep': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = sys.maxsize + p = ctypes.cast(self._as_ctype_ptr, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % ( + ctypes.sizeof(self._as_ctype_ptr.contents),) + return super(CTypesPtr, self)._get_own_repr() + # + if (BItem is self.ffi._get_cached_btype(model.void_type) or + BItem is self.ffi._get_cached_btype(model.PrimitiveType('char'))): + CTypesPtr._automatic_casts = True + # + CTypesPtr._fix_class() + return CTypesPtr + + def new_array_type(self, CTypesPtr, length): + if length is None: + brackets = ' &[]' + else: + brackets = ' &[%d]' % length + BItem = CTypesPtr._BItem + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'char' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'byte' + else: + kind = 'generic' + # + class CTypesArray(CTypesGenericArray): + __slots__ = ['_blob', '_own'] + if length is not None: + _ctype = BItem._ctype * length + else: + __slots__.append('_ctype') + _reftypename = BItem._get_c_name(brackets) + _declared_length = length + _CTPtr = CTypesPtr + + def __init__(self, init): + if length is None: + if isinstance(init, (int, long)): + len1 = init + init = None + elif kind == 'char' and isinstance(init, bytes): + len1 = len(init) + 1 # extra null + else: + init = tuple(init) + len1 = len(init) + self._ctype = BItem._ctype * len1 + self._blob = self._ctype() + self._own = True + if init is not None: + self._initialize(self._blob, init) + + @staticmethod + def _initialize(blob, init): + if isinstance(init, bytes): + init = [init[i:i+1] for i in range(len(init))] + else: + if isinstance(init, CTypesGenericArray): + if (len(init) != len(blob) or + not isinstance(init, CTypesArray)): + raise TypeError("length/type mismatch: %s" % (init,)) + init = tuple(init) + if len(init) > len(blob): + raise IndexError("too many initializers") + addr = ctypes.cast(blob, ctypes.c_void_p).value + PTR = ctypes.POINTER(BItem._ctype) + itemsize = ctypes.sizeof(BItem._ctype) + for i, value in enumerate(init): + p = ctypes.cast(addr + i * itemsize, PTR) + BItem._initialize(p.contents, value) + + def __len__(self): + return len(self._blob) + + def __getitem__(self, index): + if not (0 <= index < len(self._blob)): + raise IndexError + return BItem._from_ctypes(self._blob[index]) + + def __setitem__(self, index, value): + if not (0 <= index < len(self._blob)): + raise IndexError + self._blob[index] = BItem._to_ctypes(value) + + if kind == 'char' or kind == 'byte': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = len(self._blob) + p = ctypes.cast(self._blob, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % (ctypes.sizeof(self._blob),) + return super(CTypesArray, self)._get_own_repr() + + def _convert_to_address(self, BClass): + if BClass in (CTypesPtr, None) or BClass._automatic_casts: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @staticmethod + def _from_ctypes(ctypes_array): + self = CTypesArray.__new__(CTypesArray) + self._blob = ctypes_array + return self + + @staticmethod + def _arg_to_ctypes(value): + return CTypesPtr._arg_to_ctypes(value) + + def __add__(self, other): + if isinstance(other, (int, long)): + return CTypesPtr._new_pointer_at( + ctypes.addressof(self._blob) + + other * ctypes.sizeof(BItem._ctype)) + else: + return NotImplemented + + @classmethod + def _cast_from(cls, source): + raise NotImplementedError("casting to %r" % ( + cls._get_c_name(),)) + # + CTypesArray._fix_class() + return CTypesArray + + def _new_struct_or_union(self, kind, name, base_ctypes_class): + # + class struct_or_union(base_ctypes_class): + pass + struct_or_union.__name__ = '%s_%s' % (kind, name) + kind1 = kind + # + class CTypesStructOrUnion(CTypesBaseStructOrUnion): + __slots__ = ['_blob'] + _ctype = struct_or_union + _reftypename = '%s &' % (name,) + _kind = kind = kind1 + # + CTypesStructOrUnion._fix_class() + return CTypesStructOrUnion + + def new_struct_type(self, name): + return self._new_struct_or_union('struct', name, ctypes.Structure) + + def new_union_type(self, name): + return self._new_struct_or_union('union', name, ctypes.Union) + + def complete_struct_or_union(self, CTypesStructOrUnion, fields, tp, + totalsize=-1, totalalignment=-1, sflags=0, + pack=0): + if totalsize >= 0 or totalalignment >= 0: + raise NotImplementedError("the ctypes backend of CFFI does not support " + "structures completed by verify(); please " + "compile and install the _cffi_backend module.") + struct_or_union = CTypesStructOrUnion._ctype + fnames = [fname for (fname, BField, bitsize) in fields] + btypes = [BField for (fname, BField, bitsize) in fields] + bitfields = [bitsize for (fname, BField, bitsize) in fields] + # + bfield_types = {} + cfields = [] + for (fname, BField, bitsize) in fields: + if bitsize < 0: + cfields.append((fname, BField._ctype)) + bfield_types[fname] = BField + else: + cfields.append((fname, BField._ctype, bitsize)) + bfield_types[fname] = Ellipsis + if sflags & 8: + struct_or_union._pack_ = 1 + elif pack: + struct_or_union._pack_ = pack + struct_or_union._fields_ = cfields + CTypesStructOrUnion._bfield_types = bfield_types + # + @staticmethod + def _create_ctype_obj(init): + result = struct_or_union() + if init is not None: + initialize(result, init) + return result + CTypesStructOrUnion._create_ctype_obj = _create_ctype_obj + # + def initialize(blob, init): + if is_union: + if len(init) > 1: + raise ValueError("union initializer: %d items given, but " + "only one supported (use a dict if needed)" + % (len(init),)) + if not isinstance(init, dict): + if isinstance(init, (bytes, unicode)): + raise TypeError("union initializer: got a str") + init = tuple(init) + if len(init) > len(fnames): + raise ValueError("too many values for %s initializer" % + CTypesStructOrUnion._get_c_name()) + init = dict(zip(fnames, init)) + addr = ctypes.addressof(blob) + for fname, value in init.items(): + BField, bitsize = name2fieldtype[fname] + assert bitsize < 0, \ + "not implemented: initializer with bit fields" + offset = CTypesStructOrUnion._offsetof(fname) + PTR = ctypes.POINTER(BField._ctype) + p = ctypes.cast(addr + offset, PTR) + BField._initialize(p.contents, value) + is_union = CTypesStructOrUnion._kind == 'union' + name2fieldtype = dict(zip(fnames, zip(btypes, bitfields))) + # + for fname, BField, bitsize in fields: + if fname == '': + raise NotImplementedError("nested anonymous structs/unions") + if hasattr(CTypesStructOrUnion, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + if bitsize < 0: + def getter(self, fname=fname, BField=BField, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BField._from_ctypes(p.contents) + def setter(self, value, fname=fname, BField=BField): + setattr(self._blob, fname, BField._to_ctypes(value)) + # + if issubclass(BField, CTypesGenericArray): + setter = None + if BField._declared_length == 0: + def getter(self, fname=fname, BFieldPtr=BField._CTPtr, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BFieldPtr._from_ctypes(p) + # + else: + def getter(self, fname=fname, BField=BField): + return BField._from_ctypes(getattr(self._blob, fname)) + def setter(self, value, fname=fname, BField=BField): + # xxx obscure workaround + value = BField._to_ctypes(value) + oldvalue = getattr(self._blob, fname) + setattr(self._blob, fname, value) + if value != getattr(self._blob, fname): + setattr(self._blob, fname, oldvalue) + raise OverflowError("value too large for bitfield") + setattr(CTypesStructOrUnion, fname, property(getter, setter)) + # + CTypesPtr = self.ffi._get_cached_btype(model.PointerType(tp)) + for fname in fnames: + if hasattr(CTypesPtr, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + def getter(self, fname=fname): + return getattr(self[0], fname) + def setter(self, value, fname=fname): + setattr(self[0], fname, value) + setattr(CTypesPtr, fname, property(getter, setter)) + + def new_function_type(self, BArgs, BResult, has_varargs): + nameargs = [BArg._get_c_name() for BArg in BArgs] + if has_varargs: + nameargs.append('...') + nameargs = ', '.join(nameargs) + # + class CTypesFunctionPtr(CTypesGenericPtr): + __slots__ = ['_own_callback', '_name'] + _ctype = ctypes.CFUNCTYPE(getattr(BResult, '_ctype', None), + *[BArg._ctype for BArg in BArgs], + use_errno=True) + _reftypename = BResult._get_c_name('(* &)(%s)' % (nameargs,)) + + def __init__(self, init, error=None): + # create a callback to the Python callable init() + import traceback + assert not has_varargs, "varargs not supported for callbacks" + if getattr(BResult, '_ctype', None) is not None: + error = BResult._from_ctypes( + BResult._create_ctype_obj(error)) + else: + error = None + def callback(*args): + args2 = [] + for arg, BArg in zip(args, BArgs): + args2.append(BArg._from_ctypes(arg)) + try: + res2 = init(*args2) + res2 = BResult._to_ctypes(res2) + except: + traceback.print_exc() + res2 = error + if issubclass(BResult, CTypesGenericPtr): + if res2: + res2 = ctypes.cast(res2, ctypes.c_void_p).value + # .value: http://bugs.python.org/issue1574593 + else: + res2 = None + #print repr(res2) + return res2 + if issubclass(BResult, CTypesGenericPtr): + # The only pointers callbacks can return are void*s: + # http://bugs.python.org/issue5710 + callback_ctype = ctypes.CFUNCTYPE( + ctypes.c_void_p, + *[BArg._ctype for BArg in BArgs], + use_errno=True) + else: + callback_ctype = CTypesFunctionPtr._ctype + self._as_ctype_ptr = callback_ctype(callback) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own_callback = init + + @staticmethod + def _initialize(ctypes_ptr, value): + if value: + raise NotImplementedError("ctypes backend: not supported: " + "initializers for function pointers") + + def __repr__(self): + c_name = getattr(self, '_name', None) + if c_name: + i = self._reftypename.index('(* &)') + if self._reftypename[i-1] not in ' )*': + c_name = ' ' + c_name + c_name = self._reftypename.replace('(* &)', c_name) + return CTypesData.__repr__(self, c_name) + + def _get_own_repr(self): + if getattr(self, '_own_callback', None) is not None: + return 'calling %r' % (self._own_callback,) + return super(CTypesFunctionPtr, self)._get_own_repr() + + def __call__(self, *args): + if has_varargs: + assert len(args) >= len(BArgs) + extraargs = args[len(BArgs):] + args = args[:len(BArgs)] + else: + assert len(args) == len(BArgs) + ctypes_args = [] + for arg, BArg in zip(args, BArgs): + ctypes_args.append(BArg._arg_to_ctypes(arg)) + if has_varargs: + for i, arg in enumerate(extraargs): + if arg is None: + ctypes_args.append(ctypes.c_void_p(0)) # NULL + continue + if not isinstance(arg, CTypesData): + raise TypeError( + "argument %d passed in the variadic part " + "needs to be a cdata object (got %s)" % + (1 + len(BArgs) + i, type(arg).__name__)) + ctypes_args.append(arg._arg_to_ctypes(arg)) + result = self._as_ctype_ptr(*ctypes_args) + return BResult._from_ctypes(result) + # + CTypesFunctionPtr._fix_class() + return CTypesFunctionPtr + + def new_enum_type(self, name, enumerators, enumvalues, CTypesInt): + assert isinstance(name, str) + reverse_mapping = dict(zip(reversed(enumvalues), + reversed(enumerators))) + # + class CTypesEnum(CTypesInt): + __slots__ = [] + _reftypename = '%s &' % name + + def _get_own_repr(self): + value = self._value + try: + return '%d: %s' % (value, reverse_mapping[value]) + except KeyError: + return str(value) + + def _to_string(self, maxlen): + value = self._value + try: + return reverse_mapping[value] + except KeyError: + return str(value) + # + CTypesEnum._fix_class() + return CTypesEnum + + def get_errno(self): + return ctypes.get_errno() + + def set_errno(self, value): + ctypes.set_errno(value) + + def string(self, b, maxlen=-1): + return b._to_string(maxlen) + + def buffer(self, bptr, size=-1): + raise NotImplementedError("buffer() with ctypes backend") + + def sizeof(self, cdata_or_BType): + if isinstance(cdata_or_BType, CTypesData): + return cdata_or_BType._get_size_of_instance() + else: + assert issubclass(cdata_or_BType, CTypesData) + return cdata_or_BType._get_size() + + def alignof(self, BType): + assert issubclass(BType, CTypesData) + return BType._alignment() + + def newp(self, BType, source): + if not issubclass(BType, CTypesData): + raise TypeError + return BType._newp(source) + + def cast(self, BType, source): + return BType._cast_from(source) + + def callback(self, BType, source, error, onerror): + assert onerror is None # XXX not implemented + return BType(source, error) + + _weakref_cache_ref = None + + def gcp(self, cdata, destructor, size=0): + if self._weakref_cache_ref is None: + import weakref + class MyRef(weakref.ref): + def __eq__(self, other): + myref = self() + return self is other or ( + myref is not None and myref is other()) + def __ne__(self, other): + return not (self == other) + def __hash__(self): + try: + return self._hash + except AttributeError: + self._hash = hash(self()) + return self._hash + self._weakref_cache_ref = {}, MyRef + weak_cache, MyRef = self._weakref_cache_ref + + if destructor is None: + try: + del weak_cache[MyRef(cdata)] + except KeyError: + raise TypeError("Can remove destructor only on a object " + "previously returned by ffi.gc()") + return None + + def remove(k): + cdata, destructor = weak_cache.pop(k, (None, None)) + if destructor is not None: + destructor(cdata) + + new_cdata = self.cast(self.typeof(cdata), cdata) + assert new_cdata is not cdata + weak_cache[MyRef(new_cdata, remove)] = (cdata, destructor) + return new_cdata + + typeof = type + + def getcname(self, BType, replace_with): + return BType._get_c_name(replace_with) + + def typeoffsetof(self, BType, fieldname, num=0): + if isinstance(fieldname, str): + if num == 0 and issubclass(BType, CTypesGenericPtr): + BType = BType._BItem + if not issubclass(BType, CTypesBaseStructOrUnion): + raise TypeError("expected a struct or union ctype") + BField = BType._bfield_types[fieldname] + if BField is Ellipsis: + raise TypeError("not supported for bitfields") + return (BField, BType._offsetof(fieldname)) + elif isinstance(fieldname, (int, long)): + if issubclass(BType, CTypesGenericArray): + BType = BType._CTPtr + if not issubclass(BType, CTypesGenericPtr): + raise TypeError("expected an array or ptr ctype") + BItem = BType._BItem + offset = BItem._get_size() * fieldname + if offset > sys.maxsize: + raise OverflowError + return (BItem, offset) + else: + raise TypeError(type(fieldname)) + + def rawaddressof(self, BTypePtr, cdata, offset=None): + if isinstance(cdata, CTypesBaseStructOrUnion): + ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata)) + elif isinstance(cdata, CTypesGenericPtr): + if offset is None or not issubclass(type(cdata)._BItem, + CTypesBaseStructOrUnion): + raise TypeError("unexpected cdata type") + ptr = type(cdata)._to_ctypes(cdata) + elif isinstance(cdata, CTypesGenericArray): + ptr = type(cdata)._to_ctypes(cdata) + else: + raise TypeError("expected a ") + if offset: + ptr = ctypes.cast( + ctypes.c_void_p( + ctypes.cast(ptr, ctypes.c_void_p).value + offset), + type(ptr)) + return BTypePtr._from_ctypes(ptr) + + +class CTypesLibrary(object): + + def __init__(self, backend, cdll): + self.backend = backend + self.cdll = cdll + + def load_function(self, BType, name): + c_func = getattr(self.cdll, name) + funcobj = BType._from_ctypes(c_func) + funcobj._name = name + return funcobj + + def read_variable(self, BType, name): + try: + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + except AttributeError as e: + raise NotImplementedError(e) + return BType._from_ctypes(ctypes_obj) + + def write_variable(self, BType, name, value): + new_ctypes_obj = BType._to_ctypes(value) + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + ctypes.memmove(ctypes.addressof(ctypes_obj), + ctypes.addressof(new_ctypes_obj), + ctypes.sizeof(BType._ctype)) diff --git a/uno/lib/python/cffi/cffi_opcode.py b/uno/lib/python/cffi/cffi_opcode.py new file mode 100644 index 00000000..b26ccc96 --- /dev/null +++ b/uno/lib/python/cffi/cffi_opcode.py @@ -0,0 +1,187 @@ +from .error import VerificationError + +class CffiOp(object): + def __init__(self, op, arg): + self.op = op + self.arg = arg + + def as_c_expr(self): + if self.op is None: + assert isinstance(self.arg, str) + return '(_cffi_opcode_t)(%s)' % (self.arg,) + classname = CLASS_NAME[self.op] + return '_CFFI_OP(_CFFI_OP_%s, %s)' % (classname, self.arg) + + def as_python_bytes(self): + if self.op is None and self.arg.isdigit(): + value = int(self.arg) # non-negative: '-' not in self.arg + if value >= 2**31: + raise OverflowError("cannot emit %r: limited to 2**31-1" + % (self.arg,)) + return format_four_bytes(value) + if isinstance(self.arg, str): + raise VerificationError("cannot emit to Python: %r" % (self.arg,)) + return format_four_bytes((self.arg << 8) | self.op) + + def __str__(self): + classname = CLASS_NAME.get(self.op, self.op) + return '(%s %s)' % (classname, self.arg) + +def format_four_bytes(num): + return '\\x%02X\\x%02X\\x%02X\\x%02X' % ( + (num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF) + +OP_PRIMITIVE = 1 +OP_POINTER = 3 +OP_ARRAY = 5 +OP_OPEN_ARRAY = 7 +OP_STRUCT_UNION = 9 +OP_ENUM = 11 +OP_FUNCTION = 13 +OP_FUNCTION_END = 15 +OP_NOOP = 17 +OP_BITFIELD = 19 +OP_TYPENAME = 21 +OP_CPYTHON_BLTN_V = 23 # varargs +OP_CPYTHON_BLTN_N = 25 # noargs +OP_CPYTHON_BLTN_O = 27 # O (i.e. a single arg) +OP_CONSTANT = 29 +OP_CONSTANT_INT = 31 +OP_GLOBAL_VAR = 33 +OP_DLOPEN_FUNC = 35 +OP_DLOPEN_CONST = 37 +OP_GLOBAL_VAR_F = 39 +OP_EXTERN_PYTHON = 41 + +PRIM_VOID = 0 +PRIM_BOOL = 1 +PRIM_CHAR = 2 +PRIM_SCHAR = 3 +PRIM_UCHAR = 4 +PRIM_SHORT = 5 +PRIM_USHORT = 6 +PRIM_INT = 7 +PRIM_UINT = 8 +PRIM_LONG = 9 +PRIM_ULONG = 10 +PRIM_LONGLONG = 11 +PRIM_ULONGLONG = 12 +PRIM_FLOAT = 13 +PRIM_DOUBLE = 14 +PRIM_LONGDOUBLE = 15 + +PRIM_WCHAR = 16 +PRIM_INT8 = 17 +PRIM_UINT8 = 18 +PRIM_INT16 = 19 +PRIM_UINT16 = 20 +PRIM_INT32 = 21 +PRIM_UINT32 = 22 +PRIM_INT64 = 23 +PRIM_UINT64 = 24 +PRIM_INTPTR = 25 +PRIM_UINTPTR = 26 +PRIM_PTRDIFF = 27 +PRIM_SIZE = 28 +PRIM_SSIZE = 29 +PRIM_INT_LEAST8 = 30 +PRIM_UINT_LEAST8 = 31 +PRIM_INT_LEAST16 = 32 +PRIM_UINT_LEAST16 = 33 +PRIM_INT_LEAST32 = 34 +PRIM_UINT_LEAST32 = 35 +PRIM_INT_LEAST64 = 36 +PRIM_UINT_LEAST64 = 37 +PRIM_INT_FAST8 = 38 +PRIM_UINT_FAST8 = 39 +PRIM_INT_FAST16 = 40 +PRIM_UINT_FAST16 = 41 +PRIM_INT_FAST32 = 42 +PRIM_UINT_FAST32 = 43 +PRIM_INT_FAST64 = 44 +PRIM_UINT_FAST64 = 45 +PRIM_INTMAX = 46 +PRIM_UINTMAX = 47 +PRIM_FLOATCOMPLEX = 48 +PRIM_DOUBLECOMPLEX = 49 +PRIM_CHAR16 = 50 +PRIM_CHAR32 = 51 + +_NUM_PRIM = 52 +_UNKNOWN_PRIM = -1 +_UNKNOWN_FLOAT_PRIM = -2 +_UNKNOWN_LONG_DOUBLE = -3 + +_IO_FILE_STRUCT = -1 + +PRIMITIVE_TO_INDEX = { + 'char': PRIM_CHAR, + 'short': PRIM_SHORT, + 'int': PRIM_INT, + 'long': PRIM_LONG, + 'long long': PRIM_LONGLONG, + 'signed char': PRIM_SCHAR, + 'unsigned char': PRIM_UCHAR, + 'unsigned short': PRIM_USHORT, + 'unsigned int': PRIM_UINT, + 'unsigned long': PRIM_ULONG, + 'unsigned long long': PRIM_ULONGLONG, + 'float': PRIM_FLOAT, + 'double': PRIM_DOUBLE, + 'long double': PRIM_LONGDOUBLE, + 'float _Complex': PRIM_FLOATCOMPLEX, + 'double _Complex': PRIM_DOUBLECOMPLEX, + '_Bool': PRIM_BOOL, + 'wchar_t': PRIM_WCHAR, + 'char16_t': PRIM_CHAR16, + 'char32_t': PRIM_CHAR32, + 'int8_t': PRIM_INT8, + 'uint8_t': PRIM_UINT8, + 'int16_t': PRIM_INT16, + 'uint16_t': PRIM_UINT16, + 'int32_t': PRIM_INT32, + 'uint32_t': PRIM_UINT32, + 'int64_t': PRIM_INT64, + 'uint64_t': PRIM_UINT64, + 'intptr_t': PRIM_INTPTR, + 'uintptr_t': PRIM_UINTPTR, + 'ptrdiff_t': PRIM_PTRDIFF, + 'size_t': PRIM_SIZE, + 'ssize_t': PRIM_SSIZE, + 'int_least8_t': PRIM_INT_LEAST8, + 'uint_least8_t': PRIM_UINT_LEAST8, + 'int_least16_t': PRIM_INT_LEAST16, + 'uint_least16_t': PRIM_UINT_LEAST16, + 'int_least32_t': PRIM_INT_LEAST32, + 'uint_least32_t': PRIM_UINT_LEAST32, + 'int_least64_t': PRIM_INT_LEAST64, + 'uint_least64_t': PRIM_UINT_LEAST64, + 'int_fast8_t': PRIM_INT_FAST8, + 'uint_fast8_t': PRIM_UINT_FAST8, + 'int_fast16_t': PRIM_INT_FAST16, + 'uint_fast16_t': PRIM_UINT_FAST16, + 'int_fast32_t': PRIM_INT_FAST32, + 'uint_fast32_t': PRIM_UINT_FAST32, + 'int_fast64_t': PRIM_INT_FAST64, + 'uint_fast64_t': PRIM_UINT_FAST64, + 'intmax_t': PRIM_INTMAX, + 'uintmax_t': PRIM_UINTMAX, + } + +F_UNION = 0x01 +F_CHECK_FIELDS = 0x02 +F_PACKED = 0x04 +F_EXTERNAL = 0x08 +F_OPAQUE = 0x10 + +G_FLAGS = dict([('_CFFI_' + _key, globals()[_key]) + for _key in ['F_UNION', 'F_CHECK_FIELDS', 'F_PACKED', + 'F_EXTERNAL', 'F_OPAQUE']]) + +CLASS_NAME = {} +for _name, _value in list(globals().items()): + if _name.startswith('OP_') and isinstance(_value, int): + CLASS_NAME[_value] = _name[3:] diff --git a/uno/lib/python/cffi/commontypes.py b/uno/lib/python/cffi/commontypes.py new file mode 100644 index 00000000..e5045ee2 --- /dev/null +++ b/uno/lib/python/cffi/commontypes.py @@ -0,0 +1,80 @@ +import sys +from . import model +from .error import FFIError + + +COMMON_TYPES = {} + +try: + # fetch "bool" and all simple Windows types + from _cffi_backend import _get_common_types + _get_common_types(COMMON_TYPES) +except ImportError: + pass + +COMMON_TYPES['FILE'] = model.unknown_type('FILE', '_IO_FILE') +COMMON_TYPES['bool'] = '_Bool' # in case we got ImportError above + +for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + if _type.endswith('_t'): + COMMON_TYPES[_type] = _type +del _type + +_CACHE = {} + +def resolve_common_type(parser, commontype): + try: + return _CACHE[commontype] + except KeyError: + cdecl = COMMON_TYPES.get(commontype, commontype) + if not isinstance(cdecl, str): + result, quals = cdecl, 0 # cdecl is already a BaseType + elif cdecl in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + result, quals = model.PrimitiveType(cdecl), 0 + elif cdecl == 'set-unicode-needed': + raise FFIError("The Windows type %r is only available after " + "you call ffi.set_unicode()" % (commontype,)) + else: + if commontype == cdecl: + raise FFIError( + "Unsupported type: %r. Please look at " + "http://cffi.readthedocs.io/en/latest/cdef.html#ffi-cdef-limitations " + "and file an issue if you think this type should really " + "be supported." % (commontype,)) + result, quals = parser.parse_type_and_quals(cdecl) # recursive + + assert isinstance(result, model.BaseTypeByIdentity) + _CACHE[commontype] = result, quals + return result, quals + + +# ____________________________________________________________ +# extra types for Windows (most of them are in commontypes.c) + + +def win_common_types(): + return { + "UNICODE_STRING": model.StructType( + "_UNICODE_STRING", + ["Length", + "MaximumLength", + "Buffer"], + [model.PrimitiveType("unsigned short"), + model.PrimitiveType("unsigned short"), + model.PointerType(model.PrimitiveType("wchar_t"))], + [-1, -1, -1]), + "PUNICODE_STRING": "UNICODE_STRING *", + "PCUNICODE_STRING": "const UNICODE_STRING *", + + "TBYTE": "set-unicode-needed", + "TCHAR": "set-unicode-needed", + "LPCTSTR": "set-unicode-needed", + "PCTSTR": "set-unicode-needed", + "LPTSTR": "set-unicode-needed", + "PTSTR": "set-unicode-needed", + "PTBYTE": "set-unicode-needed", + "PTCHAR": "set-unicode-needed", + } + +if sys.platform == 'win32': + COMMON_TYPES.update(win_common_types()) diff --git a/uno/lib/python/cffi/cparser.py b/uno/lib/python/cffi/cparser.py new file mode 100644 index 00000000..c4acd23a --- /dev/null +++ b/uno/lib/python/cffi/cparser.py @@ -0,0 +1,1006 @@ +from . import model +from .commontypes import COMMON_TYPES, resolve_common_type +from .error import FFIError, CDefError +try: + from . import _pycparser as pycparser +except ImportError: + import pycparser +import weakref, re, sys + +try: + if sys.version_info < (3,): + import thread as _thread + else: + import _thread + lock = _thread.allocate_lock() +except ImportError: + lock = None + +def _workaround_for_static_import_finders(): + # Issue #392: packaging tools like cx_Freeze can not find these + # because pycparser uses exec dynamic import. This is an obscure + # workaround. This function is never called. + import pycparser.yacctab + import pycparser.lextab + +CDEF_SOURCE_STRING = "" +_r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", + re.DOTALL | re.MULTILINE) +_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" + r"\b((?:[^\n\\]|\\.)*?)$", + re.DOTALL | re.MULTILINE) +_r_line_directive = re.compile(r"^[ \t]*#[ \t]*(?:line|\d+)\b.*$", re.MULTILINE) +_r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") +_r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") +_r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") +_r_words = re.compile(r"\w+|\S") +_parser_cache = None +_r_int_literal = re.compile(r"-?0?x?[0-9a-f]+[lu]*$", re.IGNORECASE) +_r_stdcall1 = re.compile(r"\b(__stdcall|WINAPI)\b") +_r_stdcall2 = re.compile(r"[(]\s*(__stdcall|WINAPI)\b") +_r_cdecl = re.compile(r"\b__cdecl\b") +_r_extern_python = re.compile(r'\bextern\s*"' + r'(Python|Python\s*\+\s*C|C\s*\+\s*Python)"\s*.') +_r_star_const_space = re.compile( # matches "* const " + r"[*]\s*((const|volatile|restrict)\b\s*)+") +_r_int_dotdotdot = re.compile(r"(\b(int|long|short|signed|unsigned|char)\s*)+" + r"\.\.\.") +_r_float_dotdotdot = re.compile(r"\b(double|float)\s*\.\.\.") + +def _get_parser(): + global _parser_cache + if _parser_cache is None: + _parser_cache = pycparser.CParser() + return _parser_cache + +def _workaround_for_old_pycparser(csource): + # Workaround for a pycparser issue (fixed between pycparser 2.10 and + # 2.14): "char*const***" gives us a wrong syntax tree, the same as + # for "char***(*const)". This means we can't tell the difference + # afterwards. But "char(*const(***))" gives us the right syntax + # tree. The issue only occurs if there are several stars in + # sequence with no parenthesis inbetween, just possibly qualifiers. + # Attempt to fix it by adding some parentheses in the source: each + # time we see "* const" or "* const *", we add an opening + # parenthesis before each star---the hard part is figuring out where + # to close them. + parts = [] + while True: + match = _r_star_const_space.search(csource) + if not match: + break + #print repr(''.join(parts)+csource), '=>', + parts.append(csource[:match.start()]) + parts.append('('); closing = ')' + parts.append(match.group()) # e.g. "* const " + endpos = match.end() + if csource.startswith('*', endpos): + parts.append('('); closing += ')' + level = 0 + i = endpos + while i < len(csource): + c = csource[i] + if c == '(': + level += 1 + elif c == ')': + if level == 0: + break + level -= 1 + elif c in ',;=': + if level == 0: + break + i += 1 + csource = csource[endpos:i] + closing + csource[i:] + #print repr(''.join(parts)+csource) + parts.append(csource) + return ''.join(parts) + +def _preprocess_extern_python(csource): + # input: `extern "Python" int foo(int);` or + # `extern "Python" { int foo(int); }` + # output: + # void __cffi_extern_python_start; + # int foo(int); + # void __cffi_extern_python_stop; + # + # input: `extern "Python+C" int foo(int);` + # output: + # void __cffi_extern_python_plus_c_start; + # int foo(int); + # void __cffi_extern_python_stop; + parts = [] + while True: + match = _r_extern_python.search(csource) + if not match: + break + endpos = match.end() - 1 + #print + #print ''.join(parts)+csource + #print '=>' + parts.append(csource[:match.start()]) + if 'C' in match.group(1): + parts.append('void __cffi_extern_python_plus_c_start; ') + else: + parts.append('void __cffi_extern_python_start; ') + if csource[endpos] == '{': + # grouping variant + closing = csource.find('}', endpos) + if closing < 0: + raise CDefError("'extern \"Python\" {': no '}' found") + if csource.find('{', endpos + 1, closing) >= 0: + raise NotImplementedError("cannot use { } inside a block " + "'extern \"Python\" { ... }'") + parts.append(csource[endpos+1:closing]) + csource = csource[closing+1:] + else: + # non-grouping variant + semicolon = csource.find(';', endpos) + if semicolon < 0: + raise CDefError("'extern \"Python\": no ';' found") + parts.append(csource[endpos:semicolon+1]) + csource = csource[semicolon+1:] + parts.append(' void __cffi_extern_python_stop;') + #print ''.join(parts)+csource + #print + parts.append(csource) + return ''.join(parts) + +def _warn_for_string_literal(csource): + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break + +def _warn_for_non_extern_non_static_global_variable(decl): + if not decl.storage: + import warnings + warnings.warn("Global variable '%s' in cdef(): for consistency " + "with C it should have a storage class specifier " + "(usually 'extern')" % (decl.name,)) + +def _remove_line_directives(csource): + # _r_line_directive matches whole lines, without the final \n, if they + # start with '#line' with some spacing allowed, or '#NUMBER'. This + # function stores them away and replaces them with exactly the string + # '#line@N', where N is the index in the list 'line_directives'. + line_directives = [] + def replace(m): + i = len(line_directives) + line_directives.append(m.group()) + return '#line@%d' % i + csource = _r_line_directive.sub(replace, csource) + return csource, line_directives + +def _put_back_line_directives(csource, line_directives): + def replace(m): + s = m.group() + if not s.startswith('#line@'): + raise AssertionError("unexpected #line directive " + "(should have been processed and removed") + return line_directives[int(s[6:])] + return _r_line_directive.sub(replace, csource) + +def _preprocess(csource): + # First, remove the lines of the form '#line N "filename"' because + # the "filename" part could confuse the rest + csource, line_directives = _remove_line_directives(csource) + # Remove comments. NOTE: this only work because the cdef() section + # should not contain any string literals (except in line directives)! + def replace_keeping_newlines(m): + return ' ' + m.group().count('\n') * '\n' + csource = _r_comment.sub(replace_keeping_newlines, csource) + # Remove the "#define FOO x" lines + macros = {} + for match in _r_define.finditer(csource): + macroname, macrovalue = match.groups() + macrovalue = macrovalue.replace('\\\n', '').strip() + macros[macroname] = macrovalue + csource = _r_define.sub('', csource) + # + if pycparser.__version__ < '2.14': + csource = _workaround_for_old_pycparser(csource) + # + # BIG HACK: replace WINAPI or __stdcall with "volatile const". + # It doesn't make sense for the return type of a function to be + # "volatile volatile const", so we abuse it to detect __stdcall... + # Hack number 2 is that "int(volatile *fptr)();" is not valid C + # syntax, so we place the "volatile" before the opening parenthesis. + csource = _r_stdcall2.sub(' volatile volatile const(', csource) + csource = _r_stdcall1.sub(' volatile volatile const ', csource) + csource = _r_cdecl.sub(' ', csource) + # + # Replace `extern "Python"` with start/end markers + csource = _preprocess_extern_python(csource) + # + # Now there should not be any string literal left; warn if we get one + _warn_for_string_literal(csource) + # + # Replace "[...]" with "[__dotdotdotarray__]" + csource = _r_partial_array.sub('[__dotdotdotarray__]', csource) + # + # Replace "...}" with "__dotdotdotNUM__}". This construction should + # occur only at the end of enums; at the end of structs we have "...;}" + # and at the end of vararg functions "...);". Also replace "=...[,}]" + # with ",__dotdotdotNUM__[,}]": this occurs in the enums too, when + # giving an unknown value. + matches = list(_r_partial_enum.finditer(csource)) + for number, match in enumerate(reversed(matches)): + p = match.start() + if csource[p] == '=': + p2 = csource.find('...', p, match.end()) + assert p2 > p + csource = '%s,__dotdotdot%d__ %s' % (csource[:p], number, + csource[p2+3:]) + else: + assert csource[p:p+3] == '...' + csource = '%s __dotdotdot%d__ %s' % (csource[:p], number, + csource[p+3:]) + # Replace "int ..." or "unsigned long int..." with "__dotdotdotint__" + csource = _r_int_dotdotdot.sub(' __dotdotdotint__ ', csource) + # Replace "float ..." or "double..." with "__dotdotdotfloat__" + csource = _r_float_dotdotdot.sub(' __dotdotdotfloat__ ', csource) + # Replace all remaining "..." with the same name, "__dotdotdot__", + # which is declared with a typedef for the purpose of C parsing. + csource = csource.replace('...', ' __dotdotdot__ ') + # Finally, put back the line directives + csource = _put_back_line_directives(csource, line_directives) + return csource, macros + +def _common_type_names(csource): + # Look in the source for what looks like usages of types from the + # list of common types. A "usage" is approximated here as the + # appearance of the word, minus a "definition" of the type, which + # is the last word in a "typedef" statement. Approximative only + # but should be fine for all the common types. + look_for_words = set(COMMON_TYPES) + look_for_words.add(';') + look_for_words.add(',') + look_for_words.add('(') + look_for_words.add(')') + look_for_words.add('typedef') + words_used = set() + is_typedef = False + paren = 0 + previous_word = '' + for word in _r_words.findall(csource): + if word in look_for_words: + if word == ';': + if is_typedef: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + is_typedef = False + elif word == 'typedef': + is_typedef = True + paren = 0 + elif word == '(': + paren += 1 + elif word == ')': + paren -= 1 + elif word == ',': + if is_typedef and paren == 0: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + else: # word in COMMON_TYPES + words_used.add(word) + previous_word = word + return words_used + + +class Parser(object): + + def __init__(self): + self._declarations = {} + self._included_declarations = set() + self._anonymous_counter = 0 + self._structnode2type = weakref.WeakKeyDictionary() + self._options = {} + self._int_constants = {} + self._recomplete = [] + self._uses_new_feature = None + + def _parse(self, csource): + csource, macros = _preprocess(csource) + # XXX: for more efficiency we would need to poke into the + # internals of CParser... the following registers the + # typedefs, because their presence or absence influences the + # parsing itself (but what they are typedef'ed to plays no role) + ctn = _common_type_names(csource) + typenames = [] + for name in sorted(self._declarations): + if name.startswith('typedef '): + name = name[8:] + typenames.append(name) + ctn.discard(name) + typenames += sorted(ctn) + # + csourcelines = [] + csourcelines.append('# 1 ""') + for typename in typenames: + csourcelines.append('typedef int %s;' % typename) + csourcelines.append('typedef int __dotdotdotint__, __dotdotdotfloat__,' + ' __dotdotdot__;') + # this forces pycparser to consider the following in the file + # called from line 1 + csourcelines.append('# 1 "%s"' % (CDEF_SOURCE_STRING,)) + csourcelines.append(csource) + fullcsource = '\n'.join(csourcelines) + if lock is not None: + lock.acquire() # pycparser is not thread-safe... + try: + ast = _get_parser().parse(fullcsource) + except pycparser.c_parser.ParseError as e: + self.convert_pycparser_error(e, csource) + finally: + if lock is not None: + lock.release() + # csource will be used to find buggy source text + return ast, macros, csource + + def _convert_pycparser_error(self, e, csource): + # xxx look for ":NUM:" at the start of str(e) + # and interpret that as a line number. This will not work if + # the user gives explicit ``# NUM "FILE"`` directives. + line = None + msg = str(e) + match = re.match(r"%s:(\d+):" % (CDEF_SOURCE_STRING,), msg) + if match: + linenum = int(match.group(1), 10) + csourcelines = csource.splitlines() + if 1 <= linenum <= len(csourcelines): + line = csourcelines[linenum-1] + return line + + def convert_pycparser_error(self, e, csource): + line = self._convert_pycparser_error(e, csource) + + msg = str(e) + if line: + msg = 'cannot parse "%s"\n%s' % (line.strip(), msg) + else: + msg = 'parse error\n%s' % (msg,) + raise CDefError(msg) + + def parse(self, csource, override=False, packed=False, pack=None, + dllexport=False): + if packed: + if packed != True: + raise ValueError("'packed' should be False or True; use " + "'pack' to give another value") + if pack: + raise ValueError("cannot give both 'pack' and 'packed'") + pack = 1 + elif pack: + if pack & (pack - 1): + raise ValueError("'pack' must be a power of two, not %r" % + (pack,)) + else: + pack = 0 + prev_options = self._options + try: + self._options = {'override': override, + 'packed': pack, + 'dllexport': dllexport} + self._internal_parse(csource) + finally: + self._options = prev_options + + def _internal_parse(self, csource): + ast, macros, csource = self._parse(csource) + # add the macros + self._process_macros(macros) + # find the first "__dotdotdot__" and use that as a separator + # between the repeated typedefs and the real csource + iterator = iter(ast.ext) + for decl in iterator: + if decl.name == '__dotdotdot__': + break + else: + assert 0 + current_decl = None + # + try: + self._inside_extern_python = '__cffi_extern_python_stop' + for decl in iterator: + current_decl = decl + if isinstance(decl, pycparser.c_ast.Decl): + self._parse_decl(decl) + elif isinstance(decl, pycparser.c_ast.Typedef): + if not decl.name: + raise CDefError("typedef does not declare any name", + decl) + quals = 0 + if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType) and + decl.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_type(decl) + elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and + isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and + isinstance(decl.type.type.type, + pycparser.c_ast.IdentifierType) and + decl.type.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_ptr_type(decl) + else: + realtype, quals = self._get_type_and_quals( + decl.type, name=decl.name, partial_length_ok=True, + typedef_example="*(%s *)0" % (decl.name,)) + self._declare('typedef ' + decl.name, realtype, quals=quals) + elif decl.__class__.__name__ == 'Pragma': + pass # skip pragma, only in pycparser 2.15 + else: + raise CDefError("unexpected <%s>: this construct is valid " + "C but not valid in cdef()" % + decl.__class__.__name__, decl) + except CDefError as e: + if len(e.args) == 1: + e.args = e.args + (current_decl,) + raise + except FFIError as e: + msg = self._convert_pycparser_error(e, csource) + if msg: + e.args = (e.args[0] + "\n *** Err: %s" % msg,) + raise + + def _add_constants(self, key, val): + if key in self._int_constants: + if self._int_constants[key] == val: + return # ignore identical double declarations + raise FFIError( + "multiple declarations of constant: %s" % (key,)) + self._int_constants[key] = val + + def _add_integer_constant(self, name, int_str): + int_str = int_str.lower().rstrip("ul") + neg = int_str.startswith('-') + if neg: + int_str = int_str[1:] + # "010" is not valid oct in py3 + if (int_str.startswith("0") and int_str != '0' + and not int_str.startswith("0x")): + int_str = "0o" + int_str[1:] + pyvalue = int(int_str, 0) + if neg: + pyvalue = -pyvalue + self._add_constants(name, pyvalue) + self._declare('macro ' + name, pyvalue) + + def _process_macros(self, macros): + for key, value in macros.items(): + value = value.strip() + if _r_int_literal.match(value): + self._add_integer_constant(key, value) + elif value == '...': + self._declare('macro ' + key, value) + else: + raise CDefError( + 'only supports one of the following syntax:\n' + ' #define %s ... (literally dot-dot-dot)\n' + ' #define %s NUMBER (with NUMBER an integer' + ' constant, decimal/hex/octal)\n' + 'got:\n' + ' #define %s %s' + % (key, key, key, value)) + + def _declare_function(self, tp, quals, decl): + tp = self._get_type_pointer(tp, quals) + if self._options.get('dllexport'): + tag = 'dllexport_python ' + elif self._inside_extern_python == '__cffi_extern_python_start': + tag = 'extern_python ' + elif self._inside_extern_python == '__cffi_extern_python_plus_c_start': + tag = 'extern_python_plus_c ' + else: + tag = 'function ' + self._declare(tag + decl.name, tp) + + def _parse_decl(self, decl): + node = decl.type + if isinstance(node, pycparser.c_ast.FuncDecl): + tp, quals = self._get_type_and_quals(node, name=decl.name) + assert isinstance(tp, model.RawFunctionType) + self._declare_function(tp, quals, decl) + else: + if isinstance(node, pycparser.c_ast.Struct): + self._get_struct_union_enum_type('struct', node) + elif isinstance(node, pycparser.c_ast.Union): + self._get_struct_union_enum_type('union', node) + elif isinstance(node, pycparser.c_ast.Enum): + self._get_struct_union_enum_type('enum', node) + elif not decl.name: + raise CDefError("construct does not declare any variable", + decl) + # + if decl.name: + tp, quals = self._get_type_and_quals(node, + partial_length_ok=True) + if tp.is_raw_function: + self._declare_function(tp, quals, decl) + elif (tp.is_integer_type() and + hasattr(decl, 'init') and + hasattr(decl.init, 'value') and + _r_int_literal.match(decl.init.value)): + self._add_integer_constant(decl.name, decl.init.value) + elif (tp.is_integer_type() and + isinstance(decl.init, pycparser.c_ast.UnaryOp) and + decl.init.op == '-' and + hasattr(decl.init.expr, 'value') and + _r_int_literal.match(decl.init.expr.value)): + self._add_integer_constant(decl.name, + '-' + decl.init.expr.value) + elif (tp is model.void_type and + decl.name.startswith('__cffi_extern_python_')): + # hack: `extern "Python"` in the C source is replaced + # with "void __cffi_extern_python_start;" and + # "void __cffi_extern_python_stop;" + self._inside_extern_python = decl.name + else: + if self._inside_extern_python !='__cffi_extern_python_stop': + raise CDefError( + "cannot declare constants or " + "variables with 'extern \"Python\"'") + if (quals & model.Q_CONST) and not tp.is_array_type: + self._declare('constant ' + decl.name, tp, quals=quals) + else: + _warn_for_non_extern_non_static_global_variable(decl) + self._declare('variable ' + decl.name, tp, quals=quals) + + def parse_type(self, cdecl): + return self.parse_type_and_quals(cdecl)[0] + + def parse_type_and_quals(self, cdecl): + ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2] + assert not macros + exprnode = ast.ext[-1].type.args.params[0] + if isinstance(exprnode, pycparser.c_ast.ID): + raise CDefError("unknown identifier '%s'" % (exprnode.name,)) + return self._get_type_and_quals(exprnode.type) + + def _declare(self, name, obj, included=False, quals=0): + if name in self._declarations: + prevobj, prevquals = self._declarations[name] + if prevobj is obj and prevquals == quals: + return + if not self._options.get('override'): + raise FFIError( + "multiple declarations of %s (for interactive usage, " + "try cdef(xx, override=True))" % (name,)) + assert '__dotdotdot__' not in name.split() + self._declarations[name] = (obj, quals) + if included: + self._included_declarations.add(obj) + + def _extract_quals(self, type): + quals = 0 + if isinstance(type, (pycparser.c_ast.TypeDecl, + pycparser.c_ast.PtrDecl)): + if 'const' in type.quals: + quals |= model.Q_CONST + if 'volatile' in type.quals: + quals |= model.Q_VOLATILE + if 'restrict' in type.quals: + quals |= model.Q_RESTRICT + return quals + + def _get_type_pointer(self, type, quals, declname=None): + if isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + if (isinstance(type, model.StructOrUnionOrEnum) and + type.name.startswith('$') and type.name[1:].isdigit() and + type.forcename is None and declname is not None): + return model.NamedPointerType(type, declname, quals) + return model.PointerType(type, quals) + + def _get_type_and_quals(self, typenode, name=None, partial_length_ok=False, + typedef_example=None): + # first, dereference typedefs, if we have it already parsed, we're good + if (isinstance(typenode, pycparser.c_ast.TypeDecl) and + isinstance(typenode.type, pycparser.c_ast.IdentifierType) and + len(typenode.type.names) == 1 and + ('typedef ' + typenode.type.names[0]) in self._declarations): + tp, quals = self._declarations['typedef ' + typenode.type.names[0]] + quals |= self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.ArrayDecl): + # array type + if typenode.dim is None: + length = None + else: + length = self._parse_constant( + typenode.dim, partial_length_ok=partial_length_ok) + # a hack: in 'typedef int foo_t[...][...];', don't use '...' as + # the length but use directly the C expression that would be + # generated by recompiler.py. This lets the typedef be used in + # many more places within recompiler.py + if typedef_example is not None: + if length == '...': + length = '_cffi_array_len(%s)' % (typedef_example,) + typedef_example = "*" + typedef_example + # + tp, quals = self._get_type_and_quals(typenode.type, + partial_length_ok=partial_length_ok, + typedef_example=typedef_example) + return model.ArrayType(tp, length), quals + # + if isinstance(typenode, pycparser.c_ast.PtrDecl): + # pointer type + itemtype, itemquals = self._get_type_and_quals(typenode.type) + tp = self._get_type_pointer(itemtype, itemquals, declname=name) + quals = self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.TypeDecl): + quals = self._extract_quals(typenode) + type = typenode.type + if isinstance(type, pycparser.c_ast.IdentifierType): + # assume a primitive type. get it from .names, but reduce + # synonyms to a single chosen combination + names = list(type.names) + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names + ident = ' '.join(names) + if ident == 'void': + return model.void_type, quals + if ident == '__dotdotdot__': + raise FFIError(':%d: bad usage of "..."' % + typenode.coord.line) + tp0, quals0 = resolve_common_type(self, ident) + return tp0, (quals | quals0) + # + if isinstance(type, pycparser.c_ast.Struct): + # 'struct foobar' + tp = self._get_struct_union_enum_type('struct', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Union): + # 'union foobar' + tp = self._get_struct_union_enum_type('union', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Enum): + # 'enum foobar' + tp = self._get_struct_union_enum_type('enum', type, name) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.FuncDecl): + # a function type + return self._parse_function_type(typenode, name), 0 + # + # nested anonymous structs or unions end up here + if isinstance(typenode, pycparser.c_ast.Struct): + return self._get_struct_union_enum_type('struct', typenode, name, + nested=True), 0 + if isinstance(typenode, pycparser.c_ast.Union): + return self._get_struct_union_enum_type('union', typenode, name, + nested=True), 0 + # + raise FFIError(":%d: bad or unsupported type declaration" % + typenode.coord.line) + + def _parse_function_type(self, typenode, funcname=None): + params = list(getattr(typenode.args, 'params', [])) + for i, arg in enumerate(params): + if not hasattr(arg, 'type'): + raise CDefError("%s arg %d: unknown type '%s'" + " (if you meant to use the old C syntax of giving" + " untyped arguments, it is not supported)" + % (funcname or 'in expression', i + 1, + getattr(arg, 'name', '?'))) + ellipsis = ( + len(params) > 0 and + isinstance(params[-1].type, pycparser.c_ast.TypeDecl) and + isinstance(params[-1].type.type, + pycparser.c_ast.IdentifierType) and + params[-1].type.type.names == ['__dotdotdot__']) + if ellipsis: + params.pop() + if not params: + raise CDefError( + "%s: a function with only '(...)' as argument" + " is not correct C" % (funcname or 'in expression')) + args = [self._as_func_arg(*self._get_type_and_quals(argdeclnode.type)) + for argdeclnode in params] + if not ellipsis and args == [model.void_type]: + args = [] + result, quals = self._get_type_and_quals(typenode.type) + # the 'quals' on the result type are ignored. HACK: we absure them + # to detect __stdcall functions: we textually replace "__stdcall" + # with "volatile volatile const" above. + abi = None + if hasattr(typenode.type, 'quals'): # else, probable syntax error anyway + if typenode.type.quals[-3:] == ['volatile', 'volatile', 'const']: + abi = '__stdcall' + return model.RawFunctionType(tuple(args), result, ellipsis, abi) + + def _as_func_arg(self, type, quals): + if isinstance(type, model.ArrayType): + return model.PointerType(type.item, quals) + elif isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + else: + return type + + def _get_struct_union_enum_type(self, kind, type, name=None, nested=False): + # First, a level of caching on the exact 'type' node of the AST. + # This is obscure, but needed because pycparser "unrolls" declarations + # such as "typedef struct { } foo_t, *foo_p" and we end up with + # an AST that is not a tree, but a DAG, with the "type" node of the + # two branches foo_t and foo_p of the trees being the same node. + # It's a bit silly but detecting "DAG-ness" in the AST tree seems + # to be the only way to distinguish this case from two independent + # structs. See test_struct_with_two_usages. + try: + return self._structnode2type[type] + except KeyError: + pass + # + # Note that this must handle parsing "struct foo" any number of + # times and always return the same StructType object. Additionally, + # one of these times (not necessarily the first), the fields of + # the struct can be specified with "struct foo { ...fields... }". + # If no name is given, then we have to create a new anonymous struct + # with no caching; in this case, the fields are either specified + # right now or never. + # + force_name = name + name = type.name + # + # get the type or create it if needed + if name is None: + # 'force_name' is used to guess a more readable name for + # anonymous structs, for the common case "typedef struct { } foo". + if force_name is not None: + explicit_name = '$%s' % force_name + else: + self._anonymous_counter += 1 + explicit_name = '$%d' % self._anonymous_counter + tp = None + else: + explicit_name = name + key = '%s %s' % (kind, name) + tp, _ = self._declarations.get(key, (None, None)) + # + if tp is None: + if kind == 'struct': + tp = model.StructType(explicit_name, None, None, None) + elif kind == 'union': + tp = model.UnionType(explicit_name, None, None, None) + elif kind == 'enum': + if explicit_name == '__dotdotdot__': + raise CDefError("Enums cannot be declared with ...") + tp = self._build_enum_type(explicit_name, type.values) + else: + raise AssertionError("kind = %r" % (kind,)) + if name is not None: + self._declare(key, tp) + else: + if kind == 'enum' and type.values is not None: + raise NotImplementedError( + "enum %s: the '{}' declaration should appear on the first " + "time the enum is mentioned, not later" % explicit_name) + if not tp.forcename: + tp.force_the_name(force_name) + if tp.forcename and '$' in tp.name: + self._declare('anonymous %s' % tp.forcename, tp) + # + self._structnode2type[type] = tp + # + # enums: done here + if kind == 'enum': + return tp + # + # is there a 'type.decls'? If yes, then this is the place in the + # C sources that declare the fields. If no, then just return the + # existing type, possibly still incomplete. + if type.decls is None: + return tp + # + if tp.fldnames is not None: + raise CDefError("duplicate declaration of struct %s" % name) + fldnames = [] + fldtypes = [] + fldbitsize = [] + fldquals = [] + for decl in type.decls: + if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and + ''.join(decl.type.names) == '__dotdotdot__'): + # XXX pycparser is inconsistent: 'names' should be a list + # of strings, but is sometimes just one string. Use + # str.join() as a way to cope with both. + self._make_partial(tp, nested) + continue + if decl.bitsize is None: + bitsize = -1 + else: + bitsize = self._parse_constant(decl.bitsize) + self._partial_length = False + type, fqual = self._get_type_and_quals(decl.type, + partial_length_ok=True) + if self._partial_length: + self._make_partial(tp, nested) + if isinstance(type, model.StructType) and type.partial: + self._make_partial(tp, nested) + fldnames.append(decl.name or '') + fldtypes.append(type) + fldbitsize.append(bitsize) + fldquals.append(fqual) + tp.fldnames = tuple(fldnames) + tp.fldtypes = tuple(fldtypes) + tp.fldbitsize = tuple(fldbitsize) + tp.fldquals = tuple(fldquals) + if fldbitsize != [-1] * len(fldbitsize): + if isinstance(tp, model.StructType) and tp.partial: + raise NotImplementedError("%s: using both bitfields and '...;'" + % (tp,)) + tp.packed = self._options.get('packed') + if tp.completed: # must be re-completed: it is not opaque any more + tp.completed = 0 + self._recomplete.append(tp) + return tp + + def _make_partial(self, tp, nested): + if not isinstance(tp, model.StructOrUnion): + raise CDefError("%s cannot be partial" % (tp,)) + if not tp.has_c_name() and not nested: + raise NotImplementedError("%s is partial but has no C name" %(tp,)) + tp.partial = True + + def _parse_constant(self, exprnode, partial_length_ok=False): + # for now, limited to expressions that are an immediate number + # or positive/negative number + if isinstance(exprnode, pycparser.c_ast.Constant): + s = exprnode.value + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) + elif s[0] == "'" and s[-1] == "'" and ( + len(s) == 3 or (len(s) == 4 and s[1] == "\\")): + return ord(s[-2]) + else: + raise CDefError("invalid constant %r" % (s,)) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '+'): + return self._parse_constant(exprnode.expr) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '-'): + return -self._parse_constant(exprnode.expr) + # load previously defined int constant + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name in self._int_constants): + return self._int_constants[exprnode.name] + # + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name == '__dotdotdotarray__'): + if partial_length_ok: + self._partial_length = True + return '...' + raise FFIError(":%d: unsupported '[...]' here, cannot derive " + "the actual array length in this context" + % exprnode.coord.line) + # + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right + # + raise FFIError(":%d: unsupported expression: expected a " + "simple numeric constant" % exprnode.coord.line) + + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + + def _build_enum_type(self, explicit_name, decls): + if decls is not None: + partial = False + enumerators = [] + enumvalues = [] + nextenumvalue = 0 + for enum in decls.enumerators: + if _r_enum_dotdotdot.match(enum.name): + partial = True + continue + if enum.value is not None: + nextenumvalue = self._parse_constant(enum.value) + enumerators.append(enum.name) + enumvalues.append(nextenumvalue) + self._add_constants(enum.name, nextenumvalue) + nextenumvalue += 1 + enumerators = tuple(enumerators) + enumvalues = tuple(enumvalues) + tp = model.EnumType(explicit_name, enumerators, enumvalues) + tp.partial = partial + else: # opaque enum + tp = model.EnumType(explicit_name, (), ()) + return tp + + def include(self, other): + for name, (tp, quals) in other._declarations.items(): + if name.startswith('anonymous $enum_$'): + continue # fix for test_anonymous_enum_include + kind = name.split(' ', 1)[0] + if kind in ('struct', 'union', 'enum', 'anonymous', 'typedef'): + self._declare(name, tp, included=True, quals=quals) + for k, v in other._int_constants.items(): + self._add_constants(k, v) + + def _get_unknown_type(self, decl): + typenames = decl.type.type.names + if typenames == ['__dotdotdot__']: + return model.unknown_type(decl.name) + + if typenames == ['__dotdotdotint__']: + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef int... %s'" % decl.name + return model.UnknownIntegerType(decl.name) + + if typenames == ['__dotdotdotfloat__']: + # note: not for 'long double' so far + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef float... %s'" % decl.name + return model.UnknownFloatType(decl.name) + + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) + + def _get_unknown_ptr_type(self, decl): + if decl.type.type.type.names == ['__dotdotdot__']: + return model.unknown_ptr_type(decl.name) + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) diff --git a/uno/lib/python/cffi/error.py b/uno/lib/python/cffi/error.py new file mode 100644 index 00000000..0f8f406f --- /dev/null +++ b/uno/lib/python/cffi/error.py @@ -0,0 +1,31 @@ + +class FFIError(Exception): + __module__ = 'cffi' + +class CDefError(Exception): + __module__ = 'cffi' + def __str__(self): + try: + current_decl = self.args[1] + filename = current_decl.coord.file + linenum = current_decl.coord.line + prefix = '%s:%d: ' % (filename, linenum) + except (AttributeError, TypeError, IndexError): + prefix = '' + return '%s%s' % (prefix, self.args[0]) + +class VerificationError(Exception): + """ An error raised when verification fails + """ + __module__ = 'cffi' + +class VerificationMissing(Exception): + """ An error raised when incomplete structures are passed into + cdef, but no verification has been done + """ + __module__ = 'cffi' + +class PkgConfigError(Exception): + """ An error raised for missing modules in pkg-config + """ + __module__ = 'cffi' diff --git a/uno/lib/python/cffi/ffiplatform.py b/uno/lib/python/cffi/ffiplatform.py new file mode 100644 index 00000000..c0970d51 --- /dev/null +++ b/uno/lib/python/cffi/ffiplatform.py @@ -0,0 +1,113 @@ +import sys, os +from .error import VerificationError + + +LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs', + 'extra_objects', 'depends'] + +def get_extension(srcfilename, modname, sources=(), **kwds): + from cffi._shimmed_dist_utils import Extension + allsources = [srcfilename] + for src in sources: + allsources.append(os.path.normpath(src)) + return Extension(name=modname, sources=allsources, **kwds) + +def compile(tmpdir, ext, compiler_verbose=0, debug=None): + """Compile a C extension module using distutils.""" + + saved_environ = os.environ.copy() + try: + outputfilename = _build(tmpdir, ext, compiler_verbose, debug) + outputfilename = os.path.abspath(outputfilename) + finally: + # workaround for a distutils bugs where some env vars can + # become longer and longer every time it is used + for key, value in saved_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + return outputfilename + +def _build(tmpdir, ext, compiler_verbose=0, debug=None): + # XXX compact but horrible :-( + from cffi._shimmed_dist_utils import Distribution, CompileError, LinkError, set_threshold, set_verbosity + + dist = Distribution({'ext_modules': [ext]}) + dist.parse_config_files() + options = dist.get_option_dict('build_ext') + if debug is None: + debug = sys.flags.debug + options['debug'] = ('ffiplatform', debug) + options['force'] = ('ffiplatform', True) + options['build_lib'] = ('ffiplatform', tmpdir) + options['build_temp'] = ('ffiplatform', tmpdir) + # + try: + old_level = set_threshold(0) or 0 + try: + set_verbosity(compiler_verbose) + dist.run_command('build_ext') + cmd_obj = dist.get_command_obj('build_ext') + [soname] = cmd_obj.get_outputs() + finally: + set_threshold(old_level) + except (CompileError, LinkError) as e: + raise VerificationError('%s: %s' % (e.__class__.__name__, e)) + # + return soname + +try: + from os.path import samefile +except ImportError: + def samefile(f1, f2): + return os.path.abspath(f1) == os.path.abspath(f2) + +def maybe_relative_path(path): + if not os.path.isabs(path): + return path # already relative + dir = path + names = [] + while True: + prevdir = dir + dir, name = os.path.split(prevdir) + if dir == prevdir or not dir: + return path # failed to make it relative + names.append(name) + try: + if samefile(dir, os.curdir): + names.reverse() + return os.path.join(*names) + except OSError: + pass + +# ____________________________________________________________ + +try: + int_or_long = (int, long) + import cStringIO +except NameError: + int_or_long = int # Python 3 + import io as cStringIO + +def _flatten(x, f): + if isinstance(x, str): + f.write('%ds%s' % (len(x), x)) + elif isinstance(x, dict): + keys = sorted(x.keys()) + f.write('%dd' % len(keys)) + for key in keys: + _flatten(key, f) + _flatten(x[key], f) + elif isinstance(x, (list, tuple)): + f.write('%dl' % len(x)) + for value in x: + _flatten(value, f) + elif isinstance(x, int_or_long): + f.write('%di' % (x,)) + else: + raise TypeError( + "the keywords to verify() contains unsupported object %r" % (x,)) + +def flatten(x): + f = cStringIO.StringIO() + _flatten(x, f) + return f.getvalue() diff --git a/uno/lib/python/cffi/lock.py b/uno/lib/python/cffi/lock.py new file mode 100644 index 00000000..2e40ed85 --- /dev/null +++ b/uno/lib/python/cffi/lock.py @@ -0,0 +1,30 @@ +import sys + +if sys.version_info < (3,): + try: + from thread import allocate_lock + except ImportError: + from dummy_thread import allocate_lock +else: + try: + from _thread import allocate_lock + except ImportError: + from _dummy_thread import allocate_lock + + +##import sys +##l1 = allocate_lock + +##class allocate_lock(object): +## def __init__(self): +## self._real = l1() +## def __enter__(self): +## for i in range(4, 0, -1): +## print sys._getframe(i).f_code +## print +## return self._real.__enter__() +## def __exit__(self, *args): +## return self._real.__exit__(*args) +## def acquire(self, f): +## assert f is False +## return self._real.acquire(f) diff --git a/uno/lib/python/cffi/model.py b/uno/lib/python/cffi/model.py new file mode 100644 index 00000000..fcf4890c --- /dev/null +++ b/uno/lib/python/cffi/model.py @@ -0,0 +1,618 @@ +import types +import weakref + +from .lock import allocate_lock +from .error import CDefError, VerificationError, VerificationMissing + +# type qualifiers +Q_CONST = 0x01 +Q_RESTRICT = 0x02 +Q_VOLATILE = 0x04 + +def qualify(quals, replace_with): + if quals & Q_CONST: + replace_with = ' const ' + replace_with.lstrip() + if quals & Q_VOLATILE: + replace_with = ' volatile ' + replace_with.lstrip() + if quals & Q_RESTRICT: + # It seems that __restrict is supported by gcc and msvc. + # If you hit some different compiler, add a #define in + # _cffi_include.h for it (and in its copies, documented there) + replace_with = ' __restrict ' + replace_with.lstrip() + return replace_with + + +class BaseTypeByIdentity(object): + is_array_type = False + is_raw_function = False + + def get_c_name(self, replace_with='', context='a C file', quals=0): + result = self.c_name_with_marker + assert result.count('&') == 1 + # some logic duplication with ffi.getctype()... :-( + replace_with = replace_with.strip() + if replace_with: + if replace_with.startswith('*') and '&[' in result: + replace_with = '(%s)' % replace_with + elif not replace_with[0] in '[(': + replace_with = ' ' + replace_with + replace_with = qualify(quals, replace_with) + result = result.replace('&', replace_with) + if '$' in result: + raise VerificationError( + "cannot generate '%s' in %s: unknown type name" + % (self._get_c_name(), context)) + return result + + def _get_c_name(self): + return self.c_name_with_marker.replace('&', '') + + def has_c_name(self): + return '$' not in self._get_c_name() + + def is_integer_type(self): + return False + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + try: + BType = ffi._cached_btypes[self] + except KeyError: + BType = self.build_backend_type(ffi, finishlist) + BType2 = ffi._cached_btypes.setdefault(self, BType) + assert BType2 is BType + return BType + + def __repr__(self): + return '<%s>' % (self._get_c_name(),) + + def _get_items(self): + return [(name, getattr(self, name)) for name in self._attrs_] + + +class BaseType(BaseTypeByIdentity): + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self._get_items() == other._get_items()) + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.__class__, tuple(self._get_items()))) + + +class VoidType(BaseType): + _attrs_ = () + + def __init__(self): + self.c_name_with_marker = 'void&' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_void_type') + +void_type = VoidType() + + +class BasePrimitiveType(BaseType): + def is_complex_type(self): + return False + + +class PrimitiveType(BasePrimitiveType): + _attrs_ = ('name',) + + ALL_PRIMITIVE_TYPES = { + 'char': 'c', + 'short': 'i', + 'int': 'i', + 'long': 'i', + 'long long': 'i', + 'signed char': 'i', + 'unsigned char': 'i', + 'unsigned short': 'i', + 'unsigned int': 'i', + 'unsigned long': 'i', + 'unsigned long long': 'i', + 'float': 'f', + 'double': 'f', + 'long double': 'f', + 'float _Complex': 'j', + 'double _Complex': 'j', + '_Bool': 'i', + # the following types are not primitive in the C sense + 'wchar_t': 'c', + 'char16_t': 'c', + 'char32_t': 'c', + 'int8_t': 'i', + 'uint8_t': 'i', + 'int16_t': 'i', + 'uint16_t': 'i', + 'int32_t': 'i', + 'uint32_t': 'i', + 'int64_t': 'i', + 'uint64_t': 'i', + 'int_least8_t': 'i', + 'uint_least8_t': 'i', + 'int_least16_t': 'i', + 'uint_least16_t': 'i', + 'int_least32_t': 'i', + 'uint_least32_t': 'i', + 'int_least64_t': 'i', + 'uint_least64_t': 'i', + 'int_fast8_t': 'i', + 'uint_fast8_t': 'i', + 'int_fast16_t': 'i', + 'uint_fast16_t': 'i', + 'int_fast32_t': 'i', + 'uint_fast32_t': 'i', + 'int_fast64_t': 'i', + 'uint_fast64_t': 'i', + 'intptr_t': 'i', + 'uintptr_t': 'i', + 'intmax_t': 'i', + 'uintmax_t': 'i', + 'ptrdiff_t': 'i', + 'size_t': 'i', + 'ssize_t': 'i', + } + + def __init__(self, name): + assert name in self.ALL_PRIMITIVE_TYPES + self.name = name + self.c_name_with_marker = name + '&' + + def is_char_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'c' + def is_integer_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'i' + def is_float_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'f' + def is_complex_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'j' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_primitive_type', self.name) + + +class UnknownIntegerType(BasePrimitiveType): + _attrs_ = ('name',) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def is_integer_type(self): + return True + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("integer type '%s' can only be used after " + "compilation" % self.name) + +class UnknownFloatType(BasePrimitiveType): + _attrs_ = ('name', ) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("float type '%s' can only be used after " + "compilation" % self.name) + + +class BaseFunctionType(BaseType): + _attrs_ = ('args', 'result', 'ellipsis', 'abi') + + def __init__(self, args, result, ellipsis, abi=None): + self.args = args + self.result = result + self.ellipsis = ellipsis + self.abi = abi + # + reprargs = [arg._get_c_name() for arg in self.args] + if self.ellipsis: + reprargs.append('...') + reprargs = reprargs or ['void'] + replace_with = self._base_pattern % (', '.join(reprargs),) + if abi is not None: + replace_with = replace_with[:1] + abi + ' ' + replace_with[1:] + self.c_name_with_marker = ( + self.result.c_name_with_marker.replace('&', replace_with)) + + +class RawFunctionType(BaseFunctionType): + # Corresponds to a C type like 'int(int)', which is the C type of + # a function, but not a pointer-to-function. The backend has no + # notion of such a type; it's used temporarily by parsing. + _base_pattern = '(&)(%s)' + is_raw_function = True + + def build_backend_type(self, ffi, finishlist): + raise CDefError("cannot render the type %r: it is a function " + "type, not a pointer-to-function type" % (self,)) + + def as_function_pointer(self): + return FunctionPtrType(self.args, self.result, self.ellipsis, self.abi) + + +class FunctionPtrType(BaseFunctionType): + _base_pattern = '(*&)(%s)' + + def build_backend_type(self, ffi, finishlist): + result = self.result.get_cached_btype(ffi, finishlist) + args = [] + for tp in self.args: + args.append(tp.get_cached_btype(ffi, finishlist)) + abi_args = () + if self.abi == "__stdcall": + if not self.ellipsis: # __stdcall ignored for variadic funcs + try: + abi_args = (ffi._backend.FFI_STDCALL,) + except AttributeError: + pass + return global_cache(self, ffi, 'new_function_type', + tuple(args), result, self.ellipsis, *abi_args) + + def as_raw_function(self): + return RawFunctionType(self.args, self.result, self.ellipsis, self.abi) + + +class PointerType(BaseType): + _attrs_ = ('totype', 'quals') + + def __init__(self, totype, quals=0): + self.totype = totype + self.quals = quals + extra = " *&" + if totype.is_array_type: + extra = "(%s)" % (extra.lstrip(),) + extra = qualify(quals, extra) + self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra) + + def build_backend_type(self, ffi, finishlist): + BItem = self.totype.get_cached_btype(ffi, finishlist, can_delay=True) + return global_cache(self, ffi, 'new_pointer_type', BItem) + +voidp_type = PointerType(void_type) + +def ConstPointerType(totype): + return PointerType(totype, Q_CONST) + +const_voidp_type = ConstPointerType(void_type) + + +class NamedPointerType(PointerType): + _attrs_ = ('totype', 'name') + + def __init__(self, totype, name, quals=0): + PointerType.__init__(self, totype, quals) + self.name = name + self.c_name_with_marker = name + '&' + + +class ArrayType(BaseType): + _attrs_ = ('item', 'length') + is_array_type = True + + def __init__(self, item, length): + self.item = item + self.length = length + # + if length is None: + brackets = '&[]' + elif length == '...': + brackets = '&[/*...*/]' + else: + brackets = '&[%s]' % length + self.c_name_with_marker = ( + self.item.c_name_with_marker.replace('&', brackets)) + + def length_is_unknown(self): + return isinstance(self.length, str) + + def resolve_length(self, newlength): + return ArrayType(self.item, newlength) + + def build_backend_type(self, ffi, finishlist): + if self.length_is_unknown(): + raise CDefError("cannot render the type %r: unknown length" % + (self,)) + self.item.get_cached_btype(ffi, finishlist) # force the item BType + BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist) + return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length) + +char_array_type = ArrayType(PrimitiveType('char'), None) + + +class StructOrUnionOrEnum(BaseTypeByIdentity): + _attrs_ = ('name',) + forcename = None + + def build_c_name_with_marker(self): + name = self.forcename or '%s %s' % (self.kind, self.name) + self.c_name_with_marker = name + '&' + + def force_the_name(self, forcename): + self.forcename = forcename + self.build_c_name_with_marker() + + def get_official_name(self): + assert self.c_name_with_marker.endswith('&') + return self.c_name_with_marker[:-1] + + +class StructOrUnion(StructOrUnionOrEnum): + fixedlayout = None + completed = 0 + partial = False + packed = 0 + + def __init__(self, name, fldnames, fldtypes, fldbitsize, fldquals=None): + self.name = name + self.fldnames = fldnames + self.fldtypes = fldtypes + self.fldbitsize = fldbitsize + self.fldquals = fldquals + self.build_c_name_with_marker() + + def anonymous_struct_fields(self): + if self.fldtypes is not None: + for name, type in zip(self.fldnames, self.fldtypes): + if name == '' and isinstance(type, StructOrUnion): + yield type + + def enumfields(self, expand_anonymous_struct_union=True): + fldquals = self.fldquals + if fldquals is None: + fldquals = (0,) * len(self.fldnames) + for name, type, bitsize, quals in zip(self.fldnames, self.fldtypes, + self.fldbitsize, fldquals): + if (name == '' and isinstance(type, StructOrUnion) + and expand_anonymous_struct_union): + # nested anonymous struct/union + for result in type.enumfields(): + yield result + else: + yield (name, type, bitsize, quals) + + def force_flatten(self): + # force the struct or union to have a declaration that lists + # directly all fields returned by enumfields(), flattening + # nested anonymous structs/unions. + names = [] + types = [] + bitsizes = [] + fldquals = [] + for name, type, bitsize, quals in self.enumfields(): + names.append(name) + types.append(type) + bitsizes.append(bitsize) + fldquals.append(quals) + self.fldnames = tuple(names) + self.fldtypes = tuple(types) + self.fldbitsize = tuple(bitsizes) + self.fldquals = tuple(fldquals) + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + BType = StructOrUnionOrEnum.get_cached_btype(self, ffi, finishlist, + can_delay) + if not can_delay: + self.finish_backend_type(ffi, finishlist) + return BType + + def finish_backend_type(self, ffi, finishlist): + if self.completed: + if self.completed != 2: + raise NotImplementedError("recursive structure declaration " + "for '%s'" % (self.name,)) + return + BType = ffi._cached_btypes[self] + # + self.completed = 1 + # + if self.fldtypes is None: + pass # not completing it: it's an opaque struct + # + elif self.fixedlayout is None: + fldtypes = [tp.get_cached_btype(ffi, finishlist) + for tp in self.fldtypes] + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize)) + extra_flags = () + if self.packed: + if self.packed == 1: + extra_flags = (8,) # SF_PACKED + else: + extra_flags = (0, self.packed) + ffi._backend.complete_struct_or_union(BType, lst, self, + -1, -1, *extra_flags) + # + else: + fldtypes = [] + fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout + for i in range(len(self.fldnames)): + fsize = fieldsize[i] + ftype = self.fldtypes[i] + # + if isinstance(ftype, ArrayType) and ftype.length_is_unknown(): + # fix the length to match the total size + BItemType = ftype.item.get_cached_btype(ffi, finishlist) + nlen, nrest = divmod(fsize, ffi.sizeof(BItemType)) + if nrest != 0: + self._verification_error( + "field '%s.%s' has a bogus size?" % ( + self.name, self.fldnames[i] or '{}')) + ftype = ftype.resolve_length(nlen) + self.fldtypes = (self.fldtypes[:i] + (ftype,) + + self.fldtypes[i+1:]) + # + BFieldType = ftype.get_cached_btype(ffi, finishlist) + if isinstance(ftype, ArrayType) and ftype.length is None: + assert fsize == 0 + else: + bitemsize = ffi.sizeof(BFieldType) + if bitemsize != fsize: + self._verification_error( + "field '%s.%s' is declared as %d bytes, but is " + "really %d bytes" % (self.name, + self.fldnames[i] or '{}', + bitemsize, fsize)) + fldtypes.append(BFieldType) + # + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs)) + ffi._backend.complete_struct_or_union(BType, lst, self, + totalsize, totalalignment) + self.completed = 2 + + def _verification_error(self, msg): + raise VerificationError(msg) + + def check_not_partial(self): + if self.partial and self.fixedlayout is None: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + finishlist.append(self) + # + return global_cache(self, ffi, 'new_%s_type' % self.kind, + self.get_official_name(), key=self) + + +class StructType(StructOrUnion): + kind = 'struct' + + +class UnionType(StructOrUnion): + kind = 'union' + + +class EnumType(StructOrUnionOrEnum): + kind = 'enum' + partial = False + partial_resolved = False + + def __init__(self, name, enumerators, enumvalues, baseinttype=None): + self.name = name + self.enumerators = enumerators + self.enumvalues = enumvalues + self.baseinttype = baseinttype + self.build_c_name_with_marker() + + def force_the_name(self, forcename): + StructOrUnionOrEnum.force_the_name(self, forcename) + if self.forcename is None: + name = self.get_official_name() + self.forcename = '$' + name.replace(' ', '_') + + def check_not_partial(self): + if self.partial and not self.partial_resolved: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + base_btype = self.build_baseinttype(ffi, finishlist) + return global_cache(self, ffi, 'new_enum_type', + self.get_official_name(), + self.enumerators, self.enumvalues, + base_btype, key=self) + + def build_baseinttype(self, ffi, finishlist): + if self.baseinttype is not None: + return self.baseinttype.get_cached_btype(ffi, finishlist) + # + if self.enumvalues: + smallest_value = min(self.enumvalues) + largest_value = max(self.enumvalues) + else: + import warnings + try: + # XXX! The goal is to ensure that the warnings.warn() + # will not suppress the warning. We want to get it + # several times if we reach this point several times. + __warningregistry__.clear() + except NameError: + pass + warnings.warn("%r has no values explicitly defined; " + "guessing that it is equivalent to 'unsigned int'" + % self._get_c_name()) + smallest_value = largest_value = 0 + if smallest_value < 0: # needs a signed type + sign = 1 + candidate1 = PrimitiveType("int") + candidate2 = PrimitiveType("long") + else: + sign = 0 + candidate1 = PrimitiveType("unsigned int") + candidate2 = PrimitiveType("unsigned long") + btype1 = candidate1.get_cached_btype(ffi, finishlist) + btype2 = candidate2.get_cached_btype(ffi, finishlist) + size1 = ffi.sizeof(btype1) + size2 = ffi.sizeof(btype2) + if (smallest_value >= ((-1) << (8*size1-1)) and + largest_value < (1 << (8*size1-sign))): + return btype1 + if (smallest_value >= ((-1) << (8*size2-1)) and + largest_value < (1 << (8*size2-sign))): + return btype2 + raise CDefError("%s values don't all fit into either 'long' " + "or 'unsigned long'" % self._get_c_name()) + +def unknown_type(name, structname=None): + if structname is None: + structname = '$%s' % name + tp = StructType(structname, None, None, None) + tp.force_the_name(name) + tp.origin = "unknown_type" + return tp + +def unknown_ptr_type(name, structname=None): + if structname is None: + structname = '$$%s' % name + tp = StructType(structname, None, None, None) + return NamedPointerType(tp, name) + + +global_lock = allocate_lock() +_typecache_cffi_backend = weakref.WeakValueDictionary() + +def get_typecache(backend): + # returns _typecache_cffi_backend if backend is the _cffi_backend + # module, or type(backend).__typecache if backend is an instance of + # CTypesBackend (or some FakeBackend class during tests) + if isinstance(backend, types.ModuleType): + return _typecache_cffi_backend + with global_lock: + if not hasattr(type(backend), '__typecache'): + type(backend).__typecache = weakref.WeakValueDictionary() + return type(backend).__typecache + +def global_cache(srctype, ffi, funcname, *args, **kwds): + key = kwds.pop('key', (funcname, args)) + assert not kwds + try: + return ffi._typecache[key] + except KeyError: + pass + try: + res = getattr(ffi._backend, funcname)(*args) + except NotImplementedError as e: + raise NotImplementedError("%s: %r: %s" % (funcname, srctype, e)) + # note that setdefault() on WeakValueDictionary is not atomic + # and contains a rare bug (http://bugs.python.org/issue19542); + # we have to use a lock and do it ourselves + cache = ffi._typecache + with global_lock: + res1 = cache.get(key) + if res1 is None: + cache[key] = res + return res + else: + return res1 + +def pointer_cache(ffi, BType): + return global_cache('?', ffi, 'new_pointer_type', BType) + +def attach_exception_info(e, name): + if e.args and type(e.args[0]) is str: + e.args = ('%s: %s' % (name, e.args[0]),) + e.args[1:] diff --git a/uno/lib/python/cffi/parse_c_type.h b/uno/lib/python/cffi/parse_c_type.h new file mode 100644 index 00000000..ea1aa24e --- /dev/null +++ b/uno/lib/python/cffi/parse_c_type.h @@ -0,0 +1,181 @@ + +/* This part is from file 'cffi/parse_c_type.h'. It is copied at the + beginning of C sources generated by CFFI's ffi.set_source(). */ + +typedef void *_cffi_opcode_t; + +#define _CFFI_OP(opcode, arg) (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8)) +#define _CFFI_GETOP(cffi_opcode) ((unsigned char)(uintptr_t)cffi_opcode) +#define _CFFI_GETARG(cffi_opcode) (((intptr_t)cffi_opcode) >> 8) + +#define _CFFI_OP_PRIMITIVE 1 +#define _CFFI_OP_POINTER 3 +#define _CFFI_OP_ARRAY 5 +#define _CFFI_OP_OPEN_ARRAY 7 +#define _CFFI_OP_STRUCT_UNION 9 +#define _CFFI_OP_ENUM 11 +#define _CFFI_OP_FUNCTION 13 +#define _CFFI_OP_FUNCTION_END 15 +#define _CFFI_OP_NOOP 17 +#define _CFFI_OP_BITFIELD 19 +#define _CFFI_OP_TYPENAME 21 +#define _CFFI_OP_CPYTHON_BLTN_V 23 // varargs +#define _CFFI_OP_CPYTHON_BLTN_N 25 // noargs +#define _CFFI_OP_CPYTHON_BLTN_O 27 // O (i.e. a single arg) +#define _CFFI_OP_CONSTANT 29 +#define _CFFI_OP_CONSTANT_INT 31 +#define _CFFI_OP_GLOBAL_VAR 33 +#define _CFFI_OP_DLOPEN_FUNC 35 +#define _CFFI_OP_DLOPEN_CONST 37 +#define _CFFI_OP_GLOBAL_VAR_F 39 +#define _CFFI_OP_EXTERN_PYTHON 41 + +#define _CFFI_PRIM_VOID 0 +#define _CFFI_PRIM_BOOL 1 +#define _CFFI_PRIM_CHAR 2 +#define _CFFI_PRIM_SCHAR 3 +#define _CFFI_PRIM_UCHAR 4 +#define _CFFI_PRIM_SHORT 5 +#define _CFFI_PRIM_USHORT 6 +#define _CFFI_PRIM_INT 7 +#define _CFFI_PRIM_UINT 8 +#define _CFFI_PRIM_LONG 9 +#define _CFFI_PRIM_ULONG 10 +#define _CFFI_PRIM_LONGLONG 11 +#define _CFFI_PRIM_ULONGLONG 12 +#define _CFFI_PRIM_FLOAT 13 +#define _CFFI_PRIM_DOUBLE 14 +#define _CFFI_PRIM_LONGDOUBLE 15 + +#define _CFFI_PRIM_WCHAR 16 +#define _CFFI_PRIM_INT8 17 +#define _CFFI_PRIM_UINT8 18 +#define _CFFI_PRIM_INT16 19 +#define _CFFI_PRIM_UINT16 20 +#define _CFFI_PRIM_INT32 21 +#define _CFFI_PRIM_UINT32 22 +#define _CFFI_PRIM_INT64 23 +#define _CFFI_PRIM_UINT64 24 +#define _CFFI_PRIM_INTPTR 25 +#define _CFFI_PRIM_UINTPTR 26 +#define _CFFI_PRIM_PTRDIFF 27 +#define _CFFI_PRIM_SIZE 28 +#define _CFFI_PRIM_SSIZE 29 +#define _CFFI_PRIM_INT_LEAST8 30 +#define _CFFI_PRIM_UINT_LEAST8 31 +#define _CFFI_PRIM_INT_LEAST16 32 +#define _CFFI_PRIM_UINT_LEAST16 33 +#define _CFFI_PRIM_INT_LEAST32 34 +#define _CFFI_PRIM_UINT_LEAST32 35 +#define _CFFI_PRIM_INT_LEAST64 36 +#define _CFFI_PRIM_UINT_LEAST64 37 +#define _CFFI_PRIM_INT_FAST8 38 +#define _CFFI_PRIM_UINT_FAST8 39 +#define _CFFI_PRIM_INT_FAST16 40 +#define _CFFI_PRIM_UINT_FAST16 41 +#define _CFFI_PRIM_INT_FAST32 42 +#define _CFFI_PRIM_UINT_FAST32 43 +#define _CFFI_PRIM_INT_FAST64 44 +#define _CFFI_PRIM_UINT_FAST64 45 +#define _CFFI_PRIM_INTMAX 46 +#define _CFFI_PRIM_UINTMAX 47 +#define _CFFI_PRIM_FLOATCOMPLEX 48 +#define _CFFI_PRIM_DOUBLECOMPLEX 49 +#define _CFFI_PRIM_CHAR16 50 +#define _CFFI_PRIM_CHAR32 51 + +#define _CFFI__NUM_PRIM 52 +#define _CFFI__UNKNOWN_PRIM (-1) +#define _CFFI__UNKNOWN_FLOAT_PRIM (-2) +#define _CFFI__UNKNOWN_LONG_DOUBLE (-3) + +#define _CFFI__IO_FILE_STRUCT (-1) + + +struct _cffi_global_s { + const char *name; + void *address; + _cffi_opcode_t type_op; + void *size_or_direct_fn; // OP_GLOBAL_VAR: size, or 0 if unknown + // OP_CPYTHON_BLTN_*: addr of direct function +}; + +struct _cffi_getconst_s { + unsigned long long value; + const struct _cffi_type_context_s *ctx; + int gindex; +}; + +struct _cffi_struct_union_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_STRUCT_UNION + int flags; // _CFFI_F_* flags below + size_t size; + int alignment; + int first_field_index; // -> _cffi_fields array + int num_fields; +}; +#define _CFFI_F_UNION 0x01 // is a union, not a struct +#define _CFFI_F_CHECK_FIELDS 0x02 // complain if fields are not in the + // "standard layout" or if some are missing +#define _CFFI_F_PACKED 0x04 // for CHECK_FIELDS, assume a packed struct +#define _CFFI_F_EXTERNAL 0x08 // in some other ffi.include() +#define _CFFI_F_OPAQUE 0x10 // opaque + +struct _cffi_field_s { + const char *name; + size_t field_offset; + size_t field_size; + _cffi_opcode_t field_type_op; +}; + +struct _cffi_enum_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_ENUM + int type_prim; // _CFFI_PRIM_xxx + const char *enumerators; // comma-delimited string +}; + +struct _cffi_typename_s { + const char *name; + int type_index; /* if opaque, points to a possibly artificial + OP_STRUCT which is itself opaque */ +}; + +struct _cffi_type_context_s { + _cffi_opcode_t *types; + const struct _cffi_global_s *globals; + const struct _cffi_field_s *fields; + const struct _cffi_struct_union_s *struct_unions; + const struct _cffi_enum_s *enums; + const struct _cffi_typename_s *typenames; + int num_globals; + int num_struct_unions; + int num_enums; + int num_typenames; + const char *const *includes; + int num_types; + int flags; /* future extension */ +}; + +struct _cffi_parse_info_s { + const struct _cffi_type_context_s *ctx; + _cffi_opcode_t *output; + unsigned int output_size; + size_t error_location; + const char *error_message; +}; + +struct _cffi_externpy_s { + const char *name; + size_t size_of_result; + void *reserved1, *reserved2; +}; + +#ifdef _CFFI_INTERNAL +static int parse_c_type(struct _cffi_parse_info_s *info, const char *input); +static int search_in_globals(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +static int search_in_struct_unions(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +#endif diff --git a/uno/lib/python/cffi/pkgconfig.py b/uno/lib/python/cffi/pkgconfig.py new file mode 100644 index 00000000..89708a50 --- /dev/null +++ b/uno/lib/python/cffi/pkgconfig.py @@ -0,0 +1,121 @@ +# pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi +import sys, os, subprocess + +from .error import PkgConfigError + + +def merge_flags(cfg1, cfg2): + """Merge values from cffi config flags cfg2 to cf1 + + Example: + merge_flags({"libraries": ["one"]}, {"libraries": ["two"]}) + {"libraries": ["one", "two"]} + """ + for key, value in cfg2.items(): + if key not in cfg1: + cfg1[key] = value + else: + if not isinstance(cfg1[key], list): + raise TypeError("cfg1[%r] should be a list of strings" % (key,)) + if not isinstance(value, list): + raise TypeError("cfg2[%r] should be a list of strings" % (key,)) + cfg1[key].extend(value) + return cfg1 + + +def call(libname, flag, encoding=sys.getfilesystemencoding()): + """Calls pkg-config and returns the output if found + """ + a = ["pkg-config", "--print-errors"] + a.append(flag) + a.append(libname) + try: + pc = subprocess.Popen(a, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except EnvironmentError as e: + raise PkgConfigError("cannot run pkg-config: %s" % (str(e).strip(),)) + + bout, berr = pc.communicate() + if pc.returncode != 0: + try: + berr = berr.decode(encoding) + except Exception: + pass + raise PkgConfigError(berr.strip()) + + if sys.version_info >= (3,) and not isinstance(bout, str): # Python 3.x + try: + bout = bout.decode(encoding) + except UnicodeDecodeError: + raise PkgConfigError("pkg-config %s %s returned bytes that cannot " + "be decoded with encoding %r:\n%r" % + (flag, libname, encoding, bout)) + + if os.altsep != '\\' and '\\' in bout: + raise PkgConfigError("pkg-config %s %s returned an unsupported " + "backslash-escaped output:\n%r" % + (flag, libname, bout)) + return bout + + +def flags_from_pkgconfig(libs): + r"""Return compiler line flags for FFI.set_source based on pkg-config output + + Usage + ... + ffibuilder.set_source("_foo", pkgconfig = ["libfoo", "libbar >= 1.8.3"]) + + If pkg-config is installed on build machine, then arguments include_dirs, + library_dirs, libraries, define_macros, extra_compile_args and + extra_link_args are extended with an output of pkg-config for libfoo and + libbar. + + Raises PkgConfigError in case the pkg-config call fails. + """ + + def get_include_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-I")] + + def get_library_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-L")] + + def get_libraries(string): + return [x[2:] for x in string.split() if x.startswith("-l")] + + # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by distutils + def get_macros(string): + def _macro(x): + x = x[2:] # drop "-D" + if '=' in x: + return tuple(x.split("=", 1)) # "-Dfoo=bar" => ("foo", "bar") + else: + return (x, None) # "-Dfoo" => ("foo", None) + return [_macro(x) for x in string.split() if x.startswith("-D")] + + def get_other_cflags(string): + return [x for x in string.split() if not x.startswith("-I") and + not x.startswith("-D")] + + def get_other_libs(string): + return [x for x in string.split() if not x.startswith("-L") and + not x.startswith("-l")] + + # return kwargs for given libname + def kwargs(libname): + fse = sys.getfilesystemencoding() + all_cflags = call(libname, "--cflags") + all_libs = call(libname, "--libs") + return { + "include_dirs": get_include_dirs(all_cflags), + "library_dirs": get_library_dirs(all_libs), + "libraries": get_libraries(all_libs), + "define_macros": get_macros(all_cflags), + "extra_compile_args": get_other_cflags(all_cflags), + "extra_link_args": get_other_libs(all_libs), + } + + # merge all arguments together + ret = {} + for libname in libs: + lib_flags = kwargs(libname) + merge_flags(ret, lib_flags) + return ret diff --git a/uno/lib/python/cffi/recompiler.py b/uno/lib/python/cffi/recompiler.py new file mode 100644 index 00000000..34aa38e2 --- /dev/null +++ b/uno/lib/python/cffi/recompiler.py @@ -0,0 +1,1581 @@ +import os, sys, io +from . import ffiplatform, model +from .error import VerificationError +from .cffi_opcode import * + +VERSION_BASE = 0x2601 +VERSION_EMBEDDED = 0x2701 +VERSION_CHAR16CHAR32 = 0x2801 + +USE_LIMITED_API = (sys.platform != 'win32' or sys.version_info < (3, 0) or + sys.version_info >= (3, 5)) + + +class GlobalExpr: + def __init__(self, name, address, type_op, size=0, check_value=0): + self.name = name + self.address = address + self.type_op = type_op + self.size = size + self.check_value = check_value + + def as_c_expr(self): + return ' { "%s", (void *)%s, %s, (void *)%s },' % ( + self.name, self.address, self.type_op.as_c_expr(), self.size) + + def as_python_expr(self): + return "b'%s%s',%d" % (self.type_op.as_python_bytes(), self.name, + self.check_value) + +class FieldExpr: + def __init__(self, name, field_offset, field_size, fbitsize, field_type_op): + self.name = name + self.field_offset = field_offset + self.field_size = field_size + self.fbitsize = fbitsize + self.field_type_op = field_type_op + + def as_c_expr(self): + spaces = " " * len(self.name) + return (' { "%s", %s,\n' % (self.name, self.field_offset) + + ' %s %s,\n' % (spaces, self.field_size) + + ' %s %s },' % (spaces, self.field_type_op.as_c_expr())) + + def as_python_expr(self): + raise NotImplementedError + + def as_field_python_expr(self): + if self.field_type_op.op == OP_NOOP: + size_expr = '' + elif self.field_type_op.op == OP_BITFIELD: + size_expr = format_four_bytes(self.fbitsize) + else: + raise NotImplementedError + return "b'%s%s%s'" % (self.field_type_op.as_python_bytes(), + size_expr, + self.name) + +class StructUnionExpr: + def __init__(self, name, type_index, flags, size, alignment, comment, + first_field_index, c_fields): + self.name = name + self.type_index = type_index + self.flags = flags + self.size = size + self.alignment = alignment + self.comment = comment + self.first_field_index = first_field_index + self.c_fields = c_fields + + def as_c_expr(self): + return (' { "%s", %d, %s,' % (self.name, self.type_index, self.flags) + + '\n %s, %s, ' % (self.size, self.alignment) + + '%d, %d ' % (self.first_field_index, len(self.c_fields)) + + ('/* %s */ ' % self.comment if self.comment else '') + + '},') + + def as_python_expr(self): + flags = eval(self.flags, G_FLAGS) + fields_expr = [c_field.as_field_python_expr() + for c_field in self.c_fields] + return "(b'%s%s%s',%s)" % ( + format_four_bytes(self.type_index), + format_four_bytes(flags), + self.name, + ','.join(fields_expr)) + +class EnumExpr: + def __init__(self, name, type_index, size, signed, allenums): + self.name = name + self.type_index = type_index + self.size = size + self.signed = signed + self.allenums = allenums + + def as_c_expr(self): + return (' { "%s", %d, _cffi_prim_int(%s, %s),\n' + ' "%s" },' % (self.name, self.type_index, + self.size, self.signed, self.allenums)) + + def as_python_expr(self): + prim_index = { + (1, 0): PRIM_UINT8, (1, 1): PRIM_INT8, + (2, 0): PRIM_UINT16, (2, 1): PRIM_INT16, + (4, 0): PRIM_UINT32, (4, 1): PRIM_INT32, + (8, 0): PRIM_UINT64, (8, 1): PRIM_INT64, + }[self.size, self.signed] + return "b'%s%s%s\\x00%s'" % (format_four_bytes(self.type_index), + format_four_bytes(prim_index), + self.name, self.allenums) + +class TypenameExpr: + def __init__(self, name, type_index): + self.name = name + self.type_index = type_index + + def as_c_expr(self): + return ' { "%s", %d },' % (self.name, self.type_index) + + def as_python_expr(self): + return "b'%s%s'" % (format_four_bytes(self.type_index), self.name) + + +# ____________________________________________________________ + + +class Recompiler: + _num_externpy = 0 + + def __init__(self, ffi, module_name, target_is_python=False): + self.ffi = ffi + self.module_name = module_name + self.target_is_python = target_is_python + self._version = VERSION_BASE + + def needs_version(self, ver): + self._version = max(self._version, ver) + + def collect_type_table(self): + self._typesdict = {} + self._generate("collecttype") + # + all_decls = sorted(self._typesdict, key=str) + # + # prepare all FUNCTION bytecode sequences first + self.cffi_types = [] + for tp in all_decls: + if tp.is_raw_function: + assert self._typesdict[tp] is None + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + for tp1 in tp.args: + assert isinstance(tp1, (model.VoidType, + model.BasePrimitiveType, + model.PointerType, + model.StructOrUnionOrEnum, + model.FunctionPtrType)) + if self._typesdict[tp1] is None: + self._typesdict[tp1] = len(self.cffi_types) + self.cffi_types.append(tp1) # placeholder + self.cffi_types.append('END') # placeholder + # + # prepare all OTHER bytecode sequences + for tp in all_decls: + if not tp.is_raw_function and self._typesdict[tp] is None: + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + if tp.is_array_type and tp.length is not None: + self.cffi_types.append('LEN') # placeholder + assert None not in self._typesdict.values() + # + # collect all structs and unions and enums + self._struct_unions = {} + self._enums = {} + for tp in all_decls: + if isinstance(tp, model.StructOrUnion): + self._struct_unions[tp] = None + elif isinstance(tp, model.EnumType): + self._enums[tp] = None + for i, tp in enumerate(sorted(self._struct_unions, + key=lambda tp: tp.name)): + self._struct_unions[tp] = i + for i, tp in enumerate(sorted(self._enums, + key=lambda tp: tp.name)): + self._enums[tp] = i + # + # emit all bytecode sequences now + for tp in all_decls: + method = getattr(self, '_emit_bytecode_' + tp.__class__.__name__) + method(tp, self._typesdict[tp]) + # + # consistency check + for op in self.cffi_types: + assert isinstance(op, CffiOp) + self.cffi_types = tuple(self.cffi_types) # don't change any more + + def _enum_fields(self, tp): + # When producing C, expand all anonymous struct/union fields. + # That's necessary to have C code checking the offsets of the + # individual fields contained in them. When producing Python, + # don't do it and instead write it like it is, with the + # corresponding fields having an empty name. Empty names are + # recognized at runtime when we import the generated Python + # file. + expand_anonymous_struct_union = not self.target_is_python + return tp.enumfields(expand_anonymous_struct_union) + + def _do_collect_type(self, tp): + if not isinstance(tp, model.BaseTypeByIdentity): + if isinstance(tp, tuple): + for x in tp: + self._do_collect_type(x) + return + if tp not in self._typesdict: + self._typesdict[tp] = None + if isinstance(tp, model.FunctionPtrType): + self._do_collect_type(tp.as_raw_function()) + elif isinstance(tp, model.StructOrUnion): + if tp.fldtypes is not None and ( + tp not in self.ffi._parser._included_declarations): + for name1, tp1, _, _ in self._enum_fields(tp): + self._do_collect_type(self._field_type(tp, name1, tp1)) + else: + for _, x in tp._get_items(): + self._do_collect_type(x) + + def _generate(self, step_name): + lst = self.ffi._parser._declarations.items() + for name, (tp, quals) in sorted(lst): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in recompile(): %r" % name) + try: + self._current_quals = quals + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + # ---------- + + ALL_STEPS = ["global", "field", "struct_union", "enum", "typename"] + + def collect_step_tables(self): + # collect the declarations for '_cffi_globals', '_cffi_typenames', etc. + self._lsts = {} + for step_name in self.ALL_STEPS: + self._lsts[step_name] = [] + self._seen_struct_unions = set() + self._generate("ctx") + self._add_missing_struct_unions() + # + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if step_name != "field": + lst.sort(key=lambda entry: entry.name) + self._lsts[step_name] = tuple(lst) # don't change any more + # + # check for a possible internal inconsistency: _cffi_struct_unions + # should have been generated with exactly self._struct_unions + lst = self._lsts["struct_union"] + for tp, i in self._struct_unions.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._struct_unions) + # same with enums + lst = self._lsts["enum"] + for tp, i in self._enums.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._enums) + + # ---------- + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self, f, preamble): + if self.target_is_python: + assert preamble is None + self.write_py_source_to_f(f) + else: + assert preamble is not None + self.write_c_source_to_f(f, preamble) + + def _rel_readlines(self, filename): + g = open(os.path.join(os.path.dirname(__file__), filename), 'r') + lines = g.readlines() + g.close() + return lines + + def write_c_source_to_f(self, f, preamble): + self._f = f + prnt = self._prnt + if self.ffi._embedding is not None: + prnt('#define _CFFI_USE_EMBEDDING') + if not USE_LIMITED_API: + prnt('#define _CFFI_NO_LIMITED_API') + # + # first the '#include' (actually done by inlining the file's content) + lines = self._rel_readlines('_cffi_include.h') + i = lines.index('#include "parse_c_type.h"\n') + lines[i:i+1] = self._rel_readlines('parse_c_type.h') + prnt(''.join(lines)) + # + # if we have ffi._embedding != None, we give it here as a macro + # and include an extra file + base_module_name = self.module_name.split('.')[-1] + if self.ffi._embedding is not None: + prnt('#define _CFFI_MODULE_NAME "%s"' % (self.module_name,)) + prnt('static const char _CFFI_PYTHON_STARTUP_CODE[] = {') + self._print_string_literal_in_array(self.ffi._embedding) + prnt('0 };') + prnt('#ifdef PYPY_VERSION') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC _cffi_pypyinit_%s' % ( + base_module_name,)) + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC PyInit_%s' % ( + base_module_name,)) + prnt('#else') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC init%s' % ( + base_module_name,)) + prnt('#endif') + lines = self._rel_readlines('_embedding.h') + i = lines.index('#include "_cffi_errors.h"\n') + lines[i:i+1] = self._rel_readlines('_cffi_errors.h') + prnt(''.join(lines)) + self.needs_version(VERSION_EMBEDDED) + # + # then paste the C source given by the user, verbatim. + prnt('/************************************************************/') + prnt() + prnt(preamble) + prnt() + prnt('/************************************************************/') + prnt() + # + # the declaration of '_cffi_types' + prnt('static void *_cffi_types[] = {') + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + for i, op in enumerate(self.cffi_types): + comment = '' + if i in typeindex2type: + comment = ' // ' + typeindex2type[i]._get_c_name() + prnt('/* %2d */ %s,%s' % (i, op.as_c_expr(), comment)) + if not self.cffi_types: + prnt(' 0') + prnt('};') + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._seen_constants = set() + self._generate("decl") + # + # the declaration of '_cffi_globals' and '_cffi_typenames' + nums = {} + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + nums[step_name] = len(lst) + if nums[step_name] > 0: + prnt('static const struct _cffi_%s_s _cffi_%ss[] = {' % ( + step_name, step_name)) + for entry in lst: + prnt(entry.as_c_expr()) + prnt('};') + prnt() + # + # the declaration of '_cffi_includes' + if self.ffi._included_ffis: + prnt('static const char * const _cffi_includes[] = {') + for ffi_to_include in self.ffi._included_ffis: + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is None: + raise VerificationError( + "not implemented yet: ffi.include() of a Python-based " + "ffi inside a C-based ffi") + prnt(' "%s",' % (included_module_name,)) + prnt(' NULL') + prnt('};') + prnt() + # + # the declaration of '_cffi_type_context' + prnt('static const struct _cffi_type_context_s _cffi_type_context = {') + prnt(' _cffi_types,') + for step_name in self.ALL_STEPS: + if nums[step_name] > 0: + prnt(' _cffi_%ss,' % step_name) + else: + prnt(' NULL, /* no %ss */' % step_name) + for step_name in self.ALL_STEPS: + if step_name != "field": + prnt(' %d, /* num_%ss */' % (nums[step_name], step_name)) + if self.ffi._included_ffis: + prnt(' _cffi_includes,') + else: + prnt(' NULL, /* no includes */') + prnt(' %d, /* num_types */' % (len(self.cffi_types),)) + flags = 0 + if self._num_externpy > 0 or self.ffi._embedding is not None: + flags |= 1 # set to mean that we use extern "Python" + prnt(' %d, /* flags */' % flags) + prnt('};') + prnt() + # + # the init function + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility push(default) /* for -fvisibility= */') + prnt('#endif') + prnt() + prnt('#ifdef PYPY_VERSION') + prnt('PyMODINIT_FUNC') + prnt('_cffi_pypyinit_%s(const void *p[])' % (base_module_name,)) + prnt('{') + if flags & 1: + prnt(' if (((intptr_t)p[0]) >= 0x0A03) {') + prnt(' _cffi_call_python_org = ' + '(void(*)(struct _cffi_externpy_s *, char *))p[1];') + prnt(' }') + prnt(' p[0] = (const void *)0x%x;' % self._version) + prnt(' p[1] = &_cffi_type_context;') + prnt('#if PY_MAJOR_VERSION >= 3') + prnt(' return NULL;') + prnt('#endif') + prnt('}') + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + prnt('# ifdef _MSC_VER') + prnt(' PyMODINIT_FUNC') + prnt('# if PY_MAJOR_VERSION >= 3') + prnt(' PyInit_%s(void) { return NULL; }' % (base_module_name,)) + prnt('# else') + prnt(' init%s(void) { }' % (base_module_name,)) + prnt('# endif') + prnt('# endif') + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % (base_module_name,)) + prnt('{') + prnt(' return _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#else') + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % (base_module_name,)) + prnt('{') + prnt(' _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#endif') + prnt() + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility pop') + prnt('#endif') + self._version = None + + def _to_py(self, x): + if isinstance(x, str): + return "b'%s'" % (x,) + if isinstance(x, (list, tuple)): + rep = [self._to_py(item) for item in x] + if len(rep) == 1: + rep.append('') + return "(%s)" % (','.join(rep),) + return x.as_python_expr() # Py2: unicode unexpected; Py3: bytes unexp. + + def write_py_source_to_f(self, f): + self._f = f + prnt = self._prnt + # + # header + prnt("# auto-generated file") + prnt("import _cffi_backend") + # + # the 'import' of the included ffis + num_includes = len(self.ffi._included_ffis or ()) + for i in range(num_includes): + ffi_to_include = self.ffi._included_ffis[i] + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is not None: + raise VerificationError( + "not implemented yet: ffi.include() of a C-based " + "ffi inside a Python-based ffi") + prnt('from %s import ffi as _ffi%d' % (included_module_name, i)) + prnt() + prnt("ffi = _cffi_backend.FFI('%s'," % (self.module_name,)) + prnt(" _version = 0x%x," % (self._version,)) + self._version = None + # + # the '_types' keyword argument + self.cffi_types = tuple(self.cffi_types) # don't change any more + types_lst = [op.as_python_bytes() for op in self.cffi_types] + prnt(' _types = %s,' % (self._to_py(''.join(types_lst)),)) + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + # + # the keyword arguments from ALL_STEPS + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if len(lst) > 0 and step_name != "field": + prnt(' _%ss = %s,' % (step_name, self._to_py(lst))) + # + # the '_includes' keyword argument + if num_includes > 0: + prnt(' _includes = (%s,),' % ( + ', '.join(['_ffi%d' % i for i in range(num_includes)]),)) + # + # the footer + prnt(')') + + # ---------- + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.BasePrimitiveType) and not tp.is_complex_type(): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + elif isinstance(tp, model.UnknownFloatType): + # don't check with is_float_type(): it may be a 'long + # double' here, and _cffi_to_c_double would loose precision + converter = '(%s)_cffi_to_c_double' % (tp.get_c_name(''),) + else: + cname = tp.get_c_name('') + converter = '(%s)_cffi_to_c_%s' % (cname, + tp.name.replace(' ', '_')) + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif (isinstance(tp, model.StructOrUnionOrEnum) or + isinstance(tp, model.BasePrimitiveType)): + # a struct (not a struct pointer) as a function argument; + # or, a complex (the same code works) + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars, freelines): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + '(%s)alloca((size_t)datasize) : NULL;' % ( + tovar, tp.get_c_name(''))) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.BasePrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif isinstance(tp, model.UnknownFloatType): + return '_cffi_from_c_double(%s)' % (var,) + elif tp.name != 'long double' and not tp.is_complex_type(): + cname = tp.name.replace(' ', '_') + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + return '_cffi_from_c_%s(%s)' % (cname, var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs + + def _typedef_type(self, tp, name): + return self._global_type(tp, "(*(%s *)0)" % (name,)) + + def _generate_cpy_typedef_collecttype(self, tp, name): + self._do_collect_type(self._typedef_type(tp, name)) + + def _generate_cpy_typedef_decl(self, tp, name): + pass + + def _typedef_ctx(self, tp, name): + type_index = self._typesdict[tp] + self._lsts["typename"].append(TypenameExpr(name, type_index)) + + def _generate_cpy_typedef_ctx(self, tp, name): + tp = self._typedef_type(tp, name) + self._typedef_ctx(tp, name) + if getattr(tp, "origin", None) == "unknown_type": + self._struct_ctx(tp, tp.name, approxname=None) + elif isinstance(tp, model.NamedPointerType): + self._struct_ctx(tp.totype, tp.totype.name, approxname=tp.name, + named_ptr=tp) + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + self._do_collect_type(tp.as_raw_function()) + if tp.ellipsis and not self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_function_decl(self, tp, name): + assert not self.target_is_python + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_constant_decl(tp, name) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + # + # ------------------------------ + # the 'd' version of the function, only for addressof(lib, 'func') + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arguments.append(type.get_c_name(' x%d' % i, context)) + call_arguments.append('x%d' % i) + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + name_and_arguments = '%s_cffi_d_%s(%s)' % (abi, name, repr_arguments) + prnt('static %s' % (tp.result.get_c_name(name_and_arguments),)) + prnt('{') + call_arguments = ', '.join(call_arguments) + result_code = 'return ' + if isinstance(tp.result, model.VoidType): + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, call_arguments)) + prnt('}') + # + prnt('#ifndef PYPY_VERSION') # ------------------------------ + # + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' x%d' % i, context) + prnt(' %s;' % arg) + # + localvars = set() + freelines = set() + for type in tp.args: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + result_decl = ' %s;' % tp.result.get_c_name(' result', context) + prnt(result_decl) + prnt(' PyObject *pyresult;') + else: + result_decl = None + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_UnpackTuple(args, "%s", %d, %d, %s))' % ( + name, len(rng), len(rng), + ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + call_arguments = ['x%d' % i for i in range(len(tp.args))] + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' pyresult = %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') + else: + for freeline in freelines: + prnt(' ' + freeline) + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + # + prnt('#else') # ------------------------------ + # + # the PyPy version: need to replace struct/union arguments with + # pointers, and if the result is a struct/union, insert a first + # arg that is a pointer to the result. We also do that for + # complex args and return type. + def need_indirection(type): + return (isinstance(type, model.StructOrUnion) or + (isinstance(type, model.PrimitiveType) and + type.is_complex_type())) + difference = False + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + indirection = '' + if need_indirection(type): + indirection = '*' + difference = True + arg = type.get_c_name(' %sx%d' % (indirection, i), context) + arguments.append(arg) + call_arguments.append('%sx%d' % (indirection, i)) + tp_result = tp.result + if need_indirection(tp_result): + context = 'result of %s' % name + arg = tp_result.get_c_name(' *result', context) + arguments.insert(0, arg) + tp_result = model.void_type + result_decl = None + result_code = '*result = ' + difference = True + if difference: + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s_cffi_f_%s(%s)' % (abi, name, + repr_arguments) + prnt('static %s' % (tp_result.get_c_name(name_and_arguments),)) + prnt('{') + if result_decl: + prnt(result_decl) + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + if result_decl: + prnt(' return result;') + prnt('}') + else: + prnt('# define _cffi_f_%s _cffi_d_%s' % (name, name)) + # + prnt('#endif') # ------------------------------ + prnt() + + def _generate_cpy_function_ctx(self, tp, name): + if tp.ellipsis and not self.target_is_python: + self._generate_cpy_constant_ctx(tp, name) + return + type_index = self._typesdict[tp.as_raw_function()] + numargs = len(tp.args) + if self.target_is_python: + meth_kind = OP_DLOPEN_FUNC + elif numargs == 0: + meth_kind = OP_CPYTHON_BLTN_N # 'METH_NOARGS' + elif numargs == 1: + meth_kind = OP_CPYTHON_BLTN_O # 'METH_O' + else: + meth_kind = OP_CPYTHON_BLTN_V # 'METH_VARARGS' + self._lsts["global"].append( + GlobalExpr(name, '_cffi_f_%s' % name, + CffiOp(meth_kind, type_index), + size='_cffi_d_%s' % name)) + + # ---------- + # named structs or unions + + def _field_type(self, tp_struct, field_name, tp_field): + if isinstance(tp_field, model.ArrayType): + actual_length = tp_field.length + if actual_length == '...': + ptr_struct_name = tp_struct.get_c_name('*') + actual_length = '_cffi_array_len(((%s)0)->%s)' % ( + ptr_struct_name, field_name) + tp_item = self._field_type(tp_struct, '%s[0]' % field_name, + tp_field.item) + tp_field = model.ArrayType(tp_item, actual_length) + return tp_field + + def _struct_collecttype(self, tp): + self._do_collect_type(tp) + if self.target_is_python: + # also requires nested anon struct/unions in ABI mode, recursively + for fldtype in tp.anonymous_struct_fields(): + self._struct_collecttype(fldtype) + + def _struct_decl(self, tp, cname, approxname): + if tp.fldtypes is None: + return + prnt = self._prnt + checkfuncname = '_cffi_checkfld_%s' % (approxname,) + prnt('_CFFI_UNUSED_FN') + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in self._enum_fields(tp): + try: + if ftype.is_integer_type() or fbitsize >= 0: + # accept all integers, but complain on float or double + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) + continue + # only accept exactly the type declared, except that '[]' + # is interpreted as a '*' and so will match any array length. + # (It would also match '*', but that's harder to detect...) + while (isinstance(ftype, model.ArrayType) + and (ftype.length is None or ftype.length == '...')): + ftype = ftype.item + fname = fname + '[0]' + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('struct _cffi_align_%s { char x; %s y; };' % (approxname, cname)) + prnt() + + def _struct_ctx(self, tp, cname, approxname, named_ptr=None): + type_index = self._typesdict[tp] + reason_for_not_expanding = None + flags = [] + if isinstance(tp, model.UnionType): + flags.append("_CFFI_F_UNION") + if tp.fldtypes is None: + flags.append("_CFFI_F_OPAQUE") + reason_for_not_expanding = "opaque" + if (tp not in self.ffi._parser._included_declarations and + (named_ptr is None or + named_ptr not in self.ffi._parser._included_declarations)): + if tp.fldtypes is None: + pass # opaque + elif tp.partial or any(tp.anonymous_struct_fields()): + pass # field layout obtained silently from the C compiler + else: + flags.append("_CFFI_F_CHECK_FIELDS") + if tp.packed: + if tp.packed > 1: + raise NotImplementedError( + "%r is declared with 'pack=%r'; only 0 or 1 are " + "supported in API mode (try to use \"...;\", which " + "does not require a 'pack' declaration)" % + (tp, tp.packed)) + flags.append("_CFFI_F_PACKED") + else: + flags.append("_CFFI_F_EXTERNAL") + reason_for_not_expanding = "external" + flags = '|'.join(flags) or '0' + c_fields = [] + if reason_for_not_expanding is None: + enumfields = list(self._enum_fields(tp)) + for fldname, fldtype, fbitsize, fqual in enumfields: + fldtype = self._field_type(tp, fldname, fldtype) + self._check_not_opaque(fldtype, + "field '%s.%s'" % (tp.name, fldname)) + # cname is None for _add_missing_struct_unions() only + op = OP_NOOP + if fbitsize >= 0: + op = OP_BITFIELD + size = '%d /* bits */' % fbitsize + elif cname is None or ( + isinstance(fldtype, model.ArrayType) and + fldtype.length is None): + size = '(size_t)-1' + else: + size = 'sizeof(((%s)0)->%s)' % ( + tp.get_c_name('*') if named_ptr is None + else named_ptr.name, + fldname) + if cname is None or fbitsize >= 0: + offset = '(size_t)-1' + elif named_ptr is not None: + offset = '((char *)&((%s)0)->%s) - (char *)0' % ( + named_ptr.name, fldname) + else: + offset = 'offsetof(%s, %s)' % (tp.get_c_name(''), fldname) + c_fields.append( + FieldExpr(fldname, offset, size, fbitsize, + CffiOp(op, self._typesdict[fldtype]))) + first_field_index = len(self._lsts["field"]) + self._lsts["field"].extend(c_fields) + # + if cname is None: # unknown name, for _add_missing_struct_unions + size = '(size_t)-2' + align = -2 + comment = "unnamed" + else: + if named_ptr is not None: + size = 'sizeof(*(%s)0)' % (named_ptr.name,) + align = '-1 /* unknown alignment */' + else: + size = 'sizeof(%s)' % (cname,) + align = 'offsetof(struct _cffi_align_%s, y)' % (approxname,) + comment = None + else: + size = '(size_t)-1' + align = -1 + first_field_index = -1 + comment = reason_for_not_expanding + self._lsts["struct_union"].append( + StructUnionExpr(tp.name, type_index, flags, size, align, comment, + first_field_index, c_fields)) + self._seen_struct_unions.add(tp) + + def _check_not_opaque(self, tp, location): + while isinstance(tp, model.ArrayType): + tp = tp.item + if isinstance(tp, model.StructOrUnion) and tp.fldtypes is None: + raise TypeError( + "%s is of an opaque type (not declared in cdef())" % location) + + def _add_missing_struct_unions(self): + # not very nice, but some struct declarations might be missing + # because they don't have any known C name. Check that they are + # not partial (we can't complete or verify them!) and emit them + # anonymously. + lst = list(self._struct_unions.items()) + lst.sort(key=lambda tp_order: tp_order[1]) + for tp, order in lst: + if tp not in self._seen_struct_unions: + if tp.partial: + raise NotImplementedError("internal inconsistency: %r is " + "partial but was not seen at " + "this point" % (tp,)) + if tp.name.startswith('$') and tp.name[1:].isdigit(): + approxname = tp.name[1:] + elif tp.name == '_IO_FILE' and tp.forcename == 'FILE': + approxname = 'FILE' + self._typedef_ctx(tp, 'FILE') + else: + raise NotImplementedError("internal inconsistency: %r" % + (tp,)) + self._struct_ctx(tp, None, approxname) + + def _generate_cpy_struct_collecttype(self, tp, name): + self._struct_collecttype(tp) + _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype + + def _struct_names(self, tp): + cname = tp.get_c_name('') + if ' ' in cname: + return cname, cname.replace(' ', '_') + else: + return cname, '_' + cname + + def _generate_cpy_struct_decl(self, tp, name): + self._struct_decl(tp, *self._struct_names(tp)) + _generate_cpy_union_decl = _generate_cpy_struct_decl + + def _generate_cpy_struct_ctx(self, tp, name): + self._struct_ctx(tp, *self._struct_names(tp)) + _generate_cpy_union_ctx = _generate_cpy_struct_ctx + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_cpy_anonymous_collecttype(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_collecttype(tp, name) + else: + self._struct_collecttype(tp) + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp) + else: + self._struct_decl(tp, name, 'typedef_' + name) + + def _generate_cpy_anonymous_ctx(self, tp, name): + if isinstance(tp, model.EnumType): + self._enum_ctx(tp, name) + else: + self._struct_ctx(tp, name, 'typedef_' + name) + + # ---------- + # constants, declared with "static const ..." + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + check_value=None): + if (category, name) in self._seen_constants: + raise VerificationError( + "duplicate declaration of %s '%s'" % (category, name)) + self._seen_constants.add((category, name)) + # + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + if is_int: + prnt('static int %s(unsigned long long *o)' % funcname) + prnt('{') + prnt(' int n = (%s) <= 0;' % (name,)) + prnt(' *o = (unsigned long long)((%s) | 0);' + ' /* check that %s is an integer */' % (name, name)) + if check_value is not None: + if check_value > 0: + check_value = '%dU' % (check_value,) + prnt(' if (!_cffi_check_int(*o, n, %s))' % (check_value,)) + prnt(' n |= 2;') + prnt(' return n;') + prnt('}') + else: + assert check_value is None + prnt('static void %s(char *o)' % funcname) + prnt('{') + prnt(' *(%s)o = %s;' % (tp.get_c_name('*'), name)) + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = tp.is_integer_type() + if not is_int or self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + def _generate_cpy_constant_ctx(self, tp, name): + if not self.target_is_python and tp.is_integer_type(): + type_op = CffiOp(OP_CONSTANT_INT, -1) + else: + if self.target_is_python: + const_kind = OP_DLOPEN_CONST + else: + const_kind = OP_CONSTANT + type_index = self._typesdict[tp] + type_op = CffiOp(const_kind, type_index) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op)) + + # ---------- + # enums + + def _generate_cpy_enum_collecttype(self, tp, name): + self._do_collect_type(tp) + + def _generate_cpy_enum_decl(self, tp, name=None): + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator) + + def _enum_ctx(self, tp, cname): + type_index = self._typesdict[tp] + type_op = CffiOp(OP_ENUM, -1) + if self.target_is_python: + tp.check_not_partial() + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._lsts["global"].append( + GlobalExpr(enumerator, '_cffi_const_%s' % enumerator, type_op, + check_value=enumvalue)) + # + if cname is not None and '$' not in cname and not self.target_is_python: + size = "sizeof(%s)" % cname + signed = "((%s)-1) <= 0" % cname + else: + basetp = tp.build_baseinttype(self.ffi, []) + size = self.ffi.sizeof(basetp) + signed = int(int(self.ffi.cast(basetp, -1)) < 0) + allenums = ",".join(tp.enumerators) + self._lsts["enum"].append( + EnumExpr(tp.name, type_index, size, signed, allenums)) + + def _generate_cpy_enum_ctx(self, tp, name): + self._enum_ctx(tp, tp._get_c_name()) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_collecttype(self, tp, name): + pass + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + def _generate_cpy_macro_ctx(self, tp, name): + if tp == '...': + if self.target_is_python: + raise VerificationError( + "cannot use the syntax '...' in '#define %s ...' when " + "using the ABI mode" % (name,)) + check_value = None + else: + check_value = tp # an integer + type_op = CffiOp(OP_CONSTANT_INT, -1) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op, + check_value=check_value)) + + # ---------- + # global variables + + def _global_type(self, tp, global_name): + if isinstance(tp, model.ArrayType): + actual_length = tp.length + if actual_length == '...': + actual_length = '_cffi_array_len(%s)' % (global_name,) + tp_item = self._global_type(tp.item, '%s[0]' % global_name) + tp = model.ArrayType(tp_item, actual_length) + return tp + + def _generate_cpy_variable_collecttype(self, tp, name): + self._do_collect_type(self._global_type(tp, name)) + + def _generate_cpy_variable_decl(self, tp, name): + prnt = self._prnt + tp = self._global_type(tp, name) + if isinstance(tp, model.ArrayType) and tp.length is None: + tp = tp.item + ampersand = '' + else: + ampersand = '&' + # This code assumes that casts from "tp *" to "void *" is a + # no-op, i.e. a function that returns a "tp *" can be called + # as if it returned a "void *". This should be generally true + # on any modern machine. The only exception to that rule (on + # uncommon architectures, and as far as I can tell) might be + # if 'tp' were a function type, but that is not possible here. + # (If 'tp' is a function _pointer_ type, then casts from "fn_t + # **" to "void *" are again no-ops, as far as I can tell.) + decl = '*_cffi_var_%s(void)' % (name,) + prnt('static ' + tp.get_c_name(decl, quals=self._current_quals)) + prnt('{') + prnt(' return %s(%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_cpy_variable_ctx(self, tp, name): + tp = self._global_type(tp, name) + type_index = self._typesdict[tp] + if self.target_is_python: + op = OP_GLOBAL_VAR + else: + op = OP_GLOBAL_VAR_F + self._lsts["global"].append( + GlobalExpr(name, '_cffi_var_%s' % name, CffiOp(op, type_index))) + + # ---------- + # extern "Python" + + def _generate_cpy_extern_python_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + self._do_collect_type(tp) + _generate_cpy_dllexport_python_collecttype = \ + _generate_cpy_extern_python_plus_c_collecttype = \ + _generate_cpy_extern_python_collecttype + + def _extern_python_decl(self, tp, name, tag_and_space): + prnt = self._prnt + if isinstance(tp.result, model.VoidType): + size_of_result = '0' + else: + context = 'result of %s' % name + size_of_result = '(int)sizeof(%s)' % ( + tp.result.get_c_name('', context),) + prnt('static struct _cffi_externpy_s _cffi_externpy__%s =' % name) + prnt(' { "%s.%s", %s, 0, 0 };' % ( + self.module_name, name, size_of_result)) + prnt() + # + arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' a%d' % i, context) + arguments.append(arg) + # + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s(%s)' % (name, repr_arguments) + if tp.abi == "__stdcall": + name_and_arguments = '_cffi_stdcall ' + name_and_arguments + # + def may_need_128_bits(tp): + return (isinstance(tp, model.PrimitiveType) and + tp.name == 'long double') + # + size_of_a = max(len(tp.args)*8, 8) + if may_need_128_bits(tp.result): + size_of_a = max(size_of_a, 16) + if isinstance(tp.result, model.StructOrUnion): + size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % ( + tp.result.get_c_name(''), size_of_a, + tp.result.get_c_name(''), size_of_a) + prnt('%s%s' % (tag_and_space, tp.result.get_c_name(name_and_arguments))) + prnt('{') + prnt(' char a[%s];' % size_of_a) + prnt(' char *p = a;') + for i, type in enumerate(tp.args): + arg = 'a%d' % i + if (isinstance(type, model.StructOrUnion) or + may_need_128_bits(type)): + arg = '&' + arg + type = model.PointerType(type) + prnt(' *(%s)(p + %d) = %s;' % (type.get_c_name('*'), i*8, arg)) + prnt(' _cffi_call_python(&_cffi_externpy__%s, p);' % name) + if not isinstance(tp.result, model.VoidType): + prnt(' return *(%s)p;' % (tp.result.get_c_name('*'),)) + prnt('}') + prnt() + self._num_externpy += 1 + + def _generate_cpy_extern_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'static ') + + def _generate_cpy_dllexport_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'CFFI_DLLEXPORT ') + + def _generate_cpy_extern_python_plus_c_decl(self, tp, name): + self._extern_python_decl(tp, name, '') + + def _generate_cpy_extern_python_ctx(self, tp, name): + if self.target_is_python: + raise VerificationError( + "cannot use 'extern \"Python\"' in the ABI mode") + if tp.ellipsis: + raise NotImplementedError("a vararg function is extern \"Python\"") + type_index = self._typesdict[tp] + type_op = CffiOp(OP_EXTERN_PYTHON, type_index) + self._lsts["global"].append( + GlobalExpr(name, '&_cffi_externpy__%s' % name, type_op, name)) + + _generate_cpy_dllexport_python_ctx = \ + _generate_cpy_extern_python_plus_c_ctx = \ + _generate_cpy_extern_python_ctx + + def _print_string_literal_in_array(self, s): + prnt = self._prnt + prnt('// # NB. this is not a string because of a size limit in MSVC') + if not isinstance(s, bytes): # unicode + s = s.encode('utf-8') # -> bytes + else: + s.decode('utf-8') # got bytes, check for valid utf-8 + try: + s.decode('ascii') + except UnicodeDecodeError: + s = b'# -*- encoding: utf8 -*-\n' + s + for line in s.splitlines(True): + comment = line + if type('//') is bytes: # python2 + line = map(ord, line) # make a list of integers + else: # python3 + # type(line) is bytes, which enumerates like a list of integers + comment = ascii(comment)[1:-1] + prnt(('// ' + comment).rstrip()) + printed_line = '' + for c in line: + if len(printed_line) >= 76: + prnt(printed_line) + printed_line = '' + printed_line += '%d,' % (c,) + prnt(printed_line) + + # ---------- + # emitting the opcodes for individual types + + def _emit_bytecode_VoidType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, PRIM_VOID) + + def _emit_bytecode_PrimitiveType(self, tp, index): + prim_index = PRIMITIVE_TO_INDEX[tp.name] + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, prim_index) + + def _emit_bytecode_UnknownIntegerType(self, tp, index): + s = ('_cffi_prim_int(sizeof(%s), (\n' + ' ((%s)-1) | 0 /* check that %s is an integer type */\n' + ' ) <= 0)' % (tp.name, tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_UnknownFloatType(self, tp, index): + s = ('_cffi_prim_float(sizeof(%s) *\n' + ' (((%s)1) / 2) * 2 /* integer => 0, float => 1 */\n' + ' )' % (tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_RawFunctionType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_FUNCTION, self._typesdict[tp.result]) + index += 1 + for tp1 in tp.args: + realindex = self._typesdict[tp1] + if index != realindex: + if isinstance(tp1, model.PrimitiveType): + self._emit_bytecode_PrimitiveType(tp1, index) + else: + self.cffi_types[index] = CffiOp(OP_NOOP, realindex) + index += 1 + flags = int(tp.ellipsis) + if tp.abi is not None: + if tp.abi == '__stdcall': + flags |= 2 + else: + raise NotImplementedError("abi=%r" % (tp.abi,)) + self.cffi_types[index] = CffiOp(OP_FUNCTION_END, flags) + + def _emit_bytecode_PointerType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[tp.totype]) + + _emit_bytecode_ConstPointerType = _emit_bytecode_PointerType + _emit_bytecode_NamedPointerType = _emit_bytecode_PointerType + + def _emit_bytecode_FunctionPtrType(self, tp, index): + raw = tp.as_raw_function() + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[raw]) + + def _emit_bytecode_ArrayType(self, tp, index): + item_index = self._typesdict[tp.item] + if tp.length is None: + self.cffi_types[index] = CffiOp(OP_OPEN_ARRAY, item_index) + elif tp.length == '...': + raise VerificationError( + "type %s badly placed: the '...' array length can only be " + "used on global arrays or on fields of structures" % ( + str(tp).replace('/*...*/', '...'),)) + else: + assert self.cffi_types[index + 1] == 'LEN' + self.cffi_types[index] = CffiOp(OP_ARRAY, item_index) + self.cffi_types[index + 1] = CffiOp(None, str(tp.length)) + + def _emit_bytecode_StructType(self, tp, index): + struct_index = self._struct_unions[tp] + self.cffi_types[index] = CffiOp(OP_STRUCT_UNION, struct_index) + _emit_bytecode_UnionType = _emit_bytecode_StructType + + def _emit_bytecode_EnumType(self, tp, index): + enum_index = self._enums[tp] + self.cffi_types[index] = CffiOp(OP_ENUM, enum_index) + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + +def _make_c_or_py_source(ffi, module_name, preamble, target_file, verbose): + if verbose: + print("generating %s" % (target_file,)) + recompiler = Recompiler(ffi, module_name, + target_is_python=(preamble is None)) + recompiler.collect_type_table() + recompiler.collect_step_tables() + f = NativeIO() + recompiler.write_source_to_f(f, preamble) + output = f.getvalue() + try: + with open(target_file, 'r') as f1: + if f1.read(len(output) + 1) != output: + raise IOError + if verbose: + print("(already up-to-date)") + return False # already up-to-date + except IOError: + tmp_file = '%s.~%d' % (target_file, os.getpid()) + with open(tmp_file, 'w') as f1: + f1.write(output) + try: + os.rename(tmp_file, target_file) + except OSError: + os.unlink(target_file) + os.rename(tmp_file, target_file) + return True + +def make_c_source(ffi, module_name, preamble, target_c_file, verbose=False): + assert preamble is not None + return _make_c_or_py_source(ffi, module_name, preamble, target_c_file, + verbose) + +def make_py_source(ffi, module_name, target_py_file, verbose=False): + return _make_c_or_py_source(ffi, module_name, None, target_py_file, + verbose) + +def _modname_to_file(outputdir, modname, extension): + parts = modname.split('.') + try: + os.makedirs(os.path.join(outputdir, *parts[:-1])) + except OSError: + pass + parts[-1] += extension + return os.path.join(outputdir, *parts), parts + + +# Aaargh. Distutils is not tested at all for the purpose of compiling +# DLLs that are not extension modules. Here are some hacks to work +# around that, in the _patch_for_*() functions... + +def _patch_meth(patchlist, cls, name, new_meth): + old = getattr(cls, name) + patchlist.append((cls, name, old)) + setattr(cls, name, new_meth) + return old + +def _unpatch_meths(patchlist): + for cls, name, old_meth in reversed(patchlist): + setattr(cls, name, old_meth) + +def _patch_for_embedding(patchlist): + if sys.platform == 'win32': + # we must not remove the manifest when building for embedding! + from cffi._shimmed_dist_utils import MSVCCompiler + _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref', + lambda self, manifest_file: manifest_file) + + if sys.platform == 'darwin': + # we must not make a '-bundle', but a '-dynamiclib' instead + from cffi._shimmed_dist_utils import CCompiler + def my_link_shared_object(self, *args, **kwds): + if '-bundle' in self.linker_so: + self.linker_so = list(self.linker_so) + i = self.linker_so.index('-bundle') + self.linker_so[i] = '-dynamiclib' + return old_link_shared_object(self, *args, **kwds) + old_link_shared_object = _patch_meth(patchlist, CCompiler, + 'link_shared_object', + my_link_shared_object) + +def _patch_for_target(patchlist, target): + from cffi._shimmed_dist_utils import build_ext + # if 'target' is different from '*', we need to patch some internal + # method to just return this 'target' value, instead of having it + # built from module_name + if target.endswith('.*'): + target = target[:-2] + if sys.platform == 'win32': + target += '.dll' + elif sys.platform == 'darwin': + target += '.dylib' + else: + target += '.so' + _patch_meth(patchlist, build_ext, 'get_ext_filename', + lambda self, ext_name: target) + + +def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True, + c_file=None, source_extension='.c', extradir=None, + compiler_verbose=1, target=None, debug=None, **kwds): + if not isinstance(module_name, str): + module_name = module_name.encode('ascii') + if ffi._windows_unicode: + ffi._apply_windows_unicode(kwds) + if preamble is not None: + embedding = (ffi._embedding is not None) + if embedding: + ffi._apply_embedding_fix(kwds) + if c_file is None: + c_file, parts = _modname_to_file(tmpdir, module_name, + source_extension) + if extradir: + parts = [extradir] + parts + ext_c_file = os.path.join(*parts) + else: + ext_c_file = c_file + # + if target is None: + if embedding: + target = '%s.*' % module_name + else: + target = '*' + # + ext = ffiplatform.get_extension(ext_c_file, module_name, **kwds) + updated = make_c_source(ffi, module_name, preamble, c_file, + verbose=compiler_verbose) + if call_c_compiler: + patchlist = [] + cwd = os.getcwd() + try: + if embedding: + _patch_for_embedding(patchlist) + if target != '*': + _patch_for_target(patchlist, target) + if compiler_verbose: + if tmpdir == '.': + msg = 'the current directory is' + else: + msg = 'setting the current directory to' + print('%s %r' % (msg, os.path.abspath(tmpdir))) + os.chdir(tmpdir) + outputfilename = ffiplatform.compile('.', ext, + compiler_verbose, debug) + finally: + os.chdir(cwd) + _unpatch_meths(patchlist) + return outputfilename + else: + return ext, updated + else: + if c_file is None: + c_file, _ = _modname_to_file(tmpdir, module_name, '.py') + updated = make_py_source(ffi, module_name, c_file, + verbose=compiler_verbose) + if call_c_compiler: + return c_file + else: + return None, updated + diff --git a/uno/lib/python/cffi/setuptools_ext.py b/uno/lib/python/cffi/setuptools_ext.py new file mode 100644 index 00000000..04f08b6b --- /dev/null +++ b/uno/lib/python/cffi/setuptools_ext.py @@ -0,0 +1,216 @@ +import os +import sys + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +def error(msg): + from cffi._shimmed_dist_utils import DistutilsSetupError + raise DistutilsSetupError(msg) + + +def execfile(filename, glob): + # We use execfile() (here rewritten for Python 3) instead of + # __import__() to load the build script. The problem with + # a normal import is that in some packages, the intermediate + # __init__.py files may already try to import the file that + # we are generating. + with open(filename) as f: + src = f.read() + src += '\n' # Python 2.6 compatibility + code = compile(src, filename, 'exec') + exec(code, glob, glob) + + +def add_cffi_module(dist, mod_spec): + from cffi.api import FFI + + if not isinstance(mod_spec, basestring): + error("argument to 'cffi_modules=...' must be a str or a list of str," + " not %r" % (type(mod_spec).__name__,)) + mod_spec = str(mod_spec) + try: + build_file_name, ffi_var_name = mod_spec.split(':') + except ValueError: + error("%r must be of the form 'path/build.py:ffi_variable'" % + (mod_spec,)) + if not os.path.exists(build_file_name): + ext = '' + rewritten = build_file_name.replace('.', '/') + '.py' + if os.path.exists(rewritten): + ext = ' (rewrite cffi_modules to [%r])' % ( + rewritten + ':' + ffi_var_name,) + error("%r does not name an existing file%s" % (build_file_name, ext)) + + mod_vars = {'__name__': '__cffi__', '__file__': build_file_name} + execfile(build_file_name, mod_vars) + + try: + ffi = mod_vars[ffi_var_name] + except KeyError: + error("%r: object %r not found in module" % (mod_spec, + ffi_var_name)) + if not isinstance(ffi, FFI): + ffi = ffi() # maybe it's a function instead of directly an ffi + if not isinstance(ffi, FFI): + error("%r is not an FFI instance (got %r)" % (mod_spec, + type(ffi).__name__)) + if not hasattr(ffi, '_assigned_source'): + error("%r: the set_source() method was not called" % (mod_spec,)) + module_name, source, source_extension, kwds = ffi._assigned_source + if ffi._windows_unicode: + kwds = kwds.copy() + ffi._apply_windows_unicode(kwds) + + if source is None: + _add_py_module(dist, ffi, module_name) + else: + _add_c_module(dist, ffi, module_name, source, source_extension, kwds) + +def _set_py_limited_api(Extension, kwds): + """ + Add py_limited_api to kwds if setuptools >= 26 is in use. + Do not alter the setting if it already exists. + Setuptools takes care of ignoring the flag on Python 2 and PyPy. + + CPython itself should ignore the flag in a debugging version + (by not listing .abi3.so in the extensions it supports), but + it doesn't so far, creating troubles. That's why we check + for "not hasattr(sys, 'gettotalrefcount')" (the 2.7 compatible equivalent + of 'd' not in sys.abiflags). (http://bugs.python.org/issue28401) + + On Windows, with CPython <= 3.4, it's better not to use py_limited_api + because virtualenv *still* doesn't copy PYTHON3.DLL on these versions. + Recently (2020) we started shipping only >= 3.5 wheels, though. So + we'll give it another try and set py_limited_api on Windows >= 3.5. + """ + from cffi import recompiler + + if ('py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount') + and recompiler.USE_LIMITED_API): + import setuptools + try: + setuptools_major_version = int(setuptools.__version__.partition('.')[0]) + if setuptools_major_version >= 26: + kwds['py_limited_api'] = True + except ValueError: # certain development versions of setuptools + # If we don't know the version number of setuptools, we + # try to set 'py_limited_api' anyway. At worst, we get a + # warning. + kwds['py_limited_api'] = True + return kwds + +def _add_c_module(dist, ffi, module_name, source, source_extension, kwds): + # We are a setuptools extension. Need this build_ext for py_limited_api. + from setuptools.command.build_ext import build_ext + from cffi._shimmed_dist_utils import Extension, log, mkpath + from cffi import recompiler + + allsources = ['$PLACEHOLDER'] + allsources.extend(kwds.pop('sources', [])) + kwds = _set_py_limited_api(Extension, kwds) + ext = Extension(name=module_name, sources=allsources, **kwds) + + def make_mod(tmpdir, pre_run=None): + c_file = os.path.join(tmpdir, module_name + source_extension) + log.info("generating cffi module %r" % c_file) + mkpath(tmpdir) + # a setuptools-only, API-only hook: called with the "ext" and "ffi" + # arguments just before we turn the ffi into C code. To use it, + # subclass the 'distutils.command.build_ext.build_ext' class and + # add a method 'def pre_run(self, ext, ffi)'. + if pre_run is not None: + pre_run(ext, ffi) + updated = recompiler.make_c_source(ffi, module_name, source, c_file) + if not updated: + log.info("already up-to-date") + return c_file + + if dist.ext_modules is None: + dist.ext_modules = [] + dist.ext_modules.append(ext) + + base_class = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class): + def run(self): + if ext.sources[0] == '$PLACEHOLDER': + pre_run = getattr(self, 'pre_run', None) + ext.sources[0] = make_mod(self.build_temp, pre_run) + base_class.run(self) + dist.cmdclass['build_ext'] = build_ext_make_mod + # NB. multiple runs here will create multiple 'build_ext_make_mod' + # classes. Even in this case the 'build_ext' command should be + # run once; but just in case, the logic above does nothing if + # called again. + + +def _add_py_module(dist, ffi, module_name): + from setuptools.command.build_py import build_py + from setuptools.command.build_ext import build_ext + from cffi._shimmed_dist_utils import log, mkpath + from cffi import recompiler + + def generate_mod(py_file): + log.info("generating cffi module %r" % py_file) + mkpath(os.path.dirname(py_file)) + updated = recompiler.make_py_source(ffi, module_name, py_file) + if not updated: + log.info("already up-to-date") + + base_class = dist.cmdclass.get('build_py', build_py) + class build_py_make_mod(base_class): + def run(self): + base_class.run(self) + module_path = module_name.split('.') + module_path[-1] += '.py' + generate_mod(os.path.join(self.build_lib, *module_path)) + def get_source_files(self): + # This is called from 'setup.py sdist' only. Exclude + # the generate .py module in this case. + saved_py_modules = self.py_modules + try: + if saved_py_modules: + self.py_modules = [m for m in saved_py_modules + if m != module_name] + return base_class.get_source_files(self) + finally: + self.py_modules = saved_py_modules + dist.cmdclass['build_py'] = build_py_make_mod + + # distutils and setuptools have no notion I could find of a + # generated python module. If we don't add module_name to + # dist.py_modules, then things mostly work but there are some + # combination of options (--root and --record) that will miss + # the module. So we add it here, which gives a few apparently + # harmless warnings about not finding the file outside the + # build directory. + # Then we need to hack more in get_source_files(); see above. + if dist.py_modules is None: + dist.py_modules = [] + dist.py_modules.append(module_name) + + # the following is only for "build_ext -i" + base_class_2 = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class_2): + def run(self): + base_class_2.run(self) + if self.inplace: + # from get_ext_fullpath() in distutils/command/build_ext.py + module_path = module_name.split('.') + package = '.'.join(module_path[:-1]) + build_py = self.get_finalized_command('build_py') + package_dir = build_py.get_package_dir(package) + file_name = module_path[-1] + '.py' + generate_mod(os.path.join(package_dir, file_name)) + dist.cmdclass['build_ext'] = build_ext_make_mod + +def cffi_modules(dist, attr, value): + assert attr == 'cffi_modules' + if isinstance(value, basestring): + value = [value] + + for cffi_module in value: + add_cffi_module(dist, cffi_module) diff --git a/uno/lib/python/cffi/vengine_cpy.py b/uno/lib/python/cffi/vengine_cpy.py new file mode 100644 index 00000000..c501aafc --- /dev/null +++ b/uno/lib/python/cffi/vengine_cpy.py @@ -0,0 +1,1077 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys +from . import model +from .error import VerificationError +from . import _imp_emulation as imp + + +class VCPythonEngine(object): + _class_key = 'x' + _gen_python_module = True + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self._struct_pending_verification = {} + self._types_of_builtin_functions = {} + + def patch_extension_kwds(self, kwds): + pass + + def find_module(self, module_name, path, so_suffixes): + try: + f, filename, descr = imp.find_module(module_name, path) + except ImportError: + return None + if f is not None: + f.close() + # Note that after a setuptools installation, there are both .py + # and .so files with the same basename. The code here relies on + # imp.find_module() locating the .so in priority. + if descr[0] not in so_suffixes: + return None + return filename + + def collect_types(self): + self._typesdict = {} + self._generate("collecttype") + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _do_collect_type(self, tp): + if ((not isinstance(tp, model.PrimitiveType) + or tp.name == 'long double') + and tp not in self._typesdict): + num = len(self._typesdict) + self._typesdict[tp] = num + + def write_source_to_f(self): + self.collect_types() + # + # The new module will have a _cffi_setup() function that receives + # objects from the ffi world, and that calls some setup code in + # the module. This setup code is split in several independent + # functions, e.g. one per constant. The functions are "chained" + # by ending in a tail call to each other. + # + # This is further split in two chained lists, depending on if we + # can do it at import-time or if we must wait for _cffi_setup() to + # provide us with the objects. This is needed because we + # need the values of the enum constants in order to build the + # that we may have to pass to _cffi_setup(). + # + # The following two 'chained_list_constants' items contains + # the head of these two chained lists, as a string that gives the + # call to do, if any. + self._chained_list_constants = ['((void)lib,0)', '((void)lib,0)'] + # + prnt = self._prnt + # first paste some standard set of lines that are mostly '#define' + prnt(cffimod_header) + prnt() + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate("decl") + # + # implement the function _cffi_setup_custom() as calling the + # head of the chained list. + self._generate_setup_custom() + prnt() + # + # produce the method table, including the entries for the + # generated Python->C function wrappers, which are done + # by generate_cpy_function_method(). + prnt('static PyMethodDef _cffi_methods[] = {') + self._generate("method") + prnt(' {"_cffi_setup", _cffi_setup, METH_VARARGS, NULL},') + prnt(' {NULL, NULL, 0, NULL} /* Sentinel */') + prnt('};') + prnt() + # + # standard init. + modname = self.verifier.get_module_name() + constants = self._chained_list_constants[False] + prnt('#if PY_MAJOR_VERSION >= 3') + prnt() + prnt('static struct PyModuleDef _cffi_module_def = {') + prnt(' PyModuleDef_HEAD_INIT,') + prnt(' "%s",' % modname) + prnt(' NULL,') + prnt(' -1,') + prnt(' _cffi_methods,') + prnt(' NULL, NULL, NULL, NULL') + prnt('};') + prnt() + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = PyModule_Create(&_cffi_module_def);') + prnt(' if (lib == NULL)') + prnt(' return NULL;') + prnt(' if (%s < 0 || _cffi_init() < 0) {' % (constants,)) + prnt(' Py_DECREF(lib);') + prnt(' return NULL;') + prnt(' }') + prnt(' return lib;') + prnt('}') + prnt() + prnt('#else') + prnt() + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname) + prnt(' if (lib == NULL)') + prnt(' return;') + prnt(' if (%s < 0 || _cffi_init() < 0)' % (constants,)) + prnt(' return;') + prnt(' return;') + prnt('}') + prnt() + prnt('#endif') + + def load_library(self, flags=None): + # XXX review all usages of 'self' here! + # import it as a new extension module + imp.acquire_lock() + try: + if hasattr(sys, "getdlopenflags"): + previous_flags = sys.getdlopenflags() + try: + if hasattr(sys, "setdlopenflags") and flags is not None: + sys.setdlopenflags(flags) + module = imp.load_dynamic(self.verifier.get_module_name(), + self.verifier.modulefilename) + except ImportError as e: + error = "importing %r: %s" % (self.verifier.modulefilename, e) + raise VerificationError(error) + finally: + if hasattr(sys, "setdlopenflags"): + sys.setdlopenflags(previous_flags) + finally: + imp.release_lock() + # + # call loading_cpy_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + # + # the C code will need the objects. Collect them in + # order in a list. + revmapping = dict([(value, key) + for (key, value) in self._typesdict.items()]) + lst = [revmapping[i] for i in range(len(revmapping))] + lst = list(map(self.ffi._get_cached_btype, lst)) + # + # build the FFILibrary class and instance and call _cffi_setup(). + # this will set up some fields like '_cffi_types', and only then + # it will invoke the chained list of functions that will really + # build (notably) the constant objects, as if they are + # pointers, and store them as attributes on the 'library' object. + class FFILibrary(object): + _cffi_python_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + list(self.__dict__) + library = FFILibrary() + if module._cffi_setup(lst, VerificationError, library): + import warnings + warnings.warn("reimporting %r might overwrite older definitions" + % (self.verifier.get_module_name())) + # + # finally, call the loaded_cpy_xxx() functions. This will perform + # the final adjustments, like copying the Python->C wrapper + # functions from the module to the 'library' object, and setting + # up the FFILibrary class with properties for the global C variables. + self._load(module, 'loaded', library=library) + module._cffi_original_ffi = self.ffi + module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_cpy_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + else: + converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''), + tp.name.replace(' ', '_')) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif isinstance(tp, (model.StructOrUnion, model.EnumType)): + # a struct (not a struct pointer) as a function argument + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars, freelines): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + 'alloca((size_t)datasize) : NULL;' % (tovar,)) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif tp.name != 'long double': + return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs: generates no code so far + + _generate_cpy_typedef_collecttype = _generate_nothing + _generate_cpy_typedef_decl = _generate_nothing + _generate_cpy_typedef_method = _generate_nothing + _loading_cpy_typedef = _loaded_noop + _loaded_cpy_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + self._do_collect_type(tp) + else: + # don't call _do_collect_type(tp) in this common case, + # otherwise test_autofilled_struct_as_argument fails + for type in tp.args: + self._do_collect_type(type) + self._do_collect_type(tp.result) + + def _generate_cpy_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + prnt(' %s;' % type.get_c_name(' x%d' % i, context)) + # + localvars = set() + freelines = set() + for type in tp.args: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + prnt(' %s;' % tp.result.get_c_name(' result', context)) + prnt(' PyObject *pyresult;') + else: + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_ParseTuple(args, "%s:%s", %s))' % ( + 'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + prnt(' { %s%s(%s); }' % ( + result_code, name, + ', '.join(['x%d' % i for i in range(len(tp.args))]))) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' pyresult = %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') + else: + for freeline in freelines: + prnt(' ' + freeline) + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + prnt() + + def _generate_cpy_function_method(self, tp, name): + if tp.ellipsis: + return + numargs = len(tp.args) + if numargs == 0: + meth = 'METH_NOARGS' + elif numargs == 1: + meth = 'METH_O' + else: + meth = 'METH_VARARGS' + self._prnt(' {"%s", _cffi_f_%s, %s, NULL},' % (name, name, meth)) + + _loading_cpy_function = _loaded_noop + + def _loaded_cpy_function(self, tp, name, module, library): + if tp.ellipsis: + return + func = getattr(module, name) + setattr(library, name, func) + self._types_of_builtin_functions[func] = tp + + # ---------- + # named structs + + _generate_cpy_struct_collecttype = _generate_nothing + def _generate_cpy_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + def _generate_cpy_struct_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'struct', name) + def _loading_cpy_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + def _loaded_cpy_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + _generate_cpy_union_collecttype = _generate_nothing + def _generate_cpy_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + def _generate_cpy_union_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'union', name) + def _loading_cpy_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + def _loaded_cpy_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('static PyObject *') + prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static Py_ssize_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' (void)self; /* unused */') + prnt(' (void)noarg; /* unused */') + prnt(' return _cffi_get_struct_layout(nums);') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _generate_struct_or_union_method(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + self._prnt(' {"%s", %s, METH_NOARGS, NULL},' % (layoutfuncname, + layoutfuncname)) + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + function = getattr(module, layoutfuncname) + layout = function() + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + _generate_cpy_anonymous_collecttype = _generate_nothing + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _generate_cpy_anonymous_method(self, tp, name): + if not isinstance(tp, model.EnumType): + self._generate_struct_or_union_method(tp, '', name) + + def _loading_cpy_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_cpy_enum(tp, name, module) + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_cpy_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_cpy_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + vartp=None, delayed=True, size_too=False, + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + prnt(' PyObject *o;') + prnt(' int res;') + if not is_int: + prnt(' %s;' % (vartp or tp).get_c_name(' i', name)) + else: + assert category == 'const' + # + if check_value is not None: + self._check_int_constant_value(name, check_value) + # + if not is_int: + if category == 'var': + realexpr = '&' + name + else: + realexpr = name + prnt(' i = (%s);' % (realexpr,)) + prnt(' o = %s;' % (self._convert_expr_from_c(tp, 'i', + 'variable type'),)) + assert delayed + else: + prnt(' o = _cffi_from_c_int_const(%s);' % name) + prnt(' if (o == NULL)') + prnt(' return -1;') + if size_too: + prnt(' {') + prnt(' PyObject *o1 = o;') + prnt(' o = Py_BuildValue("On", o1, (Py_ssize_t)sizeof(%s));' + % (name,)) + prnt(' Py_DECREF(o1);') + prnt(' if (o == NULL)') + prnt(' return -1;') + prnt(' }') + prnt(' res = PyObject_SetAttrString(lib, "%s", o);' % name) + prnt(' Py_DECREF(o);') + prnt(' if (res < 0)') + prnt(' return -1;') + prnt(' return %s;' % self._chained_list_constants[delayed]) + self._chained_list_constants[delayed] = funcname + '(lib)' + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + if not is_int: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + _generate_cpy_constant_method = _generate_nothing + _loading_cpy_constant = _loaded_noop + _loaded_cpy_constant = _loaded_noop + + # ---------- + # enums + + def _check_int_constant_value(self, name, value, err_prefix=''): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' % + name) + prnt(' PyErr_Format(_cffi_VerificationError,') + prnt(' "%s%s has the real value %s, not %s",') + prnt(' "%s", "%s", buf, "%d");' % ( + err_prefix, name, value)) + prnt(' return -1;') + prnt(' }') + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_cpy_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator, delayed=False) + return + # + funcname = self._enum_funcname(prefix, name) + prnt = self._prnt + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue, + "enum %s: " % name) + prnt(' return %s;' % self._chained_list_constants[True]) + self._chained_list_constants[True] = funcname + '(lib)' + prnt('}') + prnt() + + _generate_cpy_enum_collecttype = _generate_nothing + _generate_cpy_enum_method = _generate_nothing + + def _loading_cpy_enum(self, tp, name, module): + if tp.partial: + enumvalues = [getattr(module, enumerator) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + + def _loaded_cpy_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + _generate_cpy_macro_collecttype = _generate_nothing + _generate_cpy_macro_method = _generate_nothing + _loading_cpy_macro = _loaded_noop + _loaded_cpy_macro = _loaded_noop + + # ---------- + # global variables + + def _generate_cpy_variable_collecttype(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + else: + tp_ptr = model.PointerType(tp) + self._do_collect_type(tp_ptr) + + def _generate_cpy_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + self._generate_cpy_const(False, name, tp, vartp=tp_ptr, + size_too = tp.length_is_unknown()) + else: + tp_ptr = model.PointerType(tp) + self._generate_cpy_const(False, name, tp_ptr, category='var') + + _generate_cpy_variable_method = _generate_nothing + _loading_cpy_variable = _loaded_noop + + def _loaded_cpy_variable(self, tp, name, module, library): + value = getattr(library, name) + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length_is_unknown(): + assert isinstance(value, tuple) + (value, size) = value + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + ptr = value + delattr(library, name) + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + + # ---------- + + def _generate_setup_custom(self): + prnt = self._prnt + prnt('static int _cffi_setup_custom(PyObject *lib)') + prnt('{') + prnt(' return %s;' % self._chained_list_constants[True]) + prnt('}') + +cffimod_header = r''' +#include +#include + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#if PY_MAJOR_VERSION < 3 +# undef PyCapsule_CheckExact +# undef PyCapsule_GetPointer +# define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) +# define PyCapsule_GetPointer(capsule, name) \ + (PyCObject_AsVoidPtr(capsule)) +#endif + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int_const(x) \ + (((x) > 0) ? \ + ((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromUnsignedLongLong((unsigned long long)(x)) : \ + ((long long)(x) >= (long long)LONG_MIN) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromLongLong((long long)(x))) + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + ((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12]) +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24]) +#define _CFFI_NUM_EXPORTS 25 + +typedef struct _ctypedescr CTypeDescrObject; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; +static PyObject *_cffi_types, *_cffi_VerificationError; + +static int _cffi_setup_custom(PyObject *lib); /* forward */ + +static PyObject *_cffi_setup(PyObject *self, PyObject *args) +{ + PyObject *library; + int was_alive = (_cffi_types != NULL); + (void)self; /* unused */ + if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError, + &library)) + return NULL; + Py_INCREF(_cffi_types); + Py_INCREF(_cffi_VerificationError); + if (_cffi_setup_custom(library) < 0) + return NULL; + return PyBool_FromLong(was_alive); +} + +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static int _cffi_convert_array_argument(CTypeDescrObject *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static void _cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} + +static int _cffi_init(void) +{ + PyObject *module, *c_api_object = NULL; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + c_api_object = PyObject_GetAttrString(module, "_C_API"); + if (c_api_object == NULL) + goto failure; + if (!PyCapsule_CheckExact(c_api_object)) { + PyErr_SetNone(PyExc_ImportError); + goto failure; + } + memcpy(_cffi_exports, PyCapsule_GetPointer(c_api_object, "cffi"), + _CFFI_NUM_EXPORTS * sizeof(void *)); + + Py_DECREF(module); + Py_DECREF(c_api_object); + return 0; + + failure: + Py_XDECREF(module); + Py_XDECREF(c_api_object); + return -1; +} + +#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num)) + +/**********/ +''' diff --git a/uno/lib/python/cffi/vengine_gen.py b/uno/lib/python/cffi/vengine_gen.py new file mode 100644 index 00000000..72e144de --- /dev/null +++ b/uno/lib/python/cffi/vengine_gen.py @@ -0,0 +1,675 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os +import types + +from . import model +from .error import VerificationError + + +class VGenericEngine(object): + _class_key = 'g' + _gen_python_module = False + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self.export_symbols = [] + self._struct_pending_verification = {} + + def patch_extension_kwds(self, kwds): + # add 'export_symbols' to the dictionary. Note that we add the + # list before filling it. When we fill it, it will thus also show + # up in kwds['export_symbols']. + kwds.setdefault('export_symbols', self.export_symbols) + + def find_module(self, module_name, path, so_suffixes): + for so_suffix in so_suffixes: + basename = module_name + so_suffix + if path is None: + path = sys.path + for dirname in path: + filename = os.path.join(dirname, basename) + if os.path.isfile(filename): + return filename + + def collect_types(self): + pass # not needed in the generic engine + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self): + prnt = self._prnt + # first paste some standard set of lines that are mostly '#include' + prnt(cffimod_header) + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + # + # call generate_gen_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate('decl') + # + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + if sys.platform == 'win32': + if sys.version_info >= (3,): + prefix = 'PyInit_' + else: + prefix = 'init' + modname = self.verifier.get_module_name() + prnt("void %s%s(void) { }\n" % (prefix, modname)) + + def load_library(self, flags=0): + # import it with the CFFI backend + backend = self.ffi._backend + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename, flags) + # + # call loading_gen_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + + # build the FFILibrary class and instance, this is a module subclass + # because modules are expected to have usually-constant-attributes and + # in PyPy this means the JIT is able to treat attributes as constant, + # which we want. + class FFILibrary(types.ModuleType): + _cffi_generic_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + library = FFILibrary("") + # + # finally, call the loaded_gen_xxx() functions. This will set + # up the 'library' object. + self._load(module, 'loaded', library=library) + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_gen_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_gen_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + # typedefs: generates no code so far + + _generate_gen_typedef_decl = _generate_nothing + _loading_gen_typedef = _loaded_noop + _loaded_gen_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_gen_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no _cffi_f_%s wrapper) + self._generate_gen_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + argnames = [] + for i, type in enumerate(tp.args): + indirection = '' + if isinstance(type, model.StructOrUnion): + indirection = '*' + argnames.append('%sx%d' % (indirection, i)) + context = 'argument of %s' % name + arglist = [type.get_c_name(' %s' % arg, context) + for type, arg in zip(tp.args, argnames)] + tpresult = tp.result + if isinstance(tpresult, model.StructOrUnion): + arglist.insert(0, tpresult.get_c_name(' *r', context)) + tpresult = model.void_type + arglist = ', '.join(arglist) or 'void' + wrappername = '_cffi_f_%s' % name + self.export_symbols.append(wrappername) + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + funcdecl = ' %s%s(%s)' % (abi, wrappername, arglist) + context = 'result of %s' % name + prnt(tpresult.get_c_name(funcdecl, context)) + prnt('{') + # + if isinstance(tp.result, model.StructOrUnion): + result_code = '*r = ' + elif not isinstance(tp.result, model.VoidType): + result_code = 'return ' + else: + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames))) + prnt('}') + prnt() + + _loading_gen_function = _loaded_noop + + def _loaded_gen_function(self, tp, name, module, library): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + newfunction = self._load_constant(False, tp, name, module) + else: + indirections = [] + base_tp = tp + if (any(isinstance(typ, model.StructOrUnion) for typ in tp.args) + or isinstance(tp.result, model.StructOrUnion)): + indirect_args = [] + for i, typ in enumerate(tp.args): + if isinstance(typ, model.StructOrUnion): + typ = model.PointerType(typ) + indirections.append((i, typ)) + indirect_args.append(typ) + indirect_result = tp.result + if isinstance(indirect_result, model.StructOrUnion): + if indirect_result.fldtypes is None: + raise TypeError("'%s' is used as result type, " + "but is opaque" % ( + indirect_result._get_c_name(),)) + indirect_result = model.PointerType(indirect_result) + indirect_args.insert(0, indirect_result) + indirections.insert(0, ("result", indirect_result)) + indirect_result = model.void_type + tp = model.FunctionPtrType(tuple(indirect_args), + indirect_result, tp.ellipsis) + BFunc = self.ffi._get_cached_btype(tp) + wrappername = '_cffi_f_%s' % name + newfunction = module.load_function(BFunc, wrappername) + for i, typ in indirections: + newfunction = self._make_struct_wrapper(newfunction, i, typ, + base_tp) + setattr(library, name, newfunction) + type(library)._cffi_dir.append(name) + + def _make_struct_wrapper(self, oldfunc, i, tp, base_tp): + backend = self.ffi._backend + BType = self.ffi._get_cached_btype(tp) + if i == "result": + ffi = self.ffi + def newfunc(*args): + res = ffi.new(BType) + oldfunc(res, *args) + return res[0] + else: + def newfunc(*args): + args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] + return oldfunc(*args) + newfunc._cffi_base_type = base_tp + return newfunc + + # ---------- + # named structs + + def _generate_gen_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + + def _loading_gen_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + + def _loaded_gen_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_gen_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + + def _loading_gen_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + + def _loaded_gen_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + self.export_symbols.append(layoutfuncname) + prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static intptr_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' return nums[i];') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0] + function = module.load_function(BFunc, layoutfuncname) + layout = [] + num = 0 + while True: + x = function(num) + if x < 0: break + layout.append(x) + num += 1 + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_gen_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_gen_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _loading_gen_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_gen_enum(tp, name, module, '') + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_gen_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_gen_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_gen_const(self, is_int, name, tp=None, category='const', + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + self.export_symbols.append(funcname) + if check_value is not None: + assert is_int + assert category == 'const' + prnt('int %s(char *out_error)' % funcname) + prnt('{') + self._check_int_constant_value(name, check_value) + prnt(' return 0;') + prnt('}') + elif is_int: + assert category == 'const' + prnt('int %s(long long *out_value)' % funcname) + prnt('{') + prnt(' *out_value = (long long)(%s);' % (name,)) + prnt(' return (%s) <= 0;' % (name,)) + prnt('}') + else: + assert tp is not None + assert check_value is None + if category == 'var': + ampersand = '&' + else: + ampersand = '' + extra = '' + if category == 'const' and isinstance(tp, model.StructOrUnion): + extra = 'const *' + ampersand = '&' + prnt(tp.get_c_name(' %s%s(void)' % (extra, funcname), name)) + prnt('{') + prnt(' return (%s%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_gen_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_gen_const(is_int, name, tp) + + _loading_gen_constant = _loaded_noop + + def _load_constant(self, is_int, tp, name, module, check_value=None): + funcname = '_cffi_const_%s' % name + if check_value is not None: + assert is_int + self._load_known_int_constant(module, funcname) + value = check_value + elif is_int: + BType = self.ffi._typeof_locked("long long*")[0] + BFunc = self.ffi._typeof_locked("int(*)(long long*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType) + negative = function(p) + value = int(p[0]) + if value < 0 and not negative: + BLongLong = self.ffi._typeof_locked("long long")[0] + value += (1 << (8*self.ffi.sizeof(BLongLong))) + else: + assert check_value is None + fntypeextra = '(*)(void)' + if isinstance(tp, model.StructOrUnion): + fntypeextra = '*' + fntypeextra + BFunc = self.ffi._typeof_locked(tp.get_c_name(fntypeextra, name))[0] + function = module.load_function(BFunc, funcname) + value = function() + if isinstance(tp, model.StructOrUnion): + value = value[0] + return value + + def _loaded_gen_constant(self, tp, name, module, library): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + value = self._load_constant(is_int, tp, name, module) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # enums + + def _check_int_constant_value(self, name, value): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' sprintf(buf, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' % + name) + prnt(' sprintf(out_error, "%s has the real value %s, not %s",') + prnt(' "%s", buf, "%d");' % (name[:100], value)) + prnt(' return -1;') + prnt(' }') + + def _load_known_int_constant(self, module, funcname): + BType = self.ffi._typeof_locked("char[]")[0] + BFunc = self.ffi._typeof_locked("int(*)(char*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType, 256) + if function(p) < 0: + error = self.ffi.string(p) + if sys.version_info >= (3,): + error = str(error, 'utf-8') + raise VerificationError(error) + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_gen_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_gen_const(True, enumerator) + return + # + funcname = self._enum_funcname(prefix, name) + self.export_symbols.append(funcname) + prnt = self._prnt + prnt('int %s(char *out_error)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue) + prnt(' return 0;') + prnt('}') + prnt() + + def _loading_gen_enum(self, tp, name, module, prefix='enum'): + if tp.partial: + enumvalues = [self._load_constant(True, tp, enumerator, module) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + else: + funcname = self._enum_funcname(prefix, name) + self._load_known_int_constant(module, funcname) + + def _loaded_gen_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + type(library)._cffi_dir.append(enumerator) + + # ---------- + # macros: for now only for integers + + def _generate_gen_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_gen_const(True, name, check_value=check_value) + + _loading_gen_macro = _loaded_noop + + def _loaded_gen_macro(self, tp, name, module, library): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + value = self._load_constant(True, tp, name, module, + check_value=check_value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # global variables + + def _generate_gen_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + if tp.length_is_unknown(): + prnt = self._prnt + funcname = '_cffi_sizeof_%s' % (name,) + self.export_symbols.append(funcname) + prnt("size_t %s(void)" % funcname) + prnt("{") + prnt(" return sizeof(%s);" % (name,)) + prnt("}") + tp_ptr = model.PointerType(tp.item) + self._generate_gen_const(False, name, tp_ptr) + else: + tp_ptr = model.PointerType(tp) + self._generate_gen_const(False, name, tp_ptr, category='var') + + _loading_gen_variable = _loaded_noop + + def _loaded_gen_variable(self, tp, name, module, library): + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length_is_unknown(): + funcname = '_cffi_sizeof_%s' % (name,) + BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0] + function = module.load_function(BFunc, funcname) + size = function() + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + tp_ptr = model.PointerType(tp.item) + value = self._load_constant(False, tp_ptr, name, module) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + funcname = '_cffi_var_%s' % name + BFunc = self.ffi._typeof_locked(tp.get_c_name('*(*)(void)', name))[0] + function = module.load_function(BFunc, funcname) + ptr = function() + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + +cffimod_header = r''' +#include +#include +#include +#include +#include /* XXX for ssize_t on some platforms */ + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif +''' diff --git a/uno/lib/python/cffi/verifier.py b/uno/lib/python/cffi/verifier.py new file mode 100644 index 00000000..108c1b9c --- /dev/null +++ b/uno/lib/python/cffi/verifier.py @@ -0,0 +1,306 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os, binascii, shutil, io +from . import __version_verifier_modules__ +from . import ffiplatform +from .error import VerificationError + +if sys.version_info >= (3, 3): + import importlib.machinery + def _extension_suffixes(): + return importlib.machinery.EXTENSION_SUFFIXES[:] +else: + import imp + def _extension_suffixes(): + return [suffix for suffix, _, type in imp.get_suffixes() + if type == imp.C_EXTENSION] + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + + +class Verifier(object): + + def __init__(self, ffi, preamble, tmpdir=None, modulename=None, + ext_package=None, tag='', force_generic_engine=False, + source_extension='.c', flags=None, relative_to=None, **kwds): + if ffi._parser._uses_new_feature: + raise VerificationError( + "feature not supported with ffi.verify(), but only " + "with ffi.set_source(): %s" % (ffi._parser._uses_new_feature,)) + self.ffi = ffi + self.preamble = preamble + if not modulename: + flattened_kwds = ffiplatform.flatten(kwds) + vengine_class = _locate_engine_class(ffi, force_generic_engine) + self._vengine = vengine_class(self) + self._vengine.patch_extension_kwds(kwds) + self.flags = flags + self.kwds = self.make_relative_to(kwds, relative_to) + # + if modulename: + if tag: + raise TypeError("can't specify both 'modulename' and 'tag'") + else: + key = '\x00'.join(['%d.%d' % sys.version_info[:2], + __version_verifier_modules__, + preamble, flattened_kwds] + + ffi._cdefsources) + if sys.version_info >= (3,): + key = key.encode('utf-8') + k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff) + k1 = k1.lstrip('0x').rstrip('L') + k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff) + k2 = k2.lstrip('0').rstrip('L') + modulename = '_cffi_%s_%s%s%s' % (tag, self._vengine._class_key, + k1, k2) + suffix = _get_so_suffixes()[0] + self.tmpdir = tmpdir or _caller_dir_pycache() + self.sourcefilename = os.path.join(self.tmpdir, modulename + source_extension) + self.modulefilename = os.path.join(self.tmpdir, modulename + suffix) + self.ext_package = ext_package + self._has_source = False + self._has_module = False + + def write_source(self, file=None): + """Write the C source code. It is produced in 'self.sourcefilename', + which can be tweaked beforehand.""" + with self.ffi._lock: + if self._has_source and file is None: + raise VerificationError( + "source code already written") + self._write_source(file) + + def compile_module(self): + """Write the C source code (if not done already) and compile it. + This produces a dynamic link library in 'self.modulefilename'.""" + with self.ffi._lock: + if self._has_module: + raise VerificationError("module already compiled") + if not self._has_source: + self._write_source() + self._compile_module() + + def load_library(self): + """Get a C module from this Verifier instance. + Returns an instance of a FFILibrary class that behaves like the + objects returned by ffi.dlopen(), but that delegates all + operations to the C module. If necessary, the C code is written + and compiled first. + """ + with self.ffi._lock: + if not self._has_module: + self._locate_module() + if not self._has_module: + if not self._has_source: + self._write_source() + self._compile_module() + return self._load_library() + + def get_module_name(self): + basename = os.path.basename(self.modulefilename) + # kill both the .so extension and the other .'s, as introduced + # by Python 3: 'basename.cpython-33m.so' + basename = basename.split('.', 1)[0] + # and the _d added in Python 2 debug builds --- but try to be + # conservative and not kill a legitimate _d + if basename.endswith('_d') and hasattr(sys, 'gettotalrefcount'): + basename = basename[:-2] + return basename + + def get_extension(self): + if not self._has_source: + with self.ffi._lock: + if not self._has_source: + self._write_source() + sourcename = ffiplatform.maybe_relative_path(self.sourcefilename) + modname = self.get_module_name() + return ffiplatform.get_extension(sourcename, modname, **self.kwds) + + def generates_python_module(self): + return self._vengine._gen_python_module + + def make_relative_to(self, kwds, relative_to): + if relative_to and os.path.dirname(relative_to): + dirname = os.path.dirname(relative_to) + kwds = kwds.copy() + for key in ffiplatform.LIST_OF_FILE_NAMES: + if key in kwds: + lst = kwds[key] + if not isinstance(lst, (list, tuple)): + raise TypeError("keyword '%s' should be a list or tuple" + % (key,)) + lst = [os.path.join(dirname, fn) for fn in lst] + kwds[key] = lst + return kwds + + # ---------- + + def _locate_module(self): + if not os.path.isfile(self.modulefilename): + if self.ext_package: + try: + pkg = __import__(self.ext_package, None, None, ['__doc__']) + except ImportError: + return # cannot import the package itself, give up + # (e.g. it might be called differently before installation) + path = pkg.__path__ + else: + path = None + filename = self._vengine.find_module(self.get_module_name(), path, + _get_so_suffixes()) + if filename is None: + return + self.modulefilename = filename + self._vengine.collect_types() + self._has_module = True + + def _write_source_to(self, file): + self._vengine._f = file + try: + self._vengine.write_source_to_f() + finally: + del self._vengine._f + + def _write_source(self, file=None): + if file is not None: + self._write_source_to(file) + else: + # Write our source file to an in memory file. + f = NativeIO() + self._write_source_to(f) + source_data = f.getvalue() + + # Determine if this matches the current file + if os.path.exists(self.sourcefilename): + with open(self.sourcefilename, "r") as fp: + needs_written = not (fp.read() == source_data) + else: + needs_written = True + + # Actually write the file out if it doesn't match + if needs_written: + _ensure_dir(self.sourcefilename) + with open(self.sourcefilename, "w") as fp: + fp.write(source_data) + + # Set this flag + self._has_source = True + + def _compile_module(self): + # compile this C source + tmpdir = os.path.dirname(self.sourcefilename) + outputfilename = ffiplatform.compile(tmpdir, self.get_extension()) + try: + same = ffiplatform.samefile(outputfilename, self.modulefilename) + except OSError: + same = False + if not same: + _ensure_dir(self.modulefilename) + shutil.move(outputfilename, self.modulefilename) + self._has_module = True + + def _load_library(self): + assert self._has_module + if self.flags is not None: + return self._vengine.load_library(self.flags) + else: + return self._vengine.load_library() + +# ____________________________________________________________ + +_FORCE_GENERIC_ENGINE = False # for tests + +def _locate_engine_class(ffi, force_generic_engine): + if _FORCE_GENERIC_ENGINE: + force_generic_engine = True + if not force_generic_engine: + if '__pypy__' in sys.builtin_module_names: + force_generic_engine = True + else: + try: + import _cffi_backend + except ImportError: + _cffi_backend = '?' + if ffi._backend is not _cffi_backend: + force_generic_engine = True + if force_generic_engine: + from . import vengine_gen + return vengine_gen.VGenericEngine + else: + from . import vengine_cpy + return vengine_cpy.VCPythonEngine + +# ____________________________________________________________ + +_TMPDIR = None + +def _caller_dir_pycache(): + if _TMPDIR: + return _TMPDIR + result = os.environ.get('CFFI_TMPDIR') + if result: + return result + filename = sys._getframe(2).f_code.co_filename + return os.path.abspath(os.path.join(os.path.dirname(filename), + '__pycache__')) + +def set_tmpdir(dirname): + """Set the temporary directory to use instead of __pycache__.""" + global _TMPDIR + _TMPDIR = dirname + +def cleanup_tmpdir(tmpdir=None, keep_so=False): + """Clean up the temporary directory by removing all files in it + called `_cffi_*.{c,so}` as well as the `build` subdirectory.""" + tmpdir = tmpdir or _caller_dir_pycache() + try: + filelist = os.listdir(tmpdir) + except OSError: + return + if keep_so: + suffix = '.c' # only remove .c files + else: + suffix = _get_so_suffixes()[0].lower() + for fn in filelist: + if fn.lower().startswith('_cffi_') and ( + fn.lower().endswith(suffix) or fn.lower().endswith('.c')): + try: + os.unlink(os.path.join(tmpdir, fn)) + except OSError: + pass + clean_dir = [os.path.join(tmpdir, 'build')] + for dir in clean_dir: + try: + for fn in os.listdir(dir): + fn = os.path.join(dir, fn) + if os.path.isdir(fn): + clean_dir.append(fn) + else: + os.unlink(fn) + except OSError: + pass + +def _get_so_suffixes(): + suffixes = _extension_suffixes() + if not suffixes: + # bah, no C_EXTENSION available. Occurs on pypy without cpyext + if sys.platform == 'win32': + suffixes = [".pyd"] + else: + suffixes = [".so"] + + return suffixes + +def _ensure_dir(filename): + dirname = os.path.dirname(filename) + if dirname and not os.path.isdir(dirname): + os.makedirs(dirname) diff --git a/uno/lib/python/pkg_resources/__init__.py b/uno/lib/python/pkg_resources/__init__.py index 955fdc48..ab6afe95 100644 --- a/uno/lib/python/pkg_resources/__init__.py +++ b/uno/lib/python/pkg_resources/__init__.py @@ -12,6 +12,9 @@ .egg files, and unpacked .egg files. It can also work in a limited way with .zip files and with custom PEP 302 loaders that support the ``get_data()`` method. + +This module is deprecated. Users are directed to :mod:`importlib.resources`, +:mod:`importlib.metadata` and :pypi:`packaging` instead. """ import sys @@ -34,7 +37,6 @@ import errno import tempfile import textwrap -import itertools import inspect import ntpath import posixpath @@ -54,8 +56,10 @@ # capture these to bypass sandboxing from os import utime + try: from os import mkdir, rename, unlink + WRITE_SUPPORT = True except ImportError: # no write support, probably under GAE @@ -66,17 +70,26 @@ try: import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. importlib_machinery.__name__ except ImportError: importlib_machinery = None -from pkg_resources.extern import appdirs +from pkg_resources.extern.jaraco.text import ( + yield_lines, + drop_comment, + join_continuation, +) + +from pkg_resources.extern import platformdirs from pkg_resources.extern import packaging + __import__('pkg_resources.extern.packaging.version') __import__('pkg_resources.extern.packaging.specifiers') __import__('pkg_resources.extern.packaging.requirements') __import__('pkg_resources.extern.packaging.markers') +__import__('pkg_resources.extern.packaging.utils') if sys.version_info < (3, 5): raise RuntimeError("Python 3.5 or later is required") @@ -102,6 +115,17 @@ _namespace_packages = None +warnings.warn( + "pkg_resources is deprecated as an API. " + "See https://setuptools.pypa.io/en/latest/pkg_resources.html", + DeprecationWarning, + stacklevel=2, +) + + +_PEP440_FALLBACK = re.compile(r"^v?(?P(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.I) + + class PEP440Warning(RuntimeWarning): """ Used when there is an issue with a version or specifier not complying with @@ -109,16 +133,7 @@ class PEP440Warning(RuntimeWarning): """ -def parse_version(v): - try: - return packaging.version.Version(v) - except packaging.version.InvalidVersion: - warnings.warn( - f"{v} is an invalid version and will not be supported in " - "a future release", - PkgResourcesDeprecationWarning, - ) - return packaging.version.LegacyVersion(v) +parse_version = packaging.version.Version _state_vars = {} @@ -190,51 +205,87 @@ def get_supported_platform(): __all__ = [ # Basic resource access and distribution/entry point discovery - 'require', 'run_script', 'get_provider', 'get_distribution', - 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'require', + 'run_script', + 'get_provider', + 'get_distribution', + 'load_entry_point', + 'get_entry_map', + 'get_entry_info', 'iter_entry_points', - 'resource_string', 'resource_stream', 'resource_filename', - 'resource_listdir', 'resource_exists', 'resource_isdir', - + 'resource_string', + 'resource_stream', + 'resource_filename', + 'resource_listdir', + 'resource_exists', + 'resource_isdir', # Environmental control - 'declare_namespace', 'working_set', 'add_activation_listener', - 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'declare_namespace', + 'working_set', + 'add_activation_listener', + 'find_distributions', + 'set_extraction_path', + 'cleanup_resources', 'get_default_cache', - # Primary implementation classes - 'Environment', 'WorkingSet', 'ResourceManager', - 'Distribution', 'Requirement', 'EntryPoint', - + 'Environment', + 'WorkingSet', + 'ResourceManager', + 'Distribution', + 'Requirement', + 'EntryPoint', # Exceptions - 'ResolutionError', 'VersionConflict', 'DistributionNotFound', - 'UnknownExtra', 'ExtractionError', - + 'ResolutionError', + 'VersionConflict', + 'DistributionNotFound', + 'UnknownExtra', + 'ExtractionError', # Warnings 'PEP440Warning', - # Parsing functions and string utilities - 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', - 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', - 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', - + 'parse_requirements', + 'parse_version', + 'safe_name', + 'safe_version', + 'get_platform', + 'compatible_platforms', + 'yield_lines', + 'split_sections', + 'safe_extra', + 'to_filename', + 'invalid_marker', + 'evaluate_marker', # filesystem utilities - 'ensure_directory', 'normalize_path', - + 'ensure_directory', + 'normalize_path', # Distribution "precedence" constants - 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', - + 'EGG_DIST', + 'BINARY_DIST', + 'SOURCE_DIST', + 'CHECKOUT_DIST', + 'DEVELOP_DIST', # "Provider" interfaces, implementations, and registration/lookup APIs - 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', - 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', - 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', - 'register_finder', 'register_namespace_handler', 'register_loader_type', - 'fixup_namespace_packages', 'get_importer', - + 'IMetadataProvider', + 'IResourceProvider', + 'FileMetadata', + 'PathMetadata', + 'EggMetadata', + 'EmptyProvider', + 'empty_provider', + 'NullProvider', + 'EggProvider', + 'DefaultProvider', + 'ZipProvider', + 'register_finder', + 'register_namespace_handler', + 'register_loader_type', + 'fixup_namespace_packages', + 'get_importer', # Warnings 'PkgResourcesDeprecationWarning', - # Deprecated/backward compatibility only - 'run_main', 'AvailableDistributions', + 'run_main', + 'AvailableDistributions', ] @@ -293,8 +344,10 @@ def required_by(self): class DistributionNotFound(ResolutionError): """A requested distribution was not found""" - _template = ("The '{self.req}' distribution was not found " - "and is required by {self.requirers_str}") + _template = ( + "The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}" + ) @property def req(self): @@ -388,7 +441,8 @@ def get_build_platform(): version = _macos_vers() machine = os.uname()[4].replace(" ", "_") return "macosx-%d.%d-%s" % ( - int(version[0]), int(version[1]), + int(version[0]), + int(version[1]), _macos_arch(machine), ) except ValueError: @@ -429,15 +483,18 @@ def compatible_platforms(provided, required): if provDarwin: dversion = int(provDarwin.group(1)) macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) - if dversion == 7 and macosversion >= "10.3" or \ - dversion == 8 and macosversion >= "10.4": + if ( + dversion == 7 + and macosversion >= "10.3" + or dversion == 8 + and macosversion >= "10.4" + ): return True # egg isn't macOS or legacy darwin return False # are they the same major version and machine type? - if provMac.group(1) != reqMac.group(1) or \ - provMac.group(3) != reqMac.group(3): + if provMac.group(1) != reqMac.group(1) or provMac.group(3) != reqMac.group(3): return False # is the required OS major update >= the provided one? @@ -499,8 +556,8 @@ def get_metadata(name): def get_metadata_lines(name): """Yield named metadata resource as list of non-blank non-comment lines - Leading and trailing whitespace is stripped from each line, and lines - with ``#`` as the first non-blank character are omitted.""" + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" def metadata_isdir(name): """Is the named metadata a directory? (like ``os.path.isdir()``)""" @@ -548,6 +605,7 @@ def __init__(self, entries=None): self.entries = [] self.entry_keys = {} self.by_key = {} + self.normalized_to_canonical_keys = {} self.callbacks = [] if entries is None: @@ -628,6 +686,14 @@ def find(self, req): is returned. """ dist = self.by_key.get(req.key) + + if dist is None: + canonical_key = self.normalized_to_canonical_keys.get(req.key) + + if canonical_key is not None: + req.key = canonical_key + dist = self.by_key.get(canonical_key) + if dist is not None and dist not in req: # XXX add more info raise VersionConflict(dist, req) @@ -696,15 +762,22 @@ def add(self, dist, entry=None, insert=True, replace=False): return self.by_key[dist.key] = dist + normalized_name = packaging.utils.canonicalize_name(dist.key) + self.normalized_to_canonical_keys[normalized_name] = dist.key if dist.key not in keys: keys.append(dist.key) if dist.key not in keys2: keys2.append(dist.key) self._added_new(dist) - # FIXME: 'WorkingSet.resolve' is too complex (11) - def resolve(self, requirements, env=None, installer=None, # noqa: C901 - replace_conflicting=False, extras=None): + def resolve( + self, + requirements, + env=None, + installer=None, + replace_conflicting=False, + extras=None, + ): """List all distributions needed to (recursively) meet `requirements` `requirements` must be a sequence of ``Requirement`` objects. `env`, @@ -753,33 +826,9 @@ def resolve(self, requirements, env=None, installer=None, # noqa: C901 if not req_extras.markers_pass(req, extras): continue - dist = best.get(req.key) - if dist is None: - # Find the best distribution and add it to the map - dist = self.by_key.get(req.key) - if dist is None or (dist not in req and replace_conflicting): - ws = self - if env is None: - if dist is None: - env = Environment(self.entries) - else: - # Use an empty environment and workingset to avoid - # any further conflicts with the conflicting - # distribution - env = Environment([]) - ws = WorkingSet([]) - dist = best[req.key] = env.best_match( - req, ws, installer, - replace_conflicting=replace_conflicting - ) - if dist is None: - requirers = required_by.get(req, None) - raise DistributionNotFound(req, requirers) - to_activate.append(dist) - if dist not in req: - # Oops, the "best" so far conflicts with a dependency - dependent_req = required_by[req] - raise VersionConflict(dist, req).with_context(dependent_req) + dist = self._resolve_dist( + req, best, replace_conflicting, env, installer, required_by, to_activate + ) # push the new requirements onto the stack new_requirements = dist.requires(req.extras)[::-1] @@ -795,8 +844,38 @@ def resolve(self, requirements, env=None, installer=None, # noqa: C901 # return list of distros to activate return to_activate - def find_plugins( - self, plugin_env, full_env=None, installer=None, fallback=True): + def _resolve_dist( + self, req, best, replace_conflicting, env, installer, required_by, to_activate + ): + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + return dist + + def find_plugins(self, plugin_env, full_env=None, installer=None, fallback=True): """Find all activatable distributions in `plugin_env` Example usage:: @@ -849,9 +928,7 @@ def find_plugins( list(map(shadow_set.add, self)) for project_name in plugin_projects: - for dist in plugin_env[project_name]: - req = [dist.as_requirement()] try: @@ -915,15 +992,19 @@ def _added_new(self, dist): def __getstate__(self): return ( - self.entries[:], self.entry_keys.copy(), self.by_key.copy(), - self.callbacks[:] + self.entries[:], + self.entry_keys.copy(), + self.by_key.copy(), + self.normalized_to_canonical_keys.copy(), + self.callbacks[:], ) - def __setstate__(self, e_k_b_c): - entries, keys, by_key, callbacks = e_k_b_c + def __setstate__(self, e_k_b_n_c): + entries, keys, by_key, normalized_to_canonical_keys, callbacks = e_k_b_n_c self.entries = entries[:] self.entry_keys = keys.copy() self.by_key = by_key.copy() + self.normalized_to_canonical_keys = normalized_to_canonical_keys.copy() self.callbacks = callbacks[:] @@ -951,8 +1032,8 @@ class Environment: """Searchable snapshot of distributions on a search path""" def __init__( - self, search_path=None, platform=get_supported_platform(), - python=PY_MAJOR): + self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR + ): """Snapshot distributions available on a search path Any distributions found on `search_path` are added to the environment. @@ -1019,16 +1100,14 @@ def __getitem__(self, project_name): return self._distmap.get(distribution_key, []) def add(self, dist): - """Add `dist` if we ``can_add()`` it and it has not already been added - """ + """Add `dist` if we ``can_add()`` it and it has not already been added""" if self.can_add(dist) and dist.has_version(): dists = self._distmap.setdefault(dist.key, []) if dist not in dists: dists.append(dist) dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) - def best_match( - self, req, working_set, installer=None, replace_conflicting=False): + def best_match(self, req, working_set, installer=None, replace_conflicting=False): """Find distribution best matching `req` and usable on `working_set` This calls the ``find(req)`` method of the `working_set` to see if a @@ -1115,6 +1194,7 @@ class ExtractionError(RuntimeError): class ResourceManager: """Manage resource extraction and packages""" + extraction_path = None def __init__(self): @@ -1126,9 +1206,7 @@ def resource_exists(self, package_or_requirement, resource_name): def resource_isdir(self, package_or_requirement, resource_name): """Is the named resource an existing directory?""" - return get_provider(package_or_requirement).resource_isdir( - resource_name - ) + return get_provider(package_or_requirement).resource_isdir(resource_name) def resource_filename(self, package_or_requirement, resource_name): """Return a true filesystem path for specified resource""" @@ -1150,9 +1228,7 @@ def resource_string(self, package_or_requirement, resource_name): def resource_listdir(self, package_or_requirement, resource_name): """List the contents of the named resource directory""" - return get_provider(package_or_requirement).resource_listdir( - resource_name - ) + return get_provider(package_or_requirement).resource_listdir(resource_name) def extraction_error(self): """Give an error message for problems extracting file(s)""" @@ -1160,7 +1236,8 @@ def extraction_error(self): old_exc = sys.exc_info()[1] cache_path = self.extraction_path or get_default_cache() - tmpl = textwrap.dedent(""" + tmpl = textwrap.dedent( + """ Can't extract file(s) to egg cache The following error occurred while trying to extract file(s) @@ -1175,7 +1252,8 @@ def extraction_error(self): Perhaps your account does not have write access to this directory? You can change the cache directory by setting the PYTHON_EGG_CACHE environment variable to point to an accessible directory. - """).lstrip() + """ + ).lstrip() err = ExtractionError(tmpl.format(**locals())) err.manager = self err.cache_path = cache_path @@ -1274,9 +1352,7 @@ def set_extraction_path(self, path): ``cleanup_resources()``.) """ if self.cached_files: - raise ValueError( - "Can't change extraction path, files already extracted" - ) + raise ValueError("Can't change extraction path, files already extracted") self.extraction_path = path @@ -1300,9 +1376,8 @@ def get_default_cache(): or a platform-relevant user cache dir for an app named "Python-Eggs". """ - return ( - os.environ.get('PYTHON_EGG_CACHE') - or appdirs.user_cache_dir(appname='Python-Eggs') + return os.environ.get('PYTHON_EGG_CACHE') or platformdirs.user_cache_dir( + appname='Python-Eggs' ) @@ -1326,6 +1401,38 @@ def safe_version(version): return re.sub('[^A-Za-z0-9.]+', '-', version) +def _forgiving_version(version): + """Fallback when ``safe_version`` is not safe enough + >>> parse_version(_forgiving_version('0.23ubuntu1')) + + >>> parse_version(_forgiving_version('0.23-')) + + >>> parse_version(_forgiving_version('0.-_')) + + >>> parse_version(_forgiving_version('42.+?1')) + + >>> parse_version(_forgiving_version('hello world')) + + """ + version = version.replace(' ', '.') + match = _PEP440_FALLBACK.search(version) + if match: + safe = match["safe"] + rest = version[len(safe) :] + else: + safe = "0" + rest = version + local = f"sanitized.{_safe_segment(rest)}".strip(".") + return f"{safe}.dev0+{local}" + + +def _safe_segment(segment): + """Convert an arbitrary string into a safe segment""" + segment = re.sub('[^A-Za-z0-9.]+', '-', segment) + segment = re.sub('-[^A-Za-z0-9]+', '-', segment) + return re.sub(r'\.[^A-Za-z0-9]+', '.', segment).strip(".-") + + def safe_extra(extra): """Convert an arbitrary string to a standard 'extra' name @@ -1439,8 +1546,9 @@ def run_script(self, script_name, namespace): script = 'scripts/' + script_name if not self.has_metadata(script): raise ResolutionError( - "Script {script!r} not found in metadata at {self.egg_info!r}" - .format(**locals()), + "Script {script!r} not found in metadata at {self.egg_info!r}".format( + **locals() + ), ) script_text = self.get_metadata(script).replace('\r\n', '\n') script_text = script_text.replace('\r', '\n') @@ -1453,8 +1561,12 @@ def run_script(self, script_name, namespace): exec(code, namespace, namespace) else: from linecache import cache + cache[script_filename] = ( - len(script_text), 0, script_text.split('\n'), script_filename + len(script_text), + 0, + script_text.split('\n'), + script_filename, ) script_code = compile(script_text, script_filename, 'exec') exec(script_code, namespace, namespace) @@ -1534,9 +1646,9 @@ def _validate_resource_path(path): AttributeError: ... """ invalid = ( - os.path.pardir in path.split(posixpath.sep) or - posixpath.isabs(path) or - ntpath.isabs(path) + os.path.pardir in path.split(posixpath.sep) + or posixpath.isabs(path) + or ntpath.isabs(path) ) if not invalid: return @@ -1549,10 +1661,9 @@ def _validate_resource_path(path): # for compatibility, warn; in future # raise ValueError(msg) - warnings.warn( + issue_warning( msg[:-1] + " and will raise exceptions in a future release.", DeprecationWarning, - stacklevel=4, ) def _get(self, path): @@ -1581,7 +1692,7 @@ class EggProvider(NullProvider): """Provider based on a virtual filesystem""" def __init__(self, module): - NullProvider.__init__(self, module) + super().__init__(module) self._setup_prefix() def _setup_prefix(self): @@ -1618,7 +1729,10 @@ def _get(self, path): @classmethod def _register(cls): - loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + loader_names = ( + 'SourceFileLoader', + 'SourcelessFileLoader', + ) for name in loader_names: loader_cls = getattr(importlib_machinery, name, type(None)) register_loader_type(loader_cls, cls) @@ -1678,6 +1792,7 @@ class MemoizedZipManifests(ZipManifests): """ Memoized zipfile manifests. """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') def load(self, path): @@ -1701,7 +1816,7 @@ class ZipProvider(EggProvider): _zip_manifests = MemoizedZipManifests() def __init__(self, module): - EggProvider.__init__(self, module) + super().__init__(module) self.zip_pre = self.loader.archive + os.sep def _zipinfo_name(self, fspath): @@ -1711,20 +1826,16 @@ def _zipinfo_name(self, fspath): if fspath == self.loader.archive: return '' if fspath.startswith(self.zip_pre): - return fspath[len(self.zip_pre):] - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.zip_pre) - ) + return fspath[len(self.zip_pre) :] + raise AssertionError("%s is not a subpath of %s" % (fspath, self.zip_pre)) def _parts(self, zip_path): # Convert a zipfile subpath into an egg-relative path part list. # pseudo-fs path fspath = self.zip_pre + zip_path if fspath.startswith(self.egg_root + os.sep): - return fspath[len(self.egg_root) + 1:].split(os.sep) - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.egg_root) - ) + return fspath[len(self.egg_root) + 1 :].split(os.sep) + raise AssertionError("%s is not a subpath of %s" % (fspath, self.egg_root)) @property def zipinfo(self): @@ -1754,25 +1865,20 @@ def _get_date_and_size(zip_stat): # FIXME: 'ZipProvider._extract_resource' is too complex (12) def _extract_resource(self, manager, zip_path): # noqa: C901 - if zip_path in self._index(): for name in self._index()[zip_path]: - last = self._extract_resource( - manager, os.path.join(zip_path, name) - ) + last = self._extract_resource(manager, os.path.join(zip_path, name)) # return the extracted directory name return os.path.dirname(last) timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) if not WRITE_SUPPORT: - raise IOError('"os.rename" and "os.unlink" are not supported ' - 'on this platform') - try: - - real_path = manager.get_cache_path( - self.egg_name, self._parts(zip_path) + raise OSError( + '"os.rename" and "os.unlink" are not supported ' 'on this platform' ) + try: + real_path = manager.get_cache_path(self.egg_name, self._parts(zip_path)) if self._is_current(real_path, zip_path): return real_path @@ -1895,7 +2001,7 @@ def get_metadata(self, name): if name != 'PKG-INFO': raise KeyError("No metadata except PKG-INFO is available") - with io.open(self.path, encoding='utf-8', errors="replace") as f: + with open(self.path, encoding='utf-8', errors="replace") as f: metadata = f.read() self._warn_on_replacement(metadata) return metadata @@ -1989,8 +2095,7 @@ def find_eggs_in_zip(importer, path_item, only=False): if _is_egg_path(subitem): subpath = os.path.join(path_item, subitem) dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) - for dist in dists: - yield dist + yield from dists elif subitem.lower().endswith(('.dist-info', '.egg-info')): subpath = os.path.join(path_item, subitem) submeta = EggMetadata(zipimport.zipimporter(subpath)) @@ -2008,93 +2113,42 @@ def find_nothing(importer, path_item, only=False): register_finder(object, find_nothing) -def _by_version_descending(names): - """ - Given a list of filenames, return them in descending order - by version number. - - >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' - >>> _by_version_descending(names) - ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'bar', 'foo'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] - """ - def try_parse(name): - """ - Attempt to parse as a version or return a null version. - """ - try: - return packaging.version.Version(name) - except Exception: - return packaging.version.Version('0') - - def _by_version(name): - """ - Parse each component of the filename - """ - name, ext = os.path.splitext(name) - parts = itertools.chain(name.split('-'), [ext]) - return [try_parse(part) for part in parts] - - return sorted(names, key=_by_version, reverse=True) - - def find_on_path(importer, path_item, only=False): """Yield distributions accessible on a sys.path directory""" path_item = _normalize_cached(path_item) if _is_unpacked_egg(path_item): yield Distribution.from_filename( - path_item, metadata=PathMetadata( - path_item, os.path.join(path_item, 'EGG-INFO') - ) + path_item, + metadata=PathMetadata(path_item, os.path.join(path_item, 'EGG-INFO')), ) return - entries = ( - os.path.join(path_item, child) - for child in safe_listdir(path_item) - ) - - # for performance, before sorting by version, - # screen entries for only those that will yield - # distributions - filtered = ( - entry - for entry in entries - if dist_factory(path_item, entry, only) - ) + entries = (os.path.join(path_item, child) for child in safe_listdir(path_item)) # scan for .egg and .egg-info in directory - path_item_entries = _by_version_descending(filtered) - for entry in path_item_entries: + for entry in sorted(entries): fullpath = os.path.join(path_item, entry) factory = dist_factory(path_item, entry, only) - for dist in factory(fullpath): - yield dist + yield from factory(fullpath) def dist_factory(path_item, entry, only): """Return a dist_factory for the given entry.""" lower = entry.lower() is_egg_info = lower.endswith('.egg-info') - is_dist_info = ( - lower.endswith('.dist-info') and - os.path.isdir(os.path.join(path_item, entry)) + is_dist_info = lower.endswith('.dist-info') and os.path.isdir( + os.path.join(path_item, entry) ) is_meta = is_egg_info or is_dist_info return ( distributions_from_metadata - if is_meta else - find_distributions - if not only and _is_egg_path(entry) else - resolve_egg_link - if not only and lower.endswith('.egg-link') else - NoDists() + if is_meta + else find_distributions + if not only and _is_egg_path(entry) + else resolve_egg_link + if not only and lower.endswith('.egg-link') + else NoDists() ) @@ -2106,6 +2160,7 @@ class NoDists: >>> list(NoDists()('anything')) [] """ + def __bool__(self): return False @@ -2140,7 +2195,10 @@ def distributions_from_metadata(path): metadata = FileMetadata(path) entry = os.path.basename(path) yield Distribution.from_location( - root, entry, metadata, precedence=DEVELOP_DIST, + root, + entry, + metadata, + precedence=DEVELOP_DIST, ) @@ -2162,17 +2220,16 @@ def resolve_egg_link(path): """ referenced_paths = non_empty_lines(path) resolved_paths = ( - os.path.join(os.path.dirname(path), ref) - for ref in referenced_paths + os.path.join(os.path.dirname(path), ref) for ref in referenced_paths ) dist_groups = map(find_distributions, resolved_paths) return next(dist_groups, ()) -register_finder(pkgutil.ImpImporter, find_on_path) +if hasattr(pkgutil, 'ImpImporter'): + register_finder(pkgutil.ImpImporter, find_on_path) -if hasattr(importlib_machinery, 'FileFinder'): - register_finder(importlib_machinery.FileFinder, find_on_path) +register_finder(importlib_machinery.FileFinder, find_on_path) _declare_state('dict', _namespace_handlers={}) _declare_state('dict', _namespace_packages={}) @@ -2205,12 +2262,14 @@ def _handle_ns(packageName, path_item): # use find_spec (PEP 451) and fall-back to find_module (PEP 302) try: - loader = importer.find_spec(packageName).loader + spec = importer.find_spec(packageName) except AttributeError: # capture warnings due to #1111 with warnings.catch_warnings(): warnings.simplefilter("ignore") loader = importer.find_module(packageName) + else: + loader = spec.loader if spec else None if loader is None: return None @@ -2268,6 +2327,15 @@ def position_in_sys_path(path): def declare_namespace(packageName): """Declare that package 'packageName' is a namespace package""" + msg = ( + f"Deprecated call to `pkg_resources.declare_namespace({packageName!r})`.\n" + "Implementing implicit namespace packages (as specified in PEP 420) " + "is preferred to `pkg_resources.declare_namespace`. " + "See https://setuptools.pypa.io/en/latest/references/" + "keywords.html#keyword-namespace-packages" + ) + warnings.warn(msg, DeprecationWarning, stacklevel=2) + _imp.acquire_lock() try: if packageName in _namespace_packages: @@ -2324,11 +2392,11 @@ def file_ns_handler(importer, path_item, packageName, module): return subpath -register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) -register_namespace_handler(zipimport.zipimporter, file_ns_handler) +if hasattr(pkgutil, 'ImpImporter'): + register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) -if hasattr(importlib_machinery, 'FileFinder'): - register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) +register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) def null_ns_handler(importer, path_item, packageName, module): @@ -2340,8 +2408,7 @@ def null_ns_handler(importer, path_item, packageName, module): def normalize_path(filename): """Normalize a file/dir name for comparison purposes""" - return os.path.normcase(os.path.realpath(os.path.normpath( - _cygwin_patch(filename)))) + return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) def _cygwin_patch(filename): # pragma: nocover @@ -2372,9 +2439,9 @@ def _is_egg_path(path): def _is_zip_egg(path): return ( - path.lower().endswith('.egg') and - os.path.isfile(path) and - zipfile.is_zipfile(path) + path.lower().endswith('.egg') + and os.path.isfile(path) + and zipfile.is_zipfile(path) ) @@ -2382,9 +2449,8 @@ def _is_unpacked_egg(path): """ Determine if given path appears to be an unpacked egg. """ - return ( - path.lower().endswith('.egg') and - os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + return path.lower().endswith('.egg') and os.path.isfile( + os.path.join(path, 'EGG-INFO', 'PKG-INFO') ) @@ -2396,21 +2462,6 @@ def _set_parent_ns(packageName): setattr(sys.modules[parent], name, sys.modules[packageName]) -def _nonblank(str): - return str and not str.startswith('#') - - -@functools.singledispatch -def yield_lines(iterable): - """Yield valid lines of a string or iterable""" - return itertools.chain.from_iterable(map(yield_lines, iterable)) - - -@yield_lines.register(str) -def _(text): - return filter(_nonblank, map(str.strip, text.splitlines())) - - MODULE = re.compile(r"\w+(\.\w+)*$").match EGG_NAME = re.compile( r""" @@ -2563,8 +2614,10 @@ def _version_from_file(lines): Given an iterable of lines from a Metadata file, return the value of the Version field, if present, or None otherwise. """ + def is_version_line(line): return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) line = next(iter(version_lines), '') _, _, value = line.partition(':') @@ -2573,12 +2626,19 @@ def is_version_line(line): class Distribution: """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' def __init__( - self, location=None, metadata=None, project_name=None, - version=None, py_version=PY_MAJOR, platform=None, - precedence=EGG_DIST): + self, + location=None, + metadata=None, + project_name=None, + version=None, + py_version=PY_MAJOR, + platform=None, + precedence=EGG_DIST, + ): self.project_name = safe_name(project_name or 'Unknown') if version is not None: self._version = safe_version(version) @@ -2601,8 +2661,13 @@ def from_location(cls, location, basename, metadata=None, **kw): 'name', 'ver', 'pyver', 'plat' ) return cls( - location, metadata, project_name=project_name, version=version, - py_version=py_version, platform=platform, **kw + location, + metadata, + project_name=project_name, + version=version, + py_version=py_version, + platform=platform, + **kw, )._reload_version() def _reload_version(self): @@ -2611,7 +2676,7 @@ def _reload_version(self): @property def hashcmp(self): return ( - self.parsed_version, + self._forgiving_parsed_version, self.precedence, self.key, self.location, @@ -2658,35 +2723,42 @@ def key(self): @property def parsed_version(self): if not hasattr(self, "_parsed_version"): - self._parsed_version = parse_version(self.version) + try: + self._parsed_version = parse_version(self.version) + except packaging.version.InvalidVersion as ex: + info = f"(package: {self.project_name})" + if hasattr(ex, "add_note"): + ex.add_note(info) # PEP 678 + raise + raise packaging.version.InvalidVersion(f"{str(ex)} {info}") from None return self._parsed_version - def _warn_legacy_version(self): - LV = packaging.version.LegacyVersion - is_legacy = isinstance(self._parsed_version, LV) - if not is_legacy: - return + @property + def _forgiving_parsed_version(self): + try: + return self.parsed_version + except packaging.version.InvalidVersion as ex: + self._parsed_version = parse_version(_forgiving_version(self.version)) - # While an empty version is technically a legacy version and - # is not a valid PEP 440 version, it's also unlikely to - # actually come from someone and instead it is more likely that - # it comes from setuptools attempting to parse a filename and - # including it in the list. So for that we'll gate this warning - # on if the version is anything at all or not. - if not self.version: - return + notes = "\n".join(getattr(ex, "__notes__", [])) # PEP 678 + msg = f"""!!\n\n + ************************************************************************* + {str(ex)}\n{notes} + + This is a long overdue deprecation. + For the time being, `pkg_resources` will use `{self._parsed_version}` + as a replacement to avoid breaking existing environments, + but no future compatibility is guaranteed. - tmpl = textwrap.dedent(""" - '{project_name} ({version})' is being parsed as a legacy, - non PEP 440, - version. You may find odd behavior and sort order. - In particular it will be sorted as less than 0.0. It - is recommended to migrate to PEP 440 compatible - versions. - """).strip().replace('\n', ' ') + If you maintain package {self.project_name} you should implement + the relevant changes to adequate the project to PEP 440 immediately. + ************************************************************************* + \n\n!! + """ + warnings.warn(msg, DeprecationWarning) - warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + return self._parsed_version @property def version(self): @@ -2696,9 +2768,9 @@ def version(self): version = self._get_version() if version is None: path = self._get_metadata_path_for_display(self.PKG_INFO) - msg = ( - "Missing 'Version:' header and/or {} file at path: {}" - ).format(self.PKG_INFO, path) + msg = ("Missing 'Version:' header and/or {} file at path: {}").format( + self.PKG_INFO, path + ) raise ValueError(msg, self) from e return version @@ -2727,8 +2799,7 @@ def _filter_extras(dm): reqs = dm.pop(extra) new_extra, _, marker = extra.partition(':') fails_marker = marker and ( - invalid_marker(marker) - or not evaluate_marker(marker) + invalid_marker(marker) or not evaluate_marker(marker) ) if fails_marker: reqs = [] @@ -2777,8 +2848,7 @@ def _get_metadata_path_for_display(self, name): def _get_metadata(self, name): if self.has_metadata(name): - for line in self.get_metadata_lines(name): - yield line + yield from self.get_metadata_lines(name) def _get_version(self): lines = self._get_metadata(self.PKG_INFO) @@ -2800,8 +2870,9 @@ def activate(self, path=None, replace=False): def egg_name(self): """Return what this distribution's standard .egg filename should be""" filename = "%s-%s-py%s" % ( - to_filename(self.project_name), to_filename(self.version), - self.py_version or PY_MAJOR + to_filename(self.project_name), + to_filename(self.version), + self.py_version or PY_MAJOR, ) if self.platform: @@ -2831,17 +2902,13 @@ def __getattr__(self, attr): def __dir__(self): return list( set(super(Distribution, self).__dir__()) - | set( - attr for attr in self._provider.__dir__() - if not attr.startswith('_') - ) + | set(attr for attr in self._provider.__dir__() if not attr.startswith('_')) ) @classmethod def from_filename(cls, filename, metadata=None, **kw): return cls.from_location( - _normalize_cached(filename), os.path.basename(filename), metadata, - **kw + _normalize_cached(filename), os.path.basename(filename), metadata, **kw ) def as_requirement(self): @@ -2953,14 +3020,18 @@ def check_version_conflict(self): nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) loc = normalize_path(self.location) for modname in self._get_metadata('top_level.txt'): - if (modname not in sys.modules or modname in nsp - or modname in _namespace_packages): + if ( + modname not in sys.modules + or modname in nsp + or modname in _namespace_packages + ): continue if modname in ('pkg_resources', 'setuptools', 'site'): continue fn = getattr(sys.modules[modname], '__file__', None) - if fn and (normalize_path(fn).startswith(loc) or - fn.startswith(self.location)): + if fn and ( + normalize_path(fn).startswith(loc) or fn.startswith(self.location) + ): continue issue_warning( "Module %s was already imported from %s, but %s is being added" @@ -2973,6 +3044,9 @@ def has_version(self): except ValueError: issue_warning("Unbuilt egg for " + repr(self)) return False + except SystemError: + # TODO: remove this except clause when python/cpython#103632 is fixed. + return False return True def clone(self, **kw): @@ -3012,6 +3086,7 @@ class DistInfoDistribution(Distribution): Wrap an actual or potential sys.path entry w/metadata, .dist-info style. """ + PKG_INFO = 'METADATA' EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") @@ -3047,12 +3122,12 @@ def reqs_for_extra(extra): if not req.marker or req.marker.evaluate({'extra': extra}): yield req - common = frozenset(reqs_for_extra(None)) + common = types.MappingProxyType(dict.fromkeys(reqs_for_extra(None))) dm[None].extend(common) for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: s_extra = safe_extra(extra.strip()) - dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + dm[s_extra] = [r for r in reqs_for_extra(extra) if r not in common] return dm @@ -3078,25 +3153,12 @@ def issue_warning(*args, **kw): def parse_requirements(strs): - """Yield ``Requirement`` objects for each specification in `strs` + """ + Yield ``Requirement`` objects for each specification in `strs`. `strs` must be a string, or a (possibly-nested) iterable thereof. """ - # create a steppable iterator, so we can handle \-continuations - lines = iter(yield_lines(strs)) - - for line in lines: - # Drop comments -- a hash without a space may be in a URL. - if ' #' in line: - line = line[:line.find(' #')] - # If there is a line continuation, drop it, and append the next line. - if line.endswith('\\'): - line = line[:-2].strip() - try: - line += next(lines) - except StopIteration: - return - yield Requirement(line) + return map(Requirement, join_continuation(map(drop_comment, yield_lines(strs)))) class RequirementParseError(packaging.requirements.InvalidRequirement): @@ -3110,8 +3172,7 @@ def __init__(self, requirement_string): self.unsafe_name = self.name project_name = safe_name(self.name) self.project_name, self.key = project_name, project_name.lower() - self.specs = [ - (spec.operator, spec.version) for spec in self.specifier] + self.specs = [(spec.operator, spec.version) for spec in self.specifier] self.extras = tuple(map(safe_extra, self.extras)) self.hashCmp = ( self.key, @@ -3123,10 +3184,7 @@ def __init__(self, requirement_string): self.__hash = hash(self.hashCmp) def __eq__(self, other): - return ( - isinstance(other, Requirement) and - self.hashCmp == other.hashCmp - ) + return isinstance(other, Requirement) and self.hashCmp == other.hashCmp def __ne__(self, other): return not self == other @@ -3151,7 +3209,7 @@ def __repr__(self): @staticmethod def parse(s): - req, = parse_requirements(s) + (req,) = parse_requirements(s) return req @@ -3182,7 +3240,7 @@ def ensure_directory(path): def _bypass_ensure_directory(path): """Sandbox-bypassing version of ensure_directory()""" if not WRITE_SUPPORT: - raise IOError('"os.mkdir" not supported on this platform.') + raise OSError('"os.mkdir" not supported on this platform.') dirname, filename = split(path) if dirname and filename and not isdir(dirname): _bypass_ensure_directory(dirname) @@ -3289,10 +3347,7 @@ def _initialize_master_working_set(): # ensure that all distributions added to the working set in the future # (e.g. by calling ``require()``) will get activated as well, # with higher priority (replace=True). - tuple( - dist.activate(replace=False) - for dist in working_set - ) + tuple(dist.activate(replace=False) for dist in working_set) add_activation_listener( lambda dist: dist.activate(replace=True), existing=False, diff --git a/uno/lib/python/pkg_resources/_vendor/appdirs.py b/uno/lib/python/pkg_resources/_vendor/appdirs.py deleted file mode 100644 index ae67001a..00000000 --- a/uno/lib/python/pkg_resources/_vendor/appdirs.py +++ /dev/null @@ -1,608 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2005-2010 ActiveState Software Inc. -# Copyright (c) 2013 Eddy Petrișor - -"""Utilities for determining application-specific dirs. - -See for details and usage. -""" -# Dev Notes: -# - MSDN on where to store app data files: -# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 -# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html -# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - -__version_info__ = (1, 4, 3) -__version__ = '.'.join(map(str, __version_info__)) - - -import sys -import os - -PY3 = sys.version_info[0] == 3 - -if PY3: - unicode = str - -if sys.platform.startswith('java'): - import platform - os_name = platform.java_ver()[3][0] - if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. - system = 'win32' - elif os_name.startswith('Mac'): # "Mac OS X", etc. - system = 'darwin' - else: # "Linux", "SunOS", "FreeBSD", etc. - # Setting this to "linux2" is not ideal, but only Windows or Mac - # are actually checked for and the rest of the module expects - # *sys.platform* style strings. - system = 'linux2' -else: - system = sys.platform - - - -def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user data directories are: - Mac OS X: ~/Library/Application Support/ - Unix: ~/.local/share/ # or in $XDG_DATA_HOME, if defined - Win XP (not roaming): C:\Documents and Settings\\Application Data\\ - Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\ - Win 7 (not roaming): C:\Users\\AppData\Local\\ - Win 7 (roaming): C:\Users\\AppData\Roaming\\ - - For Unix, we follow the XDG spec and support $XDG_DATA_HOME. - That means, by default "~/.local/share/". - """ - if system == "win32": - if appauthor is None: - appauthor = appname - const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" - path = os.path.normpath(_get_win_folder(const)) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('~/Library/Application Support/') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of data dirs should be - returned. By default, the first item from XDG_DATA_DIRS is - returned, or '/usr/local/share/', - if XDG_DATA_DIRS is not set - - Typical site data directories are: - Mac OS X: /Library/Application Support/ - Unix: /usr/local/share/ or /usr/share/ - Win XP: C:\Documents and Settings\All Users\Application Data\\ - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - Win 7: C:\ProgramData\\ # Hidden, but writeable on Win 7. - - For Unix, this is using the $XDG_DATA_DIRS[0] default. - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('/Library/Application Support') - if appname: - path = os.path.join(path, appname) - else: - # XDG default for $XDG_DATA_DIRS - # only first, if multipath is False - path = os.getenv('XDG_DATA_DIRS', - os.pathsep.join(['/usr/local/share', '/usr/share'])) - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - if appname and version: - path = os.path.join(path, version) - return path - - -def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific config dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user config directories are: - Mac OS X: same as user_data_dir - Unix: ~/.config/ # or in $XDG_CONFIG_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. - That means, by default "~/.config/". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of config dirs should be - returned. By default, the first item from XDG_CONFIG_DIRS is - returned, or '/etc/xdg/', if XDG_CONFIG_DIRS is not set - - Typical site config directories are: - Mac OS X: same as site_data_dir - Unix: /etc/xdg/ or $XDG_CONFIG_DIRS[i]/ for each value in - $XDG_CONFIG_DIRS - Win *: same as site_data_dir - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - - For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system in ["win32", "darwin"]: - path = site_data_dir(appname, appauthor) - if appname and version: - path = os.path.join(path, version) - else: - # XDG default for $XDG_CONFIG_DIRS - # only first, if multipath is False - path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - -def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific cache dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Cache" to the base app data dir for Windows. See - discussion below. - - Typical user cache directories are: - Mac OS X: ~/Library/Caches/ - Unix: ~/.cache/ (XDG default) - Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Cache - Vista: C:\Users\\AppData\Local\\\Cache - - On Windows the only suggestion in the MSDN docs is that local settings go in - the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming - app data dir (the default returned by `user_data_dir` above). Apps typically - put cache data somewhere *under* the given dir here. Some examples: - ...\Mozilla\Firefox\Profiles\\Cache - ...\Acme\SuperApp\Cache\1.0 - OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. - This can be disabled with the `opinion=False` option. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - if opinion: - path = os.path.join(path, "Cache") - elif system == 'darwin': - path = os.path.expanduser('~/Library/Caches') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific state dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user state directories are: - Mac OS X: same as user_data_dir - Unix: ~/.local/state/ # or in $XDG_STATE_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow this Debian proposal - to extend the XDG spec and support $XDG_STATE_HOME. - - That means, by default "~/.local/state/". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific log dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Logs" to the base app data dir for Windows, and "log" to the - base cache dir for Unix. See discussion below. - - Typical user log directories are: - Mac OS X: ~/Library/Logs/ - Unix: ~/.cache//log # or under $XDG_CACHE_HOME if defined - Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Logs - Vista: C:\Users\\AppData\Local\\\Logs - - On Windows the only suggestion in the MSDN docs is that local settings - go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in - examples of what some windows apps use for a logs dir.) - - OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` - value for Windows and appends "log" to the user cache dir for Unix. - This can be disabled with the `opinion=False` option. - """ - if system == "darwin": - path = os.path.join( - os.path.expanduser('~/Library/Logs'), - appname) - elif system == "win32": - path = user_data_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "Logs") - else: - path = user_cache_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "log") - if appname and version: - path = os.path.join(path, version) - return path - - -class AppDirs(object): - """Convenience wrapper for getting application dirs.""" - def __init__(self, appname=None, appauthor=None, version=None, - roaming=False, multipath=False): - self.appname = appname - self.appauthor = appauthor - self.version = version - self.roaming = roaming - self.multipath = multipath - - @property - def user_data_dir(self): - return user_data_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_data_dir(self): - return site_data_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_config_dir(self): - return user_config_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_config_dir(self): - return site_config_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_cache_dir(self): - return user_cache_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_state_dir(self): - return user_state_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_log_dir(self): - return user_log_dir(self.appname, self.appauthor, - version=self.version) - - -#---- internal support stuff - -def _get_win_folder_from_registry(csidl_name): - """This is a fallback technique at best. I'm not sure if using the - registry for this guarantees us the correct answer for all CSIDL_* - names. - """ - if PY3: - import winreg as _winreg - else: - import _winreg - - shell_folder_name = { - "CSIDL_APPDATA": "AppData", - "CSIDL_COMMON_APPDATA": "Common AppData", - "CSIDL_LOCAL_APPDATA": "Local AppData", - }[csidl_name] - - key = _winreg.OpenKey( - _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - dir, type = _winreg.QueryValueEx(key, shell_folder_name) - return dir - - -def _get_win_folder_with_pywin32(csidl_name): - from win32com.shell import shellcon, shell - dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) - # Try to make this a unicode path because SHGetFolderPath does - # not return unicode strings when there is unicode data in the - # path. - try: - dir = unicode(dir) - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - try: - import win32api - dir = win32api.GetShortPathName(dir) - except ImportError: - pass - except UnicodeError: - pass - return dir - - -def _get_win_folder_with_ctypes(csidl_name): - import ctypes - - csidl_const = { - "CSIDL_APPDATA": 26, - "CSIDL_COMMON_APPDATA": 35, - "CSIDL_LOCAL_APPDATA": 28, - }[csidl_name] - - buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf2 = ctypes.create_unicode_buffer(1024) - if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): - buf = buf2 - - return buf.value - -def _get_win_folder_with_jna(csidl_name): - import array - from com.sun import jna - from com.sun.jna.platform import win32 - - buf_size = win32.WinDef.MAX_PATH * 2 - buf = array.zeros('c', buf_size) - shell = win32.Shell32.INSTANCE - shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf = array.zeros('c', buf_size) - kernel = win32.Kernel32.INSTANCE - if kernel.GetShortPathName(dir, buf, buf_size): - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - return dir - -if system == "win32": - try: - import win32com.shell - _get_win_folder = _get_win_folder_with_pywin32 - except ImportError: - try: - from ctypes import windll - _get_win_folder = _get_win_folder_with_ctypes - except ImportError: - try: - import com.sun.jna - _get_win_folder = _get_win_folder_with_jna - except ImportError: - _get_win_folder = _get_win_folder_from_registry - - -#---- self test code - -if __name__ == "__main__": - appname = "MyApp" - appauthor = "MyCompany" - - props = ("user_data_dir", - "user_config_dir", - "user_cache_dir", - "user_state_dir", - "user_log_dir", - "site_data_dir", - "site_config_dir") - - print("-- app dirs %s --" % __version__) - - print("-- app dirs (with optional 'version')") - dirs = AppDirs(appname, appauthor, version="1.0") - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'version')") - dirs = AppDirs(appname, appauthor) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'appauthor')") - dirs = AppDirs(appname) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (with disabled 'appauthor')") - dirs = AppDirs(appname, appauthor=False) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/__init__.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/__init__.py new file mode 100644 index 00000000..34e3a995 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/__init__.py @@ -0,0 +1,36 @@ +"""Read resources contained within a package.""" + +from ._common import ( + as_file, + files, + Package, +) + +from ._legacy import ( + contents, + open_binary, + read_binary, + open_text, + read_text, + is_resource, + path, + Resource, +) + +from .abc import ResourceReader + + +__all__ = [ + 'Package', + 'Resource', + 'ResourceReader', + 'as_file', + 'contents', + 'files', + 'is_resource', + 'open_binary', + 'open_text', + 'path', + 'read_binary', + 'read_text', +] diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/_adapters.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_adapters.py new file mode 100644 index 00000000..ea363d86 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_adapters.py @@ -0,0 +1,170 @@ +from contextlib import suppress +from io import TextIOWrapper + +from . import abc + + +class SpecLoaderAdapter: + """ + Adapt a package spec to adapt the underlying loader. + """ + + def __init__(self, spec, adapter=lambda spec: spec.loader): + self.spec = spec + self.loader = adapter(spec) + + def __getattr__(self, name): + return getattr(self.spec, name) + + +class TraversableResourcesLoader: + """ + Adapt a loader to provide TraversableResources. + """ + + def __init__(self, spec): + self.spec = spec + + def get_resource_reader(self, name): + return CompatibilityFiles(self.spec)._native() + + +def _io_wrapper(file, mode='r', *args, **kwargs): + if mode == 'r': + return TextIOWrapper(file, *args, **kwargs) + elif mode == 'rb': + return file + raise ValueError( + "Invalid mode value '{}', only 'r' and 'rb' are supported".format(mode) + ) + + +class CompatibilityFiles: + """ + Adapter for an existing or non-existent resource reader + to provide a compatibility .files(). + """ + + class SpecPath(abc.Traversable): + """ + Path tied to a module spec. + Can be read and exposes the resource reader children. + """ + + def __init__(self, spec, reader): + self._spec = spec + self._reader = reader + + def iterdir(self): + if not self._reader: + return iter(()) + return iter( + CompatibilityFiles.ChildPath(self._reader, path) + for path in self._reader.contents() + ) + + def is_file(self): + return False + + is_dir = is_file + + def joinpath(self, other): + if not self._reader: + return CompatibilityFiles.OrphanPath(other) + return CompatibilityFiles.ChildPath(self._reader, other) + + @property + def name(self): + return self._spec.name + + def open(self, mode='r', *args, **kwargs): + return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs) + + class ChildPath(abc.Traversable): + """ + Path tied to a resource reader child. + Can be read but doesn't expose any meaningful children. + """ + + def __init__(self, reader, name): + self._reader = reader + self._name = name + + def iterdir(self): + return iter(()) + + def is_file(self): + return self._reader.is_resource(self.name) + + def is_dir(self): + return not self.is_file() + + def joinpath(self, other): + return CompatibilityFiles.OrphanPath(self.name, other) + + @property + def name(self): + return self._name + + def open(self, mode='r', *args, **kwargs): + return _io_wrapper( + self._reader.open_resource(self.name), mode, *args, **kwargs + ) + + class OrphanPath(abc.Traversable): + """ + Orphan path, not tied to a module spec or resource reader. + Can't be read and doesn't expose any meaningful children. + """ + + def __init__(self, *path_parts): + if len(path_parts) < 1: + raise ValueError('Need at least one path part to construct a path') + self._path = path_parts + + def iterdir(self): + return iter(()) + + def is_file(self): + return False + + is_dir = is_file + + def joinpath(self, other): + return CompatibilityFiles.OrphanPath(*self._path, other) + + @property + def name(self): + return self._path[-1] + + def open(self, mode='r', *args, **kwargs): + raise FileNotFoundError("Can't open orphan path") + + def __init__(self, spec): + self.spec = spec + + @property + def _reader(self): + with suppress(AttributeError): + return self.spec.loader.get_resource_reader(self.spec.name) + + def _native(self): + """ + Return the native reader if it supports files(). + """ + reader = self._reader + return reader if hasattr(reader, 'files') else self + + def __getattr__(self, attr): + return getattr(self._reader, attr) + + def files(self): + return CompatibilityFiles.SpecPath(self.spec, self._reader) + + +def wrap_spec(package): + """ + Construct a package spec with traversable compatibility + on the spec/loader/reader. + """ + return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/_common.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_common.py new file mode 100644 index 00000000..3c6de1cf --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_common.py @@ -0,0 +1,207 @@ +import os +import pathlib +import tempfile +import functools +import contextlib +import types +import importlib +import inspect +import warnings +import itertools + +from typing import Union, Optional, cast +from .abc import ResourceReader, Traversable + +from ._compat import wrap_spec + +Package = Union[types.ModuleType, str] +Anchor = Package + + +def package_to_anchor(func): + """ + Replace 'package' parameter as 'anchor' and warn about the change. + + Other errors should fall through. + + >>> files('a', 'b') + Traceback (most recent call last): + TypeError: files() takes from 0 to 1 positional arguments but 2 were given + """ + undefined = object() + + @functools.wraps(func) + def wrapper(anchor=undefined, package=undefined): + if package is not undefined: + if anchor is not undefined: + return func(anchor, package) + warnings.warn( + "First parameter to files is renamed to 'anchor'", + DeprecationWarning, + stacklevel=2, + ) + return func(package) + elif anchor is undefined: + return func() + return func(anchor) + + return wrapper + + +@package_to_anchor +def files(anchor: Optional[Anchor] = None) -> Traversable: + """ + Get a Traversable resource for an anchor. + """ + return from_package(resolve(anchor)) + + +def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: + """ + Return the package's loader if it's a ResourceReader. + """ + # We can't use + # a issubclass() check here because apparently abc.'s __subclasscheck__() + # hook wants to create a weak reference to the object, but + # zipimport.zipimporter does not support weak references, resulting in a + # TypeError. That seems terrible. + spec = package.__spec__ + reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore + if reader is None: + return None + return reader(spec.name) # type: ignore + + +@functools.singledispatch +def resolve(cand: Optional[Anchor]) -> types.ModuleType: + return cast(types.ModuleType, cand) + + +@resolve.register +def _(cand: str) -> types.ModuleType: + return importlib.import_module(cand) + + +@resolve.register +def _(cand: None) -> types.ModuleType: + return resolve(_infer_caller().f_globals['__name__']) + + +def _infer_caller(): + """ + Walk the stack and find the frame of the first caller not in this module. + """ + + def is_this_file(frame_info): + return frame_info.filename == __file__ + + def is_wrapper(frame_info): + return frame_info.function == 'wrapper' + + not_this_file = itertools.filterfalse(is_this_file, inspect.stack()) + # also exclude 'wrapper' due to singledispatch in the call stack + callers = itertools.filterfalse(is_wrapper, not_this_file) + return next(callers).frame + + +def from_package(package: types.ModuleType): + """ + Return a Traversable object for the given package. + + """ + spec = wrap_spec(package) + reader = spec.loader.get_resource_reader(spec.name) + return reader.files() + + +@contextlib.contextmanager +def _tempfile( + reader, + suffix='', + # gh-93353: Keep a reference to call os.remove() in late Python + # finalization. + *, + _os_remove=os.remove, +): + # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' + # blocks due to the need to close the temporary file to work on Windows + # properly. + fd, raw_path = tempfile.mkstemp(suffix=suffix) + try: + try: + os.write(fd, reader()) + finally: + os.close(fd) + del reader + yield pathlib.Path(raw_path) + finally: + try: + _os_remove(raw_path) + except FileNotFoundError: + pass + + +def _temp_file(path): + return _tempfile(path.read_bytes, suffix=path.name) + + +def _is_present_dir(path: Traversable) -> bool: + """ + Some Traversables implement ``is_dir()`` to raise an + exception (i.e. ``FileNotFoundError``) when the + directory doesn't exist. This function wraps that call + to always return a boolean and only return True + if there's a dir and it exists. + """ + with contextlib.suppress(FileNotFoundError): + return path.is_dir() + return False + + +@functools.singledispatch +def as_file(path): + """ + Given a Traversable object, return that object as a + path on the local file system in a context manager. + """ + return _temp_dir(path) if _is_present_dir(path) else _temp_file(path) + + +@as_file.register(pathlib.Path) +@contextlib.contextmanager +def _(path): + """ + Degenerate behavior for pathlib.Path objects. + """ + yield path + + +@contextlib.contextmanager +def _temp_path(dir: tempfile.TemporaryDirectory): + """ + Wrap tempfile.TemporyDirectory to return a pathlib object. + """ + with dir as result: + yield pathlib.Path(result) + + +@contextlib.contextmanager +def _temp_dir(path): + """ + Given a traversable dir, recursively replicate the whole tree + to the file system in a context manager. + """ + assert path.is_dir() + with _temp_path(tempfile.TemporaryDirectory()) as temp_dir: + yield _write_contents(temp_dir, path) + + +def _write_contents(target, source): + child = target.joinpath(source.name) + if source.is_dir(): + child.mkdir() + for item in source.iterdir(): + _write_contents(child, item) + else: + child.write_bytes(source.read_bytes()) + return child diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/_compat.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_compat.py new file mode 100644 index 00000000..8b5b1d28 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_compat.py @@ -0,0 +1,108 @@ +# flake8: noqa + +import abc +import os +import sys +import pathlib +from contextlib import suppress +from typing import Union + + +if sys.version_info >= (3, 10): + from zipfile import Path as ZipPath # type: ignore +else: + from ..zipp import Path as ZipPath # type: ignore + + +try: + from typing import runtime_checkable # type: ignore +except ImportError: + + def runtime_checkable(cls): # type: ignore + return cls + + +try: + from typing import Protocol # type: ignore +except ImportError: + Protocol = abc.ABC # type: ignore + + +class TraversableResourcesLoader: + """ + Adapt loaders to provide TraversableResources and other + compatibility. + + Used primarily for Python 3.9 and earlier where the native + loaders do not yet implement TraversableResources. + """ + + def __init__(self, spec): + self.spec = spec + + @property + def path(self): + return self.spec.origin + + def get_resource_reader(self, name): + from . import readers, _adapters + + def _zip_reader(spec): + with suppress(AttributeError): + return readers.ZipReader(spec.loader, spec.name) + + def _namespace_reader(spec): + with suppress(AttributeError, ValueError): + return readers.NamespaceReader(spec.submodule_search_locations) + + def _available_reader(spec): + with suppress(AttributeError): + return spec.loader.get_resource_reader(spec.name) + + def _native_reader(spec): + reader = _available_reader(spec) + return reader if hasattr(reader, 'files') else None + + def _file_reader(spec): + try: + path = pathlib.Path(self.path) + except TypeError: + return None + if path.exists(): + return readers.FileReader(self) + + return ( + # native reader if it supplies 'files' + _native_reader(self.spec) + or + # local ZipReader if a zip module + _zip_reader(self.spec) + or + # local NamespaceReader if a namespace module + _namespace_reader(self.spec) + or + # local FileReader + _file_reader(self.spec) + # fallback - adapt the spec ResourceReader to TraversableReader + or _adapters.CompatibilityFiles(self.spec) + ) + + +def wrap_spec(package): + """ + Construct a package spec with traversable compatibility + on the spec/loader/reader. + + Supersedes _adapters.wrap_spec to use TraversableResourcesLoader + from above for older Python compatibility (<3.10). + """ + from . import _adapters + + return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) + + +if sys.version_info >= (3, 9): + StrPath = Union[str, os.PathLike[str]] +else: + # PathLike is only subscriptable at runtime in 3.9+ + StrPath = Union[str, "os.PathLike[str]"] diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/_itertools.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_itertools.py new file mode 100644 index 00000000..cce05582 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_itertools.py @@ -0,0 +1,35 @@ +from itertools import filterfalse + +from typing import ( + Callable, + Iterable, + Iterator, + Optional, + Set, + TypeVar, + Union, +) + +# Type and type variable definitions +_T = TypeVar('_T') +_U = TypeVar('_U') + + +def unique_everseen( + iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = None +) -> Iterator[_T]: + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen: Set[Union[_T, _U]] = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/_legacy.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_legacy.py new file mode 100644 index 00000000..b1ea8105 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/_legacy.py @@ -0,0 +1,120 @@ +import functools +import os +import pathlib +import types +import warnings + +from typing import Union, Iterable, ContextManager, BinaryIO, TextIO, Any + +from . import _common + +Package = Union[types.ModuleType, str] +Resource = str + + +def deprecated(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + f"{func.__name__} is deprecated. Use files() instead. " + "Refer to https://importlib-resources.readthedocs.io" + "/en/latest/using.html#migrating-from-legacy for migration advice.", + DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + + +def normalize_path(path: Any) -> str: + """Normalize a path by ensuring it is a string. + + If the resulting string contains path separators, an exception is raised. + """ + str_path = str(path) + parent, file_name = os.path.split(str_path) + if parent: + raise ValueError(f'{path!r} must be only a file name') + return file_name + + +@deprecated +def open_binary(package: Package, resource: Resource) -> BinaryIO: + """Return a file-like object opened for binary reading of the resource.""" + return (_common.files(package) / normalize_path(resource)).open('rb') + + +@deprecated +def read_binary(package: Package, resource: Resource) -> bytes: + """Return the binary contents of the resource.""" + return (_common.files(package) / normalize_path(resource)).read_bytes() + + +@deprecated +def open_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict', +) -> TextIO: + """Return a file-like object opened for text reading of the resource.""" + return (_common.files(package) / normalize_path(resource)).open( + 'r', encoding=encoding, errors=errors + ) + + +@deprecated +def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict', +) -> str: + """Return the decoded string of the resource. + + The decoding-related arguments have the same semantics as those of + bytes.decode(). + """ + with open_text(package, resource, encoding, errors) as fp: + return fp.read() + + +@deprecated +def contents(package: Package) -> Iterable[str]: + """Return an iterable of entries in `package`. + + Note that not all entries are resources. Specifically, directories are + not considered resources. Use `is_resource()` on each entry returned here + to check if it is a resource or not. + """ + return [path.name for path in _common.files(package).iterdir()] + + +@deprecated +def is_resource(package: Package, name: str) -> bool: + """True if `name` is a resource inside `package`. + + Directories are *not* resources. + """ + resource = normalize_path(name) + return any( + traversable.name == resource and traversable.is_file() + for traversable in _common.files(package).iterdir() + ) + + +@deprecated +def path( + package: Package, + resource: Resource, +) -> ContextManager[pathlib.Path]: + """A context manager providing a file path object to the resource. + + If the resource does not already exist on its own on the file system, + a temporary file will be created. If the file was created, the file + will be deleted upon exiting the context manager (no exception is + raised if the file was deleted prior to the context manager + exiting). + """ + return _common.as_file(_common.files(package) / normalize_path(resource)) diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/abc.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/abc.py new file mode 100644 index 00000000..23b6aeaf --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/abc.py @@ -0,0 +1,170 @@ +import abc +import io +import itertools +import pathlib +from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional + +from ._compat import runtime_checkable, Protocol, StrPath + + +__all__ = ["ResourceReader", "Traversable", "TraversableResources"] + + +class ResourceReader(metaclass=abc.ABCMeta): + """Abstract base class for loaders to provide resource reading support.""" + + @abc.abstractmethod + def open_resource(self, resource: Text) -> BinaryIO: + """Return an opened, file-like object for binary reading. + + The 'resource' argument is expected to represent only a file name. + If the resource cannot be found, FileNotFoundError is raised. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def resource_path(self, resource: Text) -> Text: + """Return the file system path to the specified resource. + + The 'resource' argument is expected to represent only a file name. + If the resource does not exist on the file system, raise + FileNotFoundError. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def is_resource(self, path: Text) -> bool: + """Return True if the named 'path' is a resource. + + Files are resources, directories are not. + """ + raise FileNotFoundError + + @abc.abstractmethod + def contents(self) -> Iterable[str]: + """Return an iterable of entries in `package`.""" + raise FileNotFoundError + + +class TraversalError(Exception): + pass + + +@runtime_checkable +class Traversable(Protocol): + """ + An object with a subset of pathlib.Path methods suitable for + traversing directories and opening files. + + Any exceptions that occur when accessing the backing resource + may propagate unaltered. + """ + + @abc.abstractmethod + def iterdir(self) -> Iterator["Traversable"]: + """ + Yield Traversable objects in self + """ + + def read_bytes(self) -> bytes: + """ + Read contents of self as bytes + """ + with self.open('rb') as strm: + return strm.read() + + def read_text(self, encoding: Optional[str] = None) -> str: + """ + Read contents of self as text + """ + with self.open(encoding=encoding) as strm: + return strm.read() + + @abc.abstractmethod + def is_dir(self) -> bool: + """ + Return True if self is a directory + """ + + @abc.abstractmethod + def is_file(self) -> bool: + """ + Return True if self is a file + """ + + def joinpath(self, *descendants: StrPath) -> "Traversable": + """ + Return Traversable resolved with any descendants applied. + + Each descendant should be a path segment relative to self + and each may contain multiple levels separated by + ``posixpath.sep`` (``/``). + """ + if not descendants: + return self + names = itertools.chain.from_iterable( + path.parts for path in map(pathlib.PurePosixPath, descendants) + ) + target = next(names) + matches = ( + traversable for traversable in self.iterdir() if traversable.name == target + ) + try: + match = next(matches) + except StopIteration: + raise TraversalError( + "Target not found during traversal.", target, list(names) + ) + return match.joinpath(*names) + + def __truediv__(self, child: StrPath) -> "Traversable": + """ + Return Traversable child in self + """ + return self.joinpath(child) + + @abc.abstractmethod + def open(self, mode='r', *args, **kwargs): + """ + mode may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as pathlib.Path.open). + + When opening as text, accepts encoding parameters such as those + accepted by io.TextIOWrapper. + """ + + @property + @abc.abstractmethod + def name(self) -> str: + """ + The base name of this object without any parent references. + """ + + +class TraversableResources(ResourceReader): + """ + The required interface for providing traversable + resources. + """ + + @abc.abstractmethod + def files(self) -> "Traversable": + """Return a Traversable object for the loaded package.""" + + def open_resource(self, resource: StrPath) -> io.BufferedReader: + return self.files().joinpath(resource).open('rb') + + def resource_path(self, resource: Any) -> NoReturn: + raise FileNotFoundError(resource) + + def is_resource(self, path: StrPath) -> bool: + return self.files().joinpath(path).is_file() + + def contents(self) -> Iterator[str]: + return (item.name for item in self.files().iterdir()) diff --git a/uno/lib/python/urllib3/contrib/_securetransport/__init__.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/py.typed similarity index 100% rename from uno/lib/python/urllib3/contrib/_securetransport/__init__.py rename to uno/lib/python/pkg_resources/_vendor/importlib_resources/py.typed diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/readers.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/readers.py new file mode 100644 index 00000000..ab34db74 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/readers.py @@ -0,0 +1,120 @@ +import collections +import pathlib +import operator + +from . import abc + +from ._itertools import unique_everseen +from ._compat import ZipPath + + +def remove_duplicates(items): + return iter(collections.OrderedDict.fromkeys(items)) + + +class FileReader(abc.TraversableResources): + def __init__(self, loader): + self.path = pathlib.Path(loader.path).parent + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path + + +class ZipReader(abc.TraversableResources): + def __init__(self, loader, module): + _, _, name = module.rpartition('.') + self.prefix = loader.prefix.replace('\\', '/') + name + '/' + self.archive = loader.archive + + def open_resource(self, resource): + try: + return super().open_resource(resource) + except KeyError as exc: + raise FileNotFoundError(exc.args[0]) + + def is_resource(self, path): + # workaround for `zipfile.Path.is_file` returning true + # for non-existent paths. + target = self.files().joinpath(path) + return target.is_file() and target.exists() + + def files(self): + return ZipPath(self.archive, self.prefix) + + +class MultiplexedPath(abc.Traversable): + """ + Given a series of Traversable objects, implement a merged + version of the interface across all objects. Useful for + namespace packages which may be multihomed at a single + name. + """ + + def __init__(self, *paths): + self._paths = list(map(pathlib.Path, remove_duplicates(paths))) + if not self._paths: + message = 'MultiplexedPath must contain at least one path' + raise FileNotFoundError(message) + if not all(path.is_dir() for path in self._paths): + raise NotADirectoryError('MultiplexedPath only supports directories') + + def iterdir(self): + files = (file for path in self._paths for file in path.iterdir()) + return unique_everseen(files, key=operator.attrgetter('name')) + + def read_bytes(self): + raise FileNotFoundError(f'{self} is not a file') + + def read_text(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + def is_dir(self): + return True + + def is_file(self): + return False + + def joinpath(self, *descendants): + try: + return super().joinpath(*descendants) + except abc.TraversalError: + # One of the paths did not resolve (a directory does not exist). + # Just return something that will not exist. + return self._paths[0].joinpath(*descendants) + + def open(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + @property + def name(self): + return self._paths[0].name + + def __repr__(self): + paths = ', '.join(f"'{path}'" for path in self._paths) + return f'MultiplexedPath({paths})' + + +class NamespaceReader(abc.TraversableResources): + def __init__(self, namespace_path): + if 'NamespacePath' not in str(namespace_path): + raise ValueError('Invalid path') + self.path = MultiplexedPath(*list(namespace_path)) + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path diff --git a/uno/lib/python/pkg_resources/_vendor/importlib_resources/simple.py b/uno/lib/python/pkg_resources/_vendor/importlib_resources/simple.py new file mode 100644 index 00000000..7770c922 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/importlib_resources/simple.py @@ -0,0 +1,106 @@ +""" +Interface adapters for low-level readers. +""" + +import abc +import io +import itertools +from typing import BinaryIO, List + +from .abc import Traversable, TraversableResources + + +class SimpleReader(abc.ABC): + """ + The minimum, low-level interface required from a resource + provider. + """ + + @property + @abc.abstractmethod + def package(self) -> str: + """ + The name of the package for which this reader loads resources. + """ + + @abc.abstractmethod + def children(self) -> List['SimpleReader']: + """ + Obtain an iterable of SimpleReader for available + child containers (e.g. directories). + """ + + @abc.abstractmethod + def resources(self) -> List[str]: + """ + Obtain available named resources for this virtual package. + """ + + @abc.abstractmethod + def open_binary(self, resource: str) -> BinaryIO: + """ + Obtain a File-like for a named resource. + """ + + @property + def name(self): + return self.package.split('.')[-1] + + +class ResourceContainer(Traversable): + """ + Traversable container for a package's resources via its reader. + """ + + def __init__(self, reader: SimpleReader): + self.reader = reader + + def is_dir(self): + return True + + def is_file(self): + return False + + def iterdir(self): + files = (ResourceHandle(self, name) for name in self.reader.resources) + dirs = map(ResourceContainer, self.reader.children()) + return itertools.chain(files, dirs) + + def open(self, *args, **kwargs): + raise IsADirectoryError() + + +class ResourceHandle(Traversable): + """ + Handle to a named resource in a ResourceReader. + """ + + def __init__(self, parent: ResourceContainer, name: str): + self.parent = parent + self.name = name # type: ignore + + def is_file(self): + return True + + def is_dir(self): + return False + + def open(self, mode='r', *args, **kwargs): + stream = self.parent.reader.open_binary(self.name) + if 'b' not in mode: + stream = io.TextIOWrapper(*args, **kwargs) + return stream + + def joinpath(self, name): + raise RuntimeError("Cannot traverse into a resource") + + +class TraversableReader(TraversableResources, SimpleReader): + """ + A TraversableResources based on SimpleReader. Resource providers + may derive from this class to provide the TraversableResources + interface by supplying the SimpleReader interface. + """ + + def files(self): + return ResourceContainer(self) diff --git a/uno/lib/python/pkg_resources/_vendor/jaraco/__init__.py b/uno/lib/python/pkg_resources/_vendor/jaraco/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/pkg_resources/_vendor/jaraco/context.py b/uno/lib/python/pkg_resources/_vendor/jaraco/context.py new file mode 100644 index 00000000..b0d1ef37 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/jaraco/context.py @@ -0,0 +1,288 @@ +import os +import subprocess +import contextlib +import functools +import tempfile +import shutil +import operator +import warnings + + +@contextlib.contextmanager +def pushd(dir): + """ + >>> tmp_path = getfixture('tmp_path') + >>> with pushd(tmp_path): + ... assert os.getcwd() == os.fspath(tmp_path) + >>> assert os.getcwd() != os.fspath(tmp_path) + """ + + orig = os.getcwd() + os.chdir(dir) + try: + yield dir + finally: + os.chdir(orig) + + +@contextlib.contextmanager +def tarball_context(url, target_dir=None, runner=None, pushd=pushd): + """ + Get a tarball, extract it, change to that directory, yield, then + clean up. + `runner` is the function to invoke commands. + `pushd` is a context manager for changing the directory. + """ + if target_dir is None: + target_dir = os.path.basename(url).replace('.tar.gz', '').replace('.tgz', '') + if runner is None: + runner = functools.partial(subprocess.check_call, shell=True) + else: + warnings.warn("runner parameter is deprecated", DeprecationWarning) + # In the tar command, use --strip-components=1 to strip the first path and + # then + # use -C to cause the files to be extracted to {target_dir}. This ensures + # that we always know where the files were extracted. + runner('mkdir {target_dir}'.format(**vars())) + try: + getter = 'wget {url} -O -' + extract = 'tar x{compression} --strip-components=1 -C {target_dir}' + cmd = ' | '.join((getter, extract)) + runner(cmd.format(compression=infer_compression(url), **vars())) + with pushd(target_dir): + yield target_dir + finally: + runner('rm -Rf {target_dir}'.format(**vars())) + + +def infer_compression(url): + """ + Given a URL or filename, infer the compression code for tar. + + >>> infer_compression('http://foo/bar.tar.gz') + 'z' + >>> infer_compression('http://foo/bar.tgz') + 'z' + >>> infer_compression('file.bz') + 'j' + >>> infer_compression('file.xz') + 'J' + """ + # cheat and just assume it's the last two characters + compression_indicator = url[-2:] + mapping = dict(gz='z', bz='j', xz='J') + # Assume 'z' (gzip) if no match + return mapping.get(compression_indicator, 'z') + + +@contextlib.contextmanager +def temp_dir(remover=shutil.rmtree): + """ + Create a temporary directory context. Pass a custom remover + to override the removal behavior. + + >>> import pathlib + >>> with temp_dir() as the_dir: + ... assert os.path.isdir(the_dir) + ... _ = pathlib.Path(the_dir).joinpath('somefile').write_text('contents') + >>> assert not os.path.exists(the_dir) + """ + temp_dir = tempfile.mkdtemp() + try: + yield temp_dir + finally: + remover(temp_dir) + + +@contextlib.contextmanager +def repo_context(url, branch=None, quiet=True, dest_ctx=temp_dir): + """ + Check out the repo indicated by url. + + If dest_ctx is supplied, it should be a context manager + to yield the target directory for the check out. + """ + exe = 'git' if 'git' in url else 'hg' + with dest_ctx() as repo_dir: + cmd = [exe, 'clone', url, repo_dir] + if branch: + cmd.extend(['--branch', branch]) + devnull = open(os.path.devnull, 'w') + stdout = devnull if quiet else None + subprocess.check_call(cmd, stdout=stdout) + yield repo_dir + + +@contextlib.contextmanager +def null(): + """ + A null context suitable to stand in for a meaningful context. + + >>> with null() as value: + ... assert value is None + """ + yield + + +class ExceptionTrap: + """ + A context manager that will catch certain exceptions and provide an + indication they occurred. + + >>> with ExceptionTrap() as trap: + ... raise Exception() + >>> bool(trap) + True + + >>> with ExceptionTrap() as trap: + ... pass + >>> bool(trap) + False + + >>> with ExceptionTrap(ValueError) as trap: + ... raise ValueError("1 + 1 is not 3") + >>> bool(trap) + True + >>> trap.value + ValueError('1 + 1 is not 3') + >>> trap.tb + + + >>> with ExceptionTrap(ValueError) as trap: + ... raise Exception() + Traceback (most recent call last): + ... + Exception + + >>> bool(trap) + False + """ + + exc_info = None, None, None + + def __init__(self, exceptions=(Exception,)): + self.exceptions = exceptions + + def __enter__(self): + return self + + @property + def type(self): + return self.exc_info[0] + + @property + def value(self): + return self.exc_info[1] + + @property + def tb(self): + return self.exc_info[2] + + def __exit__(self, *exc_info): + type = exc_info[0] + matches = type and issubclass(type, self.exceptions) + if matches: + self.exc_info = exc_info + return matches + + def __bool__(self): + return bool(self.type) + + def raises(self, func, *, _test=bool): + """ + Wrap func and replace the result with the truth + value of the trap (True if an exception occurred). + + First, give the decorator an alias to support Python 3.8 + Syntax. + + >>> raises = ExceptionTrap(ValueError).raises + + Now decorate a function that always fails. + + >>> @raises + ... def fail(): + ... raise ValueError('failed') + >>> fail() + True + """ + + @functools.wraps(func) + def wrapper(*args, **kwargs): + with ExceptionTrap(self.exceptions) as trap: + func(*args, **kwargs) + return _test(trap) + + return wrapper + + def passes(self, func): + """ + Wrap func and replace the result with the truth + value of the trap (True if no exception). + + First, give the decorator an alias to support Python 3.8 + Syntax. + + >>> passes = ExceptionTrap(ValueError).passes + + Now decorate a function that always fails. + + >>> @passes + ... def fail(): + ... raise ValueError('failed') + + >>> fail() + False + """ + return self.raises(func, _test=operator.not_) + + +class suppress(contextlib.suppress, contextlib.ContextDecorator): + """ + A version of contextlib.suppress with decorator support. + + >>> @suppress(KeyError) + ... def key_error(): + ... {}[''] + >>> key_error() + """ + + +class on_interrupt(contextlib.ContextDecorator): + """ + Replace a KeyboardInterrupt with SystemExit(1) + + >>> def do_interrupt(): + ... raise KeyboardInterrupt() + >>> on_interrupt('error')(do_interrupt)() + Traceback (most recent call last): + ... + SystemExit: 1 + >>> on_interrupt('error', code=255)(do_interrupt)() + Traceback (most recent call last): + ... + SystemExit: 255 + >>> on_interrupt('suppress')(do_interrupt)() + >>> with __import__('pytest').raises(KeyboardInterrupt): + ... on_interrupt('ignore')(do_interrupt)() + """ + + def __init__( + self, + action='error', + # py3.7 compat + # /, + code=1, + ): + self.action = action + self.code = code + + def __enter__(self): + return self + + def __exit__(self, exctype, excinst, exctb): + if exctype is not KeyboardInterrupt or self.action == 'ignore': + return + elif self.action == 'error': + raise SystemExit(self.code) from excinst + return self.action == 'suppress' diff --git a/uno/lib/python/pkg_resources/_vendor/jaraco/functools.py b/uno/lib/python/pkg_resources/_vendor/jaraco/functools.py new file mode 100644 index 00000000..67aeadc3 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/jaraco/functools.py @@ -0,0 +1,556 @@ +import functools +import time +import inspect +import collections +import types +import itertools +import warnings + +import pkg_resources.extern.more_itertools + +from typing import Callable, TypeVar + + +CallableT = TypeVar("CallableT", bound=Callable[..., object]) + + +def compose(*funcs): + """ + Compose any number of unary functions into a single unary function. + + >>> import textwrap + >>> expected = str.strip(textwrap.dedent(compose.__doc__)) + >>> strip_and_dedent = compose(str.strip, textwrap.dedent) + >>> strip_and_dedent(compose.__doc__) == expected + True + + Compose also allows the innermost function to take arbitrary arguments. + + >>> round_three = lambda x: round(x, ndigits=3) + >>> f = compose(round_three, int.__truediv__) + >>> [f(3*x, x+1) for x in range(1,10)] + [1.5, 2.0, 2.25, 2.4, 2.5, 2.571, 2.625, 2.667, 2.7] + """ + + def compose_two(f1, f2): + return lambda *args, **kwargs: f1(f2(*args, **kwargs)) + + return functools.reduce(compose_two, funcs) + + +def method_caller(method_name, *args, **kwargs): + """ + Return a function that will call a named method on the + target object with optional positional and keyword + arguments. + + >>> lower = method_caller('lower') + >>> lower('MyString') + 'mystring' + """ + + def call_method(target): + func = getattr(target, method_name) + return func(*args, **kwargs) + + return call_method + + +def once(func): + """ + Decorate func so it's only ever called the first time. + + This decorator can ensure that an expensive or non-idempotent function + will not be expensive on subsequent calls and is idempotent. + + >>> add_three = once(lambda a: a+3) + >>> add_three(3) + 6 + >>> add_three(9) + 6 + >>> add_three('12') + 6 + + To reset the stored value, simply clear the property ``saved_result``. + + >>> del add_three.saved_result + >>> add_three(9) + 12 + >>> add_three(8) + 12 + + Or invoke 'reset()' on it. + + >>> add_three.reset() + >>> add_three(-3) + 0 + >>> add_three(0) + 0 + """ + + @functools.wraps(func) + def wrapper(*args, **kwargs): + if not hasattr(wrapper, 'saved_result'): + wrapper.saved_result = func(*args, **kwargs) + return wrapper.saved_result + + wrapper.reset = lambda: vars(wrapper).__delitem__('saved_result') + return wrapper + + +def method_cache( + method: CallableT, + cache_wrapper: Callable[ + [CallableT], CallableT + ] = functools.lru_cache(), # type: ignore[assignment] +) -> CallableT: + """ + Wrap lru_cache to support storing the cache data in the object instances. + + Abstracts the common paradigm where the method explicitly saves an + underscore-prefixed protected property on first call and returns that + subsequently. + + >>> class MyClass: + ... calls = 0 + ... + ... @method_cache + ... def method(self, value): + ... self.calls += 1 + ... return value + + >>> a = MyClass() + >>> a.method(3) + 3 + >>> for x in range(75): + ... res = a.method(x) + >>> a.calls + 75 + + Note that the apparent behavior will be exactly like that of lru_cache + except that the cache is stored on each instance, so values in one + instance will not flush values from another, and when an instance is + deleted, so are the cached values for that instance. + + >>> b = MyClass() + >>> for x in range(35): + ... res = b.method(x) + >>> b.calls + 35 + >>> a.method(0) + 0 + >>> a.calls + 75 + + Note that if method had been decorated with ``functools.lru_cache()``, + a.calls would have been 76 (due to the cached value of 0 having been + flushed by the 'b' instance). + + Clear the cache with ``.cache_clear()`` + + >>> a.method.cache_clear() + + Same for a method that hasn't yet been called. + + >>> c = MyClass() + >>> c.method.cache_clear() + + Another cache wrapper may be supplied: + + >>> cache = functools.lru_cache(maxsize=2) + >>> MyClass.method2 = method_cache(lambda self: 3, cache_wrapper=cache) + >>> a = MyClass() + >>> a.method2() + 3 + + Caution - do not subsequently wrap the method with another decorator, such + as ``@property``, which changes the semantics of the function. + + See also + http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ + for another implementation and additional justification. + """ + + def wrapper(self: object, *args: object, **kwargs: object) -> object: + # it's the first call, replace the method with a cached, bound method + bound_method: CallableT = types.MethodType( # type: ignore[assignment] + method, self + ) + cached_method = cache_wrapper(bound_method) + setattr(self, method.__name__, cached_method) + return cached_method(*args, **kwargs) + + # Support cache clear even before cache has been created. + wrapper.cache_clear = lambda: None # type: ignore[attr-defined] + + return ( # type: ignore[return-value] + _special_method_cache(method, cache_wrapper) or wrapper + ) + + +def _special_method_cache(method, cache_wrapper): + """ + Because Python treats special methods differently, it's not + possible to use instance attributes to implement the cached + methods. + + Instead, install the wrapper method under a different name + and return a simple proxy to that wrapper. + + https://github.com/jaraco/jaraco.functools/issues/5 + """ + name = method.__name__ + special_names = '__getattr__', '__getitem__' + if name not in special_names: + return + + wrapper_name = '__cached' + name + + def proxy(self, *args, **kwargs): + if wrapper_name not in vars(self): + bound = types.MethodType(method, self) + cache = cache_wrapper(bound) + setattr(self, wrapper_name, cache) + else: + cache = getattr(self, wrapper_name) + return cache(*args, **kwargs) + + return proxy + + +def apply(transform): + """ + Decorate a function with a transform function that is + invoked on results returned from the decorated function. + + >>> @apply(reversed) + ... def get_numbers(start): + ... "doc for get_numbers" + ... return range(start, start+3) + >>> list(get_numbers(4)) + [6, 5, 4] + >>> get_numbers.__doc__ + 'doc for get_numbers' + """ + + def wrap(func): + return functools.wraps(func)(compose(transform, func)) + + return wrap + + +def result_invoke(action): + r""" + Decorate a function with an action function that is + invoked on the results returned from the decorated + function (for its side-effect), then return the original + result. + + >>> @result_invoke(print) + ... def add_two(a, b): + ... return a + b + >>> x = add_two(2, 3) + 5 + >>> x + 5 + """ + + def wrap(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + result = func(*args, **kwargs) + action(result) + return result + + return wrapper + + return wrap + + +def invoke(f, *args, **kwargs): + """ + Call a function for its side effect after initialization. + + The benefit of using the decorator instead of simply invoking a function + after defining it is that it makes explicit the author's intent for the + function to be called immediately. Whereas if one simply calls the + function immediately, it's less obvious if that was intentional or + incidental. It also avoids repeating the name - the two actions, defining + the function and calling it immediately are modeled separately, but linked + by the decorator construct. + + The benefit of having a function construct (opposed to just invoking some + behavior inline) is to serve as a scope in which the behavior occurs. It + avoids polluting the global namespace with local variables, provides an + anchor on which to attach documentation (docstring), keeps the behavior + logically separated (instead of conceptually separated or not separated at + all), and provides potential to re-use the behavior for testing or other + purposes. + + This function is named as a pithy way to communicate, "call this function + primarily for its side effect", or "while defining this function, also + take it aside and call it". It exists because there's no Python construct + for "define and call" (nor should there be, as decorators serve this need + just fine). The behavior happens immediately and synchronously. + + >>> @invoke + ... def func(): print("called") + called + >>> func() + called + + Use functools.partial to pass parameters to the initial call + + >>> @functools.partial(invoke, name='bingo') + ... def func(name): print("called with", name) + called with bingo + """ + f(*args, **kwargs) + return f + + +def call_aside(*args, **kwargs): + """ + Deprecated name for invoke. + """ + warnings.warn("call_aside is deprecated, use invoke", DeprecationWarning) + return invoke(*args, **kwargs) + + +class Throttler: + """ + Rate-limit a function (or other callable) + """ + + def __init__(self, func, max_rate=float('Inf')): + if isinstance(func, Throttler): + func = func.func + self.func = func + self.max_rate = max_rate + self.reset() + + def reset(self): + self.last_called = 0 + + def __call__(self, *args, **kwargs): + self._wait() + return self.func(*args, **kwargs) + + def _wait(self): + "ensure at least 1/max_rate seconds from last call" + elapsed = time.time() - self.last_called + must_wait = 1 / self.max_rate - elapsed + time.sleep(max(0, must_wait)) + self.last_called = time.time() + + def __get__(self, obj, type=None): + return first_invoke(self._wait, functools.partial(self.func, obj)) + + +def first_invoke(func1, func2): + """ + Return a function that when invoked will invoke func1 without + any parameters (for its side-effect) and then invoke func2 + with whatever parameters were passed, returning its result. + """ + + def wrapper(*args, **kwargs): + func1() + return func2(*args, **kwargs) + + return wrapper + + +def retry_call(func, cleanup=lambda: None, retries=0, trap=()): + """ + Given a callable func, trap the indicated exceptions + for up to 'retries' times, invoking cleanup on the + exception. On the final attempt, allow any exceptions + to propagate. + """ + attempts = itertools.count() if retries == float('inf') else range(retries) + for attempt in attempts: + try: + return func() + except trap: + cleanup() + + return func() + + +def retry(*r_args, **r_kwargs): + """ + Decorator wrapper for retry_call. Accepts arguments to retry_call + except func and then returns a decorator for the decorated function. + + Ex: + + >>> @retry(retries=3) + ... def my_func(a, b): + ... "this is my funk" + ... print(a, b) + >>> my_func.__doc__ + 'this is my funk' + """ + + def decorate(func): + @functools.wraps(func) + def wrapper(*f_args, **f_kwargs): + bound = functools.partial(func, *f_args, **f_kwargs) + return retry_call(bound, *r_args, **r_kwargs) + + return wrapper + + return decorate + + +def print_yielded(func): + """ + Convert a generator into a function that prints all yielded elements + + >>> @print_yielded + ... def x(): + ... yield 3; yield None + >>> x() + 3 + None + """ + print_all = functools.partial(map, print) + print_results = compose(more_itertools.consume, print_all, func) + return functools.wraps(func)(print_results) + + +def pass_none(func): + """ + Wrap func so it's not called if its first param is None + + >>> print_text = pass_none(print) + >>> print_text('text') + text + >>> print_text(None) + """ + + @functools.wraps(func) + def wrapper(param, *args, **kwargs): + if param is not None: + return func(param, *args, **kwargs) + + return wrapper + + +def assign_params(func, namespace): + """ + Assign parameters from namespace where func solicits. + + >>> def func(x, y=3): + ... print(x, y) + >>> assigned = assign_params(func, dict(x=2, z=4)) + >>> assigned() + 2 3 + + The usual errors are raised if a function doesn't receive + its required parameters: + + >>> assigned = assign_params(func, dict(y=3, z=4)) + >>> assigned() + Traceback (most recent call last): + TypeError: func() ...argument... + + It even works on methods: + + >>> class Handler: + ... def meth(self, arg): + ... print(arg) + >>> assign_params(Handler().meth, dict(arg='crystal', foo='clear'))() + crystal + """ + sig = inspect.signature(func) + params = sig.parameters.keys() + call_ns = {k: namespace[k] for k in params if k in namespace} + return functools.partial(func, **call_ns) + + +def save_method_args(method): + """ + Wrap a method such that when it is called, the args and kwargs are + saved on the method. + + >>> class MyClass: + ... @save_method_args + ... def method(self, a, b): + ... print(a, b) + >>> my_ob = MyClass() + >>> my_ob.method(1, 2) + 1 2 + >>> my_ob._saved_method.args + (1, 2) + >>> my_ob._saved_method.kwargs + {} + >>> my_ob.method(a=3, b='foo') + 3 foo + >>> my_ob._saved_method.args + () + >>> my_ob._saved_method.kwargs == dict(a=3, b='foo') + True + + The arguments are stored on the instance, allowing for + different instance to save different args. + + >>> your_ob = MyClass() + >>> your_ob.method({str('x'): 3}, b=[4]) + {'x': 3} [4] + >>> your_ob._saved_method.args + ({'x': 3},) + >>> my_ob._saved_method.args + () + """ + args_and_kwargs = collections.namedtuple('args_and_kwargs', 'args kwargs') + + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + attr_name = '_saved_' + method.__name__ + attr = args_and_kwargs(args, kwargs) + setattr(self, attr_name, attr) + return method(self, *args, **kwargs) + + return wrapper + + +def except_(*exceptions, replace=None, use=None): + """ + Replace the indicated exceptions, if raised, with the indicated + literal replacement or evaluated expression (if present). + + >>> safe_int = except_(ValueError)(int) + >>> safe_int('five') + >>> safe_int('5') + 5 + + Specify a literal replacement with ``replace``. + + >>> safe_int_r = except_(ValueError, replace=0)(int) + >>> safe_int_r('five') + 0 + + Provide an expression to ``use`` to pass through particular parameters. + + >>> safe_int_pt = except_(ValueError, use='args[0]')(int) + >>> safe_int_pt('five') + 'five' + + """ + + def decorate(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except exceptions: + try: + return eval(use) + except TypeError: + return replace + + return wrapper + + return decorate diff --git a/uno/lib/python/pkg_resources/_vendor/jaraco/text/__init__.py b/uno/lib/python/pkg_resources/_vendor/jaraco/text/__init__.py new file mode 100644 index 00000000..c466378c --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/jaraco/text/__init__.py @@ -0,0 +1,599 @@ +import re +import itertools +import textwrap +import functools + +try: + from importlib.resources import files # type: ignore +except ImportError: # pragma: nocover + from pkg_resources.extern.importlib_resources import files # type: ignore + +from pkg_resources.extern.jaraco.functools import compose, method_cache +from pkg_resources.extern.jaraco.context import ExceptionTrap + + +def substitution(old, new): + """ + Return a function that will perform a substitution on a string + """ + return lambda s: s.replace(old, new) + + +def multi_substitution(*substitutions): + """ + Take a sequence of pairs specifying substitutions, and create + a function that performs those substitutions. + + >>> multi_substitution(('foo', 'bar'), ('bar', 'baz'))('foo') + 'baz' + """ + substitutions = itertools.starmap(substitution, substitutions) + # compose function applies last function first, so reverse the + # substitutions to get the expected order. + substitutions = reversed(tuple(substitutions)) + return compose(*substitutions) + + +class FoldedCase(str): + """ + A case insensitive string class; behaves just like str + except compares equal when the only variation is case. + + >>> s = FoldedCase('hello world') + + >>> s == 'Hello World' + True + + >>> 'Hello World' == s + True + + >>> s != 'Hello World' + False + + >>> s.index('O') + 4 + + >>> s.split('O') + ['hell', ' w', 'rld'] + + >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) + ['alpha', 'Beta', 'GAMMA'] + + Sequence membership is straightforward. + + >>> "Hello World" in [s] + True + >>> s in ["Hello World"] + True + + You may test for set inclusion, but candidate and elements + must both be folded. + + >>> FoldedCase("Hello World") in {s} + True + >>> s in {FoldedCase("Hello World")} + True + + String inclusion works as long as the FoldedCase object + is on the right. + + >>> "hello" in FoldedCase("Hello World") + True + + But not if the FoldedCase object is on the left: + + >>> FoldedCase('hello') in 'Hello World' + False + + In that case, use ``in_``: + + >>> FoldedCase('hello').in_('Hello World') + True + + >>> FoldedCase('hello') > FoldedCase('Hello') + False + """ + + def __lt__(self, other): + return self.lower() < other.lower() + + def __gt__(self, other): + return self.lower() > other.lower() + + def __eq__(self, other): + return self.lower() == other.lower() + + def __ne__(self, other): + return self.lower() != other.lower() + + def __hash__(self): + return hash(self.lower()) + + def __contains__(self, other): + return super().lower().__contains__(other.lower()) + + def in_(self, other): + "Does self appear in other?" + return self in FoldedCase(other) + + # cache lower since it's likely to be called frequently. + @method_cache + def lower(self): + return super().lower() + + def index(self, sub): + return self.lower().index(sub.lower()) + + def split(self, splitter=' ', maxsplit=0): + pattern = re.compile(re.escape(splitter), re.I) + return pattern.split(self, maxsplit) + + +# Python 3.8 compatibility +_unicode_trap = ExceptionTrap(UnicodeDecodeError) + + +@_unicode_trap.passes +def is_decodable(value): + r""" + Return True if the supplied value is decodable (using the default + encoding). + + >>> is_decodable(b'\xff') + False + >>> is_decodable(b'\x32') + True + """ + value.decode() + + +def is_binary(value): + r""" + Return True if the value appears to be binary (that is, it's a byte + string and isn't decodable). + + >>> is_binary(b'\xff') + True + >>> is_binary('\xff') + False + """ + return isinstance(value, bytes) and not is_decodable(value) + + +def trim(s): + r""" + Trim something like a docstring to remove the whitespace that + is common due to indentation and formatting. + + >>> trim("\n\tfoo = bar\n\t\tbar = baz\n") + 'foo = bar\n\tbar = baz' + """ + return textwrap.dedent(s).strip() + + +def wrap(s): + """ + Wrap lines of text, retaining existing newlines as + paragraph markers. + + >>> print(wrap(lorem_ipsum)) + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + + Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam + varius, turpis et commodo pharetra, est eros bibendum elit, nec luctus + magna felis sollicitudin mauris. Integer in mauris eu nibh euismod + gravida. Duis ac tellus et risus vulputate vehicula. Donec lobortis + risus a elit. Etiam tempor. Ut ullamcorper, ligula eu tempor congue, + eros est euismod turpis, id tincidunt sapien risus a quam. Maecenas + fermentum consequat mi. Donec fermentum. Pellentesque malesuada nulla + a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, + neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing + sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque + nunc. Nullam arcu. Aliquam consequat. Curabitur augue lorem, dapibus + quis, laoreet et, pretium ac, nisi. Aenean magna nisl, mollis quis, + molestie eu, feugiat in, orci. In hac habitasse platea dictumst. + """ + paragraphs = s.splitlines() + wrapped = ('\n'.join(textwrap.wrap(para)) for para in paragraphs) + return '\n\n'.join(wrapped) + + +def unwrap(s): + r""" + Given a multi-line string, return an unwrapped version. + + >>> wrapped = wrap(lorem_ipsum) + >>> wrapped.count('\n') + 20 + >>> unwrapped = unwrap(wrapped) + >>> unwrapped.count('\n') + 1 + >>> print(unwrapped) + Lorem ipsum dolor sit amet, consectetur adipiscing ... + Curabitur pretium tincidunt lacus. Nulla gravida orci ... + + """ + paragraphs = re.split(r'\n\n+', s) + cleaned = (para.replace('\n', ' ') for para in paragraphs) + return '\n'.join(cleaned) + + + + +class Splitter(object): + """object that will split a string with the given arguments for each call + + >>> s = Splitter(',') + >>> s('hello, world, this is your, master calling') + ['hello', ' world', ' this is your', ' master calling'] + """ + + def __init__(self, *args): + self.args = args + + def __call__(self, s): + return s.split(*self.args) + + +def indent(string, prefix=' ' * 4): + """ + >>> indent('foo') + ' foo' + """ + return prefix + string + + +class WordSet(tuple): + """ + Given an identifier, return the words that identifier represents, + whether in camel case, underscore-separated, etc. + + >>> WordSet.parse("camelCase") + ('camel', 'Case') + + >>> WordSet.parse("under_sep") + ('under', 'sep') + + Acronyms should be retained + + >>> WordSet.parse("firstSNL") + ('first', 'SNL') + + >>> WordSet.parse("you_and_I") + ('you', 'and', 'I') + + >>> WordSet.parse("A simple test") + ('A', 'simple', 'test') + + Multiple caps should not interfere with the first cap of another word. + + >>> WordSet.parse("myABCClass") + ('my', 'ABC', 'Class') + + The result is a WordSet, so you can get the form you need. + + >>> WordSet.parse("myABCClass").underscore_separated() + 'my_ABC_Class' + + >>> WordSet.parse('a-command').camel_case() + 'ACommand' + + >>> WordSet.parse('someIdentifier').lowered().space_separated() + 'some identifier' + + Slices of the result should return another WordSet. + + >>> WordSet.parse('taken-out-of-context')[1:].underscore_separated() + 'out_of_context' + + >>> WordSet.from_class_name(WordSet()).lowered().space_separated() + 'word set' + + >>> example = WordSet.parse('figured it out') + >>> example.headless_camel_case() + 'figuredItOut' + >>> example.dash_separated() + 'figured-it-out' + + """ + + _pattern = re.compile('([A-Z]?[a-z]+)|([A-Z]+(?![a-z]))') + + def capitalized(self): + return WordSet(word.capitalize() for word in self) + + def lowered(self): + return WordSet(word.lower() for word in self) + + def camel_case(self): + return ''.join(self.capitalized()) + + def headless_camel_case(self): + words = iter(self) + first = next(words).lower() + new_words = itertools.chain((first,), WordSet(words).camel_case()) + return ''.join(new_words) + + def underscore_separated(self): + return '_'.join(self) + + def dash_separated(self): + return '-'.join(self) + + def space_separated(self): + return ' '.join(self) + + def trim_right(self, item): + """ + Remove the item from the end of the set. + + >>> WordSet.parse('foo bar').trim_right('foo') + ('foo', 'bar') + >>> WordSet.parse('foo bar').trim_right('bar') + ('foo',) + >>> WordSet.parse('').trim_right('bar') + () + """ + return self[:-1] if self and self[-1] == item else self + + def trim_left(self, item): + """ + Remove the item from the beginning of the set. + + >>> WordSet.parse('foo bar').trim_left('foo') + ('bar',) + >>> WordSet.parse('foo bar').trim_left('bar') + ('foo', 'bar') + >>> WordSet.parse('').trim_left('bar') + () + """ + return self[1:] if self and self[0] == item else self + + def trim(self, item): + """ + >>> WordSet.parse('foo bar').trim('foo') + ('bar',) + """ + return self.trim_left(item).trim_right(item) + + def __getitem__(self, item): + result = super(WordSet, self).__getitem__(item) + if isinstance(item, slice): + result = WordSet(result) + return result + + @classmethod + def parse(cls, identifier): + matches = cls._pattern.finditer(identifier) + return WordSet(match.group(0) for match in matches) + + @classmethod + def from_class_name(cls, subject): + return cls.parse(subject.__class__.__name__) + + +# for backward compatibility +words = WordSet.parse + + +def simple_html_strip(s): + r""" + Remove HTML from the string `s`. + + >>> str(simple_html_strip('')) + '' + + >>> print(simple_html_strip('A stormy day in paradise')) + A stormy day in paradise + + >>> print(simple_html_strip('Somebody tell the truth.')) + Somebody tell the truth. + + >>> print(simple_html_strip('What about
\nmultiple lines?')) + What about + multiple lines? + """ + html_stripper = re.compile('()|(<[^>]*>)|([^<]+)', re.DOTALL) + texts = (match.group(3) or '' for match in html_stripper.finditer(s)) + return ''.join(texts) + + +class SeparatedValues(str): + """ + A string separated by a separator. Overrides __iter__ for getting + the values. + + >>> list(SeparatedValues('a,b,c')) + ['a', 'b', 'c'] + + Whitespace is stripped and empty values are discarded. + + >>> list(SeparatedValues(' a, b , c, ')) + ['a', 'b', 'c'] + """ + + separator = ',' + + def __iter__(self): + parts = self.split(self.separator) + return filter(None, (part.strip() for part in parts)) + + +class Stripper: + r""" + Given a series of lines, find the common prefix and strip it from them. + + >>> lines = [ + ... 'abcdefg\n', + ... 'abc\n', + ... 'abcde\n', + ... ] + >>> res = Stripper.strip_prefix(lines) + >>> res.prefix + 'abc' + >>> list(res.lines) + ['defg\n', '\n', 'de\n'] + + If no prefix is common, nothing should be stripped. + + >>> lines = [ + ... 'abcd\n', + ... '1234\n', + ... ] + >>> res = Stripper.strip_prefix(lines) + >>> res.prefix = '' + >>> list(res.lines) + ['abcd\n', '1234\n'] + """ + + def __init__(self, prefix, lines): + self.prefix = prefix + self.lines = map(self, lines) + + @classmethod + def strip_prefix(cls, lines): + prefix_lines, lines = itertools.tee(lines) + prefix = functools.reduce(cls.common_prefix, prefix_lines) + return cls(prefix, lines) + + def __call__(self, line): + if not self.prefix: + return line + null, prefix, rest = line.partition(self.prefix) + return rest + + @staticmethod + def common_prefix(s1, s2): + """ + Return the common prefix of two lines. + """ + index = min(len(s1), len(s2)) + while s1[:index] != s2[:index]: + index -= 1 + return s1[:index] + + +def remove_prefix(text, prefix): + """ + Remove the prefix from the text if it exists. + + >>> remove_prefix('underwhelming performance', 'underwhelming ') + 'performance' + + >>> remove_prefix('something special', 'sample') + 'something special' + """ + null, prefix, rest = text.rpartition(prefix) + return rest + + +def remove_suffix(text, suffix): + """ + Remove the suffix from the text if it exists. + + >>> remove_suffix('name.git', '.git') + 'name' + + >>> remove_suffix('something special', 'sample') + 'something special' + """ + rest, suffix, null = text.partition(suffix) + return rest + + +def normalize_newlines(text): + r""" + Replace alternate newlines with the canonical newline. + + >>> normalize_newlines('Lorem Ipsum\u2029') + 'Lorem Ipsum\n' + >>> normalize_newlines('Lorem Ipsum\r\n') + 'Lorem Ipsum\n' + >>> normalize_newlines('Lorem Ipsum\x85') + 'Lorem Ipsum\n' + """ + newlines = ['\r\n', '\r', '\n', '\u0085', '\u2028', '\u2029'] + pattern = '|'.join(newlines) + return re.sub(pattern, '\n', text) + + +def _nonblank(str): + return str and not str.startswith('#') + + +@functools.singledispatch +def yield_lines(iterable): + r""" + Yield valid lines of a string or iterable. + + >>> list(yield_lines('')) + [] + >>> list(yield_lines(['foo', 'bar'])) + ['foo', 'bar'] + >>> list(yield_lines('foo\nbar')) + ['foo', 'bar'] + >>> list(yield_lines('\nfoo\n#bar\nbaz #comment')) + ['foo', 'baz #comment'] + >>> list(yield_lines(['foo\nbar', 'baz', 'bing\n\n\n'])) + ['foo', 'bar', 'baz', 'bing'] + """ + return itertools.chain.from_iterable(map(yield_lines, iterable)) + + +@yield_lines.register(str) +def _(text): + return filter(_nonblank, map(str.strip, text.splitlines())) + + +def drop_comment(line): + """ + Drop comments. + + >>> drop_comment('foo # bar') + 'foo' + + A hash without a space may be in a URL. + + >>> drop_comment('http://example.com/foo#bar') + 'http://example.com/foo#bar' + """ + return line.partition(' #')[0] + + +def join_continuation(lines): + r""" + Join lines continued by a trailing backslash. + + >>> list(join_continuation(['foo \\', 'bar', 'baz'])) + ['foobar', 'baz'] + >>> list(join_continuation(['foo \\', 'bar', 'baz'])) + ['foobar', 'baz'] + >>> list(join_continuation(['foo \\', 'bar \\', 'baz'])) + ['foobarbaz'] + + Not sure why, but... + The character preceeding the backslash is also elided. + + >>> list(join_continuation(['goo\\', 'dly'])) + ['godly'] + + A terrible idea, but... + If no line is available to continue, suppress the lines. + + >>> list(join_continuation(['foo', 'bar\\', 'baz\\'])) + ['foo'] + """ + lines = iter(lines) + for item in lines: + while item.endswith('\\'): + try: + item = item[:-2].strip() + next(lines) + except StopIteration: + return + yield item diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.py b/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.py new file mode 100644 index 00000000..66443971 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.py @@ -0,0 +1,6 @@ +"""More routines for operating on iterables, beyond itertools""" + +from .more import * # noqa +from .recipes import * # noqa + +__version__ = '9.1.0' diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.pyi b/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.pyi new file mode 100644 index 00000000..96f6e36c --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/__init__.pyi @@ -0,0 +1,2 @@ +from .more import * +from .recipes import * diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/more.py b/uno/lib/python/pkg_resources/_vendor/more_itertools/more.py new file mode 100644 index 00000000..e0e2d3de --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/more.py @@ -0,0 +1,4391 @@ +import warnings + +from collections import Counter, defaultdict, deque, abc +from collections.abc import Sequence +from functools import partial, reduce, wraps +from heapq import heapify, heapreplace, heappop +from itertools import ( + chain, + compress, + count, + cycle, + dropwhile, + groupby, + islice, + repeat, + starmap, + takewhile, + tee, + zip_longest, +) +from math import exp, factorial, floor, log +from queue import Empty, Queue +from random import random, randrange, uniform +from operator import itemgetter, mul, sub, gt, lt, ge, le +from sys import hexversion, maxsize +from time import monotonic + +from .recipes import ( + _marker, + _zip_equal, + UnequalIterablesError, + consume, + flatten, + pairwise, + powerset, + take, + unique_everseen, + all_equal, +) + +__all__ = [ + 'AbortThread', + 'SequenceView', + 'UnequalIterablesError', + 'adjacent', + 'all_unique', + 'always_iterable', + 'always_reversible', + 'bucket', + 'callback_iter', + 'chunked', + 'chunked_even', + 'circular_shifts', + 'collapse', + 'combination_index', + 'consecutive_groups', + 'constrained_batches', + 'consumer', + 'count_cycle', + 'countable', + 'difference', + 'distinct_combinations', + 'distinct_permutations', + 'distribute', + 'divide', + 'duplicates_everseen', + 'duplicates_justseen', + 'exactly_n', + 'filter_except', + 'first', + 'gray_product', + 'groupby_transform', + 'ichunked', + 'iequals', + 'ilen', + 'interleave', + 'interleave_evenly', + 'interleave_longest', + 'intersperse', + 'is_sorted', + 'islice_extended', + 'iterate', + 'last', + 'locate', + 'longest_common_prefix', + 'lstrip', + 'make_decorator', + 'map_except', + 'map_if', + 'map_reduce', + 'mark_ends', + 'minmax', + 'nth_or_last', + 'nth_permutation', + 'nth_product', + 'numeric_range', + 'one', + 'only', + 'padded', + 'partitions', + 'peekable', + 'permutation_index', + 'product_index', + 'raise_', + 'repeat_each', + 'repeat_last', + 'replace', + 'rlocate', + 'rstrip', + 'run_length', + 'sample', + 'seekable', + 'set_partitions', + 'side_effect', + 'sliced', + 'sort_together', + 'split_after', + 'split_at', + 'split_before', + 'split_into', + 'split_when', + 'spy', + 'stagger', + 'strip', + 'strictly_n', + 'substrings', + 'substrings_indexes', + 'time_limited', + 'unique_in_window', + 'unique_to_each', + 'unzip', + 'value_chain', + 'windowed', + 'windowed_complete', + 'with_iter', + 'zip_broadcast', + 'zip_equal', + 'zip_offset', +] + + +def chunked(iterable, n, strict=False): + """Break *iterable* into lists of length *n*: + + >>> list(chunked([1, 2, 3, 4, 5, 6], 3)) + [[1, 2, 3], [4, 5, 6]] + + By the default, the last yielded list will have fewer than *n* elements + if the length of *iterable* is not divisible by *n*: + + >>> list(chunked([1, 2, 3, 4, 5, 6, 7, 8], 3)) + [[1, 2, 3], [4, 5, 6], [7, 8]] + + To use a fill-in value instead, see the :func:`grouper` recipe. + + If the length of *iterable* is not divisible by *n* and *strict* is + ``True``, then ``ValueError`` will be raised before the last + list is yielded. + + """ + iterator = iter(partial(take, n, iter(iterable)), []) + if strict: + if n is None: + raise ValueError('n must not be None when using strict mode.') + + def ret(): + for chunk in iterator: + if len(chunk) != n: + raise ValueError('iterable is not divisible by n.') + yield chunk + + return iter(ret()) + else: + return iterator + + +def first(iterable, default=_marker): + """Return the first item of *iterable*, or *default* if *iterable* is + empty. + + >>> first([0, 1, 2, 3]) + 0 + >>> first([], 'some default') + 'some default' + + If *default* is not provided and there are no items in the iterable, + raise ``ValueError``. + + :func:`first` is useful when you have a generator of expensive-to-retrieve + values and want any arbitrary one. It is marginally shorter than + ``next(iter(iterable), default)``. + + """ + try: + return next(iter(iterable)) + except StopIteration as e: + if default is _marker: + raise ValueError( + 'first() was called on an empty iterable, and no ' + 'default value was provided.' + ) from e + return default + + +def last(iterable, default=_marker): + """Return the last item of *iterable*, or *default* if *iterable* is + empty. + + >>> last([0, 1, 2, 3]) + 3 + >>> last([], 'some default') + 'some default' + + If *default* is not provided and there are no items in the iterable, + raise ``ValueError``. + """ + try: + if isinstance(iterable, Sequence): + return iterable[-1] + # Work around https://bugs.python.org/issue38525 + elif hasattr(iterable, '__reversed__') and (hexversion != 0x030800F0): + return next(reversed(iterable)) + else: + return deque(iterable, maxlen=1)[-1] + except (IndexError, TypeError, StopIteration): + if default is _marker: + raise ValueError( + 'last() was called on an empty iterable, and no default was ' + 'provided.' + ) + return default + + +def nth_or_last(iterable, n, default=_marker): + """Return the nth or the last item of *iterable*, + or *default* if *iterable* is empty. + + >>> nth_or_last([0, 1, 2, 3], 2) + 2 + >>> nth_or_last([0, 1], 2) + 1 + >>> nth_or_last([], 0, 'some default') + 'some default' + + If *default* is not provided and there are no items in the iterable, + raise ``ValueError``. + """ + return last(islice(iterable, n + 1), default=default) + + +class peekable: + """Wrap an iterator to allow lookahead and prepending elements. + + Call :meth:`peek` on the result to get the value that will be returned + by :func:`next`. This won't advance the iterator: + + >>> p = peekable(['a', 'b']) + >>> p.peek() + 'a' + >>> next(p) + 'a' + + Pass :meth:`peek` a default value to return that instead of raising + ``StopIteration`` when the iterator is exhausted. + + >>> p = peekable([]) + >>> p.peek('hi') + 'hi' + + peekables also offer a :meth:`prepend` method, which "inserts" items + at the head of the iterable: + + >>> p = peekable([1, 2, 3]) + >>> p.prepend(10, 11, 12) + >>> next(p) + 10 + >>> p.peek() + 11 + >>> list(p) + [11, 12, 1, 2, 3] + + peekables can be indexed. Index 0 is the item that will be returned by + :func:`next`, index 1 is the item after that, and so on: + The values up to the given index will be cached. + + >>> p = peekable(['a', 'b', 'c', 'd']) + >>> p[0] + 'a' + >>> p[1] + 'b' + >>> next(p) + 'a' + + Negative indexes are supported, but be aware that they will cache the + remaining items in the source iterator, which may require significant + storage. + + To check whether a peekable is exhausted, check its truth value: + + >>> p = peekable(['a', 'b']) + >>> if p: # peekable has items + ... list(p) + ['a', 'b'] + >>> if not p: # peekable is exhausted + ... list(p) + [] + + """ + + def __init__(self, iterable): + self._it = iter(iterable) + self._cache = deque() + + def __iter__(self): + return self + + def __bool__(self): + try: + self.peek() + except StopIteration: + return False + return True + + def peek(self, default=_marker): + """Return the item that will be next returned from ``next()``. + + Return ``default`` if there are no items left. If ``default`` is not + provided, raise ``StopIteration``. + + """ + if not self._cache: + try: + self._cache.append(next(self._it)) + except StopIteration: + if default is _marker: + raise + return default + return self._cache[0] + + def prepend(self, *items): + """Stack up items to be the next ones returned from ``next()`` or + ``self.peek()``. The items will be returned in + first in, first out order:: + + >>> p = peekable([1, 2, 3]) + >>> p.prepend(10, 11, 12) + >>> next(p) + 10 + >>> list(p) + [11, 12, 1, 2, 3] + + It is possible, by prepending items, to "resurrect" a peekable that + previously raised ``StopIteration``. + + >>> p = peekable([]) + >>> next(p) + Traceback (most recent call last): + ... + StopIteration + >>> p.prepend(1) + >>> next(p) + 1 + >>> next(p) + Traceback (most recent call last): + ... + StopIteration + + """ + self._cache.extendleft(reversed(items)) + + def __next__(self): + if self._cache: + return self._cache.popleft() + + return next(self._it) + + def _get_slice(self, index): + # Normalize the slice's arguments + step = 1 if (index.step is None) else index.step + if step > 0: + start = 0 if (index.start is None) else index.start + stop = maxsize if (index.stop is None) else index.stop + elif step < 0: + start = -1 if (index.start is None) else index.start + stop = (-maxsize - 1) if (index.stop is None) else index.stop + else: + raise ValueError('slice step cannot be zero') + + # If either the start or stop index is negative, we'll need to cache + # the rest of the iterable in order to slice from the right side. + if (start < 0) or (stop < 0): + self._cache.extend(self._it) + # Otherwise we'll need to find the rightmost index and cache to that + # point. + else: + n = min(max(start, stop) + 1, maxsize) + cache_len = len(self._cache) + if n >= cache_len: + self._cache.extend(islice(self._it, n - cache_len)) + + return list(self._cache)[index] + + def __getitem__(self, index): + if isinstance(index, slice): + return self._get_slice(index) + + cache_len = len(self._cache) + if index < 0: + self._cache.extend(self._it) + elif index >= cache_len: + self._cache.extend(islice(self._it, index + 1 - cache_len)) + + return self._cache[index] + + +def consumer(func): + """Decorator that automatically advances a PEP-342-style "reverse iterator" + to its first yield point so you don't have to call ``next()`` on it + manually. + + >>> @consumer + ... def tally(): + ... i = 0 + ... while True: + ... print('Thing number %s is %s.' % (i, (yield))) + ... i += 1 + ... + >>> t = tally() + >>> t.send('red') + Thing number 0 is red. + >>> t.send('fish') + Thing number 1 is fish. + + Without the decorator, you would have to call ``next(t)`` before + ``t.send()`` could be used. + + """ + + @wraps(func) + def wrapper(*args, **kwargs): + gen = func(*args, **kwargs) + next(gen) + return gen + + return wrapper + + +def ilen(iterable): + """Return the number of items in *iterable*. + + >>> ilen(x for x in range(1000000) if x % 3 == 0) + 333334 + + This consumes the iterable, so handle with care. + + """ + # This approach was selected because benchmarks showed it's likely the + # fastest of the known implementations at the time of writing. + # See GitHub tracker: #236, #230. + counter = count() + deque(zip(iterable, counter), maxlen=0) + return next(counter) + + +def iterate(func, start): + """Return ``start``, ``func(start)``, ``func(func(start))``, ... + + >>> from itertools import islice + >>> list(islice(iterate(lambda x: 2*x, 1), 10)) + [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] + + """ + while True: + yield start + start = func(start) + + +def with_iter(context_manager): + """Wrap an iterable in a ``with`` statement, so it closes once exhausted. + + For example, this will close the file when the iterator is exhausted:: + + upper_lines = (line.upper() for line in with_iter(open('foo'))) + + Any context manager which returns an iterable is a candidate for + ``with_iter``. + + """ + with context_manager as iterable: + yield from iterable + + +def one(iterable, too_short=None, too_long=None): + """Return the first item from *iterable*, which is expected to contain only + that item. Raise an exception if *iterable* is empty or has more than one + item. + + :func:`one` is useful for ensuring that an iterable contains only one item. + For example, it can be used to retrieve the result of a database query + that is expected to return a single row. + + If *iterable* is empty, ``ValueError`` will be raised. You may specify a + different exception with the *too_short* keyword: + + >>> it = [] + >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: too many items in iterable (expected 1)' + >>> too_short = IndexError('too few items') + >>> one(it, too_short=too_short) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + IndexError: too few items + + Similarly, if *iterable* contains more than one item, ``ValueError`` will + be raised. You may specify a different exception with the *too_long* + keyword: + + >>> it = ['too', 'many'] + >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: Expected exactly one item in iterable, but got 'too', + 'many', and perhaps more. + >>> too_long = RuntimeError + >>> one(it, too_long=too_long) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + RuntimeError + + Note that :func:`one` attempts to advance *iterable* twice to ensure there + is only one item. See :func:`spy` or :func:`peekable` to check iterable + contents less destructively. + + """ + it = iter(iterable) + + try: + first_value = next(it) + except StopIteration as e: + raise ( + too_short or ValueError('too few items in iterable (expected 1)') + ) from e + + try: + second_value = next(it) + except StopIteration: + pass + else: + msg = ( + 'Expected exactly one item in iterable, but got {!r}, {!r}, ' + 'and perhaps more.'.format(first_value, second_value) + ) + raise too_long or ValueError(msg) + + return first_value + + +def raise_(exception, *args): + raise exception(*args) + + +def strictly_n(iterable, n, too_short=None, too_long=None): + """Validate that *iterable* has exactly *n* items and return them if + it does. If it has fewer than *n* items, call function *too_short* + with those items. If it has more than *n* items, call function + *too_long* with the first ``n + 1`` items. + + >>> iterable = ['a', 'b', 'c', 'd'] + >>> n = 4 + >>> list(strictly_n(iterable, n)) + ['a', 'b', 'c', 'd'] + + By default, *too_short* and *too_long* are functions that raise + ``ValueError``. + + >>> list(strictly_n('ab', 3)) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: too few items in iterable (got 2) + + >>> list(strictly_n('abc', 2)) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: too many items in iterable (got at least 3) + + You can instead supply functions that do something else. + *too_short* will be called with the number of items in *iterable*. + *too_long* will be called with `n + 1`. + + >>> def too_short(item_count): + ... raise RuntimeError + >>> it = strictly_n('abcd', 6, too_short=too_short) + >>> list(it) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + RuntimeError + + >>> def too_long(item_count): + ... print('The boss is going to hear about this') + >>> it = strictly_n('abcdef', 4, too_long=too_long) + >>> list(it) + The boss is going to hear about this + ['a', 'b', 'c', 'd'] + + """ + if too_short is None: + too_short = lambda item_count: raise_( + ValueError, + 'Too few items in iterable (got {})'.format(item_count), + ) + + if too_long is None: + too_long = lambda item_count: raise_( + ValueError, + 'Too many items in iterable (got at least {})'.format(item_count), + ) + + it = iter(iterable) + for i in range(n): + try: + item = next(it) + except StopIteration: + too_short(i) + return + else: + yield item + + try: + next(it) + except StopIteration: + pass + else: + too_long(n + 1) + + +def distinct_permutations(iterable, r=None): + """Yield successive distinct permutations of the elements in *iterable*. + + >>> sorted(distinct_permutations([1, 0, 1])) + [(0, 1, 1), (1, 0, 1), (1, 1, 0)] + + Equivalent to ``set(permutations(iterable))``, except duplicates are not + generated and thrown away. For larger input sequences this is much more + efficient. + + Duplicate permutations arise when there are duplicated elements in the + input iterable. The number of items returned is + `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of + items input, and each `x_i` is the count of a distinct item in the input + sequence. + + If *r* is given, only the *r*-length permutations are yielded. + + >>> sorted(distinct_permutations([1, 0, 1], r=2)) + [(0, 1), (1, 0), (1, 1)] + >>> sorted(distinct_permutations(range(3), r=2)) + [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] + + """ + + # Algorithm: https://w.wiki/Qai + def _full(A): + while True: + # Yield the permutation we have + yield tuple(A) + + # Find the largest index i such that A[i] < A[i + 1] + for i in range(size - 2, -1, -1): + if A[i] < A[i + 1]: + break + # If no such index exists, this permutation is the last one + else: + return + + # Find the largest index j greater than j such that A[i] < A[j] + for j in range(size - 1, i, -1): + if A[i] < A[j]: + break + + # Swap the value of A[i] with that of A[j], then reverse the + # sequence from A[i + 1] to form the new permutation + A[i], A[j] = A[j], A[i] + A[i + 1 :] = A[: i - size : -1] # A[i + 1:][::-1] + + # Algorithm: modified from the above + def _partial(A, r): + # Split A into the first r items and the last r items + head, tail = A[:r], A[r:] + right_head_indexes = range(r - 1, -1, -1) + left_tail_indexes = range(len(tail)) + + while True: + # Yield the permutation we have + yield tuple(head) + + # Starting from the right, find the first index of the head with + # value smaller than the maximum value of the tail - call it i. + pivot = tail[-1] + for i in right_head_indexes: + if head[i] < pivot: + break + pivot = head[i] + else: + return + + # Starting from the left, find the first value of the tail + # with a value greater than head[i] and swap. + for j in left_tail_indexes: + if tail[j] > head[i]: + head[i], tail[j] = tail[j], head[i] + break + # If we didn't find one, start from the right and find the first + # index of the head with a value greater than head[i] and swap. + else: + for j in right_head_indexes: + if head[j] > head[i]: + head[i], head[j] = head[j], head[i] + break + + # Reverse head[i + 1:] and swap it with tail[:r - (i + 1)] + tail += head[: i - r : -1] # head[i + 1:][::-1] + i += 1 + head[i:], tail[:] = tail[: r - i], tail[r - i :] + + items = sorted(iterable) + + size = len(items) + if r is None: + r = size + + if 0 < r <= size: + return _full(items) if (r == size) else _partial(items, r) + + return iter(() if r else ((),)) + + +def intersperse(e, iterable, n=1): + """Intersperse filler element *e* among the items in *iterable*, leaving + *n* items between each filler element. + + >>> list(intersperse('!', [1, 2, 3, 4, 5])) + [1, '!', 2, '!', 3, '!', 4, '!', 5] + + >>> list(intersperse(None, [1, 2, 3, 4, 5], n=2)) + [1, 2, None, 3, 4, None, 5] + + """ + if n == 0: + raise ValueError('n must be > 0') + elif n == 1: + # interleave(repeat(e), iterable) -> e, x_0, e, x_1, e, x_2... + # islice(..., 1, None) -> x_0, e, x_1, e, x_2... + return islice(interleave(repeat(e), iterable), 1, None) + else: + # interleave(filler, chunks) -> [e], [x_0, x_1], [e], [x_2, x_3]... + # islice(..., 1, None) -> [x_0, x_1], [e], [x_2, x_3]... + # flatten(...) -> x_0, x_1, e, x_2, x_3... + filler = repeat([e]) + chunks = chunked(iterable, n) + return flatten(islice(interleave(filler, chunks), 1, None)) + + +def unique_to_each(*iterables): + """Return the elements from each of the input iterables that aren't in the + other input iterables. + + For example, suppose you have a set of packages, each with a set of + dependencies:: + + {'pkg_1': {'A', 'B'}, 'pkg_2': {'B', 'C'}, 'pkg_3': {'B', 'D'}} + + If you remove one package, which dependencies can also be removed? + + If ``pkg_1`` is removed, then ``A`` is no longer necessary - it is not + associated with ``pkg_2`` or ``pkg_3``. Similarly, ``C`` is only needed for + ``pkg_2``, and ``D`` is only needed for ``pkg_3``:: + + >>> unique_to_each({'A', 'B'}, {'B', 'C'}, {'B', 'D'}) + [['A'], ['C'], ['D']] + + If there are duplicates in one input iterable that aren't in the others + they will be duplicated in the output. Input order is preserved:: + + >>> unique_to_each("mississippi", "missouri") + [['p', 'p'], ['o', 'u', 'r']] + + It is assumed that the elements of each iterable are hashable. + + """ + pool = [list(it) for it in iterables] + counts = Counter(chain.from_iterable(map(set, pool))) + uniques = {element for element in counts if counts[element] == 1} + return [list(filter(uniques.__contains__, it)) for it in pool] + + +def windowed(seq, n, fillvalue=None, step=1): + """Return a sliding window of width *n* over the given iterable. + + >>> all_windows = windowed([1, 2, 3, 4, 5], 3) + >>> list(all_windows) + [(1, 2, 3), (2, 3, 4), (3, 4, 5)] + + When the window is larger than the iterable, *fillvalue* is used in place + of missing values: + + >>> list(windowed([1, 2, 3], 4)) + [(1, 2, 3, None)] + + Each window will advance in increments of *step*: + + >>> list(windowed([1, 2, 3, 4, 5, 6], 3, fillvalue='!', step=2)) + [(1, 2, 3), (3, 4, 5), (5, 6, '!')] + + To slide into the iterable's items, use :func:`chain` to add filler items + to the left: + + >>> iterable = [1, 2, 3, 4] + >>> n = 3 + >>> padding = [None] * (n - 1) + >>> list(windowed(chain(padding, iterable), 3)) + [(None, None, 1), (None, 1, 2), (1, 2, 3), (2, 3, 4)] + """ + if n < 0: + raise ValueError('n must be >= 0') + if n == 0: + yield tuple() + return + if step < 1: + raise ValueError('step must be >= 1') + + window = deque(maxlen=n) + i = n + for _ in map(window.append, seq): + i -= 1 + if not i: + i = step + yield tuple(window) + + size = len(window) + if size == 0: + return + elif size < n: + yield tuple(chain(window, repeat(fillvalue, n - size))) + elif 0 < i < min(step, n): + window += (fillvalue,) * i + yield tuple(window) + + +def substrings(iterable): + """Yield all of the substrings of *iterable*. + + >>> [''.join(s) for s in substrings('more')] + ['m', 'o', 'r', 'e', 'mo', 'or', 're', 'mor', 'ore', 'more'] + + Note that non-string iterables can also be subdivided. + + >>> list(substrings([0, 1, 2])) + [(0,), (1,), (2,), (0, 1), (1, 2), (0, 1, 2)] + + """ + # The length-1 substrings + seq = [] + for item in iter(iterable): + seq.append(item) + yield (item,) + seq = tuple(seq) + item_count = len(seq) + + # And the rest + for n in range(2, item_count + 1): + for i in range(item_count - n + 1): + yield seq[i : i + n] + + +def substrings_indexes(seq, reverse=False): + """Yield all substrings and their positions in *seq* + + The items yielded will be a tuple of the form ``(substr, i, j)``, where + ``substr == seq[i:j]``. + + This function only works for iterables that support slicing, such as + ``str`` objects. + + >>> for item in substrings_indexes('more'): + ... print(item) + ('m', 0, 1) + ('o', 1, 2) + ('r', 2, 3) + ('e', 3, 4) + ('mo', 0, 2) + ('or', 1, 3) + ('re', 2, 4) + ('mor', 0, 3) + ('ore', 1, 4) + ('more', 0, 4) + + Set *reverse* to ``True`` to yield the same items in the opposite order. + + + """ + r = range(1, len(seq) + 1) + if reverse: + r = reversed(r) + return ( + (seq[i : i + L], i, i + L) for L in r for i in range(len(seq) - L + 1) + ) + + +class bucket: + """Wrap *iterable* and return an object that buckets it iterable into + child iterables based on a *key* function. + + >>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3'] + >>> s = bucket(iterable, key=lambda x: x[0]) # Bucket by 1st character + >>> sorted(list(s)) # Get the keys + ['a', 'b', 'c'] + >>> a_iterable = s['a'] + >>> next(a_iterable) + 'a1' + >>> next(a_iterable) + 'a2' + >>> list(s['b']) + ['b1', 'b2', 'b3'] + + The original iterable will be advanced and its items will be cached until + they are used by the child iterables. This may require significant storage. + + By default, attempting to select a bucket to which no items belong will + exhaust the iterable and cache all values. + If you specify a *validator* function, selected buckets will instead be + checked against it. + + >>> from itertools import count + >>> it = count(1, 2) # Infinite sequence of odd numbers + >>> key = lambda x: x % 10 # Bucket by last digit + >>> validator = lambda x: x in {1, 3, 5, 7, 9} # Odd digits only + >>> s = bucket(it, key=key, validator=validator) + >>> 2 in s + False + >>> list(s[2]) + [] + + """ + + def __init__(self, iterable, key, validator=None): + self._it = iter(iterable) + self._key = key + self._cache = defaultdict(deque) + self._validator = validator or (lambda x: True) + + def __contains__(self, value): + if not self._validator(value): + return False + + try: + item = next(self[value]) + except StopIteration: + return False + else: + self._cache[value].appendleft(item) + + return True + + def _get_values(self, value): + """ + Helper to yield items from the parent iterator that match *value*. + Items that don't match are stored in the local cache as they + are encountered. + """ + while True: + # If we've cached some items that match the target value, emit + # the first one and evict it from the cache. + if self._cache[value]: + yield self._cache[value].popleft() + # Otherwise we need to advance the parent iterator to search for + # a matching item, caching the rest. + else: + while True: + try: + item = next(self._it) + except StopIteration: + return + item_value = self._key(item) + if item_value == value: + yield item + break + elif self._validator(item_value): + self._cache[item_value].append(item) + + def __iter__(self): + for item in self._it: + item_value = self._key(item) + if self._validator(item_value): + self._cache[item_value].append(item) + + yield from self._cache.keys() + + def __getitem__(self, value): + if not self._validator(value): + return iter(()) + + return self._get_values(value) + + +def spy(iterable, n=1): + """Return a 2-tuple with a list containing the first *n* elements of + *iterable*, and an iterator with the same items as *iterable*. + This allows you to "look ahead" at the items in the iterable without + advancing it. + + There is one item in the list by default: + + >>> iterable = 'abcdefg' + >>> head, iterable = spy(iterable) + >>> head + ['a'] + >>> list(iterable) + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + + You may use unpacking to retrieve items instead of lists: + + >>> (head,), iterable = spy('abcdefg') + >>> head + 'a' + >>> (first, second), iterable = spy('abcdefg', 2) + >>> first + 'a' + >>> second + 'b' + + The number of items requested can be larger than the number of items in + the iterable: + + >>> iterable = [1, 2, 3, 4, 5] + >>> head, iterable = spy(iterable, 10) + >>> head + [1, 2, 3, 4, 5] + >>> list(iterable) + [1, 2, 3, 4, 5] + + """ + it = iter(iterable) + head = take(n, it) + + return head.copy(), chain(head, it) + + +def interleave(*iterables): + """Return a new iterable yielding from each iterable in turn, + until the shortest is exhausted. + + >>> list(interleave([1, 2, 3], [4, 5], [6, 7, 8])) + [1, 4, 6, 2, 5, 7] + + For a version that doesn't terminate after the shortest iterable is + exhausted, see :func:`interleave_longest`. + + """ + return chain.from_iterable(zip(*iterables)) + + +def interleave_longest(*iterables): + """Return a new iterable yielding from each iterable in turn, + skipping any that are exhausted. + + >>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8])) + [1, 4, 6, 2, 5, 7, 3, 8] + + This function produces the same output as :func:`roundrobin`, but may + perform better for some inputs (in particular when the number of iterables + is large). + + """ + i = chain.from_iterable(zip_longest(*iterables, fillvalue=_marker)) + return (x for x in i if x is not _marker) + + +def interleave_evenly(iterables, lengths=None): + """ + Interleave multiple iterables so that their elements are evenly distributed + throughout the output sequence. + + >>> iterables = [1, 2, 3, 4, 5], ['a', 'b'] + >>> list(interleave_evenly(iterables)) + [1, 2, 'a', 3, 4, 'b', 5] + + >>> iterables = [[1, 2, 3], [4, 5], [6, 7, 8]] + >>> list(interleave_evenly(iterables)) + [1, 6, 4, 2, 7, 3, 8, 5] + + This function requires iterables of known length. Iterables without + ``__len__()`` can be used by manually specifying lengths with *lengths*: + + >>> from itertools import combinations, repeat + >>> iterables = [combinations(range(4), 2), ['a', 'b', 'c']] + >>> lengths = [4 * (4 - 1) // 2, 3] + >>> list(interleave_evenly(iterables, lengths=lengths)) + [(0, 1), (0, 2), 'a', (0, 3), (1, 2), 'b', (1, 3), (2, 3), 'c'] + + Based on Bresenham's algorithm. + """ + if lengths is None: + try: + lengths = [len(it) for it in iterables] + except TypeError: + raise ValueError( + 'Iterable lengths could not be determined automatically. ' + 'Specify them with the lengths keyword.' + ) + elif len(iterables) != len(lengths): + raise ValueError('Mismatching number of iterables and lengths.') + + dims = len(lengths) + + # sort iterables by length, descending + lengths_permute = sorted( + range(dims), key=lambda i: lengths[i], reverse=True + ) + lengths_desc = [lengths[i] for i in lengths_permute] + iters_desc = [iter(iterables[i]) for i in lengths_permute] + + # the longest iterable is the primary one (Bresenham: the longest + # distance along an axis) + delta_primary, deltas_secondary = lengths_desc[0], lengths_desc[1:] + iter_primary, iters_secondary = iters_desc[0], iters_desc[1:] + errors = [delta_primary // dims] * len(deltas_secondary) + + to_yield = sum(lengths) + while to_yield: + yield next(iter_primary) + to_yield -= 1 + # update errors for each secondary iterable + errors = [e - delta for e, delta in zip(errors, deltas_secondary)] + + # those iterables for which the error is negative are yielded + # ("diagonal step" in Bresenham) + for i, e in enumerate(errors): + if e < 0: + yield next(iters_secondary[i]) + to_yield -= 1 + errors[i] += delta_primary + + +def collapse(iterable, base_type=None, levels=None): + """Flatten an iterable with multiple levels of nesting (e.g., a list of + lists of tuples) into non-iterable types. + + >>> iterable = [(1, 2), ([3, 4], [[5], [6]])] + >>> list(collapse(iterable)) + [1, 2, 3, 4, 5, 6] + + Binary and text strings are not considered iterable and + will not be collapsed. + + To avoid collapsing other types, specify *base_type*: + + >>> iterable = ['ab', ('cd', 'ef'), ['gh', 'ij']] + >>> list(collapse(iterable, base_type=tuple)) + ['ab', ('cd', 'ef'), 'gh', 'ij'] + + Specify *levels* to stop flattening after a certain level: + + >>> iterable = [('a', ['b']), ('c', ['d'])] + >>> list(collapse(iterable)) # Fully flattened + ['a', 'b', 'c', 'd'] + >>> list(collapse(iterable, levels=1)) # Only one level flattened + ['a', ['b'], 'c', ['d']] + + """ + + def walk(node, level): + if ( + ((levels is not None) and (level > levels)) + or isinstance(node, (str, bytes)) + or ((base_type is not None) and isinstance(node, base_type)) + ): + yield node + return + + try: + tree = iter(node) + except TypeError: + yield node + return + else: + for child in tree: + yield from walk(child, level + 1) + + yield from walk(iterable, 0) + + +def side_effect(func, iterable, chunk_size=None, before=None, after=None): + """Invoke *func* on each item in *iterable* (or on each *chunk_size* group + of items) before yielding the item. + + `func` must be a function that takes a single argument. Its return value + will be discarded. + + *before* and *after* are optional functions that take no arguments. They + will be executed before iteration starts and after it ends, respectively. + + `side_effect` can be used for logging, updating progress bars, or anything + that is not functionally "pure." + + Emitting a status message: + + >>> from more_itertools import consume + >>> func = lambda item: print('Received {}'.format(item)) + >>> consume(side_effect(func, range(2))) + Received 0 + Received 1 + + Operating on chunks of items: + + >>> pair_sums = [] + >>> func = lambda chunk: pair_sums.append(sum(chunk)) + >>> list(side_effect(func, [0, 1, 2, 3, 4, 5], 2)) + [0, 1, 2, 3, 4, 5] + >>> list(pair_sums) + [1, 5, 9] + + Writing to a file-like object: + + >>> from io import StringIO + >>> from more_itertools import consume + >>> f = StringIO() + >>> func = lambda x: print(x, file=f) + >>> before = lambda: print(u'HEADER', file=f) + >>> after = f.close + >>> it = [u'a', u'b', u'c'] + >>> consume(side_effect(func, it, before=before, after=after)) + >>> f.closed + True + + """ + try: + if before is not None: + before() + + if chunk_size is None: + for item in iterable: + func(item) + yield item + else: + for chunk in chunked(iterable, chunk_size): + func(chunk) + yield from chunk + finally: + if after is not None: + after() + + +def sliced(seq, n, strict=False): + """Yield slices of length *n* from the sequence *seq*. + + >>> list(sliced((1, 2, 3, 4, 5, 6), 3)) + [(1, 2, 3), (4, 5, 6)] + + By the default, the last yielded slice will have fewer than *n* elements + if the length of *seq* is not divisible by *n*: + + >>> list(sliced((1, 2, 3, 4, 5, 6, 7, 8), 3)) + [(1, 2, 3), (4, 5, 6), (7, 8)] + + If the length of *seq* is not divisible by *n* and *strict* is + ``True``, then ``ValueError`` will be raised before the last + slice is yielded. + + This function will only work for iterables that support slicing. + For non-sliceable iterables, see :func:`chunked`. + + """ + iterator = takewhile(len, (seq[i : i + n] for i in count(0, n))) + if strict: + + def ret(): + for _slice in iterator: + if len(_slice) != n: + raise ValueError("seq is not divisible by n.") + yield _slice + + return iter(ret()) + else: + return iterator + + +def split_at(iterable, pred, maxsplit=-1, keep_separator=False): + """Yield lists of items from *iterable*, where each list is delimited by + an item where callable *pred* returns ``True``. + + >>> list(split_at('abcdcba', lambda x: x == 'b')) + [['a'], ['c', 'd', 'c'], ['a']] + + >>> list(split_at(range(10), lambda n: n % 2 == 1)) + [[0], [2], [4], [6], [8], []] + + At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, + then there is no limit on the number of splits: + + >>> list(split_at(range(10), lambda n: n % 2 == 1, maxsplit=2)) + [[0], [2], [4, 5, 6, 7, 8, 9]] + + By default, the delimiting items are not included in the output. + To include them, set *keep_separator* to ``True``. + + >>> list(split_at('abcdcba', lambda x: x == 'b', keep_separator=True)) + [['a'], ['b'], ['c', 'd', 'c'], ['b'], ['a']] + + """ + if maxsplit == 0: + yield list(iterable) + return + + buf = [] + it = iter(iterable) + for item in it: + if pred(item): + yield buf + if keep_separator: + yield [item] + if maxsplit == 1: + yield list(it) + return + buf = [] + maxsplit -= 1 + else: + buf.append(item) + yield buf + + +def split_before(iterable, pred, maxsplit=-1): + """Yield lists of items from *iterable*, where each list ends just before + an item for which callable *pred* returns ``True``: + + >>> list(split_before('OneTwo', lambda s: s.isupper())) + [['O', 'n', 'e'], ['T', 'w', 'o']] + + >>> list(split_before(range(10), lambda n: n % 3 == 0)) + [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] + + At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, + then there is no limit on the number of splits: + + >>> list(split_before(range(10), lambda n: n % 3 == 0, maxsplit=2)) + [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]] + """ + if maxsplit == 0: + yield list(iterable) + return + + buf = [] + it = iter(iterable) + for item in it: + if pred(item) and buf: + yield buf + if maxsplit == 1: + yield [item] + list(it) + return + buf = [] + maxsplit -= 1 + buf.append(item) + if buf: + yield buf + + +def split_after(iterable, pred, maxsplit=-1): + """Yield lists of items from *iterable*, where each list ends with an + item where callable *pred* returns ``True``: + + >>> list(split_after('one1two2', lambda s: s.isdigit())) + [['o', 'n', 'e', '1'], ['t', 'w', 'o', '2']] + + >>> list(split_after(range(10), lambda n: n % 3 == 0)) + [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9]] + + At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, + then there is no limit on the number of splits: + + >>> list(split_after(range(10), lambda n: n % 3 == 0, maxsplit=2)) + [[0], [1, 2, 3], [4, 5, 6, 7, 8, 9]] + + """ + if maxsplit == 0: + yield list(iterable) + return + + buf = [] + it = iter(iterable) + for item in it: + buf.append(item) + if pred(item) and buf: + yield buf + if maxsplit == 1: + buf = list(it) + if buf: + yield buf + return + buf = [] + maxsplit -= 1 + if buf: + yield buf + + +def split_when(iterable, pred, maxsplit=-1): + """Split *iterable* into pieces based on the output of *pred*. + *pred* should be a function that takes successive pairs of items and + returns ``True`` if the iterable should be split in between them. + + For example, to find runs of increasing numbers, split the iterable when + element ``i`` is larger than element ``i + 1``: + + >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], lambda x, y: x > y)) + [[1, 2, 3, 3], [2, 5], [2, 4], [2]] + + At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, + then there is no limit on the number of splits: + + >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], + ... lambda x, y: x > y, maxsplit=2)) + [[1, 2, 3, 3], [2, 5], [2, 4, 2]] + + """ + if maxsplit == 0: + yield list(iterable) + return + + it = iter(iterable) + try: + cur_item = next(it) + except StopIteration: + return + + buf = [cur_item] + for next_item in it: + if pred(cur_item, next_item): + yield buf + if maxsplit == 1: + yield [next_item] + list(it) + return + buf = [] + maxsplit -= 1 + + buf.append(next_item) + cur_item = next_item + + yield buf + + +def split_into(iterable, sizes): + """Yield a list of sequential items from *iterable* of length 'n' for each + integer 'n' in *sizes*. + + >>> list(split_into([1,2,3,4,5,6], [1,2,3])) + [[1], [2, 3], [4, 5, 6]] + + If the sum of *sizes* is smaller than the length of *iterable*, then the + remaining items of *iterable* will not be returned. + + >>> list(split_into([1,2,3,4,5,6], [2,3])) + [[1, 2], [3, 4, 5]] + + If the sum of *sizes* is larger than the length of *iterable*, fewer items + will be returned in the iteration that overruns *iterable* and further + lists will be empty: + + >>> list(split_into([1,2,3,4], [1,2,3,4])) + [[1], [2, 3], [4], []] + + When a ``None`` object is encountered in *sizes*, the returned list will + contain items up to the end of *iterable* the same way that itertools.slice + does: + + >>> list(split_into([1,2,3,4,5,6,7,8,9,0], [2,3,None])) + [[1, 2], [3, 4, 5], [6, 7, 8, 9, 0]] + + :func:`split_into` can be useful for grouping a series of items where the + sizes of the groups are not uniform. An example would be where in a row + from a table, multiple columns represent elements of the same feature + (e.g. a point represented by x,y,z) but, the format is not the same for + all columns. + """ + # convert the iterable argument into an iterator so its contents can + # be consumed by islice in case it is a generator + it = iter(iterable) + + for size in sizes: + if size is None: + yield list(it) + return + else: + yield list(islice(it, size)) + + +def padded(iterable, fillvalue=None, n=None, next_multiple=False): + """Yield the elements from *iterable*, followed by *fillvalue*, such that + at least *n* items are emitted. + + >>> list(padded([1, 2, 3], '?', 5)) + [1, 2, 3, '?', '?'] + + If *next_multiple* is ``True``, *fillvalue* will be emitted until the + number of items emitted is a multiple of *n*:: + + >>> list(padded([1, 2, 3, 4], n=3, next_multiple=True)) + [1, 2, 3, 4, None, None] + + If *n* is ``None``, *fillvalue* will be emitted indefinitely. + + """ + it = iter(iterable) + if n is None: + yield from chain(it, repeat(fillvalue)) + elif n < 1: + raise ValueError('n must be at least 1') + else: + item_count = 0 + for item in it: + yield item + item_count += 1 + + remaining = (n - item_count) % n if next_multiple else n - item_count + for _ in range(remaining): + yield fillvalue + + +def repeat_each(iterable, n=2): + """Repeat each element in *iterable* *n* times. + + >>> list(repeat_each('ABC', 3)) + ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'] + """ + return chain.from_iterable(map(repeat, iterable, repeat(n))) + + +def repeat_last(iterable, default=None): + """After the *iterable* is exhausted, keep yielding its last element. + + >>> list(islice(repeat_last(range(3)), 5)) + [0, 1, 2, 2, 2] + + If the iterable is empty, yield *default* forever:: + + >>> list(islice(repeat_last(range(0), 42), 5)) + [42, 42, 42, 42, 42] + + """ + item = _marker + for item in iterable: + yield item + final = default if item is _marker else item + yield from repeat(final) + + +def distribute(n, iterable): + """Distribute the items from *iterable* among *n* smaller iterables. + + >>> group_1, group_2 = distribute(2, [1, 2, 3, 4, 5, 6]) + >>> list(group_1) + [1, 3, 5] + >>> list(group_2) + [2, 4, 6] + + If the length of *iterable* is not evenly divisible by *n*, then the + length of the returned iterables will not be identical: + + >>> children = distribute(3, [1, 2, 3, 4, 5, 6, 7]) + >>> [list(c) for c in children] + [[1, 4, 7], [2, 5], [3, 6]] + + If the length of *iterable* is smaller than *n*, then the last returned + iterables will be empty: + + >>> children = distribute(5, [1, 2, 3]) + >>> [list(c) for c in children] + [[1], [2], [3], [], []] + + This function uses :func:`itertools.tee` and may require significant + storage. If you need the order items in the smaller iterables to match the + original iterable, see :func:`divide`. + + """ + if n < 1: + raise ValueError('n must be at least 1') + + children = tee(iterable, n) + return [islice(it, index, None, n) for index, it in enumerate(children)] + + +def stagger(iterable, offsets=(-1, 0, 1), longest=False, fillvalue=None): + """Yield tuples whose elements are offset from *iterable*. + The amount by which the `i`-th item in each tuple is offset is given by + the `i`-th item in *offsets*. + + >>> list(stagger([0, 1, 2, 3])) + [(None, 0, 1), (0, 1, 2), (1, 2, 3)] + >>> list(stagger(range(8), offsets=(0, 2, 4))) + [(0, 2, 4), (1, 3, 5), (2, 4, 6), (3, 5, 7)] + + By default, the sequence will end when the final element of a tuple is the + last item in the iterable. To continue until the first element of a tuple + is the last item in the iterable, set *longest* to ``True``:: + + >>> list(stagger([0, 1, 2, 3], longest=True)) + [(None, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, None), (3, None, None)] + + By default, ``None`` will be used to replace offsets beyond the end of the + sequence. Specify *fillvalue* to use some other value. + + """ + children = tee(iterable, len(offsets)) + + return zip_offset( + *children, offsets=offsets, longest=longest, fillvalue=fillvalue + ) + + +def zip_equal(*iterables): + """``zip`` the input *iterables* together, but raise + ``UnequalIterablesError`` if they aren't all the same length. + + >>> it_1 = range(3) + >>> it_2 = iter('abc') + >>> list(zip_equal(it_1, it_2)) + [(0, 'a'), (1, 'b'), (2, 'c')] + + >>> it_1 = range(3) + >>> it_2 = iter('abcd') + >>> list(zip_equal(it_1, it_2)) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + more_itertools.more.UnequalIterablesError: Iterables have different + lengths + + """ + if hexversion >= 0x30A00A6: + warnings.warn( + ( + 'zip_equal will be removed in a future version of ' + 'more-itertools. Use the builtin zip function with ' + 'strict=True instead.' + ), + DeprecationWarning, + ) + + return _zip_equal(*iterables) + + +def zip_offset(*iterables, offsets, longest=False, fillvalue=None): + """``zip`` the input *iterables* together, but offset the `i`-th iterable + by the `i`-th item in *offsets*. + + >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1))) + [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e')] + + This can be used as a lightweight alternative to SciPy or pandas to analyze + data sets in which some series have a lead or lag relationship. + + By default, the sequence will end when the shortest iterable is exhausted. + To continue until the longest iterable is exhausted, set *longest* to + ``True``. + + >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1), longest=True)) + [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e'), (None, 'f')] + + By default, ``None`` will be used to replace offsets beyond the end of the + sequence. Specify *fillvalue* to use some other value. + + """ + if len(iterables) != len(offsets): + raise ValueError("Number of iterables and offsets didn't match") + + staggered = [] + for it, n in zip(iterables, offsets): + if n < 0: + staggered.append(chain(repeat(fillvalue, -n), it)) + elif n > 0: + staggered.append(islice(it, n, None)) + else: + staggered.append(it) + + if longest: + return zip_longest(*staggered, fillvalue=fillvalue) + + return zip(*staggered) + + +def sort_together(iterables, key_list=(0,), key=None, reverse=False): + """Return the input iterables sorted together, with *key_list* as the + priority for sorting. All iterables are trimmed to the length of the + shortest one. + + This can be used like the sorting function in a spreadsheet. If each + iterable represents a column of data, the key list determines which + columns are used for sorting. + + By default, all iterables are sorted using the ``0``-th iterable:: + + >>> iterables = [(4, 3, 2, 1), ('a', 'b', 'c', 'd')] + >>> sort_together(iterables) + [(1, 2, 3, 4), ('d', 'c', 'b', 'a')] + + Set a different key list to sort according to another iterable. + Specifying multiple keys dictates how ties are broken:: + + >>> iterables = [(3, 1, 2), (0, 1, 0), ('c', 'b', 'a')] + >>> sort_together(iterables, key_list=(1, 2)) + [(2, 3, 1), (0, 0, 1), ('a', 'c', 'b')] + + To sort by a function of the elements of the iterable, pass a *key* + function. Its arguments are the elements of the iterables corresponding to + the key list:: + + >>> names = ('a', 'b', 'c') + >>> lengths = (1, 2, 3) + >>> widths = (5, 2, 1) + >>> def area(length, width): + ... return length * width + >>> sort_together([names, lengths, widths], key_list=(1, 2), key=area) + [('c', 'b', 'a'), (3, 2, 1), (1, 2, 5)] + + Set *reverse* to ``True`` to sort in descending order. + + >>> sort_together([(1, 2, 3), ('c', 'b', 'a')], reverse=True) + [(3, 2, 1), ('a', 'b', 'c')] + + """ + if key is None: + # if there is no key function, the key argument to sorted is an + # itemgetter + key_argument = itemgetter(*key_list) + else: + # if there is a key function, call it with the items at the offsets + # specified by the key function as arguments + key_list = list(key_list) + if len(key_list) == 1: + # if key_list contains a single item, pass the item at that offset + # as the only argument to the key function + key_offset = key_list[0] + key_argument = lambda zipped_items: key(zipped_items[key_offset]) + else: + # if key_list contains multiple items, use itemgetter to return a + # tuple of items, which we pass as *args to the key function + get_key_items = itemgetter(*key_list) + key_argument = lambda zipped_items: key( + *get_key_items(zipped_items) + ) + + return list( + zip(*sorted(zip(*iterables), key=key_argument, reverse=reverse)) + ) + + +def unzip(iterable): + """The inverse of :func:`zip`, this function disaggregates the elements + of the zipped *iterable*. + + The ``i``-th iterable contains the ``i``-th element from each element + of the zipped iterable. The first element is used to determine the + length of the remaining elements. + + >>> iterable = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] + >>> letters, numbers = unzip(iterable) + >>> list(letters) + ['a', 'b', 'c', 'd'] + >>> list(numbers) + [1, 2, 3, 4] + + This is similar to using ``zip(*iterable)``, but it avoids reading + *iterable* into memory. Note, however, that this function uses + :func:`itertools.tee` and thus may require significant storage. + + """ + head, iterable = spy(iter(iterable)) + if not head: + # empty iterable, e.g. zip([], [], []) + return () + # spy returns a one-length iterable as head + head = head[0] + iterables = tee(iterable, len(head)) + + def itemgetter(i): + def getter(obj): + try: + return obj[i] + except IndexError: + # basically if we have an iterable like + # iter([(1, 2, 3), (4, 5), (6,)]) + # the second unzipped iterable would fail at the third tuple + # since it would try to access tup[1] + # same with the third unzipped iterable and the second tuple + # to support these "improperly zipped" iterables, + # we create a custom itemgetter + # which just stops the unzipped iterables + # at first length mismatch + raise StopIteration + + return getter + + return tuple(map(itemgetter(i), it) for i, it in enumerate(iterables)) + + +def divide(n, iterable): + """Divide the elements from *iterable* into *n* parts, maintaining + order. + + >>> group_1, group_2 = divide(2, [1, 2, 3, 4, 5, 6]) + >>> list(group_1) + [1, 2, 3] + >>> list(group_2) + [4, 5, 6] + + If the length of *iterable* is not evenly divisible by *n*, then the + length of the returned iterables will not be identical: + + >>> children = divide(3, [1, 2, 3, 4, 5, 6, 7]) + >>> [list(c) for c in children] + [[1, 2, 3], [4, 5], [6, 7]] + + If the length of the iterable is smaller than n, then the last returned + iterables will be empty: + + >>> children = divide(5, [1, 2, 3]) + >>> [list(c) for c in children] + [[1], [2], [3], [], []] + + This function will exhaust the iterable before returning and may require + significant storage. If order is not important, see :func:`distribute`, + which does not first pull the iterable into memory. + + """ + if n < 1: + raise ValueError('n must be at least 1') + + try: + iterable[:0] + except TypeError: + seq = tuple(iterable) + else: + seq = iterable + + q, r = divmod(len(seq), n) + + ret = [] + stop = 0 + for i in range(1, n + 1): + start = stop + stop += q + 1 if i <= r else q + ret.append(iter(seq[start:stop])) + + return ret + + +def always_iterable(obj, base_type=(str, bytes)): + """If *obj* is iterable, return an iterator over its items:: + + >>> obj = (1, 2, 3) + >>> list(always_iterable(obj)) + [1, 2, 3] + + If *obj* is not iterable, return a one-item iterable containing *obj*:: + + >>> obj = 1 + >>> list(always_iterable(obj)) + [1] + + If *obj* is ``None``, return an empty iterable: + + >>> obj = None + >>> list(always_iterable(None)) + [] + + By default, binary and text strings are not considered iterable:: + + >>> obj = 'foo' + >>> list(always_iterable(obj)) + ['foo'] + + If *base_type* is set, objects for which ``isinstance(obj, base_type)`` + returns ``True`` won't be considered iterable. + + >>> obj = {'a': 1} + >>> list(always_iterable(obj)) # Iterate over the dict's keys + ['a'] + >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit + [{'a': 1}] + + Set *base_type* to ``None`` to avoid any special handling and treat objects + Python considers iterable as iterable: + + >>> obj = 'foo' + >>> list(always_iterable(obj, base_type=None)) + ['f', 'o', 'o'] + """ + if obj is None: + return iter(()) + + if (base_type is not None) and isinstance(obj, base_type): + return iter((obj,)) + + try: + return iter(obj) + except TypeError: + return iter((obj,)) + + +def adjacent(predicate, iterable, distance=1): + """Return an iterable over `(bool, item)` tuples where the `item` is + drawn from *iterable* and the `bool` indicates whether + that item satisfies the *predicate* or is adjacent to an item that does. + + For example, to find whether items are adjacent to a ``3``:: + + >>> list(adjacent(lambda x: x == 3, range(6))) + [(False, 0), (False, 1), (True, 2), (True, 3), (True, 4), (False, 5)] + + Set *distance* to change what counts as adjacent. For example, to find + whether items are two places away from a ``3``: + + >>> list(adjacent(lambda x: x == 3, range(6), distance=2)) + [(False, 0), (True, 1), (True, 2), (True, 3), (True, 4), (True, 5)] + + This is useful for contextualizing the results of a search function. + For example, a code comparison tool might want to identify lines that + have changed, but also surrounding lines to give the viewer of the diff + context. + + The predicate function will only be called once for each item in the + iterable. + + See also :func:`groupby_transform`, which can be used with this function + to group ranges of items with the same `bool` value. + + """ + # Allow distance=0 mainly for testing that it reproduces results with map() + if distance < 0: + raise ValueError('distance must be at least 0') + + i1, i2 = tee(iterable) + padding = [False] * distance + selected = chain(padding, map(predicate, i1), padding) + adjacent_to_selected = map(any, windowed(selected, 2 * distance + 1)) + return zip(adjacent_to_selected, i2) + + +def groupby_transform(iterable, keyfunc=None, valuefunc=None, reducefunc=None): + """An extension of :func:`itertools.groupby` that can apply transformations + to the grouped data. + + * *keyfunc* is a function computing a key value for each item in *iterable* + * *valuefunc* is a function that transforms the individual items from + *iterable* after grouping + * *reducefunc* is a function that transforms each group of items + + >>> iterable = 'aAAbBBcCC' + >>> keyfunc = lambda k: k.upper() + >>> valuefunc = lambda v: v.lower() + >>> reducefunc = lambda g: ''.join(g) + >>> list(groupby_transform(iterable, keyfunc, valuefunc, reducefunc)) + [('A', 'aaa'), ('B', 'bbb'), ('C', 'ccc')] + + Each optional argument defaults to an identity function if not specified. + + :func:`groupby_transform` is useful when grouping elements of an iterable + using a separate iterable as the key. To do this, :func:`zip` the iterables + and pass a *keyfunc* that extracts the first element and a *valuefunc* + that extracts the second element:: + + >>> from operator import itemgetter + >>> keys = [0, 0, 1, 1, 1, 2, 2, 2, 3] + >>> values = 'abcdefghi' + >>> iterable = zip(keys, values) + >>> grouper = groupby_transform(iterable, itemgetter(0), itemgetter(1)) + >>> [(k, ''.join(g)) for k, g in grouper] + [(0, 'ab'), (1, 'cde'), (2, 'fgh'), (3, 'i')] + + Note that the order of items in the iterable is significant. + Only adjacent items are grouped together, so if you don't want any + duplicate groups, you should sort the iterable by the key function. + + """ + ret = groupby(iterable, keyfunc) + if valuefunc: + ret = ((k, map(valuefunc, g)) for k, g in ret) + if reducefunc: + ret = ((k, reducefunc(g)) for k, g in ret) + + return ret + + +class numeric_range(abc.Sequence, abc.Hashable): + """An extension of the built-in ``range()`` function whose arguments can + be any orderable numeric type. + + With only *stop* specified, *start* defaults to ``0`` and *step* + defaults to ``1``. The output items will match the type of *stop*: + + >>> list(numeric_range(3.5)) + [0.0, 1.0, 2.0, 3.0] + + With only *start* and *stop* specified, *step* defaults to ``1``. The + output items will match the type of *start*: + + >>> from decimal import Decimal + >>> start = Decimal('2.1') + >>> stop = Decimal('5.1') + >>> list(numeric_range(start, stop)) + [Decimal('2.1'), Decimal('3.1'), Decimal('4.1')] + + With *start*, *stop*, and *step* specified the output items will match + the type of ``start + step``: + + >>> from fractions import Fraction + >>> start = Fraction(1, 2) # Start at 1/2 + >>> stop = Fraction(5, 2) # End at 5/2 + >>> step = Fraction(1, 2) # Count by 1/2 + >>> list(numeric_range(start, stop, step)) + [Fraction(1, 2), Fraction(1, 1), Fraction(3, 2), Fraction(2, 1)] + + If *step* is zero, ``ValueError`` is raised. Negative steps are supported: + + >>> list(numeric_range(3, -1, -1.0)) + [3.0, 2.0, 1.0, 0.0] + + Be aware of the limitations of floating point numbers; the representation + of the yielded numbers may be surprising. + + ``datetime.datetime`` objects can be used for *start* and *stop*, if *step* + is a ``datetime.timedelta`` object: + + >>> import datetime + >>> start = datetime.datetime(2019, 1, 1) + >>> stop = datetime.datetime(2019, 1, 3) + >>> step = datetime.timedelta(days=1) + >>> items = iter(numeric_range(start, stop, step)) + >>> next(items) + datetime.datetime(2019, 1, 1, 0, 0) + >>> next(items) + datetime.datetime(2019, 1, 2, 0, 0) + + """ + + _EMPTY_HASH = hash(range(0, 0)) + + def __init__(self, *args): + argc = len(args) + if argc == 1: + (self._stop,) = args + self._start = type(self._stop)(0) + self._step = type(self._stop - self._start)(1) + elif argc == 2: + self._start, self._stop = args + self._step = type(self._stop - self._start)(1) + elif argc == 3: + self._start, self._stop, self._step = args + elif argc == 0: + raise TypeError( + 'numeric_range expected at least ' + '1 argument, got {}'.format(argc) + ) + else: + raise TypeError( + 'numeric_range expected at most ' + '3 arguments, got {}'.format(argc) + ) + + self._zero = type(self._step)(0) + if self._step == self._zero: + raise ValueError('numeric_range() arg 3 must not be zero') + self._growing = self._step > self._zero + self._init_len() + + def __bool__(self): + if self._growing: + return self._start < self._stop + else: + return self._start > self._stop + + def __contains__(self, elem): + if self._growing: + if self._start <= elem < self._stop: + return (elem - self._start) % self._step == self._zero + else: + if self._start >= elem > self._stop: + return (self._start - elem) % (-self._step) == self._zero + + return False + + def __eq__(self, other): + if isinstance(other, numeric_range): + empty_self = not bool(self) + empty_other = not bool(other) + if empty_self or empty_other: + return empty_self and empty_other # True if both empty + else: + return ( + self._start == other._start + and self._step == other._step + and self._get_by_index(-1) == other._get_by_index(-1) + ) + else: + return False + + def __getitem__(self, key): + if isinstance(key, int): + return self._get_by_index(key) + elif isinstance(key, slice): + step = self._step if key.step is None else key.step * self._step + + if key.start is None or key.start <= -self._len: + start = self._start + elif key.start >= self._len: + start = self._stop + else: # -self._len < key.start < self._len + start = self._get_by_index(key.start) + + if key.stop is None or key.stop >= self._len: + stop = self._stop + elif key.stop <= -self._len: + stop = self._start + else: # -self._len < key.stop < self._len + stop = self._get_by_index(key.stop) + + return numeric_range(start, stop, step) + else: + raise TypeError( + 'numeric range indices must be ' + 'integers or slices, not {}'.format(type(key).__name__) + ) + + def __hash__(self): + if self: + return hash((self._start, self._get_by_index(-1), self._step)) + else: + return self._EMPTY_HASH + + def __iter__(self): + values = (self._start + (n * self._step) for n in count()) + if self._growing: + return takewhile(partial(gt, self._stop), values) + else: + return takewhile(partial(lt, self._stop), values) + + def __len__(self): + return self._len + + def _init_len(self): + if self._growing: + start = self._start + stop = self._stop + step = self._step + else: + start = self._stop + stop = self._start + step = -self._step + distance = stop - start + if distance <= self._zero: + self._len = 0 + else: # distance > 0 and step > 0: regular euclidean division + q, r = divmod(distance, step) + self._len = int(q) + int(r != self._zero) + + def __reduce__(self): + return numeric_range, (self._start, self._stop, self._step) + + def __repr__(self): + if self._step == 1: + return "numeric_range({}, {})".format( + repr(self._start), repr(self._stop) + ) + else: + return "numeric_range({}, {}, {})".format( + repr(self._start), repr(self._stop), repr(self._step) + ) + + def __reversed__(self): + return iter( + numeric_range( + self._get_by_index(-1), self._start - self._step, -self._step + ) + ) + + def count(self, value): + return int(value in self) + + def index(self, value): + if self._growing: + if self._start <= value < self._stop: + q, r = divmod(value - self._start, self._step) + if r == self._zero: + return int(q) + else: + if self._start >= value > self._stop: + q, r = divmod(self._start - value, -self._step) + if r == self._zero: + return int(q) + + raise ValueError("{} is not in numeric range".format(value)) + + def _get_by_index(self, i): + if i < 0: + i += self._len + if i < 0 or i >= self._len: + raise IndexError("numeric range object index out of range") + return self._start + i * self._step + + +def count_cycle(iterable, n=None): + """Cycle through the items from *iterable* up to *n* times, yielding + the number of completed cycles along with each item. If *n* is omitted the + process repeats indefinitely. + + >>> list(count_cycle('AB', 3)) + [(0, 'A'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')] + + """ + iterable = tuple(iterable) + if not iterable: + return iter(()) + counter = count() if n is None else range(n) + return ((i, item) for i in counter for item in iterable) + + +def mark_ends(iterable): + """Yield 3-tuples of the form ``(is_first, is_last, item)``. + + >>> list(mark_ends('ABC')) + [(True, False, 'A'), (False, False, 'B'), (False, True, 'C')] + + Use this when looping over an iterable to take special action on its first + and/or last items: + + >>> iterable = ['Header', 100, 200, 'Footer'] + >>> total = 0 + >>> for is_first, is_last, item in mark_ends(iterable): + ... if is_first: + ... continue # Skip the header + ... if is_last: + ... continue # Skip the footer + ... total += item + >>> print(total) + 300 + """ + it = iter(iterable) + + try: + b = next(it) + except StopIteration: + return + + try: + for i in count(): + a = b + b = next(it) + yield i == 0, False, a + + except StopIteration: + yield i == 0, True, a + + +def locate(iterable, pred=bool, window_size=None): + """Yield the index of each item in *iterable* for which *pred* returns + ``True``. + + *pred* defaults to :func:`bool`, which will select truthy items: + + >>> list(locate([0, 1, 1, 0, 1, 0, 0])) + [1, 2, 4] + + Set *pred* to a custom function to, e.g., find the indexes for a particular + item. + + >>> list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b')) + [1, 3] + + If *window_size* is given, then the *pred* function will be called with + that many items. This enables searching for sub-sequences: + + >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] + >>> pred = lambda *args: args == (1, 2, 3) + >>> list(locate(iterable, pred=pred, window_size=3)) + [1, 5, 9] + + Use with :func:`seekable` to find indexes and then retrieve the associated + items: + + >>> from itertools import count + >>> from more_itertools import seekable + >>> source = (3 * n + 1 if (n % 2) else n // 2 for n in count()) + >>> it = seekable(source) + >>> pred = lambda x: x > 100 + >>> indexes = locate(it, pred=pred) + >>> i = next(indexes) + >>> it.seek(i) + >>> next(it) + 106 + + """ + if window_size is None: + return compress(count(), map(pred, iterable)) + + if window_size < 1: + raise ValueError('window size must be at least 1') + + it = windowed(iterable, window_size, fillvalue=_marker) + return compress(count(), starmap(pred, it)) + + +def longest_common_prefix(iterables): + """Yield elements of the longest common prefix amongst given *iterables*. + + >>> ''.join(longest_common_prefix(['abcd', 'abc', 'abf'])) + 'ab' + + """ + return (c[0] for c in takewhile(all_equal, zip(*iterables))) + + +def lstrip(iterable, pred): + """Yield the items from *iterable*, but strip any from the beginning + for which *pred* returns ``True``. + + For example, to remove a set of items from the start of an iterable: + + >>> iterable = (None, False, None, 1, 2, None, 3, False, None) + >>> pred = lambda x: x in {None, False, ''} + >>> list(lstrip(iterable, pred)) + [1, 2, None, 3, False, None] + + This function is analogous to to :func:`str.lstrip`, and is essentially + an wrapper for :func:`itertools.dropwhile`. + + """ + return dropwhile(pred, iterable) + + +def rstrip(iterable, pred): + """Yield the items from *iterable*, but strip any from the end + for which *pred* returns ``True``. + + For example, to remove a set of items from the end of an iterable: + + >>> iterable = (None, False, None, 1, 2, None, 3, False, None) + >>> pred = lambda x: x in {None, False, ''} + >>> list(rstrip(iterable, pred)) + [None, False, None, 1, 2, None, 3] + + This function is analogous to :func:`str.rstrip`. + + """ + cache = [] + cache_append = cache.append + cache_clear = cache.clear + for x in iterable: + if pred(x): + cache_append(x) + else: + yield from cache + cache_clear() + yield x + + +def strip(iterable, pred): + """Yield the items from *iterable*, but strip any from the + beginning and end for which *pred* returns ``True``. + + For example, to remove a set of items from both ends of an iterable: + + >>> iterable = (None, False, None, 1, 2, None, 3, False, None) + >>> pred = lambda x: x in {None, False, ''} + >>> list(strip(iterable, pred)) + [1, 2, None, 3] + + This function is analogous to :func:`str.strip`. + + """ + return rstrip(lstrip(iterable, pred), pred) + + +class islice_extended: + """An extension of :func:`itertools.islice` that supports negative values + for *stop*, *start*, and *step*. + + >>> iterable = iter('abcdefgh') + >>> list(islice_extended(iterable, -4, -1)) + ['e', 'f', 'g'] + + Slices with negative values require some caching of *iterable*, but this + function takes care to minimize the amount of memory required. + + For example, you can use a negative step with an infinite iterator: + + >>> from itertools import count + >>> list(islice_extended(count(), 110, 99, -2)) + [110, 108, 106, 104, 102, 100] + + You can also use slice notation directly: + + >>> iterable = map(str, count()) + >>> it = islice_extended(iterable)[10:20:2] + >>> list(it) + ['10', '12', '14', '16', '18'] + + """ + + def __init__(self, iterable, *args): + it = iter(iterable) + if args: + self._iterable = _islice_helper(it, slice(*args)) + else: + self._iterable = it + + def __iter__(self): + return self + + def __next__(self): + return next(self._iterable) + + def __getitem__(self, key): + if isinstance(key, slice): + return islice_extended(_islice_helper(self._iterable, key)) + + raise TypeError('islice_extended.__getitem__ argument must be a slice') + + +def _islice_helper(it, s): + start = s.start + stop = s.stop + if s.step == 0: + raise ValueError('step argument must be a non-zero integer or None.') + step = s.step or 1 + + if step > 0: + start = 0 if (start is None) else start + + if start < 0: + # Consume all but the last -start items + cache = deque(enumerate(it, 1), maxlen=-start) + len_iter = cache[-1][0] if cache else 0 + + # Adjust start to be positive + i = max(len_iter + start, 0) + + # Adjust stop to be positive + if stop is None: + j = len_iter + elif stop >= 0: + j = min(stop, len_iter) + else: + j = max(len_iter + stop, 0) + + # Slice the cache + n = j - i + if n <= 0: + return + + for index, item in islice(cache, 0, n, step): + yield item + elif (stop is not None) and (stop < 0): + # Advance to the start position + next(islice(it, start, start), None) + + # When stop is negative, we have to carry -stop items while + # iterating + cache = deque(islice(it, -stop), maxlen=-stop) + + for index, item in enumerate(it): + cached_item = cache.popleft() + if index % step == 0: + yield cached_item + cache.append(item) + else: + # When both start and stop are positive we have the normal case + yield from islice(it, start, stop, step) + else: + start = -1 if (start is None) else start + + if (stop is not None) and (stop < 0): + # Consume all but the last items + n = -stop - 1 + cache = deque(enumerate(it, 1), maxlen=n) + len_iter = cache[-1][0] if cache else 0 + + # If start and stop are both negative they are comparable and + # we can just slice. Otherwise we can adjust start to be negative + # and then slice. + if start < 0: + i, j = start, stop + else: + i, j = min(start - len_iter, -1), None + + for index, item in list(cache)[i:j:step]: + yield item + else: + # Advance to the stop position + if stop is not None: + m = stop + 1 + next(islice(it, m, m), None) + + # stop is positive, so if start is negative they are not comparable + # and we need the rest of the items. + if start < 0: + i = start + n = None + # stop is None and start is positive, so we just need items up to + # the start index. + elif stop is None: + i = None + n = start + 1 + # Both stop and start are positive, so they are comparable. + else: + i = None + n = start - stop + if n <= 0: + return + + cache = list(islice(it, n)) + + yield from cache[i::step] + + +def always_reversible(iterable): + """An extension of :func:`reversed` that supports all iterables, not + just those which implement the ``Reversible`` or ``Sequence`` protocols. + + >>> print(*always_reversible(x for x in range(3))) + 2 1 0 + + If the iterable is already reversible, this function returns the + result of :func:`reversed()`. If the iterable is not reversible, + this function will cache the remaining items in the iterable and + yield them in reverse order, which may require significant storage. + """ + try: + return reversed(iterable) + except TypeError: + return reversed(list(iterable)) + + +def consecutive_groups(iterable, ordering=lambda x: x): + """Yield groups of consecutive items using :func:`itertools.groupby`. + The *ordering* function determines whether two items are adjacent by + returning their position. + + By default, the ordering function is the identity function. This is + suitable for finding runs of numbers: + + >>> iterable = [1, 10, 11, 12, 20, 30, 31, 32, 33, 40] + >>> for group in consecutive_groups(iterable): + ... print(list(group)) + [1] + [10, 11, 12] + [20] + [30, 31, 32, 33] + [40] + + For finding runs of adjacent letters, try using the :meth:`index` method + of a string of letters: + + >>> from string import ascii_lowercase + >>> iterable = 'abcdfgilmnop' + >>> ordering = ascii_lowercase.index + >>> for group in consecutive_groups(iterable, ordering): + ... print(list(group)) + ['a', 'b', 'c', 'd'] + ['f', 'g'] + ['i'] + ['l', 'm', 'n', 'o', 'p'] + + Each group of consecutive items is an iterator that shares it source with + *iterable*. When an an output group is advanced, the previous group is + no longer available unless its elements are copied (e.g., into a ``list``). + + >>> iterable = [1, 2, 11, 12, 21, 22] + >>> saved_groups = [] + >>> for group in consecutive_groups(iterable): + ... saved_groups.append(list(group)) # Copy group elements + >>> saved_groups + [[1, 2], [11, 12], [21, 22]] + + """ + for k, g in groupby( + enumerate(iterable), key=lambda x: x[0] - ordering(x[1]) + ): + yield map(itemgetter(1), g) + + +def difference(iterable, func=sub, *, initial=None): + """This function is the inverse of :func:`itertools.accumulate`. By default + it will compute the first difference of *iterable* using + :func:`operator.sub`: + + >>> from itertools import accumulate + >>> iterable = accumulate([0, 1, 2, 3, 4]) # produces 0, 1, 3, 6, 10 + >>> list(difference(iterable)) + [0, 1, 2, 3, 4] + + *func* defaults to :func:`operator.sub`, but other functions can be + specified. They will be applied as follows:: + + A, B, C, D, ... --> A, func(B, A), func(C, B), func(D, C), ... + + For example, to do progressive division: + + >>> iterable = [1, 2, 6, 24, 120] + >>> func = lambda x, y: x // y + >>> list(difference(iterable, func)) + [1, 2, 3, 4, 5] + + If the *initial* keyword is set, the first element will be skipped when + computing successive differences. + + >>> it = [10, 11, 13, 16] # from accumulate([1, 2, 3], initial=10) + >>> list(difference(it, initial=10)) + [1, 2, 3] + + """ + a, b = tee(iterable) + try: + first = [next(b)] + except StopIteration: + return iter([]) + + if initial is not None: + first = [] + + return chain(first, map(func, b, a)) + + +class SequenceView(Sequence): + """Return a read-only view of the sequence object *target*. + + :class:`SequenceView` objects are analogous to Python's built-in + "dictionary view" types. They provide a dynamic view of a sequence's items, + meaning that when the sequence updates, so does the view. + + >>> seq = ['0', '1', '2'] + >>> view = SequenceView(seq) + >>> view + SequenceView(['0', '1', '2']) + >>> seq.append('3') + >>> view + SequenceView(['0', '1', '2', '3']) + + Sequence views support indexing, slicing, and length queries. They act + like the underlying sequence, except they don't allow assignment: + + >>> view[1] + '1' + >>> view[1:-1] + ['1', '2'] + >>> len(view) + 4 + + Sequence views are useful as an alternative to copying, as they don't + require (much) extra storage. + + """ + + def __init__(self, target): + if not isinstance(target, Sequence): + raise TypeError + self._target = target + + def __getitem__(self, index): + return self._target[index] + + def __len__(self): + return len(self._target) + + def __repr__(self): + return '{}({})'.format(self.__class__.__name__, repr(self._target)) + + +class seekable: + """Wrap an iterator to allow for seeking backward and forward. This + progressively caches the items in the source iterable so they can be + re-visited. + + Call :meth:`seek` with an index to seek to that position in the source + iterable. + + To "reset" an iterator, seek to ``0``: + + >>> from itertools import count + >>> it = seekable((str(n) for n in count())) + >>> next(it), next(it), next(it) + ('0', '1', '2') + >>> it.seek(0) + >>> next(it), next(it), next(it) + ('0', '1', '2') + >>> next(it) + '3' + + You can also seek forward: + + >>> it = seekable((str(n) for n in range(20))) + >>> it.seek(10) + >>> next(it) + '10' + >>> it.seek(20) # Seeking past the end of the source isn't a problem + >>> list(it) + [] + >>> it.seek(0) # Resetting works even after hitting the end + >>> next(it), next(it), next(it) + ('0', '1', '2') + + Call :meth:`peek` to look ahead one item without advancing the iterator: + + >>> it = seekable('1234') + >>> it.peek() + '1' + >>> list(it) + ['1', '2', '3', '4'] + >>> it.peek(default='empty') + 'empty' + + Before the iterator is at its end, calling :func:`bool` on it will return + ``True``. After it will return ``False``: + + >>> it = seekable('5678') + >>> bool(it) + True + >>> list(it) + ['5', '6', '7', '8'] + >>> bool(it) + False + + You may view the contents of the cache with the :meth:`elements` method. + That returns a :class:`SequenceView`, a view that updates automatically: + + >>> it = seekable((str(n) for n in range(10))) + >>> next(it), next(it), next(it) + ('0', '1', '2') + >>> elements = it.elements() + >>> elements + SequenceView(['0', '1', '2']) + >>> next(it) + '3' + >>> elements + SequenceView(['0', '1', '2', '3']) + + By default, the cache grows as the source iterable progresses, so beware of + wrapping very large or infinite iterables. Supply *maxlen* to limit the + size of the cache (this of course limits how far back you can seek). + + >>> from itertools import count + >>> it = seekable((str(n) for n in count()), maxlen=2) + >>> next(it), next(it), next(it), next(it) + ('0', '1', '2', '3') + >>> list(it.elements()) + ['2', '3'] + >>> it.seek(0) + >>> next(it), next(it), next(it), next(it) + ('2', '3', '4', '5') + >>> next(it) + '6' + + """ + + def __init__(self, iterable, maxlen=None): + self._source = iter(iterable) + if maxlen is None: + self._cache = [] + else: + self._cache = deque([], maxlen) + self._index = None + + def __iter__(self): + return self + + def __next__(self): + if self._index is not None: + try: + item = self._cache[self._index] + except IndexError: + self._index = None + else: + self._index += 1 + return item + + item = next(self._source) + self._cache.append(item) + return item + + def __bool__(self): + try: + self.peek() + except StopIteration: + return False + return True + + def peek(self, default=_marker): + try: + peeked = next(self) + except StopIteration: + if default is _marker: + raise + return default + if self._index is None: + self._index = len(self._cache) + self._index -= 1 + return peeked + + def elements(self): + return SequenceView(self._cache) + + def seek(self, index): + self._index = index + remainder = index - len(self._cache) + if remainder > 0: + consume(self, remainder) + + +class run_length: + """ + :func:`run_length.encode` compresses an iterable with run-length encoding. + It yields groups of repeated items with the count of how many times they + were repeated: + + >>> uncompressed = 'abbcccdddd' + >>> list(run_length.encode(uncompressed)) + [('a', 1), ('b', 2), ('c', 3), ('d', 4)] + + :func:`run_length.decode` decompresses an iterable that was previously + compressed with run-length encoding. It yields the items of the + decompressed iterable: + + >>> compressed = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] + >>> list(run_length.decode(compressed)) + ['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd'] + + """ + + @staticmethod + def encode(iterable): + return ((k, ilen(g)) for k, g in groupby(iterable)) + + @staticmethod + def decode(iterable): + return chain.from_iterable(repeat(k, n) for k, n in iterable) + + +def exactly_n(iterable, n, predicate=bool): + """Return ``True`` if exactly ``n`` items in the iterable are ``True`` + according to the *predicate* function. + + >>> exactly_n([True, True, False], 2) + True + >>> exactly_n([True, True, False], 1) + False + >>> exactly_n([0, 1, 2, 3, 4, 5], 3, lambda x: x < 3) + True + + The iterable will be advanced until ``n + 1`` truthy items are encountered, + so avoid calling it on infinite iterables. + + """ + return len(take(n + 1, filter(predicate, iterable))) == n + + +def circular_shifts(iterable): + """Return a list of circular shifts of *iterable*. + + >>> circular_shifts(range(4)) + [(0, 1, 2, 3), (1, 2, 3, 0), (2, 3, 0, 1), (3, 0, 1, 2)] + """ + lst = list(iterable) + return take(len(lst), windowed(cycle(lst), len(lst))) + + +def make_decorator(wrapping_func, result_index=0): + """Return a decorator version of *wrapping_func*, which is a function that + modifies an iterable. *result_index* is the position in that function's + signature where the iterable goes. + + This lets you use itertools on the "production end," i.e. at function + definition. This can augment what the function returns without changing the + function's code. + + For example, to produce a decorator version of :func:`chunked`: + + >>> from more_itertools import chunked + >>> chunker = make_decorator(chunked, result_index=0) + >>> @chunker(3) + ... def iter_range(n): + ... return iter(range(n)) + ... + >>> list(iter_range(9)) + [[0, 1, 2], [3, 4, 5], [6, 7, 8]] + + To only allow truthy items to be returned: + + >>> truth_serum = make_decorator(filter, result_index=1) + >>> @truth_serum(bool) + ... def boolean_test(): + ... return [0, 1, '', ' ', False, True] + ... + >>> list(boolean_test()) + [1, ' ', True] + + The :func:`peekable` and :func:`seekable` wrappers make for practical + decorators: + + >>> from more_itertools import peekable + >>> peekable_function = make_decorator(peekable) + >>> @peekable_function() + ... def str_range(*args): + ... return (str(x) for x in range(*args)) + ... + >>> it = str_range(1, 20, 2) + >>> next(it), next(it), next(it) + ('1', '3', '5') + >>> it.peek() + '7' + >>> next(it) + '7' + + """ + + # See https://sites.google.com/site/bbayles/index/decorator_factory for + # notes on how this works. + def decorator(*wrapping_args, **wrapping_kwargs): + def outer_wrapper(f): + def inner_wrapper(*args, **kwargs): + result = f(*args, **kwargs) + wrapping_args_ = list(wrapping_args) + wrapping_args_.insert(result_index, result) + return wrapping_func(*wrapping_args_, **wrapping_kwargs) + + return inner_wrapper + + return outer_wrapper + + return decorator + + +def map_reduce(iterable, keyfunc, valuefunc=None, reducefunc=None): + """Return a dictionary that maps the items in *iterable* to categories + defined by *keyfunc*, transforms them with *valuefunc*, and + then summarizes them by category with *reducefunc*. + + *valuefunc* defaults to the identity function if it is unspecified. + If *reducefunc* is unspecified, no summarization takes place: + + >>> keyfunc = lambda x: x.upper() + >>> result = map_reduce('abbccc', keyfunc) + >>> sorted(result.items()) + [('A', ['a']), ('B', ['b', 'b']), ('C', ['c', 'c', 'c'])] + + Specifying *valuefunc* transforms the categorized items: + + >>> keyfunc = lambda x: x.upper() + >>> valuefunc = lambda x: 1 + >>> result = map_reduce('abbccc', keyfunc, valuefunc) + >>> sorted(result.items()) + [('A', [1]), ('B', [1, 1]), ('C', [1, 1, 1])] + + Specifying *reducefunc* summarizes the categorized items: + + >>> keyfunc = lambda x: x.upper() + >>> valuefunc = lambda x: 1 + >>> reducefunc = sum + >>> result = map_reduce('abbccc', keyfunc, valuefunc, reducefunc) + >>> sorted(result.items()) + [('A', 1), ('B', 2), ('C', 3)] + + You may want to filter the input iterable before applying the map/reduce + procedure: + + >>> all_items = range(30) + >>> items = [x for x in all_items if 10 <= x <= 20] # Filter + >>> keyfunc = lambda x: x % 2 # Evens map to 0; odds to 1 + >>> categories = map_reduce(items, keyfunc=keyfunc) + >>> sorted(categories.items()) + [(0, [10, 12, 14, 16, 18, 20]), (1, [11, 13, 15, 17, 19])] + >>> summaries = map_reduce(items, keyfunc=keyfunc, reducefunc=sum) + >>> sorted(summaries.items()) + [(0, 90), (1, 75)] + + Note that all items in the iterable are gathered into a list before the + summarization step, which may require significant storage. + + The returned object is a :obj:`collections.defaultdict` with the + ``default_factory`` set to ``None``, such that it behaves like a normal + dictionary. + + """ + valuefunc = (lambda x: x) if (valuefunc is None) else valuefunc + + ret = defaultdict(list) + for item in iterable: + key = keyfunc(item) + value = valuefunc(item) + ret[key].append(value) + + if reducefunc is not None: + for key, value_list in ret.items(): + ret[key] = reducefunc(value_list) + + ret.default_factory = None + return ret + + +def rlocate(iterable, pred=bool, window_size=None): + """Yield the index of each item in *iterable* for which *pred* returns + ``True``, starting from the right and moving left. + + *pred* defaults to :func:`bool`, which will select truthy items: + + >>> list(rlocate([0, 1, 1, 0, 1, 0, 0])) # Truthy at 1, 2, and 4 + [4, 2, 1] + + Set *pred* to a custom function to, e.g., find the indexes for a particular + item: + + >>> iterable = iter('abcb') + >>> pred = lambda x: x == 'b' + >>> list(rlocate(iterable, pred)) + [3, 1] + + If *window_size* is given, then the *pred* function will be called with + that many items. This enables searching for sub-sequences: + + >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] + >>> pred = lambda *args: args == (1, 2, 3) + >>> list(rlocate(iterable, pred=pred, window_size=3)) + [9, 5, 1] + + Beware, this function won't return anything for infinite iterables. + If *iterable* is reversible, ``rlocate`` will reverse it and search from + the right. Otherwise, it will search from the left and return the results + in reverse order. + + See :func:`locate` to for other example applications. + + """ + if window_size is None: + try: + len_iter = len(iterable) + return (len_iter - i - 1 for i in locate(reversed(iterable), pred)) + except TypeError: + pass + + return reversed(list(locate(iterable, pred, window_size))) + + +def replace(iterable, pred, substitutes, count=None, window_size=1): + """Yield the items from *iterable*, replacing the items for which *pred* + returns ``True`` with the items from the iterable *substitutes*. + + >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1] + >>> pred = lambda x: x == 0 + >>> substitutes = (2, 3) + >>> list(replace(iterable, pred, substitutes)) + [1, 1, 2, 3, 1, 1, 2, 3, 1, 1] + + If *count* is given, the number of replacements will be limited: + + >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1, 0] + >>> pred = lambda x: x == 0 + >>> substitutes = [None] + >>> list(replace(iterable, pred, substitutes, count=2)) + [1, 1, None, 1, 1, None, 1, 1, 0] + + Use *window_size* to control the number of items passed as arguments to + *pred*. This allows for locating and replacing subsequences. + + >>> iterable = [0, 1, 2, 5, 0, 1, 2, 5] + >>> window_size = 3 + >>> pred = lambda *args: args == (0, 1, 2) # 3 items passed to pred + >>> substitutes = [3, 4] # Splice in these items + >>> list(replace(iterable, pred, substitutes, window_size=window_size)) + [3, 4, 5, 3, 4, 5] + + """ + if window_size < 1: + raise ValueError('window_size must be at least 1') + + # Save the substitutes iterable, since it's used more than once + substitutes = tuple(substitutes) + + # Add padding such that the number of windows matches the length of the + # iterable + it = chain(iterable, [_marker] * (window_size - 1)) + windows = windowed(it, window_size) + + n = 0 + for w in windows: + # If the current window matches our predicate (and we haven't hit + # our maximum number of replacements), splice in the substitutes + # and then consume the following windows that overlap with this one. + # For example, if the iterable is (0, 1, 2, 3, 4...) + # and the window size is 2, we have (0, 1), (1, 2), (2, 3)... + # If the predicate matches on (0, 1), we need to zap (0, 1) and (1, 2) + if pred(*w): + if (count is None) or (n < count): + n += 1 + yield from substitutes + consume(windows, window_size - 1) + continue + + # If there was no match (or we've reached the replacement limit), + # yield the first item from the window. + if w and (w[0] is not _marker): + yield w[0] + + +def partitions(iterable): + """Yield all possible order-preserving partitions of *iterable*. + + >>> iterable = 'abc' + >>> for part in partitions(iterable): + ... print([''.join(p) for p in part]) + ['abc'] + ['a', 'bc'] + ['ab', 'c'] + ['a', 'b', 'c'] + + This is unrelated to :func:`partition`. + + """ + sequence = list(iterable) + n = len(sequence) + for i in powerset(range(1, n)): + yield [sequence[i:j] for i, j in zip((0,) + i, i + (n,))] + + +def set_partitions(iterable, k=None): + """ + Yield the set partitions of *iterable* into *k* parts. Set partitions are + not order-preserving. + + >>> iterable = 'abc' + >>> for part in set_partitions(iterable, 2): + ... print([''.join(p) for p in part]) + ['a', 'bc'] + ['ab', 'c'] + ['b', 'ac'] + + + If *k* is not given, every set partition is generated. + + >>> iterable = 'abc' + >>> for part in set_partitions(iterable): + ... print([''.join(p) for p in part]) + ['abc'] + ['a', 'bc'] + ['ab', 'c'] + ['b', 'ac'] + ['a', 'b', 'c'] + + """ + L = list(iterable) + n = len(L) + if k is not None: + if k < 1: + raise ValueError( + "Can't partition in a negative or zero number of groups" + ) + elif k > n: + return + + def set_partitions_helper(L, k): + n = len(L) + if k == 1: + yield [L] + elif n == k: + yield [[s] for s in L] + else: + e, *M = L + for p in set_partitions_helper(M, k - 1): + yield [[e], *p] + for p in set_partitions_helper(M, k): + for i in range(len(p)): + yield p[:i] + [[e] + p[i]] + p[i + 1 :] + + if k is None: + for k in range(1, n + 1): + yield from set_partitions_helper(L, k) + else: + yield from set_partitions_helper(L, k) + + +class time_limited: + """ + Yield items from *iterable* until *limit_seconds* have passed. + If the time limit expires before all items have been yielded, the + ``timed_out`` parameter will be set to ``True``. + + >>> from time import sleep + >>> def generator(): + ... yield 1 + ... yield 2 + ... sleep(0.2) + ... yield 3 + >>> iterable = time_limited(0.1, generator()) + >>> list(iterable) + [1, 2] + >>> iterable.timed_out + True + + Note that the time is checked before each item is yielded, and iteration + stops if the time elapsed is greater than *limit_seconds*. If your time + limit is 1 second, but it takes 2 seconds to generate the first item from + the iterable, the function will run for 2 seconds and not yield anything. + + """ + + def __init__(self, limit_seconds, iterable): + if limit_seconds < 0: + raise ValueError('limit_seconds must be positive') + self.limit_seconds = limit_seconds + self._iterable = iter(iterable) + self._start_time = monotonic() + self.timed_out = False + + def __iter__(self): + return self + + def __next__(self): + item = next(self._iterable) + if monotonic() - self._start_time > self.limit_seconds: + self.timed_out = True + raise StopIteration + + return item + + +def only(iterable, default=None, too_long=None): + """If *iterable* has only one item, return it. + If it has zero items, return *default*. + If it has more than one item, raise the exception given by *too_long*, + which is ``ValueError`` by default. + + >>> only([], default='missing') + 'missing' + >>> only([1]) + 1 + >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: Expected exactly one item in iterable, but got 1, 2, + and perhaps more.' + >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + TypeError + + Note that :func:`only` attempts to advance *iterable* twice to ensure there + is only one item. See :func:`spy` or :func:`peekable` to check + iterable contents less destructively. + """ + it = iter(iterable) + first_value = next(it, default) + + try: + second_value = next(it) + except StopIteration: + pass + else: + msg = ( + 'Expected exactly one item in iterable, but got {!r}, {!r}, ' + 'and perhaps more.'.format(first_value, second_value) + ) + raise too_long or ValueError(msg) + + return first_value + + +class _IChunk: + def __init__(self, iterable, n): + self._it = islice(iterable, n) + self._cache = deque() + + def fill_cache(self): + self._cache.extend(self._it) + + def __iter__(self): + return self + + def __next__(self): + try: + return next(self._it) + except StopIteration: + if self._cache: + return self._cache.popleft() + else: + raise + + +def ichunked(iterable, n): + """Break *iterable* into sub-iterables with *n* elements each. + :func:`ichunked` is like :func:`chunked`, but it yields iterables + instead of lists. + + If the sub-iterables are read in order, the elements of *iterable* + won't be stored in memory. + If they are read out of order, :func:`itertools.tee` is used to cache + elements as necessary. + + >>> from itertools import count + >>> all_chunks = ichunked(count(), 4) + >>> c_1, c_2, c_3 = next(all_chunks), next(all_chunks), next(all_chunks) + >>> list(c_2) # c_1's elements have been cached; c_3's haven't been + [4, 5, 6, 7] + >>> list(c_1) + [0, 1, 2, 3] + >>> list(c_3) + [8, 9, 10, 11] + + """ + source = peekable(iter(iterable)) + ichunk_marker = object() + while True: + # Check to see whether we're at the end of the source iterable + item = source.peek(ichunk_marker) + if item is ichunk_marker: + return + + chunk = _IChunk(source, n) + yield chunk + + # Advance the source iterable and fill previous chunk's cache + chunk.fill_cache() + + +def iequals(*iterables): + """Return ``True`` if all given *iterables* are equal to each other, + which means that they contain the same elements in the same order. + + The function is useful for comparing iterables of different data types + or iterables that do not support equality checks. + + >>> iequals("abc", ['a', 'b', 'c'], ('a', 'b', 'c'), iter("abc")) + True + + >>> iequals("abc", "acb") + False + + Not to be confused with :func:`all_equals`, which checks whether all + elements of iterable are equal to each other. + + """ + return all(map(all_equal, zip_longest(*iterables, fillvalue=object()))) + + +def distinct_combinations(iterable, r): + """Yield the distinct combinations of *r* items taken from *iterable*. + + >>> list(distinct_combinations([0, 0, 1], 2)) + [(0, 0), (0, 1)] + + Equivalent to ``set(combinations(iterable))``, except duplicates are not + generated and thrown away. For larger input sequences this is much more + efficient. + + """ + if r < 0: + raise ValueError('r must be non-negative') + elif r == 0: + yield () + return + pool = tuple(iterable) + generators = [unique_everseen(enumerate(pool), key=itemgetter(1))] + current_combo = [None] * r + level = 0 + while generators: + try: + cur_idx, p = next(generators[-1]) + except StopIteration: + generators.pop() + level -= 1 + continue + current_combo[level] = p + if level + 1 == r: + yield tuple(current_combo) + else: + generators.append( + unique_everseen( + enumerate(pool[cur_idx + 1 :], cur_idx + 1), + key=itemgetter(1), + ) + ) + level += 1 + + +def filter_except(validator, iterable, *exceptions): + """Yield the items from *iterable* for which the *validator* function does + not raise one of the specified *exceptions*. + + *validator* is called for each item in *iterable*. + It should be a function that accepts one argument and raises an exception + if that item is not valid. + + >>> iterable = ['1', '2', 'three', '4', None] + >>> list(filter_except(int, iterable, ValueError, TypeError)) + ['1', '2', '4'] + + If an exception other than one given by *exceptions* is raised by + *validator*, it is raised like normal. + """ + for item in iterable: + try: + validator(item) + except exceptions: + pass + else: + yield item + + +def map_except(function, iterable, *exceptions): + """Transform each item from *iterable* with *function* and yield the + result, unless *function* raises one of the specified *exceptions*. + + *function* is called to transform each item in *iterable*. + It should accept one argument. + + >>> iterable = ['1', '2', 'three', '4', None] + >>> list(map_except(int, iterable, ValueError, TypeError)) + [1, 2, 4] + + If an exception other than one given by *exceptions* is raised by + *function*, it is raised like normal. + """ + for item in iterable: + try: + yield function(item) + except exceptions: + pass + + +def map_if(iterable, pred, func, func_else=lambda x: x): + """Evaluate each item from *iterable* using *pred*. If the result is + equivalent to ``True``, transform the item with *func* and yield it. + Otherwise, transform the item with *func_else* and yield it. + + *pred*, *func*, and *func_else* should each be functions that accept + one argument. By default, *func_else* is the identity function. + + >>> from math import sqrt + >>> iterable = list(range(-5, 5)) + >>> iterable + [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] + >>> list(map_if(iterable, lambda x: x > 3, lambda x: 'toobig')) + [-5, -4, -3, -2, -1, 0, 1, 2, 3, 'toobig'] + >>> list(map_if(iterable, lambda x: x >= 0, + ... lambda x: f'{sqrt(x):.2f}', lambda x: None)) + [None, None, None, None, None, '0.00', '1.00', '1.41', '1.73', '2.00'] + """ + for item in iterable: + yield func(item) if pred(item) else func_else(item) + + +def _sample_unweighted(iterable, k): + # Implementation of "Algorithm L" from the 1994 paper by Kim-Hung Li: + # "Reservoir-Sampling Algorithms of Time Complexity O(n(1+log(N/n)))". + + # Fill up the reservoir (collection of samples) with the first `k` samples + reservoir = take(k, iterable) + + # Generate random number that's the largest in a sample of k U(0,1) numbers + # Largest order statistic: https://en.wikipedia.org/wiki/Order_statistic + W = exp(log(random()) / k) + + # The number of elements to skip before changing the reservoir is a random + # number with a geometric distribution. Sample it using random() and logs. + next_index = k + floor(log(random()) / log(1 - W)) + + for index, element in enumerate(iterable, k): + if index == next_index: + reservoir[randrange(k)] = element + # The new W is the largest in a sample of k U(0, `old_W`) numbers + W *= exp(log(random()) / k) + next_index += floor(log(random()) / log(1 - W)) + 1 + + return reservoir + + +def _sample_weighted(iterable, k, weights): + # Implementation of "A-ExpJ" from the 2006 paper by Efraimidis et al. : + # "Weighted random sampling with a reservoir". + + # Log-transform for numerical stability for weights that are small/large + weight_keys = (log(random()) / weight for weight in weights) + + # Fill up the reservoir (collection of samples) with the first `k` + # weight-keys and elements, then heapify the list. + reservoir = take(k, zip(weight_keys, iterable)) + heapify(reservoir) + + # The number of jumps before changing the reservoir is a random variable + # with an exponential distribution. Sample it using random() and logs. + smallest_weight_key, _ = reservoir[0] + weights_to_skip = log(random()) / smallest_weight_key + + for weight, element in zip(weights, iterable): + if weight >= weights_to_skip: + # The notation here is consistent with the paper, but we store + # the weight-keys in log-space for better numerical stability. + smallest_weight_key, _ = reservoir[0] + t_w = exp(weight * smallest_weight_key) + r_2 = uniform(t_w, 1) # generate U(t_w, 1) + weight_key = log(r_2) / weight + heapreplace(reservoir, (weight_key, element)) + smallest_weight_key, _ = reservoir[0] + weights_to_skip = log(random()) / smallest_weight_key + else: + weights_to_skip -= weight + + # Equivalent to [element for weight_key, element in sorted(reservoir)] + return [heappop(reservoir)[1] for _ in range(k)] + + +def sample(iterable, k, weights=None): + """Return a *k*-length list of elements chosen (without replacement) + from the *iterable*. Like :func:`random.sample`, but works on iterables + of unknown length. + + >>> iterable = range(100) + >>> sample(iterable, 5) # doctest: +SKIP + [81, 60, 96, 16, 4] + + An iterable with *weights* may also be given: + + >>> iterable = range(100) + >>> weights = (i * i + 1 for i in range(100)) + >>> sampled = sample(iterable, 5, weights=weights) # doctest: +SKIP + [79, 67, 74, 66, 78] + + The algorithm can also be used to generate weighted random permutations. + The relative weight of each item determines the probability that it + appears late in the permutation. + + >>> data = "abcdefgh" + >>> weights = range(1, len(data) + 1) + >>> sample(data, k=len(data), weights=weights) # doctest: +SKIP + ['c', 'a', 'b', 'e', 'g', 'd', 'h', 'f'] + """ + if k == 0: + return [] + + iterable = iter(iterable) + if weights is None: + return _sample_unweighted(iterable, k) + else: + weights = iter(weights) + return _sample_weighted(iterable, k, weights) + + +def is_sorted(iterable, key=None, reverse=False, strict=False): + """Returns ``True`` if the items of iterable are in sorted order, and + ``False`` otherwise. *key* and *reverse* have the same meaning that they do + in the built-in :func:`sorted` function. + + >>> is_sorted(['1', '2', '3', '4', '5'], key=int) + True + >>> is_sorted([5, 4, 3, 1, 2], reverse=True) + False + + If *strict*, tests for strict sorting, that is, returns ``False`` if equal + elements are found: + + >>> is_sorted([1, 2, 2]) + True + >>> is_sorted([1, 2, 2], strict=True) + False + + The function returns ``False`` after encountering the first out-of-order + item. If there are no out-of-order items, the iterable is exhausted. + """ + + compare = (le if reverse else ge) if strict else (lt if reverse else gt) + it = iterable if key is None else map(key, iterable) + return not any(starmap(compare, pairwise(it))) + + +class AbortThread(BaseException): + pass + + +class callback_iter: + """Convert a function that uses callbacks to an iterator. + + Let *func* be a function that takes a `callback` keyword argument. + For example: + + >>> def func(callback=None): + ... for i, c in [(1, 'a'), (2, 'b'), (3, 'c')]: + ... if callback: + ... callback(i, c) + ... return 4 + + + Use ``with callback_iter(func)`` to get an iterator over the parameters + that are delivered to the callback. + + >>> with callback_iter(func) as it: + ... for args, kwargs in it: + ... print(args) + (1, 'a') + (2, 'b') + (3, 'c') + + The function will be called in a background thread. The ``done`` property + indicates whether it has completed execution. + + >>> it.done + True + + If it completes successfully, its return value will be available + in the ``result`` property. + + >>> it.result + 4 + + Notes: + + * If the function uses some keyword argument besides ``callback``, supply + *callback_kwd*. + * If it finished executing, but raised an exception, accessing the + ``result`` property will raise the same exception. + * If it hasn't finished executing, accessing the ``result`` + property from within the ``with`` block will raise ``RuntimeError``. + * If it hasn't finished executing, accessing the ``result`` property from + outside the ``with`` block will raise a + ``more_itertools.AbortThread`` exception. + * Provide *wait_seconds* to adjust how frequently the it is polled for + output. + + """ + + def __init__(self, func, callback_kwd='callback', wait_seconds=0.1): + self._func = func + self._callback_kwd = callback_kwd + self._aborted = False + self._future = None + self._wait_seconds = wait_seconds + # Lazily import concurrent.future + self._executor = __import__( + ).futures.__import__("concurrent.futures").futures.ThreadPoolExecutor(max_workers=1) + self._iterator = self._reader() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self._aborted = True + self._executor.shutdown() + + def __iter__(self): + return self + + def __next__(self): + return next(self._iterator) + + @property + def done(self): + if self._future is None: + return False + return self._future.done() + + @property + def result(self): + if not self.done: + raise RuntimeError('Function has not yet completed') + + return self._future.result() + + def _reader(self): + q = Queue() + + def callback(*args, **kwargs): + if self._aborted: + raise AbortThread('canceled by user') + + q.put((args, kwargs)) + + self._future = self._executor.submit( + self._func, **{self._callback_kwd: callback} + ) + + while True: + try: + item = q.get(timeout=self._wait_seconds) + except Empty: + pass + else: + q.task_done() + yield item + + if self._future.done(): + break + + remaining = [] + while True: + try: + item = q.get_nowait() + except Empty: + break + else: + q.task_done() + remaining.append(item) + q.join() + yield from remaining + + +def windowed_complete(iterable, n): + """ + Yield ``(beginning, middle, end)`` tuples, where: + + * Each ``middle`` has *n* items from *iterable* + * Each ``beginning`` has the items before the ones in ``middle`` + * Each ``end`` has the items after the ones in ``middle`` + + >>> iterable = range(7) + >>> n = 3 + >>> for beginning, middle, end in windowed_complete(iterable, n): + ... print(beginning, middle, end) + () (0, 1, 2) (3, 4, 5, 6) + (0,) (1, 2, 3) (4, 5, 6) + (0, 1) (2, 3, 4) (5, 6) + (0, 1, 2) (3, 4, 5) (6,) + (0, 1, 2, 3) (4, 5, 6) () + + Note that *n* must be at least 0 and most equal to the length of + *iterable*. + + This function will exhaust the iterable and may require significant + storage. + """ + if n < 0: + raise ValueError('n must be >= 0') + + seq = tuple(iterable) + size = len(seq) + + if n > size: + raise ValueError('n must be <= len(seq)') + + for i in range(size - n + 1): + beginning = seq[:i] + middle = seq[i : i + n] + end = seq[i + n :] + yield beginning, middle, end + + +def all_unique(iterable, key=None): + """ + Returns ``True`` if all the elements of *iterable* are unique (no two + elements are equal). + + >>> all_unique('ABCB') + False + + If a *key* function is specified, it will be used to make comparisons. + + >>> all_unique('ABCb') + True + >>> all_unique('ABCb', str.lower) + False + + The function returns as soon as the first non-unique element is + encountered. Iterables with a mix of hashable and unhashable items can + be used, but the function will be slower for unhashable items. + """ + seenset = set() + seenset_add = seenset.add + seenlist = [] + seenlist_add = seenlist.append + for element in map(key, iterable) if key else iterable: + try: + if element in seenset: + return False + seenset_add(element) + except TypeError: + if element in seenlist: + return False + seenlist_add(element) + return True + + +def nth_product(index, *args): + """Equivalent to ``list(product(*args))[index]``. + + The products of *args* can be ordered lexicographically. + :func:`nth_product` computes the product at sort position *index* without + computing the previous products. + + >>> nth_product(8, range(2), range(2), range(2), range(2)) + (1, 0, 0, 0) + + ``IndexError`` will be raised if the given *index* is invalid. + """ + pools = list(map(tuple, reversed(args))) + ns = list(map(len, pools)) + + c = reduce(mul, ns) + + if index < 0: + index += c + + if not 0 <= index < c: + raise IndexError + + result = [] + for pool, n in zip(pools, ns): + result.append(pool[index % n]) + index //= n + + return tuple(reversed(result)) + + +def nth_permutation(iterable, r, index): + """Equivalent to ``list(permutations(iterable, r))[index]``` + + The subsequences of *iterable* that are of length *r* where order is + important can be ordered lexicographically. :func:`nth_permutation` + computes the subsequence at sort position *index* directly, without + computing the previous subsequences. + + >>> nth_permutation('ghijk', 2, 5) + ('h', 'i') + + ``ValueError`` will be raised If *r* is negative or greater than the length + of *iterable*. + ``IndexError`` will be raised if the given *index* is invalid. + """ + pool = list(iterable) + n = len(pool) + + if r is None or r == n: + r, c = n, factorial(n) + elif not 0 <= r < n: + raise ValueError + else: + c = factorial(n) // factorial(n - r) + + if index < 0: + index += c + + if not 0 <= index < c: + raise IndexError + + if c == 0: + return tuple() + + result = [0] * r + q = index * factorial(n) // c if r < n else index + for d in range(1, n + 1): + q, i = divmod(q, d) + if 0 <= n - d < r: + result[n - d] = i + if q == 0: + break + + return tuple(map(pool.pop, result)) + + +def value_chain(*args): + """Yield all arguments passed to the function in the same order in which + they were passed. If an argument itself is iterable then iterate over its + values. + + >>> list(value_chain(1, 2, 3, [4, 5, 6])) + [1, 2, 3, 4, 5, 6] + + Binary and text strings are not considered iterable and are emitted + as-is: + + >>> list(value_chain('12', '34', ['56', '78'])) + ['12', '34', '56', '78'] + + + Multiple levels of nesting are not flattened. + + """ + for value in args: + if isinstance(value, (str, bytes)): + yield value + continue + try: + yield from value + except TypeError: + yield value + + +def product_index(element, *args): + """Equivalent to ``list(product(*args)).index(element)`` + + The products of *args* can be ordered lexicographically. + :func:`product_index` computes the first index of *element* without + computing the previous products. + + >>> product_index([8, 2], range(10), range(5)) + 42 + + ``ValueError`` will be raised if the given *element* isn't in the product + of *args*. + """ + index = 0 + + for x, pool in zip_longest(element, args, fillvalue=_marker): + if x is _marker or pool is _marker: + raise ValueError('element is not a product of args') + + pool = tuple(pool) + index = index * len(pool) + pool.index(x) + + return index + + +def combination_index(element, iterable): + """Equivalent to ``list(combinations(iterable, r)).index(element)`` + + The subsequences of *iterable* that are of length *r* can be ordered + lexicographically. :func:`combination_index` computes the index of the + first *element*, without computing the previous combinations. + + >>> combination_index('adf', 'abcdefg') + 10 + + ``ValueError`` will be raised if the given *element* isn't one of the + combinations of *iterable*. + """ + element = enumerate(element) + k, y = next(element, (None, None)) + if k is None: + return 0 + + indexes = [] + pool = enumerate(iterable) + for n, x in pool: + if x == y: + indexes.append(n) + tmp, y = next(element, (None, None)) + if tmp is None: + break + else: + k = tmp + else: + raise ValueError('element is not a combination of iterable') + + n, _ = last(pool, default=(n, None)) + + # Python versions below 3.8 don't have math.comb + index = 1 + for i, j in enumerate(reversed(indexes), start=1): + j = n - j + if i <= j: + index += factorial(j) // (factorial(i) * factorial(j - i)) + + return factorial(n + 1) // (factorial(k + 1) * factorial(n - k)) - index + + +def permutation_index(element, iterable): + """Equivalent to ``list(permutations(iterable, r)).index(element)``` + + The subsequences of *iterable* that are of length *r* where order is + important can be ordered lexicographically. :func:`permutation_index` + computes the index of the first *element* directly, without computing + the previous permutations. + + >>> permutation_index([1, 3, 2], range(5)) + 19 + + ``ValueError`` will be raised if the given *element* isn't one of the + permutations of *iterable*. + """ + index = 0 + pool = list(iterable) + for i, x in zip(range(len(pool), -1, -1), element): + r = pool.index(x) + index = index * i + r + del pool[r] + + return index + + +class countable: + """Wrap *iterable* and keep a count of how many items have been consumed. + + The ``items_seen`` attribute starts at ``0`` and increments as the iterable + is consumed: + + >>> iterable = map(str, range(10)) + >>> it = countable(iterable) + >>> it.items_seen + 0 + >>> next(it), next(it) + ('0', '1') + >>> list(it) + ['2', '3', '4', '5', '6', '7', '8', '9'] + >>> it.items_seen + 10 + """ + + def __init__(self, iterable): + self._it = iter(iterable) + self.items_seen = 0 + + def __iter__(self): + return self + + def __next__(self): + item = next(self._it) + self.items_seen += 1 + + return item + + +def chunked_even(iterable, n): + """Break *iterable* into lists of approximately length *n*. + Items are distributed such the lengths of the lists differ by at most + 1 item. + + >>> iterable = [1, 2, 3, 4, 5, 6, 7] + >>> n = 3 + >>> list(chunked_even(iterable, n)) # List lengths: 3, 2, 2 + [[1, 2, 3], [4, 5], [6, 7]] + >>> list(chunked(iterable, n)) # List lengths: 3, 3, 1 + [[1, 2, 3], [4, 5, 6], [7]] + + """ + + len_method = getattr(iterable, '__len__', None) + + if len_method is None: + return _chunked_even_online(iterable, n) + else: + return _chunked_even_finite(iterable, len_method(), n) + + +def _chunked_even_online(iterable, n): + buffer = [] + maxbuf = n + (n - 2) * (n - 1) + for x in iterable: + buffer.append(x) + if len(buffer) == maxbuf: + yield buffer[:n] + buffer = buffer[n:] + yield from _chunked_even_finite(buffer, len(buffer), n) + + +def _chunked_even_finite(iterable, N, n): + if N < 1: + return + + # Lists are either size `full_size <= n` or `partial_size = full_size - 1` + q, r = divmod(N, n) + num_lists = q + (1 if r > 0 else 0) + q, r = divmod(N, num_lists) + full_size = q + (1 if r > 0 else 0) + partial_size = full_size - 1 + num_full = N - partial_size * num_lists + num_partial = num_lists - num_full + + buffer = [] + iterator = iter(iterable) + + # Yield num_full lists of full_size + for x in iterator: + buffer.append(x) + if len(buffer) == full_size: + yield buffer + buffer = [] + num_full -= 1 + if num_full <= 0: + break + + # Yield num_partial lists of partial_size + for x in iterator: + buffer.append(x) + if len(buffer) == partial_size: + yield buffer + buffer = [] + num_partial -= 1 + + +def zip_broadcast(*objects, scalar_types=(str, bytes), strict=False): + """A version of :func:`zip` that "broadcasts" any scalar + (i.e., non-iterable) items into output tuples. + + >>> iterable_1 = [1, 2, 3] + >>> iterable_2 = ['a', 'b', 'c'] + >>> scalar = '_' + >>> list(zip_broadcast(iterable_1, iterable_2, scalar)) + [(1, 'a', '_'), (2, 'b', '_'), (3, 'c', '_')] + + The *scalar_types* keyword argument determines what types are considered + scalar. It is set to ``(str, bytes)`` by default. Set it to ``None`` to + treat strings and byte strings as iterable: + + >>> list(zip_broadcast('abc', 0, 'xyz', scalar_types=None)) + [('a', 0, 'x'), ('b', 0, 'y'), ('c', 0, 'z')] + + If the *strict* keyword argument is ``True``, then + ``UnequalIterablesError`` will be raised if any of the iterables have + different lengths. + """ + + def is_scalar(obj): + if scalar_types and isinstance(obj, scalar_types): + return True + try: + iter(obj) + except TypeError: + return True + else: + return False + + size = len(objects) + if not size: + return + + iterables, iterable_positions = [], [] + scalars, scalar_positions = [], [] + for i, obj in enumerate(objects): + if is_scalar(obj): + scalars.append(obj) + scalar_positions.append(i) + else: + iterables.append(iter(obj)) + iterable_positions.append(i) + + if len(scalars) == size: + yield tuple(objects) + return + + zipper = _zip_equal if strict else zip + for item in zipper(*iterables): + new_item = [None] * size + + for i, elem in zip(iterable_positions, item): + new_item[i] = elem + + for i, elem in zip(scalar_positions, scalars): + new_item[i] = elem + + yield tuple(new_item) + + +def unique_in_window(iterable, n, key=None): + """Yield the items from *iterable* that haven't been seen recently. + *n* is the size of the lookback window. + + >>> iterable = [0, 1, 0, 2, 3, 0] + >>> n = 3 + >>> list(unique_in_window(iterable, n)) + [0, 1, 2, 3, 0] + + The *key* function, if provided, will be used to determine uniqueness: + + >>> list(unique_in_window('abAcda', 3, key=lambda x: x.lower())) + ['a', 'b', 'c', 'd', 'a'] + + The items in *iterable* must be hashable. + + """ + if n <= 0: + raise ValueError('n must be greater than 0') + + window = deque(maxlen=n) + uniques = set() + use_key = key is not None + + for item in iterable: + k = key(item) if use_key else item + if k in uniques: + continue + + if len(uniques) == n: + uniques.discard(window[0]) + + uniques.add(k) + window.append(k) + + yield item + + +def duplicates_everseen(iterable, key=None): + """Yield duplicate elements after their first appearance. + + >>> list(duplicates_everseen('mississippi')) + ['s', 'i', 's', 's', 'i', 'p', 'i'] + >>> list(duplicates_everseen('AaaBbbCccAaa', str.lower)) + ['a', 'a', 'b', 'b', 'c', 'c', 'A', 'a', 'a'] + + This function is analagous to :func:`unique_everseen` and is subject to + the same performance considerations. + + """ + seen_set = set() + seen_list = [] + use_key = key is not None + + for element in iterable: + k = key(element) if use_key else element + try: + if k not in seen_set: + seen_set.add(k) + else: + yield element + except TypeError: + if k not in seen_list: + seen_list.append(k) + else: + yield element + + +def duplicates_justseen(iterable, key=None): + """Yields serially-duplicate elements after their first appearance. + + >>> list(duplicates_justseen('mississippi')) + ['s', 's', 'p'] + >>> list(duplicates_justseen('AaaBbbCccAaa', str.lower)) + ['a', 'a', 'b', 'b', 'c', 'c', 'a', 'a'] + + This function is analagous to :func:`unique_justseen`. + + """ + return flatten( + map( + lambda group_tuple: islice_extended(group_tuple[1])[1:], + groupby(iterable, key), + ) + ) + + +def minmax(iterable_or_value, *others, key=None, default=_marker): + """Returns both the smallest and largest items in an iterable + or the largest of two or more arguments. + + >>> minmax([3, 1, 5]) + (1, 5) + + >>> minmax(4, 2, 6) + (2, 6) + + If a *key* function is provided, it will be used to transform the input + items for comparison. + + >>> minmax([5, 30], key=str) # '30' sorts before '5' + (30, 5) + + If a *default* value is provided, it will be returned if there are no + input items. + + >>> minmax([], default=(0, 0)) + (0, 0) + + Otherwise ``ValueError`` is raised. + + This function is based on the + `recipe `__ by + Raymond Hettinger and takes care to minimize the number of comparisons + performed. + """ + iterable = (iterable_or_value, *others) if others else iterable_or_value + + it = iter(iterable) + + try: + lo = hi = next(it) + except StopIteration as e: + if default is _marker: + raise ValueError( + '`minmax()` argument is an empty iterable. ' + 'Provide a `default` value to suppress this error.' + ) from e + return default + + # Different branches depending on the presence of key. This saves a lot + # of unimportant copies which would slow the "key=None" branch + # significantly down. + if key is None: + for x, y in zip_longest(it, it, fillvalue=lo): + if y < x: + x, y = y, x + if x < lo: + lo = x + if hi < y: + hi = y + + else: + lo_key = hi_key = key(lo) + + for x, y in zip_longest(it, it, fillvalue=lo): + x_key, y_key = key(x), key(y) + + if y_key < x_key: + x, y, x_key, y_key = y, x, y_key, x_key + if x_key < lo_key: + lo, lo_key = x, x_key + if hi_key < y_key: + hi, hi_key = y, y_key + + return lo, hi + + +def constrained_batches( + iterable, max_size, max_count=None, get_len=len, strict=True +): + """Yield batches of items from *iterable* with a combined size limited by + *max_size*. + + >>> iterable = [b'12345', b'123', b'12345678', b'1', b'1', b'12', b'1'] + >>> list(constrained_batches(iterable, 10)) + [(b'12345', b'123'), (b'12345678', b'1', b'1'), (b'12', b'1')] + + If a *max_count* is supplied, the number of items per batch is also + limited: + + >>> iterable = [b'12345', b'123', b'12345678', b'1', b'1', b'12', b'1'] + >>> list(constrained_batches(iterable, 10, max_count = 2)) + [(b'12345', b'123'), (b'12345678', b'1'), (b'1', b'12'), (b'1',)] + + If a *get_len* function is supplied, use that instead of :func:`len` to + determine item size. + + If *strict* is ``True``, raise ``ValueError`` if any single item is bigger + than *max_size*. Otherwise, allow single items to exceed *max_size*. + """ + if max_size <= 0: + raise ValueError('maximum size must be greater than zero') + + batch = [] + batch_size = 0 + batch_count = 0 + for item in iterable: + item_len = get_len(item) + if strict and item_len > max_size: + raise ValueError('item size exceeds maximum size') + + reached_count = batch_count == max_count + reached_size = item_len + batch_size > max_size + if batch_count and (reached_size or reached_count): + yield tuple(batch) + batch.clear() + batch_size = 0 + batch_count = 0 + + batch.append(item) + batch_size += item_len + batch_count += 1 + + if batch: + yield tuple(batch) + + +def gray_product(*iterables): + """Like :func:`itertools.product`, but return tuples in an order such + that only one element in the generated tuple changes from one iteration + to the next. + + >>> list(gray_product('AB','CD')) + [('A', 'C'), ('B', 'C'), ('B', 'D'), ('A', 'D')] + + This function consumes all of the input iterables before producing output. + If any of the input iterables have fewer than two items, ``ValueError`` + is raised. + + For information on the algorithm, see + `this section `__ + of Donald Knuth's *The Art of Computer Programming*. + """ + all_iterables = tuple(tuple(x) for x in iterables) + iterable_count = len(all_iterables) + for iterable in all_iterables: + if len(iterable) < 2: + raise ValueError("each iterable must have two or more items") + + # This is based on "Algorithm H" from section 7.2.1.1, page 20. + # a holds the indexes of the source iterables for the n-tuple to be yielded + # f is the array of "focus pointers" + # o is the array of "directions" + a = [0] * iterable_count + f = list(range(iterable_count + 1)) + o = [1] * iterable_count + while True: + yield tuple(all_iterables[i][a[i]] for i in range(iterable_count)) + j = f[0] + f[0] = 0 + if j == iterable_count: + break + a[j] = a[j] + o[j] + if a[j] == 0 or a[j] == len(all_iterables[j]) - 1: + o[j] = -o[j] + f[j] = f[j + 1] + f[j + 1] = j + 1 diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/more.pyi b/uno/lib/python/pkg_resources/_vendor/more_itertools/more.pyi new file mode 100644 index 00000000..75c5232c --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/more.pyi @@ -0,0 +1,666 @@ +"""Stubs for more_itertools.more""" +from __future__ import annotations + +from types import TracebackType +from typing import ( + Any, + Callable, + Container, + ContextManager, + Generic, + Hashable, + Iterable, + Iterator, + overload, + Reversible, + Sequence, + Sized, + Type, + TypeVar, + type_check_only, +) +from typing_extensions import Protocol + +# Type and type variable definitions +_T = TypeVar('_T') +_T1 = TypeVar('_T1') +_T2 = TypeVar('_T2') +_U = TypeVar('_U') +_V = TypeVar('_V') +_W = TypeVar('_W') +_T_co = TypeVar('_T_co', covariant=True) +_GenFn = TypeVar('_GenFn', bound=Callable[..., Iterator[object]]) +_Raisable = BaseException | Type[BaseException] + +@type_check_only +class _SizedIterable(Protocol[_T_co], Sized, Iterable[_T_co]): ... + +@type_check_only +class _SizedReversible(Protocol[_T_co], Sized, Reversible[_T_co]): ... + +@type_check_only +class _SupportsSlicing(Protocol[_T_co]): + def __getitem__(self, __k: slice) -> _T_co: ... + +def chunked( + iterable: Iterable[_T], n: int | None, strict: bool = ... +) -> Iterator[list[_T]]: ... +@overload +def first(iterable: Iterable[_T]) -> _T: ... +@overload +def first(iterable: Iterable[_T], default: _U) -> _T | _U: ... +@overload +def last(iterable: Iterable[_T]) -> _T: ... +@overload +def last(iterable: Iterable[_T], default: _U) -> _T | _U: ... +@overload +def nth_or_last(iterable: Iterable[_T], n: int) -> _T: ... +@overload +def nth_or_last(iterable: Iterable[_T], n: int, default: _U) -> _T | _U: ... + +class peekable(Generic[_T], Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> peekable[_T]: ... + def __bool__(self) -> bool: ... + @overload + def peek(self) -> _T: ... + @overload + def peek(self, default: _U) -> _T | _U: ... + def prepend(self, *items: _T) -> None: ... + def __next__(self) -> _T: ... + @overload + def __getitem__(self, index: int) -> _T: ... + @overload + def __getitem__(self, index: slice) -> list[_T]: ... + +def consumer(func: _GenFn) -> _GenFn: ... +def ilen(iterable: Iterable[object]) -> int: ... +def iterate(func: Callable[[_T], _T], start: _T) -> Iterator[_T]: ... +def with_iter( + context_manager: ContextManager[Iterable[_T]], +) -> Iterator[_T]: ... +def one( + iterable: Iterable[_T], + too_short: _Raisable | None = ..., + too_long: _Raisable | None = ..., +) -> _T: ... +def raise_(exception: _Raisable, *args: Any) -> None: ... +def strictly_n( + iterable: Iterable[_T], + n: int, + too_short: _GenFn | None = ..., + too_long: _GenFn | None = ..., +) -> list[_T]: ... +def distinct_permutations( + iterable: Iterable[_T], r: int | None = ... +) -> Iterator[tuple[_T, ...]]: ... +def intersperse( + e: _U, iterable: Iterable[_T], n: int = ... +) -> Iterator[_T | _U]: ... +def unique_to_each(*iterables: Iterable[_T]) -> list[list[_T]]: ... +@overload +def windowed( + seq: Iterable[_T], n: int, *, step: int = ... +) -> Iterator[tuple[_T | None, ...]]: ... +@overload +def windowed( + seq: Iterable[_T], n: int, fillvalue: _U, step: int = ... +) -> Iterator[tuple[_T | _U, ...]]: ... +def substrings(iterable: Iterable[_T]) -> Iterator[tuple[_T, ...]]: ... +def substrings_indexes( + seq: Sequence[_T], reverse: bool = ... +) -> Iterator[tuple[Sequence[_T], int, int]]: ... + +class bucket(Generic[_T, _U], Container[_U]): + def __init__( + self, + iterable: Iterable[_T], + key: Callable[[_T], _U], + validator: Callable[[object], object] | None = ..., + ) -> None: ... + def __contains__(self, value: object) -> bool: ... + def __iter__(self) -> Iterator[_U]: ... + def __getitem__(self, value: object) -> Iterator[_T]: ... + +def spy( + iterable: Iterable[_T], n: int = ... +) -> tuple[list[_T], Iterator[_T]]: ... +def interleave(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def interleave_longest(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def interleave_evenly( + iterables: list[Iterable[_T]], lengths: list[int] | None = ... +) -> Iterator[_T]: ... +def collapse( + iterable: Iterable[Any], + base_type: type | None = ..., + levels: int | None = ..., +) -> Iterator[Any]: ... +@overload +def side_effect( + func: Callable[[_T], object], + iterable: Iterable[_T], + chunk_size: None = ..., + before: Callable[[], object] | None = ..., + after: Callable[[], object] | None = ..., +) -> Iterator[_T]: ... +@overload +def side_effect( + func: Callable[[list[_T]], object], + iterable: Iterable[_T], + chunk_size: int, + before: Callable[[], object] | None = ..., + after: Callable[[], object] | None = ..., +) -> Iterator[_T]: ... +def sliced( + seq: _SupportsSlicing[_T], n: int, strict: bool = ... +) -> Iterator[_T]: ... +def split_at( + iterable: Iterable[_T], + pred: Callable[[_T], object], + maxsplit: int = ..., + keep_separator: bool = ..., +) -> Iterator[list[_T]]: ... +def split_before( + iterable: Iterable[_T], pred: Callable[[_T], object], maxsplit: int = ... +) -> Iterator[list[_T]]: ... +def split_after( + iterable: Iterable[_T], pred: Callable[[_T], object], maxsplit: int = ... +) -> Iterator[list[_T]]: ... +def split_when( + iterable: Iterable[_T], + pred: Callable[[_T, _T], object], + maxsplit: int = ..., +) -> Iterator[list[_T]]: ... +def split_into( + iterable: Iterable[_T], sizes: Iterable[int | None] +) -> Iterator[list[_T]]: ... +@overload +def padded( + iterable: Iterable[_T], + *, + n: int | None = ..., + next_multiple: bool = ..., +) -> Iterator[_T | None]: ... +@overload +def padded( + iterable: Iterable[_T], + fillvalue: _U, + n: int | None = ..., + next_multiple: bool = ..., +) -> Iterator[_T | _U]: ... +@overload +def repeat_last(iterable: Iterable[_T]) -> Iterator[_T]: ... +@overload +def repeat_last(iterable: Iterable[_T], default: _U) -> Iterator[_T | _U]: ... +def distribute(n: int, iterable: Iterable[_T]) -> list[Iterator[_T]]: ... +@overload +def stagger( + iterable: Iterable[_T], + offsets: _SizedIterable[int] = ..., + longest: bool = ..., +) -> Iterator[tuple[_T | None, ...]]: ... +@overload +def stagger( + iterable: Iterable[_T], + offsets: _SizedIterable[int] = ..., + longest: bool = ..., + fillvalue: _U = ..., +) -> Iterator[tuple[_T | _U, ...]]: ... + +class UnequalIterablesError(ValueError): + def __init__(self, details: tuple[int, int, int] | None = ...) -> None: ... + +@overload +def zip_equal(__iter1: Iterable[_T1]) -> Iterator[tuple[_T1]]: ... +@overload +def zip_equal( + __iter1: Iterable[_T1], __iter2: Iterable[_T2] +) -> Iterator[tuple[_T1, _T2]]: ... +@overload +def zip_equal( + __iter1: Iterable[_T], + __iter2: Iterable[_T], + __iter3: Iterable[_T], + *iterables: Iterable[_T], +) -> Iterator[tuple[_T, ...]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T1], + *, + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: None = None, +) -> Iterator[tuple[_T1 | None]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T1], + __iter2: Iterable[_T2], + *, + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: None = None, +) -> Iterator[tuple[_T1 | None, _T2 | None]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T], + __iter2: Iterable[_T], + __iter3: Iterable[_T], + *iterables: Iterable[_T], + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: None = None, +) -> Iterator[tuple[_T | None, ...]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T1], + *, + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: _U, +) -> Iterator[tuple[_T1 | _U]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T1], + __iter2: Iterable[_T2], + *, + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: _U, +) -> Iterator[tuple[_T1 | _U, _T2 | _U]]: ... +@overload +def zip_offset( + __iter1: Iterable[_T], + __iter2: Iterable[_T], + __iter3: Iterable[_T], + *iterables: Iterable[_T], + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: _U, +) -> Iterator[tuple[_T | _U, ...]]: ... +def sort_together( + iterables: Iterable[Iterable[_T]], + key_list: Iterable[int] = ..., + key: Callable[..., Any] | None = ..., + reverse: bool = ..., +) -> list[tuple[_T, ...]]: ... +def unzip(iterable: Iterable[Sequence[_T]]) -> tuple[Iterator[_T], ...]: ... +def divide(n: int, iterable: Iterable[_T]) -> list[Iterator[_T]]: ... +def always_iterable( + obj: object, + base_type: type | tuple[type | tuple[Any, ...], ...] | None = ..., +) -> Iterator[Any]: ... +def adjacent( + predicate: Callable[[_T], bool], + iterable: Iterable[_T], + distance: int = ..., +) -> Iterator[tuple[bool, _T]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: None = None, + valuefunc: None = None, + reducefunc: None = None, +) -> Iterator[tuple[_T, Iterator[_T]]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None, + reducefunc: None, +) -> Iterator[tuple[_U, Iterator[_T]]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: None, + valuefunc: Callable[[_T], _V], + reducefunc: None, +) -> Iterable[tuple[_T, Iterable[_V]]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: None, +) -> Iterable[tuple[_U, Iterator[_V]]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: None, + valuefunc: None, + reducefunc: Callable[[Iterator[_T]], _W], +) -> Iterable[tuple[_T, _W]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None, + reducefunc: Callable[[Iterator[_T]], _W], +) -> Iterable[tuple[_U, _W]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: None, + valuefunc: Callable[[_T], _V], + reducefunc: Callable[[Iterable[_V]], _W], +) -> Iterable[tuple[_T, _W]]: ... +@overload +def groupby_transform( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: Callable[[Iterable[_V]], _W], +) -> Iterable[tuple[_U, _W]]: ... + +class numeric_range(Generic[_T, _U], Sequence[_T], Hashable, Reversible[_T]): + @overload + def __init__(self, __stop: _T) -> None: ... + @overload + def __init__(self, __start: _T, __stop: _T) -> None: ... + @overload + def __init__(self, __start: _T, __stop: _T, __step: _U) -> None: ... + def __bool__(self) -> bool: ... + def __contains__(self, elem: object) -> bool: ... + def __eq__(self, other: object) -> bool: ... + @overload + def __getitem__(self, key: int) -> _T: ... + @overload + def __getitem__(self, key: slice) -> numeric_range[_T, _U]: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[_T]: ... + def __len__(self) -> int: ... + def __reduce__( + self, + ) -> tuple[Type[numeric_range[_T, _U]], tuple[_T, _T, _U]]: ... + def __repr__(self) -> str: ... + def __reversed__(self) -> Iterator[_T]: ... + def count(self, value: _T) -> int: ... + def index(self, value: _T) -> int: ... # type: ignore + +def count_cycle( + iterable: Iterable[_T], n: int | None = ... +) -> Iterable[tuple[int, _T]]: ... +def mark_ends( + iterable: Iterable[_T], +) -> Iterable[tuple[bool, bool, _T]]: ... +def locate( + iterable: Iterable[object], + pred: Callable[..., Any] = ..., + window_size: int | None = ..., +) -> Iterator[int]: ... +def lstrip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... +def rstrip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... +def strip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... + +class islice_extended(Generic[_T], Iterator[_T]): + def __init__(self, iterable: Iterable[_T], *args: int | None) -> None: ... + def __iter__(self) -> islice_extended[_T]: ... + def __next__(self) -> _T: ... + def __getitem__(self, index: slice) -> islice_extended[_T]: ... + +def always_reversible(iterable: Iterable[_T]) -> Iterator[_T]: ... +def consecutive_groups( + iterable: Iterable[_T], ordering: Callable[[_T], int] = ... +) -> Iterator[Iterator[_T]]: ... +@overload +def difference( + iterable: Iterable[_T], + func: Callable[[_T, _T], _U] = ..., + *, + initial: None = ..., +) -> Iterator[_T | _U]: ... +@overload +def difference( + iterable: Iterable[_T], func: Callable[[_T, _T], _U] = ..., *, initial: _U +) -> Iterator[_U]: ... + +class SequenceView(Generic[_T], Sequence[_T]): + def __init__(self, target: Sequence[_T]) -> None: ... + @overload + def __getitem__(self, index: int) -> _T: ... + @overload + def __getitem__(self, index: slice) -> Sequence[_T]: ... + def __len__(self) -> int: ... + +class seekable(Generic[_T], Iterator[_T]): + def __init__( + self, iterable: Iterable[_T], maxlen: int | None = ... + ) -> None: ... + def __iter__(self) -> seekable[_T]: ... + def __next__(self) -> _T: ... + def __bool__(self) -> bool: ... + @overload + def peek(self) -> _T: ... + @overload + def peek(self, default: _U) -> _T | _U: ... + def elements(self) -> SequenceView[_T]: ... + def seek(self, index: int) -> None: ... + +class run_length: + @staticmethod + def encode(iterable: Iterable[_T]) -> Iterator[tuple[_T, int]]: ... + @staticmethod + def decode(iterable: Iterable[tuple[_T, int]]) -> Iterator[_T]: ... + +def exactly_n( + iterable: Iterable[_T], n: int, predicate: Callable[[_T], object] = ... +) -> bool: ... +def circular_shifts(iterable: Iterable[_T]) -> list[tuple[_T, ...]]: ... +def make_decorator( + wrapping_func: Callable[..., _U], result_index: int = ... +) -> Callable[..., Callable[[Callable[..., Any]], Callable[..., _U]]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None = ..., + reducefunc: None = ..., +) -> dict[_U, list[_T]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: None = ..., +) -> dict[_U, list[_V]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None = ..., + reducefunc: Callable[[list[_T]], _W] = ..., +) -> dict[_U, _W]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: Callable[[list[_V]], _W], +) -> dict[_U, _W]: ... +def rlocate( + iterable: Iterable[_T], + pred: Callable[..., object] = ..., + window_size: int | None = ..., +) -> Iterator[int]: ... +def replace( + iterable: Iterable[_T], + pred: Callable[..., object], + substitutes: Iterable[_U], + count: int | None = ..., + window_size: int = ..., +) -> Iterator[_T | _U]: ... +def partitions(iterable: Iterable[_T]) -> Iterator[list[list[_T]]]: ... +def set_partitions( + iterable: Iterable[_T], k: int | None = ... +) -> Iterator[list[list[_T]]]: ... + +class time_limited(Generic[_T], Iterator[_T]): + def __init__( + self, limit_seconds: float, iterable: Iterable[_T] + ) -> None: ... + def __iter__(self) -> islice_extended[_T]: ... + def __next__(self) -> _T: ... + +@overload +def only( + iterable: Iterable[_T], *, too_long: _Raisable | None = ... +) -> _T | None: ... +@overload +def only( + iterable: Iterable[_T], default: _U, too_long: _Raisable | None = ... +) -> _T | _U: ... +def ichunked(iterable: Iterable[_T], n: int) -> Iterator[Iterator[_T]]: ... +def distinct_combinations( + iterable: Iterable[_T], r: int +) -> Iterator[tuple[_T, ...]]: ... +def filter_except( + validator: Callable[[Any], object], + iterable: Iterable[_T], + *exceptions: Type[BaseException], +) -> Iterator[_T]: ... +def map_except( + function: Callable[[Any], _U], + iterable: Iterable[_T], + *exceptions: Type[BaseException], +) -> Iterator[_U]: ... +def map_if( + iterable: Iterable[Any], + pred: Callable[[Any], bool], + func: Callable[[Any], Any], + func_else: Callable[[Any], Any] | None = ..., +) -> Iterator[Any]: ... +def sample( + iterable: Iterable[_T], + k: int, + weights: Iterable[float] | None = ..., +) -> list[_T]: ... +def is_sorted( + iterable: Iterable[_T], + key: Callable[[_T], _U] | None = ..., + reverse: bool = False, + strict: bool = False, +) -> bool: ... + +class AbortThread(BaseException): + pass + +class callback_iter(Generic[_T], Iterator[_T]): + def __init__( + self, + func: Callable[..., Any], + callback_kwd: str = ..., + wait_seconds: float = ..., + ) -> None: ... + def __enter__(self) -> callback_iter[_T]: ... + def __exit__( + self, + exc_type: Type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> bool | None: ... + def __iter__(self) -> callback_iter[_T]: ... + def __next__(self) -> _T: ... + def _reader(self) -> Iterator[_T]: ... + @property + def done(self) -> bool: ... + @property + def result(self) -> Any: ... + +def windowed_complete( + iterable: Iterable[_T], n: int +) -> Iterator[tuple[_T, ...]]: ... +def all_unique( + iterable: Iterable[_T], key: Callable[[_T], _U] | None = ... +) -> bool: ... +def nth_product(index: int, *args: Iterable[_T]) -> tuple[_T, ...]: ... +def nth_permutation( + iterable: Iterable[_T], r: int, index: int +) -> tuple[_T, ...]: ... +def value_chain(*args: _T | Iterable[_T]) -> Iterable[_T]: ... +def product_index(element: Iterable[_T], *args: Iterable[_T]) -> int: ... +def combination_index( + element: Iterable[_T], iterable: Iterable[_T] +) -> int: ... +def permutation_index( + element: Iterable[_T], iterable: Iterable[_T] +) -> int: ... +def repeat_each(iterable: Iterable[_T], n: int = ...) -> Iterator[_T]: ... + +class countable(Generic[_T], Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> countable[_T]: ... + def __next__(self) -> _T: ... + +def chunked_even(iterable: Iterable[_T], n: int) -> Iterator[list[_T]]: ... +def zip_broadcast( + *objects: _T | Iterable[_T], + scalar_types: type | tuple[type | tuple[Any, ...], ...] | None = ..., + strict: bool = ..., +) -> Iterable[tuple[_T, ...]]: ... +def unique_in_window( + iterable: Iterable[_T], n: int, key: Callable[[_T], _U] | None = ... +) -> Iterator[_T]: ... +def duplicates_everseen( + iterable: Iterable[_T], key: Callable[[_T], _U] | None = ... +) -> Iterator[_T]: ... +def duplicates_justseen( + iterable: Iterable[_T], key: Callable[[_T], _U] | None = ... +) -> Iterator[_T]: ... + +class _SupportsLessThan(Protocol): + def __lt__(self, __other: Any) -> bool: ... + +_SupportsLessThanT = TypeVar("_SupportsLessThanT", bound=_SupportsLessThan) + +@overload +def minmax( + iterable_or_value: Iterable[_SupportsLessThanT], *, key: None = None +) -> tuple[_SupportsLessThanT, _SupportsLessThanT]: ... +@overload +def minmax( + iterable_or_value: Iterable[_T], *, key: Callable[[_T], _SupportsLessThan] +) -> tuple[_T, _T]: ... +@overload +def minmax( + iterable_or_value: Iterable[_SupportsLessThanT], + *, + key: None = None, + default: _U, +) -> _U | tuple[_SupportsLessThanT, _SupportsLessThanT]: ... +@overload +def minmax( + iterable_or_value: Iterable[_T], + *, + key: Callable[[_T], _SupportsLessThan], + default: _U, +) -> _U | tuple[_T, _T]: ... +@overload +def minmax( + iterable_or_value: _SupportsLessThanT, + __other: _SupportsLessThanT, + *others: _SupportsLessThanT, +) -> tuple[_SupportsLessThanT, _SupportsLessThanT]: ... +@overload +def minmax( + iterable_or_value: _T, + __other: _T, + *others: _T, + key: Callable[[_T], _SupportsLessThan], +) -> tuple[_T, _T]: ... +def longest_common_prefix( + iterables: Iterable[Iterable[_T]], +) -> Iterator[_T]: ... +def iequals(*iterables: Iterable[object]) -> bool: ... +def constrained_batches( + iterable: Iterable[object], + max_size: int, + max_count: int | None = ..., + get_len: Callable[[_T], object] = ..., + strict: bool = ..., +) -> Iterator[tuple[_T]]: ... +def gray_product(*iterables: Iterable[_T]) -> Iterator[tuple[_T, ...]]: ... diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/py.typed b/uno/lib/python/pkg_resources/_vendor/more_itertools/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.py b/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.py new file mode 100644 index 00000000..3facc2e3 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.py @@ -0,0 +1,930 @@ +"""Imported from the recipes section of the itertools documentation. + +All functions taken from the recipes section of the itertools library docs +[1]_. +Some backward-compatible usability improvements have been made. + +.. [1] http://docs.python.org/library/itertools.html#recipes + +""" +import math +import operator +import warnings + +from collections import deque +from collections.abc import Sized +from functools import reduce +from itertools import ( + chain, + combinations, + compress, + count, + cycle, + groupby, + islice, + product, + repeat, + starmap, + tee, + zip_longest, +) +from random import randrange, sample, choice +from sys import hexversion + +__all__ = [ + 'all_equal', + 'batched', + 'before_and_after', + 'consume', + 'convolve', + 'dotproduct', + 'first_true', + 'factor', + 'flatten', + 'grouper', + 'iter_except', + 'iter_index', + 'matmul', + 'ncycles', + 'nth', + 'nth_combination', + 'padnone', + 'pad_none', + 'pairwise', + 'partition', + 'polynomial_from_roots', + 'powerset', + 'prepend', + 'quantify', + 'random_combination_with_replacement', + 'random_combination', + 'random_permutation', + 'random_product', + 'repeatfunc', + 'roundrobin', + 'sieve', + 'sliding_window', + 'subslices', + 'tabulate', + 'tail', + 'take', + 'transpose', + 'triplewise', + 'unique_everseen', + 'unique_justseen', +] + +_marker = object() + + +def take(n, iterable): + """Return first *n* items of the iterable as a list. + + >>> take(3, range(10)) + [0, 1, 2] + + If there are fewer than *n* items in the iterable, all of them are + returned. + + >>> take(10, range(3)) + [0, 1, 2] + + """ + return list(islice(iterable, n)) + + +def tabulate(function, start=0): + """Return an iterator over the results of ``func(start)``, + ``func(start + 1)``, ``func(start + 2)``... + + *func* should be a function that accepts one integer argument. + + If *start* is not specified it defaults to 0. It will be incremented each + time the iterator is advanced. + + >>> square = lambda x: x ** 2 + >>> iterator = tabulate(square, -3) + >>> take(4, iterator) + [9, 4, 1, 0] + + """ + return map(function, count(start)) + + +def tail(n, iterable): + """Return an iterator over the last *n* items of *iterable*. + + >>> t = tail(3, 'ABCDEFG') + >>> list(t) + ['E', 'F', 'G'] + + """ + # If the given iterable has a length, then we can use islice to get its + # final elements. Note that if the iterable is not actually Iterable, + # either islice or deque will throw a TypeError. This is why we don't + # check if it is Iterable. + if isinstance(iterable, Sized): + yield from islice(iterable, max(0, len(iterable) - n), None) + else: + yield from iter(deque(iterable, maxlen=n)) + + +def consume(iterator, n=None): + """Advance *iterable* by *n* steps. If *n* is ``None``, consume it + entirely. + + Efficiently exhausts an iterator without returning values. Defaults to + consuming the whole iterator, but an optional second argument may be + provided to limit consumption. + + >>> i = (x for x in range(10)) + >>> next(i) + 0 + >>> consume(i, 3) + >>> next(i) + 4 + >>> consume(i) + >>> next(i) + Traceback (most recent call last): + File "", line 1, in + StopIteration + + If the iterator has fewer items remaining than the provided limit, the + whole iterator will be consumed. + + >>> i = (x for x in range(3)) + >>> consume(i, 5) + >>> next(i) + Traceback (most recent call last): + File "", line 1, in + StopIteration + + """ + # Use functions that consume iterators at C speed. + if n is None: + # feed the entire iterator into a zero-length deque + deque(iterator, maxlen=0) + else: + # advance to the empty slice starting at position n + next(islice(iterator, n, n), None) + + +def nth(iterable, n, default=None): + """Returns the nth item or a default value. + + >>> l = range(10) + >>> nth(l, 3) + 3 + >>> nth(l, 20, "zebra") + 'zebra' + + """ + return next(islice(iterable, n, None), default) + + +def all_equal(iterable): + """ + Returns ``True`` if all the elements are equal to each other. + + >>> all_equal('aaaa') + True + >>> all_equal('aaab') + False + + """ + g = groupby(iterable) + return next(g, True) and not next(g, False) + + +def quantify(iterable, pred=bool): + """Return the how many times the predicate is true. + + >>> quantify([True, False, True]) + 2 + + """ + return sum(map(pred, iterable)) + + +def pad_none(iterable): + """Returns the sequence of elements and then returns ``None`` indefinitely. + + >>> take(5, pad_none(range(3))) + [0, 1, 2, None, None] + + Useful for emulating the behavior of the built-in :func:`map` function. + + See also :func:`padded`. + + """ + return chain(iterable, repeat(None)) + + +padnone = pad_none + + +def ncycles(iterable, n): + """Returns the sequence elements *n* times + + >>> list(ncycles(["a", "b"], 3)) + ['a', 'b', 'a', 'b', 'a', 'b'] + + """ + return chain.from_iterable(repeat(tuple(iterable), n)) + + +def dotproduct(vec1, vec2): + """Returns the dot product of the two iterables. + + >>> dotproduct([10, 10], [20, 20]) + 400 + + """ + return sum(map(operator.mul, vec1, vec2)) + + +def flatten(listOfLists): + """Return an iterator flattening one level of nesting in a list of lists. + + >>> list(flatten([[0, 1], [2, 3]])) + [0, 1, 2, 3] + + See also :func:`collapse`, which can flatten multiple levels of nesting. + + """ + return chain.from_iterable(listOfLists) + + +def repeatfunc(func, times=None, *args): + """Call *func* with *args* repeatedly, returning an iterable over the + results. + + If *times* is specified, the iterable will terminate after that many + repetitions: + + >>> from operator import add + >>> times = 4 + >>> args = 3, 5 + >>> list(repeatfunc(add, times, *args)) + [8, 8, 8, 8] + + If *times* is ``None`` the iterable will not terminate: + + >>> from random import randrange + >>> times = None + >>> args = 1, 11 + >>> take(6, repeatfunc(randrange, times, *args)) # doctest:+SKIP + [2, 4, 8, 1, 8, 4] + + """ + if times is None: + return starmap(func, repeat(args)) + return starmap(func, repeat(args, times)) + + +def _pairwise(iterable): + """Returns an iterator of paired items, overlapping, from the original + + >>> take(4, pairwise(count())) + [(0, 1), (1, 2), (2, 3), (3, 4)] + + On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`. + + """ + a, b = tee(iterable) + next(b, None) + yield from zip(a, b) + + +try: + from itertools import pairwise as itertools_pairwise +except ImportError: + pairwise = _pairwise +else: + + def pairwise(iterable): + yield from itertools_pairwise(iterable) + + pairwise.__doc__ = _pairwise.__doc__ + + +class UnequalIterablesError(ValueError): + def __init__(self, details=None): + msg = 'Iterables have different lengths' + if details is not None: + msg += (': index 0 has length {}; index {} has length {}').format( + *details + ) + + super().__init__(msg) + + +def _zip_equal_generator(iterables): + for combo in zip_longest(*iterables, fillvalue=_marker): + for val in combo: + if val is _marker: + raise UnequalIterablesError() + yield combo + + +def _zip_equal(*iterables): + # Check whether the iterables are all the same size. + try: + first_size = len(iterables[0]) + for i, it in enumerate(iterables[1:], 1): + size = len(it) + if size != first_size: + break + else: + # If we didn't break out, we can use the built-in zip. + return zip(*iterables) + + # If we did break out, there was a mismatch. + raise UnequalIterablesError(details=(first_size, i, size)) + # If any one of the iterables didn't have a length, start reading + # them until one runs out. + except TypeError: + return _zip_equal_generator(iterables) + + +def grouper(iterable, n, incomplete='fill', fillvalue=None): + """Group elements from *iterable* into fixed-length groups of length *n*. + + >>> list(grouper('ABCDEF', 3)) + [('A', 'B', 'C'), ('D', 'E', 'F')] + + The keyword arguments *incomplete* and *fillvalue* control what happens for + iterables whose length is not a multiple of *n*. + + When *incomplete* is `'fill'`, the last group will contain instances of + *fillvalue*. + + >>> list(grouper('ABCDEFG', 3, incomplete='fill', fillvalue='x')) + [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')] + + When *incomplete* is `'ignore'`, the last group will not be emitted. + + >>> list(grouper('ABCDEFG', 3, incomplete='ignore', fillvalue='x')) + [('A', 'B', 'C'), ('D', 'E', 'F')] + + When *incomplete* is `'strict'`, a subclass of `ValueError` will be raised. + + >>> it = grouper('ABCDEFG', 3, incomplete='strict') + >>> list(it) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + UnequalIterablesError + + """ + args = [iter(iterable)] * n + if incomplete == 'fill': + return zip_longest(*args, fillvalue=fillvalue) + if incomplete == 'strict': + return _zip_equal(*args) + if incomplete == 'ignore': + return zip(*args) + else: + raise ValueError('Expected fill, strict, or ignore') + + +def roundrobin(*iterables): + """Yields an item from each iterable, alternating between them. + + >>> list(roundrobin('ABC', 'D', 'EF')) + ['A', 'D', 'E', 'B', 'F', 'C'] + + This function produces the same output as :func:`interleave_longest`, but + may perform better for some inputs (in particular when the number of + iterables is small). + + """ + # Recipe credited to George Sakkis + pending = len(iterables) + nexts = cycle(iter(it).__next__ for it in iterables) + while pending: + try: + for next in nexts: + yield next() + except StopIteration: + pending -= 1 + nexts = cycle(islice(nexts, pending)) + + +def partition(pred, iterable): + """ + Returns a 2-tuple of iterables derived from the input iterable. + The first yields the items that have ``pred(item) == False``. + The second yields the items that have ``pred(item) == True``. + + >>> is_odd = lambda x: x % 2 != 0 + >>> iterable = range(10) + >>> even_items, odd_items = partition(is_odd, iterable) + >>> list(even_items), list(odd_items) + ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) + + If *pred* is None, :func:`bool` is used. + + >>> iterable = [0, 1, False, True, '', ' '] + >>> false_items, true_items = partition(None, iterable) + >>> list(false_items), list(true_items) + ([0, False, ''], [1, True, ' ']) + + """ + if pred is None: + pred = bool + + evaluations = ((pred(x), x) for x in iterable) + t1, t2 = tee(evaluations) + return ( + (x for (cond, x) in t1 if not cond), + (x for (cond, x) in t2 if cond), + ) + + +def powerset(iterable): + """Yields all possible subsets of the iterable. + + >>> list(powerset([1, 2, 3])) + [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] + + :func:`powerset` will operate on iterables that aren't :class:`set` + instances, so repeated elements in the input will produce repeated elements + in the output. Use :func:`unique_everseen` on the input to avoid generating + duplicates: + + >>> seq = [1, 1, 0] + >>> list(powerset(seq)) + [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)] + >>> from more_itertools import unique_everseen + >>> list(powerset(unique_everseen(seq))) + [(), (1,), (0,), (1, 0)] + + """ + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) + + +def unique_everseen(iterable, key=None): + """ + Yield unique elements, preserving order. + + >>> list(unique_everseen('AAAABBBCCDAABBB')) + ['A', 'B', 'C', 'D'] + >>> list(unique_everseen('ABBCcAD', str.lower)) + ['A', 'B', 'C', 'D'] + + Sequences with a mix of hashable and unhashable items can be used. + The function will be slower (i.e., `O(n^2)`) for unhashable items. + + Remember that ``list`` objects are unhashable - you can use the *key* + parameter to transform the list to a tuple (which is hashable) to + avoid a slowdown. + + >>> iterable = ([1, 2], [2, 3], [1, 2]) + >>> list(unique_everseen(iterable)) # Slow + [[1, 2], [2, 3]] + >>> list(unique_everseen(iterable, key=tuple)) # Faster + [[1, 2], [2, 3]] + + Similary, you may want to convert unhashable ``set`` objects with + ``key=frozenset``. For ``dict`` objects, + ``key=lambda x: frozenset(x.items())`` can be used. + + """ + seenset = set() + seenset_add = seenset.add + seenlist = [] + seenlist_add = seenlist.append + use_key = key is not None + + for element in iterable: + k = key(element) if use_key else element + try: + if k not in seenset: + seenset_add(k) + yield element + except TypeError: + if k not in seenlist: + seenlist_add(k) + yield element + + +def unique_justseen(iterable, key=None): + """Yields elements in order, ignoring serial duplicates + + >>> list(unique_justseen('AAAABBBCCDAABBB')) + ['A', 'B', 'C', 'D', 'A', 'B'] + >>> list(unique_justseen('ABBCcAD', str.lower)) + ['A', 'B', 'C', 'A', 'D'] + + """ + return map(next, map(operator.itemgetter(1), groupby(iterable, key))) + + +def iter_except(func, exception, first=None): + """Yields results from a function repeatedly until an exception is raised. + + Converts a call-until-exception interface to an iterator interface. + Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel + to end the loop. + + >>> l = [0, 1, 2] + >>> list(iter_except(l.pop, IndexError)) + [2, 1, 0] + + Multiple exceptions can be specified as a stopping condition: + + >>> l = [1, 2, 3, '...', 4, 5, 6] + >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError))) + [7, 6, 5] + >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError))) + [4, 3, 2] + >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError))) + [] + + """ + try: + if first is not None: + yield first() + while 1: + yield func() + except exception: + pass + + +def first_true(iterable, default=None, pred=None): + """ + Returns the first true value in the iterable. + + If no true value is found, returns *default* + + If *pred* is not None, returns the first item for which + ``pred(item) == True`` . + + >>> first_true(range(10)) + 1 + >>> first_true(range(10), pred=lambda x: x > 5) + 6 + >>> first_true(range(10), default='missing', pred=lambda x: x > 9) + 'missing' + + """ + return next(filter(pred, iterable), default) + + +def random_product(*args, repeat=1): + """Draw an item at random from each of the input iterables. + + >>> random_product('abc', range(4), 'XYZ') # doctest:+SKIP + ('c', 3, 'Z') + + If *repeat* is provided as a keyword argument, that many items will be + drawn from each iterable. + + >>> random_product('abcd', range(4), repeat=2) # doctest:+SKIP + ('a', 2, 'd', 3) + + This equivalent to taking a random selection from + ``itertools.product(*args, **kwarg)``. + + """ + pools = [tuple(pool) for pool in args] * repeat + return tuple(choice(pool) for pool in pools) + + +def random_permutation(iterable, r=None): + """Return a random *r* length permutation of the elements in *iterable*. + + If *r* is not specified or is ``None``, then *r* defaults to the length of + *iterable*. + + >>> random_permutation(range(5)) # doctest:+SKIP + (3, 4, 0, 1, 2) + + This equivalent to taking a random selection from + ``itertools.permutations(iterable, r)``. + + """ + pool = tuple(iterable) + r = len(pool) if r is None else r + return tuple(sample(pool, r)) + + +def random_combination(iterable, r): + """Return a random *r* length subsequence of the elements in *iterable*. + + >>> random_combination(range(5), 3) # doctest:+SKIP + (2, 3, 4) + + This equivalent to taking a random selection from + ``itertools.combinations(iterable, r)``. + + """ + pool = tuple(iterable) + n = len(pool) + indices = sorted(sample(range(n), r)) + return tuple(pool[i] for i in indices) + + +def random_combination_with_replacement(iterable, r): + """Return a random *r* length subsequence of elements in *iterable*, + allowing individual elements to be repeated. + + >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP + (0, 0, 1, 2, 2) + + This equivalent to taking a random selection from + ``itertools.combinations_with_replacement(iterable, r)``. + + """ + pool = tuple(iterable) + n = len(pool) + indices = sorted(randrange(n) for i in range(r)) + return tuple(pool[i] for i in indices) + + +def nth_combination(iterable, r, index): + """Equivalent to ``list(combinations(iterable, r))[index]``. + + The subsequences of *iterable* that are of length *r* can be ordered + lexicographically. :func:`nth_combination` computes the subsequence at + sort position *index* directly, without computing the previous + subsequences. + + >>> nth_combination(range(5), 3, 5) + (0, 3, 4) + + ``ValueError`` will be raised If *r* is negative or greater than the length + of *iterable*. + ``IndexError`` will be raised if the given *index* is invalid. + """ + pool = tuple(iterable) + n = len(pool) + if (r < 0) or (r > n): + raise ValueError + + c = 1 + k = min(r, n - r) + for i in range(1, k + 1): + c = c * (n - k + i) // i + + if index < 0: + index += c + + if (index < 0) or (index >= c): + raise IndexError + + result = [] + while r: + c, n, r = c * r // n, n - 1, r - 1 + while index >= c: + index -= c + c, n = c * (n - r) // n, n - 1 + result.append(pool[-1 - n]) + + return tuple(result) + + +def prepend(value, iterator): + """Yield *value*, followed by the elements in *iterator*. + + >>> value = '0' + >>> iterator = ['1', '2', '3'] + >>> list(prepend(value, iterator)) + ['0', '1', '2', '3'] + + To prepend multiple values, see :func:`itertools.chain` + or :func:`value_chain`. + + """ + return chain([value], iterator) + + +def convolve(signal, kernel): + """Convolve the iterable *signal* with the iterable *kernel*. + + >>> signal = (1, 2, 3, 4, 5) + >>> kernel = [3, 2, 1] + >>> list(convolve(signal, kernel)) + [3, 8, 14, 20, 26, 14, 5] + + Note: the input arguments are not interchangeable, as the *kernel* + is immediately consumed and stored. + + """ + kernel = tuple(kernel)[::-1] + n = len(kernel) + window = deque([0], maxlen=n) * n + for x in chain(signal, repeat(0, n - 1)): + window.append(x) + yield sum(map(operator.mul, kernel, window)) + + +def before_and_after(predicate, it): + """A variant of :func:`takewhile` that allows complete access to the + remainder of the iterator. + + >>> it = iter('ABCdEfGhI') + >>> all_upper, remainder = before_and_after(str.isupper, it) + >>> ''.join(all_upper) + 'ABC' + >>> ''.join(remainder) # takewhile() would lose the 'd' + 'dEfGhI' + + Note that the first iterator must be fully consumed before the second + iterator can generate valid results. + """ + it = iter(it) + transition = [] + + def true_iterator(): + for elem in it: + if predicate(elem): + yield elem + else: + transition.append(elem) + return + + # Note: this is different from itertools recipes to allow nesting + # before_and_after remainders into before_and_after again. See tests + # for an example. + remainder_iterator = chain(transition, it) + + return true_iterator(), remainder_iterator + + +def triplewise(iterable): + """Return overlapping triplets from *iterable*. + + >>> list(triplewise('ABCDE')) + [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E')] + + """ + for (a, _), (b, c) in pairwise(pairwise(iterable)): + yield a, b, c + + +def sliding_window(iterable, n): + """Return a sliding window of width *n* over *iterable*. + + >>> list(sliding_window(range(6), 4)) + [(0, 1, 2, 3), (1, 2, 3, 4), (2, 3, 4, 5)] + + If *iterable* has fewer than *n* items, then nothing is yielded: + + >>> list(sliding_window(range(3), 4)) + [] + + For a variant with more features, see :func:`windowed`. + """ + it = iter(iterable) + window = deque(islice(it, n), maxlen=n) + if len(window) == n: + yield tuple(window) + for x in it: + window.append(x) + yield tuple(window) + + +def subslices(iterable): + """Return all contiguous non-empty subslices of *iterable*. + + >>> list(subslices('ABC')) + [['A'], ['A', 'B'], ['A', 'B', 'C'], ['B'], ['B', 'C'], ['C']] + + This is similar to :func:`substrings`, but emits items in a different + order. + """ + seq = list(iterable) + slices = starmap(slice, combinations(range(len(seq) + 1), 2)) + return map(operator.getitem, repeat(seq), slices) + + +def polynomial_from_roots(roots): + """Compute a polynomial's coefficients from its roots. + + >>> roots = [5, -4, 3] # (x - 5) * (x + 4) * (x - 3) + >>> polynomial_from_roots(roots) # x^3 - 4 * x^2 - 17 * x + 60 + [1, -4, -17, 60] + """ + # Use math.prod for Python 3.8+, + prod = getattr(math, 'prod', lambda x: reduce(operator.mul, x, 1)) + roots = list(map(operator.neg, roots)) + return [ + sum(map(prod, combinations(roots, k))) for k in range(len(roots) + 1) + ] + + +def iter_index(iterable, value, start=0): + """Yield the index of each place in *iterable* that *value* occurs, + beginning with index *start*. + + See :func:`locate` for a more general means of finding the indexes + associated with particular values. + + >>> list(iter_index('AABCADEAF', 'A')) + [0, 1, 4, 7] + """ + try: + seq_index = iterable.index + except AttributeError: + # Slow path for general iterables + it = islice(iterable, start, None) + for i, element in enumerate(it, start): + if element is value or element == value: + yield i + else: + # Fast path for sequences + i = start - 1 + try: + while True: + i = seq_index(value, i + 1) + yield i + except ValueError: + pass + + +def sieve(n): + """Yield the primes less than n. + + >>> list(sieve(30)) + [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] + """ + isqrt = getattr(math, 'isqrt', lambda x: int(math.sqrt(x))) + data = bytearray((0, 1)) * (n // 2) + data[:3] = 0, 0, 0 + limit = isqrt(n) + 1 + for p in compress(range(limit), data): + data[p * p : n : p + p] = bytes(len(range(p * p, n, p + p))) + data[2] = 1 + return iter_index(data, 1) if n > 2 else iter([]) + + +def batched(iterable, n): + """Batch data into lists of length *n*. The last batch may be shorter. + + >>> list(batched('ABCDEFG', 3)) + [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']] + + This recipe is from the ``itertools`` docs. This library also provides + :func:`chunked`, which has a different implementation. + """ + if hexversion >= 0x30C00A0: # Python 3.12.0a0 + warnings.warn( + ( + 'batched will be removed in a future version of ' + 'more-itertools. Use the standard library ' + 'itertools.batched function instead' + ), + DeprecationWarning, + ) + + it = iter(iterable) + while True: + batch = list(islice(it, n)) + if not batch: + break + yield batch + + +def transpose(it): + """Swap the rows and columns of the input. + + >>> list(transpose([(1, 2, 3), (11, 22, 33)])) + [(1, 11), (2, 22), (3, 33)] + + The caller should ensure that the dimensions of the input are compatible. + """ + # TODO: when 3.9 goes end-of-life, add stric=True to this. + return zip(*it) + + +def matmul(m1, m2): + """Multiply two matrices. + >>> list(matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)])) + [[49, 80], [41, 60]] + + The caller should ensure that the dimensions of the input matrices are + compatible with each other. + """ + n = len(m2[0]) + return batched(starmap(dotproduct, product(m1, transpose(m2))), n) + + +def factor(n): + """Yield the prime factors of n. + >>> list(factor(360)) + [2, 2, 2, 3, 3, 5] + """ + isqrt = getattr(math, 'isqrt', lambda x: int(math.sqrt(x))) + for prime in sieve(isqrt(n) + 1): + while True: + quotient, remainder = divmod(n, prime) + if remainder: + break + yield prime + n = quotient + if n == 1: + return + if n >= 2: + yield n diff --git a/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.pyi b/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.pyi new file mode 100644 index 00000000..0267ed56 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/more_itertools/recipes.pyi @@ -0,0 +1,119 @@ +"""Stubs for more_itertools.recipes""" +from __future__ import annotations + +from typing import ( + Any, + Callable, + Iterable, + Iterator, + overload, + Sequence, + Type, + TypeVar, +) + +# Type and type variable definitions +_T = TypeVar('_T') +_U = TypeVar('_U') + +def take(n: int, iterable: Iterable[_T]) -> list[_T]: ... +def tabulate( + function: Callable[[int], _T], start: int = ... +) -> Iterator[_T]: ... +def tail(n: int, iterable: Iterable[_T]) -> Iterator[_T]: ... +def consume(iterator: Iterable[object], n: int | None = ...) -> None: ... +@overload +def nth(iterable: Iterable[_T], n: int) -> _T | None: ... +@overload +def nth(iterable: Iterable[_T], n: int, default: _U) -> _T | _U: ... +def all_equal(iterable: Iterable[object]) -> bool: ... +def quantify( + iterable: Iterable[_T], pred: Callable[[_T], bool] = ... +) -> int: ... +def pad_none(iterable: Iterable[_T]) -> Iterator[_T | None]: ... +def padnone(iterable: Iterable[_T]) -> Iterator[_T | None]: ... +def ncycles(iterable: Iterable[_T], n: int) -> Iterator[_T]: ... +def dotproduct(vec1: Iterable[object], vec2: Iterable[object]) -> object: ... +def flatten(listOfLists: Iterable[Iterable[_T]]) -> Iterator[_T]: ... +def repeatfunc( + func: Callable[..., _U], times: int | None = ..., *args: Any +) -> Iterator[_U]: ... +def pairwise(iterable: Iterable[_T]) -> Iterator[tuple[_T, _T]]: ... +def grouper( + iterable: Iterable[_T], + n: int, + incomplete: str = ..., + fillvalue: _U = ..., +) -> Iterator[tuple[_T | _U, ...]]: ... +def roundrobin(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def partition( + pred: Callable[[_T], object] | None, iterable: Iterable[_T] +) -> tuple[Iterator[_T], Iterator[_T]]: ... +def powerset(iterable: Iterable[_T]) -> Iterator[tuple[_T, ...]]: ... +def unique_everseen( + iterable: Iterable[_T], key: Callable[[_T], _U] | None = ... +) -> Iterator[_T]: ... +def unique_justseen( + iterable: Iterable[_T], key: Callable[[_T], object] | None = ... +) -> Iterator[_T]: ... +@overload +def iter_except( + func: Callable[[], _T], + exception: Type[BaseException] | tuple[Type[BaseException], ...], + first: None = ..., +) -> Iterator[_T]: ... +@overload +def iter_except( + func: Callable[[], _T], + exception: Type[BaseException] | tuple[Type[BaseException], ...], + first: Callable[[], _U], +) -> Iterator[_T | _U]: ... +@overload +def first_true( + iterable: Iterable[_T], *, pred: Callable[[_T], object] | None = ... +) -> _T | None: ... +@overload +def first_true( + iterable: Iterable[_T], + default: _U, + pred: Callable[[_T], object] | None = ..., +) -> _T | _U: ... +def random_product( + *args: Iterable[_T], repeat: int = ... +) -> tuple[_T, ...]: ... +def random_permutation( + iterable: Iterable[_T], r: int | None = ... +) -> tuple[_T, ...]: ... +def random_combination(iterable: Iterable[_T], r: int) -> tuple[_T, ...]: ... +def random_combination_with_replacement( + iterable: Iterable[_T], r: int +) -> tuple[_T, ...]: ... +def nth_combination( + iterable: Iterable[_T], r: int, index: int +) -> tuple[_T, ...]: ... +def prepend(value: _T, iterator: Iterable[_U]) -> Iterator[_T | _U]: ... +def convolve(signal: Iterable[_T], kernel: Iterable[_T]) -> Iterator[_T]: ... +def before_and_after( + predicate: Callable[[_T], bool], it: Iterable[_T] +) -> tuple[Iterator[_T], Iterator[_T]]: ... +def triplewise(iterable: Iterable[_T]) -> Iterator[tuple[_T, _T, _T]]: ... +def sliding_window( + iterable: Iterable[_T], n: int +) -> Iterator[tuple[_T, ...]]: ... +def subslices(iterable: Iterable[_T]) -> Iterator[list[_T]]: ... +def polynomial_from_roots(roots: Sequence[int]) -> list[int]: ... +def iter_index( + iterable: Iterable[object], + value: Any, + start: int | None = ..., +) -> Iterator[int]: ... +def sieve(n: int) -> Iterator[int]: ... +def batched( + iterable: Iterable[_T], + n: int, +) -> Iterator[list[_T]]: ... +def transpose( + it: Iterable[Iterable[_T]], +) -> tuple[Iterator[_T], ...]: ... +def matmul(m1: Sequence[_T], m2: Sequence[_T]) -> Iterator[list[_T]]: ... +def factor(n: int) -> Iterator[int]: ... diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/__about__.py b/uno/lib/python/pkg_resources/_vendor/packaging/__about__.py deleted file mode 100644 index c359122f..00000000 --- a/uno/lib/python/pkg_resources/_vendor/packaging/__about__.py +++ /dev/null @@ -1,26 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -__all__ = [ - "__title__", - "__summary__", - "__uri__", - "__version__", - "__author__", - "__email__", - "__license__", - "__copyright__", -] - -__title__ = "packaging" -__summary__ = "Core utilities for Python packages" -__uri__ = "https://github.com/pypa/packaging" - -__version__ = "21.2" - -__author__ = "Donald Stufft and individual contributors" -__email__ = "donald@stufft.io" - -__license__ = "BSD-2-Clause or Apache-2.0" -__copyright__ = "2014-2019 %s" % __author__ diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/__init__.py b/uno/lib/python/pkg_resources/_vendor/packaging/__init__.py index 3c50c5dc..13cadc7f 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/__init__.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/__init__.py @@ -2,24 +2,14 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -from .__about__ import ( - __author__, - __copyright__, - __email__, - __license__, - __summary__, - __title__, - __uri__, - __version__, -) +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" -__all__ = [ - "__title__", - "__summary__", - "__uri__", - "__version__", - "__author__", - "__email__", - "__license__", - "__copyright__", -] +__version__ = "23.1" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD-2-Clause or Apache-2.0" +__copyright__ = "2014-2019 %s" % __author__ diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_elffile.py b/uno/lib/python/pkg_resources/_vendor/packaging/_elffile.py new file mode 100644 index 00000000..6fb19b30 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_elffile.py @@ -0,0 +1,108 @@ +""" +ELF file parser. + +This provides a class ``ELFFile`` that parses an ELF executable in a similar +interface to ``ZipFile``. Only the read interface is implemented. + +Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca +ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html +""" + +import enum +import os +import struct +from typing import IO, Optional, Tuple + + +class ELFInvalid(ValueError): + pass + + +class EIClass(enum.IntEnum): + C32 = 1 + C64 = 2 + + +class EIData(enum.IntEnum): + Lsb = 1 + Msb = 2 + + +class EMachine(enum.IntEnum): + I386 = 3 + S390 = 22 + Arm = 40 + X8664 = 62 + AArc64 = 183 + + +class ELFFile: + """ + Representation of an ELF executable. + """ + + def __init__(self, f: IO[bytes]) -> None: + self._f = f + + try: + ident = self._read("16B") + except struct.error: + raise ELFInvalid("unable to parse identification") + magic = bytes(ident[:4]) + if magic != b"\x7fELF": + raise ELFInvalid(f"invalid magic: {magic!r}") + + self.capacity = ident[4] # Format for program header (bitness). + self.encoding = ident[5] # Data structure encoding (endianness). + + try: + # e_fmt: Format for program header. + # p_fmt: Format for section header. + # p_idx: Indexes to find p_type, p_offset, and p_filesz. + e_fmt, self._p_fmt, self._p_idx = { + (1, 1): ("HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. + (2, 1): ("HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. + }[(self.capacity, self.encoding)] + except KeyError: + raise ELFInvalid( + f"unrecognized capacity ({self.capacity}) or " + f"encoding ({self.encoding})" + ) + + try: + ( + _, + self.machine, # Architecture type. + _, + _, + self._e_phoff, # Offset of program header. + _, + self.flags, # Processor-specific flags. + _, + self._e_phentsize, # Size of section. + self._e_phnum, # Number of sections. + ) = self._read(e_fmt) + except struct.error as e: + raise ELFInvalid("unable to parse machine and section information") from e + + def _read(self, fmt: str) -> Tuple[int, ...]: + return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) + + @property + def interpreter(self) -> Optional[str]: + """ + The path recorded in the ``PT_INTERP`` section header. + """ + for index in range(self._e_phnum): + self._f.seek(self._e_phoff + self._e_phentsize * index) + try: + data = self._read(self._p_fmt) + except struct.error: + continue + if data[self._p_idx[0]] != 3: # Not PT_INTERP. + continue + self._f.seek(data[self._p_idx[1]]) + return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") + return None diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_manylinux.py b/uno/lib/python/pkg_resources/_vendor/packaging/_manylinux.py index 4c379aa6..449c655b 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/_manylinux.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_manylinux.py @@ -1,121 +1,60 @@ import collections +import contextlib import functools import os import re -import struct import sys import warnings -from typing import IO, Dict, Iterator, NamedTuple, Optional, Tuple - - -# Python does not provide platform information at sufficient granularity to -# identify the architecture of the running executable in some cases, so we -# determine it dynamically by reading the information from the running -# process. This only applies on Linux, which uses the ELF format. -class _ELFFileHeader: - # https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header - class _InvalidELFFileHeader(ValueError): - """ - An invalid ELF file header was found. - """ - - ELF_MAGIC_NUMBER = 0x7F454C46 - ELFCLASS32 = 1 - ELFCLASS64 = 2 - ELFDATA2LSB = 1 - ELFDATA2MSB = 2 - EM_386 = 3 - EM_S390 = 22 - EM_ARM = 40 - EM_X86_64 = 62 - EF_ARM_ABIMASK = 0xFF000000 - EF_ARM_ABI_VER5 = 0x05000000 - EF_ARM_ABI_FLOAT_HARD = 0x00000400 - - def __init__(self, file: IO[bytes]) -> None: - def unpack(fmt: str) -> int: - try: - data = file.read(struct.calcsize(fmt)) - result: Tuple[int, ...] = struct.unpack(fmt, data) - except struct.error: - raise _ELFFileHeader._InvalidELFFileHeader() - return result[0] - - self.e_ident_magic = unpack(">I") - if self.e_ident_magic != self.ELF_MAGIC_NUMBER: - raise _ELFFileHeader._InvalidELFFileHeader() - self.e_ident_class = unpack("B") - if self.e_ident_class not in {self.ELFCLASS32, self.ELFCLASS64}: - raise _ELFFileHeader._InvalidELFFileHeader() - self.e_ident_data = unpack("B") - if self.e_ident_data not in {self.ELFDATA2LSB, self.ELFDATA2MSB}: - raise _ELFFileHeader._InvalidELFFileHeader() - self.e_ident_version = unpack("B") - self.e_ident_osabi = unpack("B") - self.e_ident_abiversion = unpack("B") - self.e_ident_pad = file.read(7) - format_h = "H" - format_i = "I" - format_q = "Q" - format_p = format_i if self.e_ident_class == self.ELFCLASS32 else format_q - self.e_type = unpack(format_h) - self.e_machine = unpack(format_h) - self.e_version = unpack(format_i) - self.e_entry = unpack(format_p) - self.e_phoff = unpack(format_p) - self.e_shoff = unpack(format_p) - self.e_flags = unpack(format_i) - self.e_ehsize = unpack(format_h) - self.e_phentsize = unpack(format_h) - self.e_phnum = unpack(format_h) - self.e_shentsize = unpack(format_h) - self.e_shnum = unpack(format_h) - self.e_shstrndx = unpack(format_h) - - -def _get_elf_header() -> Optional[_ELFFileHeader]: +from typing import Dict, Generator, Iterator, NamedTuple, Optional, Tuple + +from ._elffile import EIClass, EIData, ELFFile, EMachine + +EF_ARM_ABIMASK = 0xFF000000 +EF_ARM_ABI_VER5 = 0x05000000 +EF_ARM_ABI_FLOAT_HARD = 0x00000400 + + +# `os.PathLike` not a generic type until Python 3.9, so sticking with `str` +# as the type for `path` until then. +@contextlib.contextmanager +def _parse_elf(path: str) -> Generator[Optional[ELFFile], None, None]: try: - with open(sys.executable, "rb") as f: - elf_header = _ELFFileHeader(f) - except (OSError, TypeError, _ELFFileHeader._InvalidELFFileHeader): - return None - return elf_header + with open(path, "rb") as f: + yield ELFFile(f) + except (OSError, TypeError, ValueError): + yield None -def _is_linux_armhf() -> bool: +def _is_linux_armhf(executable: str) -> bool: # hard-float ABI can be detected from the ELF header of the running # process # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf - elf_header = _get_elf_header() - if elf_header is None: - return False - result = elf_header.e_ident_class == elf_header.ELFCLASS32 - result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB - result &= elf_header.e_machine == elf_header.EM_ARM - result &= ( - elf_header.e_flags & elf_header.EF_ARM_ABIMASK - ) == elf_header.EF_ARM_ABI_VER5 - result &= ( - elf_header.e_flags & elf_header.EF_ARM_ABI_FLOAT_HARD - ) == elf_header.EF_ARM_ABI_FLOAT_HARD - return result - - -def _is_linux_i686() -> bool: - elf_header = _get_elf_header() - if elf_header is None: - return False - result = elf_header.e_ident_class == elf_header.ELFCLASS32 - result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB - result &= elf_header.e_machine == elf_header.EM_386 - return result + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.Arm + and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5 + and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD + ) + + +def _is_linux_i686(executable: str) -> bool: + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.I386 + ) -def _have_compatible_abi(arch: str) -> bool: +def _have_compatible_abi(executable: str, arch: str) -> bool: if arch == "armv7l": - return _is_linux_armhf() + return _is_linux_armhf(executable) if arch == "i686": - return _is_linux_i686() + return _is_linux_i686(executable) return arch in {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x"} @@ -141,10 +80,10 @@ def _glibc_version_string_confstr() -> Optional[str]: # platform module. # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183 try: - # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17". - version_string = os.confstr("CS_GNU_LIBC_VERSION") + # Should be a string like "glibc 2.17". + version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION") assert version_string is not None - _, version = version_string.split() + _, version = version_string.rsplit() except (AssertionError, AttributeError, OSError, ValueError): # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... return None @@ -211,8 +150,8 @@ def _parse_glibc_version(version_str: str) -> Tuple[int, int]: m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) if not m: warnings.warn( - "Expected glibc version with 2 components major.minor," - " got: %s" % version_str, + f"Expected glibc version with 2 components major.minor," + f" got: {version_str}", RuntimeWarning, ) return -1, -1 @@ -265,7 +204,7 @@ def _is_compatible(name: str, arch: str, version: _GLibCVersion) -> bool: def platform_tags(linux: str, arch: str) -> Iterator[str]: - if not _have_compatible_abi(arch): + if not _have_compatible_abi(sys.executable, arch): return # Oldest glibc to be supported regardless of architecture is (2, 17). too_old_glibc2 = _GLibCVersion(2, 16) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_musllinux.py b/uno/lib/python/pkg_resources/_vendor/packaging/_musllinux.py index 85450faf..706ba600 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/_musllinux.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_musllinux.py @@ -4,68 +4,13 @@ linked against musl, and what musl version is used. """ -import contextlib import functools -import operator -import os import re -import struct import subprocess import sys -from typing import IO, Iterator, NamedTuple, Optional, Tuple +from typing import Iterator, NamedTuple, Optional - -def _read_unpacked(f: IO[bytes], fmt: str) -> Tuple[int, ...]: - return struct.unpack(fmt, f.read(struct.calcsize(fmt))) - - -def _parse_ld_musl_from_elf(f: IO[bytes]) -> Optional[str]: - """Detect musl libc location by parsing the Python executable. - - Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca - ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html - """ - f.seek(0) - try: - ident = _read_unpacked(f, "16B") - except struct.error: - return None - if ident[:4] != tuple(b"\x7fELF"): # Invalid magic, not ELF. - return None - f.seek(struct.calcsize("HHI"), 1) # Skip file type, machine, and version. - - try: - # e_fmt: Format for program header. - # p_fmt: Format for section header. - # p_idx: Indexes to find p_type, p_offset, and p_filesz. - e_fmt, p_fmt, p_idx = { - 1: ("IIIIHHH", "IIIIIIII", (0, 1, 4)), # 32-bit. - 2: ("QQQIHHH", "IIQQQQQQ", (0, 2, 5)), # 64-bit. - }[ident[4]] - except KeyError: - return None - else: - p_get = operator.itemgetter(*p_idx) - - # Find the interpreter section and return its content. - try: - _, e_phoff, _, _, _, e_phentsize, e_phnum = _read_unpacked(f, e_fmt) - except struct.error: - return None - for i in range(e_phnum + 1): - f.seek(e_phoff + e_phentsize * i) - try: - p_type, p_offset, p_filesz = p_get(_read_unpacked(f, p_fmt)) - except struct.error: - return None - if p_type != 3: # Not PT_INTERP. - continue - f.seek(p_offset) - interpreter = os.fsdecode(f.read(p_filesz)).strip("\0") - if "musl" not in interpreter: - return None - return interpreter - return None +from ._elffile import ELFFile class _MuslVersion(NamedTuple): @@ -95,13 +40,12 @@ def _get_musl_version(executable: str) -> Optional[_MuslVersion]: Version 1.2.2 Dynamic Program Loader """ - with contextlib.ExitStack() as stack: - try: - f = stack.enter_context(open(executable, "rb")) - except IOError: - return None - ld = _parse_ld_musl_from_elf(f) - if not ld: + try: + with open(executable, "rb") as f: + ld = ELFFile(f).interpreter + except (OSError, TypeError, ValueError): + return None + if ld is None or "musl" not in ld: return None proc = subprocess.run([ld], stderr=subprocess.PIPE, universal_newlines=True) return _parse_musl_version(proc.stderr) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_parser.py b/uno/lib/python/pkg_resources/_vendor/packaging/_parser.py new file mode 100644 index 00000000..5a18b758 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_parser.py @@ -0,0 +1,353 @@ +"""Handwritten parser of dependency specifiers. + +The docstring for each __parse_* function contains ENBF-inspired grammar representing +the implementation. +""" + +import ast +from typing import Any, List, NamedTuple, Optional, Tuple, Union + +from ._tokenizer import DEFAULT_RULES, Tokenizer + + +class Node: + def __init__(self, value: str) -> None: + self.value = value + + def __str__(self) -> str: + return self.value + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}('{self}')>" + + def serialize(self) -> str: + raise NotImplementedError + + +class Variable(Node): + def serialize(self) -> str: + return str(self) + + +class Value(Node): + def serialize(self) -> str: + return f'"{self}"' + + +class Op(Node): + def serialize(self) -> str: + return str(self) + + +MarkerVar = Union[Variable, Value] +MarkerItem = Tuple[MarkerVar, Op, MarkerVar] +# MarkerAtom = Union[MarkerItem, List["MarkerAtom"]] +# MarkerList = List[Union["MarkerList", MarkerAtom, str]] +# mypy does not support recursive type definition +# https://github.com/python/mypy/issues/731 +MarkerAtom = Any +MarkerList = List[Any] + + +class ParsedRequirement(NamedTuple): + name: str + url: str + extras: List[str] + specifier: str + marker: Optional[MarkerList] + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for dependency specifier +# -------------------------------------------------------------------------------------- +def parse_requirement(source: str) -> ParsedRequirement: + return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement: + """ + requirement = WS? IDENTIFIER WS? extras WS? requirement_details + """ + tokenizer.consume("WS") + + name_token = tokenizer.expect( + "IDENTIFIER", expected="package name at the start of dependency specifier" + ) + name = name_token.text + tokenizer.consume("WS") + + extras = _parse_extras(tokenizer) + tokenizer.consume("WS") + + url, specifier, marker = _parse_requirement_details(tokenizer) + tokenizer.expect("END", expected="end of dependency specifier") + + return ParsedRequirement(name, url, extras, specifier, marker) + + +def _parse_requirement_details( + tokenizer: Tokenizer, +) -> Tuple[str, str, Optional[MarkerList]]: + """ + requirement_details = AT URL (WS requirement_marker?)? + | specifier WS? (requirement_marker)? + """ + + specifier = "" + url = "" + marker = None + + if tokenizer.check("AT"): + tokenizer.read() + tokenizer.consume("WS") + + url_start = tokenizer.position + url = tokenizer.expect("URL", expected="URL after @").text + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + tokenizer.expect("WS", expected="whitespace after URL") + + # The input might end after whitespace. + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, span_start=url_start, after="URL and whitespace" + ) + else: + specifier_start = tokenizer.position + specifier = _parse_specifier(tokenizer) + tokenizer.consume("WS") + + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, + span_start=specifier_start, + after=( + "version specifier" + if specifier + else "name and no valid version specifier" + ), + ) + + return (url, specifier, marker) + + +def _parse_requirement_marker( + tokenizer: Tokenizer, *, span_start: int, after: str +) -> MarkerList: + """ + requirement_marker = SEMICOLON marker WS? + """ + + if not tokenizer.check("SEMICOLON"): + tokenizer.raise_syntax_error( + f"Expected end or semicolon (after {after})", + span_start=span_start, + ) + tokenizer.read() + + marker = _parse_marker(tokenizer) + tokenizer.consume("WS") + + return marker + + +def _parse_extras(tokenizer: Tokenizer) -> List[str]: + """ + extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)? + """ + if not tokenizer.check("LEFT_BRACKET", peek=True): + return [] + + with tokenizer.enclosing_tokens( + "LEFT_BRACKET", + "RIGHT_BRACKET", + around="extras", + ): + tokenizer.consume("WS") + extras = _parse_extras_list(tokenizer) + tokenizer.consume("WS") + + return extras + + +def _parse_extras_list(tokenizer: Tokenizer) -> List[str]: + """ + extras_list = identifier (wsp* ',' wsp* identifier)* + """ + extras: List[str] = [] + + if not tokenizer.check("IDENTIFIER"): + return extras + + extras.append(tokenizer.read().text) + + while True: + tokenizer.consume("WS") + if tokenizer.check("IDENTIFIER", peek=True): + tokenizer.raise_syntax_error("Expected comma between extra names") + elif not tokenizer.check("COMMA"): + break + + tokenizer.read() + tokenizer.consume("WS") + + extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma") + extras.append(extra_token.text) + + return extras + + +def _parse_specifier(tokenizer: Tokenizer) -> str: + """ + specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS + | WS? version_many WS? + """ + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="version specifier", + ): + tokenizer.consume("WS") + parsed_specifiers = _parse_version_many(tokenizer) + tokenizer.consume("WS") + + return parsed_specifiers + + +def _parse_version_many(tokenizer: Tokenizer) -> str: + """ + version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)? + """ + parsed_specifiers = "" + while tokenizer.check("SPECIFIER"): + span_start = tokenizer.position + parsed_specifiers += tokenizer.read().text + if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True): + tokenizer.raise_syntax_error( + ".* suffix can only be used with `==` or `!=` operators", + span_start=span_start, + span_end=tokenizer.position + 1, + ) + if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True): + tokenizer.raise_syntax_error( + "Local version label can only be used with `==` or `!=` operators", + span_start=span_start, + span_end=tokenizer.position, + ) + tokenizer.consume("WS") + if not tokenizer.check("COMMA"): + break + parsed_specifiers += tokenizer.read().text + tokenizer.consume("WS") + + return parsed_specifiers + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for marker expression +# -------------------------------------------------------------------------------------- +def parse_marker(source: str) -> MarkerList: + return _parse_marker(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_marker(tokenizer: Tokenizer) -> MarkerList: + """ + marker = marker_atom (BOOLOP marker_atom)+ + """ + expression = [_parse_marker_atom(tokenizer)] + while tokenizer.check("BOOLOP"): + token = tokenizer.read() + expr_right = _parse_marker_atom(tokenizer) + expression.extend((token.text, expr_right)) + return expression + + +def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom: + """ + marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS? + | WS? marker_item WS? + """ + + tokenizer.consume("WS") + if tokenizer.check("LEFT_PARENTHESIS", peek=True): + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="marker expression", + ): + tokenizer.consume("WS") + marker: MarkerAtom = _parse_marker(tokenizer) + tokenizer.consume("WS") + else: + marker = _parse_marker_item(tokenizer) + tokenizer.consume("WS") + return marker + + +def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem: + """ + marker_item = WS? marker_var WS? marker_op WS? marker_var WS? + """ + tokenizer.consume("WS") + marker_var_left = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + marker_op = _parse_marker_op(tokenizer) + tokenizer.consume("WS") + marker_var_right = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + return (marker_var_left, marker_op, marker_var_right) + + +def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar: + """ + marker_var = VARIABLE | QUOTED_STRING + """ + if tokenizer.check("VARIABLE"): + return process_env_var(tokenizer.read().text.replace(".", "_")) + elif tokenizer.check("QUOTED_STRING"): + return process_python_str(tokenizer.read().text) + else: + tokenizer.raise_syntax_error( + message="Expected a marker variable or quoted string" + ) + + +def process_env_var(env_var: str) -> Variable: + if ( + env_var == "platform_python_implementation" + or env_var == "python_implementation" + ): + return Variable("platform_python_implementation") + else: + return Variable(env_var) + + +def process_python_str(python_str: str) -> Value: + value = ast.literal_eval(python_str) + return Value(str(value)) + + +def _parse_marker_op(tokenizer: Tokenizer) -> Op: + """ + marker_op = IN | NOT IN | OP + """ + if tokenizer.check("IN"): + tokenizer.read() + return Op("in") + elif tokenizer.check("NOT"): + tokenizer.read() + tokenizer.expect("WS", expected="whitespace after 'not'") + tokenizer.expect("IN", expected="'in' after 'not'") + return Op("not in") + elif tokenizer.check("OP"): + return Op(tokenizer.read().text) + else: + return tokenizer.raise_syntax_error( + "Expected marker operator, one of " + "<=, <, !=, ==, >=, >, ~=, ===, in, not in" + ) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_structures.py b/uno/lib/python/pkg_resources/_vendor/packaging/_structures.py index 95154975..90a6465f 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/_structures.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_structures.py @@ -19,9 +19,6 @@ def __le__(self, other: object) -> bool: def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) - def __ne__(self, other: object) -> bool: - return not isinstance(other, self.__class__) - def __gt__(self, other: object) -> bool: return True @@ -51,9 +48,6 @@ def __le__(self, other: object) -> bool: def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) - def __ne__(self, other: object) -> bool: - return not isinstance(other, self.__class__) - def __gt__(self, other: object) -> bool: return False diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/_tokenizer.py b/uno/lib/python/pkg_resources/_vendor/packaging/_tokenizer.py new file mode 100644 index 00000000..dd0d648d --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/packaging/_tokenizer.py @@ -0,0 +1,192 @@ +import contextlib +import re +from dataclasses import dataclass +from typing import Dict, Iterator, NoReturn, Optional, Tuple, Union + +from .specifiers import Specifier + + +@dataclass +class Token: + name: str + text: str + position: int + + +class ParserSyntaxError(Exception): + """The provided source text could not be parsed correctly.""" + + def __init__( + self, + message: str, + *, + source: str, + span: Tuple[int, int], + ) -> None: + self.span = span + self.message = message + self.source = source + + super().__init__() + + def __str__(self) -> str: + marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^" + return "\n ".join([self.message, self.source, marker]) + + +DEFAULT_RULES: "Dict[str, Union[str, re.Pattern[str]]]" = { + "LEFT_PARENTHESIS": r"\(", + "RIGHT_PARENTHESIS": r"\)", + "LEFT_BRACKET": r"\[", + "RIGHT_BRACKET": r"\]", + "SEMICOLON": r";", + "COMMA": r",", + "QUOTED_STRING": re.compile( + r""" + ( + ('[^']*') + | + ("[^"]*") + ) + """, + re.VERBOSE, + ), + "OP": r"(===|==|~=|!=|<=|>=|<|>)", + "BOOLOP": r"\b(or|and)\b", + "IN": r"\bin\b", + "NOT": r"\bnot\b", + "VARIABLE": re.compile( + r""" + \b( + python_version + |python_full_version + |os[._]name + |sys[._]platform + |platform_(release|system) + |platform[._](version|machine|python_implementation) + |python_implementation + |implementation_(name|version) + |extra + )\b + """, + re.VERBOSE, + ), + "SPECIFIER": re.compile( + Specifier._operator_regex_str + Specifier._version_regex_str, + re.VERBOSE | re.IGNORECASE, + ), + "AT": r"\@", + "URL": r"[^ \t]+", + "IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b", + "VERSION_PREFIX_TRAIL": r"\.\*", + "VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*", + "WS": r"[ \t]+", + "END": r"$", +} + + +class Tokenizer: + """Context-sensitive token parsing. + + Provides methods to examine the input stream to check whether the next token + matches. + """ + + def __init__( + self, + source: str, + *, + rules: "Dict[str, Union[str, re.Pattern[str]]]", + ) -> None: + self.source = source + self.rules: Dict[str, re.Pattern[str]] = { + name: re.compile(pattern) for name, pattern in rules.items() + } + self.next_token: Optional[Token] = None + self.position = 0 + + def consume(self, name: str) -> None: + """Move beyond provided token name, if at current position.""" + if self.check(name): + self.read() + + def check(self, name: str, *, peek: bool = False) -> bool: + """Check whether the next token has the provided name. + + By default, if the check succeeds, the token *must* be read before + another check. If `peek` is set to `True`, the token is not loaded and + would need to be checked again. + """ + assert ( + self.next_token is None + ), f"Cannot check for {name!r}, already have {self.next_token!r}" + assert name in self.rules, f"Unknown token name: {name!r}" + + expression = self.rules[name] + + match = expression.match(self.source, self.position) + if match is None: + return False + if not peek: + self.next_token = Token(name, match[0], self.position) + return True + + def expect(self, name: str, *, expected: str) -> Token: + """Expect a certain token name next, failing with a syntax error otherwise. + + The token is *not* read. + """ + if not self.check(name): + raise self.raise_syntax_error(f"Expected {expected}") + return self.read() + + def read(self) -> Token: + """Consume the next token and return it.""" + token = self.next_token + assert token is not None + + self.position += len(token.text) + self.next_token = None + + return token + + def raise_syntax_error( + self, + message: str, + *, + span_start: Optional[int] = None, + span_end: Optional[int] = None, + ) -> NoReturn: + """Raise ParserSyntaxError at the given position.""" + span = ( + self.position if span_start is None else span_start, + self.position if span_end is None else span_end, + ) + raise ParserSyntaxError( + message, + source=self.source, + span=span, + ) + + @contextlib.contextmanager + def enclosing_tokens( + self, open_token: str, close_token: str, *, around: str + ) -> Iterator[None]: + if self.check(open_token): + open_position = self.position + self.read() + else: + open_position = None + + yield + + if open_position is None: + return + + if not self.check(close_token): + self.raise_syntax_error( + f"Expected matching {close_token} for {open_token}, after {around}", + span_start=open_position, + ) + + self.read() diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/markers.py b/uno/lib/python/pkg_resources/_vendor/packaging/markers.py index 18769b09..8b98fca7 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/markers.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/markers.py @@ -8,19 +8,17 @@ import sys from typing import Any, Callable, Dict, List, Optional, Tuple, Union -from pkg_resources.extern.pyparsing import ( # noqa: N817 - Forward, - Group, - Literal as L, - ParseException, - ParseResults, - QuotedString, - ZeroOrMore, - stringEnd, - stringStart, +from ._parser import ( + MarkerAtom, + MarkerList, + Op, + Value, + Variable, + parse_marker as _parse_marker, ) - +from ._tokenizer import ParserSyntaxError from .specifiers import InvalidSpecifier, Specifier +from .utils import canonicalize_name __all__ = [ "InvalidMarker", @@ -52,101 +50,24 @@ class UndefinedEnvironmentName(ValueError): """ -class Node: - def __init__(self, value: Any) -> None: - self.value = value - - def __str__(self) -> str: - return str(self.value) - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}('{self}')>" - - def serialize(self) -> str: - raise NotImplementedError - - -class Variable(Node): - def serialize(self) -> str: - return str(self) - - -class Value(Node): - def serialize(self) -> str: - return f'"{self}"' - - -class Op(Node): - def serialize(self) -> str: - return str(self) - - -VARIABLE = ( - L("implementation_version") - | L("platform_python_implementation") - | L("implementation_name") - | L("python_full_version") - | L("platform_release") - | L("platform_version") - | L("platform_machine") - | L("platform_system") - | L("python_version") - | L("sys_platform") - | L("os_name") - | L("os.name") # PEP-345 - | L("sys.platform") # PEP-345 - | L("platform.version") # PEP-345 - | L("platform.machine") # PEP-345 - | L("platform.python_implementation") # PEP-345 - | L("python_implementation") # undocumented setuptools legacy - | L("extra") # PEP-508 -) -ALIASES = { - "os.name": "os_name", - "sys.platform": "sys_platform", - "platform.version": "platform_version", - "platform.machine": "platform_machine", - "platform.python_implementation": "platform_python_implementation", - "python_implementation": "platform_python_implementation", -} -VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) - -VERSION_CMP = ( - L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<") -) - -MARKER_OP = VERSION_CMP | L("not in") | L("in") -MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) - -MARKER_VALUE = QuotedString("'") | QuotedString('"') -MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) - -BOOLOP = L("and") | L("or") - -MARKER_VAR = VARIABLE | MARKER_VALUE - -MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) -MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) - -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() - -MARKER_EXPR = Forward() -MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) -MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) - -MARKER = stringStart + MARKER_EXPR + stringEnd - - -def _coerce_parse_result(results: Union[ParseResults, List[Any]]) -> List[Any]: - if isinstance(results, ParseResults): - return [_coerce_parse_result(i) for i in results] - else: - return results +def _normalize_extra_values(results: Any) -> Any: + """ + Normalize extra values. + """ + if isinstance(results[0], tuple): + lhs, op, rhs = results[0] + if isinstance(lhs, Variable) and lhs.value == "extra": + normalized_extra = canonicalize_name(rhs.value) + rhs = Value(normalized_extra) + elif isinstance(rhs, Variable) and rhs.value == "extra": + normalized_extra = canonicalize_name(lhs.value) + lhs = Value(normalized_extra) + results[0] = lhs, op, rhs + return results def _format_marker( - marker: Union[List[str], Tuple[Node, ...], str], first: Optional[bool] = True + marker: Union[List[str], MarkerAtom, str], first: Optional[bool] = True ) -> str: assert isinstance(marker, (list, tuple, str)) @@ -192,7 +113,7 @@ def _eval_op(lhs: str, op: Op, rhs: str) -> bool: except InvalidSpecifier: pass else: - return spec.contains(lhs) + return spec.contains(lhs, prereleases=True) oper: Optional[Operator] = _operators.get(op.serialize()) if oper is None: @@ -201,25 +122,19 @@ def _eval_op(lhs: str, op: Op, rhs: str) -> bool: return oper(lhs, rhs) -class Undefined: - pass - +def _normalize(*values: str, key: str) -> Tuple[str, ...]: + # PEP 685 – Comparison of extra names for optional distribution dependencies + # https://peps.python.org/pep-0685/ + # > When comparing extra names, tools MUST normalize the names being + # > compared using the semantics outlined in PEP 503 for names + if key == "extra": + return tuple(canonicalize_name(v) for v in values) -_undefined = Undefined() + # other environment markers don't have such standards + return values -def _get_env(environment: Dict[str, str], name: str) -> str: - value: Union[str, Undefined] = environment.get(name, _undefined) - - if isinstance(value, Undefined): - raise UndefinedEnvironmentName( - f"{name!r} does not exist in evaluation environment." - ) - - return value - - -def _evaluate_markers(markers: List[Any], environment: Dict[str, str]) -> bool: +def _evaluate_markers(markers: MarkerList, environment: Dict[str, str]) -> bool: groups: List[List[bool]] = [[]] for marker in markers: @@ -231,12 +146,15 @@ def _evaluate_markers(markers: List[Any], environment: Dict[str, str]) -> bool: lhs, op, rhs = marker if isinstance(lhs, Variable): - lhs_value = _get_env(environment, lhs.value) + environment_key = lhs.value + lhs_value = environment[environment_key] rhs_value = rhs.value else: lhs_value = lhs.value - rhs_value = _get_env(environment, rhs.value) + environment_key = rhs.value + rhs_value = environment[environment_key] + lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) groups[-1].append(_eval_op(lhs_value, op, rhs_value)) else: assert marker in ["and", "or"] @@ -274,13 +192,29 @@ def default_environment() -> Dict[str, str]: class Marker: def __init__(self, marker: str) -> None: + # Note: We create a Marker object without calling this constructor in + # packaging.requirements.Requirement. If any additional logic is + # added here, make sure to mirror/adapt Requirement. try: - self._markers = _coerce_parse_result(MARKER.parseString(marker)) - except ParseException as e: - raise InvalidMarker( - f"Invalid marker: {marker!r}, parse error at " - f"{marker[e.loc : e.loc + 8]!r}" - ) + self._markers = _normalize_extra_values(_parse_marker(marker)) + # The attribute `_markers` can be described in terms of a recursive type: + # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]] + # + # For example, the following expression: + # python_version > "3.6" or (python_version == "3.6" and os_name == "unix") + # + # is parsed into: + # [ + # (, ')>, ), + # 'and', + # [ + # (, , ), + # 'or', + # (, , ) + # ] + # ] + except ParserSyntaxError as e: + raise InvalidMarker(str(e)) from e def __str__(self) -> str: return _format_marker(self._markers) @@ -288,6 +222,15 @@ def __str__(self) -> str: def __repr__(self) -> str: return f"" + def __hash__(self) -> int: + return hash((self.__class__.__name__, str(self))) + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, Marker): + return NotImplemented + + return str(self) == str(other) + def evaluate(self, environment: Optional[Dict[str, str]] = None) -> bool: """Evaluate a marker. @@ -298,7 +241,12 @@ def evaluate(self, environment: Optional[Dict[str, str]] = None) -> bool: The environment is determined from the current Python process. """ current_environment = default_environment() + current_environment["extra"] = "" if environment is not None: current_environment.update(environment) + # The API used to allow setting extra to None. We need to handle this + # case for backwards compatibility. + if current_environment["extra"] is None: + current_environment["extra"] = "" return _evaluate_markers(self._markers, current_environment) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/metadata.py b/uno/lib/python/pkg_resources/_vendor/packaging/metadata.py new file mode 100644 index 00000000..e76a60c3 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/packaging/metadata.py @@ -0,0 +1,408 @@ +import email.feedparser +import email.header +import email.message +import email.parser +import email.policy +import sys +import typing +from typing import Dict, List, Optional, Tuple, Union, cast + +if sys.version_info >= (3, 8): # pragma: no cover + from typing import TypedDict +else: # pragma: no cover + if typing.TYPE_CHECKING: + from typing_extensions import TypedDict + else: + try: + from typing_extensions import TypedDict + except ImportError: + + class TypedDict: + def __init_subclass__(*_args, **_kwargs): + pass + + +# The RawMetadata class attempts to make as few assumptions about the underlying +# serialization formats as possible. The idea is that as long as a serialization +# formats offer some very basic primitives in *some* way then we can support +# serializing to and from that format. +class RawMetadata(TypedDict, total=False): + """A dictionary of raw core metadata. + + Each field in core metadata maps to a key of this dictionary (when data is + provided). The key is lower-case and underscores are used instead of dashes + compared to the equivalent core metadata field. Any core metadata field that + can be specified multiple times or can hold multiple values in a single + field have a key with a plural name. + + Core metadata fields that can be specified multiple times are stored as a + list or dict depending on which is appropriate for the field. Any fields + which hold multiple values in a single field are stored as a list. + + """ + + # Metadata 1.0 - PEP 241 + metadata_version: str + name: str + version: str + platforms: List[str] + summary: str + description: str + keywords: List[str] + home_page: str + author: str + author_email: str + license: str + + # Metadata 1.1 - PEP 314 + supported_platforms: List[str] + download_url: str + classifiers: List[str] + requires: List[str] + provides: List[str] + obsoletes: List[str] + + # Metadata 1.2 - PEP 345 + maintainer: str + maintainer_email: str + requires_dist: List[str] + provides_dist: List[str] + obsoletes_dist: List[str] + requires_python: str + requires_external: List[str] + project_urls: Dict[str, str] + + # Metadata 2.0 + # PEP 426 attempted to completely revamp the metadata format + # but got stuck without ever being able to build consensus on + # it and ultimately ended up withdrawn. + # + # However, a number of tools had started emiting METADATA with + # `2.0` Metadata-Version, so for historical reasons, this version + # was skipped. + + # Metadata 2.1 - PEP 566 + description_content_type: str + provides_extra: List[str] + + # Metadata 2.2 - PEP 643 + dynamic: List[str] + + # Metadata 2.3 - PEP 685 + # No new fields were added in PEP 685, just some edge case were + # tightened up to provide better interoptability. + + +_STRING_FIELDS = { + "author", + "author_email", + "description", + "description_content_type", + "download_url", + "home_page", + "license", + "maintainer", + "maintainer_email", + "metadata_version", + "name", + "requires_python", + "summary", + "version", +} + +_LIST_STRING_FIELDS = { + "classifiers", + "dynamic", + "obsoletes", + "obsoletes_dist", + "platforms", + "provides", + "provides_dist", + "provides_extra", + "requires", + "requires_dist", + "requires_external", + "supported_platforms", +} + + +def _parse_keywords(data: str) -> List[str]: + """Split a string of comma-separate keyboards into a list of keywords.""" + return [k.strip() for k in data.split(",")] + + +def _parse_project_urls(data: List[str]) -> Dict[str, str]: + """Parse a list of label/URL string pairings separated by a comma.""" + urls = {} + for pair in data: + # Our logic is slightly tricky here as we want to try and do + # *something* reasonable with malformed data. + # + # The main thing that we have to worry about, is data that does + # not have a ',' at all to split the label from the Value. There + # isn't a singular right answer here, and we will fail validation + # later on (if the caller is validating) so it doesn't *really* + # matter, but since the missing value has to be an empty str + # and our return value is dict[str, str], if we let the key + # be the missing value, then they'd have multiple '' values that + # overwrite each other in a accumulating dict. + # + # The other potentional issue is that it's possible to have the + # same label multiple times in the metadata, with no solid "right" + # answer with what to do in that case. As such, we'll do the only + # thing we can, which is treat the field as unparseable and add it + # to our list of unparsed fields. + parts = [p.strip() for p in pair.split(",", 1)] + parts.extend([""] * (max(0, 2 - len(parts)))) # Ensure 2 items + + # TODO: The spec doesn't say anything about if the keys should be + # considered case sensitive or not... logically they should + # be case-preserving and case-insensitive, but doing that + # would open up more cases where we might have duplicate + # entries. + label, url = parts + if label in urls: + # The label already exists in our set of urls, so this field + # is unparseable, and we can just add the whole thing to our + # unparseable data and stop processing it. + raise KeyError("duplicate labels in project urls") + urls[label] = url + + return urls + + +def _get_payload(msg: email.message.Message, source: Union[bytes, str]) -> str: + """Get the body of the message.""" + # If our source is a str, then our caller has managed encodings for us, + # and we don't need to deal with it. + if isinstance(source, str): + payload: str = msg.get_payload() + return payload + # If our source is a bytes, then we're managing the encoding and we need + # to deal with it. + else: + bpayload: bytes = msg.get_payload(decode=True) + try: + return bpayload.decode("utf8", "strict") + except UnicodeDecodeError: + raise ValueError("payload in an invalid encoding") + + +# The various parse_FORMAT functions here are intended to be as lenient as +# possible in their parsing, while still returning a correctly typed +# RawMetadata. +# +# To aid in this, we also generally want to do as little touching of the +# data as possible, except where there are possibly some historic holdovers +# that make valid data awkward to work with. +# +# While this is a lower level, intermediate format than our ``Metadata`` +# class, some light touch ups can make a massive difference in usability. + +# Map METADATA fields to RawMetadata. +_EMAIL_TO_RAW_MAPPING = { + "author": "author", + "author-email": "author_email", + "classifier": "classifiers", + "description": "description", + "description-content-type": "description_content_type", + "download-url": "download_url", + "dynamic": "dynamic", + "home-page": "home_page", + "keywords": "keywords", + "license": "license", + "maintainer": "maintainer", + "maintainer-email": "maintainer_email", + "metadata-version": "metadata_version", + "name": "name", + "obsoletes": "obsoletes", + "obsoletes-dist": "obsoletes_dist", + "platform": "platforms", + "project-url": "project_urls", + "provides": "provides", + "provides-dist": "provides_dist", + "provides-extra": "provides_extra", + "requires": "requires", + "requires-dist": "requires_dist", + "requires-external": "requires_external", + "requires-python": "requires_python", + "summary": "summary", + "supported-platform": "supported_platforms", + "version": "version", +} + + +def parse_email(data: Union[bytes, str]) -> Tuple[RawMetadata, Dict[str, List[str]]]: + """Parse a distribution's metadata. + + This function returns a two-item tuple of dicts. The first dict is of + recognized fields from the core metadata specification. Fields that can be + parsed and translated into Python's built-in types are converted + appropriately. All other fields are left as-is. Fields that are allowed to + appear multiple times are stored as lists. + + The second dict contains all other fields from the metadata. This includes + any unrecognized fields. It also includes any fields which are expected to + be parsed into a built-in type but were not formatted appropriately. Finally, + any fields that are expected to appear only once but are repeated are + included in this dict. + + """ + raw: Dict[str, Union[str, List[str], Dict[str, str]]] = {} + unparsed: Dict[str, List[str]] = {} + + if isinstance(data, str): + parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data) + else: + parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data) + + # We have to wrap parsed.keys() in a set, because in the case of multiple + # values for a key (a list), the key will appear multiple times in the + # list of keys, but we're avoiding that by using get_all(). + for name in frozenset(parsed.keys()): + # Header names in RFC are case insensitive, so we'll normalize to all + # lower case to make comparisons easier. + name = name.lower() + + # We use get_all() here, even for fields that aren't multiple use, + # because otherwise someone could have e.g. two Name fields, and we + # would just silently ignore it rather than doing something about it. + headers = parsed.get_all(name) + + # The way the email module works when parsing bytes is that it + # unconditionally decodes the bytes as ascii using the surrogateescape + # handler. When you pull that data back out (such as with get_all() ), + # it looks to see if the str has any surrogate escapes, and if it does + # it wraps it in a Header object instead of returning the string. + # + # As such, we'll look for those Header objects, and fix up the encoding. + value = [] + # Flag if we have run into any issues processing the headers, thus + # signalling that the data belongs in 'unparsed'. + valid_encoding = True + for h in headers: + # It's unclear if this can return more types than just a Header or + # a str, so we'll just assert here to make sure. + assert isinstance(h, (email.header.Header, str)) + + # If it's a header object, we need to do our little dance to get + # the real data out of it. In cases where there is invalid data + # we're going to end up with mojibake, but there's no obvious, good + # way around that without reimplementing parts of the Header object + # ourselves. + # + # That should be fine since, if mojibacked happens, this key is + # going into the unparsed dict anyways. + if isinstance(h, email.header.Header): + # The Header object stores it's data as chunks, and each chunk + # can be independently encoded, so we'll need to check each + # of them. + chunks: List[Tuple[bytes, Optional[str]]] = [] + for bin, encoding in email.header.decode_header(h): + try: + bin.decode("utf8", "strict") + except UnicodeDecodeError: + # Enable mojibake. + encoding = "latin1" + valid_encoding = False + else: + encoding = "utf8" + chunks.append((bin, encoding)) + + # Turn our chunks back into a Header object, then let that + # Header object do the right thing to turn them into a + # string for us. + value.append(str(email.header.make_header(chunks))) + # This is already a string, so just add it. + else: + value.append(h) + + # We've processed all of our values to get them into a list of str, + # but we may have mojibake data, in which case this is an unparsed + # field. + if not valid_encoding: + unparsed[name] = value + continue + + raw_name = _EMAIL_TO_RAW_MAPPING.get(name) + if raw_name is None: + # This is a bit of a weird situation, we've encountered a key that + # we don't know what it means, so we don't know whether it's meant + # to be a list or not. + # + # Since we can't really tell one way or another, we'll just leave it + # as a list, even though it may be a single item list, because that's + # what makes the most sense for email headers. + unparsed[name] = value + continue + + # If this is one of our string fields, then we'll check to see if our + # value is a list of a single item. If it is then we'll assume that + # it was emitted as a single string, and unwrap the str from inside + # the list. + # + # If it's any other kind of data, then we haven't the faintest clue + # what we should parse it as, and we have to just add it to our list + # of unparsed stuff. + if raw_name in _STRING_FIELDS and len(value) == 1: + raw[raw_name] = value[0] + # If this is one of our list of string fields, then we can just assign + # the value, since email *only* has strings, and our get_all() call + # above ensures that this is a list. + elif raw_name in _LIST_STRING_FIELDS: + raw[raw_name] = value + # Special Case: Keywords + # The keywords field is implemented in the metadata spec as a str, + # but it conceptually is a list of strings, and is serialized using + # ", ".join(keywords), so we'll do some light data massaging to turn + # this into what it logically is. + elif raw_name == "keywords" and len(value) == 1: + raw[raw_name] = _parse_keywords(value[0]) + # Special Case: Project-URL + # The project urls is implemented in the metadata spec as a list of + # specially-formatted strings that represent a key and a value, which + # is fundamentally a mapping, however the email format doesn't support + # mappings in a sane way, so it was crammed into a list of strings + # instead. + # + # We will do a little light data massaging to turn this into a map as + # it logically should be. + elif raw_name == "project_urls": + try: + raw[raw_name] = _parse_project_urls(value) + except KeyError: + unparsed[name] = value + # Nothing that we've done has managed to parse this, so it'll just + # throw it in our unparseable data and move on. + else: + unparsed[name] = value + + # We need to support getting the Description from the message payload in + # addition to getting it from the the headers. This does mean, though, there + # is the possibility of it being set both ways, in which case we put both + # in 'unparsed' since we don't know which is right. + try: + payload = _get_payload(parsed, data) + except ValueError: + unparsed.setdefault("description", []).append( + parsed.get_payload(decode=isinstance(data, bytes)) + ) + else: + if payload: + # Check to see if we've already got a description, if so then both + # it, and this body move to unparseable. + if "description" in raw: + description_header = cast(str, raw.pop("description")) + unparsed.setdefault("description", []).extend( + [description_header, payload] + ) + elif "description" in unparsed: + unparsed["description"].append(payload) + else: + raw["description"] = payload + + # We need to cast our `raw` to a metadata, because a TypedDict only support + # literal key names, but we're computing our key names on purpose, but the + # way this function is implemented, our `TypedDict` can only have valid key + # names. + return cast(RawMetadata, raw), unparsed diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/py.typed b/uno/lib/python/pkg_resources/_vendor/packaging/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/requirements.py b/uno/lib/python/pkg_resources/_vendor/packaging/requirements.py index 6af14ec4..f34bfa85 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/requirements.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/requirements.py @@ -2,26 +2,13 @@ # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. -import re -import string import urllib.parse -from typing import List, Optional as TOptional, Set +from typing import Any, List, Optional, Set -from pkg_resources.extern.pyparsing import ( # noqa - Combine, - Literal as L, - Optional, - ParseException, - Regex, - Word, - ZeroOrMore, - originalTextFor, - stringEnd, - stringStart, -) - -from .markers import MARKER_EXPR, Marker -from .specifiers import LegacySpecifier, Specifier, SpecifierSet +from ._parser import parse_requirement as _parse_requirement +from ._tokenizer import ParserSyntaxError +from .markers import Marker, _normalize_extra_values +from .specifiers import SpecifierSet class InvalidRequirement(ValueError): @@ -30,60 +17,6 @@ class InvalidRequirement(ValueError): """ -ALPHANUM = Word(string.ascii_letters + string.digits) - -LBRACKET = L("[").suppress() -RBRACKET = L("]").suppress() -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() -COMMA = L(",").suppress() -SEMICOLON = L(";").suppress() -AT = L("@").suppress() - -PUNCTUATION = Word("-_.") -IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) -IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) - -NAME = IDENTIFIER("name") -EXTRA = IDENTIFIER - -URI = Regex(r"[^ ]+")("url") -URL = AT + URI - -EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) -EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") - -VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) -VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) - -VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY -VERSION_MANY = Combine( - VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False -)("_raw_spec") -_VERSION_SPEC = Optional((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY) -_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") - -VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") -VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) - -MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") -MARKER_EXPR.setParseAction( - lambda s, l, t: Marker(s[t._original_start : t._original_end]) -) -MARKER_SEPARATOR = SEMICOLON -MARKER = MARKER_SEPARATOR + MARKER_EXPR - -VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) -URL_AND_MARKER = URL + Optional(MARKER) - -NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) - -REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd -# pkg_resources.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see -# issue #104 -REQUIREMENT.parseString("x[]") - - class Requirement: """Parse a requirement. @@ -99,28 +32,29 @@ class Requirement: def __init__(self, requirement_string: str) -> None: try: - req = REQUIREMENT.parseString(requirement_string) - except ParseException as e: - raise InvalidRequirement( - f'Parse error at "{ requirement_string[e.loc : e.loc + 8]!r}": {e.msg}' - ) - - self.name: str = req.name - if req.url: - parsed_url = urllib.parse.urlparse(req.url) + parsed = _parse_requirement(requirement_string) + except ParserSyntaxError as e: + raise InvalidRequirement(str(e)) from e + + self.name: str = parsed.name + if parsed.url: + parsed_url = urllib.parse.urlparse(parsed.url) if parsed_url.scheme == "file": - if urllib.parse.urlunparse(parsed_url) != req.url: + if urllib.parse.urlunparse(parsed_url) != parsed.url: raise InvalidRequirement("Invalid URL given") elif not (parsed_url.scheme and parsed_url.netloc) or ( not parsed_url.scheme and not parsed_url.netloc ): - raise InvalidRequirement(f"Invalid URL: {req.url}") - self.url: TOptional[str] = req.url + raise InvalidRequirement(f"Invalid URL: {parsed.url}") + self.url: Optional[str] = parsed.url else: self.url = None - self.extras: Set[str] = set(req.extras.asList() if req.extras else []) - self.specifier: SpecifierSet = SpecifierSet(req.specifier) - self.marker: TOptional[Marker] = req.marker if req.marker else None + self.extras: Set[str] = set(parsed.extras if parsed.extras else []) + self.specifier: SpecifierSet = SpecifierSet(parsed.specifier) + self.marker: Optional[Marker] = None + if parsed.marker is not None: + self.marker = Marker.__new__(Marker) + self.marker._markers = _normalize_extra_values(parsed.marker) def __str__(self) -> str: parts: List[str] = [self.name] @@ -144,3 +78,18 @@ def __str__(self) -> str: def __repr__(self) -> str: return f"" + + def __hash__(self) -> int: + return hash((self.__class__.__name__, str(self))) + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, Requirement): + return NotImplemented + + return ( + self.name == other.name + and self.extras == other.extras + and self.specifier == other.specifier + and self.url == other.url + and self.marker == other.marker + ) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/specifiers.py b/uno/lib/python/pkg_resources/_vendor/packaging/specifiers.py index ce66bd4a..ba8fe37b 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/specifiers.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/specifiers.py @@ -1,20 +1,22 @@ # This file is dual licensed under the terms of the Apache License, Version # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +""" +.. testsetup:: + + from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier + from packaging.version import Version +""" import abc -import functools import itertools import re -import warnings from typing import ( Callable, - Dict, Iterable, Iterator, List, Optional, - Pattern, Set, Tuple, TypeVar, @@ -22,17 +24,28 @@ ) from .utils import canonicalize_version -from .version import LegacyVersion, Version, parse +from .version import Version + +UnparsedVersion = Union[Version, str] +UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) +CallableOperator = Callable[[Version, str], bool] -ParsedVersion = Union[Version, LegacyVersion] -UnparsedVersion = Union[Version, LegacyVersion, str] -VersionTypeVar = TypeVar("VersionTypeVar", bound=UnparsedVersion) -CallableOperator = Callable[[ParsedVersion, str], bool] + +def _coerce_version(version: UnparsedVersion) -> Version: + if not isinstance(version, Version): + version = Version(version) + return version class InvalidSpecifier(ValueError): """ - An invalid specifier was found, users should refer to PEP 440. + Raised when attempting to create a :class:`Specifier` with a specifier + string that is invalid. + + >>> Specifier("lolwat") + Traceback (most recent call last): + ... + packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat' """ @@ -40,42 +53,39 @@ class BaseSpecifier(metaclass=abc.ABCMeta): @abc.abstractmethod def __str__(self) -> str: """ - Returns the str representation of this Specifier like object. This + Returns the str representation of this Specifier-like object. This should be representative of the Specifier itself. """ @abc.abstractmethod def __hash__(self) -> int: """ - Returns a hash value for this Specifier like object. + Returns a hash value for this Specifier-like object. """ @abc.abstractmethod def __eq__(self, other: object) -> bool: """ - Returns a boolean representing whether or not the two Specifier like + Returns a boolean representing whether or not the two Specifier-like objects are equal. - """ - @abc.abstractmethod - def __ne__(self, other: object) -> bool: - """ - Returns a boolean representing whether or not the two Specifier like - objects are not equal. + :param other: The other object to check against. """ - @abc.abstractproperty + @property + @abc.abstractmethod def prereleases(self) -> Optional[bool]: - """ - Returns whether or not pre-releases as a whole are allowed by this - specifier. + """Whether or not pre-releases as a whole are allowed. + + This can be set to either ``True`` or ``False`` to explicitly enable or disable + prereleases or it can be set to ``None`` (the default) to use default semantics. """ @prereleases.setter def prereleases(self, value: bool) -> None: - """ - Sets whether or not pre-releases as a whole are allowed by this - specifier. + """Setter for :attr:`prereleases`. + + :param value: The value to set. """ @abc.abstractmethod @@ -86,238 +96,28 @@ def contains(self, item: str, prereleases: Optional[bool] = None) -> bool: @abc.abstractmethod def filter( - self, iterable: Iterable[VersionTypeVar], prereleases: Optional[bool] = None - ) -> Iterable[VersionTypeVar]: + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: """ Takes an iterable of items and filters them so that only items which are contained within this specifier are allowed in it. """ -class _IndividualSpecifier(BaseSpecifier): - - _operators: Dict[str, str] = {} - _regex: Pattern[str] - - def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None: - match = self._regex.search(spec) - if not match: - raise InvalidSpecifier(f"Invalid specifier: '{spec}'") - - self._spec: Tuple[str, str] = ( - match.group("operator").strip(), - match.group("version").strip(), - ) - - # Store whether or not this Specifier should accept prereleases - self._prereleases = prereleases - - def __repr__(self) -> str: - pre = ( - f", prereleases={self.prereleases!r}" - if self._prereleases is not None - else "" - ) - - return "<{}({!r}{})>".format(self.__class__.__name__, str(self), pre) - - def __str__(self) -> str: - return "{}{}".format(*self._spec) - - @property - def _canonical_spec(self) -> Tuple[str, str]: - return self._spec[0], canonicalize_version(self._spec[1]) - - def __hash__(self) -> int: - return hash(self._canonical_spec) - - def __eq__(self, other: object) -> bool: - if isinstance(other, str): - try: - other = self.__class__(str(other)) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._canonical_spec == other._canonical_spec - - def __ne__(self, other: object) -> bool: - if isinstance(other, str): - try: - other = self.__class__(str(other)) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._spec != other._spec - - def _get_operator(self, op: str) -> CallableOperator: - operator_callable: CallableOperator = getattr( - self, f"_compare_{self._operators[op]}" - ) - return operator_callable - - def _coerce_version(self, version: UnparsedVersion) -> ParsedVersion: - if not isinstance(version, (LegacyVersion, Version)): - version = parse(version) - return version - - @property - def operator(self) -> str: - return self._spec[0] - - @property - def version(self) -> str: - return self._spec[1] - - @property - def prereleases(self) -> Optional[bool]: - return self._prereleases - - @prereleases.setter - def prereleases(self, value: bool) -> None: - self._prereleases = value - - def __contains__(self, item: str) -> bool: - return self.contains(item) - - def contains( - self, item: UnparsedVersion, prereleases: Optional[bool] = None - ) -> bool: - - # Determine if prereleases are to be allowed or not. - if prereleases is None: - prereleases = self.prereleases - - # Normalize item to a Version or LegacyVersion, this allows us to have - # a shortcut for ``"2.0" in Specifier(">=2") - normalized_item = self._coerce_version(item) - - # Determine if we should be supporting prereleases in this specifier - # or not, if we do not support prereleases than we can short circuit - # logic if this version is a prereleases. - if normalized_item.is_prerelease and not prereleases: - return False - - # Actually do the comparison to determine if this item is contained - # within this Specifier or not. - operator_callable: CallableOperator = self._get_operator(self.operator) - return operator_callable(normalized_item, self.version) - - def filter( - self, iterable: Iterable[VersionTypeVar], prereleases: Optional[bool] = None - ) -> Iterable[VersionTypeVar]: - - yielded = False - found_prereleases = [] - - kw = {"prereleases": prereleases if prereleases is not None else True} - - # Attempt to iterate over all the values in the iterable and if any of - # them match, yield them. - for version in iterable: - parsed_version = self._coerce_version(version) - - if self.contains(parsed_version, **kw): - # If our version is a prerelease, and we were not set to allow - # prereleases, then we'll store it for later in case nothing - # else matches this specifier. - if parsed_version.is_prerelease and not ( - prereleases or self.prereleases - ): - found_prereleases.append(version) - # Either this is not a prerelease, or we should have been - # accepting prereleases from the beginning. - else: - yielded = True - yield version - - # Now that we've iterated over everything, determine if we've yielded - # any values, and if we have not and we have any prereleases stored up - # then we will go ahead and yield the prereleases. - if not yielded and found_prereleases: - for version in found_prereleases: - yield version - - -class LegacySpecifier(_IndividualSpecifier): - - _regex_str = r""" - (?P(==|!=|<=|>=|<|>)) - \s* - (?P - [^,;\s)]* # Since this is a "legacy" specifier, and the version - # string can be just about anything, we match everything - # except for whitespace, a semi-colon for marker support, - # a closing paren since versions can be enclosed in - # them, and a comma since it's a version separator. - ) - """ - - _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) - - _operators = { - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - } +class Specifier(BaseSpecifier): + """This class abstracts handling of version specifiers. - def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None: - super().__init__(spec, prereleases) + .. tip:: - warnings.warn( - "Creating a LegacyVersion has been deprecated and will be " - "removed in the next major release", - DeprecationWarning, - ) - - def _coerce_version(self, version: UnparsedVersion) -> LegacyVersion: - if not isinstance(version, LegacyVersion): - version = LegacyVersion(str(version)) - return version - - def _compare_equal(self, prospective: LegacyVersion, spec: str) -> bool: - return prospective == self._coerce_version(spec) - - def _compare_not_equal(self, prospective: LegacyVersion, spec: str) -> bool: - return prospective != self._coerce_version(spec) - - def _compare_less_than_equal(self, prospective: LegacyVersion, spec: str) -> bool: - return prospective <= self._coerce_version(spec) - - def _compare_greater_than_equal( - self, prospective: LegacyVersion, spec: str - ) -> bool: - return prospective >= self._coerce_version(spec) - - def _compare_less_than(self, prospective: LegacyVersion, spec: str) -> bool: - return prospective < self._coerce_version(spec) - - def _compare_greater_than(self, prospective: LegacyVersion, spec: str) -> bool: - return prospective > self._coerce_version(spec) - - -def _require_version_compare( - fn: Callable[["Specifier", ParsedVersion, str], bool] -) -> Callable[["Specifier", ParsedVersion, str], bool]: - @functools.wraps(fn) - def wrapped(self: "Specifier", prospective: ParsedVersion, spec: str) -> bool: - if not isinstance(prospective, Version): - return False - return fn(self, prospective, spec) - - return wrapped - - -class Specifier(_IndividualSpecifier): + It is generally not required to instantiate this manually. You should instead + prefer to work with :class:`SpecifierSet` instead, which can parse + comma-separated version specifiers (which is what package metadata contains). + """ - _regex_str = r""" + _operator_regex_str = r""" (?P(~=|==|!=|<=|>=|<|>|===)) + """ + _version_regex_str = r""" (?P (?: # The identity operators allow for an escape hatch that will @@ -327,8 +127,10 @@ class Specifier(_IndividualSpecifier): # but included entirely as an escape hatch. (?<====) # Only match for the identity operator \s* - [^\s]* # We just match everything, except for whitespace - # since we are only testing for strict identity. + [^\s;)]* # The arbitrary version can be just about anything, + # we match everything except for whitespace, a + # semi-colon for marker support, and a closing paren + # since versions can be enclosed in them. ) | (?: @@ -341,23 +143,23 @@ class Specifier(_IndividualSpecifier): v? (?:[0-9]+!)? # epoch [0-9]+(?:\.[0-9]+)* # release - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - # You cannot use a wild card and a dev or local version - # together so group them with a | and make them optional. + # You cannot use a wild card and a pre-release, post-release, a dev or + # local version together so group them with a | and make them optional. (?: + \.\* # Wild card syntax of .* + | + (?: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local - | - \.\* # Wild card syntax of .* )? ) | @@ -372,7 +174,7 @@ class Specifier(_IndividualSpecifier): [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) (?: # pre release [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) + (alpha|beta|preview|pre|a|b|c|rc) [-_\.]? [0-9]* )? @@ -397,7 +199,7 @@ class Specifier(_IndividualSpecifier): [0-9]+(?:\.[0-9]+)* # release (?: # pre release [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) + (alpha|beta|preview|pre|a|b|c|rc) [-_\.]? [0-9]* )? @@ -409,7 +211,10 @@ class Specifier(_IndividualSpecifier): ) """ - _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + _regex = re.compile( + r"^\s*" + _operator_regex_str + _version_regex_str + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) _operators = { "~=": "compatible", @@ -422,8 +227,153 @@ class Specifier(_IndividualSpecifier): "===": "arbitrary", } - @_require_version_compare - def _compare_compatible(self, prospective: ParsedVersion, spec: str) -> bool: + def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None: + """Initialize a Specifier instance. + + :param spec: + The string representation of a specifier which will be parsed and + normalized before use. + :param prereleases: + This tells the specifier if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + :raises InvalidSpecifier: + If the given specifier is invalid (i.e. bad syntax). + """ + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier(f"Invalid specifier: '{spec}'") + + self._spec: Tuple[str, str] = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + # https://github.com/python/mypy/pull/13475#pullrequestreview-1079784515 + @property # type: ignore[override] + def prereleases(self) -> bool: + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if Version(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value: bool) -> None: + self._prereleases = value + + @property + def operator(self) -> str: + """The operator of this specifier. + + >>> Specifier("==1.2.3").operator + '==' + """ + return self._spec[0] + + @property + def version(self) -> str: + """The version of this specifier. + + >>> Specifier("==1.2.3").version + '1.2.3' + """ + return self._spec[1] + + def __repr__(self) -> str: + """A representation of the Specifier that shows all internal state. + + >>> Specifier('>=1.0.0') + =1.0.0')> + >>> Specifier('>=1.0.0', prereleases=False) + =1.0.0', prereleases=False)> + >>> Specifier('>=1.0.0', prereleases=True) + =1.0.0', prereleases=True)> + """ + pre = ( + f", prereleases={self.prereleases!r}" + if self._prereleases is not None + else "" + ) + + return f"<{self.__class__.__name__}({str(self)!r}{pre})>" + + def __str__(self) -> str: + """A string representation of the Specifier that can be round-tripped. + + >>> str(Specifier('>=1.0.0')) + '>=1.0.0' + >>> str(Specifier('>=1.0.0', prereleases=False)) + '>=1.0.0' + """ + return "{}{}".format(*self._spec) + + @property + def _canonical_spec(self) -> Tuple[str, str]: + canonical_version = canonicalize_version( + self._spec[1], + strip_trailing_zero=(self._spec[0] != "~="), + ) + return self._spec[0], canonical_version + + def __hash__(self) -> int: + return hash(self._canonical_spec) + + def __eq__(self, other: object) -> bool: + """Whether or not the two Specifier-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0") + True + >>> (Specifier("==1.2.3", prereleases=False) == + ... Specifier("==1.2.3", prereleases=True)) + True + >>> Specifier("==1.2.3") == "==1.2.3" + True + >>> Specifier("==1.2.3") == Specifier("==1.2.4") + False + >>> Specifier("==1.2.3") == Specifier("~=1.2.3") + False + """ + if isinstance(other, str): + try: + other = self.__class__(str(other)) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._canonical_spec == other._canonical_spec + + def _get_operator(self, op: str) -> CallableOperator: + operator_callable: CallableOperator = getattr( + self, f"_compare_{self._operators[op]}" + ) + return operator_callable + + def _compare_compatible(self, prospective: Version, spec: str) -> bool: # Compatible releases have an equivalent combination of >= and ==. That # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to @@ -444,34 +394,35 @@ def _compare_compatible(self, prospective: ParsedVersion, spec: str) -> bool: prospective, prefix ) - @_require_version_compare - def _compare_equal(self, prospective: ParsedVersion, spec: str) -> bool: + def _compare_equal(self, prospective: Version, spec: str) -> bool: # We need special logic to handle prefix matching if spec.endswith(".*"): # In the case of prefix matching we want to ignore local segment. - prospective = Version(prospective.public) + normalized_prospective = canonicalize_version( + prospective.public, strip_trailing_zero=False + ) + # Get the normalized version string ignoring the trailing .* + normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False) # Split the spec out by dots, and pretend that there is an implicit # dot in between a release segment and a pre-release segment. - split_spec = _version_split(spec[:-2]) # Remove the trailing .* + split_spec = _version_split(normalized_spec) # Split the prospective version out by dots, and pretend that there # is an implicit dot in between a release segment and a pre-release # segment. - split_prospective = _version_split(str(prospective)) + split_prospective = _version_split(normalized_prospective) + + # 0-pad the prospective version before shortening it to get the correct + # shortened version. + padded_prospective, _ = _pad_version(split_prospective, split_spec) # Shorten the prospective version to be the same length as the spec # so that we can determine if the specifier is a prefix of the # prospective version or not. - shortened_prospective = split_prospective[: len(split_spec)] - - # Pad out our two sides with zeros so that they both equal the same - # length. - padded_spec, padded_prospective = _pad_version( - split_spec, shortened_prospective - ) + shortened_prospective = padded_prospective[: len(split_spec)] - return padded_prospective == padded_spec + return shortened_prospective == split_spec else: # Convert our spec string into a Version spec_version = Version(spec) @@ -484,30 +435,24 @@ def _compare_equal(self, prospective: ParsedVersion, spec: str) -> bool: return prospective == spec_version - @_require_version_compare - def _compare_not_equal(self, prospective: ParsedVersion, spec: str) -> bool: + def _compare_not_equal(self, prospective: Version, spec: str) -> bool: return not self._compare_equal(prospective, spec) - @_require_version_compare - def _compare_less_than_equal(self, prospective: ParsedVersion, spec: str) -> bool: + def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool: # NB: Local version identifiers are NOT permitted in the version # specifier, so local version labels can be universally removed from # the prospective version. return Version(prospective.public) <= Version(spec) - @_require_version_compare - def _compare_greater_than_equal( - self, prospective: ParsedVersion, spec: str - ) -> bool: + def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool: # NB: Local version identifiers are NOT permitted in the version # specifier, so local version labels can be universally removed from # the prospective version. return Version(prospective.public) >= Version(spec) - @_require_version_compare - def _compare_less_than(self, prospective: ParsedVersion, spec_str: str) -> bool: + def _compare_less_than(self, prospective: Version, spec_str: str) -> bool: # Convert our spec to a Version instance, since we'll want to work with # it as a version. @@ -532,8 +477,7 @@ def _compare_less_than(self, prospective: ParsedVersion, spec_str: str) -> bool: # version in the spec. return True - @_require_version_compare - def _compare_greater_than(self, prospective: ParsedVersion, spec_str: str) -> bool: + def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool: # Convert our spec to a Version instance, since we'll want to work with # it as a version. @@ -567,34 +511,133 @@ def _compare_greater_than(self, prospective: ParsedVersion, spec_str: str) -> bo def _compare_arbitrary(self, prospective: Version, spec: str) -> bool: return str(prospective).lower() == str(spec).lower() - @property - def prereleases(self) -> bool: + def __contains__(self, item: Union[str, Version]) -> bool: + """Return whether or not the item is contained in this specifier. - # If there is an explicit prereleases set for this, then we'll just - # blindly use that. - if self._prereleases is not None: - return self._prereleases + :param item: The item to check for. - # Look at all of our specifiers and determine if they are inclusive - # operators, and if they are if they are including an explicit - # prerelease. - operator, version = self._spec - if operator in ["==", ">=", "<=", "~=", "==="]: - # The == specifier can include a trailing .*, if it does we - # want to remove before parsing. - if operator == "==" and version.endswith(".*"): - version = version[:-2] + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. - # Parse the version, and if it is a pre-release than this - # specifier allows pre-releases. - if parse(version).is_prerelease: - return True + >>> "1.2.3" in Specifier(">=1.2.3") + True + >>> Version("1.2.3") in Specifier(">=1.2.3") + True + >>> "1.0.0" in Specifier(">=1.2.3") + False + >>> "1.3.0a1" in Specifier(">=1.2.3") + False + >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) + True + """ + return self.contains(item) - return False + def contains( + self, item: UnparsedVersion, prereleases: Optional[bool] = None + ) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: + The item to check for, which can be a version string or a + :class:`Version` instance. + :param prereleases: + Whether or not to match prereleases with this Specifier. If set to + ``None`` (the default), it uses :attr:`prereleases` to determine + whether or not prereleases are allowed. + + >>> Specifier(">=1.2.3").contains("1.2.3") + True + >>> Specifier(">=1.2.3").contains(Version("1.2.3")) + True + >>> Specifier(">=1.2.3").contains("1.0.0") + False + >>> Specifier(">=1.2.3").contains("1.3.0a1") + False + >>> Specifier(">=1.2.3", prereleases=True).contains("1.3.0a1") + True + >>> Specifier(">=1.2.3").contains("1.3.0a1", prereleases=True) + True + """ - @prereleases.setter - def prereleases(self, value: bool) -> None: - self._prereleases = value + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version, this allows us to have a shortcut for + # "2.0" in Specifier(">=2") + normalized_item = _coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if normalized_item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + operator_callable: CallableOperator = self._get_operator(self.operator) + return operator_callable(normalized_item, self.version) + + def filter( + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: + """Filter items in the given iterable, that match the specifier. + + :param iterable: + An iterable that can contain version strings and :class:`Version` instances. + The items in the iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will be intelligently decide whether to allow + prereleases or not (based on the :attr:`prereleases` attribute, and + whether the only versions matching are prereleases). + + This method is smarter than just ``filter(Specifier().contains, [...])`` + because it implements the rule from :pep:`440` that a prerelease item + SHOULD be accepted if no other versions match the given specifier. + + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")])) + ['1.2.3', '1.3', ] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"])) + ['1.5a1'] + >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + """ + + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = _coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later in case nothing + # else matches this specifier. + if parsed_version.is_prerelease and not ( + prereleases or self.prereleases + ): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version _prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") @@ -636,22 +679,39 @@ def _pad_version(left: List[str], right: List[str]) -> Tuple[List[str], List[str class SpecifierSet(BaseSpecifier): + """This class abstracts handling of a set of version specifiers. + + It can be passed a single specifier (``>=3.0``), a comma-separated list of + specifiers (``>=3.0,!=3.1``), or no specifier at all. + """ + def __init__( self, specifiers: str = "", prereleases: Optional[bool] = None ) -> None: + """Initialize a SpecifierSet instance. + + :param specifiers: + The string representation of a specifier or a comma-separated list of + specifiers which will be parsed and normalized before use. + :param prereleases: + This tells the SpecifierSet if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + + :raises InvalidSpecifier: + If the given ``specifiers`` are not parseable than this exception will be + raised. + """ - # Split on , to break each individual specifier into it's own item, and + # Split on `,` to break each individual specifier into it's own item, and # strip each item to remove leading/trailing whitespace. split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] # Parsed each individual specifier, attempting first to make it a - # Specifier and falling back to a LegacySpecifier. - parsed: Set[_IndividualSpecifier] = set() + # Specifier. + parsed: Set[Specifier] = set() for specifier in split_specifiers: - try: - parsed.add(Specifier(specifier)) - except InvalidSpecifier: - parsed.add(LegacySpecifier(specifier)) + parsed.add(Specifier(specifier)) # Turn our parsed specifiers into a frozen set and save them for later. self._specs = frozenset(parsed) @@ -660,22 +720,74 @@ def __init__( # we accept prereleases or not. self._prereleases = prereleases + @property + def prereleases(self) -> Optional[bool]: + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value: bool) -> None: + self._prereleases = value + def __repr__(self) -> str: + """A representation of the specifier set that shows all internal state. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> SpecifierSet('>=1.0.0,!=2.0.0') + =1.0.0')> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) + =1.0.0', prereleases=False)> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) + =1.0.0', prereleases=True)> + """ pre = ( f", prereleases={self.prereleases!r}" if self._prereleases is not None else "" ) - return "".format(str(self), pre) + return f"" def __str__(self) -> str: + """A string representation of the specifier set that can be round-tripped. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> str(SpecifierSet(">=1.0.0,!=1.0.1")) + '!=1.0.1,>=1.0.0' + >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False)) + '!=1.0.1,>=1.0.0' + """ return ",".join(sorted(str(s) for s in self._specs)) def __hash__(self) -> int: return hash(self._specs) def __and__(self, other: Union["SpecifierSet", str]) -> "SpecifierSet": + """Return a SpecifierSet which is a combination of the two sets. + + :param other: The other object to combine with. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1' + =1.0.0')> + >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') + =1.0.0')> + """ if isinstance(other, str): other = SpecifierSet(other) elif not isinstance(other, SpecifierSet): @@ -699,59 +811,98 @@ def __and__(self, other: Union["SpecifierSet", str]) -> "SpecifierSet": return specifier def __eq__(self, other: object) -> bool: - if isinstance(other, (str, _IndividualSpecifier)): + """Whether or not the two SpecifierSet-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) == + ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1" + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2") + False + """ + if isinstance(other, (str, Specifier)): other = SpecifierSet(str(other)) elif not isinstance(other, SpecifierSet): return NotImplemented return self._specs == other._specs - def __ne__(self, other: object) -> bool: - if isinstance(other, (str, _IndividualSpecifier)): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._specs != other._specs - def __len__(self) -> int: + """Returns the number of specifiers in this specifier set.""" return len(self._specs) - def __iter__(self) -> Iterator[_IndividualSpecifier]: - return iter(self._specs) - - @property - def prereleases(self) -> Optional[bool]: - - # If we have been given an explicit prerelease modifier, then we'll - # pass that through here. - if self._prereleases is not None: - return self._prereleases - - # If we don't have any specifiers, and we don't have a forced value, - # then we'll just return None since we don't know if this should have - # pre-releases or not. - if not self._specs: - return None - - # Otherwise we'll see if any of the given specifiers accept - # prereleases, if any of them do we'll return True, otherwise False. - return any(s.prereleases for s in self._specs) + def __iter__(self) -> Iterator[Specifier]: + """ + Returns an iterator over all the underlying :class:`Specifier` instances + in this specifier set. - @prereleases.setter - def prereleases(self, value: bool) -> None: - self._prereleases = value + >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str) + [, =1.0.0')>] + """ + return iter(self._specs) def __contains__(self, item: UnparsedVersion) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: The item to check for. + + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. + + >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1") + False + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1") + False + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) + True + """ return self.contains(item) def contains( - self, item: UnparsedVersion, prereleases: Optional[bool] = None + self, + item: UnparsedVersion, + prereleases: Optional[bool] = None, + installed: Optional[bool] = None, ) -> bool: - - # Ensure that our item is a Version or LegacyVersion instance. - if not isinstance(item, (LegacyVersion, Version)): - item = parse(item) + """Return whether or not the item is contained in this SpecifierSet. + + :param item: + The item to check for, which can be a version string or a + :class:`Version` instance. + :param prereleases: + Whether or not to match prereleases with this SpecifierSet. If set to + ``None`` (the default), it uses :attr:`prereleases` to determine + whether or not prereleases are allowed. + + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3")) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True).contains("1.3.0a1") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) + True + """ + # Ensure that our item is a Version instance. + if not isinstance(item, Version): + item = Version(item) # Determine if we're forcing a prerelease or not, if we're not forcing # one for this particular filter call, then we'll use whatever the @@ -768,6 +919,9 @@ def contains( if not prereleases and item.is_prerelease: return False + if installed and item.is_prerelease: + item = Version(item.base_version) + # We simply dispatch to the underlying specs here to make sure that the # given version is contained within all of them. # Note: This use of all() here means that an empty set of specifiers @@ -775,9 +929,46 @@ def contains( return all(s.contains(item, prereleases=prereleases) for s in self._specs) def filter( - self, iterable: Iterable[VersionTypeVar], prereleases: Optional[bool] = None - ) -> Iterable[VersionTypeVar]: - + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: + """Filter items in the given iterable, that match the specifiers in this set. + + :param iterable: + An iterable that can contain version strings and :class:`Version` instances. + The items in the iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will be intelligently decide whether to allow + prereleases or not (based on the :attr:`prereleases` attribute, and + whether the only versions matching are prereleases). + + This method is smarter than just ``filter(SpecifierSet(...).contains, [...])`` + because it implements the rule from :pep:`440` that a prerelease item + SHOULD be accepted if no other versions match the given specifier. + + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")])) + ['1.3', ] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"])) + [] + >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + + An "empty" SpecifierSet will filter items based on the presence of prerelease + versions in the set. + + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet("").filter(["1.5a1"])) + ['1.5a1'] + >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + """ # Determine if we're forcing a prerelease or not, if we're not forcing # one for this particular filter call, then we'll use whatever the # SpecifierSet thinks for whether or not we should support prereleases. @@ -790,27 +981,16 @@ def filter( if self._specs: for spec in self._specs: iterable = spec.filter(iterable, prereleases=bool(prereleases)) - return iterable + return iter(iterable) # If we do not have any specifiers, then we need to have a rough filter # which will filter out any pre-releases, unless there are no final - # releases, and which will filter out LegacyVersion in general. + # releases. else: - filtered: List[VersionTypeVar] = [] - found_prereleases: List[VersionTypeVar] = [] - - item: UnparsedVersion - parsed_version: Union[Version, LegacyVersion] + filtered: List[UnparsedVersionVar] = [] + found_prereleases: List[UnparsedVersionVar] = [] for item in iterable: - # Ensure that we some kind of Version class for this item. - if not isinstance(item, (LegacyVersion, Version)): - parsed_version = parse(item) - else: - parsed_version = item - - # Filter out any item which is parsed as a LegacyVersion - if isinstance(parsed_version, LegacyVersion): - continue + parsed_version = _coerce_version(item) # Store any item which is a pre-release for later unless we've # already found a final version or we are accepting prereleases @@ -823,6 +1003,6 @@ def filter( # If we've found no items except for pre-releases, then we'll go # ahead and use the pre-releases if not filtered and found_prereleases and prereleases is None: - return found_prereleases + return iter(found_prereleases) - return filtered + return iter(filtered) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/tags.py b/uno/lib/python/pkg_resources/_vendor/packaging/tags.py index e65890a9..76d24341 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/tags.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/tags.py @@ -4,6 +4,7 @@ import logging import platform +import subprocess import sys import sysconfig from importlib.machinery import EXTENSION_SUFFIXES @@ -36,7 +37,7 @@ } -_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32 +_32_BIT_INTERPRETER = sys.maxsize <= 2**32 class Tag: @@ -90,7 +91,7 @@ def __str__(self) -> str: return f"{self._interpreter}-{self._abi}-{self._platform}" def __repr__(self) -> str: - return "<{self} @ {self_id}>".format(self=self, self_id=id(self)) + return f"<{self} @ {id(self)}>" def parse_tag(tag: str) -> FrozenSet[Tag]: @@ -110,7 +111,7 @@ def parse_tag(tag: str) -> FrozenSet[Tag]: def _get_config_var(name: str, warn: bool = False) -> Union[int, str, None]: - value = sysconfig.get_config_var(name) + value: Union[int, str, None] = sysconfig.get_config_var(name) if value is None and warn: logger.debug( "Config variable '%s' is unset, Python ABI tag may be incorrect", name @@ -119,7 +120,7 @@ def _get_config_var(name: str, warn: bool = False) -> Union[int, str, None]: def _normalize_string(string: str) -> str: - return string.replace(".", "_").replace("-", "_") + return string.replace(".", "_").replace("-", "_").replace(" ", "_") def _abi3_applies(python_version: PythonVersion) -> bool: @@ -192,7 +193,7 @@ def cpython_tags( if not python_version: python_version = sys.version_info[:2] - interpreter = "cp{}".format(_version_nodot(python_version[:2])) + interpreter = f"cp{_version_nodot(python_version[:2])}" if abis is None: if len(python_version) > 1: @@ -224,10 +225,45 @@ def cpython_tags( yield Tag(interpreter, "abi3", platform_) -def _generic_abi() -> Iterator[str]: - abi = sysconfig.get_config_var("SOABI") - if abi: - yield _normalize_string(abi) +def _generic_abi() -> List[str]: + """ + Return the ABI tag based on EXT_SUFFIX. + """ + # The following are examples of `EXT_SUFFIX`. + # We want to keep the parts which are related to the ABI and remove the + # parts which are related to the platform: + # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310 + # - mac: '.cpython-310-darwin.so' => cp310 + # - win: '.cp310-win_amd64.pyd' => cp310 + # - win: '.pyd' => cp37 (uses _cpython_abis()) + # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73 + # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' + # => graalpy_38_native + + ext_suffix = _get_config_var("EXT_SUFFIX", warn=True) + if not isinstance(ext_suffix, str) or ext_suffix[0] != ".": + raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") + parts = ext_suffix.split(".") + if len(parts) < 3: + # CPython3.7 and earlier uses ".pyd" on Windows. + return _cpython_abis(sys.version_info[:2]) + soabi = parts[1] + if soabi.startswith("cpython"): + # non-windows + abi = "cp" + soabi.split("-")[1] + elif soabi.startswith("cp"): + # windows + abi = soabi.split("-")[0] + elif soabi.startswith("pypy"): + abi = "-".join(soabi.split("-")[:2]) + elif soabi.startswith("graalpy"): + abi = "-".join(soabi.split("-")[:3]) + elif soabi: + # pyston, ironpython, others? + abi = soabi + else: + return [] + return [_normalize_string(abi)] def generic_tags( @@ -251,8 +287,9 @@ def generic_tags( interpreter = "".join([interp_name, interp_version]) if abis is None: abis = _generic_abi() + else: + abis = list(abis) platforms = list(platforms or platform_tags()) - abis = list(abis) if "none" not in abis: abis.append("none") for abi in abis: @@ -268,11 +305,11 @@ def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]: all previous versions of that major version. """ if len(py_version) > 1: - yield "py{version}".format(version=_version_nodot(py_version[:2])) - yield "py{major}".format(major=py_version[0]) + yield f"py{_version_nodot(py_version[:2])}" + yield f"py{py_version[0]}" if len(py_version) > 1: for minor in range(py_version[1] - 1, -1, -1): - yield "py{version}".format(version=_version_nodot((py_version[0], minor))) + yield f"py{_version_nodot((py_version[0], minor))}" def compatible_tags( @@ -356,6 +393,22 @@ def mac_platforms( version_str, _, cpu_arch = platform.mac_ver() if version is None: version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2]))) + if version == (10, 16): + # When built against an older macOS SDK, Python will report macOS 10.16 + # instead of the real version. + version_str = subprocess.run( + [ + sys.executable, + "-sS", + "-c", + "import platform; print(platform.mac_ver()[0])", + ], + check=True, + env={"SYSTEM_VERSION_COMPAT": "0"}, + stdout=subprocess.PIPE, + universal_newlines=True, + ).stdout + version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2]))) else: version = version if arch is None: @@ -446,6 +499,9 @@ def platform_tags() -> Iterator[str]: def interpreter_name() -> str: """ Returns the name of the running interpreter. + + Some implementations have a reserved, two-letter abbreviation which will + be returned when appropriate. """ name = sys.implementation.name return INTERPRETER_SHORT_NAMES.get(name) or name @@ -481,4 +537,10 @@ def sys_tags(*, warn: bool = False) -> Iterator[Tag]: else: yield from generic_tags() - yield from compatible_tags() + if interp_name == "pp": + interp = "pp3" + elif interp_name == "cp": + interp = "cp" + interpreter_version(warn=warn) + else: + interp = None + yield from compatible_tags(interpreter=interp) diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/utils.py b/uno/lib/python/pkg_resources/_vendor/packaging/utils.py index bab11b80..33c613b7 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/utils.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/utils.py @@ -35,7 +35,9 @@ def canonicalize_name(name: str) -> NormalizedName: return cast(NormalizedName, value) -def canonicalize_version(version: Union[Version, str]) -> str: +def canonicalize_version( + version: Union[Version, str], *, strip_trailing_zero: bool = True +) -> str: """ This is very similar to Version.__str__, but has one subtle difference with the way it handles the release segment. @@ -56,8 +58,11 @@ def canonicalize_version(version: Union[Version, str]) -> str: parts.append(f"{parsed.epoch}!") # Release segment - # NB: This strips trailing '.0's to normalize - parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in parsed.release))) + release_segment = ".".join(str(x) for x in parsed.release) + if strip_trailing_zero: + # NB: This strips trailing '.0's to normalize + release_segment = re.sub(r"(\.0)+$", "", release_segment) + parts.append(release_segment) # Pre-release if parsed.pre is not None: diff --git a/uno/lib/python/pkg_resources/_vendor/packaging/version.py b/uno/lib/python/pkg_resources/_vendor/packaging/version.py index de9a09a4..b30e8cbf 100644 --- a/uno/lib/python/pkg_resources/_vendor/packaging/version.py +++ b/uno/lib/python/pkg_resources/_vendor/packaging/version.py @@ -1,16 +1,20 @@ # This file is dual licensed under the terms of the Apache License, Version # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +""" +.. testsetup:: + + from packaging.version import parse, Version +""" import collections import itertools import re -import warnings -from typing import Callable, Iterator, List, Optional, SupportsInt, Tuple, Union +from typing import Any, Callable, Optional, SupportsInt, Tuple, Union from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType -__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] +__all__ = ["VERSION_PATTERN", "parse", "Version", "InvalidVersion"] InfiniteTypes = Union[InfinityType, NegativeInfinityType] PrePostDevType = Union[InfiniteTypes, Tuple[str, int]] @@ -29,36 +33,37 @@ CmpKey = Tuple[ int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType ] -LegacyCmpKey = Tuple[int, Tuple[str, ...]] -VersionComparisonMethod = Callable[ - [Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool -] +VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] _Version = collections.namedtuple( "_Version", ["epoch", "release", "dev", "pre", "post", "local"] ) -def parse(version: str) -> Union["LegacyVersion", "Version"]: - """ - Parse the given version string and return either a :class:`Version` object - or a :class:`LegacyVersion` object depending on if the given version is - a valid PEP 440 version or a legacy version. +def parse(version: str) -> "Version": + """Parse the given version string. + + >>> parse('1.0.dev1') + + + :param version: The version string to parse. + :raises InvalidVersion: When the version string is not a valid version. """ - try: - return Version(version) - except InvalidVersion: - return LegacyVersion(version) + return Version(version) class InvalidVersion(ValueError): - """ - An invalid version was found, users should refer to PEP 440. + """Raised when a version string is not a valid version. + + >>> Version("invalid") + Traceback (most recent call last): + ... + packaging.version.InvalidVersion: Invalid version: 'invalid' """ class _BaseVersion: - _key: Union[CmpKey, LegacyCmpKey] + _key: Tuple[Any, ...] def __hash__(self) -> int: return hash(self._key) @@ -103,126 +108,9 @@ def __ne__(self, other: object) -> bool: return self._key != other._key -class LegacyVersion(_BaseVersion): - def __init__(self, version: str) -> None: - self._version = str(version) - self._key = _legacy_cmpkey(self._version) - - warnings.warn( - "Creating a LegacyVersion has been deprecated and will be " - "removed in the next major release", - DeprecationWarning, - ) - - def __str__(self) -> str: - return self._version - - def __repr__(self) -> str: - return f"" - - @property - def public(self) -> str: - return self._version - - @property - def base_version(self) -> str: - return self._version - - @property - def epoch(self) -> int: - return -1 - - @property - def release(self) -> None: - return None - - @property - def pre(self) -> None: - return None - - @property - def post(self) -> None: - return None - - @property - def dev(self) -> None: - return None - - @property - def local(self) -> None: - return None - - @property - def is_prerelease(self) -> bool: - return False - - @property - def is_postrelease(self) -> bool: - return False - - @property - def is_devrelease(self) -> bool: - return False - - -_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) - -_legacy_version_replacement_map = { - "pre": "c", - "preview": "c", - "-": "final-", - "rc": "c", - "dev": "@", -} - - -def _parse_version_parts(s: str) -> Iterator[str]: - for part in _legacy_version_component_re.split(s): - part = _legacy_version_replacement_map.get(part, part) - - if not part or part == ".": - continue - - if part[:1] in "0123456789": - # pad for numeric comparison - yield part.zfill(8) - else: - yield "*" + part - - # ensure that alpha/beta/candidate are before final - yield "*final" - - -def _legacy_cmpkey(version: str) -> LegacyCmpKey: - - # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch - # greater than or equal to 0. This will effectively put the LegacyVersion, - # which uses the defacto standard originally implemented by setuptools, - # as before all PEP 440 versions. - epoch = -1 - - # This scheme is taken from pkg_resources.parse_version setuptools prior to - # it's adoption of the packaging library. - parts: List[str] = [] - for part in _parse_version_parts(version.lower()): - if part.startswith("*"): - # remove "-" before a prerelease tag - if part < "*final": - while parts and parts[-1] == "*final-": - parts.pop() - - # remove trailing zeros from each series of numeric parts - while parts and parts[-1] == "00000000": - parts.pop() - - parts.append(part) - - return epoch, tuple(parts) - - # Deliberately not anchored to the start and end of the string, to make it # easier for 3rd party code to reuse -VERSION_PATTERN = r""" +_VERSION_PATTERN = r""" v? (?: (?:(?P[0-9]+)!)? # epoch @@ -253,12 +141,56 @@ def _legacy_cmpkey(version: str) -> LegacyCmpKey: (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version """ +VERSION_PATTERN = _VERSION_PATTERN +""" +A string containing the regular expression used to match a valid version. + +The pattern is not anchored at either end, and is intended for embedding in larger +expressions (for example, matching a version number as part of a file name). The +regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE`` +flags set. + +:meta hide-value: +""" + class Version(_BaseVersion): + """This class abstracts handling of a project's versions. + + A :class:`Version` instance is comparison aware and can be compared and + sorted using the standard Python interfaces. + + >>> v1 = Version("1.0a5") + >>> v2 = Version("1.0") + >>> v1 + + >>> v2 + + >>> v1 < v2 + True + >>> v1 == v2 + False + >>> v1 > v2 + False + >>> v1 >= v2 + False + >>> v1 <= v2 + True + """ _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) + _key: CmpKey def __init__(self, version: str) -> None: + """Initialize a Version object. + + :param version: + The string representation of a version which will be parsed and normalized + before use. + :raises InvalidVersion: + If the ``version`` does not conform to PEP 440 in any way then this + exception will be raised. + """ # Validate the version and parse it into pieces match = self._regex.search(version) @@ -288,9 +220,19 @@ def __init__(self, version: str) -> None: ) def __repr__(self) -> str: + """A representation of the Version that shows all internal state. + + >>> Version('1.0.0') + + """ return f"" def __str__(self) -> str: + """A string representation of the version that can be rounded-tripped. + + >>> str(Version("1.0a5")) + '1.0a5' + """ parts = [] # Epoch @@ -320,29 +262,80 @@ def __str__(self) -> str: @property def epoch(self) -> int: + """The epoch of the version. + + >>> Version("2.0.0").epoch + 0 + >>> Version("1!2.0.0").epoch + 1 + """ _epoch: int = self._version.epoch return _epoch @property def release(self) -> Tuple[int, ...]: + """The components of the "release" segment of the version. + + >>> Version("1.2.3").release + (1, 2, 3) + >>> Version("2.0.0").release + (2, 0, 0) + >>> Version("1!2.0.0.post0").release + (2, 0, 0) + + Includes trailing zeroes but not the epoch or any pre-release / development / + post-release suffixes. + """ _release: Tuple[int, ...] = self._version.release return _release @property def pre(self) -> Optional[Tuple[str, int]]: + """The pre-release segment of the version. + + >>> print(Version("1.2.3").pre) + None + >>> Version("1.2.3a1").pre + ('a', 1) + >>> Version("1.2.3b1").pre + ('b', 1) + >>> Version("1.2.3rc1").pre + ('rc', 1) + """ _pre: Optional[Tuple[str, int]] = self._version.pre return _pre @property def post(self) -> Optional[int]: + """The post-release number of the version. + + >>> print(Version("1.2.3").post) + None + >>> Version("1.2.3.post1").post + 1 + """ return self._version.post[1] if self._version.post else None @property def dev(self) -> Optional[int]: + """The development number of the version. + + >>> print(Version("1.2.3").dev) + None + >>> Version("1.2.3.dev1").dev + 1 + """ return self._version.dev[1] if self._version.dev else None @property def local(self) -> Optional[str]: + """The local version segment of the version. + + >>> print(Version("1.2.3").local) + None + >>> Version("1.2.3+abc").local + 'abc' + """ if self._version.local: return ".".join(str(x) for x in self._version.local) else: @@ -350,10 +343,31 @@ def local(self) -> Optional[str]: @property def public(self) -> str: + """The public portion of the version. + + >>> Version("1.2.3").public + '1.2.3' + >>> Version("1.2.3+abc").public + '1.2.3' + >>> Version("1.2.3+abc.dev1").public + '1.2.3' + """ return str(self).split("+", 1)[0] @property def base_version(self) -> str: + """The "base version" of the version. + + >>> Version("1.2.3").base_version + '1.2.3' + >>> Version("1.2.3+abc").base_version + '1.2.3' + >>> Version("1!1.2.3+abc.dev1").base_version + '1!1.2.3' + + The "base version" is the public version of the project without any pre or post + release markers. + """ parts = [] # Epoch @@ -367,26 +381,72 @@ def base_version(self) -> str: @property def is_prerelease(self) -> bool: + """Whether this version is a pre-release. + + >>> Version("1.2.3").is_prerelease + False + >>> Version("1.2.3a1").is_prerelease + True + >>> Version("1.2.3b1").is_prerelease + True + >>> Version("1.2.3rc1").is_prerelease + True + >>> Version("1.2.3dev1").is_prerelease + True + """ return self.dev is not None or self.pre is not None @property def is_postrelease(self) -> bool: + """Whether this version is a post-release. + + >>> Version("1.2.3").is_postrelease + False + >>> Version("1.2.3.post1").is_postrelease + True + """ return self.post is not None @property def is_devrelease(self) -> bool: + """Whether this version is a development release. + + >>> Version("1.2.3").is_devrelease + False + >>> Version("1.2.3.dev1").is_devrelease + True + """ return self.dev is not None @property def major(self) -> int: + """The first item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").major + 1 + """ return self.release[0] if len(self.release) >= 1 else 0 @property def minor(self) -> int: + """The second item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").minor + 2 + >>> Version("1").minor + 0 + """ return self.release[1] if len(self.release) >= 2 else 0 @property def micro(self) -> int: + """The third item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").micro + 3 + >>> Version("1").micro + 0 + """ return self.release[2] if len(self.release) >= 3 else 0 diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/__init__.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/__init__.py new file mode 100644 index 00000000..aef2821b --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/__init__.py @@ -0,0 +1,342 @@ +""" +Utilities for determining application-specific dirs. See for details and +usage. +""" +from __future__ import annotations + +import os +import sys +from pathlib import Path + +if sys.version_info >= (3, 8): # pragma: no cover (py38+) + from typing import Literal +else: # pragma: no cover (py38+) + from ..typing_extensions import Literal + +from .api import PlatformDirsABC +from .version import __version__ +from .version import __version_tuple__ as __version_info__ + + +def _set_platform_dir_class() -> type[PlatformDirsABC]: + if sys.platform == "win32": + from .windows import Windows as Result + elif sys.platform == "darwin": + from .macos import MacOS as Result + else: + from .unix import Unix as Result + + if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system": + + if os.getenv("SHELL") or os.getenv("PREFIX"): + return Result + + from .android import _android_folder + + if _android_folder() is not None: + from .android import Android + + return Android # return to avoid redefinition of result + + return Result + + +PlatformDirs = _set_platform_dir_class() #: Currently active platform +AppDirs = PlatformDirs #: Backwards compatibility with appdirs + + +def user_data_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: data directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_data_dir + + +def site_data_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + multipath: bool = False, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param multipath: See `roaming `. + :returns: data directory shared by users + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_data_dir + + +def user_config_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: config directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_config_dir + + +def site_config_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + multipath: bool = False, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param multipath: See `roaming `. + :returns: config directory shared by the users + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_config_dir + + +def user_cache_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `roaming `. + :returns: cache directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_cache_dir + + +def user_state_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: state directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_state_dir + + +def user_log_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `roaming `. + :returns: log directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_dir + + +def user_documents_dir() -> str: + """ + :returns: documents directory tied to the user + """ + return PlatformDirs().user_documents_dir + + +def user_runtime_dir( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> str: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `opinion `. + :returns: runtime directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_dir + + +def user_data_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: data path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_data_path + + +def site_data_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + multipath: bool = False, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param multipath: See `multipath `. + :returns: data path shared by users + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_data_path + + +def user_config_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: config path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_config_path + + +def site_config_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + multipath: bool = False, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param multipath: See `roaming `. + :returns: config path shared by the users + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_config_path + + +def user_cache_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `roaming `. + :returns: cache path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_cache_path + + +def user_state_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param roaming: See `roaming `. + :returns: state path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_state_path + + +def user_log_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `roaming `. + :returns: log path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_path + + +def user_documents_path() -> Path: + """ + :returns: documents path tied to the user + """ + return PlatformDirs().user_documents_path + + +def user_runtime_path( + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + opinion: bool = True, +) -> Path: + """ + :param appname: See `appname `. + :param appauthor: See `appauthor `. + :param version: See `version `. + :param opinion: See `opinion `. + :returns: runtime path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_path + + +__all__ = [ + "__version__", + "__version_info__", + "PlatformDirs", + "AppDirs", + "PlatformDirsABC", + "user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "user_documents_dir", + "user_runtime_dir", + "site_data_dir", + "site_config_dir", + "user_data_path", + "user_config_path", + "user_cache_path", + "user_state_path", + "user_log_path", + "user_documents_path", + "user_runtime_path", + "site_data_path", + "site_config_path", +] diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/__main__.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/__main__.py new file mode 100644 index 00000000..0fc1edd5 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/__main__.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from platformdirs import PlatformDirs, __version__ + +PROPS = ( + "user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "user_documents_dir", + "user_runtime_dir", + "site_data_dir", + "site_config_dir", +) + + +def main() -> None: + app_name = "MyApp" + app_author = "MyCompany" + + print(f"-- platformdirs {__version__} --") + + print("-- app dirs (with optional 'version')") + dirs = PlatformDirs(app_name, app_author, version="1.0") + for prop in PROPS: + print(f"{prop}: {getattr(dirs, prop)}") + + print("\n-- app dirs (without optional 'version')") + dirs = PlatformDirs(app_name, app_author) + for prop in PROPS: + print(f"{prop}: {getattr(dirs, prop)}") + + print("\n-- app dirs (without optional 'appauthor')") + dirs = PlatformDirs(app_name) + for prop in PROPS: + print(f"{prop}: {getattr(dirs, prop)}") + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = PlatformDirs(app_name, appauthor=False) + for prop in PROPS: + print(f"{prop}: {getattr(dirs, prop)}") + + +if __name__ == "__main__": + main() diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/android.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/android.py new file mode 100644 index 00000000..eda80935 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/android.py @@ -0,0 +1,120 @@ +from __future__ import annotations + +import os +import re +import sys +from functools import lru_cache +from typing import cast + +from .api import PlatformDirsABC + + +class Android(PlatformDirsABC): + """ + Follows the guidance `from here `_. Makes use of the + `appname ` and + `version `. + """ + + @property + def user_data_dir(self) -> str: + """:return: data directory tied to the user, e.g. ``/data/user///files/``""" + return self._append_app_name_and_version(cast(str, _android_folder()), "files") + + @property + def site_data_dir(self) -> str: + """:return: data directory shared by users, same as `user_data_dir`""" + return self.user_data_dir + + @property + def user_config_dir(self) -> str: + """ + :return: config directory tied to the user, e.g. ``/data/user///shared_prefs/`` + """ + return self._append_app_name_and_version(cast(str, _android_folder()), "shared_prefs") + + @property + def site_config_dir(self) -> str: + """:return: config directory shared by the users, same as `user_config_dir`""" + return self.user_config_dir + + @property + def user_cache_dir(self) -> str: + """:return: cache directory tied to the user, e.g. e.g. ``/data/user///cache/``""" + return self._append_app_name_and_version(cast(str, _android_folder()), "cache") + + @property + def user_state_dir(self) -> str: + """:return: state directory tied to the user, same as `user_data_dir`""" + return self.user_data_dir + + @property + def user_log_dir(self) -> str: + """ + :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it, + e.g. ``/data/user///cache//log`` + """ + path = self.user_cache_dir + if self.opinion: + path = os.path.join(path, "log") + return path + + @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents`` + """ + return _android_documents_folder() + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it, + e.g. ``/data/user///cache//tmp`` + """ + path = self.user_cache_dir + if self.opinion: + path = os.path.join(path, "tmp") + return path + + +@lru_cache(maxsize=1) +def _android_folder() -> str | None: + """:return: base folder for the Android OS or None if cannot be found""" + try: + # First try to get path to android app via pyjnius + from jnius import autoclass + + Context = autoclass("android.content.Context") # noqa: N806 + result: str | None = Context.getFilesDir().getParentFile().getAbsolutePath() + except Exception: + # if fails find an android folder looking path on the sys.path + pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files") + for path in sys.path: + if pattern.match(path): + result = path.split("/files")[0] + break + else: + result = None + return result + + +@lru_cache(maxsize=1) +def _android_documents_folder() -> str: + """:return: documents folder for the Android OS""" + # Get directories with pyjnius + try: + from jnius import autoclass + + Context = autoclass("android.content.Context") # noqa: N806 + Environment = autoclass("android.os.Environment") # noqa: N806 + documents_dir: str = Context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + except Exception: + documents_dir = "/storage/emulated/0/Documents" + + return documents_dir + + +__all__ = [ + "Android", +] diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/api.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/api.py new file mode 100644 index 00000000..6f6e2c2c --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/api.py @@ -0,0 +1,156 @@ +from __future__ import annotations + +import os +import sys +from abc import ABC, abstractmethod +from pathlib import Path + +if sys.version_info >= (3, 8): # pragma: no branch + from typing import Literal # pragma: no cover + + +class PlatformDirsABC(ABC): + """ + Abstract base class for platform directories. + """ + + def __init__( + self, + appname: str | None = None, + appauthor: str | None | Literal[False] = None, + version: str | None = None, + roaming: bool = False, + multipath: bool = False, + opinion: bool = True, + ): + """ + Create a new platform directory. + + :param appname: See `appname`. + :param appauthor: See `appauthor`. + :param version: See `version`. + :param roaming: See `roaming`. + :param multipath: See `multipath`. + :param opinion: See `opinion`. + """ + self.appname = appname #: The name of application. + self.appauthor = appauthor + """ + The name of the app author or distributing body for this application. Typically, it is the owning company name. + Defaults to `appname`. You may pass ``False`` to disable it. + """ + self.version = version + """ + An optional version path element to append to the path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this would typically be ``.``. + """ + self.roaming = roaming + """ + Whether to use the roaming appdata directory on Windows. That means that for users on a Windows network setup + for roaming profiles, this user data will be synced on login (see + `here `_). + """ + self.multipath = multipath + """ + An optional parameter only applicable to Unix/Linux which indicates that the entire list of data dirs should be + returned. By default, the first item would only be returned. + """ + self.opinion = opinion #: A flag to indicating to use opinionated values. + + def _append_app_name_and_version(self, *base: str) -> str: + params = list(base[1:]) + if self.appname: + params.append(self.appname) + if self.version: + params.append(self.version) + return os.path.join(base[0], *params) + + @property + @abstractmethod + def user_data_dir(self) -> str: + """:return: data directory tied to the user""" + + @property + @abstractmethod + def site_data_dir(self) -> str: + """:return: data directory shared by users""" + + @property + @abstractmethod + def user_config_dir(self) -> str: + """:return: config directory tied to the user""" + + @property + @abstractmethod + def site_config_dir(self) -> str: + """:return: config directory shared by the users""" + + @property + @abstractmethod + def user_cache_dir(self) -> str: + """:return: cache directory tied to the user""" + + @property + @abstractmethod + def user_state_dir(self) -> str: + """:return: state directory tied to the user""" + + @property + @abstractmethod + def user_log_dir(self) -> str: + """:return: log directory tied to the user""" + + @property + @abstractmethod + def user_documents_dir(self) -> str: + """:return: documents directory tied to the user""" + + @property + @abstractmethod + def user_runtime_dir(self) -> str: + """:return: runtime directory tied to the user""" + + @property + def user_data_path(self) -> Path: + """:return: data path tied to the user""" + return Path(self.user_data_dir) + + @property + def site_data_path(self) -> Path: + """:return: data path shared by users""" + return Path(self.site_data_dir) + + @property + def user_config_path(self) -> Path: + """:return: config path tied to the user""" + return Path(self.user_config_dir) + + @property + def site_config_path(self) -> Path: + """:return: config path shared by the users""" + return Path(self.site_config_dir) + + @property + def user_cache_path(self) -> Path: + """:return: cache path tied to the user""" + return Path(self.user_cache_dir) + + @property + def user_state_path(self) -> Path: + """:return: state path tied to the user""" + return Path(self.user_state_dir) + + @property + def user_log_path(self) -> Path: + """:return: log path tied to the user""" + return Path(self.user_log_dir) + + @property + def user_documents_path(self) -> Path: + """:return: documents path tied to the user""" + return Path(self.user_documents_dir) + + @property + def user_runtime_path(self) -> Path: + """:return: runtime path tied to the user""" + return Path(self.user_runtime_dir) diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/macos.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/macos.py new file mode 100644 index 00000000..a01337c7 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/macos.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +import os + +from .api import PlatformDirsABC + + +class MacOS(PlatformDirsABC): + """ + Platform directories for the macOS operating system. Follows the guidance from `Apple documentation + `_. + Makes use of the `appname ` and + `version `. + """ + + @property + def user_data_dir(self) -> str: + """:return: data directory tied to the user, e.g. ``~/Library/Application Support/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Application Support/")) + + @property + def site_data_dir(self) -> str: + """:return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``""" + return self._append_app_name_and_version("/Library/Application Support") + + @property + def user_config_dir(self) -> str: + """:return: config directory tied to the user, e.g. ``~/Library/Preferences/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Preferences/")) + + @property + def site_config_dir(self) -> str: + """:return: config directory shared by the users, e.g. ``/Library/Preferences/$appname``""" + return self._append_app_name_and_version("/Library/Preferences") + + @property + def user_cache_dir(self) -> str: + """:return: cache directory tied to the user, e.g. ``~/Library/Caches/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches")) + + @property + def user_state_dir(self) -> str: + """:return: state directory tied to the user, same as `user_data_dir`""" + return self.user_data_dir + + @property + def user_log_dir(self) -> str: + """:return: log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Logs")) + + @property + def user_documents_dir(self) -> str: + """:return: documents directory tied to the user, e.g. ``~/Documents``""" + return os.path.expanduser("~/Documents") + + @property + def user_runtime_dir(self) -> str: + """:return: runtime directory tied to the user, e.g. ``~/Library/Caches/TemporaryItems/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches/TemporaryItems")) + + +__all__ = [ + "MacOS", +] diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/py.typed b/uno/lib/python/pkg_resources/_vendor/platformdirs/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/unix.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/unix.py new file mode 100644 index 00000000..9aca5a03 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/unix.py @@ -0,0 +1,181 @@ +from __future__ import annotations + +import os +import sys +from configparser import ConfigParser +from pathlib import Path + +from .api import PlatformDirsABC + +if sys.platform.startswith("linux"): # pragma: no branch # no op check, only to please the type checker + from os import getuid +else: + + def getuid() -> int: + raise RuntimeError("should only be used on Linux") + + +class Unix(PlatformDirsABC): + """ + On Unix/Linux, we follow the + `XDG Basedir Spec `_. The spec allows + overriding directories with environment variables. The examples show are the default values, alongside the name of + the environment variable that overrides them. Makes use of the + `appname `, + `version `, + `multipath `, + `opinion `. + """ + + @property + def user_data_dir(self) -> str: + """ + :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or + ``$XDG_DATA_HOME/$appname/$version`` + """ + path = os.environ.get("XDG_DATA_HOME", "") + if not path.strip(): + path = os.path.expanduser("~/.local/share") + return self._append_app_name_and_version(path) + + @property + def site_data_dir(self) -> str: + """ + :return: data directories shared by users (if `multipath ` is + enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS + path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` + """ + # XDG default for $XDG_DATA_DIRS; only first, if multipath is False + path = os.environ.get("XDG_DATA_DIRS", "") + if not path.strip(): + path = f"/usr/local/share{os.pathsep}/usr/share" + return self._with_multi_path(path) + + def _with_multi_path(self, path: str) -> str: + path_list = path.split(os.pathsep) + if not self.multipath: + path_list = path_list[0:1] + path_list = [self._append_app_name_and_version(os.path.expanduser(p)) for p in path_list] + return os.pathsep.join(path_list) + + @property + def user_config_dir(self) -> str: + """ + :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or + ``$XDG_CONFIG_HOME/$appname/$version`` + """ + path = os.environ.get("XDG_CONFIG_HOME", "") + if not path.strip(): + path = os.path.expanduser("~/.config") + return self._append_app_name_and_version(path) + + @property + def site_config_dir(self) -> str: + """ + :return: config directories shared by users (if `multipath ` + is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS + path separator), e.g. ``/etc/xdg/$appname/$version`` + """ + # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False + path = os.environ.get("XDG_CONFIG_DIRS", "") + if not path.strip(): + path = "/etc/xdg" + return self._with_multi_path(path) + + @property + def user_cache_dir(self) -> str: + """ + :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or + ``~/$XDG_CACHE_HOME/$appname/$version`` + """ + path = os.environ.get("XDG_CACHE_HOME", "") + if not path.strip(): + path = os.path.expanduser("~/.cache") + return self._append_app_name_and_version(path) + + @property + def user_state_dir(self) -> str: + """ + :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or + ``$XDG_STATE_HOME/$appname/$version`` + """ + path = os.environ.get("XDG_STATE_HOME", "") + if not path.strip(): + path = os.path.expanduser("~/.local/state") + return self._append_app_name_and_version(path) + + @property + def user_log_dir(self) -> str: + """ + :return: log directory tied to the user, same as `user_state_dir` if not opinionated else ``log`` in it + """ + path = self.user_state_dir + if self.opinion: + path = os.path.join(path, "log") + return path + + @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user, e.g. ``~/Documents`` + """ + documents_dir = _get_user_dirs_folder("XDG_DOCUMENTS_DIR") + if documents_dir is None: + documents_dir = os.environ.get("XDG_DOCUMENTS_DIR", "").strip() + if not documents_dir: + documents_dir = os.path.expanduser("~/Documents") + + return documents_dir + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or + ``$XDG_RUNTIME_DIR/$appname/$version`` + """ + path = os.environ.get("XDG_RUNTIME_DIR", "") + if not path.strip(): + path = f"/run/user/{getuid()}" + return self._append_app_name_and_version(path) + + @property + def site_data_path(self) -> Path: + """:return: data path shared by users. Only return first item, even if ``multipath`` is set to ``True``""" + return self._first_item_as_path_if_multipath(self.site_data_dir) + + @property + def site_config_path(self) -> Path: + """:return: config path shared by the users. Only return first item, even if ``multipath`` is set to ``True``""" + return self._first_item_as_path_if_multipath(self.site_config_dir) + + def _first_item_as_path_if_multipath(self, directory: str) -> Path: + if self.multipath: + # If multipath is True, the first path is returned. + directory = directory.split(os.pathsep)[0] + return Path(directory) + + +def _get_user_dirs_folder(key: str) -> str | None: + """Return directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/""" + user_dirs_config_path = os.path.join(Unix().user_config_dir, "user-dirs.dirs") + if os.path.exists(user_dirs_config_path): + parser = ConfigParser() + + with open(user_dirs_config_path) as stream: + # Add fake section header, so ConfigParser doesn't complain + parser.read_string(f"[top]\n{stream.read()}") + + if key not in parser["top"]: + return None + + path = parser["top"][key].strip('"') + # Handle relative home paths + path = path.replace("$HOME", os.path.expanduser("~")) + return path + + return None + + +__all__ = [ + "Unix", +] diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/version.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/version.py new file mode 100644 index 00000000..9f6eb98e --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/version.py @@ -0,0 +1,4 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +__version__ = version = '2.6.2' +__version_tuple__ = version_tuple = (2, 6, 2) diff --git a/uno/lib/python/pkg_resources/_vendor/platformdirs/windows.py b/uno/lib/python/pkg_resources/_vendor/platformdirs/windows.py new file mode 100644 index 00000000..d5c27b34 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/platformdirs/windows.py @@ -0,0 +1,184 @@ +from __future__ import annotations + +import ctypes +import os +import sys +from functools import lru_cache +from typing import Callable + +from .api import PlatformDirsABC + + +class Windows(PlatformDirsABC): + """`MSDN on where to store app data files + `_. + Makes use of the + `appname `, + `appauthor `, + `version `, + `roaming `, + `opinion `.""" + + @property + def user_data_dir(self) -> str: + """ + :return: data directory tied to the user, e.g. + ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname`` (not roaming) or + ``%USERPROFILE%\\AppData\\Roaming\\$appauthor\\$appname`` (roaming) + """ + const = "CSIDL_APPDATA" if self.roaming else "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(get_win_folder(const)) + return self._append_parts(path) + + def _append_parts(self, path: str, *, opinion_value: str | None = None) -> str: + params = [] + if self.appname: + if self.appauthor is not False: + author = self.appauthor or self.appname + params.append(author) + params.append(self.appname) + if opinion_value is not None and self.opinion: + params.append(opinion_value) + if self.version: + params.append(self.version) + return os.path.join(path, *params) + + @property + def site_data_dir(self) -> str: + """:return: data directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname``""" + path = os.path.normpath(get_win_folder("CSIDL_COMMON_APPDATA")) + return self._append_parts(path) + + @property + def user_config_dir(self) -> str: + """:return: config directory tied to the user, same as `user_data_dir`""" + return self.user_data_dir + + @property + def site_config_dir(self) -> str: + """:return: config directory shared by the users, same as `site_data_dir`""" + return self.site_data_dir + + @property + def user_cache_dir(self) -> str: + """ + :return: cache directory tied to the user (if opinionated with ``Cache`` folder within ``$appname``) e.g. + ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname\\Cache\\$version`` + """ + path = os.path.normpath(get_win_folder("CSIDL_LOCAL_APPDATA")) + return self._append_parts(path, opinion_value="Cache") + + @property + def user_state_dir(self) -> str: + """:return: state directory tied to the user, same as `user_data_dir`""" + return self.user_data_dir + + @property + def user_log_dir(self) -> str: + """ + :return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``Logs`` in it + """ + path = self.user_data_dir + if self.opinion: + path = os.path.join(path, "Logs") + return path + + @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user e.g. ``%USERPROFILE%\\Documents`` + """ + return os.path.normpath(get_win_folder("CSIDL_PERSONAL")) + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, e.g. + ``%USERPROFILE%\\AppData\\Local\\Temp\\$appauthor\\$appname`` + """ + path = os.path.normpath(os.path.join(get_win_folder("CSIDL_LOCAL_APPDATA"), "Temp")) + return self._append_parts(path) + + +def get_win_folder_from_env_vars(csidl_name: str) -> str: + """Get folder from environment variables.""" + if csidl_name == "CSIDL_PERSONAL": # does not have an environment name + return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Documents") + + env_var_name = { + "CSIDL_APPDATA": "APPDATA", + "CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE", + "CSIDL_LOCAL_APPDATA": "LOCALAPPDATA", + }.get(csidl_name) + if env_var_name is None: + raise ValueError(f"Unknown CSIDL name: {csidl_name}") + result = os.environ.get(env_var_name) + if result is None: + raise ValueError(f"Unset environment variable: {env_var_name}") + return result + + +def get_win_folder_from_registry(csidl_name: str) -> str: + """Get folder from the registry. + + This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + "CSIDL_PERSONAL": "Personal", + }.get(csidl_name) + if shell_folder_name is None: + raise ValueError(f"Unknown CSIDL name: {csidl_name}") + if sys.platform != "win32": # only needed for mypy type checker to know that this code runs only on Windows + raise NotImplementedError + import winreg + + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") + directory, _ = winreg.QueryValueEx(key, shell_folder_name) + return str(directory) + + +def get_win_folder_via_ctypes(csidl_name: str) -> str: + """Get folder with ctypes.""" + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + "CSIDL_PERSONAL": 5, + }.get(csidl_name) + if csidl_const is None: + raise ValueError(f"Unknown CSIDL name: {csidl_name}") + + buf = ctypes.create_unicode_buffer(1024) + windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker + windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if it has highbit chars. + if any(ord(c) > 255 for c in buf): + buf2 = ctypes.create_unicode_buffer(1024) + if windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + + +def _pick_get_win_folder() -> Callable[[str], str]: + if hasattr(ctypes, "windll"): + return get_win_folder_via_ctypes + try: + import winreg # noqa: F401 + except ImportError: + return get_win_folder_from_env_vars + else: + return get_win_folder_from_registry + + +get_win_folder = lru_cache(maxsize=None)(_pick_get_win_folder()) + +__all__ = [ + "Windows", +] diff --git a/uno/lib/python/pkg_resources/_vendor/pyparsing.py b/uno/lib/python/pkg_resources/_vendor/pyparsing.py deleted file mode 100644 index cf75e1e5..00000000 --- a/uno/lib/python/pkg_resources/_vendor/pyparsing.py +++ /dev/null @@ -1,5742 +0,0 @@ -# module pyparsing.py -# -# Copyright (c) 2003-2018 Paul T. McGuire -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__doc__ = \ -""" -pyparsing module - Classes and methods to define and execute parsing grammars -============================================================================= - -The pyparsing module is an alternative approach to creating and executing simple grammars, -vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you -don't need to learn a new syntax for defining grammars or matching expressions - the parsing module -provides a library of classes that you use to construct the grammar directly in Python. - -Here is a program to parse "Hello, World!" (or any greeting of the form -C{", !"}), built up using L{Word}, L{Literal}, and L{And} elements -(L{'+'} operator gives L{And} expressions, strings are auto-converted to -L{Literal} expressions):: - - from pyparsing import Word, alphas - - # define grammar of a greeting - greet = Word(alphas) + "," + Word(alphas) + "!" - - hello = "Hello, World!" - print (hello, "->", greet.parseString(hello)) - -The program outputs the following:: - - Hello, World! -> ['Hello', ',', 'World', '!'] - -The Python representation of the grammar is quite readable, owing to the self-explanatory -class names, and the use of '+', '|' and '^' operators. - -The L{ParseResults} object returned from L{ParserElement.parseString} can be accessed as a nested list, a dictionary, or an -object with named attributes. - -The pyparsing module handles some of the problems that are typically vexing when writing text parsers: - - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) - - quoted strings - - embedded comments - - -Getting Started - ------------------ -Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing -classes inherit from. Use the docstrings for examples of how to: - - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes - - construct character word-group expressions using the L{Word} class - - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes - - use L{'+'}, L{'|'}, L{'^'}, and L{'&'} operators to combine simple expressions into more complex ones - - associate names with your parsed results using L{ParserElement.setResultsName} - - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} - - find more useful common expressions in the L{pyparsing_common} namespace class -""" - -__version__ = "2.2.1" -__versionTime__ = "18 Sep 2018 00:49 UTC" -__author__ = "Paul McGuire " - -import string -from weakref import ref as wkref -import copy -import sys -import warnings -import re -import sre_constants -import collections -import pprint -import traceback -import types -from datetime import datetime - -try: - from _thread import RLock -except ImportError: - from threading import RLock - -try: - # Python 3 - from collections.abc import Iterable - from collections.abc import MutableMapping -except ImportError: - # Python 2.7 - from collections import Iterable - from collections import MutableMapping - -try: - from collections import OrderedDict as _OrderedDict -except ImportError: - try: - from ordereddict import OrderedDict as _OrderedDict - except ImportError: - _OrderedDict = None - -#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) - -__all__ = [ -'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', -'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', -'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', -'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', -'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', -'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', -'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', -'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', -'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', -'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', -'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', -'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', -'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', -'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', -'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', -'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', -'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', -'CloseMatch', 'tokenMap', 'pyparsing_common', -] - -system_version = tuple(sys.version_info)[:3] -PY_3 = system_version[0] == 3 -if PY_3: - _MAX_INT = sys.maxsize - basestring = str - unichr = chr - _ustr = str - - # build list of single arg builtins, that can be used as parse actions - singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] - -else: - _MAX_INT = sys.maxint - range = xrange - - def _ustr(obj): - """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries - str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It - then < returns the unicode object | encodes it with the default encoding | ... >. - """ - if isinstance(obj,unicode): - return obj - - try: - # If this works, then _ustr(obj) has the same behaviour as str(obj), so - # it won't break any existing code. - return str(obj) - - except UnicodeEncodeError: - # Else encode it - ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') - xmlcharref = Regex(r'&#\d+;') - xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) - return xmlcharref.transformString(ret) - - # build list of single arg builtins, tolerant of Python version, that can be used as parse actions - singleArgBuiltins = [] - import __builtin__ - for fname in "sum len sorted reversed list tuple set any all min max".split(): - try: - singleArgBuiltins.append(getattr(__builtin__,fname)) - except AttributeError: - continue - -_generatorType = type((y for y in range(1))) - -def _xml_escape(data): - """Escape &, <, >, ", ', etc. in a string of data.""" - - # ampersand must be replaced first - from_symbols = '&><"\'' - to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) - for from_,to_ in zip(from_symbols, to_symbols): - data = data.replace(from_, to_) - return data - -class _Constants(object): - pass - -alphas = string.ascii_uppercase + string.ascii_lowercase -nums = "0123456789" -hexnums = nums + "ABCDEFabcdef" -alphanums = alphas + nums -_bslash = chr(92) -printables = "".join(c for c in string.printable if c not in string.whitespace) - -class ParseBaseException(Exception): - """base exception class for all parsing runtime exceptions""" - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, pstr, loc=0, msg=None, elem=None ): - self.loc = loc - if msg is None: - self.msg = pstr - self.pstr = "" - else: - self.msg = msg - self.pstr = pstr - self.parserElement = elem - self.args = (pstr, loc, msg) - - @classmethod - def _from_exception(cls, pe): - """ - internal factory method to simplify creating one type of ParseException - from another - avoids having __init__ signature conflicts among subclasses - """ - return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) - - def __getattr__( self, aname ): - """supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - """ - if( aname == "lineno" ): - return lineno( self.loc, self.pstr ) - elif( aname in ("col", "column") ): - return col( self.loc, self.pstr ) - elif( aname == "line" ): - return line( self.loc, self.pstr ) - else: - raise AttributeError(aname) - - def __str__( self ): - return "%s (at char %d), (line:%d, col:%d)" % \ - ( self.msg, self.loc, self.lineno, self.column ) - def __repr__( self ): - return _ustr(self) - def markInputline( self, markerString = ">!<" ): - """Extracts the exception line from the input string, and marks - the location of the exception with a special symbol. - """ - line_str = self.line - line_column = self.column - 1 - if markerString: - line_str = "".join((line_str[:line_column], - markerString, line_str[line_column:])) - return line_str.strip() - def __dir__(self): - return "lineno col line".split() + dir(type(self)) - -class ParseException(ParseBaseException): - """ - Exception thrown when parse expressions don't match class; - supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - - Example:: - try: - Word(nums).setName("integer").parseString("ABC") - except ParseException as pe: - print(pe) - print("column: {}".format(pe.col)) - - prints:: - Expected integer (at char 0), (line:1, col:1) - column: 1 - """ - pass - -class ParseFatalException(ParseBaseException): - """user-throwable exception thrown when inconsistent parse content - is found; stops all parsing immediately""" - pass - -class ParseSyntaxException(ParseFatalException): - """just like L{ParseFatalException}, but thrown internally when an - L{ErrorStop} ('-' operator) indicates that parsing is to stop - immediately because an unbacktrackable syntax error has been found""" - pass - -#~ class ReparseException(ParseBaseException): - #~ """Experimental class - parse actions can raise this exception to cause - #~ pyparsing to reparse the input string: - #~ - with a modified input string, and/or - #~ - with a modified start location - #~ Set the values of the ReparseException in the constructor, and raise the - #~ exception in a parse action to cause pyparsing to use the new string/location. - #~ Setting the values as None causes no change to be made. - #~ """ - #~ def __init_( self, newstring, restartLoc ): - #~ self.newParseText = newstring - #~ self.reparseLoc = restartLoc - -class RecursiveGrammarException(Exception): - """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" - def __init__( self, parseElementList ): - self.parseElementTrace = parseElementList - - def __str__( self ): - return "RecursiveGrammarException: %s" % self.parseElementTrace - -class _ParseResultsWithOffset(object): - def __init__(self,p1,p2): - self.tup = (p1,p2) - def __getitem__(self,i): - return self.tup[i] - def __repr__(self): - return repr(self.tup[0]) - def setOffset(self,i): - self.tup = (self.tup[0],i) - -class ParseResults(object): - """ - Structured parse results, to provide multiple means of access to the parsed data: - - as a list (C{len(results)}) - - by list index (C{results[0], results[1]}, etc.) - - by attribute (C{results.} - see L{ParserElement.setResultsName}) - - Example:: - integer = Word(nums) - date_str = (integer.setResultsName("year") + '/' - + integer.setResultsName("month") + '/' - + integer.setResultsName("day")) - # equivalent form: - # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - # parseString returns a ParseResults object - result = date_str.parseString("1999/12/31") - - def test(s, fn=repr): - print("%s -> %s" % (s, fn(eval(s)))) - test("list(result)") - test("result[0]") - test("result['month']") - test("result.day") - test("'month' in result") - test("'minutes' in result") - test("result.dump()", str) - prints:: - list(result) -> ['1999', '/', '12', '/', '31'] - result[0] -> '1999' - result['month'] -> '12' - result.day -> '31' - 'month' in result -> True - 'minutes' in result -> False - result.dump() -> ['1999', '/', '12', '/', '31'] - - day: 31 - - month: 12 - - year: 1999 - """ - def __new__(cls, toklist=None, name=None, asList=True, modal=True ): - if isinstance(toklist, cls): - return toklist - retobj = object.__new__(cls) - retobj.__doinit = True - return retobj - - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): - if self.__doinit: - self.__doinit = False - self.__name = None - self.__parent = None - self.__accumNames = {} - self.__asList = asList - self.__modal = modal - if toklist is None: - toklist = [] - if isinstance(toklist, list): - self.__toklist = toklist[:] - elif isinstance(toklist, _generatorType): - self.__toklist = list(toklist) - else: - self.__toklist = [toklist] - self.__tokdict = dict() - - if name is not None and name: - if not modal: - self.__accumNames[name] = 0 - if isinstance(name,int): - name = _ustr(name) # will always return a str, but use _ustr for consistency - self.__name = name - if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): - if isinstance(toklist,basestring): - toklist = [ toklist ] - if asList: - if isinstance(toklist,ParseResults): - self[name] = _ParseResultsWithOffset(toklist.copy(),0) - else: - self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) - self[name].__name = name - else: - try: - self[name] = toklist[0] - except (KeyError,TypeError,IndexError): - self[name] = toklist - - def __getitem__( self, i ): - if isinstance( i, (int,slice) ): - return self.__toklist[i] - else: - if i not in self.__accumNames: - return self.__tokdict[i][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[i] ]) - - def __setitem__( self, k, v, isinstance=isinstance ): - if isinstance(v,_ParseResultsWithOffset): - self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] - sub = v[0] - elif isinstance(k,(int,slice)): - self.__toklist[k] = v - sub = v - else: - self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] - sub = v - if isinstance(sub,ParseResults): - sub.__parent = wkref(self) - - def __delitem__( self, i ): - if isinstance(i,(int,slice)): - mylen = len( self.__toklist ) - del self.__toklist[i] - - # convert int to slice - if isinstance(i, int): - if i < 0: - i += mylen - i = slice(i, i+1) - # get removed indices - removed = list(range(*i.indices(mylen))) - removed.reverse() - # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): - for j in removed: - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) - else: - del self.__tokdict[i] - - def __contains__( self, k ): - return k in self.__tokdict - - def __len__( self ): return len( self.__toklist ) - def __bool__(self): return ( not not self.__toklist ) - __nonzero__ = __bool__ - def __iter__( self ): return iter( self.__toklist ) - def __reversed__( self ): return iter( self.__toklist[::-1] ) - def _iterkeys( self ): - if hasattr(self.__tokdict, "iterkeys"): - return self.__tokdict.iterkeys() - else: - return iter(self.__tokdict) - - def _itervalues( self ): - return (self[k] for k in self._iterkeys()) - - def _iteritems( self ): - return ((k, self[k]) for k in self._iterkeys()) - - if PY_3: - keys = _iterkeys - """Returns an iterator of all named result keys (Python 3.x only).""" - - values = _itervalues - """Returns an iterator of all named result values (Python 3.x only).""" - - items = _iteritems - """Returns an iterator of all named result key-value tuples (Python 3.x only).""" - - else: - iterkeys = _iterkeys - """Returns an iterator of all named result keys (Python 2.x only).""" - - itervalues = _itervalues - """Returns an iterator of all named result values (Python 2.x only).""" - - iteritems = _iteritems - """Returns an iterator of all named result key-value tuples (Python 2.x only).""" - - def keys( self ): - """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" - return list(self.iterkeys()) - - def values( self ): - """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" - return list(self.itervalues()) - - def items( self ): - """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" - return list(self.iteritems()) - - def haskeys( self ): - """Since keys() returns an iterator, this method is helpful in bypassing - code that looks for the existence of any defined results names.""" - return bool(self.__tokdict) - - def pop( self, *args, **kwargs): - """ - Removes and returns item at specified index (default=C{last}). - Supports both C{list} and C{dict} semantics for C{pop()}. If passed no - argument or an integer argument, it will use C{list} semantics - and pop tokens from the list of parsed tokens. If passed a - non-integer argument (most likely a string), it will use C{dict} - semantics and pop the corresponding value from any defined - results names. A second default return value argument is - supported, just as in C{dict.pop()}. - - Example:: - def remove_first(tokens): - tokens.pop(0) - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] - - label = Word(alphas) - patt = label("LABEL") + OneOrMore(Word(nums)) - print(patt.parseString("AAB 123 321").dump()) - - # Use pop() in a parse action to remove named result (note that corresponding value is not - # removed from list form of results) - def remove_LABEL(tokens): - tokens.pop("LABEL") - return tokens - patt.addParseAction(remove_LABEL) - print(patt.parseString("AAB 123 321").dump()) - prints:: - ['AAB', '123', '321'] - - LABEL: AAB - - ['AAB', '123', '321'] - """ - if not args: - args = [-1] - for k,v in kwargs.items(): - if k == 'default': - args = (args[0], v) - else: - raise TypeError("pop() got an unexpected keyword argument '%s'" % k) - if (isinstance(args[0], int) or - len(args) == 1 or - args[0] in self): - index = args[0] - ret = self[index] - del self[index] - return ret - else: - defaultvalue = args[1] - return defaultvalue - - def get(self, key, defaultValue=None): - """ - Returns named result matching the given key, or if there is no - such name, then returns the given C{defaultValue} or C{None} if no - C{defaultValue} is specified. - - Similar to C{dict.get()}. - - Example:: - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString("1999/12/31") - print(result.get("year")) # -> '1999' - print(result.get("hour", "not specified")) # -> 'not specified' - print(result.get("hour")) # -> None - """ - if key in self: - return self[key] - else: - return defaultValue - - def insert( self, index, insStr ): - """ - Inserts new element at location index in the list of parsed tokens. - - Similar to C{list.insert()}. - - Example:: - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - - # use a parse action to insert the parse location in the front of the parsed results - def insert_locn(locn, tokens): - tokens.insert(0, locn) - print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] - """ - self.__toklist.insert(index, insStr) - # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) - - def append( self, item ): - """ - Add single element to end of ParseResults list of elements. - - Example:: - print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - - # use a parse action to compute the sum of the parsed integers, and add it to the end - def append_sum(tokens): - tokens.append(sum(map(int, tokens))) - print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] - """ - self.__toklist.append(item) - - def extend( self, itemseq ): - """ - Add sequence of elements to end of ParseResults list of elements. - - Example:: - patt = OneOrMore(Word(alphas)) - - # use a parse action to append the reverse of the matched strings, to make a palindrome - def make_palindrome(tokens): - tokens.extend(reversed([t[::-1] for t in tokens])) - return ''.join(tokens) - print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' - """ - if isinstance(itemseq, ParseResults): - self += itemseq - else: - self.__toklist.extend(itemseq) - - def clear( self ): - """ - Clear all elements and results names. - """ - del self.__toklist[:] - self.__tokdict.clear() - - def __getattr__( self, name ): - try: - return self[name] - except KeyError: - return "" - - if name in self.__tokdict: - if name not in self.__accumNames: - return self.__tokdict[name][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[name] ]) - else: - return "" - - def __add__( self, other ): - ret = self.copy() - ret += other - return ret - - def __iadd__( self, other ): - if other.__tokdict: - offset = len(self.__toklist) - addoffset = lambda a: offset if a<0 else a+offset - otheritems = other.__tokdict.items() - otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) - for (k,vlist) in otheritems for v in vlist] - for k,v in otherdictitems: - self[k] = v - if isinstance(v[0],ParseResults): - v[0].__parent = wkref(self) - - self.__toklist += other.__toklist - self.__accumNames.update( other.__accumNames ) - return self - - def __radd__(self, other): - if isinstance(other,int) and other == 0: - # useful for merging many ParseResults using sum() builtin - return self.copy() - else: - # this may raise a TypeError - so be it - return other + self - - def __repr__( self ): - return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) - - def __str__( self ): - return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' - - def _asStringList( self, sep='' ): - out = [] - for item in self.__toklist: - if out and sep: - out.append(sep) - if isinstance( item, ParseResults ): - out += item._asStringList() - else: - out.append( _ustr(item) ) - return out - - def asList( self ): - """ - Returns the parse results as a nested list of matching tokens, all converted to strings. - - Example:: - patt = OneOrMore(Word(alphas)) - result = patt.parseString("sldkj lsdkj sldkj") - # even though the result prints in string-like form, it is actually a pyparsing ParseResults - print(type(result), result) # -> ['sldkj', 'lsdkj', 'sldkj'] - - # Use asList() to create an actual list - result_list = result.asList() - print(type(result_list), result_list) # -> ['sldkj', 'lsdkj', 'sldkj'] - """ - return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] - - def asDict( self ): - """ - Returns the named parse results as a nested dictionary. - - Example:: - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString('12/31/1999') - print(type(result), repr(result)) # -> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) - - result_dict = result.asDict() - print(type(result_dict), repr(result_dict)) # -> {'day': '1999', 'year': '12', 'month': '31'} - - # even though a ParseResults supports dict-like access, sometime you just need to have a dict - import json - print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable - print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} - """ - if PY_3: - item_fn = self.items - else: - item_fn = self.iteritems - - def toItem(obj): - if isinstance(obj, ParseResults): - if obj.haskeys(): - return obj.asDict() - else: - return [toItem(v) for v in obj] - else: - return obj - - return dict((k,toItem(v)) for k,v in item_fn()) - - def copy( self ): - """ - Returns a new copy of a C{ParseResults} object. - """ - ret = ParseResults( self.__toklist ) - ret.__tokdict = self.__tokdict.copy() - ret.__parent = self.__parent - ret.__accumNames.update( self.__accumNames ) - ret.__name = self.__name - return ret - - def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): - """ - (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. - """ - nl = "\n" - out = [] - namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() - for v in vlist) - nextLevelIndent = indent + " " - - # collapse out indents if formatting is not desired - if not formatted: - indent = "" - nextLevelIndent = "" - nl = "" - - selfTag = None - if doctag is not None: - selfTag = doctag - else: - if self.__name: - selfTag = self.__name - - if not selfTag: - if namedItemsOnly: - return "" - else: - selfTag = "ITEM" - - out += [ nl, indent, "<", selfTag, ">" ] - - for i,res in enumerate(self.__toklist): - if isinstance(res,ParseResults): - if i in namedItems: - out += [ res.asXML(namedItems[i], - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - out += [ res.asXML(None, - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - # individual token, see if there is a name for it - resTag = None - if i in namedItems: - resTag = namedItems[i] - if not resTag: - if namedItemsOnly: - continue - else: - resTag = "ITEM" - xmlBodyText = _xml_escape(_ustr(res)) - out += [ nl, nextLevelIndent, "<", resTag, ">", - xmlBodyText, - "" ] - - out += [ nl, indent, "" ] - return "".join(out) - - def __lookup(self,sub): - for k,vlist in self.__tokdict.items(): - for v,loc in vlist: - if sub is v: - return k - return None - - def getName(self): - r""" - Returns the results name for this token expression. Useful when several - different expressions might match at a particular location. - - Example:: - integer = Word(nums) - ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") - house_number_expr = Suppress('#') + Word(nums, alphanums) - user_data = (Group(house_number_expr)("house_number") - | Group(ssn_expr)("ssn") - | Group(integer)("age")) - user_info = OneOrMore(user_data) - - result = user_info.parseString("22 111-22-3333 #221B") - for item in result: - print(item.getName(), ':', item[0]) - prints:: - age : 22 - ssn : 111-22-3333 - house_number : 221B - """ - if self.__name: - return self.__name - elif self.__parent: - par = self.__parent() - if par: - return par.__lookup(self) - else: - return None - elif (len(self) == 1 and - len(self.__tokdict) == 1 and - next(iter(self.__tokdict.values()))[0][1] in (0,-1)): - return next(iter(self.__tokdict.keys())) - else: - return None - - def dump(self, indent='', depth=0, full=True): - """ - Diagnostic method for listing out the contents of a C{ParseResults}. - Accepts an optional C{indent} argument so that this string can be embedded - in a nested display of other data. - - Example:: - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - result = date_str.parseString('12/31/1999') - print(result.dump()) - prints:: - ['12', '/', '31', '/', '1999'] - - day: 1999 - - month: 31 - - year: 12 - """ - out = [] - NL = '\n' - out.append( indent+_ustr(self.asList()) ) - if full: - if self.haskeys(): - items = sorted((str(k), v) for k,v in self.items()) - for k,v in items: - if out: - out.append(NL) - out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) - if isinstance(v,ParseResults): - if v: - out.append( v.dump(indent,depth+1) ) - else: - out.append(_ustr(v)) - else: - out.append(repr(v)) - elif any(isinstance(vv,ParseResults) for vv in self): - v = self - for i,vv in enumerate(v): - if isinstance(vv,ParseResults): - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) - else: - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) - - return "".join(out) - - def pprint(self, *args, **kwargs): - """ - Pretty-printer for parsed results as a list, using the C{pprint} module. - Accepts additional positional or keyword args as defined for the - C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) - - Example:: - ident = Word(alphas, alphanums) - num = Word(nums) - func = Forward() - term = ident | num | Group('(' + func + ')') - func <<= ident + Group(Optional(delimitedList(term))) - result = func.parseString("fna a,b,(fnb c,d,200),100") - result.pprint(width=40) - prints:: - ['fna', - ['a', - 'b', - ['(', 'fnb', ['c', 'd', '200'], ')'], - '100']] - """ - pprint.pprint(self.asList(), *args, **kwargs) - - # add support for pickle protocol - def __getstate__(self): - return ( self.__toklist, - ( self.__tokdict.copy(), - self.__parent is not None and self.__parent() or None, - self.__accumNames, - self.__name ) ) - - def __setstate__(self,state): - self.__toklist = state[0] - (self.__tokdict, - par, - inAccumNames, - self.__name) = state[1] - self.__accumNames = {} - self.__accumNames.update(inAccumNames) - if par is not None: - self.__parent = wkref(par) - else: - self.__parent = None - - def __getnewargs__(self): - return self.__toklist, self.__name, self.__asList, self.__modal - - def __dir__(self): - return (dir(type(self)) + list(self.keys())) - -MutableMapping.register(ParseResults) - -def col (loc,strg): - """Returns current column within a string, counting newlines as line separators. - The first column is number 1. - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See L{I{ParserElement.parseString}} for more information - on parsing strings containing C{}s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - """ - s = strg - return 1 if 0} for more information - on parsing strings containing C{}s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - """ - return strg.count("\n",0,loc) + 1 - -def line( loc, strg ): - """Returns the line of text containing loc within a string, counting newlines as line separators. - """ - lastCR = strg.rfind("\n", 0, loc) - nextCR = strg.find("\n", loc) - if nextCR >= 0: - return strg[lastCR+1:nextCR] - else: - return strg[lastCR+1:] - -def _defaultStartDebugAction( instring, loc, expr ): - print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) - -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): - print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) - -def _defaultExceptionDebugAction( instring, loc, expr, exc ): - print ("Exception raised:" + _ustr(exc)) - -def nullDebugAction(*args): - """'Do-nothing' debug action, to suppress debugging output during parsing.""" - pass - -# Only works on Python 3.x - nonlocal is toxic to Python 2 installs -#~ 'decorator to trim function calls to match the arity of the target' -#~ def _trim_arity(func, maxargs=3): - #~ if func in singleArgBuiltins: - #~ return lambda s,l,t: func(t) - #~ limit = 0 - #~ foundArity = False - #~ def wrapper(*args): - #~ nonlocal limit,foundArity - #~ while 1: - #~ try: - #~ ret = func(*args[limit:]) - #~ foundArity = True - #~ return ret - #~ except TypeError: - #~ if limit == maxargs or foundArity: - #~ raise - #~ limit += 1 - #~ continue - #~ return wrapper - -# this version is Python 2.x-3.x cross-compatible -'decorator to trim function calls to match the arity of the target' -def _trim_arity(func, maxargs=2): - if func in singleArgBuiltins: - return lambda s,l,t: func(t) - limit = [0] - foundArity = [False] - - # traceback return data structure changed in Py3.5 - normalize back to plain tuples - if system_version[:2] >= (3,5): - def extract_stack(limit=0): - # special handling for Python 3.5.0 - extra deep call stack by 1 - offset = -3 if system_version == (3,5,0) else -2 - frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] - return [frame_summary[:2]] - def extract_tb(tb, limit=0): - frames = traceback.extract_tb(tb, limit=limit) - frame_summary = frames[-1] - return [frame_summary[:2]] - else: - extract_stack = traceback.extract_stack - extract_tb = traceback.extract_tb - - # synthesize what would be returned by traceback.extract_stack at the call to - # user's parse action 'func', so that we don't incur call penalty at parse time - - LINE_DIFF = 6 - # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND - # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! - this_line = extract_stack(limit=2)[-1] - pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) - - def wrapper(*args): - while 1: - try: - ret = func(*args[limit[0]:]) - foundArity[0] = True - return ret - except TypeError: - # re-raise TypeErrors if they did not come from our arity testing - if foundArity[0]: - raise - else: - try: - tb = sys.exc_info()[-1] - if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: - raise - finally: - del tb - - if limit[0] <= maxargs: - limit[0] += 1 - continue - raise - - # copy func name to wrapper for sensible debug output - func_name = "" - try: - func_name = getattr(func, '__name__', - getattr(func, '__class__').__name__) - except Exception: - func_name = str(func) - wrapper.__name__ = func_name - - return wrapper - -class ParserElement(object): - """Abstract base level parser element class.""" - DEFAULT_WHITE_CHARS = " \n\t\r" - verbose_stacktrace = False - - @staticmethod - def setDefaultWhitespaceChars( chars ): - r""" - Overrides the default whitespace chars - - Example:: - # default whitespace chars are space, and newline - OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] - - # change to just treat newline as significant - ParserElement.setDefaultWhitespaceChars(" \t") - OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] - """ - ParserElement.DEFAULT_WHITE_CHARS = chars - - @staticmethod - def inlineLiteralsUsing(cls): - """ - Set class to be used for inclusion of string literals into a parser. - - Example:: - # default literal class used is Literal - integer = Word(nums) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] - - - # change to Suppress - ParserElement.inlineLiteralsUsing(Suppress) - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - - date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] - """ - ParserElement._literalStringClass = cls - - def __init__( self, savelist=False ): - self.parseAction = list() - self.failAction = None - #~ self.name = "" # don't define self.name, let subclasses try/except upcall - self.strRepr = None - self.resultsName = None - self.saveAsList = savelist - self.skipWhitespace = True - self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS - self.copyDefaultWhiteChars = True - self.mayReturnEmpty = False # used when checking for left-recursion - self.keepTabs = False - self.ignoreExprs = list() - self.debug = False - self.streamlined = False - self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index - self.errmsg = "" - self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) - self.debugActions = ( None, None, None ) #custom debug actions - self.re = None - self.callPreparse = True # used to avoid redundant calls to preParse - self.callDuringTry = False - - def copy( self ): - """ - Make a copy of this C{ParserElement}. Useful for defining different parse actions - for the same parsing pattern, using copies of the original parse element. - - Example:: - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") - integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") - - print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) - prints:: - [5120, 100, 655360, 268435456] - Equivalent form of C{expr.copy()} is just C{expr()}:: - integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") - """ - cpy = copy.copy( self ) - cpy.parseAction = self.parseAction[:] - cpy.ignoreExprs = self.ignoreExprs[:] - if self.copyDefaultWhiteChars: - cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS - return cpy - - def setName( self, name ): - """ - Define name for this expression, makes debugging and exception messages clearer. - - Example:: - Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) - Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) - """ - self.name = name - self.errmsg = "Expected " + self.name - if hasattr(self,"exception"): - self.exception.msg = self.errmsg - return self - - def setResultsName( self, name, listAllMatches=False ): - """ - Define name for referencing matching tokens as a nested attribute - of the returned parse results. - NOTE: this returns a *copy* of the original C{ParserElement} object; - this is so that the client can define a basic element, such as an - integer, and reference it in multiple places with different names. - - You can also set results names using the abbreviated syntax, - C{expr("name")} in place of C{expr.setResultsName("name")} - - see L{I{__call__}<__call__>}. - - Example:: - date_str = (integer.setResultsName("year") + '/' - + integer.setResultsName("month") + '/' - + integer.setResultsName("day")) - - # equivalent form: - date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - """ - newself = self.copy() - if name.endswith("*"): - name = name[:-1] - listAllMatches=True - newself.resultsName = name - newself.modalResults = not listAllMatches - return newself - - def setBreak(self,breakFlag = True): - """Method to invoke the Python pdb debugger when this element is - about to be parsed. Set C{breakFlag} to True to enable, False to - disable. - """ - if breakFlag: - _parseMethod = self._parse - def breaker(instring, loc, doActions=True, callPreParse=True): - import pdb - pdb.set_trace() - return _parseMethod( instring, loc, doActions, callPreParse ) - breaker._originalParseMethod = _parseMethod - self._parse = breaker - else: - if hasattr(self._parse,"_originalParseMethod"): - self._parse = self._parse._originalParseMethod - return self - - def setParseAction( self, *fns, **kwargs ): - """ - Define one or more actions to perform when successfully matching parse element definition. - Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, - C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: - - s = the original string being parsed (see note below) - - loc = the location of the matching substring - - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object - If the functions in fns modify the tokens, they can return them as the return - value from fn, and the modified list of tokens will replace the original. - Otherwise, fn does not need to return any value. - - Optional keyword arguments: - - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See L{I{parseString}} for more information - on parsing strings containing C{}s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - - Example:: - integer = Word(nums) - date_str = integer + '/' + integer + '/' + integer - - date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] - - # use parse action to convert to ints at parse time - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - date_str = integer + '/' + integer + '/' + integer - - # note that integer fields are now ints, not strings - date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] - """ - self.parseAction = list(map(_trim_arity, list(fns))) - self.callDuringTry = kwargs.get("callDuringTry", False) - return self - - def addParseAction( self, *fns, **kwargs ): - """ - Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}}. - - See examples in L{I{copy}}. - """ - self.parseAction += list(map(_trim_arity, list(fns))) - self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) - return self - - def addCondition(self, *fns, **kwargs): - """Add a boolean predicate function to expression's list of parse actions. See - L{I{setParseAction}} for function call signatures. Unlike C{setParseAction}, - functions passed to C{addCondition} need to return boolean success/fail of the condition. - - Optional keyword arguments: - - message = define a custom message to be used in the raised exception - - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException - - Example:: - integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - year_int = integer.copy() - year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") - date_str = year_int + '/' + integer + '/' + integer - - result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) - """ - msg = kwargs.get("message", "failed user-defined condition") - exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException - for fn in fns: - def pa(s,l,t): - if not bool(_trim_arity(fn)(s,l,t)): - raise exc_type(s,l,msg) - self.parseAction.append(pa) - self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) - return self - - def setFailAction( self, fn ): - """Define action to perform if parsing fails at this expression. - Fail acton fn is a callable function that takes the arguments - C{fn(s,loc,expr,err)} where: - - s = string being parsed - - loc = location where expression match was attempted and failed - - expr = the parse expression that failed - - err = the exception thrown - The function returns no value. It may throw C{L{ParseFatalException}} - if it is desired to stop parsing immediately.""" - self.failAction = fn - return self - - def _skipIgnorables( self, instring, loc ): - exprsFound = True - while exprsFound: - exprsFound = False - for e in self.ignoreExprs: - try: - while 1: - loc,dummy = e._parse( instring, loc ) - exprsFound = True - except ParseException: - pass - return loc - - def preParse( self, instring, loc ): - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - - if self.skipWhitespace: - wt = self.whiteChars - instrlen = len(instring) - while loc < instrlen and instring[loc] in wt: - loc += 1 - - return loc - - def parseImpl( self, instring, loc, doActions=True ): - return loc, [] - - def postParse( self, instring, loc, tokenlist ): - return tokenlist - - #~ @profile - def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): - debugging = ( self.debug ) #and doActions ) - - if debugging or self.failAction: - #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) - if (self.debugActions[0] ): - self.debugActions[0]( instring, loc, self ) - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = preloc - try: - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - except ParseBaseException as err: - #~ print ("Exception raised:", err) - if self.debugActions[2]: - self.debugActions[2]( instring, tokensStart, self, err ) - if self.failAction: - self.failAction( instring, tokensStart, self, err ) - raise - else: - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = preloc - if self.mayIndexError or preloc >= len(instring): - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - else: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - - tokens = self.postParse( instring, loc, tokens ) - - retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) - if self.parseAction and (doActions or self.callDuringTry): - if debugging: - try: - for fn in self.parseAction: - tokens = fn( instring, tokensStart, retTokens ) - if tokens is not None: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - except ParseBaseException as err: - #~ print "Exception raised in user parse action:", err - if (self.debugActions[2] ): - self.debugActions[2]( instring, tokensStart, self, err ) - raise - else: - for fn in self.parseAction: - tokens = fn( instring, tokensStart, retTokens ) - if tokens is not None: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - if debugging: - #~ print ("Matched",self,"->",retTokens.asList()) - if (self.debugActions[1] ): - self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) - - return loc, retTokens - - def tryParse( self, instring, loc ): - try: - return self._parse( instring, loc, doActions=False )[0] - except ParseFatalException: - raise ParseException( instring, loc, self.errmsg, self) - - def canParseNext(self, instring, loc): - try: - self.tryParse(instring, loc) - except (ParseException, IndexError): - return False - else: - return True - - class _UnboundedCache(object): - def __init__(self): - cache = {} - self.not_in_cache = not_in_cache = object() - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - - def clear(self): - cache.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - if _OrderedDict is not None: - class _FifoCache(object): - def __init__(self, size): - self.not_in_cache = not_in_cache = object() - - cache = _OrderedDict() - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - while len(cache) > size: - try: - cache.popitem(False) - except KeyError: - pass - - def clear(self): - cache.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - else: - class _FifoCache(object): - def __init__(self, size): - self.not_in_cache = not_in_cache = object() - - cache = {} - key_fifo = collections.deque([], size) - - def get(self, key): - return cache.get(key, not_in_cache) - - def set(self, key, value): - cache[key] = value - while len(key_fifo) > size: - cache.pop(key_fifo.popleft(), None) - key_fifo.append(key) - - def clear(self): - cache.clear() - key_fifo.clear() - - def cache_len(self): - return len(cache) - - self.get = types.MethodType(get, self) - self.set = types.MethodType(set, self) - self.clear = types.MethodType(clear, self) - self.__len__ = types.MethodType(cache_len, self) - - # argument cache for optimizing repeated calls when backtracking through recursive expressions - packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail - packrat_cache_lock = RLock() - packrat_cache_stats = [0, 0] - - # this method gets repeatedly called during backtracking with the same arguments - - # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression - def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): - HIT, MISS = 0, 1 - lookup = (self, instring, loc, callPreParse, doActions) - with ParserElement.packrat_cache_lock: - cache = ParserElement.packrat_cache - value = cache.get(lookup) - if value is cache.not_in_cache: - ParserElement.packrat_cache_stats[MISS] += 1 - try: - value = self._parseNoCache(instring, loc, doActions, callPreParse) - except ParseBaseException as pe: - # cache a copy of the exception, without the traceback - cache.set(lookup, pe.__class__(*pe.args)) - raise - else: - cache.set(lookup, (value[0], value[1].copy())) - return value - else: - ParserElement.packrat_cache_stats[HIT] += 1 - if isinstance(value, Exception): - raise value - return (value[0], value[1].copy()) - - _parse = _parseNoCache - - @staticmethod - def resetCache(): - ParserElement.packrat_cache.clear() - ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) - - _packratEnabled = False - @staticmethod - def enablePackrat(cache_size_limit=128): - """Enables "packrat" parsing, which adds memoizing to the parsing logic. - Repeated parse attempts at the same string location (which happens - often in many complex grammars) can immediately return a cached value, - instead of re-executing parsing/validating code. Memoizing is done of - both valid results and parsing exceptions. - - Parameters: - - cache_size_limit - (default=C{128}) - if an integer value is provided - will limit the size of the packrat cache; if None is passed, then - the cache size will be unbounded; if 0 is passed, the cache will - be effectively disabled. - - This speedup may break existing programs that use parse actions that - have side-effects. For this reason, packrat parsing is disabled when - you first import pyparsing. To activate the packrat feature, your - program must call the class method C{ParserElement.enablePackrat()}. If - your program uses C{psyco} to "compile as you go", you must call - C{enablePackrat} before calling C{psyco.full()}. If you do not do this, - Python will crash. For best results, call C{enablePackrat()} immediately - after importing pyparsing. - - Example:: - import pyparsing - pyparsing.ParserElement.enablePackrat() - """ - if not ParserElement._packratEnabled: - ParserElement._packratEnabled = True - if cache_size_limit is None: - ParserElement.packrat_cache = ParserElement._UnboundedCache() - else: - ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) - ParserElement._parse = ParserElement._parseCache - - def parseString( self, instring, parseAll=False ): - """ - Execute the parse expression with the given string. - This is the main interface to the client code, once the complete - expression has been built. - - If you want the grammar to require that the entire input string be - successfully parsed, then set C{parseAll} to True (equivalent to ending - the grammar with C{L{StringEnd()}}). - - Note: C{parseString} implicitly calls C{expandtabs()} on the input string, - in order to report proper column numbers in parse actions. - If the input string contains tabs and - the grammar uses parse actions that use the C{loc} argument to index into the - string being parsed, you can ensure you have a consistent view of the input - string by: - - calling C{parseWithTabs} on your grammar before calling C{parseString} - (see L{I{parseWithTabs}}) - - define your parse action using the full C{(s,loc,toks)} signature, and - reference the input string using the parse action's C{s} argument - - explictly expand the tabs in your input string before calling - C{parseString} - - Example:: - Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] - Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text - """ - ParserElement.resetCache() - if not self.streamlined: - self.streamline() - #~ self.saveAsList = True - for e in self.ignoreExprs: - e.streamline() - if not self.keepTabs: - instring = instring.expandtabs() - try: - loc, tokens = self._parse( instring, 0 ) - if parseAll: - loc = self.preParse( instring, loc ) - se = Empty() + StringEnd() - se._parse( instring, loc ) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - else: - return tokens - - def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): - """ - Scan the input string for expression matches. Each match will return the - matching tokens, start location, and end location. May be called with optional - C{maxMatches} argument, to clip scanning after 'n' matches are found. If - C{overlap} is specified, then overlapping matches will be reported. - - Note that the start and end locations are reported relative to the string - being parsed. See L{I{parseString}} for more information on parsing - strings with embedded tabs. - - Example:: - source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" - print(source) - for tokens,start,end in Word(alphas).scanString(source): - print(' '*start + '^'*(end-start)) - print(' '*start + tokens[0]) - - prints:: - - sldjf123lsdjjkf345sldkjf879lkjsfd987 - ^^^^^ - sldjf - ^^^^^^^ - lsdjjkf - ^^^^^^ - sldkjf - ^^^^^^ - lkjsfd - """ - if not self.streamlined: - self.streamline() - for e in self.ignoreExprs: - e.streamline() - - if not self.keepTabs: - instring = _ustr(instring).expandtabs() - instrlen = len(instring) - loc = 0 - preparseFn = self.preParse - parseFn = self._parse - ParserElement.resetCache() - matches = 0 - try: - while loc <= instrlen and matches < maxMatches: - try: - preloc = preparseFn( instring, loc ) - nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) - except ParseException: - loc = preloc+1 - else: - if nextLoc > loc: - matches += 1 - yield tokens, preloc, nextLoc - if overlap: - nextloc = preparseFn( instring, loc ) - if nextloc > loc: - loc = nextLoc - else: - loc += 1 - else: - loc = nextLoc - else: - loc = preloc+1 - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def transformString( self, instring ): - """ - Extension to C{L{scanString}}, to modify matching text with modified tokens that may - be returned from a parse action. To use C{transformString}, define a grammar and - attach a parse action to it that modifies the returned token list. - Invoking C{transformString()} on a target string will then scan for matches, - and replace the matched text patterns according to the logic in the parse - action. C{transformString()} returns the resulting transformed string. - - Example:: - wd = Word(alphas) - wd.setParseAction(lambda toks: toks[0].title()) - - print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) - Prints:: - Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. - """ - out = [] - lastE = 0 - # force preservation of s, to minimize unwanted transformation of string, and to - # keep string locs straight between transformString and scanString - self.keepTabs = True - try: - for t,s,e in self.scanString( instring ): - out.append( instring[lastE:s] ) - if t: - if isinstance(t,ParseResults): - out += t.asList() - elif isinstance(t,list): - out += t - else: - out.append(t) - lastE = e - out.append(instring[lastE:]) - out = [o for o in out if o] - return "".join(map(_ustr,_flatten(out))) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def searchString( self, instring, maxMatches=_MAX_INT ): - """ - Another extension to C{L{scanString}}, simplifying the access to the tokens found - to match the given parse expression. May be called with optional - C{maxMatches} argument, to clip searching after 'n' matches are found. - - Example:: - # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters - cap_word = Word(alphas.upper(), alphas.lower()) - - print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) - - # the sum() builtin can be used to merge results into a single ParseResults object - print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) - prints:: - [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] - ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] - """ - try: - return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): - """ - Generator method to split a string using the given expression as a separator. - May be called with optional C{maxsplit} argument, to limit the number of splits; - and the optional C{includeSeparators} argument (default=C{False}), if the separating - matching text should be included in the split results. - - Example:: - punc = oneOf(list(".,;:/-!?")) - print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) - prints:: - ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] - """ - splits = 0 - last = 0 - for t,s,e in self.scanString(instring, maxMatches=maxsplit): - yield instring[last:s] - if includeSeparators: - yield t[0] - last = e - yield instring[last:] - - def __add__(self, other ): - """ - Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement - converts them to L{Literal}s by default. - - Example:: - greet = Word(alphas) + "," + Word(alphas) + "!" - hello = "Hello, World!" - print (hello, "->", greet.parseString(hello)) - Prints:: - Hello, World! -> ['Hello', ',', 'World', '!'] - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return And( [ self, other ] ) - - def __radd__(self, other ): - """ - Implementation of + operator when left operand is not a C{L{ParserElement}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other + self - - def __sub__(self, other): - """ - Implementation of - operator, returns C{L{And}} with error stop - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return self + And._ErrorStop() + other - - def __rsub__(self, other ): - """ - Implementation of - operator when left operand is not a C{L{ParserElement}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other - self - - def __mul__(self,other): - """ - Implementation of * operator, allows use of C{expr * 3} in place of - C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer - tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples - may also include C{None} as in: - - C{expr*(n,None)} or C{expr*(n,)} is equivalent - to C{expr*n + L{ZeroOrMore}(expr)} - (read as "at least n instances of C{expr}") - - C{expr*(None,n)} is equivalent to C{expr*(0,n)} - (read as "0 to n instances of C{expr}") - - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} - - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} - - Note that C{expr*(None,n)} does not raise an exception if - more than n exprs exist in the input stream; that is, - C{expr*(None,n)} does not enforce a maximum number of expr - occurrences. If this behavior is desired, then write - C{expr*(None,n) + ~expr} - """ - if isinstance(other,int): - minElements, optElements = other,0 - elif isinstance(other,tuple): - other = (other + (None, None))[:2] - if other[0] is None: - other = (0, other[1]) - if isinstance(other[0],int) and other[1] is None: - if other[0] == 0: - return ZeroOrMore(self) - if other[0] == 1: - return OneOrMore(self) - else: - return self*other[0] + ZeroOrMore(self) - elif isinstance(other[0],int) and isinstance(other[1],int): - minElements, optElements = other - optElements -= minElements - else: - raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) - else: - raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) - - if minElements < 0: - raise ValueError("cannot multiply ParserElement by negative value") - if optElements < 0: - raise ValueError("second tuple value must be greater or equal to first tuple value") - if minElements == optElements == 0: - raise ValueError("cannot multiply ParserElement by 0 or (0,0)") - - if (optElements): - def makeOptionalList(n): - if n>1: - return Optional(self + makeOptionalList(n-1)) - else: - return Optional(self) - if minElements: - if minElements == 1: - ret = self + makeOptionalList(optElements) - else: - ret = And([self]*minElements) + makeOptionalList(optElements) - else: - ret = makeOptionalList(optElements) - else: - if minElements == 1: - ret = self - else: - ret = And([self]*minElements) - return ret - - def __rmul__(self, other): - return self.__mul__(other) - - def __or__(self, other ): - """ - Implementation of | operator - returns C{L{MatchFirst}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return MatchFirst( [ self, other ] ) - - def __ror__(self, other ): - """ - Implementation of | operator when left operand is not a C{L{ParserElement}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other | self - - def __xor__(self, other ): - """ - Implementation of ^ operator - returns C{L{Or}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Or( [ self, other ] ) - - def __rxor__(self, other ): - """ - Implementation of ^ operator when left operand is not a C{L{ParserElement}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other ^ self - - def __and__(self, other ): - """ - Implementation of & operator - returns C{L{Each}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Each( [ self, other ] ) - - def __rand__(self, other ): - """ - Implementation of & operator when left operand is not a C{L{ParserElement}} - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other & self - - def __invert__( self ): - """ - Implementation of ~ operator - returns C{L{NotAny}} - """ - return NotAny( self ) - - def __call__(self, name=None): - """ - Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. - - If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be - passed as C{True}. - - If C{name} is omitted, same as calling C{L{copy}}. - - Example:: - # these are equivalent - userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") - userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") - """ - if name is not None: - return self.setResultsName(name) - else: - return self.copy() - - def suppress( self ): - """ - Suppresses the output of this C{ParserElement}; useful to keep punctuation from - cluttering up returned output. - """ - return Suppress( self ) - - def leaveWhitespace( self ): - """ - Disables the skipping of whitespace before matching the characters in the - C{ParserElement}'s defined pattern. This is normally only used internally by - the pyparsing module, but may be needed in some whitespace-sensitive grammars. - """ - self.skipWhitespace = False - return self - - def setWhitespaceChars( self, chars ): - """ - Overrides the default whitespace chars - """ - self.skipWhitespace = True - self.whiteChars = chars - self.copyDefaultWhiteChars = False - return self - - def parseWithTabs( self ): - """ - Overrides default behavior to expand C{}s to spaces before parsing the input string. - Must be called before C{parseString} when the input grammar contains elements that - match C{} characters. - """ - self.keepTabs = True - return self - - def ignore( self, other ): - """ - Define expression to be ignored (e.g., comments) while doing pattern - matching; may be called repeatedly, to define multiple comment or other - ignorable patterns. - - Example:: - patt = OneOrMore(Word(alphas)) - patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] - - patt.ignore(cStyleComment) - patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] - """ - if isinstance(other, basestring): - other = Suppress(other) - - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - self.ignoreExprs.append(other) - else: - self.ignoreExprs.append( Suppress( other.copy() ) ) - return self - - def setDebugActions( self, startAction, successAction, exceptionAction ): - """ - Enable display of debugging messages while doing pattern matching. - """ - self.debugActions = (startAction or _defaultStartDebugAction, - successAction or _defaultSuccessDebugAction, - exceptionAction or _defaultExceptionDebugAction) - self.debug = True - return self - - def setDebug( self, flag=True ): - """ - Enable display of debugging messages while doing pattern matching. - Set C{flag} to True to enable, False to disable. - - Example:: - wd = Word(alphas).setName("alphaword") - integer = Word(nums).setName("numword") - term = wd | integer - - # turn on debugging for wd - wd.setDebug() - - OneOrMore(term).parseString("abc 123 xyz 890") - - prints:: - Match alphaword at loc 0(1,1) - Matched alphaword -> ['abc'] - Match alphaword at loc 3(1,4) - Exception raised:Expected alphaword (at char 4), (line:1, col:5) - Match alphaword at loc 7(1,8) - Matched alphaword -> ['xyz'] - Match alphaword at loc 11(1,12) - Exception raised:Expected alphaword (at char 12), (line:1, col:13) - Match alphaword at loc 15(1,16) - Exception raised:Expected alphaword (at char 15), (line:1, col:16) - - The output shown is that produced by the default debug actions - custom debug actions can be - specified using L{setDebugActions}. Prior to attempting - to match the C{wd} expression, the debugging message C{"Match at loc (,)"} - is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} - message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, - which makes debugging and exception messages easier to understand - for instance, the default - name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. - """ - if flag: - self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) - else: - self.debug = False - return self - - def __str__( self ): - return self.name - - def __repr__( self ): - return _ustr(self) - - def streamline( self ): - self.streamlined = True - self.strRepr = None - return self - - def checkRecursion( self, parseElementList ): - pass - - def validate( self, validateTrace=[] ): - """ - Check defined expressions for valid structure, check for infinite recursive definitions. - """ - self.checkRecursion( [] ) - - def parseFile( self, file_or_filename, parseAll=False ): - """ - Execute the parse expression on the given file or filename. - If a filename is specified (instead of a file object), - the entire file is opened, read, and closed before parsing. - """ - try: - file_contents = file_or_filename.read() - except AttributeError: - with open(file_or_filename, "r") as f: - file_contents = f.read() - try: - return self.parseString(file_contents, parseAll) - except ParseBaseException as exc: - if ParserElement.verbose_stacktrace: - raise - else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace - raise exc - - def __eq__(self,other): - if isinstance(other, ParserElement): - return self is other or vars(self) == vars(other) - elif isinstance(other, basestring): - return self.matches(other) - else: - return super(ParserElement,self)==other - - def __ne__(self,other): - return not (self == other) - - def __hash__(self): - return hash(id(self)) - - def __req__(self,other): - return self == other - - def __rne__(self,other): - return not (self == other) - - def matches(self, testString, parseAll=True): - """ - Method for quick testing of a parser against a test string. Good for simple - inline microtests of sub expressions while building up larger parser. - - Parameters: - - testString - to test against this expression for a match - - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests - - Example:: - expr = Word(nums) - assert expr.matches("100") - """ - try: - self.parseString(_ustr(testString), parseAll=parseAll) - return True - except ParseBaseException: - return False - - def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): - """ - Execute the parse expression on a series of test strings, showing each - test, the parsed results or where the parse failed. Quick and easy way to - run a parse expression against a list of sample strings. - - Parameters: - - tests - a list of separate test strings, or a multiline string of test strings - - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests - - comment - (default=C{'#'}) - expression for indicating embedded comments in the test - string; pass None to disable comment filtering - - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; - if False, only dump nested list - - printResults - (default=C{True}) prints test output to stdout - - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing - - Returns: a (success, results) tuple, where success indicates that all tests succeeded - (or failed if C{failureTests} is True), and the results contain a list of lines of each - test's output - - Example:: - number_expr = pyparsing_common.number.copy() - - result = number_expr.runTests(''' - # unsigned integer - 100 - # negative integer - -100 - # float with scientific notation - 6.02e23 - # integer with scientific notation - 1e-12 - ''') - print("Success" if result[0] else "Failed!") - - result = number_expr.runTests(''' - # stray character - 100Z - # missing leading digit before '.' - -.100 - # too many '.' - 3.14.159 - ''', failureTests=True) - print("Success" if result[0] else "Failed!") - prints:: - # unsigned integer - 100 - [100] - - # negative integer - -100 - [-100] - - # float with scientific notation - 6.02e23 - [6.02e+23] - - # integer with scientific notation - 1e-12 - [1e-12] - - Success - - # stray character - 100Z - ^ - FAIL: Expected end of text (at char 3), (line:1, col:4) - - # missing leading digit before '.' - -.100 - ^ - FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) - - # too many '.' - 3.14.159 - ^ - FAIL: Expected end of text (at char 4), (line:1, col:5) - - Success - - Each test string must be on a single line. If you want to test a string that spans multiple - lines, create a test like this:: - - expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") - - (Note that this is a raw string literal, you must include the leading 'r'.) - """ - if isinstance(tests, basestring): - tests = list(map(str.strip, tests.rstrip().splitlines())) - if isinstance(comment, basestring): - comment = Literal(comment) - allResults = [] - comments = [] - success = True - for t in tests: - if comment is not None and comment.matches(t, False) or comments and not t: - comments.append(t) - continue - if not t: - continue - out = ['\n'.join(comments), t] - comments = [] - try: - t = t.replace(r'\n','\n') - result = self.parseString(t, parseAll=parseAll) - out.append(result.dump(full=fullDump)) - success = success and not failureTests - except ParseBaseException as pe: - fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" - if '\n' in t: - out.append(line(pe.loc, t)) - out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) - else: - out.append(' '*pe.loc + '^' + fatal) - out.append("FAIL: " + str(pe)) - success = success and failureTests - result = pe - except Exception as exc: - out.append("FAIL-EXCEPTION: " + str(exc)) - success = success and failureTests - result = exc - - if printResults: - if fullDump: - out.append('') - print('\n'.join(out)) - - allResults.append((t, result)) - - return success, allResults - - -class Token(ParserElement): - """ - Abstract C{ParserElement} subclass, for defining atomic matching patterns. - """ - def __init__( self ): - super(Token,self).__init__( savelist=False ) - - -class Empty(Token): - """ - An empty token, will always match. - """ - def __init__( self ): - super(Empty,self).__init__() - self.name = "Empty" - self.mayReturnEmpty = True - self.mayIndexError = False - - -class NoMatch(Token): - """ - A token that will never match. - """ - def __init__( self ): - super(NoMatch,self).__init__() - self.name = "NoMatch" - self.mayReturnEmpty = True - self.mayIndexError = False - self.errmsg = "Unmatchable token" - - def parseImpl( self, instring, loc, doActions=True ): - raise ParseException(instring, loc, self.errmsg, self) - - -class Literal(Token): - """ - Token to exactly match a specified string. - - Example:: - Literal('blah').parseString('blah') # -> ['blah'] - Literal('blah').parseString('blahfooblah') # -> ['blah'] - Literal('blah').parseString('bla') # -> Exception: Expected "blah" - - For case-insensitive matching, use L{CaselessLiteral}. - - For keyword matching (force word break before and after the matched string), - use L{Keyword} or L{CaselessKeyword}. - """ - def __init__( self, matchString ): - super(Literal,self).__init__() - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Literal; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.__class__ = Empty - self.name = '"%s"' % _ustr(self.match) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - self.mayIndexError = False - - # Performance tuning: this routine gets called a *lot* - # if this is a single character match string and the first character matches, - # short-circuit as quickly as possible, and avoid calling startswith - #~ @profile - def parseImpl( self, instring, loc, doActions=True ): - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) ): - return loc+self.matchLen, self.match - raise ParseException(instring, loc, self.errmsg, self) -_L = Literal -ParserElement._literalStringClass = Literal - -class Keyword(Token): - """ - Token to exactly match a specified string as a keyword, that is, it must be - immediately followed by a non-keyword character. Compare with C{L{Literal}}: - - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. - - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} - Accepts two optional constructor arguments in addition to the keyword string: - - C{identChars} is a string of characters that would be valid identifier characters, - defaulting to all alphanumerics + "_" and "$" - - C{caseless} allows case-insensitive matching, default is C{False}. - - Example:: - Keyword("start").parseString("start") # -> ['start'] - Keyword("start").parseString("starting") # -> Exception - - For case-insensitive matching, use L{CaselessKeyword}. - """ - DEFAULT_KEYWORD_CHARS = alphanums+"_$" - - def __init__( self, matchString, identChars=None, caseless=False ): - super(Keyword,self).__init__() - if identChars is None: - identChars = Keyword.DEFAULT_KEYWORD_CHARS - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Keyword; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.name = '"%s"' % self.match - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - self.mayIndexError = False - self.caseless = caseless - if caseless: - self.caselessmatch = matchString.upper() - identChars = identChars.upper() - self.identChars = set(identChars) - - def parseImpl( self, instring, loc, doActions=True ): - if self.caseless: - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and - (loc == 0 or instring[loc-1].upper() not in self.identChars) ): - return loc+self.matchLen, self.match - else: - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and - (loc == 0 or instring[loc-1] not in self.identChars) ): - return loc+self.matchLen, self.match - raise ParseException(instring, loc, self.errmsg, self) - - def copy(self): - c = super(Keyword,self).copy() - c.identChars = Keyword.DEFAULT_KEYWORD_CHARS - return c - - @staticmethod - def setDefaultKeywordChars( chars ): - """Overrides the default Keyword chars - """ - Keyword.DEFAULT_KEYWORD_CHARS = chars - -class CaselessLiteral(Literal): - """ - Token to match a specified string, ignoring case of letters. - Note: the matched results will always be in the case of the given - match string, NOT the case of the input text. - - Example:: - OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] - - (Contrast with example for L{CaselessKeyword}.) - """ - def __init__( self, matchString ): - super(CaselessLiteral,self).__init__( matchString.upper() ) - # Preserve the defining literal. - self.returnString = matchString - self.name = "'%s'" % self.returnString - self.errmsg = "Expected " + self.name - - def parseImpl( self, instring, loc, doActions=True ): - if instring[ loc:loc+self.matchLen ].upper() == self.match: - return loc+self.matchLen, self.returnString - raise ParseException(instring, loc, self.errmsg, self) - -class CaselessKeyword(Keyword): - """ - Caseless version of L{Keyword}. - - Example:: - OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] - - (Contrast with example for L{CaselessLiteral}.) - """ - def __init__( self, matchString, identChars=None ): - super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) - - def parseImpl( self, instring, loc, doActions=True ): - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): - return loc+self.matchLen, self.match - raise ParseException(instring, loc, self.errmsg, self) - -class CloseMatch(Token): - """ - A variation on L{Literal} which matches "close" matches, that is, - strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: - - C{match_string} - string to be matched - - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match - - The results from a successful parse will contain the matched text from the input string and the following named results: - - C{mismatches} - a list of the positions within the match_string where mismatches were found - - C{original} - the original match_string used to compare against the input string - - If C{mismatches} is an empty list, then the match was an exact match. - - Example:: - patt = CloseMatch("ATCATCGAATGGA") - patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) - patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) - - # exact match - patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) - - # close match allowing up to 2 mismatches - patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) - patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) - """ - def __init__(self, match_string, maxMismatches=1): - super(CloseMatch,self).__init__() - self.name = match_string - self.match_string = match_string - self.maxMismatches = maxMismatches - self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) - self.mayIndexError = False - self.mayReturnEmpty = False - - def parseImpl( self, instring, loc, doActions=True ): - start = loc - instrlen = len(instring) - maxloc = start + len(self.match_string) - - if maxloc <= instrlen: - match_string = self.match_string - match_stringloc = 0 - mismatches = [] - maxMismatches = self.maxMismatches - - for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): - src,mat = s_m - if src != mat: - mismatches.append(match_stringloc) - if len(mismatches) > maxMismatches: - break - else: - loc = match_stringloc + 1 - results = ParseResults([instring[start:loc]]) - results['original'] = self.match_string - results['mismatches'] = mismatches - return loc, results - - raise ParseException(instring, loc, self.errmsg, self) - - -class Word(Token): - """ - Token for matching words composed of allowed character sets. - Defined with string containing all allowed initial characters, - an optional string containing allowed body characters (if omitted, - defaults to the initial character set), and an optional minimum, - maximum, and/or exact length. The default value for C{min} is 1 (a - minimum value < 1 is not valid); the default values for C{max} and C{exact} - are 0, meaning no maximum or exact length restriction. An optional - C{excludeChars} parameter can list characters that might be found in - the input C{bodyChars} string; useful to define a word of all printables - except for one or two characters, for instance. - - L{srange} is useful for defining custom character set strings for defining - C{Word} expressions, using range notation from regular expression character sets. - - A common mistake is to use C{Word} to match a specific literal string, as in - C{Word("Address")}. Remember that C{Word} uses the string argument to define - I{sets} of matchable characters. This expression would match "Add", "AAA", - "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. - To match an exact literal string, use L{Literal} or L{Keyword}. - - pyparsing includes helper strings for building Words: - - L{alphas} - - L{nums} - - L{alphanums} - - L{hexnums} - - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) - - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) - - L{printables} (any non-whitespace character) - - Example:: - # a word composed of digits - integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) - - # a word with a leading capital, and zero or more lowercase - capital_word = Word(alphas.upper(), alphas.lower()) - - # hostnames are alphanumeric, with leading alpha, and '-' - hostname = Word(alphas, alphanums+'-') - - # roman numeral (not a strict parser, accepts invalid mix of characters) - roman = Word("IVXLCDM") - - # any string of non-whitespace characters, except for ',' - csv_value = Word(printables, excludeChars=",") - """ - def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): - super(Word,self).__init__() - if excludeChars: - initChars = ''.join(c for c in initChars if c not in excludeChars) - if bodyChars: - bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) - self.initCharsOrig = initChars - self.initChars = set(initChars) - if bodyChars : - self.bodyCharsOrig = bodyChars - self.bodyChars = set(bodyChars) - else: - self.bodyCharsOrig = initChars - self.bodyChars = set(initChars) - - self.maxSpecified = max > 0 - - if min < 1: - raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.asKeyword = asKeyword - - if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): - if self.bodyCharsOrig == self.initCharsOrig: - self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) - elif len(self.initCharsOrig) == 1: - self.reString = "%s[%s]*" % \ - (re.escape(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - else: - self.reString = "[%s][%s]*" % \ - (_escapeRegexRangeChars(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - if self.asKeyword: - self.reString = r"\b"+self.reString+r"\b" - try: - self.re = re.compile( self.reString ) - except Exception: - self.re = None - - def parseImpl( self, instring, loc, doActions=True ): - if self.re: - result = self.re.match(instring,loc) - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - return loc, result.group() - - if not(instring[ loc ] in self.initChars): - raise ParseException(instring, loc, self.errmsg, self) - - start = loc - loc += 1 - instrlen = len(instring) - bodychars = self.bodyChars - maxloc = start + self.maxLen - maxloc = min( maxloc, instrlen ) - while loc < maxloc and instring[loc] in bodychars: - loc += 1 - - throwException = False - if loc - start < self.minLen: - throwException = True - if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: - throwException = True - if self.asKeyword: - if (start>0 and instring[start-1] in bodychars) or (loc4: - return s[:4]+"..." - else: - return s - - if ( self.initCharsOrig != self.bodyCharsOrig ): - self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) - else: - self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) - - return self.strRepr - - -class Regex(Token): - r""" - Token for matching strings that match a given regular expression. - Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. - If the given regex contains named groups (defined using C{(?P...)}), these will be preserved as - named parse results. - - Example:: - realnum = Regex(r"[+-]?\d+\.\d*") - date = Regex(r'(?P\d{4})-(?P\d\d?)-(?P\d\d?)') - # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression - roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") - """ - compiledREtype = type(re.compile("[A-Z]")) - def __init__( self, pattern, flags=0): - """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" - super(Regex,self).__init__() - - if isinstance(pattern, basestring): - if not pattern: - warnings.warn("null string passed to Regex; use Empty() instead", - SyntaxWarning, stacklevel=2) - - self.pattern = pattern - self.flags = flags - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % pattern, - SyntaxWarning, stacklevel=2) - raise - - elif isinstance(pattern, Regex.compiledREtype): - self.re = pattern - self.pattern = \ - self.reString = str(pattern) - self.flags = flags - - else: - raise ValueError("Regex may only be constructed with a string or a compiled RE object") - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - result = self.re.match(instring,loc) - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - d = result.groupdict() - ret = ParseResults(result.group()) - if d: - for k in d: - ret[k] = d[k] - return loc,ret - - def __str__( self ): - try: - return super(Regex,self).__str__() - except Exception: - pass - - if self.strRepr is None: - self.strRepr = "Re:(%s)" % repr(self.pattern) - - return self.strRepr - - -class QuotedString(Token): - r""" - Token for matching strings that are delimited by quoting characters. - - Defined with the following parameters: - - quoteChar - string of one or more characters defining the quote delimiting string - - escChar - character to escape quotes, typically backslash (default=C{None}) - - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) - - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) - - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) - - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) - - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) - - Example:: - qs = QuotedString('"') - print(qs.searchString('lsjdf "This is the quote" sldjf')) - complex_qs = QuotedString('{{', endQuoteChar='}}') - print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) - sql_qs = QuotedString('"', escQuote='""') - print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) - prints:: - [['This is the quote']] - [['This is the "quote"']] - [['This is the quote with "embedded" quotes']] - """ - def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): - super(QuotedString,self).__init__() - - # remove white space from quote chars - wont work anyway - quoteChar = quoteChar.strip() - if not quoteChar: - warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - if endQuoteChar is None: - endQuoteChar = quoteChar - else: - endQuoteChar = endQuoteChar.strip() - if not endQuoteChar: - warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - self.quoteChar = quoteChar - self.quoteCharLen = len(quoteChar) - self.firstQuoteChar = quoteChar[0] - self.endQuoteChar = endQuoteChar - self.endQuoteCharLen = len(endQuoteChar) - self.escChar = escChar - self.escQuote = escQuote - self.unquoteResults = unquoteResults - self.convertWhitespaceEscapes = convertWhitespaceEscapes - - if multiline: - self.flags = re.MULTILINE | re.DOTALL - self.pattern = r'%s(?:[^%s%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - else: - self.flags = 0 - self.pattern = r'%s(?:[^%s\n\r%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - if len(self.endQuoteChar) > 1: - self.pattern += ( - '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), - _escapeRegexRangeChars(self.endQuoteChar[i])) - for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' - ) - if escQuote: - self.pattern += (r'|(?:%s)' % re.escape(escQuote)) - if escChar: - self.pattern += (r'|(?:%s.)' % re.escape(escChar)) - self.escCharReplacePattern = re.escape(self.escChar)+"(.)" - self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, - SyntaxWarning, stacklevel=2) - raise - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayIndexError = False - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - ret = result.group() - - if self.unquoteResults: - - # strip off quotes - ret = ret[self.quoteCharLen:-self.endQuoteCharLen] - - if isinstance(ret,basestring): - # replace escaped whitespace - if '\\' in ret and self.convertWhitespaceEscapes: - ws_map = { - r'\t' : '\t', - r'\n' : '\n', - r'\f' : '\f', - r'\r' : '\r', - } - for wslit,wschar in ws_map.items(): - ret = ret.replace(wslit, wschar) - - # replace escaped characters - if self.escChar: - ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) - - # replace escaped quotes - if self.escQuote: - ret = ret.replace(self.escQuote, self.endQuoteChar) - - return loc, ret - - def __str__( self ): - try: - return super(QuotedString,self).__str__() - except Exception: - pass - - if self.strRepr is None: - self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) - - return self.strRepr - - -class CharsNotIn(Token): - """ - Token for matching words composed of characters I{not} in a given set (will - include whitespace in matched characters if not listed in the provided exclusion set - see example). - Defined with string containing all disallowed characters, and an optional - minimum, maximum, and/or exact length. The default value for C{min} is 1 (a - minimum value < 1 is not valid); the default values for C{max} and C{exact} - are 0, meaning no maximum or exact length restriction. - - Example:: - # define a comma-separated-value as anything that is not a ',' - csv_value = CharsNotIn(',') - print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) - prints:: - ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] - """ - def __init__( self, notChars, min=1, max=0, exact=0 ): - super(CharsNotIn,self).__init__() - self.skipWhitespace = False - self.notChars = notChars - - if min < 1: - raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = ( self.minLen == 0 ) - self.mayIndexError = False - - def parseImpl( self, instring, loc, doActions=True ): - if instring[loc] in self.notChars: - raise ParseException(instring, loc, self.errmsg, self) - - start = loc - loc += 1 - notchars = self.notChars - maxlen = min( start+self.maxLen, len(instring) ) - while loc < maxlen and \ - (instring[loc] not in notchars): - loc += 1 - - if loc - start < self.minLen: - raise ParseException(instring, loc, self.errmsg, self) - - return loc, instring[start:loc] - - def __str__( self ): - try: - return super(CharsNotIn, self).__str__() - except Exception: - pass - - if self.strRepr is None: - if len(self.notChars) > 4: - self.strRepr = "!W:(%s...)" % self.notChars[:4] - else: - self.strRepr = "!W:(%s)" % self.notChars - - return self.strRepr - -class White(Token): - """ - Special matching class for matching whitespace. Normally, whitespace is ignored - by pyparsing grammars. This class is included when some whitespace structures - are significant. Define with a string containing the whitespace characters to be - matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, - as defined for the C{L{Word}} class. - """ - whiteStrs = { - " " : "", - "\t": "", - "\n": "", - "\r": "", - "\f": "", - } - def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): - super(White,self).__init__() - self.matchWhite = ws - self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) - #~ self.leaveWhitespace() - self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) - self.mayReturnEmpty = True - self.errmsg = "Expected " + self.name - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - def parseImpl( self, instring, loc, doActions=True ): - if not(instring[ loc ] in self.matchWhite): - raise ParseException(instring, loc, self.errmsg, self) - start = loc - loc += 1 - maxloc = start + self.maxLen - maxloc = min( maxloc, len(instring) ) - while loc < maxloc and instring[loc] in self.matchWhite: - loc += 1 - - if loc - start < self.minLen: - raise ParseException(instring, loc, self.errmsg, self) - - return loc, instring[start:loc] - - -class _PositionToken(Token): - def __init__( self ): - super(_PositionToken,self).__init__() - self.name=self.__class__.__name__ - self.mayReturnEmpty = True - self.mayIndexError = False - -class GoToColumn(_PositionToken): - """ - Token to advance to a specific column of input text; useful for tabular report scraping. - """ - def __init__( self, colno ): - super(GoToColumn,self).__init__() - self.col = colno - - def preParse( self, instring, loc ): - if col(loc,instring) != self.col: - instrlen = len(instring) - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : - loc += 1 - return loc - - def parseImpl( self, instring, loc, doActions=True ): - thiscol = col( loc, instring ) - if thiscol > self.col: - raise ParseException( instring, loc, "Text not in expected column", self ) - newloc = loc + self.col - thiscol - ret = instring[ loc: newloc ] - return newloc, ret - - -class LineStart(_PositionToken): - """ - Matches if current position is at the beginning of a line within the parse string - - Example:: - - test = '''\ - AAA this line - AAA and this line - AAA but not this one - B AAA and definitely not this one - ''' - - for t in (LineStart() + 'AAA' + restOfLine).searchString(test): - print(t) - - Prints:: - ['AAA', ' this line'] - ['AAA', ' and this line'] - - """ - def __init__( self ): - super(LineStart,self).__init__() - self.errmsg = "Expected start of line" - - def parseImpl( self, instring, loc, doActions=True ): - if col(loc, instring) == 1: - return loc, [] - raise ParseException(instring, loc, self.errmsg, self) - -class LineEnd(_PositionToken): - """ - Matches if current position is at the end of a line within the parse string - """ - def __init__( self ): - super(LineEnd,self).__init__() - self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) - self.errmsg = "Expected end of line" - - def parseImpl( self, instring, loc, doActions=True ): - if loc len(instring): - return loc, [] - else: - raise ParseException(instring, loc, self.errmsg, self) - -class WordStart(_PositionToken): - """ - Matches if the current position is at the beginning of a Word, and - is not preceded by any character in a given set of C{wordChars} - (default=C{printables}). To emulate the C{\b} behavior of regular expressions, - use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of - the string being parsed, or at the beginning of a line. - """ - def __init__(self, wordChars = printables): - super(WordStart,self).__init__() - self.wordChars = set(wordChars) - self.errmsg = "Not at the start of a word" - - def parseImpl(self, instring, loc, doActions=True ): - if loc != 0: - if (instring[loc-1] in self.wordChars or - instring[loc] not in self.wordChars): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - -class WordEnd(_PositionToken): - """ - Matches if the current position is at the end of a Word, and - is not followed by any character in a given set of C{wordChars} - (default=C{printables}). To emulate the C{\b} behavior of regular expressions, - use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of - the string being parsed, or at the end of a line. - """ - def __init__(self, wordChars = printables): - super(WordEnd,self).__init__() - self.wordChars = set(wordChars) - self.skipWhitespace = False - self.errmsg = "Not at the end of a word" - - def parseImpl(self, instring, loc, doActions=True ): - instrlen = len(instring) - if instrlen>0 and loc maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - else: - # save match among all matches, to retry longest to shortest - matches.append((loc2, e)) - - if matches: - matches.sort(key=lambda x: -x[0]) - for _,e in matches: - try: - return e._parse( instring, loc, doActions ) - except ParseException as err: - err.__traceback__ = None - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - - if maxException is not None: - maxException.msg = self.errmsg - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - - def __ixor__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #Or( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class MatchFirst(ParseExpression): - """ - Requires that at least one C{ParseExpression} is found. - If two expressions match, the first one listed is the one that will match. - May be constructed using the C{'|'} operator. - - Example:: - # construct MatchFirst using '|' operator - - # watch the order of expressions to match - number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) - print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] - - # put more selective expression first - number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) - print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] - """ - def __init__( self, exprs, savelist = False ): - super(MatchFirst,self).__init__(exprs, savelist) - if self.exprs: - self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) - else: - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - maxExcLoc = -1 - maxException = None - for e in self.exprs: - try: - ret = e._parse( instring, loc, doActions ) - return ret - except ParseException as err: - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - - # only got here if no expression matched, raise exception for match that made it the furthest - else: - if maxException is not None: - maxException.msg = self.errmsg - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - def __ior__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #MatchFirst( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class Each(ParseExpression): - """ - Requires all given C{ParseExpression}s to be found, but in any order. - Expressions may be separated by whitespace. - May be constructed using the C{'&'} operator. - - Example:: - color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") - shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") - integer = Word(nums) - shape_attr = "shape:" + shape_type("shape") - posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") - color_attr = "color:" + color("color") - size_attr = "size:" + integer("size") - - # use Each (using operator '&') to accept attributes in any order - # (shape and posn are required, color and size are optional) - shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) - - shape_spec.runTests(''' - shape: SQUARE color: BLACK posn: 100, 120 - shape: CIRCLE size: 50 color: BLUE posn: 50,80 - color:GREEN size:20 shape:TRIANGLE posn:20,40 - ''' - ) - prints:: - shape: SQUARE color: BLACK posn: 100, 120 - ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] - - color: BLACK - - posn: ['100', ',', '120'] - - x: 100 - - y: 120 - - shape: SQUARE - - - shape: CIRCLE size: 50 color: BLUE posn: 50,80 - ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] - - color: BLUE - - posn: ['50', ',', '80'] - - x: 50 - - y: 80 - - shape: CIRCLE - - size: 50 - - - color: GREEN size: 20 shape: TRIANGLE posn: 20,40 - ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] - - color: GREEN - - posn: ['20', ',', '40'] - - x: 20 - - y: 40 - - shape: TRIANGLE - - size: 20 - """ - def __init__( self, exprs, savelist = True ): - super(Each,self).__init__(exprs, savelist) - self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - self.skipWhitespace = True - self.initExprGroups = True - - def parseImpl( self, instring, loc, doActions=True ): - if self.initExprGroups: - self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) - opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] - opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] - self.optionals = opt1 + opt2 - self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] - self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] - self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] - self.required += self.multirequired - self.initExprGroups = False - tmpLoc = loc - tmpReqd = self.required[:] - tmpOpt = self.optionals[:] - matchOrder = [] - - keepMatching = True - while keepMatching: - tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired - failed = [] - for e in tmpExprs: - try: - tmpLoc = e.tryParse( instring, tmpLoc ) - except ParseException: - failed.append(e) - else: - matchOrder.append(self.opt1map.get(id(e),e)) - if e in tmpReqd: - tmpReqd.remove(e) - elif e in tmpOpt: - tmpOpt.remove(e) - if len(failed) == len(tmpExprs): - keepMatching = False - - if tmpReqd: - missing = ", ".join(_ustr(e) for e in tmpReqd) - raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) - - # add any unmatched Optionals, in case they have default values defined - matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] - - resultlist = [] - for e in matchOrder: - loc,results = e._parse(instring,loc,doActions) - resultlist.append(results) - - finalResults = sum(resultlist, ParseResults([])) - return loc, finalResults - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class ParseElementEnhance(ParserElement): - """ - Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. - """ - def __init__( self, expr, savelist=False ): - super(ParseElementEnhance,self).__init__(savelist) - if isinstance( expr, basestring ): - if issubclass(ParserElement._literalStringClass, Token): - expr = ParserElement._literalStringClass(expr) - else: - expr = ParserElement._literalStringClass(Literal(expr)) - self.expr = expr - self.strRepr = None - if expr is not None: - self.mayIndexError = expr.mayIndexError - self.mayReturnEmpty = expr.mayReturnEmpty - self.setWhitespaceChars( expr.whiteChars ) - self.skipWhitespace = expr.skipWhitespace - self.saveAsList = expr.saveAsList - self.callPreparse = expr.callPreparse - self.ignoreExprs.extend(expr.ignoreExprs) - - def parseImpl( self, instring, loc, doActions=True ): - if self.expr is not None: - return self.expr._parse( instring, loc, doActions, callPreParse=False ) - else: - raise ParseException("",loc,self.errmsg,self) - - def leaveWhitespace( self ): - self.skipWhitespace = False - self.expr = self.expr.copy() - if self.expr is not None: - self.expr.leaveWhitespace() - return self - - def ignore( self, other ): - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - else: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - return self - - def streamline( self ): - super(ParseElementEnhance,self).streamline() - if self.expr is not None: - self.expr.streamline() - return self - - def checkRecursion( self, parseElementList ): - if self in parseElementList: - raise RecursiveGrammarException( parseElementList+[self] ) - subRecCheckList = parseElementList[:] + [ self ] - if self.expr is not None: - self.expr.checkRecursion( subRecCheckList ) - - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion( [] ) - - def __str__( self ): - try: - return super(ParseElementEnhance,self).__str__() - except Exception: - pass - - if self.strRepr is None and self.expr is not None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) - return self.strRepr - - -class FollowedBy(ParseElementEnhance): - """ - Lookahead matching of the given parse expression. C{FollowedBy} - does I{not} advance the parsing position within the input string, it only - verifies that the specified parse expression matches at the current - position. C{FollowedBy} always returns a null token list. - - Example:: - # use FollowedBy to match a label only if it is followed by a ':' - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - - OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() - prints:: - [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] - """ - def __init__( self, expr ): - super(FollowedBy,self).__init__(expr) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - self.expr.tryParse( instring, loc ) - return loc, [] - - -class NotAny(ParseElementEnhance): - """ - Lookahead to disallow matching with the given parse expression. C{NotAny} - does I{not} advance the parsing position within the input string, it only - verifies that the specified parse expression does I{not} match at the current - position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} - always returns a null token list. May be constructed using the '~' operator. - - Example:: - - """ - def __init__( self, expr ): - super(NotAny,self).__init__(expr) - #~ self.leaveWhitespace() - self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs - self.mayReturnEmpty = True - self.errmsg = "Found unwanted token, "+_ustr(self.expr) - - def parseImpl( self, instring, loc, doActions=True ): - if self.expr.canParseNext(instring, loc): - raise ParseException(instring, loc, self.errmsg, self) - return loc, [] - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "~{" + _ustr(self.expr) + "}" - - return self.strRepr - -class _MultipleMatch(ParseElementEnhance): - def __init__( self, expr, stopOn=None): - super(_MultipleMatch, self).__init__(expr) - self.saveAsList = True - ender = stopOn - if isinstance(ender, basestring): - ender = ParserElement._literalStringClass(ender) - self.not_ender = ~ender if ender is not None else None - - def parseImpl( self, instring, loc, doActions=True ): - self_expr_parse = self.expr._parse - self_skip_ignorables = self._skipIgnorables - check_ender = self.not_ender is not None - if check_ender: - try_not_ender = self.not_ender.tryParse - - # must be at least one (but first see if we are the stopOn sentinel; - # if so, fail) - if check_ender: - try_not_ender(instring, loc) - loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) - try: - hasIgnoreExprs = (not not self.ignoreExprs) - while 1: - if check_ender: - try_not_ender(instring, loc) - if hasIgnoreExprs: - preloc = self_skip_ignorables( instring, loc ) - else: - preloc = loc - loc, tmptokens = self_expr_parse( instring, preloc, doActions ) - if tmptokens or tmptokens.haskeys(): - tokens += tmptokens - except (ParseException,IndexError): - pass - - return loc, tokens - -class OneOrMore(_MultipleMatch): - """ - Repetition of one or more of the given expression. - - Parameters: - - expr - expression that must match one or more times - - stopOn - (default=C{None}) - expression for a terminating sentinel - (only required if the sentinel would ordinarily match the repetition - expression) - - Example:: - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) - - text = "shape: SQUARE posn: upper left color: BLACK" - OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] - - # use stopOn attribute for OneOrMore to avoid reading label string as part of the data - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] - - # could also be written as - (attr_expr * (1,)).parseString(text).pprint() - """ - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + _ustr(self.expr) + "}..." - - return self.strRepr - -class ZeroOrMore(_MultipleMatch): - """ - Optional repetition of zero or more of the given expression. - - Parameters: - - expr - expression that must match zero or more times - - stopOn - (default=C{None}) - expression for a terminating sentinel - (only required if the sentinel would ordinarily match the repetition - expression) - - Example: similar to L{OneOrMore} - """ - def __init__( self, expr, stopOn=None): - super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - try: - return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) - except (ParseException,IndexError): - return loc, [] - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]..." - - return self.strRepr - -class _NullToken(object): - def __bool__(self): - return False - __nonzero__ = __bool__ - def __str__(self): - return "" - -_optionalNotMatched = _NullToken() -class Optional(ParseElementEnhance): - """ - Optional matching of the given expression. - - Parameters: - - expr - expression that must match zero or more times - - default (optional) - value to be returned if the optional expression is not found. - - Example:: - # US postal code can be a 5-digit zip, plus optional 4-digit qualifier - zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) - zip.runTests(''' - # traditional ZIP code - 12345 - - # ZIP+4 form - 12101-0001 - - # invalid ZIP - 98765- - ''') - prints:: - # traditional ZIP code - 12345 - ['12345'] - - # ZIP+4 form - 12101-0001 - ['12101-0001'] - - # invalid ZIP - 98765- - ^ - FAIL: Expected end of text (at char 5), (line:1, col:6) - """ - def __init__( self, expr, default=_optionalNotMatched ): - super(Optional,self).__init__( expr, savelist=False ) - self.saveAsList = self.expr.saveAsList - self.defaultValue = default - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - try: - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - except (ParseException,IndexError): - if self.defaultValue is not _optionalNotMatched: - if self.expr.resultsName: - tokens = ParseResults([ self.defaultValue ]) - tokens[self.expr.resultsName] = self.defaultValue - else: - tokens = [ self.defaultValue ] - else: - tokens = [] - return loc, tokens - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]" - - return self.strRepr - -class SkipTo(ParseElementEnhance): - """ - Token for skipping over all undefined text until the matched expression is found. - - Parameters: - - expr - target expression marking the end of the data to be skipped - - include - (default=C{False}) if True, the target expression is also parsed - (the skipped text and target expression are returned as a 2-element list). - - ignore - (default=C{None}) used to define grammars (typically quoted strings and - comments) that might contain false matches to the target expression - - failOn - (default=C{None}) define expressions that are not allowed to be - included in the skipped test; if found before the target expression is found, - the SkipTo is not a match - - Example:: - report = ''' - Outstanding Issues Report - 1 Jan 2000 - - # | Severity | Description | Days Open - -----+----------+-------------------------------------------+----------- - 101 | Critical | Intermittent system crash | 6 - 94 | Cosmetic | Spelling error on Login ('log|n') | 14 - 79 | Minor | System slow when running too many reports | 47 - ''' - integer = Word(nums) - SEP = Suppress('|') - # use SkipTo to simply match everything up until the next SEP - # - ignore quoted strings, so that a '|' character inside a quoted string does not match - # - parse action will call token.strip() for each matched token, i.e., the description body - string_data = SkipTo(SEP, ignore=quotedString) - string_data.setParseAction(tokenMap(str.strip)) - ticket_expr = (integer("issue_num") + SEP - + string_data("sev") + SEP - + string_data("desc") + SEP - + integer("days_open")) - - for tkt in ticket_expr.searchString(report): - print tkt.dump() - prints:: - ['101', 'Critical', 'Intermittent system crash', '6'] - - days_open: 6 - - desc: Intermittent system crash - - issue_num: 101 - - sev: Critical - ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] - - days_open: 14 - - desc: Spelling error on Login ('log|n') - - issue_num: 94 - - sev: Cosmetic - ['79', 'Minor', 'System slow when running too many reports', '47'] - - days_open: 47 - - desc: System slow when running too many reports - - issue_num: 79 - - sev: Minor - """ - def __init__( self, other, include=False, ignore=None, failOn=None ): - super( SkipTo, self ).__init__( other ) - self.ignoreExpr = ignore - self.mayReturnEmpty = True - self.mayIndexError = False - self.includeMatch = include - self.asList = False - if isinstance(failOn, basestring): - self.failOn = ParserElement._literalStringClass(failOn) - else: - self.failOn = failOn - self.errmsg = "No match found for "+_ustr(self.expr) - - def parseImpl( self, instring, loc, doActions=True ): - startloc = loc - instrlen = len(instring) - expr = self.expr - expr_parse = self.expr._parse - self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None - self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None - - tmploc = loc - while tmploc <= instrlen: - if self_failOn_canParseNext is not None: - # break if failOn expression matches - if self_failOn_canParseNext(instring, tmploc): - break - - if self_ignoreExpr_tryParse is not None: - # advance past ignore expressions - while 1: - try: - tmploc = self_ignoreExpr_tryParse(instring, tmploc) - except ParseBaseException: - break - - try: - expr_parse(instring, tmploc, doActions=False, callPreParse=False) - except (ParseException, IndexError): - # no match, advance loc in string - tmploc += 1 - else: - # matched skipto expr, done - break - - else: - # ran off the end of the input string without matching skipto expr, fail - raise ParseException(instring, loc, self.errmsg, self) - - # build up return values - loc = tmploc - skiptext = instring[startloc:loc] - skipresult = ParseResults(skiptext) - - if self.includeMatch: - loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) - skipresult += mat - - return loc, skipresult - -class Forward(ParseElementEnhance): - """ - Forward declaration of an expression to be defined later - - used for recursive grammars, such as algebraic infix notation. - When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. - - Note: take care when assigning to C{Forward} not to overlook precedence of operators. - Specifically, '|' has a lower precedence than '<<', so that:: - fwdExpr << a | b | c - will actually be evaluated as:: - (fwdExpr << a) | b | c - thereby leaving b and c out as parseable alternatives. It is recommended that you - explicitly group the values inserted into the C{Forward}:: - fwdExpr << (a | b | c) - Converting to use the '<<=' operator instead will avoid this problem. - - See L{ParseResults.pprint} for an example of a recursive parser created using - C{Forward}. - """ - def __init__( self, other=None ): - super(Forward,self).__init__( other, savelist=False ) - - def __lshift__( self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass(other) - self.expr = other - self.strRepr = None - self.mayIndexError = self.expr.mayIndexError - self.mayReturnEmpty = self.expr.mayReturnEmpty - self.setWhitespaceChars( self.expr.whiteChars ) - self.skipWhitespace = self.expr.skipWhitespace - self.saveAsList = self.expr.saveAsList - self.ignoreExprs.extend(self.expr.ignoreExprs) - return self - - def __ilshift__(self, other): - return self << other - - def leaveWhitespace( self ): - self.skipWhitespace = False - return self - - def streamline( self ): - if not self.streamlined: - self.streamlined = True - if self.expr is not None: - self.expr.streamline() - return self - - def validate( self, validateTrace=[] ): - if self not in validateTrace: - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion([]) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - return self.__class__.__name__ + ": ..." - - # stubbed out for now - creates awful memory and perf issues - self._revertClass = self.__class__ - self.__class__ = _ForwardNoRecurse - try: - if self.expr is not None: - retString = _ustr(self.expr) - else: - retString = "None" - finally: - self.__class__ = self._revertClass - return self.__class__.__name__ + ": " + retString - - def copy(self): - if self.expr is not None: - return super(Forward,self).copy() - else: - ret = Forward() - ret <<= self - return ret - -class _ForwardNoRecurse(Forward): - def __str__( self ): - return "..." - -class TokenConverter(ParseElementEnhance): - """ - Abstract subclass of C{ParseExpression}, for converting parsed results. - """ - def __init__( self, expr, savelist=False ): - super(TokenConverter,self).__init__( expr )#, savelist ) - self.saveAsList = False - -class Combine(TokenConverter): - """ - Converter to concatenate all matching tokens to a single string. - By default, the matching patterns must also be contiguous in the input string; - this can be disabled by specifying C{'adjacent=False'} in the constructor. - - Example:: - real = Word(nums) + '.' + Word(nums) - print(real.parseString('3.1416')) # -> ['3', '.', '1416'] - # will also erroneously match the following - print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] - - real = Combine(Word(nums) + '.' + Word(nums)) - print(real.parseString('3.1416')) # -> ['3.1416'] - # no match when there are internal spaces - print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) - """ - def __init__( self, expr, joinString="", adjacent=True ): - super(Combine,self).__init__( expr ) - # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself - if adjacent: - self.leaveWhitespace() - self.adjacent = adjacent - self.skipWhitespace = True - self.joinString = joinString - self.callPreparse = True - - def ignore( self, other ): - if self.adjacent: - ParserElement.ignore(self, other) - else: - super( Combine, self).ignore( other ) - return self - - def postParse( self, instring, loc, tokenlist ): - retToks = tokenlist.copy() - del retToks[:] - retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) - - if self.resultsName and retToks.haskeys(): - return [ retToks ] - else: - return retToks - -class Group(TokenConverter): - """ - Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. - - Example:: - ident = Word(alphas) - num = Word(nums) - term = ident | num - func = ident + Optional(delimitedList(term)) - print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] - - func = ident + Group(Optional(delimitedList(term))) - print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] - """ - def __init__( self, expr ): - super(Group,self).__init__( expr ) - self.saveAsList = True - - def postParse( self, instring, loc, tokenlist ): - return [ tokenlist ] - -class Dict(TokenConverter): - """ - Converter to return a repetitive expression as a list, but also as a dictionary. - Each element can also be referenced using the first token in the expression as its key. - Useful for tabular report scraping when the first column can be used as a item key. - - Example:: - data_word = Word(alphas) - label = data_word + FollowedBy(':') - attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) - - text = "shape: SQUARE posn: upper left color: light blue texture: burlap" - attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - - # print attributes as plain groups - print(OneOrMore(attr_expr).parseString(text).dump()) - - # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names - result = Dict(OneOrMore(Group(attr_expr))).parseString(text) - print(result.dump()) - - # access named fields as dict entries, or output as dict - print(result['shape']) - print(result.asDict()) - prints:: - ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] - - [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - - color: light blue - - posn: upper left - - shape: SQUARE - - texture: burlap - SQUARE - {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} - See more examples at L{ParseResults} of accessing fields by results name. - """ - def __init__( self, expr ): - super(Dict,self).__init__( expr ) - self.saveAsList = True - - def postParse( self, instring, loc, tokenlist ): - for i,tok in enumerate(tokenlist): - if len(tok) == 0: - continue - ikey = tok[0] - if isinstance(ikey,int): - ikey = _ustr(tok[0]).strip() - if len(tok)==1: - tokenlist[ikey] = _ParseResultsWithOffset("",i) - elif len(tok)==2 and not isinstance(tok[1],ParseResults): - tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) - else: - dictvalue = tok.copy() #ParseResults(i) - del dictvalue[0] - if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) - else: - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) - - if self.resultsName: - return [ tokenlist ] - else: - return tokenlist - - -class Suppress(TokenConverter): - """ - Converter for ignoring the results of a parsed expression. - - Example:: - source = "a, b, c,d" - wd = Word(alphas) - wd_list1 = wd + ZeroOrMore(',' + wd) - print(wd_list1.parseString(source)) - - # often, delimiters that are useful during parsing are just in the - # way afterward - use Suppress to keep them out of the parsed output - wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) - print(wd_list2.parseString(source)) - prints:: - ['a', ',', 'b', ',', 'c', ',', 'd'] - ['a', 'b', 'c', 'd'] - (See also L{delimitedList}.) - """ - def postParse( self, instring, loc, tokenlist ): - return [] - - def suppress( self ): - return self - - -class OnlyOnce(object): - """ - Wrapper for parse actions, to ensure they are only called once. - """ - def __init__(self, methodCall): - self.callable = _trim_arity(methodCall) - self.called = False - def __call__(self,s,l,t): - if not self.called: - results = self.callable(s,l,t) - self.called = True - return results - raise ParseException(s,l,"") - def reset(self): - self.called = False - -def traceParseAction(f): - """ - Decorator for debugging parse actions. - - When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} - When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. - - Example:: - wd = Word(alphas) - - @traceParseAction - def remove_duplicate_chars(tokens): - return ''.join(sorted(set(''.join(tokens)))) - - wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) - print(wds.parseString("slkdjs sld sldd sdlf sdljf")) - prints:: - >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) - <3: - thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc - sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) - try: - ret = f(*paArgs) - except Exception as exc: - sys.stderr.write( "< ['aa', 'bb', 'cc'] - delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] - """ - dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." - if combine: - return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) - else: - return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) - -def countedArray( expr, intExpr=None ): - """ - Helper to define a counted list of expressions. - This helper defines a pattern of the form:: - integer expr expr expr... - where the leading integer tells how many expr expressions follow. - The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. - - If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. - - Example:: - countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] - - # in this parser, the leading integer value is given in binary, - # '10' indicating that 2 values are in the array - binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) - countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] - """ - arrayExpr = Forward() - def countFieldParseAction(s,l,t): - n = t[0] - arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) - return [] - if intExpr is None: - intExpr = Word(nums).setParseAction(lambda t:int(t[0])) - else: - intExpr = intExpr.copy() - intExpr.setName("arrayLen") - intExpr.addParseAction(countFieldParseAction, callDuringTry=True) - return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') - -def _flatten(L): - ret = [] - for i in L: - if isinstance(i,list): - ret.extend(_flatten(i)) - else: - ret.append(i) - return ret - -def matchPreviousLiteral(expr): - """ - Helper to define an expression that is indirectly defined from - the tokens matched in a previous expression, that is, it looks - for a 'repeat' of a previous expression. For example:: - first = Word(nums) - second = matchPreviousLiteral(first) - matchExpr = first + ":" + second - will match C{"1:1"}, but not C{"1:2"}. Because this matches a - previous literal, will also match the leading C{"1:1"} in C{"1:10"}. - If this is not desired, use C{matchPreviousExpr}. - Do I{not} use with packrat parsing enabled. - """ - rep = Forward() - def copyTokenToRepeater(s,l,t): - if t: - if len(t) == 1: - rep << t[0] - else: - # flatten t tokens - tflat = _flatten(t.asList()) - rep << And(Literal(tt) for tt in tflat) - else: - rep << Empty() - expr.addParseAction(copyTokenToRepeater, callDuringTry=True) - rep.setName('(prev) ' + _ustr(expr)) - return rep - -def matchPreviousExpr(expr): - """ - Helper to define an expression that is indirectly defined from - the tokens matched in a previous expression, that is, it looks - for a 'repeat' of a previous expression. For example:: - first = Word(nums) - second = matchPreviousExpr(first) - matchExpr = first + ":" + second - will match C{"1:1"}, but not C{"1:2"}. Because this matches by - expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; - the expressions are evaluated first, and then compared, so - C{"1"} is compared with C{"10"}. - Do I{not} use with packrat parsing enabled. - """ - rep = Forward() - e2 = expr.copy() - rep <<= e2 - def copyTokenToRepeater(s,l,t): - matchTokens = _flatten(t.asList()) - def mustMatchTheseTokens(s,l,t): - theseTokens = _flatten(t.asList()) - if theseTokens != matchTokens: - raise ParseException("",0,"") - rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) - expr.addParseAction(copyTokenToRepeater, callDuringTry=True) - rep.setName('(prev) ' + _ustr(expr)) - return rep - -def _escapeRegexRangeChars(s): - #~ escape these chars: ^-] - for c in r"\^-]": - s = s.replace(c,_bslash+c) - s = s.replace("\n",r"\n") - s = s.replace("\t",r"\t") - return _ustr(s) - -def oneOf( strs, caseless=False, useRegex=True ): - """ - Helper to quickly define a set of alternative Literals, and makes sure to do - longest-first testing when there is a conflict, regardless of the input order, - but returns a C{L{MatchFirst}} for best performance. - - Parameters: - - strs - a string of space-delimited literals, or a collection of string literals - - caseless - (default=C{False}) - treat all literals as caseless - - useRegex - (default=C{True}) - as an optimization, will generate a Regex - object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or - if creating a C{Regex} raises an exception) - - Example:: - comp_oper = oneOf("< = > <= >= !=") - var = Word(alphas) - number = Word(nums) - term = var | number - comparison_expr = term + comp_oper + term - print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) - prints:: - [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] - """ - if caseless: - isequal = ( lambda a,b: a.upper() == b.upper() ) - masks = ( lambda a,b: b.upper().startswith(a.upper()) ) - parseElementClass = CaselessLiteral - else: - isequal = ( lambda a,b: a == b ) - masks = ( lambda a,b: b.startswith(a) ) - parseElementClass = Literal - - symbols = [] - if isinstance(strs,basestring): - symbols = strs.split() - elif isinstance(strs, Iterable): - symbols = list(strs) - else: - warnings.warn("Invalid argument to oneOf, expected string or iterable", - SyntaxWarning, stacklevel=2) - if not symbols: - return NoMatch() - - i = 0 - while i < len(symbols)-1: - cur = symbols[i] - for j,other in enumerate(symbols[i+1:]): - if ( isequal(other, cur) ): - del symbols[i+j+1] - break - elif ( masks(cur, other) ): - del symbols[i+j+1] - symbols.insert(i,other) - cur = other - break - else: - i += 1 - - if not caseless and useRegex: - #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) - try: - if len(symbols)==len("".join(symbols)): - return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) - else: - return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) - except Exception: - warnings.warn("Exception creating Regex for oneOf, building MatchFirst", - SyntaxWarning, stacklevel=2) - - - # last resort, just use MatchFirst - return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) - -def dictOf( key, value ): - """ - Helper to easily and clearly define a dictionary by specifying the respective patterns - for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens - in the proper order. The key pattern can include delimiting markers or punctuation, - as long as they are suppressed, thereby leaving the significant key text. The value - pattern can include named results, so that the C{Dict} results can include named token - fields. - - Example:: - text = "shape: SQUARE posn: upper left color: light blue texture: burlap" - attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) - print(OneOrMore(attr_expr).parseString(text).dump()) - - attr_label = label - attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) - - # similar to Dict, but simpler call format - result = dictOf(attr_label, attr_value).parseString(text) - print(result.dump()) - print(result['shape']) - print(result.shape) # object attribute access works too - print(result.asDict()) - prints:: - [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - - color: light blue - - posn: upper left - - shape: SQUARE - - texture: burlap - SQUARE - SQUARE - {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} - """ - return Dict( ZeroOrMore( Group ( key + value ) ) ) - -def originalTextFor(expr, asString=True): - """ - Helper to return the original, untokenized text for a given expression. Useful to - restore the parsed fields of an HTML start tag into the raw tag text itself, or to - revert separate tokens with intervening whitespace back to the original matching - input text. By default, returns astring containing the original parsed text. - - If the optional C{asString} argument is passed as C{False}, then the return value is a - C{L{ParseResults}} containing any results names that were originally matched, and a - single token containing the original matched text from the input string. So if - the expression passed to C{L{originalTextFor}} contains expressions with defined - results names, you must set C{asString} to C{False} if you want to preserve those - results name values. - - Example:: - src = "this is test bold text normal text " - for tag in ("b","i"): - opener,closer = makeHTMLTags(tag) - patt = originalTextFor(opener + SkipTo(closer) + closer) - print(patt.searchString(src)[0]) - prints:: - [' bold text '] - ['text'] - """ - locMarker = Empty().setParseAction(lambda s,loc,t: loc) - endlocMarker = locMarker.copy() - endlocMarker.callPreparse = False - matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") - if asString: - extractText = lambda s,l,t: s[t._original_start:t._original_end] - else: - def extractText(s,l,t): - t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] - matchExpr.setParseAction(extractText) - matchExpr.ignoreExprs = expr.ignoreExprs - return matchExpr - -def ungroup(expr): - """ - Helper to undo pyparsing's default grouping of And expressions, even - if all but one are non-empty. - """ - return TokenConverter(expr).setParseAction(lambda t:t[0]) - -def locatedExpr(expr): - """ - Helper to decorate a returned token with its starting and ending locations in the input string. - This helper adds the following results names: - - locn_start = location where matched expression begins - - locn_end = location where matched expression ends - - value = the actual parsed results - - Be careful if the input text contains C{} characters, you may want to call - C{L{ParserElement.parseWithTabs}} - - Example:: - wd = Word(alphas) - for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): - print(match) - prints:: - [[0, 'ljsdf', 5]] - [[8, 'lksdjjf', 15]] - [[18, 'lkkjj', 23]] - """ - locator = Empty().setParseAction(lambda s,l,t: l) - return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) - - -# convenience constants for positional expressions -empty = Empty().setName("empty") -lineStart = LineStart().setName("lineStart") -lineEnd = LineEnd().setName("lineEnd") -stringStart = StringStart().setName("stringStart") -stringEnd = StringEnd().setName("stringEnd") - -_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) -_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) -_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) -_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) -_charRange = Group(_singleChar + Suppress("-") + _singleChar) -_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" - -def srange(s): - r""" - Helper to easily define string ranges for use in Word construction. Borrows - syntax from regexp '[]' string range definitions:: - srange("[0-9]") -> "0123456789" - srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" - srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" - The input string must be enclosed in []'s, and the returned string is the expanded - character set joined into a single string. - The values enclosed in the []'s may be: - - a single character - - an escaped character with a leading backslash (such as C{\-} or C{\]}) - - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) - (C{\0x##} is also supported for backwards compatibility) - - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) - - a range of any of the above, separated by a dash (C{'a-z'}, etc.) - - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) - """ - _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) - try: - return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) - except Exception: - return "" - -def matchOnlyAtCol(n): - """ - Helper method for defining parse actions that require matching at a specific - column in the input text. - """ - def verifyCol(strg,locn,toks): - if col(locn,strg) != n: - raise ParseException(strg,locn,"matched token not at column %d" % n) - return verifyCol - -def replaceWith(replStr): - """ - Helper method for common parse actions that simply return a literal value. Especially - useful when used with C{L{transformString}()}. - - Example:: - num = Word(nums).setParseAction(lambda toks: int(toks[0])) - na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) - term = na | num - - OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] - """ - return lambda s,l,t: [replStr] - -def removeQuotes(s,l,t): - """ - Helper parse action for removing quotation marks from parsed quoted strings. - - Example:: - # by default, quotation marks are included in parsed results - quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] - - # use removeQuotes to strip quotation marks from parsed results - quotedString.setParseAction(removeQuotes) - quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] - """ - return t[0][1:-1] - -def tokenMap(func, *args): - """ - Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional - args are passed, they are forwarded to the given function as additional arguments after - the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the - parsed data to an integer using base 16. - - Example (compare the last to example in L{ParserElement.transformString}:: - hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) - hex_ints.runTests(''' - 00 11 22 aa FF 0a 0d 1a - ''') - - upperword = Word(alphas).setParseAction(tokenMap(str.upper)) - OneOrMore(upperword).runTests(''' - my kingdom for a horse - ''') - - wd = Word(alphas).setParseAction(tokenMap(str.title)) - OneOrMore(wd).setParseAction(' '.join).runTests(''' - now is the winter of our discontent made glorious summer by this sun of york - ''') - prints:: - 00 11 22 aa FF 0a 0d 1a - [0, 17, 34, 170, 255, 10, 13, 26] - - my kingdom for a horse - ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] - - now is the winter of our discontent made glorious summer by this sun of york - ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] - """ - def pa(s,l,t): - return [func(tokn, *args) for tokn in t] - - try: - func_name = getattr(func, '__name__', - getattr(func, '__class__').__name__) - except Exception: - func_name = str(func) - pa.__name__ = func_name - - return pa - -upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) -"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" - -downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) -"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" - -def _makeTags(tagStr, xml): - """Internal helper to construct opening and closing tag expressions, given a tag name""" - if isinstance(tagStr,basestring): - resname = tagStr - tagStr = Keyword(tagStr, caseless=not xml) - else: - resname = tagStr.name - - tagAttrName = Word(alphas,alphanums+"_-:") - if (xml): - tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) - openTag = Suppress("<") + tagStr("tag") + \ - Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - else: - printablesLessRAbrack = "".join(c for c in printables if c not in ">") - tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) - openTag = Suppress("<") + tagStr("tag") + \ - Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ - Optional( Suppress("=") + tagAttrValue ) ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - closeTag = Combine(_L("") - - openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) - closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % resname) - openTag.tag = resname - closeTag.tag = resname - return openTag, closeTag - -def makeHTMLTags(tagStr): - """ - Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches - tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. - - Example:: - text = 'More info at the pyparsing wiki page' - # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple - a,a_end = makeHTMLTags("A") - link_expr = a + SkipTo(a_end)("link_text") + a_end - - for link in link_expr.searchString(text): - # attributes in the tag (like "href" shown here) are also accessible as named results - print(link.link_text, '->', link.href) - prints:: - pyparsing -> http://pyparsing.wikispaces.com - """ - return _makeTags( tagStr, False ) - -def makeXMLTags(tagStr): - """ - Helper to construct opening and closing tag expressions for XML, given a tag name. Matches - tags only in the given upper/lower case. - - Example: similar to L{makeHTMLTags} - """ - return _makeTags( tagStr, True ) - -def withAttribute(*args,**attrDict): - """ - Helper to create a validating parse action to be used with start tags created - with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag - with a required attribute value, to avoid false matches on common tags such as - C{} or C{
}. - - Call C{withAttribute} with a series of attribute names and values. Specify the list - of filter attributes names and values as: - - keyword arguments, as in C{(align="right")}, or - - as an explicit dict with C{**} operator, when an attribute name is also a Python - reserved word, as in C{**{"class":"Customer", "align":"right"}} - - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) - For attribute names with a namespace prefix, you must use the second form. Attribute - names are matched insensitive to upper/lower case. - - If just testing for C{class} (with or without a namespace), use C{L{withClass}}. - - To verify that the attribute exists, but without specifying a value, pass - C{withAttribute.ANY_VALUE} as the value. - - Example:: - html = ''' -
- Some text -
1 4 0 1 0
-
1,3 2,3 1,1
-
this has no type
-
- - ''' - div,div_end = makeHTMLTags("div") - - # only match div tag having a type attribute with value "grid" - div_grid = div().setParseAction(withAttribute(type="grid")) - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - # construct a match with any div tag having a type attribute, regardless of the value - div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - prints:: - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - if args: - attrs = args[:] - else: - attrs = attrDict.items() - attrs = [(k,v) for k,v in attrs] - def pa(s,l,tokens): - for attrName,attrValue in attrs: - if attrName not in tokens: - raise ParseException(s,l,"no matching attribute " + attrName) - if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: - raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % - (attrName, tokens[attrName], attrValue)) - return pa -withAttribute.ANY_VALUE = object() - -def withClass(classname, namespace=''): - """ - Simplified version of C{L{withAttribute}} when matching on a div class - made - difficult because C{class} is a reserved word in Python. - - Example:: - html = ''' -
- Some text -
1 4 0 1 0
-
1,3 2,3 1,1
-
this <div> has no class
-
- - ''' - div,div_end = makeHTMLTags("div") - div_grid = div().setParseAction(withClass("grid")) - - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - prints:: - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - classattr = "%s:class" % namespace if namespace else "class" - return withAttribute(**{classattr : classname}) - -opAssoc = _Constants() -opAssoc.LEFT = object() -opAssoc.RIGHT = object() - -def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): - """ - Helper method for constructing grammars of expressions made up of - operators working in a precedence hierarchy. Operators may be unary or - binary, left- or right-associative. Parse actions can also be attached - to operator expressions. The generated parser will also recognize the use - of parentheses to override operator precedences (see example below). - - Note: if you define a deep operator list, you may see performance issues - when using infixNotation. See L{ParserElement.enablePackrat} for a - mechanism to potentially improve your parser performance. - - Parameters: - - baseExpr - expression representing the most basic element for the nested - - opList - list of tuples, one for each operator precedence level in the - expression grammar; each tuple is of the form - (opExpr, numTerms, rightLeftAssoc, parseAction), where: - - opExpr is the pyparsing expression for the operator; - may also be a string, which will be converted to a Literal; - if numTerms is 3, opExpr is a tuple of two expressions, for the - two operators separating the 3 terms - - numTerms is the number of terms for this operator (must - be 1, 2, or 3) - - rightLeftAssoc is the indicator whether the operator is - right or left associative, using the pyparsing-defined - constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. - - parseAction is the parse action to be associated with - expressions matching this operator expression (the - parse action tuple member may be omitted); if the parse action - is passed a tuple or list of functions, this is equivalent to - calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) - - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) - - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) - - Example:: - # simple example of four-function arithmetic with ints and variable names - integer = pyparsing_common.signed_integer - varname = pyparsing_common.identifier - - arith_expr = infixNotation(integer | varname, - [ - ('-', 1, opAssoc.RIGHT), - (oneOf('* /'), 2, opAssoc.LEFT), - (oneOf('+ -'), 2, opAssoc.LEFT), - ]) - - arith_expr.runTests(''' - 5+3*6 - (5+3)*6 - -2--11 - ''', fullDump=False) - prints:: - 5+3*6 - [[5, '+', [3, '*', 6]]] - - (5+3)*6 - [[[5, '+', 3], '*', 6]] - - -2--11 - [[['-', 2], '-', ['-', 11]]] - """ - ret = Forward() - lastExpr = baseExpr | ( lpar + ret + rpar ) - for i,operDef in enumerate(opList): - opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] - termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr - if arity == 3: - if opExpr is None or len(opExpr) != 2: - raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") - opExpr1, opExpr2 = opExpr - thisExpr = Forward().setName(termName) - if rightLeftAssoc == opAssoc.LEFT: - if arity == 1: - matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) - else: - matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ - Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - elif rightLeftAssoc == opAssoc.RIGHT: - if arity == 1: - # try to avoid LR with this extra test - if not isinstance(opExpr, Optional): - opExpr = Optional(opExpr) - matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) - else: - matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ - Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - else: - raise ValueError("operator must indicate right or left associativity") - if pa: - if isinstance(pa, (tuple, list)): - matchExpr.setParseAction(*pa) - else: - matchExpr.setParseAction(pa) - thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) - lastExpr = thisExpr - ret <<= lastExpr - return ret - -operatorPrecedence = infixNotation -"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" - -dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") -sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") -quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| - Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") -unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") - -def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): - """ - Helper method for defining nested lists enclosed in opening and closing - delimiters ("(" and ")" are the default). - - Parameters: - - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression - - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression - - content - expression for items within the nested lists (default=C{None}) - - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) - - If an expression is not provided for the content argument, the nested - expression will capture all whitespace-delimited content between delimiters - as a list of separate values. - - Use the C{ignoreExpr} argument to define expressions that may contain - opening or closing characters that should not be treated as opening - or closing characters for nesting, such as quotedString or a comment - expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. - The default is L{quotedString}, but if no expressions are to be ignored, - then pass C{None} for this argument. - - Example:: - data_type = oneOf("void int short long char float double") - decl_data_type = Combine(data_type + Optional(Word('*'))) - ident = Word(alphas+'_', alphanums+'_') - number = pyparsing_common.number - arg = Group(decl_data_type + ident) - LPAR,RPAR = map(Suppress, "()") - - code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) - - c_function = (decl_data_type("type") - + ident("name") - + LPAR + Optional(delimitedList(arg), [])("args") + RPAR - + code_body("body")) - c_function.ignore(cStyleComment) - - source_code = ''' - int is_odd(int x) { - return (x%2); - } - - int dec_to_hex(char hchar) { - if (hchar >= '0' && hchar <= '9') { - return (ord(hchar)-ord('0')); - } else { - return (10+ord(hchar)-ord('A')); - } - } - ''' - for func in c_function.searchString(source_code): - print("%(name)s (%(type)s) args: %(args)s" % func) - - prints:: - is_odd (int) args: [['int', 'x']] - dec_to_hex (int) args: [['char', 'hchar']] - """ - if opener == closer: - raise ValueError("opening and closing strings cannot be the same") - if content is None: - if isinstance(opener,basestring) and isinstance(closer,basestring): - if len(opener) == 1 and len(closer)==1: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS - ).setParseAction(lambda t:t[0].strip())) - else: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - ~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - raise ValueError("opening and closing arguments must be strings if no content expression is given") - ret = Forward() - if ignoreExpr is not None: - ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) - else: - ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) - ret.setName('nested %s%s expression' % (opener,closer)) - return ret - -def indentedBlock(blockStatementExpr, indentStack, indent=True): - """ - Helper method for defining space-delimited indentation blocks, such as - those used to define block statements in Python source code. - - Parameters: - - blockStatementExpr - expression defining syntax of statement that - is repeated within the indented block - - indentStack - list created by caller to manage indentation stack - (multiple statementWithIndentedBlock expressions within a single grammar - should share a common indentStack) - - indent - boolean indicating whether block must be indented beyond the - the current level; set to False for block of left-most statements - (default=C{True}) - - A valid block must contain at least one C{blockStatement}. - - Example:: - data = ''' - def A(z): - A1 - B = 100 - G = A2 - A2 - A3 - B - def BB(a,b,c): - BB1 - def BBA(): - bba1 - bba2 - bba3 - C - D - def spam(x,y): - def eggs(z): - pass - ''' - - - indentStack = [1] - stmt = Forward() - - identifier = Word(alphas, alphanums) - funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") - func_body = indentedBlock(stmt, indentStack) - funcDef = Group( funcDecl + func_body ) - - rvalue = Forward() - funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") - rvalue << (funcCall | identifier | Word(nums)) - assignment = Group(identifier + "=" + rvalue) - stmt << ( funcDef | assignment | identifier ) - - module_body = OneOrMore(stmt) - - parseTree = module_body.parseString(data) - parseTree.pprint() - prints:: - [['def', - 'A', - ['(', 'z', ')'], - ':', - [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], - 'B', - ['def', - 'BB', - ['(', 'a', 'b', 'c', ')'], - ':', - [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], - 'C', - 'D', - ['def', - 'spam', - ['(', 'x', 'y', ')'], - ':', - [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] - """ - def checkPeerIndent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if curCol != indentStack[-1]: - if curCol > indentStack[-1]: - raise ParseFatalException(s,l,"illegal nesting") - raise ParseException(s,l,"not a peer entry") - - def checkSubIndent(s,l,t): - curCol = col(l,s) - if curCol > indentStack[-1]: - indentStack.append( curCol ) - else: - raise ParseException(s,l,"not a subentry") - - def checkUnindent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): - raise ParseException(s,l,"not an unindent") - indentStack.pop() - - NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) - INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') - PEER = Empty().setParseAction(checkPeerIndent).setName('') - UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') - if indent: - smExpr = Group( Optional(NL) + - #~ FollowedBy(blockStatementExpr) + - INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) - else: - smExpr = Group( Optional(NL) + - (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) - blockStatementExpr.ignore(_bslash + LineEnd()) - return smExpr.setName('indented block') - -alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") -punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") - -anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) -_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) -commonHTMLEntity = Regex('&(?P' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") -def replaceHTMLEntity(t): - """Helper parser action to replace common HTML entities with their special characters""" - return _htmlEntityMap.get(t.entity) - -# it's easy to get these comment structures wrong - they're very common, so may as well make them available -cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") -"Comment of the form C{/* ... */}" - -htmlComment = Regex(r"").setName("HTML comment") -"Comment of the form C{}" - -restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") -dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") -"Comment of the form C{// ... (to end of line)}" - -cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") -"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" - -javaStyleComment = cppStyleComment -"Same as C{L{cppStyleComment}}" - -pythonStyleComment = Regex(r"#.*").setName("Python style comment") -"Comment of the form C{# ... (to end of line)}" - -_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + - Optional( Word(" \t") + - ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") -commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") -"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. - This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" - -# some other useful expressions - using lower-case class name since we are really using this as a namespace -class pyparsing_common: - """ - Here are some common low-level expressions that may be useful in jump-starting parser development: - - numeric forms (L{integers}, L{reals}, L{scientific notation}) - - common L{programming identifiers} - - network addresses (L{MAC}, L{IPv4}, L{IPv6}) - - ISO8601 L{dates} and L{datetime} - - L{UUID} - - L{comma-separated list} - Parse actions: - - C{L{convertToInteger}} - - C{L{convertToFloat}} - - C{L{convertToDate}} - - C{L{convertToDatetime}} - - C{L{stripHTMLTags}} - - C{L{upcaseTokens}} - - C{L{downcaseTokens}} - - Example:: - pyparsing_common.number.runTests(''' - # any int or real number, returned as the appropriate type - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.fnumber.runTests(''' - # any int or real number, returned as float - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.hex_integer.runTests(''' - # hex numbers - 100 - FF - ''') - - pyparsing_common.fraction.runTests(''' - # fractions - 1/2 - -3/4 - ''') - - pyparsing_common.mixed_integer.runTests(''' - # mixed fractions - 1 - 1/2 - -3/4 - 1-3/4 - ''') - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(''' - # uuid - 12345678-1234-5678-1234-567812345678 - ''') - prints:: - # any int or real number, returned as the appropriate type - 100 - [100] - - -100 - [-100] - - +100 - [100] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # any int or real number, returned as float - 100 - [100.0] - - -100 - [-100.0] - - +100 - [100.0] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # hex numbers - 100 - [256] - - FF - [255] - - # fractions - 1/2 - [0.5] - - -3/4 - [-0.75] - - # mixed fractions - 1 - [1] - - 1/2 - [0.5] - - -3/4 - [-0.75] - - 1-3/4 - [1.75] - - # uuid - 12345678-1234-5678-1234-567812345678 - [UUID('12345678-1234-5678-1234-567812345678')] - """ - - convertToInteger = tokenMap(int) - """ - Parse action for converting parsed integers to Python int - """ - - convertToFloat = tokenMap(float) - """ - Parse action for converting parsed numbers to Python float - """ - - integer = Word(nums).setName("integer").setParseAction(convertToInteger) - """expression that parses an unsigned integer, returns an int""" - - hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) - """expression that parses a hexadecimal integer, returns an int""" - - signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) - """expression that parses an integer with optional leading sign, returns an int""" - - fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") - """fractional expression of an integer divided by an integer, returns a float""" - fraction.addParseAction(lambda t: t[0]/t[-1]) - - mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") - """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" - mixed_integer.addParseAction(sum) - - real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) - """expression that parses a floating point number and returns a float""" - - sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) - """expression that parses a floating point number with optional scientific notation and returns a float""" - - # streamlining this expression makes the docs nicer-looking - number = (sci_real | real | signed_integer).streamline() - """any numeric expression, returns the corresponding Python type""" - - fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) - """any int or real number, returned as float""" - - identifier = Word(alphas+'_', alphanums+'_').setName("identifier") - """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" - - ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") - "IPv4 address (C{0.0.0.0 - 255.255.255.255})" - - _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") - _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") - _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") - _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) - _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") - ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") - "IPv6 address (long, short, or mixed form)" - - mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") - "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" - - @staticmethod - def convertToDate(fmt="%Y-%m-%d"): - """ - Helper to create a parse action for converting parsed date string to Python datetime.date - - Params - - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) - - Example:: - date_expr = pyparsing_common.iso8601_date.copy() - date_expr.setParseAction(pyparsing_common.convertToDate()) - print(date_expr.parseString("1999-12-31")) - prints:: - [datetime.date(1999, 12, 31)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt).date() - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - @staticmethod - def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): - """ - Helper to create a parse action for converting parsed datetime string to Python datetime.datetime - - Params - - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) - - Example:: - dt_expr = pyparsing_common.iso8601_datetime.copy() - dt_expr.setParseAction(pyparsing_common.convertToDatetime()) - print(dt_expr.parseString("1999-12-31T23:59:59.999")) - prints:: - [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt) - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - iso8601_date = Regex(r'(?P\d{4})(?:-(?P\d\d)(?:-(?P\d\d))?)?').setName("ISO8601 date") - "ISO8601 date (C{yyyy-mm-dd})" - - iso8601_datetime = Regex(r'(?P\d{4})-(?P\d\d)-(?P\d\d)[T ](?P\d\d):(?P\d\d)(:(?P\d\d(\.\d*)?)?)?(?PZ|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") - "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" - - uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") - "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" - - _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() - @staticmethod - def stripHTMLTags(s, l, tokens): - """ - Parse action to remove HTML tags from web page HTML source - - Example:: - # strip HTML links from normal text - text = 'More info at the
pyparsing wiki page' - td,td_end = makeHTMLTags("TD") - table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end - - print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' - """ - return pyparsing_common._html_stripper.transformString(tokens[0]) - - _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') - + Optional( White(" \t") ) ) ).streamline().setName("commaItem") - comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") - """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" - - upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) - """Parse action to convert tokens to upper case.""" - - downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) - """Parse action to convert tokens to lower case.""" - - -if __name__ == "__main__": - - selectToken = CaselessLiteral("select") - fromToken = CaselessLiteral("from") - - ident = Word(alphas, alphanums + "_$") - - columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - columnNameList = Group(delimitedList(columnName)).setName("columns") - columnSpec = ('*' | columnNameList) - - tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - tableNameList = Group(delimitedList(tableName)).setName("tables") - - simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") - - # demo runTests method, including embedded comments in test string - simpleSQL.runTests(""" - # '*' as column list and dotted table name - select * from SYS.XYZZY - - # caseless match on "SELECT", and casts back to "select" - SELECT * from XYZZY, ABC - - # list of column names, and mixed case SELECT keyword - Select AA,BB,CC from Sys.dual - - # multiple tables - Select A, B, C from Sys.dual, Table2 - - # invalid SELECT keyword - should fail - Xelect A, B, C from Sys.dual - - # incomplete command - should fail - Select - - # invalid column name - should fail - Select ^^^ frox Sys.dual - - """) - - pyparsing_common.number.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - # any int or real number, returned as float - pyparsing_common.fnumber.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - pyparsing_common.hex_integer.runTests(""" - 100 - FF - """) - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(""" - 12345678-1234-5678-1234-567812345678 - """) diff --git a/uno/lib/python/pkg_resources/_vendor/typing_extensions.py b/uno/lib/python/pkg_resources/_vendor/typing_extensions.py new file mode 100644 index 00000000..ef42417c --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/typing_extensions.py @@ -0,0 +1,2209 @@ +import abc +import collections +import collections.abc +import functools +import operator +import sys +import types as _types +import typing + + +__all__ = [ + # Super-special typing primitives. + 'Any', + 'ClassVar', + 'Concatenate', + 'Final', + 'LiteralString', + 'ParamSpec', + 'ParamSpecArgs', + 'ParamSpecKwargs', + 'Self', + 'Type', + 'TypeVar', + 'TypeVarTuple', + 'Unpack', + + # ABCs (from collections.abc). + 'Awaitable', + 'AsyncIterator', + 'AsyncIterable', + 'Coroutine', + 'AsyncGenerator', + 'AsyncContextManager', + 'ChainMap', + + # Concrete collection types. + 'ContextManager', + 'Counter', + 'Deque', + 'DefaultDict', + 'NamedTuple', + 'OrderedDict', + 'TypedDict', + + # Structural checks, a.k.a. protocols. + 'SupportsIndex', + + # One-off things. + 'Annotated', + 'assert_never', + 'assert_type', + 'clear_overloads', + 'dataclass_transform', + 'get_overloads', + 'final', + 'get_args', + 'get_origin', + 'get_type_hints', + 'IntVar', + 'is_typeddict', + 'Literal', + 'NewType', + 'overload', + 'override', + 'Protocol', + 'reveal_type', + 'runtime', + 'runtime_checkable', + 'Text', + 'TypeAlias', + 'TypeGuard', + 'TYPE_CHECKING', + 'Never', + 'NoReturn', + 'Required', + 'NotRequired', +] + +# for backward compatibility +PEP_560 = True +GenericMeta = type + +# The functions below are modified copies of typing internal helpers. +# They are needed by _ProtocolMeta and they provide support for PEP 646. + +_marker = object() + + +def _check_generic(cls, parameters, elen=_marker): + """Check correct count for parameters of a generic cls (internal helper). + This gives a nice error message in case of count mismatch. + """ + if not elen: + raise TypeError(f"{cls} is not a generic class") + if elen is _marker: + if not hasattr(cls, "__parameters__") or not cls.__parameters__: + raise TypeError(f"{cls} is not a generic class") + elen = len(cls.__parameters__) + alen = len(parameters) + if alen != elen: + if hasattr(cls, "__parameters__"): + parameters = [p for p in cls.__parameters__ if not _is_unpack(p)] + num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters) + if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples): + return + raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};" + f" actual {alen}, expected {elen}") + + +if sys.version_info >= (3, 10): + def _should_collect_from_parameters(t): + return isinstance( + t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType) + ) +elif sys.version_info >= (3, 9): + def _should_collect_from_parameters(t): + return isinstance(t, (typing._GenericAlias, _types.GenericAlias)) +else: + def _should_collect_from_parameters(t): + return isinstance(t, typing._GenericAlias) and not t._special + + +def _collect_type_vars(types, typevar_types=None): + """Collect all type variable contained in types in order of + first appearance (lexicographic order). For example:: + + _collect_type_vars((T, List[S, T])) == (T, S) + """ + if typevar_types is None: + typevar_types = typing.TypeVar + tvars = [] + for t in types: + if ( + isinstance(t, typevar_types) and + t not in tvars and + not _is_unpack(t) + ): + tvars.append(t) + if _should_collect_from_parameters(t): + tvars.extend([t for t in t.__parameters__ if t not in tvars]) + return tuple(tvars) + + +NoReturn = typing.NoReturn + +# Some unconstrained type variables. These are used by the container types. +# (These are not for export.) +T = typing.TypeVar('T') # Any type. +KT = typing.TypeVar('KT') # Key type. +VT = typing.TypeVar('VT') # Value type. +T_co = typing.TypeVar('T_co', covariant=True) # Any type covariant containers. +T_contra = typing.TypeVar('T_contra', contravariant=True) # Ditto contravariant. + + +if sys.version_info >= (3, 11): + from typing import Any +else: + + class _AnyMeta(type): + def __instancecheck__(self, obj): + if self is Any: + raise TypeError("typing_extensions.Any cannot be used with isinstance()") + return super().__instancecheck__(obj) + + def __repr__(self): + if self is Any: + return "typing_extensions.Any" + return super().__repr__() + + class Any(metaclass=_AnyMeta): + """Special type indicating an unconstrained type. + - Any is compatible with every type. + - Any assumed to have all methods. + - All values assumed to be instances of Any. + Note that all the above statements are true from the point of view of + static type checkers. At runtime, Any should not be used with instance + checks. + """ + def __new__(cls, *args, **kwargs): + if cls is Any: + raise TypeError("Any cannot be instantiated") + return super().__new__(cls, *args, **kwargs) + + +ClassVar = typing.ClassVar + +# On older versions of typing there is an internal class named "Final". +# 3.8+ +if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7): + Final = typing.Final +# 3.7 +else: + class _FinalForm(typing._SpecialForm, _root=True): + + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + + Final = _FinalForm('Final', + doc="""A special typing construct to indicate that a name + cannot be re-assigned or overridden in a subclass. + For example: + + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker + + class Connection: + TIMEOUT: Final[int] = 10 + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker + + There is no runtime checking of these properties.""") + +if sys.version_info >= (3, 11): + final = typing.final +else: + # @final exists in 3.8+, but we backport it for all versions + # before 3.11 to keep support for the __final__ attribute. + # See https://bugs.python.org/issue46342 + def final(f): + """This decorator can be used to indicate to type checkers that + the decorated method cannot be overridden, and decorated class + cannot be subclassed. For example: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. The decorator + sets the ``__final__`` attribute to ``True`` on the decorated object + to allow runtime introspection. + """ + try: + f.__final__ = True + except (AttributeError, TypeError): + # Skip the attribute silently if it is not writable. + # AttributeError happens if the object has __slots__ or a + # read-only property, TypeError if it's a builtin class. + pass + return f + + +def IntVar(name): + return typing.TypeVar(name) + + +# 3.8+: +if hasattr(typing, 'Literal'): + Literal = typing.Literal +# 3.7: +else: + class _LiteralForm(typing._SpecialForm, _root=True): + + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + return typing._GenericAlias(self, parameters) + + Literal = _LiteralForm('Literal', + doc="""A type that can be used to indicate to type checkers + that the corresponding value has a value literally equivalent + to the provided parameter. For example: + + var: Literal[4] = 4 + + The type checker understands that 'var' is literally equal to + the value 4 and no other value. + + Literal[...] cannot be subclassed. There is no runtime + checking verifying that the parameter is actually a value + instead of a type.""") + + +_overload_dummy = typing._overload_dummy # noqa + + +if hasattr(typing, "get_overloads"): # 3.11+ + overload = typing.overload + get_overloads = typing.get_overloads + clear_overloads = typing.clear_overloads +else: + # {module: {qualname: {firstlineno: func}}} + _overload_registry = collections.defaultdict( + functools.partial(collections.defaultdict, dict) + ) + + def overload(func): + """Decorator for overloaded functions/methods. + + In a stub file, place two or more stub definitions for the same + function in a row, each decorated with @overload. For example: + + @overload + def utf8(value: None) -> None: ... + @overload + def utf8(value: bytes) -> bytes: ... + @overload + def utf8(value: str) -> bytes: ... + + In a non-stub file (i.e. a regular .py file), do the same but + follow it with an implementation. The implementation should *not* + be decorated with @overload. For example: + + @overload + def utf8(value: None) -> None: ... + @overload + def utf8(value: bytes) -> bytes: ... + @overload + def utf8(value: str) -> bytes: ... + def utf8(value): + # implementation goes here + + The overloads for a function can be retrieved at runtime using the + get_overloads() function. + """ + # classmethod and staticmethod + f = getattr(func, "__func__", func) + try: + _overload_registry[f.__module__][f.__qualname__][ + f.__code__.co_firstlineno + ] = func + except AttributeError: + # Not a normal function; ignore. + pass + return _overload_dummy + + def get_overloads(func): + """Return all defined overloads for *func* as a sequence.""" + # classmethod and staticmethod + f = getattr(func, "__func__", func) + if f.__module__ not in _overload_registry: + return [] + mod_dict = _overload_registry[f.__module__] + if f.__qualname__ not in mod_dict: + return [] + return list(mod_dict[f.__qualname__].values()) + + def clear_overloads(): + """Clear all overloads in the registry.""" + _overload_registry.clear() + + +# This is not a real generic class. Don't use outside annotations. +Type = typing.Type + +# Various ABCs mimicking those in collections.abc. +# A few are simply re-exported for completeness. + + +Awaitable = typing.Awaitable +Coroutine = typing.Coroutine +AsyncIterable = typing.AsyncIterable +AsyncIterator = typing.AsyncIterator +Deque = typing.Deque +ContextManager = typing.ContextManager +AsyncContextManager = typing.AsyncContextManager +DefaultDict = typing.DefaultDict + +# 3.7.2+ +if hasattr(typing, 'OrderedDict'): + OrderedDict = typing.OrderedDict +# 3.7.0-3.7.2 +else: + OrderedDict = typing._alias(collections.OrderedDict, (KT, VT)) + +Counter = typing.Counter +ChainMap = typing.ChainMap +AsyncGenerator = typing.AsyncGenerator +NewType = typing.NewType +Text = typing.Text +TYPE_CHECKING = typing.TYPE_CHECKING + + +_PROTO_WHITELIST = ['Callable', 'Awaitable', + 'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator', + 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', + 'ContextManager', 'AsyncContextManager'] + + +def _get_protocol_attrs(cls): + attrs = set() + for base in cls.__mro__[:-1]: # without object + if base.__name__ in ('Protocol', 'Generic'): + continue + annotations = getattr(base, '__annotations__', {}) + for attr in list(base.__dict__.keys()) + list(annotations.keys()): + if (not attr.startswith('_abc_') and attr not in ( + '__abstractmethods__', '__annotations__', '__weakref__', + '_is_protocol', '_is_runtime_protocol', '__dict__', + '__args__', '__slots__', + '__next_in_mro__', '__parameters__', '__origin__', + '__orig_bases__', '__extra__', '__tree_hash__', + '__doc__', '__subclasshook__', '__init__', '__new__', + '__module__', '_MutableMapping__marker', '_gorg')): + attrs.add(attr) + return attrs + + +def _is_callable_members_only(cls): + return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) + + +def _maybe_adjust_parameters(cls): + """Helper function used in Protocol.__init_subclass__ and _TypedDictMeta.__new__. + + The contents of this function are very similar + to logic found in typing.Generic.__init_subclass__ + on the CPython main branch. + """ + tvars = [] + if '__orig_bases__' in cls.__dict__: + tvars = typing._collect_type_vars(cls.__orig_bases__) + # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn]. + # If found, tvars must be a subset of it. + # If not found, tvars is it. + # Also check for and reject plain Generic, + # and reject multiple Generic[...] and/or Protocol[...]. + gvars = None + for base in cls.__orig_bases__: + if (isinstance(base, typing._GenericAlias) and + base.__origin__ in (typing.Generic, Protocol)): + # for error messages + the_base = base.__origin__.__name__ + if gvars is not None: + raise TypeError( + "Cannot inherit from Generic[...]" + " and/or Protocol[...] multiple types.") + gvars = base.__parameters__ + if gvars is None: + gvars = tvars + else: + tvarset = set(tvars) + gvarset = set(gvars) + if not tvarset <= gvarset: + s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) + s_args = ', '.join(str(g) for g in gvars) + raise TypeError(f"Some type variables ({s_vars}) are" + f" not listed in {the_base}[{s_args}]") + tvars = gvars + cls.__parameters__ = tuple(tvars) + + +# 3.8+ +if hasattr(typing, 'Protocol'): + Protocol = typing.Protocol +# 3.7 +else: + + def _no_init(self, *args, **kwargs): + if type(self)._is_protocol: + raise TypeError('Protocols cannot be instantiated') + + class _ProtocolMeta(abc.ABCMeta): # noqa: B024 + # This metaclass is a bit unfortunate and exists only because of the lack + # of __instancehook__. + def __instancecheck__(cls, instance): + # We need this method for situations where attributes are + # assigned in __init__. + if ((not getattr(cls, '_is_protocol', False) or + _is_callable_members_only(cls)) and + issubclass(instance.__class__, cls)): + return True + if cls._is_protocol: + if all(hasattr(instance, attr) and + (not callable(getattr(cls, attr, None)) or + getattr(instance, attr) is not None) + for attr in _get_protocol_attrs(cls)): + return True + return super().__instancecheck__(instance) + + class Protocol(metaclass=_ProtocolMeta): + # There is quite a lot of overlapping code with typing.Generic. + # Unfortunately it is hard to avoid this while these live in two different + # modules. The duplicated code will be removed when Protocol is moved to typing. + """Base class for protocol classes. Protocol classes are defined as:: + + class Proto(Protocol): + def meth(self) -> int: + ... + + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: + + class C: + def meth(self) -> int: + return 0 + + def func(x: Proto) -> int: + return x.meth() + + func(C()) # Passes static type check + + See PEP 544 for details. Protocol classes decorated with + @typing_extensions.runtime act as simple-minded runtime protocol that checks + only the presence of given attributes, ignoring their type signatures. + + Protocol classes can be generic, they are defined as:: + + class GenProto(Protocol[T]): + def meth(self) -> T: + ... + """ + __slots__ = () + _is_protocol = True + + def __new__(cls, *args, **kwds): + if cls is Protocol: + raise TypeError("Type Protocol cannot be instantiated; " + "it can only be used as a base class") + return super().__new__(cls) + + @typing._tp_cache + def __class_getitem__(cls, params): + if not isinstance(params, tuple): + params = (params,) + if not params and cls is not typing.Tuple: + raise TypeError( + f"Parameter list to {cls.__qualname__}[...] cannot be empty") + msg = "Parameters to generic types must be types." + params = tuple(typing._type_check(p, msg) for p in params) # noqa + if cls is Protocol: + # Generic can only be subscripted with unique type variables. + if not all(isinstance(p, typing.TypeVar) for p in params): + i = 0 + while isinstance(params[i], typing.TypeVar): + i += 1 + raise TypeError( + "Parameters to Protocol[...] must all be type variables." + f" Parameter {i + 1} is {params[i]}") + if len(set(params)) != len(params): + raise TypeError( + "Parameters to Protocol[...] must all be unique") + else: + # Subscripting a regular Generic subclass. + _check_generic(cls, params, len(cls.__parameters__)) + return typing._GenericAlias(cls, params) + + def __init_subclass__(cls, *args, **kwargs): + if '__orig_bases__' in cls.__dict__: + error = typing.Generic in cls.__orig_bases__ + else: + error = typing.Generic in cls.__bases__ + if error: + raise TypeError("Cannot inherit from plain Generic") + _maybe_adjust_parameters(cls) + + # Determine if this is a protocol or a concrete subclass. + if not cls.__dict__.get('_is_protocol', None): + cls._is_protocol = any(b is Protocol for b in cls.__bases__) + + # Set (or override) the protocol subclass hook. + def _proto_hook(other): + if not cls.__dict__.get('_is_protocol', None): + return NotImplemented + if not getattr(cls, '_is_runtime_protocol', False): + if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']: + return NotImplemented + raise TypeError("Instance and class checks can only be used with" + " @runtime protocols") + if not _is_callable_members_only(cls): + if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']: + return NotImplemented + raise TypeError("Protocols with non-method members" + " don't support issubclass()") + if not isinstance(other, type): + # Same error as for issubclass(1, int) + raise TypeError('issubclass() arg 1 must be a class') + for attr in _get_protocol_attrs(cls): + for base in other.__mro__: + if attr in base.__dict__: + if base.__dict__[attr] is None: + return NotImplemented + break + annotations = getattr(base, '__annotations__', {}) + if (isinstance(annotations, typing.Mapping) and + attr in annotations and + isinstance(other, _ProtocolMeta) and + other._is_protocol): + break + else: + return NotImplemented + return True + if '__subclasshook__' not in cls.__dict__: + cls.__subclasshook__ = _proto_hook + + # We have nothing more to do for non-protocols. + if not cls._is_protocol: + return + + # Check consistency of bases. + for base in cls.__bases__: + if not (base in (object, typing.Generic) or + base.__module__ == 'collections.abc' and + base.__name__ in _PROTO_WHITELIST or + isinstance(base, _ProtocolMeta) and base._is_protocol): + raise TypeError('Protocols can only inherit from other' + f' protocols, got {repr(base)}') + cls.__init__ = _no_init + + +# 3.8+ +if hasattr(typing, 'runtime_checkable'): + runtime_checkable = typing.runtime_checkable +# 3.7 +else: + def runtime_checkable(cls): + """Mark a protocol class as a runtime protocol, so that it + can be used with isinstance() and issubclass(). Raise TypeError + if applied to a non-protocol class. + + This allows a simple-minded structural check very similar to the + one-offs in collections.abc such as Hashable. + """ + if not isinstance(cls, _ProtocolMeta) or not cls._is_protocol: + raise TypeError('@runtime_checkable can be only applied to protocol classes,' + f' got {cls!r}') + cls._is_runtime_protocol = True + return cls + + +# Exists for backwards compatibility. +runtime = runtime_checkable + + +# 3.8+ +if hasattr(typing, 'SupportsIndex'): + SupportsIndex = typing.SupportsIndex +# 3.7 +else: + @runtime_checkable + class SupportsIndex(Protocol): + __slots__ = () + + @abc.abstractmethod + def __index__(self) -> int: + pass + + +if hasattr(typing, "Required"): + # The standard library TypedDict in Python 3.8 does not store runtime information + # about which (if any) keys are optional. See https://bugs.python.org/issue38834 + # The standard library TypedDict in Python 3.9.0/1 does not honour the "total" + # keyword with old-style TypedDict(). See https://bugs.python.org/issue42059 + # The standard library TypedDict below Python 3.11 does not store runtime + # information about optional and required keys when using Required or NotRequired. + # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11. + TypedDict = typing.TypedDict + _TypedDictMeta = typing._TypedDictMeta + is_typeddict = typing.is_typeddict +else: + def _check_fails(cls, other): + try: + if sys._getframe(1).f_globals['__name__'] not in ['abc', + 'functools', + 'typing']: + # Typed dicts are only for static structural subtyping. + raise TypeError('TypedDict does not support instance and class checks') + except (AttributeError, ValueError): + pass + return False + + def _dict_new(*args, **kwargs): + if not args: + raise TypeError('TypedDict.__new__(): not enough arguments') + _, args = args[0], args[1:] # allow the "cls" keyword be passed + return dict(*args, **kwargs) + + _dict_new.__text_signature__ = '($cls, _typename, _fields=None, /, **kwargs)' + + def _typeddict_new(*args, total=True, **kwargs): + if not args: + raise TypeError('TypedDict.__new__(): not enough arguments') + _, args = args[0], args[1:] # allow the "cls" keyword be passed + if args: + typename, args = args[0], args[1:] # allow the "_typename" keyword be passed + elif '_typename' in kwargs: + typename = kwargs.pop('_typename') + import warnings + warnings.warn("Passing '_typename' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError("TypedDict.__new__() missing 1 required positional " + "argument: '_typename'") + if args: + try: + fields, = args # allow the "_fields" keyword be passed + except ValueError: + raise TypeError('TypedDict.__new__() takes from 2 to 3 ' + f'positional arguments but {len(args) + 2} ' + 'were given') + elif '_fields' in kwargs and len(kwargs) == 1: + fields = kwargs.pop('_fields') + import warnings + warnings.warn("Passing '_fields' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + fields = None + + if fields is None: + fields = kwargs + elif kwargs: + raise TypeError("TypedDict takes either a dict or keyword arguments," + " but not both") + + ns = {'__annotations__': dict(fields)} + try: + # Setting correct module is necessary to make typed dict classes pickleable. + ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + + return _TypedDictMeta(typename, (), ns, total=total) + + _typeddict_new.__text_signature__ = ('($cls, _typename, _fields=None,' + ' /, *, total=True, **kwargs)') + + class _TypedDictMeta(type): + def __init__(cls, name, bases, ns, total=True): + super().__init__(name, bases, ns) + + def __new__(cls, name, bases, ns, total=True): + # Create new typed dict class object. + # This method is called directly when TypedDict is subclassed, + # or via _typeddict_new when TypedDict is instantiated. This way + # TypedDict supports all three syntaxes described in its docstring. + # Subclasses and instances of TypedDict return actual dictionaries + # via _dict_new. + ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new + # Don't insert typing.Generic into __bases__ here, + # or Generic.__init_subclass__ will raise TypeError + # in the super().__new__() call. + # Instead, monkey-patch __bases__ onto the class after it's been created. + tp_dict = super().__new__(cls, name, (dict,), ns) + + if any(issubclass(base, typing.Generic) for base in bases): + tp_dict.__bases__ = (typing.Generic, dict) + _maybe_adjust_parameters(tp_dict) + + annotations = {} + own_annotations = ns.get('__annotations__', {}) + msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" + own_annotations = { + n: typing._type_check(tp, msg) for n, tp in own_annotations.items() + } + required_keys = set() + optional_keys = set() + + for base in bases: + annotations.update(base.__dict__.get('__annotations__', {})) + required_keys.update(base.__dict__.get('__required_keys__', ())) + optional_keys.update(base.__dict__.get('__optional_keys__', ())) + + annotations.update(own_annotations) + for annotation_key, annotation_type in own_annotations.items(): + annotation_origin = get_origin(annotation_type) + if annotation_origin is Annotated: + annotation_args = get_args(annotation_type) + if annotation_args: + annotation_type = annotation_args[0] + annotation_origin = get_origin(annotation_type) + + if annotation_origin is Required: + required_keys.add(annotation_key) + elif annotation_origin is NotRequired: + optional_keys.add(annotation_key) + elif total: + required_keys.add(annotation_key) + else: + optional_keys.add(annotation_key) + + tp_dict.__annotations__ = annotations + tp_dict.__required_keys__ = frozenset(required_keys) + tp_dict.__optional_keys__ = frozenset(optional_keys) + if not hasattr(tp_dict, '__total__'): + tp_dict.__total__ = total + return tp_dict + + __instancecheck__ = __subclasscheck__ = _check_fails + + TypedDict = _TypedDictMeta('TypedDict', (dict,), {}) + TypedDict.__module__ = __name__ + TypedDict.__doc__ = \ + """A simple typed name space. At runtime it is equivalent to a plain dict. + + TypedDict creates a dictionary type that expects all of its + instances to have a certain set of keys, with each key + associated with a value of a consistent type. This expectation + is not checked at runtime but is only enforced by type checkers. + Usage:: + + class Point2D(TypedDict): + x: int + y: int + label: str + + a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK + b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check + + assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + + The type info can be accessed via the Point2D.__annotations__ dict, and + the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. + TypedDict supports two additional equivalent forms:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + + The class syntax is only supported in Python 3.6+, while two other + syntax forms work for Python 2.7 and 3.2+ + """ + + if hasattr(typing, "_TypedDictMeta"): + _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta) + else: + _TYPEDDICT_TYPES = (_TypedDictMeta,) + + def is_typeddict(tp): + """Check if an annotation is a TypedDict class + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + """ + return isinstance(tp, tuple(_TYPEDDICT_TYPES)) + + +if hasattr(typing, "assert_type"): + assert_type = typing.assert_type + +else: + def assert_type(__val, __typ): + """Assert (to the type checker) that the value is of the given type. + + When the type checker encounters a call to assert_type(), it + emits an error if the value is not of the specified type:: + + def greet(name: str) -> None: + assert_type(name, str) # ok + assert_type(name, int) # type checker error + + At runtime this returns the first argument unchanged and otherwise + does nothing. + """ + return __val + + +if hasattr(typing, "Required"): + get_type_hints = typing.get_type_hints +else: + import functools + import types + + # replaces _strip_annotations() + def _strip_extras(t): + """Strips Annotated, Required and NotRequired from a given type.""" + if isinstance(t, _AnnotatedAlias): + return _strip_extras(t.__origin__) + if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): + return _strip_extras(t.__args__[0]) + if isinstance(t, typing._GenericAlias): + stripped_args = tuple(_strip_extras(a) for a in t.__args__) + if stripped_args == t.__args__: + return t + return t.copy_with(stripped_args) + if hasattr(types, "GenericAlias") and isinstance(t, types.GenericAlias): + stripped_args = tuple(_strip_extras(a) for a in t.__args__) + if stripped_args == t.__args__: + return t + return types.GenericAlias(t.__origin__, stripped_args) + if hasattr(types, "UnionType") and isinstance(t, types.UnionType): + stripped_args = tuple(_strip_extras(a) for a in t.__args__) + if stripped_args == t.__args__: + return t + return functools.reduce(operator.or_, stripped_args) + + return t + + def get_type_hints(obj, globalns=None, localns=None, include_extras=False): + """Return type hints for an object. + + This is often the same as obj.__annotations__, but it handles + forward references encoded as string literals, adds Optional[t] if a + default value equal to None is set and recursively replaces all + 'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T' + (unless 'include_extras=True'). + + The argument may be a module, class, method, or function. The annotations + are returned as a dictionary. For classes, annotations include also + inherited members. + + TypeError is raised if the argument is not of a type that can contain + annotations, and an empty dictionary is returned if no annotations are + present. + + BEWARE -- the behavior of globalns and localns is counterintuitive + (unless you are familiar with how eval() and exec() work). The + search order is locals first, then globals. + + - If no dict arguments are passed, an attempt is made to use the + globals from obj (or the respective module's globals for classes), + and these are also used as the locals. If the object does not appear + to have globals, an empty dictionary is used. + + - If one dict argument is passed, it is used for both globals and + locals. + + - If two dict arguments are passed, they specify globals and + locals, respectively. + """ + if hasattr(typing, "Annotated"): + hint = typing.get_type_hints( + obj, globalns=globalns, localns=localns, include_extras=True + ) + else: + hint = typing.get_type_hints(obj, globalns=globalns, localns=localns) + if include_extras: + return hint + return {k: _strip_extras(t) for k, t in hint.items()} + + +# Python 3.9+ has PEP 593 (Annotated) +if hasattr(typing, 'Annotated'): + Annotated = typing.Annotated + # Not exported and not a public API, but needed for get_origin() and get_args() + # to work. + _AnnotatedAlias = typing._AnnotatedAlias +# 3.7-3.8 +else: + class _AnnotatedAlias(typing._GenericAlias, _root=True): + """Runtime representation of an annotated type. + + At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' + with extra annotations. The alias behaves like a normal typing alias, + instantiating is the same as instantiating the underlying type, binding + it to types is also the same. + """ + def __init__(self, origin, metadata): + if isinstance(origin, _AnnotatedAlias): + metadata = origin.__metadata__ + metadata + origin = origin.__origin__ + super().__init__(origin, origin) + self.__metadata__ = metadata + + def copy_with(self, params): + assert len(params) == 1 + new_type = params[0] + return _AnnotatedAlias(new_type, self.__metadata__) + + def __repr__(self): + return (f"typing_extensions.Annotated[{typing._type_repr(self.__origin__)}, " + f"{', '.join(repr(a) for a in self.__metadata__)}]") + + def __reduce__(self): + return operator.getitem, ( + Annotated, (self.__origin__,) + self.__metadata__ + ) + + def __eq__(self, other): + if not isinstance(other, _AnnotatedAlias): + return NotImplemented + if self.__origin__ != other.__origin__: + return False + return self.__metadata__ == other.__metadata__ + + def __hash__(self): + return hash((self.__origin__, self.__metadata__)) + + class Annotated: + """Add context specific metadata to a type. + + Example: Annotated[int, runtime_check.Unsigned] indicates to the + hypothetical runtime_check module that this type is an unsigned int. + Every other consumer of this type can ignore this metadata and treat + this type as int. + + The first argument to Annotated must be a valid type (and will be in + the __origin__ field), the remaining arguments are kept as a tuple in + the __extra__ field. + + Details: + + - It's an error to call `Annotated` with less than two arguments. + - Nested Annotated are flattened:: + + Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] + + - Instantiating an annotated type is equivalent to instantiating the + underlying type:: + + Annotated[C, Ann1](5) == C(5) + + - Annotated can be used as a generic type alias:: + + Optimized = Annotated[T, runtime.Optimize()] + Optimized[int] == Annotated[int, runtime.Optimize()] + + OptimizedList = Annotated[List[T], runtime.Optimize()] + OptimizedList[int] == Annotated[List[int], runtime.Optimize()] + """ + + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise TypeError("Type Annotated cannot be instantiated.") + + @typing._tp_cache + def __class_getitem__(cls, params): + if not isinstance(params, tuple) or len(params) < 2: + raise TypeError("Annotated[...] should be used " + "with at least two arguments (a type and an " + "annotation).") + allowed_special_forms = (ClassVar, Final) + if get_origin(params[0]) in allowed_special_forms: + origin = params[0] + else: + msg = "Annotated[t, ...]: t must be a type." + origin = typing._type_check(params[0], msg) + metadata = tuple(params[1:]) + return _AnnotatedAlias(origin, metadata) + + def __init_subclass__(cls, *args, **kwargs): + raise TypeError( + f"Cannot subclass {cls.__module__}.Annotated" + ) + +# Python 3.8 has get_origin() and get_args() but those implementations aren't +# Annotated-aware, so we can't use those. Python 3.9's versions don't support +# ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do. +if sys.version_info[:2] >= (3, 10): + get_origin = typing.get_origin + get_args = typing.get_args +# 3.7-3.9 +else: + try: + # 3.9+ + from typing import _BaseGenericAlias + except ImportError: + _BaseGenericAlias = typing._GenericAlias + try: + # 3.9+ + from typing import GenericAlias as _typing_GenericAlias + except ImportError: + _typing_GenericAlias = typing._GenericAlias + + def get_origin(tp): + """Get the unsubscripted version of a type. + + This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar + and Annotated. Return None for unsupported types. Examples:: + + get_origin(Literal[42]) is Literal + get_origin(int) is None + get_origin(ClassVar[int]) is ClassVar + get_origin(Generic) is Generic + get_origin(Generic[T]) is Generic + get_origin(Union[T, int]) is Union + get_origin(List[Tuple[T, T]][int]) == list + get_origin(P.args) is P + """ + if isinstance(tp, _AnnotatedAlias): + return Annotated + if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias, _BaseGenericAlias, + ParamSpecArgs, ParamSpecKwargs)): + return tp.__origin__ + if tp is typing.Generic: + return typing.Generic + return None + + def get_args(tp): + """Get type arguments with all substitutions performed. + + For unions, basic simplifications used by Union constructor are performed. + Examples:: + get_args(Dict[str, int]) == (str, int) + get_args(int) == () + get_args(Union[int, Union[T, int], str][int]) == (int, str) + get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) + get_args(Callable[[], T][int]) == ([], int) + """ + if isinstance(tp, _AnnotatedAlias): + return (tp.__origin__,) + tp.__metadata__ + if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias)): + if getattr(tp, "_special", False): + return () + res = tp.__args__ + if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: + res = (list(res[:-1]), res[-1]) + return res + return () + + +# 3.10+ +if hasattr(typing, 'TypeAlias'): + TypeAlias = typing.TypeAlias +# 3.9 +elif sys.version_info[:2] >= (3, 9): + class _TypeAliasForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + @_TypeAliasForm + def TypeAlias(self, parameters): + """Special marker indicating that an assignment should + be recognized as a proper type alias definition by type + checkers. + + For example:: + + Predicate: TypeAlias = Callable[..., bool] + + It's invalid when used anywhere except as in the example above. + """ + raise TypeError(f"{self} is not subscriptable") +# 3.7-3.8 +else: + class _TypeAliasForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + TypeAlias = _TypeAliasForm('TypeAlias', + doc="""Special marker indicating that an assignment should + be recognized as a proper type alias definition by type + checkers. + + For example:: + + Predicate: TypeAlias = Callable[..., bool] + + It's invalid when used anywhere except as in the example + above.""") + + +class _DefaultMixin: + """Mixin for TypeVarLike defaults.""" + + __slots__ = () + + def __init__(self, default): + if isinstance(default, (tuple, list)): + self.__default__ = tuple((typing._type_check(d, "Default must be a type") + for d in default)) + elif default: + self.__default__ = typing._type_check(default, "Default must be a type") + else: + self.__default__ = None + + +# Add default and infer_variance parameters from PEP 696 and 695 +class TypeVar(typing.TypeVar, _DefaultMixin, _root=True): + """Type variable.""" + + __module__ = 'typing' + + def __init__(self, name, *constraints, bound=None, + covariant=False, contravariant=False, + default=None, infer_variance=False): + super().__init__(name, *constraints, bound=bound, covariant=covariant, + contravariant=contravariant) + _DefaultMixin.__init__(self, default) + self.__infer_variance__ = infer_variance + + # for pickling: + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing_extensions': + self.__module__ = def_mod + + +# Python 3.10+ has PEP 612 +if hasattr(typing, 'ParamSpecArgs'): + ParamSpecArgs = typing.ParamSpecArgs + ParamSpecKwargs = typing.ParamSpecKwargs +# 3.7-3.9 +else: + class _Immutable: + """Mixin to indicate that object should not be copied.""" + __slots__ = () + + def __copy__(self): + return self + + def __deepcopy__(self, memo): + return self + + class ParamSpecArgs(_Immutable): + """The args for a ParamSpec object. + + Given a ParamSpec object P, P.args is an instance of ParamSpecArgs. + + ParamSpecArgs objects have a reference back to their ParamSpec: + + P.args.__origin__ is P + + This type is meant for runtime introspection and has no special meaning to + static type checkers. + """ + def __init__(self, origin): + self.__origin__ = origin + + def __repr__(self): + return f"{self.__origin__.__name__}.args" + + def __eq__(self, other): + if not isinstance(other, ParamSpecArgs): + return NotImplemented + return self.__origin__ == other.__origin__ + + class ParamSpecKwargs(_Immutable): + """The kwargs for a ParamSpec object. + + Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs. + + ParamSpecKwargs objects have a reference back to their ParamSpec: + + P.kwargs.__origin__ is P + + This type is meant for runtime introspection and has no special meaning to + static type checkers. + """ + def __init__(self, origin): + self.__origin__ = origin + + def __repr__(self): + return f"{self.__origin__.__name__}.kwargs" + + def __eq__(self, other): + if not isinstance(other, ParamSpecKwargs): + return NotImplemented + return self.__origin__ == other.__origin__ + +# 3.10+ +if hasattr(typing, 'ParamSpec'): + + # Add default Parameter - PEP 696 + class ParamSpec(typing.ParamSpec, _DefaultMixin, _root=True): + """Parameter specification variable.""" + + __module__ = 'typing' + + def __init__(self, name, *, bound=None, covariant=False, contravariant=False, + default=None): + super().__init__(name, bound=bound, covariant=covariant, + contravariant=contravariant) + _DefaultMixin.__init__(self, default) + + # for pickling: + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing_extensions': + self.__module__ = def_mod + +# 3.7-3.9 +else: + + # Inherits from list as a workaround for Callable checks in Python < 3.9.2. + class ParamSpec(list, _DefaultMixin): + """Parameter specification variable. + + Usage:: + + P = ParamSpec('P') + + Parameter specification variables exist primarily for the benefit of static + type checkers. They are used to forward the parameter types of one + callable to another callable, a pattern commonly found in higher order + functions and decorators. They are only valid when used in ``Concatenate``, + or s the first argument to ``Callable``. In Python 3.10 and higher, + they are also supported in user-defined Generics at runtime. + See class Generic for more information on generic types. An + example for annotating a decorator:: + + T = TypeVar('T') + P = ParamSpec('P') + + def add_logging(f: Callable[P, T]) -> Callable[P, T]: + '''A type-safe decorator to add logging to a function.''' + def inner(*args: P.args, **kwargs: P.kwargs) -> T: + logging.info(f'{f.__name__} was called') + return f(*args, **kwargs) + return inner + + @add_logging + def add_two(x: float, y: float) -> float: + '''Add two numbers together.''' + return x + y + + Parameter specification variables defined with covariant=True or + contravariant=True can be used to declare covariant or contravariant + generic types. These keyword arguments are valid, but their actual semantics + are yet to be decided. See PEP 612 for details. + + Parameter specification variables can be introspected. e.g.: + + P.__name__ == 'T' + P.__bound__ == None + P.__covariant__ == False + P.__contravariant__ == False + + Note that only parameter specification variables defined in global scope can + be pickled. + """ + + # Trick Generic __parameters__. + __class__ = typing.TypeVar + + @property + def args(self): + return ParamSpecArgs(self) + + @property + def kwargs(self): + return ParamSpecKwargs(self) + + def __init__(self, name, *, bound=None, covariant=False, contravariant=False, + default=None): + super().__init__([self]) + self.__name__ = name + self.__covariant__ = bool(covariant) + self.__contravariant__ = bool(contravariant) + if bound: + self.__bound__ = typing._type_check(bound, 'Bound must be a type.') + else: + self.__bound__ = None + _DefaultMixin.__init__(self, default) + + # for pickling: + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing_extensions': + self.__module__ = def_mod + + def __repr__(self): + if self.__covariant__: + prefix = '+' + elif self.__contravariant__: + prefix = '-' + else: + prefix = '~' + return prefix + self.__name__ + + def __hash__(self): + return object.__hash__(self) + + def __eq__(self, other): + return self is other + + def __reduce__(self): + return self.__name__ + + # Hack to get typing._type_check to pass. + def __call__(self, *args, **kwargs): + pass + + +# 3.7-3.9 +if not hasattr(typing, 'Concatenate'): + # Inherits from list as a workaround for Callable checks in Python < 3.9.2. + class _ConcatenateGenericAlias(list): + + # Trick Generic into looking into this for __parameters__. + __class__ = typing._GenericAlias + + # Flag in 3.8. + _special = False + + def __init__(self, origin, args): + super().__init__(args) + self.__origin__ = origin + self.__args__ = args + + def __repr__(self): + _type_repr = typing._type_repr + return (f'{_type_repr(self.__origin__)}' + f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]') + + def __hash__(self): + return hash((self.__origin__, self.__args__)) + + # Hack to get typing._type_check to pass in Generic. + def __call__(self, *args, **kwargs): + pass + + @property + def __parameters__(self): + return tuple( + tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec)) + ) + + +# 3.7-3.9 +@typing._tp_cache +def _concatenate_getitem(self, parameters): + if parameters == (): + raise TypeError("Cannot take a Concatenate of no types.") + if not isinstance(parameters, tuple): + parameters = (parameters,) + if not isinstance(parameters[-1], ParamSpec): + raise TypeError("The last parameter to Concatenate should be a " + "ParamSpec variable.") + msg = "Concatenate[arg, ...]: each arg must be a type." + parameters = tuple(typing._type_check(p, msg) for p in parameters) + return _ConcatenateGenericAlias(self, parameters) + + +# 3.10+ +if hasattr(typing, 'Concatenate'): + Concatenate = typing.Concatenate + _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa +# 3.9 +elif sys.version_info[:2] >= (3, 9): + @_TypeAliasForm + def Concatenate(self, parameters): + """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a + higher order function which adds, removes or transforms parameters of a + callable. + + For example:: + + Callable[Concatenate[int, P], int] + + See PEP 612 for detailed information. + """ + return _concatenate_getitem(self, parameters) +# 3.7-8 +else: + class _ConcatenateForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + return _concatenate_getitem(self, parameters) + + Concatenate = _ConcatenateForm( + 'Concatenate', + doc="""Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a + higher order function which adds, removes or transforms parameters of a + callable. + + For example:: + + Callable[Concatenate[int, P], int] + + See PEP 612 for detailed information. + """) + +# 3.10+ +if hasattr(typing, 'TypeGuard'): + TypeGuard = typing.TypeGuard +# 3.9 +elif sys.version_info[:2] >= (3, 9): + class _TypeGuardForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + @_TypeGuardForm + def TypeGuard(self, parameters): + """Special typing form used to annotate the return type of a user-defined + type guard function. ``TypeGuard`` only accepts a single type argument. + At runtime, functions marked this way should return a boolean. + + ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static + type checkers to determine a more precise type of an expression within a + program's code flow. Usually type narrowing is done by analyzing + conditional code flow and applying the narrowing to a block of code. The + conditional expression here is sometimes referred to as a "type guard". + + Sometimes it would be convenient to use a user-defined boolean function + as a type guard. Such a function should use ``TypeGuard[...]`` as its + return type to alert static type checkers to this intention. + + Using ``-> TypeGuard`` tells the static type checker that for a given + function: + + 1. The return value is a boolean. + 2. If the return value is ``True``, the type of its argument + is the type inside ``TypeGuard``. + + For example:: + + def is_str(val: Union[str, float]): + # "isinstance" type guard + if isinstance(val, str): + # Type of ``val`` is narrowed to ``str`` + ... + else: + # Else, type of ``val`` is narrowed to ``float``. + ... + + Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower + form of ``TypeA`` (it can even be a wider form) and this may lead to + type-unsafe results. The main reason is to allow for things like + narrowing ``List[object]`` to ``List[str]`` even though the latter is not + a subtype of the former, since ``List`` is invariant. The responsibility of + writing type-safe type guards is left to the user. + + ``TypeGuard`` also works with type variables. For more information, see + PEP 647 (User-Defined Type Guards). + """ + item = typing._type_check(parameters, f'{self} accepts only a single type.') + return typing._GenericAlias(self, (item,)) +# 3.7-3.8 +else: + class _TypeGuardForm(typing._SpecialForm, _root=True): + + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type') + return typing._GenericAlias(self, (item,)) + + TypeGuard = _TypeGuardForm( + 'TypeGuard', + doc="""Special typing form used to annotate the return type of a user-defined + type guard function. ``TypeGuard`` only accepts a single type argument. + At runtime, functions marked this way should return a boolean. + + ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static + type checkers to determine a more precise type of an expression within a + program's code flow. Usually type narrowing is done by analyzing + conditional code flow and applying the narrowing to a block of code. The + conditional expression here is sometimes referred to as a "type guard". + + Sometimes it would be convenient to use a user-defined boolean function + as a type guard. Such a function should use ``TypeGuard[...]`` as its + return type to alert static type checkers to this intention. + + Using ``-> TypeGuard`` tells the static type checker that for a given + function: + + 1. The return value is a boolean. + 2. If the return value is ``True``, the type of its argument + is the type inside ``TypeGuard``. + + For example:: + + def is_str(val: Union[str, float]): + # "isinstance" type guard + if isinstance(val, str): + # Type of ``val`` is narrowed to ``str`` + ... + else: + # Else, type of ``val`` is narrowed to ``float``. + ... + + Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower + form of ``TypeA`` (it can even be a wider form) and this may lead to + type-unsafe results. The main reason is to allow for things like + narrowing ``List[object]`` to ``List[str]`` even though the latter is not + a subtype of the former, since ``List`` is invariant. The responsibility of + writing type-safe type guards is left to the user. + + ``TypeGuard`` also works with type variables. For more information, see + PEP 647 (User-Defined Type Guards). + """) + + +# Vendored from cpython typing._SpecialFrom +class _SpecialForm(typing._Final, _root=True): + __slots__ = ('_name', '__doc__', '_getitem') + + def __init__(self, getitem): + self._getitem = getitem + self._name = getitem.__name__ + self.__doc__ = getitem.__doc__ + + def __getattr__(self, item): + if item in {'__name__', '__qualname__'}: + return self._name + + raise AttributeError(item) + + def __mro_entries__(self, bases): + raise TypeError(f"Cannot subclass {self!r}") + + def __repr__(self): + return f'typing_extensions.{self._name}' + + def __reduce__(self): + return self._name + + def __call__(self, *args, **kwds): + raise TypeError(f"Cannot instantiate {self!r}") + + def __or__(self, other): + return typing.Union[self, other] + + def __ror__(self, other): + return typing.Union[other, self] + + def __instancecheck__(self, obj): + raise TypeError(f"{self} cannot be used with isinstance()") + + def __subclasscheck__(self, cls): + raise TypeError(f"{self} cannot be used with issubclass()") + + @typing._tp_cache + def __getitem__(self, parameters): + return self._getitem(self, parameters) + + +if hasattr(typing, "LiteralString"): + LiteralString = typing.LiteralString +else: + @_SpecialForm + def LiteralString(self, params): + """Represents an arbitrary literal string. + + Example:: + + from typing_extensions import LiteralString + + def query(sql: LiteralString) -> ...: + ... + + query("SELECT * FROM table") # ok + query(f"SELECT * FROM {input()}") # not ok + + See PEP 675 for details. + + """ + raise TypeError(f"{self} is not subscriptable") + + +if hasattr(typing, "Self"): + Self = typing.Self +else: + @_SpecialForm + def Self(self, params): + """Used to spell the type of "self" in classes. + + Example:: + + from typing import Self + + class ReturnsSelf: + def parse(self, data: bytes) -> Self: + ... + return self + + """ + + raise TypeError(f"{self} is not subscriptable") + + +if hasattr(typing, "Never"): + Never = typing.Never +else: + @_SpecialForm + def Never(self, params): + """The bottom type, a type that has no members. + + This can be used to define a function that should never be + called, or a function that never returns:: + + from typing_extensions import Never + + def never_call_me(arg: Never) -> None: + pass + + def int_or_str(arg: int | str) -> None: + never_call_me(arg) # type checker error + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + never_call_me(arg) # ok, arg is of type Never + + """ + + raise TypeError(f"{self} is not subscriptable") + + +if hasattr(typing, 'Required'): + Required = typing.Required + NotRequired = typing.NotRequired +elif sys.version_info[:2] >= (3, 9): + class _ExtensionsSpecialForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + @_ExtensionsSpecialForm + def Required(self, parameters): + """A special typing construct to mark a key of a total=False TypedDict + as required. For example: + + class Movie(TypedDict, total=False): + title: Required[str] + year: int + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + + There is no runtime checking that a required key is actually provided + when instantiating a related TypedDict. + """ + item = typing._type_check(parameters, f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + + @_ExtensionsSpecialForm + def NotRequired(self, parameters): + """A special typing construct to mark a key of a TypedDict as + potentially missing. For example: + + class Movie(TypedDict): + title: str + year: NotRequired[int] + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + """ + item = typing._type_check(parameters, f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + +else: + class _RequiredForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type.') + return typing._GenericAlias(self, (item,)) + + Required = _RequiredForm( + 'Required', + doc="""A special typing construct to mark a key of a total=False TypedDict + as required. For example: + + class Movie(TypedDict, total=False): + title: Required[str] + year: int + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + + There is no runtime checking that a required key is actually provided + when instantiating a related TypedDict. + """) + NotRequired = _RequiredForm( + 'NotRequired', + doc="""A special typing construct to mark a key of a TypedDict as + potentially missing. For example: + + class Movie(TypedDict): + title: str + year: NotRequired[int] + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + """) + + +if hasattr(typing, "Unpack"): # 3.11+ + Unpack = typing.Unpack +elif sys.version_info[:2] >= (3, 9): + class _UnpackSpecialForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + class _UnpackAlias(typing._GenericAlias, _root=True): + __class__ = typing.TypeVar + + @_UnpackSpecialForm + def Unpack(self, parameters): + """A special typing construct to unpack a variadic type. For example: + + Shape = TypeVarTuple('Shape') + Batch = NewType('Batch', int) + + def add_batch_axis( + x: Array[Unpack[Shape]] + ) -> Array[Batch, Unpack[Shape]]: ... + + """ + item = typing._type_check(parameters, f'{self._name} accepts only a single type.') + return _UnpackAlias(self, (item,)) + + def _is_unpack(obj): + return isinstance(obj, _UnpackAlias) + +else: + class _UnpackAlias(typing._GenericAlias, _root=True): + __class__ = typing.TypeVar + + class _UnpackForm(typing._SpecialForm, _root=True): + def __repr__(self): + return 'typing_extensions.' + self._name + + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type.') + return _UnpackAlias(self, (item,)) + + Unpack = _UnpackForm( + 'Unpack', + doc="""A special typing construct to unpack a variadic type. For example: + + Shape = TypeVarTuple('Shape') + Batch = NewType('Batch', int) + + def add_batch_axis( + x: Array[Unpack[Shape]] + ) -> Array[Batch, Unpack[Shape]]: ... + + """) + + def _is_unpack(obj): + return isinstance(obj, _UnpackAlias) + + +if hasattr(typing, "TypeVarTuple"): # 3.11+ + + # Add default Parameter - PEP 696 + class TypeVarTuple(typing.TypeVarTuple, _DefaultMixin, _root=True): + """Type variable tuple.""" + + def __init__(self, name, *, default=None): + super().__init__(name) + _DefaultMixin.__init__(self, default) + + # for pickling: + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing_extensions': + self.__module__ = def_mod + +else: + class TypeVarTuple(_DefaultMixin): + """Type variable tuple. + + Usage:: + + Ts = TypeVarTuple('Ts') + + In the same way that a normal type variable is a stand-in for a single + type such as ``int``, a type variable *tuple* is a stand-in for a *tuple* + type such as ``Tuple[int, str]``. + + Type variable tuples can be used in ``Generic`` declarations. + Consider the following example:: + + class Array(Generic[*Ts]): ... + + The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``, + where ``T1`` and ``T2`` are type variables. To use these type variables + as type parameters of ``Array``, we must *unpack* the type variable tuple using + the star operator: ``*Ts``. The signature of ``Array`` then behaves + as if we had simply written ``class Array(Generic[T1, T2]): ...``. + In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows + us to parameterise the class with an *arbitrary* number of type parameters. + + Type variable tuples can be used anywhere a normal ``TypeVar`` can. + This includes class definitions, as shown above, as well as function + signatures and variable annotations:: + + class Array(Generic[*Ts]): + + def __init__(self, shape: Tuple[*Ts]): + self._shape: Tuple[*Ts] = shape + + def get_shape(self) -> Tuple[*Ts]: + return self._shape + + shape = (Height(480), Width(640)) + x: Array[Height, Width] = Array(shape) + y = abs(x) # Inferred type is Array[Height, Width] + z = x + x # ... is Array[Height, Width] + x.get_shape() # ... is tuple[Height, Width] + + """ + + # Trick Generic __parameters__. + __class__ = typing.TypeVar + + def __iter__(self): + yield self.__unpacked__ + + def __init__(self, name, *, default=None): + self.__name__ = name + _DefaultMixin.__init__(self, default) + + # for pickling: + try: + def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + def_mod = None + if def_mod != 'typing_extensions': + self.__module__ = def_mod + + self.__unpacked__ = Unpack[self] + + def __repr__(self): + return self.__name__ + + def __hash__(self): + return object.__hash__(self) + + def __eq__(self, other): + return self is other + + def __reduce__(self): + return self.__name__ + + def __init_subclass__(self, *args, **kwds): + if '_root' not in kwds: + raise TypeError("Cannot subclass special typing classes") + + +if hasattr(typing, "reveal_type"): + reveal_type = typing.reveal_type +else: + def reveal_type(__obj: T) -> T: + """Reveal the inferred type of a variable. + + When a static type checker encounters a call to ``reveal_type()``, + it will emit the inferred type of the argument:: + + x: int = 1 + reveal_type(x) + + Running a static type checker (e.g., ``mypy``) on this example + will produce output similar to 'Revealed type is "builtins.int"'. + + At runtime, the function prints the runtime type of the + argument and returns it unchanged. + + """ + print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr) + return __obj + + +if hasattr(typing, "assert_never"): + assert_never = typing.assert_never +else: + def assert_never(__arg: Never) -> Never: + """Assert to the type checker that a line of code is unreachable. + + Example:: + + def int_or_str(arg: int | str) -> None: + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + assert_never(arg) + + If a type checker finds that a call to assert_never() is + reachable, it will emit an error. + + At runtime, this throws an exception when called. + + """ + raise AssertionError("Expected code to be unreachable") + + +if hasattr(typing, 'dataclass_transform'): + dataclass_transform = typing.dataclass_transform +else: + def dataclass_transform( + *, + eq_default: bool = True, + order_default: bool = False, + kw_only_default: bool = False, + field_specifiers: typing.Tuple[ + typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]], + ... + ] = (), + **kwargs: typing.Any, + ) -> typing.Callable[[T], T]: + """Decorator that marks a function, class, or metaclass as providing + dataclass-like behavior. + + Example: + + from typing_extensions import dataclass_transform + + _T = TypeVar("_T") + + # Used on a decorator function + @dataclass_transform() + def create_model(cls: type[_T]) -> type[_T]: + ... + return cls + + @create_model + class CustomerModel: + id: int + name: str + + # Used on a base class + @dataclass_transform() + class ModelBase: ... + + class CustomerModel(ModelBase): + id: int + name: str + + # Used on a metaclass + @dataclass_transform() + class ModelMeta(type): ... + + class ModelBase(metaclass=ModelMeta): ... + + class CustomerModel(ModelBase): + id: int + name: str + + Each of the ``CustomerModel`` classes defined in this example will now + behave similarly to a dataclass created with the ``@dataclasses.dataclass`` + decorator. For example, the type checker will synthesize an ``__init__`` + method. + + The arguments to this decorator can be used to customize this behavior: + - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be + True or False if it is omitted by the caller. + - ``order_default`` indicates whether the ``order`` parameter is + assumed to be True or False if it is omitted by the caller. + - ``kw_only_default`` indicates whether the ``kw_only`` parameter is + assumed to be True or False if it is omitted by the caller. + - ``field_specifiers`` specifies a static list of supported classes + or functions that describe fields, similar to ``dataclasses.field()``. + + At runtime, this decorator records its arguments in the + ``__dataclass_transform__`` attribute on the decorated object. + + See PEP 681 for details. + + """ + def decorator(cls_or_fn): + cls_or_fn.__dataclass_transform__ = { + "eq_default": eq_default, + "order_default": order_default, + "kw_only_default": kw_only_default, + "field_specifiers": field_specifiers, + "kwargs": kwargs, + } + return cls_or_fn + return decorator + + +if hasattr(typing, "override"): + override = typing.override +else: + _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any]) + + def override(__arg: _F) -> _F: + """Indicate that a method is intended to override a method in a base class. + + Usage: + + class Base: + def method(self) -> None: ... + pass + + class Child(Base): + @override + def method(self) -> None: + super().method() + + When this decorator is applied to a method, the type checker will + validate that it overrides a method with the same name on a base class. + This helps prevent bugs that may occur when a base class is changed + without an equivalent change to a child class. + + See PEP 698 for details. + + """ + return __arg + + +# We have to do some monkey patching to deal with the dual nature of +# Unpack/TypeVarTuple: +# - We want Unpack to be a kind of TypeVar so it gets accepted in +# Generic[Unpack[Ts]] +# - We want it to *not* be treated as a TypeVar for the purposes of +# counting generic parameters, so that when we subscript a generic, +# the runtime doesn't try to substitute the Unpack with the subscripted type. +if not hasattr(typing, "TypeVarTuple"): + typing._collect_type_vars = _collect_type_vars + typing._check_generic = _check_generic + + +# Backport typing.NamedTuple as it exists in Python 3.11. +# In 3.11, the ability to define generic `NamedTuple`s was supported. +# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8. +if sys.version_info >= (3, 11): + NamedTuple = typing.NamedTuple +else: + def _caller(): + try: + return sys._getframe(2).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): # For platforms without _getframe() + return None + + def _make_nmtuple(name, types, module, defaults=()): + fields = [n for n, t in types] + annotations = {n: typing._type_check(t, f"field {n} annotation must be a type") + for n, t in types} + nm_tpl = collections.namedtuple(name, fields, + defaults=defaults, module=module) + nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations + # The `_field_types` attribute was removed in 3.9; + # in earlier versions, it is the same as the `__annotations__` attribute + if sys.version_info < (3, 9): + nm_tpl._field_types = annotations + return nm_tpl + + _prohibited_namedtuple_fields = typing._prohibited + _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'}) + + class _NamedTupleMeta(type): + def __new__(cls, typename, bases, ns): + assert _NamedTuple in bases + for base in bases: + if base is not _NamedTuple and base is not typing.Generic: + raise TypeError( + 'can only inherit from a NamedTuple type and Generic') + bases = tuple(tuple if base is _NamedTuple else base for base in bases) + types = ns.get('__annotations__', {}) + default_names = [] + for field_name in types: + if field_name in ns: + default_names.append(field_name) + elif default_names: + raise TypeError(f"Non-default namedtuple field {field_name} " + f"cannot follow default field" + f"{'s' if len(default_names) > 1 else ''} " + f"{', '.join(default_names)}") + nm_tpl = _make_nmtuple( + typename, types.items(), + defaults=[ns[n] for n in default_names], + module=ns['__module__'] + ) + nm_tpl.__bases__ = bases + if typing.Generic in bases: + class_getitem = typing.Generic.__class_getitem__.__func__ + nm_tpl.__class_getitem__ = classmethod(class_getitem) + # update from user namespace without overriding special namedtuple attributes + for key in ns: + if key in _prohibited_namedtuple_fields: + raise AttributeError("Cannot overwrite NamedTuple attribute " + key) + elif key not in _special_namedtuple_fields and key not in nm_tpl._fields: + setattr(nm_tpl, key, ns[key]) + if typing.Generic in bases: + nm_tpl.__init_subclass__() + return nm_tpl + + def NamedTuple(__typename, __fields=None, **kwargs): + if __fields is None: + __fields = kwargs.items() + elif kwargs: + raise TypeError("Either list of fields or keywords" + " can be provided to NamedTuple, not both") + return _make_nmtuple(__typename, __fields, module=_caller()) + + NamedTuple.__doc__ = typing.NamedTuple.__doc__ + _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {}) + + # On 3.8+, alter the signature so that it matches typing.NamedTuple. + # The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7, + # so just leave the signature as it is on 3.7. + if sys.version_info >= (3, 8): + NamedTuple.__text_signature__ = '(typename, fields=None, /, **kwargs)' + + def _namedtuple_mro_entries(bases): + assert NamedTuple in bases + return (_NamedTuple,) + + NamedTuple.__mro_entries__ = _namedtuple_mro_entries diff --git a/uno/lib/python/pkg_resources/_vendor/zipp.py b/uno/lib/python/pkg_resources/_vendor/zipp.py new file mode 100644 index 00000000..26b723c1 --- /dev/null +++ b/uno/lib/python/pkg_resources/_vendor/zipp.py @@ -0,0 +1,329 @@ +import io +import posixpath +import zipfile +import itertools +import contextlib +import sys +import pathlib + +if sys.version_info < (3, 7): + from collections import OrderedDict +else: + OrderedDict = dict + + +__all__ = ['Path'] + + +def _parents(path): + """ + Given a path with elements separated by + posixpath.sep, generate all parents of that path. + + >>> list(_parents('b/d')) + ['b'] + >>> list(_parents('/b/d/')) + ['/b'] + >>> list(_parents('b/d/f/')) + ['b/d', 'b'] + >>> list(_parents('b')) + [] + >>> list(_parents('')) + [] + """ + return itertools.islice(_ancestry(path), 1, None) + + +def _ancestry(path): + """ + Given a path with elements separated by + posixpath.sep, generate all elements of that path + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] + >>> list(_ancestry('/b/d/')) + ['/b/d', '/b'] + >>> list(_ancestry('b/d/f/')) + ['b/d/f', 'b/d', 'b'] + >>> list(_ancestry('b')) + ['b'] + >>> list(_ancestry('')) + [] + """ + path = path.rstrip(posixpath.sep) + while path and path != posixpath.sep: + yield path + path, tail = posixpath.split(path) + + +_dedupe = OrderedDict.fromkeys +"""Deduplicate an iterable in original order""" + + +def _difference(minuend, subtrahend): + """ + Return items in minuend not in subtrahend, retaining order + with O(1) lookup. + """ + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + +class CompleteDirs(zipfile.ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + as_dirs = (p + posixpath.sep for p in parents) + return _dedupe(_difference(as_dirs, names)) + + def namelist(self): + names = super(CompleteDirs, self).namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, zipfile.ZipFile): + return cls(_pathlib_compat(source)) + + # Only allow for FastLookup when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + source.__class__ = cls + return source + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super(FastLookup, self).namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super(FastLookup, self)._name_set() + return self.__lookup + + +def _pathlib_compat(path): + """ + For path-like objects, convert to a filename for compatibility + on Python 3.6.1 and earlier. + """ + try: + return path.__fspath__() + except AttributeError: + return str(path) + + +class Path: + """ + A pathlib-compatible interface for zip files. + + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = zipfile.ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'mem/abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('mem/abcde.zip', 'a.txt') + >>> b + Path('mem/abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('mem/abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text() + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coercion to string: + + >>> import os + >>> str(c).replace(os.sep, posixpath.sep) + 'mem/abcde.zip/b/c.txt' + + At the root, ``name``, ``filename``, and ``parent`` + resolve to the zipfile. Note these attributes are not + valid and will raise a ``ValueError`` if the zipfile + has no filename. + + >>> root.name + 'abcde.zip' + >>> str(root.filename).replace(os.sep, posixpath.sep) + 'mem/abcde.zip' + >>> str(root.parent) + 'mem' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + """ + Construct a Path from a ZipFile or filename. + + Note: When the source is an existing ZipFile object, + its type (__class__) will be mutated to a + specialized type. If the caller wishes to retain the + original type, the caller should either create a + separate ZipFile object or pass a filename. + """ + self.root = FastLookup.make(root) + self.at = at + + def open(self, mode='r', *args, pwd=None, **kwargs): + """ + Open this entry as text or binary following the semantics + of ``pathlib.Path.open()`` by passing arguments through + to io.TextIOWrapper(). + """ + if self.is_dir(): + raise IsADirectoryError(self) + zip_mode = mode[0] + if not self.exists() and zip_mode == 'r': + raise FileNotFoundError(self) + stream = self.root.open(self.at, zip_mode, pwd=pwd) + if 'b' in mode: + if args or kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + return io.TextIOWrapper(stream, *args, **kwargs) + + @property + def name(self): + return pathlib.Path(self.at).name or self.filename.name + + @property + def suffix(self): + return pathlib.Path(self.at).suffix or self.filename.suffix + + @property + def suffixes(self): + return pathlib.Path(self.at).suffixes or self.filename.suffixes + + @property + def stem(self): + return pathlib.Path(self.at).stem or self.filename.stem + + @property + def filename(self): + return pathlib.Path(self.root.filename).joinpath(self.at) + + def read_text(self, *args, **kwargs): + with self.open('r', *args, **kwargs) as strm: + return strm.read() + + def read_bytes(self): + with self.open('rb') as strm: + return strm.read() + + def _is_child(self, path): + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") + + def _next(self, at): + return self.__class__(self.root, at) + + def is_dir(self): + return not self.at or self.at.endswith("/") + + def is_file(self): + return self.exists() and not self.is_dir() + + def exists(self): + return self.at in self.root._name_set() + + def iterdir(self): + if not self.is_dir(): + raise ValueError("Can't listdir a file") + subs = map(self._next, self.root.namelist()) + return filter(self._is_child, subs) + + def __str__(self): + return posixpath.join(self.root.filename, self.at) + + def __repr__(self): + return self.__repr.format(self=self) + + def joinpath(self, *other): + next = posixpath.join(self.at, *map(_pathlib_compat, other)) + return self._next(self.root.resolve_dir(next)) + + __truediv__ = joinpath + + @property + def parent(self): + if not self.at: + return self.filename.parent + parent_at = posixpath.dirname(self.at.rstrip('/')) + if parent_at: + parent_at += '/' + return self._next(parent_at) diff --git a/uno/lib/python/pkg_resources/extern/__init__.py b/uno/lib/python/pkg_resources/extern/__init__.py index fed59295..948bcc60 100644 --- a/uno/lib/python/pkg_resources/extern/__init__.py +++ b/uno/lib/python/pkg_resources/extern/__init__.py @@ -58,7 +58,8 @@ def find_spec(self, fullname, path=None, target=None): """Return a module spec for vendored names.""" return ( importlib.util.spec_from_loader(fullname, self) - if self._module_matches_namespace(fullname) else None + if self._module_matches_namespace(fullname) + else None ) def install(self): @@ -69,5 +70,11 @@ def install(self): sys.meta_path.append(self) -names = 'packaging', 'pyparsing', 'appdirs' +names = ( + 'packaging', + 'platformdirs', + 'jaraco', + 'importlib_resources', + 'more_itertools', +) VendorImporter(__name__, names).install() diff --git a/uno/lib/python/pkg_resources/tests/data/my-test-package-source/setup.py b/uno/lib/python/pkg_resources/tests/data/my-test-package-source/setup.py deleted file mode 100644 index fe80d28f..00000000 --- a/uno/lib/python/pkg_resources/tests/data/my-test-package-source/setup.py +++ /dev/null @@ -1,6 +0,0 @@ -import setuptools -setuptools.setup( - name="my-test-package", - version="1.0", - zip_safe=True, -) diff --git a/uno/lib/python/poub/attr/__init__.py b/uno/lib/python/poub/attr/__init__.py new file mode 100644 index 00000000..7cfa792f --- /dev/null +++ b/uno/lib/python/poub/attr/__init__.py @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: MIT + +""" +Classes Without Boilerplate +""" + +from functools import partial +from typing import Callable + +from . import converters, exceptions, filters, setters, validators +from ._cmp import cmp_using +from ._config import get_run_validators, set_run_validators +from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types +from ._make import ( + NOTHING, + Attribute, + Factory, + attrib, + attrs, + fields, + fields_dict, + make_class, + validate, +) +from ._next_gen import define, field, frozen, mutable +from ._version_info import VersionInfo + + +s = attributes = attrs +ib = attr = attrib +dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + + +class AttrsInstance: + pass + + +__all__ = [ + "Attribute", + "AttrsInstance", + "Factory", + "NOTHING", + "asdict", + "assoc", + "astuple", + "attr", + "attrib", + "attributes", + "attrs", + "cmp_using", + "converters", + "define", + "evolve", + "exceptions", + "field", + "fields", + "fields_dict", + "filters", + "frozen", + "get_run_validators", + "has", + "ib", + "make_class", + "mutable", + "resolve_types", + "s", + "set_run_validators", + "setters", + "validate", + "validators", +] + + +def _make_getattr(mod_name: str) -> Callable: + """ + Create a metadata proxy for packaging information that uses *mod_name* in + its warnings and errors. + """ + + def __getattr__(name: str) -> str: + dunder_to_metadata = { + "__title__": "Name", + "__copyright__": "", + "__version__": "version", + "__version_info__": "version", + "__description__": "summary", + "__uri__": "", + "__url__": "", + "__author__": "", + "__email__": "", + "__license__": "license", + } + if name not in dunder_to_metadata.keys(): + raise AttributeError(f"module {mod_name} has no attribute {name}") + + import sys + import warnings + + if sys.version_info < (3, 8): + from importlib_metadata import metadata + else: + from importlib.metadata import metadata + + if name != "__version_info__": + warnings.warn( + f"Accessing {mod_name}.{name} is deprecated and will be " + "removed in a future release. Use importlib.metadata directly " + "to query for attrs's packaging metadata.", + DeprecationWarning, + stacklevel=2, + ) + + meta = metadata("attrs") + if name == "__license__": + return "MIT" + elif name == "__copyright__": + return "Copyright (c) 2015 Hynek Schlawack" + elif name in ("__uri__", "__url__"): + return meta["Project-URL"].split(" ", 1)[-1] + elif name == "__version_info__": + return VersionInfo._from_version_string(meta["version"]) + elif name == "__author__": + return meta["Author-email"].rsplit(" ", 1)[0] + elif name == "__email__": + return meta["Author-email"].rsplit("<", 1)[1][:-1] + + return meta[dunder_to_metadata[name]] + + return __getattr__ + + +__getattr__ = _make_getattr(__name__) diff --git a/uno/lib/python/poub/attr/__init__.pyi b/uno/lib/python/poub/attr/__init__.pyi new file mode 100644 index 00000000..ced5a3fd --- /dev/null +++ b/uno/lib/python/poub/attr/__init__.pyi @@ -0,0 +1,571 @@ +import enum +import sys + +from typing import ( + Any, + Callable, + Dict, + Generic, + List, + Mapping, + Optional, + Protocol, + Sequence, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +# `import X as X` is required to make these public +from . import converters as converters +from . import exceptions as exceptions +from . import filters as filters +from . import setters as setters +from . import validators as validators +from ._cmp import cmp_using as cmp_using +from ._typing_compat import AttrsInstance_ +from ._version_info import VersionInfo + +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +__version__: str +__version_info__: VersionInfo +__title__: str +__description__: str +__url__: str +__uri__: str +__author__: str +__email__: str +__license__: str +__copyright__: str + +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) + +_EqOrderType = Union[bool, Callable[[Any], Any]] +_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] +_ConverterType = Callable[[Any], Any] +_FilterType = Callable[["Attribute[_T]", _T], bool] +_ReprType = Callable[[Any], str] +_ReprArgType = Union[bool, _ReprType] +_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] +_OnSetAttrArgType = Union[ + _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType +] +_FieldTransformer = Callable[ + [type, List["Attribute[Any]"]], List["Attribute[Any]"] +] +# FIXME: in reality, if multiple validators are passed they must be in a list +# or tuple, but those are invariant and so would prevent subtypes of +# _ValidatorType from working when passed in a list or tuple. +_ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] + +# We subclass this here to keep the protocol's qualified name clean. +class AttrsInstance(AttrsInstance_, Protocol): + pass + +_A = TypeVar("_A", bound=AttrsInstance) +# _make -- + +class _Nothing(enum.Enum): + NOTHING = enum.auto() + +NOTHING = _Nothing.NOTHING + +# NOTE: Factory lies about its return type to make this possible: +# `x: List[int] # = Factory(list)` +# Work around mypy issue #4554 in the common case by using an overload. +if sys.version_info >= (3, 8): + from typing import Literal + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Callable[[Any], _T], + takes_self: Literal[True], + ) -> _T: ... + @overload + def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], + ) -> _T: ... + +else: + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Union[Callable[[Any], _T], Callable[[], _T]], + takes_self: bool = ..., + ) -> _T: ... + +# Static type inference support via __dataclass_transform__ implemented as per: +# https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md +# This annotation must be applied to all overloads of "define" and "attrs" +# +# NOTE: This is a typing construct and does not exist at runtime. Extensions +# wrapping attrs decorators should declare a separate __dataclass_transform__ +# signature in the extension module using the specification linked above to +# provide pyright support. +def __dataclass_transform__( + *, + eq_default: bool = True, + order_default: bool = False, + kw_only_default: bool = False, + frozen_default: bool = False, + field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), +) -> Callable[[_T], _T]: ... + +class Attribute(Generic[_T]): + name: str + default: Optional[_T] + validator: Optional[_ValidatorType[_T]] + repr: _ReprArgType + cmp: _EqOrderType + eq: _EqOrderType + order: _EqOrderType + hash: Optional[bool] + init: bool + converter: Optional[_ConverterType] + metadata: Dict[Any, Any] + type: Optional[Type[_T]] + kw_only: bool + on_setattr: _OnSetAttrType + alias: Optional[str] + + def evolve(self, **changes: Any) -> "Attribute[Any]": ... + +# NOTE: We had several choices for the annotation to use for type arg: +# 1) Type[_T] +# - Pros: Handles simple cases correctly +# - Cons: Might produce less informative errors in the case of conflicting +# TypeVars e.g. `attr.ib(default='bad', type=int)` +# 2) Callable[..., _T] +# - Pros: Better error messages than #1 for conflicting TypeVars +# - Cons: Terrible error messages for validator checks. +# e.g. attr.ib(type=int, validator=validate_str) +# -> error: Cannot infer function type argument +# 3) type (and do all of the work in the mypy plugin) +# - Pros: Simple here, and we could customize the plugin with our own errors. +# - Cons: Would need to write mypy plugin code to handle all the cases. +# We chose option #1. + +# `attr` lies about its return type to make the following possible: +# attr() -> Any +# attr(8) -> int +# attr(validator=) -> Whatever the callable expects. +# This makes this type of assignments possible: +# x: int = attr(8) +# +# This form catches explicit None or no default but with no other arguments +# returns Any. +@overload +def attrib( + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def attrib( + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def attrib( + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def attrib( + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: object = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., +) -> Any: ... +@overload +def field( + *, + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def field( + *, + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def field( + *, + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def field( + *, + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., + type: Optional[type] = ..., +) -> Any: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: _C, + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., + unsafe_hash: Optional[bool] = ..., +) -> _C: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: None = ..., + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., + unsafe_hash: Optional[bool] = ..., +) -> Callable[[_C], _C]: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: _C, + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: None = ..., + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... + +mutable = define + +@overload +@__dataclass_transform__( + frozen_default=True, field_descriptors=(attrib, field) +) +def frozen( + maybe_cls: _C, + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@__dataclass_transform__( + frozen_default=True, field_descriptors=(attrib, field) +) +def frozen( + maybe_cls: None = ..., + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + unsafe_hash: Optional[bool] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... +def fields(cls: Type[AttrsInstance]) -> Any: ... +def fields_dict(cls: Type[AttrsInstance]) -> Dict[str, Attribute[Any]]: ... +def validate(inst: AttrsInstance) -> None: ... +def resolve_types( + cls: _A, + globalns: Optional[Dict[str, Any]] = ..., + localns: Optional[Dict[str, Any]] = ..., + attribs: Optional[List[Attribute[Any]]] = ..., + include_extras: bool = ..., +) -> _A: ... + +# TODO: add support for returning a proper attrs class from the mypy plugin +# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', +# [attr.ib()])` is valid +def make_class( + name: str, + attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], + bases: Tuple[type, ...] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + collect_by_mro: bool = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> type: ... + +# _funcs -- + +# TODO: add support for returning TypedDict from the mypy plugin +# FIXME: asdict/astuple do not honor their factory args. Waiting on one of +# these: +# https://github.com/python/mypy/issues/4236 +# https://github.com/python/typing/issues/253 +# XXX: remember to fix attrs.asdict/astuple too! +def asdict( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: Optional[bool] = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... +def has(cls: type) -> TypeGuard[Type[AttrsInstance]]: ... +def assoc(inst: _T, **changes: Any) -> _T: ... +def evolve(inst: _T, **changes: Any) -> _T: ... + +# _config -- + +def set_run_validators(run: bool) -> None: ... +def get_run_validators() -> bool: ... + +# aliases -- + +s = attributes = attrs +ib = attr = attrib +dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/uno/lib/python/poub/attr/_cmp.py b/uno/lib/python/poub/attr/_cmp.py new file mode 100644 index 00000000..d9cbe22c --- /dev/null +++ b/uno/lib/python/poub/attr/_cmp.py @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: MIT + + +import functools +import types + +from ._make import _make_ne + + +_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} + + +def cmp_using( + eq=None, + lt=None, + le=None, + gt=None, + ge=None, + require_same_type=True, + class_name="Comparable", +): + """ + Create a class that can be passed into `attrs.field`'s ``eq``, ``order``, + and ``cmp`` arguments to customize field comparison. + + The resulting class will have a full set of ordering methods if at least + one of ``{lt, le, gt, ge}`` and ``eq`` are provided. + + :param Optional[callable] eq: `callable` used to evaluate equality of two + objects. + :param Optional[callable] lt: `callable` used to evaluate whether one + object is less than another object. + :param Optional[callable] le: `callable` used to evaluate whether one + object is less than or equal to another object. + :param Optional[callable] gt: `callable` used to evaluate whether one + object is greater than another object. + :param Optional[callable] ge: `callable` used to evaluate whether one + object is greater than or equal to another object. + + :param bool require_same_type: When `True`, equality and ordering methods + will return `NotImplemented` if objects are not of the same type. + + :param Optional[str] class_name: Name of class. Defaults to 'Comparable'. + + See `comparison` for more details. + + .. versionadded:: 21.1.0 + """ + + body = { + "__slots__": ["value"], + "__init__": _make_init(), + "_requirements": [], + "_is_comparable_to": _is_comparable_to, + } + + # Add operations. + num_order_functions = 0 + has_eq_function = False + + if eq is not None: + has_eq_function = True + body["__eq__"] = _make_operator("eq", eq) + body["__ne__"] = _make_ne() + + if lt is not None: + num_order_functions += 1 + body["__lt__"] = _make_operator("lt", lt) + + if le is not None: + num_order_functions += 1 + body["__le__"] = _make_operator("le", le) + + if gt is not None: + num_order_functions += 1 + body["__gt__"] = _make_operator("gt", gt) + + if ge is not None: + num_order_functions += 1 + body["__ge__"] = _make_operator("ge", ge) + + type_ = types.new_class( + class_name, (object,), {}, lambda ns: ns.update(body) + ) + + # Add same type requirement. + if require_same_type: + type_._requirements.append(_check_same_type) + + # Add total ordering if at least one operation was defined. + if 0 < num_order_functions < 4: + if not has_eq_function: + # functools.total_ordering requires __eq__ to be defined, + # so raise early error here to keep a nice stack. + raise ValueError( + "eq must be define is order to complete ordering from " + "lt, le, gt, ge." + ) + type_ = functools.total_ordering(type_) + + return type_ + + +def _make_init(): + """ + Create __init__ method. + """ + + def __init__(self, value): + """ + Initialize object with *value*. + """ + self.value = value + + return __init__ + + +def _make_operator(name, func): + """ + Create operator method. + """ + + def method(self, other): + if not self._is_comparable_to(other): + return NotImplemented + + result = func(self.value, other.value) + if result is NotImplemented: + return NotImplemented + + return result + + method.__name__ = f"__{name}__" + method.__doc__ = ( + f"Return a {_operation_names[name]} b. Computed by attrs." + ) + + return method + + +def _is_comparable_to(self, other): + """ + Check whether `other` is comparable to `self`. + """ + for func in self._requirements: + if not func(self, other): + return False + return True + + +def _check_same_type(self, other): + """ + Return True if *self* and *other* are of the same type, False otherwise. + """ + return other.value.__class__ is self.value.__class__ diff --git a/uno/lib/python/poub/attr/_cmp.pyi b/uno/lib/python/poub/attr/_cmp.pyi new file mode 100644 index 00000000..f3dcdc1a --- /dev/null +++ b/uno/lib/python/poub/attr/_cmp.pyi @@ -0,0 +1,13 @@ +from typing import Any, Callable, Optional, Type + +_CompareWithType = Callable[[Any, Any], bool] + +def cmp_using( + eq: Optional[_CompareWithType] = ..., + lt: Optional[_CompareWithType] = ..., + le: Optional[_CompareWithType] = ..., + gt: Optional[_CompareWithType] = ..., + ge: Optional[_CompareWithType] = ..., + require_same_type: bool = ..., + class_name: str = ..., +) -> Type: ... diff --git a/uno/lib/python/poub/attr/_compat.py b/uno/lib/python/poub/attr/_compat.py new file mode 100644 index 00000000..c3bf5e33 --- /dev/null +++ b/uno/lib/python/poub/attr/_compat.py @@ -0,0 +1,185 @@ +# SPDX-License-Identifier: MIT + + +import inspect +import platform +import sys +import threading +import types +import warnings + +from collections.abc import Mapping, Sequence # noqa +from typing import _GenericAlias + + +PYPY = platform.python_implementation() == "PyPy" +PY_3_9_PLUS = sys.version_info[:2] >= (3, 9) +PY310 = sys.version_info[:2] >= (3, 10) +PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) + + +def just_warn(*args, **kw): + warnings.warn( + "Running interpreter doesn't sufficiently support code object " + "introspection. Some features like bare super() or accessing " + "__class__ will not work with slotted classes.", + RuntimeWarning, + stacklevel=2, + ) + + +class _AnnotationExtractor: + """ + Extract type annotations from a callable, returning None whenever there + is none. + """ + + __slots__ = ["sig"] + + def __init__(self, callable): + try: + self.sig = inspect.signature(callable) + except (ValueError, TypeError): # inspect failed + self.sig = None + + def get_first_param_type(self): + """ + Return the type annotation of the first argument if it's not empty. + """ + if not self.sig: + return None + + params = list(self.sig.parameters.values()) + if params and params[0].annotation is not inspect.Parameter.empty: + return params[0].annotation + + return None + + def get_return_type(self): + """ + Return the return type if it's not empty. + """ + if ( + self.sig + and self.sig.return_annotation is not inspect.Signature.empty + ): + return self.sig.return_annotation + + return None + + +def make_set_closure_cell(): + """Return a function of two arguments (cell, value) which sets + the value stored in the closure cell `cell` to `value`. + """ + # pypy makes this easy. (It also supports the logic below, but + # why not do the easy/fast thing?) + if PYPY: + + def set_closure_cell(cell, value): + cell.__setstate__((value,)) + + return set_closure_cell + + # Otherwise gotta do it the hard way. + + try: + if sys.version_info >= (3, 8): + + def set_closure_cell(cell, value): + cell.cell_contents = value + + else: + # Create a function that will set its first cellvar to `value`. + def set_first_cellvar_to(value): + x = value + return + + # This function will be eliminated as dead code, but + # not before its reference to `x` forces `x` to be + # represented as a closure cell rather than a local. + def force_x_to_be_a_cell(): # pragma: no cover + return x + + # Extract the code object and make sure our assumptions about + # the closure behavior are correct. + co = set_first_cellvar_to.__code__ + if co.co_cellvars != ("x",) or co.co_freevars != (): + raise AssertionError # pragma: no cover + + # Convert this code object to a code object that sets the + # function's first _freevar_ (not cellvar) to the argument. + args = [co.co_argcount] + args.append(co.co_kwonlyargcount) + args.extend( + [ + co.co_nlocals, + co.co_stacksize, + co.co_flags, + co.co_code, + co.co_consts, + co.co_names, + co.co_varnames, + co.co_filename, + co.co_name, + co.co_firstlineno, + co.co_lnotab, + # These two arguments are reversed: + co.co_cellvars, + co.co_freevars, + ] + ) + set_first_freevar_code = types.CodeType(*args) + + def set_closure_cell(cell, value): + # Create a function using the set_first_freevar_code, + # whose first closure cell is `cell`. Calling it will + # change the value of that cell. + setter = types.FunctionType( + set_first_freevar_code, {}, "setter", (), (cell,) + ) + # And call it to set the cell. + setter(value) + + # Make sure it works on this interpreter: + def make_func_with_cell(): + x = None + + def func(): + return x # pragma: no cover + + return func + + cell = make_func_with_cell().__closure__[0] + set_closure_cell(cell, 100) + if cell.cell_contents != 100: + raise AssertionError # pragma: no cover + + except Exception: + return just_warn + else: + return set_closure_cell + + +set_closure_cell = make_set_closure_cell() + +# Thread-local global to track attrs instances which are already being repr'd. +# This is needed because there is no other (thread-safe) way to pass info +# about the instances that are already being repr'd through the call stack +# in order to ensure we don't perform infinite recursion. +# +# For instance, if an instance contains a dict which contains that instance, +# we need to know that we're already repr'ing the outside instance from within +# the dict's repr() call. +# +# This lives here rather than in _make.py so that the functions in _make.py +# don't have a direct reference to the thread-local in their globals dict. +# If they have such a reference, it breaks cloudpickle. +repr_context = threading.local() + + +def get_generic_base(cl): + """If this is a generic class (A[str]), return the generic base for it.""" + if cl.__class__ is _GenericAlias: + return cl.__origin__ + return None diff --git a/uno/lib/python/poub/attr/_config.py b/uno/lib/python/poub/attr/_config.py new file mode 100644 index 00000000..96d42007 --- /dev/null +++ b/uno/lib/python/poub/attr/_config.py @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: MIT + + +__all__ = ["set_run_validators", "get_run_validators"] + +_run_validators = True + + +def set_run_validators(run): + """ + Set whether or not validators are run. By default, they are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.set_disabled()` + instead. + """ + if not isinstance(run, bool): + raise TypeError("'run' must be bool.") + global _run_validators + _run_validators = run + + +def get_run_validators(): + """ + Return whether or not validators are run. + + .. deprecated:: 21.3.0 It will not be removed, but it also will not be + moved to new ``attrs`` namespace. Use `attrs.validators.get_disabled()` + instead. + """ + return _run_validators diff --git a/uno/lib/python/poub/attr/_funcs.py b/uno/lib/python/poub/attr/_funcs.py new file mode 100644 index 00000000..7f5d9610 --- /dev/null +++ b/uno/lib/python/poub/attr/_funcs.py @@ -0,0 +1,477 @@ +# SPDX-License-Identifier: MIT + + +import copy + +from ._compat import PY_3_9_PLUS, get_generic_base +from ._make import NOTHING, _obj_setattr, fields +from .exceptions import AttrsAttributeNotFoundError + + +def asdict( + inst, + recurse=True, + filter=None, + dict_factory=dict, + retain_collection_types=False, + value_serializer=None, +): + """ + Return the *attrs* attribute values of *inst* as a dict. + + Optionally recurse into other *attrs*-decorated classes. + + :param inst: Instance of an *attrs*-decorated class. + :param bool recurse: Recurse into classes that are also + *attrs*-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attrs.Attribute` as the first argument and the + value as the second argument. + :param callable dict_factory: A callable to produce dictionaries from. For + example, to produce ordered dictionaries instead of normal Python + dictionaries, pass in ``collections.OrderedDict``. + :param bool retain_collection_types: Do not convert to ``list`` when + encountering an attribute whose type is ``tuple`` or ``set``. Only + meaningful if ``recurse`` is ``True``. + :param Optional[callable] value_serializer: A hook that is called for every + attribute or dict key/value. It receives the current instance, field + and value and must return the (updated) value. The hook is run *after* + the optional *filter* has been applied. + + :rtype: return type of *dict_factory* + + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + .. versionadded:: 16.0.0 *dict_factory* + .. versionadded:: 16.1.0 *retain_collection_types* + .. versionadded:: 20.3.0 *value_serializer* + .. versionadded:: 21.3.0 If a dict has a collection for a key, it is + serialized as a tuple. + """ + attrs = fields(inst.__class__) + rv = dict_factory() + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + + if value_serializer is not None: + v = value_serializer(inst, a, v) + + if recurse is True: + if has(v.__class__): + rv[a.name] = asdict( + v, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain_collection_types is True else list + rv[a.name] = cf( + [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in v + ] + ) + elif isinstance(v, dict): + df = dict_factory + rv[a.name] = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in v.items() + ) + else: + rv[a.name] = v + else: + rv[a.name] = v + return rv + + +def _asdict_anything( + val, + is_key, + filter, + dict_factory, + retain_collection_types, + value_serializer, +): + """ + ``asdict`` only works on attrs instances, this works on anything. + """ + if getattr(val.__class__, "__attrs_attrs__", None) is not None: + # Attrs class. + rv = asdict( + val, + recurse=True, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + elif isinstance(val, (tuple, list, set, frozenset)): + if retain_collection_types is True: + cf = val.__class__ + elif is_key: + cf = tuple + else: + cf = list + + rv = cf( + [ + _asdict_anything( + i, + is_key=False, + filter=filter, + dict_factory=dict_factory, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ) + for i in val + ] + ) + elif isinstance(val, dict): + df = dict_factory + rv = df( + ( + _asdict_anything( + kk, + is_key=True, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + _asdict_anything( + vv, + is_key=False, + filter=filter, + dict_factory=df, + retain_collection_types=retain_collection_types, + value_serializer=value_serializer, + ), + ) + for kk, vv in val.items() + ) + else: + rv = val + if value_serializer is not None: + rv = value_serializer(None, None, rv) + + return rv + + +def astuple( + inst, + recurse=True, + filter=None, + tuple_factory=tuple, + retain_collection_types=False, +): + """ + Return the *attrs* attribute values of *inst* as a tuple. + + Optionally recurse into other *attrs*-decorated classes. + + :param inst: Instance of an *attrs*-decorated class. + :param bool recurse: Recurse into classes that are also + *attrs*-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attrs.Attribute` as the first argument and the + value as the second argument. + :param callable tuple_factory: A callable to produce tuples from. For + example, to produce lists instead of tuples. + :param bool retain_collection_types: Do not convert to ``list`` + or ``dict`` when encountering an attribute which type is + ``tuple``, ``dict`` or ``set``. Only meaningful if ``recurse`` is + ``True``. + + :rtype: return type of *tuple_factory* + + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + .. versionadded:: 16.2.0 + """ + attrs = fields(inst.__class__) + rv = [] + retain = retain_collection_types # Very long. :/ + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv.append( + astuple( + v, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain is True else list + rv.append( + cf( + [ + astuple( + j, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(j.__class__) + else j + for j in v + ] + ) + ) + elif isinstance(v, dict): + df = v.__class__ if retain is True else dict + rv.append( + df( + ( + astuple( + kk, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(kk.__class__) + else kk, + astuple( + vv, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(vv.__class__) + else vv, + ) + for kk, vv in v.items() + ) + ) + else: + rv.append(v) + else: + rv.append(v) + + return rv if tuple_factory is list else tuple_factory(rv) + + +def has(cls): + """ + Check whether *cls* is a class with *attrs* attributes. + + :param type cls: Class to introspect. + :raise TypeError: If *cls* is not a class. + + :rtype: bool + """ + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is not None: + return True + + # No attrs, maybe it's a specialized generic (A[str])? + generic_base = get_generic_base(cls) + if generic_base is not None: + generic_attrs = getattr(generic_base, "__attrs_attrs__", None) + if generic_attrs is not None: + # Stick it on here for speed next time. + cls.__attrs_attrs__ = generic_attrs + return generic_attrs is not None + return False + + +def assoc(inst, **changes): + """ + Copy *inst* and apply *changes*. + + This is different from `evolve` that applies the changes to the arguments + that create the new instance. + + `evolve`'s behavior is preferable, but there are `edge cases`_ where it + doesn't work. Therefore `assoc` is deprecated, but will not be removed. + + .. _`edge cases`: https://github.com/python-attrs/attrs/issues/251 + + :param inst: Instance of a class with *attrs* attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise attrs.exceptions.AttrsAttributeNotFoundError: If *attr_name* + couldn't be found on *cls*. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + .. deprecated:: 17.1.0 + Use `attrs.evolve` instead if you can. + This function will not be removed du to the slightly different approach + compared to `attrs.evolve`. + """ + new = copy.copy(inst) + attrs = fields(inst.__class__) + for k, v in changes.items(): + a = getattr(attrs, k, NOTHING) + if a is NOTHING: + raise AttrsAttributeNotFoundError( + f"{k} is not an attrs attribute on {new.__class__}." + ) + _obj_setattr(new, k, v) + return new + + +def evolve(*args, **changes): + """ + Create a new instance, based on the first positional argument with + *changes* applied. + + :param inst: Instance of a class with *attrs* attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise TypeError: If *attr_name* couldn't be found in the class + ``__init__``. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + .. versionadded:: 17.1.0 + .. deprecated:: 23.1.0 + It is now deprecated to pass the instance using the keyword argument + *inst*. It will raise a warning until at least April 2024, after which + it will become an error. Always pass the instance as a positional + argument. + """ + # Try to get instance by positional argument first. + # Use changes otherwise and warn it'll break. + if args: + try: + (inst,) = args + except ValueError: + raise TypeError( + f"evolve() takes 1 positional argument, but {len(args)} " + "were given" + ) from None + else: + try: + inst = changes.pop("inst") + except KeyError: + raise TypeError( + "evolve() missing 1 required positional argument: 'inst'" + ) from None + + import warnings + + warnings.warn( + "Passing the instance per keyword argument is deprecated and " + "will stop working in, or after, April 2024.", + DeprecationWarning, + stacklevel=2, + ) + + cls = inst.__class__ + attrs = fields(cls) + for a in attrs: + if not a.init: + continue + attr_name = a.name # To deal with private attributes. + init_name = a.alias + if init_name not in changes: + changes[init_name] = getattr(inst, attr_name) + + return cls(**changes) + + +def resolve_types( + cls, globalns=None, localns=None, attribs=None, include_extras=True +): + """ + Resolve any strings and forward annotations in type annotations. + + This is only required if you need concrete types in `Attribute`'s *type* + field. In other words, you don't need to resolve your types if you only + use them for static type checking. + + With no arguments, names will be looked up in the module in which the class + was created. If this is not what you want, e.g. if the name only exists + inside a method, you may pass *globalns* or *localns* to specify other + dictionaries in which to look up these names. See the docs of + `typing.get_type_hints` for more details. + + :param type cls: Class to resolve. + :param Optional[dict] globalns: Dictionary containing global variables. + :param Optional[dict] localns: Dictionary containing local variables. + :param Optional[list] attribs: List of attribs for the given class. + This is necessary when calling from inside a ``field_transformer`` + since *cls* is not an *attrs* class yet. + :param bool include_extras: Resolve more accurately, if possible. + Pass ``include_extras`` to ``typing.get_hints``, if supported by the + typing module. On supported Python versions (3.9+), this resolves the + types more accurately. + + :raise TypeError: If *cls* is not a class. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class and you didn't pass any attribs. + :raise NameError: If types cannot be resolved because of missing variables. + + :returns: *cls* so you can use this function also as a class decorator. + Please note that you have to apply it **after** `attrs.define`. That + means the decorator has to come in the line **before** `attrs.define`. + + .. versionadded:: 20.1.0 + .. versionadded:: 21.1.0 *attribs* + .. versionadded:: 23.1.0 *include_extras* + + """ + # Since calling get_type_hints is expensive we cache whether we've + # done it already. + if getattr(cls, "__attrs_types_resolved__", None) != cls: + import typing + + kwargs = {"globalns": globalns, "localns": localns} + + if PY_3_9_PLUS: + kwargs["include_extras"] = include_extras + + hints = typing.get_type_hints(cls, **kwargs) + for field in fields(cls) if attribs is None else attribs: + if field.name in hints: + # Since fields have been frozen we must work around it. + _obj_setattr(field, "type", hints[field.name]) + # We store the class we resolved so that subclasses know they haven't + # been resolved. + cls.__attrs_types_resolved__ = cls + + # Return the class so you can use it as a decorator too. + return cls diff --git a/uno/lib/python/poub/attr/_make.py b/uno/lib/python/poub/attr/_make.py new file mode 100644 index 00000000..d72f738e --- /dev/null +++ b/uno/lib/python/poub/attr/_make.py @@ -0,0 +1,2987 @@ +# SPDX-License-Identifier: MIT + +import copy +import enum +import linecache +import sys +import types +import typing + +from operator import itemgetter + +# We need to import _compat itself in addition to the _compat members to avoid +# having the thread-local in the globals here. +from . import _compat, _config, setters +from ._compat import ( + PY310, + _AnnotationExtractor, + get_generic_base, + set_closure_cell, +) +from .exceptions import ( + DefaultAlreadySetError, + FrozenInstanceError, + NotAnAttrsClassError, + UnannotatedAttributeError, +) + + +# This is used at least twice, so cache it here. +_obj_setattr = object.__setattr__ +_init_converter_pat = "__attr_converter_%s" +_init_factory_pat = "__attr_factory_%s" +_classvar_prefixes = ( + "typing.ClassVar", + "t.ClassVar", + "ClassVar", + "typing_extensions.ClassVar", +) +# we don't use a double-underscore prefix because that triggers +# name mangling when trying to create a slot for the field +# (when slots=True) +_hash_cache_field = "_attrs_cached_hash" + +_empty_metadata_singleton = types.MappingProxyType({}) + +# Unique object for unequivocal getattr() defaults. +_sentinel = object() + +_ng_default_on_setattr = setters.pipe(setters.convert, setters.validate) + + +class _Nothing(enum.Enum): + """ + Sentinel to indicate the lack of a value when ``None`` is ambiguous. + + If extending attrs, you can use ``typing.Literal[NOTHING]`` to show + that a value may be ``NOTHING``. + + .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. + .. versionchanged:: 22.2.0 ``NOTHING`` is now an ``enum.Enum`` variant. + """ + + NOTHING = enum.auto() + + def __repr__(self): + return "NOTHING" + + def __bool__(self): + return False + + +NOTHING = _Nothing.NOTHING +""" +Sentinel to indicate the lack of a value when ``None`` is ambiguous. +""" + + +class _CacheHashWrapper(int): + """ + An integer subclass that pickles / copies as None + + This is used for non-slots classes with ``cache_hash=True``, to avoid + serializing a potentially (even likely) invalid hash value. Since ``None`` + is the default value for uncalculated hashes, whenever this is copied, + the copy's value for the hash should automatically reset. + + See GH #613 for more details. + """ + + def __reduce__(self, _none_constructor=type(None), _args=()): + return _none_constructor, _args + + +def attrib( + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, + alias=None, +): + """ + Create a new attribute on a class. + + .. warning:: + + Does *not* do anything unless the class is also decorated with + `attr.s` / `attrs.define` / et cetera! + + Please consider using `attrs.field` in new code (``attr.ib`` will *never* + go away, though). + + :param default: A value that is used if an *attrs*-generated ``__init__`` + is used and no value is passed while instantiating or the attribute is + excluded using ``init=False``. + + If the value is an instance of `attrs.Factory`, its callable will be + used to construct a new value (useful for mutable data types like lists + or dicts). + + If a default is not set (or set manually to `attrs.NOTHING`), a value + *must* be supplied when instantiating; otherwise a `TypeError` + will be raised. + + The default can also be set using decorator notation as shown below. + + :type default: Any value + + :param callable factory: Syntactic sugar for + ``default=attr.Factory(factory)``. + + :param validator: `callable` that is called by *attrs*-generated + ``__init__`` methods after the instance has been initialized. They + receive the initialized instance, the :func:`~attrs.Attribute`, and the + passed value. + + The return value is *not* inspected so the validator has to throw an + exception itself. + + If a `list` is passed, its items are treated as validators and must + all pass. + + Validators can be globally disabled and re-enabled using + `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. + + The validator can also be set using decorator notation as shown below. + + :type validator: `callable` or a `list` of `callable`\\ s. + + :param repr: Include this attribute in the generated ``__repr__`` + method. If ``True``, include the attribute; if ``False``, omit it. By + default, the built-in ``repr()`` function is used. To override how the + attribute value is formatted, pass a ``callable`` that takes a single + value and returns a string. Note that the resulting string is used + as-is, i.e. it will be used directly *instead* of calling ``repr()`` + (the default). + :type repr: a `bool` or a `callable` to use a custom function. + + :param eq: If ``True`` (default), include this attribute in the + generated ``__eq__`` and ``__ne__`` methods that check two instances + for equality. To override how the attribute value is compared, + pass a ``callable`` that takes a single value and returns the value + to be compared. + :type eq: a `bool` or a `callable`. + + :param order: If ``True`` (default), include this attributes in the + generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. + To override how the attribute value is ordered, + pass a ``callable`` that takes a single value and returns the value + to be ordered. + :type order: a `bool` or a `callable`. + + :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the + same value. Must not be mixed with *eq* or *order*. + :type cmp: a `bool` or a `callable`. + + :param Optional[bool] hash: Include this attribute in the generated + ``__hash__`` method. If ``None`` (default), mirror *eq*'s value. This + is the correct behavior according the Python spec. Setting this value + to anything else than ``None`` is *discouraged*. + :param bool init: Include this attribute in the generated ``__init__`` + method. It is possible to set this to ``False`` and set a default + value. In that case this attributed is unconditionally initialized + with the specified default value or factory. + :param callable converter: `callable` that is called by + *attrs*-generated ``__init__`` methods to convert attribute's value + to the desired format. It is given the passed-in value, and the + returned value will be used as the new value of the attribute. The + value is converted before being passed to the validator, if any. + :param metadata: An arbitrary mapping, to be used by third-party + components. See `extending-metadata`. + + :param type: The type of the attribute. Nowadays, the preferred method to + specify the type is using a variable annotation (see :pep:`526`). + This argument is provided for backward compatibility. + Regardless of the approach used, the type will be stored on + ``Attribute.type``. + + Please note that *attrs* doesn't do anything with this metadata by + itself. You can use it as part of your own code or for + `static type checking `. + :param kw_only: Make this attribute keyword-only in the generated + ``__init__`` (if ``init`` is ``False``, this parameter is ignored). + :param on_setattr: Allows to overwrite the *on_setattr* setting from + `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used. + Set to `attrs.setters.NO_OP` to run **no** `setattr` hooks for this + attribute -- regardless of the setting in `attr.s`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attrs.setters.NO_OP` + :param Optional[str] alias: Override this attribute's parameter name in the + generated ``__init__`` method. If left `None`, default to ``name`` + stripped of leading underscores. See `private-attributes`. + + .. versionadded:: 15.2.0 *convert* + .. versionadded:: 16.3.0 *metadata* + .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. + .. versionchanged:: 17.1.0 + *hash* is ``None`` and therefore mirrors *eq* by default. + .. versionadded:: 17.3.0 *type* + .. deprecated:: 17.4.0 *convert* + .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated + *convert* to achieve consistency with other noun-based arguments. + .. versionadded:: 18.1.0 + ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. + .. versionadded:: 18.2.0 *kw_only* + .. versionchanged:: 19.2.0 *convert* keyword argument removed. + .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 + .. versionchanged:: 21.1.0 + *eq*, *order*, and *cmp* also accept a custom callable + .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 22.2.0 *alias* + """ + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq, order, True + ) + + if hash is not None and hash is not True and hash is not False: + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + + if factory is not None: + if default is not NOTHING: + raise ValueError( + "The `default` and `factory` arguments are mutually " + "exclusive." + ) + if not callable(factory): + raise ValueError("The `factory` argument must be a callable.") + default = Factory(factory) + + if metadata is None: + metadata = {} + + # Apply syntactic sugar by auto-wrapping. + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + if validator and isinstance(validator, (list, tuple)): + validator = and_(*validator) + + if converter and isinstance(converter, (list, tuple)): + converter = pipe(*converter) + + return _CountingAttr( + default=default, + validator=validator, + repr=repr, + cmp=None, + hash=hash, + init=init, + converter=converter, + metadata=metadata, + type=type, + kw_only=kw_only, + eq=eq, + eq_key=eq_key, + order=order, + order_key=order_key, + on_setattr=on_setattr, + alias=alias, + ) + + +def _compile_and_eval(script, globs, locs=None, filename=""): + """ + "Exec" the script with the given global (globs) and local (locs) variables. + """ + bytecode = compile(script, filename, "exec") + eval(bytecode, globs, locs) + + +def _make_method(name, script, filename, globs): + """ + Create the method with the script given and return the method object. + """ + locs = {} + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + count = 1 + base_filename = filename + while True: + linecache_tuple = ( + len(script), + None, + script.splitlines(True), + filename, + ) + old_val = linecache.cache.setdefault(filename, linecache_tuple) + if old_val == linecache_tuple: + break + else: + filename = f"{base_filename[:-1]}-{count}>" + count += 1 + + _compile_and_eval(script, globs, locs, filename) + + return locs[name] + + +def _make_attr_tuple_class(cls_name, attr_names): + """ + Create a tuple subclass to hold `Attribute`s for an `attrs` class. + + The subclass is a bare tuple with properties for names. + + class MyClassAttributes(tuple): + __slots__ = () + x = property(itemgetter(0)) + """ + attr_class_name = f"{cls_name}Attributes" + attr_class_template = [ + f"class {attr_class_name}(tuple):", + " __slots__ = ()", + ] + if attr_names: + for i, attr_name in enumerate(attr_names): + attr_class_template.append( + f" {attr_name} = _attrs_property(_attrs_itemgetter({i}))" + ) + else: + attr_class_template.append(" pass") + globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} + _compile_and_eval("\n".join(attr_class_template), globs) + return globs[attr_class_name] + + +# Tuple class for extracted attributes from a class definition. +# `base_attrs` is a subset of `attrs`. +_Attributes = _make_attr_tuple_class( + "_Attributes", + [ + # all attributes to build dunder methods for + "attrs", + # attributes that have been inherited + "base_attrs", + # map inherited attributes to their originating classes + "base_attrs_map", + ], +) + + +def _is_class_var(annot): + """ + Check whether *annot* is a typing.ClassVar. + + The string comparison hack is used to avoid evaluating all string + annotations which would put attrs-based classes at a performance + disadvantage compared to plain old classes. + """ + annot = str(annot) + + # Annotation can be quoted. + if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): + annot = annot[1:-1] + + return annot.startswith(_classvar_prefixes) + + +def _has_own_attribute(cls, attrib_name): + """ + Check whether *cls* defines *attrib_name* (and doesn't just inherit it). + """ + attr = getattr(cls, attrib_name, _sentinel) + if attr is _sentinel: + return False + + for base_cls in cls.__mro__[1:]: + a = getattr(base_cls, attrib_name, None) + if attr is a: + return False + + return True + + +def _get_annotations(cls): + """ + Get annotations for *cls*. + """ + if _has_own_attribute(cls, "__annotations__"): + return cls.__annotations__ + + return {} + + +def _collect_base_attrs(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in reversed(cls.__mro__[1:-1]): + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.inherited or a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + # For each name, only keep the freshest definition i.e. the furthest at the + # back. base_attr_map is fine because it gets overwritten with every new + # instance. + filtered = [] + seen = set() + for a in reversed(base_attrs): + if a.name in seen: + continue + filtered.insert(0, a) + seen.add(a.name) + + return filtered, base_attr_map + + +def _collect_base_attrs_broken(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + + N.B. *taken_attr_names* will be mutated. + + Adhere to the old incorrect behavior. + + Notably it collects from the front and considers inherited attributes which + leads to the buggy behavior reported in #428. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in cls.__mro__[1:-1]: + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + taken_attr_names.add(a.name) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + return base_attrs, base_attr_map + + +def _transform_attrs( + cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer +): + """ + Transform all `_CountingAttr`s on a class into `Attribute`s. + + If *these* is passed, use that and don't look for them on the class. + + *collect_by_mro* is True, collect them in the correct MRO order, otherwise + use the old -- incorrect -- order. See #428. + + Return an `_Attributes`. + """ + cd = cls.__dict__ + anns = _get_annotations(cls) + + if these is not None: + ca_list = [(name, ca) for name, ca in these.items()] + elif auto_attribs is True: + ca_names = { + name + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + } + ca_list = [] + annot_names = set() + for attr_name, type in anns.items(): + if _is_class_var(type): + continue + annot_names.add(attr_name) + a = cd.get(attr_name, NOTHING) + + if not isinstance(a, _CountingAttr): + if a is NOTHING: + a = attrib() + else: + a = attrib(default=a) + ca_list.append((attr_name, a)) + + unannotated = ca_names - annot_names + if len(unannotated) > 0: + raise UnannotatedAttributeError( + "The following `attr.ib`s lack a type annotation: " + + ", ".join( + sorted(unannotated, key=lambda n: cd.get(n).counter) + ) + + "." + ) + else: + ca_list = sorted( + ( + (name, attr) + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + ), + key=lambda e: e[1].counter, + ) + + own_attrs = [ + Attribute.from_counting_attr( + name=attr_name, ca=ca, type=anns.get(attr_name) + ) + for attr_name, ca in ca_list + ] + + if collect_by_mro: + base_attrs, base_attr_map = _collect_base_attrs( + cls, {a.name for a in own_attrs} + ) + else: + base_attrs, base_attr_map = _collect_base_attrs_broken( + cls, {a.name for a in own_attrs} + ) + + if kw_only: + own_attrs = [a.evolve(kw_only=True) for a in own_attrs] + base_attrs = [a.evolve(kw_only=True) for a in base_attrs] + + attrs = base_attrs + own_attrs + + # Mandatory vs non-mandatory attr order only matters when they are part of + # the __init__ signature and when they aren't kw_only (which are moved to + # the end and can be mandatory or non-mandatory in any order, as they will + # be specified as keyword args anyway). Check the order of those attrs: + had_default = False + for a in (a for a in attrs if a.init is not False and a.kw_only is False): + if had_default is True and a.default is NOTHING: + raise ValueError( + "No mandatory attributes allowed after an attribute with a " + f"default value or factory. Attribute in question: {a!r}" + ) + + if had_default is False and a.default is not NOTHING: + had_default = True + + if field_transformer is not None: + attrs = field_transformer(cls, attrs) + + # Resolve default field alias after executing field_transformer. + # This allows field_transformer to differentiate between explicit vs + # default aliases and supply their own defaults. + attrs = [ + a.evolve(alias=_default_init_alias_for(a.name)) if not a.alias else a + for a in attrs + ] + + # Create AttrsClass *after* applying the field_transformer since it may + # add or remove attributes! + attr_names = [a.name for a in attrs] + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) + + return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map)) + + +def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + if isinstance(self, BaseException) and name in ( + "__cause__", + "__context__", + "__traceback__", + ): + BaseException.__setattr__(self, name, value) + return + + raise FrozenInstanceError() + + +def _frozen_delattrs(self, name): + """ + Attached to frozen classes as __delattr__. + """ + raise FrozenInstanceError() + + +class _ClassBuilder: + """ + Iteratively build *one* class. + """ + + __slots__ = ( + "_attr_names", + "_attrs", + "_base_attr_map", + "_base_names", + "_cache_hash", + "_cls", + "_cls_dict", + "_delete_attribs", + "_frozen", + "_has_pre_init", + "_has_post_init", + "_is_exc", + "_on_setattr", + "_slots", + "_weakref_slot", + "_wrote_own_setattr", + "_has_custom_setattr", + ) + + def __init__( + self, + cls, + these, + slots, + frozen, + weakref_slot, + getstate_setstate, + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_custom_setattr, + field_transformer, + ): + attrs, base_attrs, base_map = _transform_attrs( + cls, + these, + auto_attribs, + kw_only, + collect_by_mro, + field_transformer, + ) + + self._cls = cls + self._cls_dict = dict(cls.__dict__) if slots else {} + self._attrs = attrs + self._base_names = {a.name for a in base_attrs} + self._base_attr_map = base_map + self._attr_names = tuple(a.name for a in attrs) + self._slots = slots + self._frozen = frozen + self._weakref_slot = weakref_slot + self._cache_hash = cache_hash + self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) + self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) + self._delete_attribs = not bool(these) + self._is_exc = is_exc + self._on_setattr = on_setattr + + self._has_custom_setattr = has_custom_setattr + self._wrote_own_setattr = False + + self._cls_dict["__attrs_attrs__"] = self._attrs + + if frozen: + self._cls_dict["__setattr__"] = _frozen_setattrs + self._cls_dict["__delattr__"] = _frozen_delattrs + + self._wrote_own_setattr = True + elif on_setattr in ( + _ng_default_on_setattr, + setters.validate, + setters.convert, + ): + has_validator = has_converter = False + for a in attrs: + if a.validator is not None: + has_validator = True + if a.converter is not None: + has_converter = True + + if has_validator and has_converter: + break + if ( + ( + on_setattr == _ng_default_on_setattr + and not (has_validator or has_converter) + ) + or (on_setattr == setters.validate and not has_validator) + or (on_setattr == setters.convert and not has_converter) + ): + # If class-level on_setattr is set to convert + validate, but + # there's no field to convert or validate, pretend like there's + # no on_setattr. + self._on_setattr = None + + if getstate_setstate: + ( + self._cls_dict["__getstate__"], + self._cls_dict["__setstate__"], + ) = self._make_getstate_setstate() + + def __repr__(self): + return f"<_ClassBuilder(cls={self._cls.__name__})>" + + if PY310: + import abc + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + + return self.abc.update_abstractmethods( + self._patch_original_class() + ) + + else: + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + + return self._patch_original_class() + + def _patch_original_class(self): + """ + Apply accumulated methods and return the class. + """ + cls = self._cls + base_names = self._base_names + + # Clean class of attribute definitions (`attr.ib()`s). + if self._delete_attribs: + for name in self._attr_names: + if ( + name not in base_names + and getattr(cls, name, _sentinel) is not _sentinel + ): + try: + delattr(cls, name) + except AttributeError: + # This can happen if a base class defines a class + # variable and we want to set an attribute with the + # same name by using only a type annotation. + pass + + # Attach our dunder methods. + for name, value in self._cls_dict.items(): + setattr(cls, name, value) + + # If we've inherited an attrs __setattr__ and don't write our own, + # reset it to object's. + if not self._wrote_own_setattr and getattr( + cls, "__attrs_own_setattr__", False + ): + cls.__attrs_own_setattr__ = False + + if not self._has_custom_setattr: + cls.__setattr__ = _obj_setattr + + return cls + + def _create_slots_class(self): + """ + Build and return a new class with a `__slots__` attribute. + """ + cd = { + k: v + for k, v in self._cls_dict.items() + if k not in tuple(self._attr_names) + ("__dict__", "__weakref__") + } + + # If our class doesn't have its own implementation of __setattr__ + # (either from the user or by us), check the bases, if one of them has + # an attrs-made __setattr__, that needs to be reset. We don't walk the + # MRO because we only care about our immediate base classes. + # XXX: This can be confused by subclassing a slotted attrs class with + # XXX: a non-attrs class and subclass the resulting class with an attrs + # XXX: class. See `test_slotted_confused` for details. For now that's + # XXX: OK with us. + if not self._wrote_own_setattr: + cd["__attrs_own_setattr__"] = False + + if not self._has_custom_setattr: + for base_cls in self._cls.__bases__: + if base_cls.__dict__.get("__attrs_own_setattr__", False): + cd["__setattr__"] = _obj_setattr + break + + # Traverse the MRO to collect existing slots + # and check for an existing __weakref__. + existing_slots = dict() + weakref_inherited = False + for base_cls in self._cls.__mro__[1:-1]: + if base_cls.__dict__.get("__weakref__", None) is not None: + weakref_inherited = True + existing_slots.update( + { + name: getattr(base_cls, name) + for name in getattr(base_cls, "__slots__", []) + } + ) + + base_names = set(self._base_names) + + names = self._attr_names + if ( + self._weakref_slot + and "__weakref__" not in getattr(self._cls, "__slots__", ()) + and "__weakref__" not in names + and not weakref_inherited + ): + names += ("__weakref__",) + + # We only add the names of attributes that aren't inherited. + # Setting __slots__ to inherited attributes wastes memory. + slot_names = [name for name in names if name not in base_names] + # There are slots for attributes from current class + # that are defined in parent classes. + # As their descriptors may be overridden by a child class, + # we collect them here and update the class dict + reused_slots = { + slot: slot_descriptor + for slot, slot_descriptor in existing_slots.items() + if slot in slot_names + } + slot_names = [name for name in slot_names if name not in reused_slots] + cd.update(reused_slots) + if self._cache_hash: + slot_names.append(_hash_cache_field) + cd["__slots__"] = tuple(slot_names) + + cd["__qualname__"] = self._cls.__qualname__ + + # Create new class based on old class and our methods. + cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) + + # The following is a fix for + # . + # If a method mentions `__class__` or uses the no-arg super(), the + # compiler will bake a reference to the class in the method itself + # as `method.__closure__`. Since we replace the class with a + # clone, we rewrite these references so it keeps working. + for item in cls.__dict__.values(): + if isinstance(item, (classmethod, staticmethod)): + # Class- and staticmethods hide their functions inside. + # These might need to be rewritten as well. + closure_cells = getattr(item.__func__, "__closure__", None) + elif isinstance(item, property): + # Workaround for property `super()` shortcut (PY3-only). + # There is no universal way for other descriptors. + closure_cells = getattr(item.fget, "__closure__", None) + else: + closure_cells = getattr(item, "__closure__", None) + + if not closure_cells: # Catch None or the empty list. + continue + for cell in closure_cells: + try: + match = cell.cell_contents is self._cls + except ValueError: # ValueError: Cell is empty + pass + else: + if match: + set_closure_cell(cell, cls) + + return cls + + def add_repr(self, ns): + self._cls_dict["__repr__"] = self._add_method_dunders( + _make_repr(self._attrs, ns, self._cls) + ) + return self + + def add_str(self): + repr = self._cls_dict.get("__repr__") + if repr is None: + raise ValueError( + "__str__ can only be generated if a __repr__ exists." + ) + + def __str__(self): + return self.__repr__() + + self._cls_dict["__str__"] = self._add_method_dunders(__str__) + return self + + def _make_getstate_setstate(self): + """ + Create custom __setstate__ and __getstate__ methods. + """ + # __weakref__ is not writable. + state_attr_names = tuple( + an for an in self._attr_names if an != "__weakref__" + ) + + def slots_getstate(self): + """ + Automatically created by attrs. + """ + return {name: getattr(self, name) for name in state_attr_names} + + hash_caching_enabled = self._cache_hash + + def slots_setstate(self, state): + """ + Automatically created by attrs. + """ + __bound_setattr = _obj_setattr.__get__(self) + if isinstance(state, tuple): + # Backward compatibility with attrs instances pickled with + # attrs versions before v22.2.0 which stored tuples. + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + else: + for name in state_attr_names: + if name in state: + __bound_setattr(name, state[name]) + + # The hash code cache is not included when the object is + # serialized, but it still needs to be initialized to None to + # indicate that the first call to __hash__ should be a cache + # miss. + if hash_caching_enabled: + __bound_setattr(_hash_cache_field, None) + + return slots_getstate, slots_setstate + + def make_unhashable(self): + self._cls_dict["__hash__"] = None + return self + + def add_hash(self): + self._cls_dict["__hash__"] = self._add_method_dunders( + _make_hash( + self._cls, + self._attrs, + frozen=self._frozen, + cache_hash=self._cache_hash, + ) + ) + + return self + + def add_init(self): + self._cls_dict["__init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=False, + ) + ) + + return self + + def add_match_args(self): + self._cls_dict["__match_args__"] = tuple( + field.name + for field in self._attrs + if field.init and not field.kw_only + ) + + def add_attrs_init(self): + self._cls_dict["__attrs_init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr, + attrs_init=True, + ) + ) + + return self + + def add_eq(self): + cd = self._cls_dict + + cd["__eq__"] = self._add_method_dunders( + _make_eq(self._cls, self._attrs) + ) + cd["__ne__"] = self._add_method_dunders(_make_ne()) + + return self + + def add_order(self): + cd = self._cls_dict + + cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( + self._add_method_dunders(meth) + for meth in _make_order(self._cls, self._attrs) + ) + + return self + + def add_setattr(self): + if self._frozen: + return self + + sa_attrs = {} + for a in self._attrs: + on_setattr = a.on_setattr or self._on_setattr + if on_setattr and on_setattr is not setters.NO_OP: + sa_attrs[a.name] = a, on_setattr + + if not sa_attrs: + return self + + if self._has_custom_setattr: + # We need to write a __setattr__ but there already is one! + raise ValueError( + "Can't combine custom __setattr__ with on_setattr hooks." + ) + + # docstring comes from _add_method_dunders + def __setattr__(self, name, val): + try: + a, hook = sa_attrs[name] + except KeyError: + nval = val + else: + nval = hook(self, a, val) + + _obj_setattr(self, name, nval) + + self._cls_dict["__attrs_own_setattr__"] = True + self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) + self._wrote_own_setattr = True + + return self + + def _add_method_dunders(self, method): + """ + Add __module__ and __qualname__ to a *method* if possible. + """ + try: + method.__module__ = self._cls.__module__ + except AttributeError: + pass + + try: + method.__qualname__ = ".".join( + (self._cls.__qualname__, method.__name__) + ) + except AttributeError: + pass + + try: + method.__doc__ = ( + "Method generated by attrs for class " + f"{self._cls.__qualname__}." + ) + except AttributeError: + pass + + return method + + +def _determine_attrs_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + return cmp, cmp + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq = default_eq + + if order is None: + order = eq + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, order + + +def _determine_attrib_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + def decide_callable_or_boolean(value): + """ + Decide whether a key function is used. + """ + if callable(value): + value, key = True, value + else: + key = None + return value, key + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + cmp, cmp_key = decide_callable_or_boolean(cmp) + return cmp, cmp_key, cmp, cmp_key + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq, eq_key = default_eq, None + else: + eq, eq_key = decide_callable_or_boolean(eq) + + if order is None: + order, order_key = eq, eq_key + else: + order, order_key = decide_callable_or_boolean(order) + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, eq_key, order, order_key + + +def _determine_whether_to_implement( + cls, flag, auto_detect, dunders, default=True +): + """ + Check whether we should implement a set of methods for *cls*. + + *flag* is the argument passed into @attr.s like 'init', *auto_detect* the + same as passed into @attr.s and *dunders* is a tuple of attribute names + whose presence signal that the user has implemented it themselves. + + Return *default* if no reason for either for or against is found. + """ + if flag is True or flag is False: + return flag + + if flag is None and auto_detect is False: + return default + + # Logically, flag is None and auto_detect is True here. + for dunder in dunders: + if _has_own_attribute(cls, dunder): + return False + + return default + + +def attrs( + maybe_cls=None, + these=None, + repr_ns=None, + repr=None, + cmp=None, + hash=None, + init=None, + slots=False, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=False, + kw_only=False, + cache_hash=False, + auto_exc=False, + eq=None, + order=None, + auto_detect=False, + collect_by_mro=False, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, + unsafe_hash=None, +): + r""" + A class decorator that adds :term:`dunder methods` according to the + specified attributes using `attr.ib` or the *these* argument. + + Please consider using `attrs.define` / `attrs.frozen` in new code + (``attr.s`` will *never* go away, though). + + :param these: A dictionary of name to `attr.ib` mappings. This is + useful to avoid the definition of your attributes within the class body + because you can't (e.g. if you want to add ``__repr__`` methods to + Django models) or don't want to. + + If *these* is not ``None``, *attrs* will *not* search the class body + for attributes and will *not* remove any attributes from it. + + The order is deduced from the order of the attributes inside *these*. + + :type these: `dict` of `str` to `attr.ib` + + :param str repr_ns: When using nested classes, there's no way in Python 2 + to automatically detect that. Therefore it's possible to set the + namespace explicitly for a more meaningful ``repr`` output. + :param bool auto_detect: Instead of setting the *init*, *repr*, *eq*, + *order*, and *hash* arguments explicitly, assume they are set to + ``True`` **unless any** of the involved methods for one of the + arguments is implemented in the *current* class (i.e. it is *not* + inherited from some base class). + + So for example by implementing ``__eq__`` on a class yourself, + *attrs* will deduce ``eq=False`` and will create *neither* + ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible + ``__ne__`` by default, so it *should* be enough to only implement + ``__eq__`` in most cases). + + .. warning:: + + If you prevent *attrs* from creating the ordering methods for you + (``order=False``, e.g. by implementing ``__le__``), it becomes + *your* responsibility to make sure its ordering is sound. The best + way is to use the `functools.total_ordering` decorator. + + + Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, + *cmp*, or *hash* overrides whatever *auto_detect* would determine. + + :param bool repr: Create a ``__repr__`` method with a human readable + representation of *attrs* attributes.. + :param bool str: Create a ``__str__`` method that is identical to + ``__repr__``. This is usually not necessary except for + `Exception`\ s. + :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__`` + and ``__ne__`` methods that check two instances for equality. + + They compare the instances as if they were tuples of their *attrs* + attributes if and only if the types of both classes are *identical*! + :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``, + ``__gt__``, and ``__ge__`` methods that behave like *eq* above and + allow instances to be ordered. If ``None`` (default) mirror value of + *eq*. + :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq* + and *order* to the same value. Must not be mixed with *eq* or *order*. + :param Optional[bool] unsafe_hash: If ``None`` (default), the ``__hash__`` + method is generated according how *eq* and *frozen* are set. + + 1. If *both* are True, *attrs* will generate a ``__hash__`` for you. + 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to + None, marking it unhashable (which it is). + 3. If *eq* is False, ``__hash__`` will be left untouched meaning the + ``__hash__`` method of the base class will be used (if base class is + ``object``, this means it will fall back to id-based hashing.). + + Although not recommended, you can decide for yourself and force + *attrs* to create one (e.g. if the class is immutable even though you + didn't freeze it programmatically) by passing ``True`` or not. Both of + these cases are rather special and should be used carefully. + + See our documentation on `hashing`, Python's documentation on + `object.__hash__`, and the `GitHub issue that led to the default \ + behavior `_ for more + details. + :param Optional[bool] hash: Alias for *unsafe_hash*. *unsafe_hash* takes + precedence. + :param bool init: Create a ``__init__`` method that initializes the + *attrs* attributes. Leading underscores are stripped for the argument + name. If a ``__attrs_pre_init__`` method exists on the class, it will + be called before the class is initialized. If a ``__attrs_post_init__`` + method exists on the class, it will be called after the class is fully + initialized. + + If ``init`` is ``False``, an ``__attrs_init__`` method will be + injected instead. This allows you to define a custom ``__init__`` + method that can do pre-init work such as ``super().__init__()``, + and then call ``__attrs_init__()`` and ``__attrs_post_init__()``. + :param bool slots: Create a :term:`slotted class ` that's + more memory-efficient. Slotted classes are generally superior to the + default dict classes, but have some gotchas you should know about, so + we encourage you to read the :term:`glossary entry `. + :param bool frozen: Make instances immutable after initialization. If + someone attempts to modify a frozen instance, + `attrs.exceptions.FrozenInstanceError` is raised. + + .. note:: + + 1. This is achieved by installing a custom ``__setattr__`` method + on your class, so you can't implement your own. + + 2. True immutability is impossible in Python. + + 3. This *does* have a minor a runtime performance `impact + ` when initializing new instances. In other words: + ``__init__`` is slightly slower with ``frozen=True``. + + 4. If a class is frozen, you cannot modify ``self`` in + ``__attrs_post_init__`` or a self-written ``__init__``. You can + circumvent that limitation by using + ``object.__setattr__(self, "attribute_name", value)``. + + 5. Subclasses of a frozen class are frozen too. + + :param bool weakref_slot: Make instances weak-referenceable. This has no + effect unless ``slots`` is also enabled. + :param bool auto_attribs: If ``True``, collect :pep:`526`-annotated + attributes from the class body. + + In this case, you **must** annotate every field. If *attrs* + encounters a field that is set to an `attr.ib` but lacks a type + annotation, an `attr.exceptions.UnannotatedAttributeError` is + raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't + want to set a type. + + If you assign a value to those attributes (e.g. ``x: int = 42``), that + value becomes the default value like if it were passed using + ``attr.ib(default=42)``. Passing an instance of `attrs.Factory` also + works as expected in most cases (see warning below). + + Attributes annotated as `typing.ClassVar`, and attributes that are + neither annotated nor set to an `attr.ib` are **ignored**. + + .. warning:: + For features that use the attribute name to create decorators (e.g. + :ref:`validators `), you still *must* assign `attr.ib` + to them. Otherwise Python will either not find the name or try to + use the default value to call e.g. ``validator`` on it. + + These errors can be quite confusing and probably the most common bug + report on our bug tracker. + + :param bool kw_only: Make all attributes keyword-only + in the generated ``__init__`` (if ``init`` is ``False``, this + parameter is ignored). + :param bool cache_hash: Ensure that the object's hash code is computed + only once and stored on the object. If this is set to ``True``, + hashing must be either explicitly or implicitly enabled for this + class. If the hash code is cached, avoid any reassignments of + fields involved in hash code computation or mutations of the objects + those fields point to after object creation. If such changes occur, + the behavior of the object's hash code is undefined. + :param bool auto_exc: If the class subclasses `BaseException` + (which implicitly includes any subclass of any exception), the + following happens to behave like a well-behaved Python exceptions + class: + + - the values for *eq*, *order*, and *hash* are ignored and the + instances compare and hash by the instance's ids (N.B. *attrs* will + *not* remove existing implementations of ``__hash__`` or the equality + methods. It just won't add own ones.), + - all attributes that are either passed into ``__init__`` or have a + default value are additionally available as a tuple in the ``args`` + attribute, + - the value of *str* is ignored leaving ``__str__`` to base classes. + :param bool collect_by_mro: Setting this to `True` fixes the way *attrs* + collects attributes from base classes. The default behavior is + incorrect in certain cases of multiple inheritance. It should be on by + default but is kept off for backward-compatibility. + + See issue `#428 `_ for + more details. + + :param Optional[bool] getstate_setstate: + .. note:: + This is usually only interesting for slotted classes and you should + probably just set *auto_detect* to `True`. + + If `True`, ``__getstate__`` and + ``__setstate__`` are generated and attached to the class. This is + necessary for slotted classes to be pickleable. If left `None`, it's + `True` by default for slotted classes and ``False`` for dict classes. + + If *auto_detect* is `True`, and *getstate_setstate* is left `None`, + and **either** ``__getstate__`` or ``__setstate__`` is detected directly + on the class (i.e. not inherited), it is set to `False` (this is usually + what you want). + + :param on_setattr: A callable that is run whenever the user attempts to set + an attribute (either by assignment like ``i.x = 42`` or by using + `setattr` like ``setattr(i, "x", 42)``). It receives the same arguments + as validators: the instance, the attribute that is being modified, and + the new value. + + If no exception is raised, the attribute is set to the return value of + the callable. + + If a list of callables is passed, they're automatically wrapped in an + `attrs.setters.pipe`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attrs.setters.NO_OP` + + :param Optional[callable] field_transformer: + A function that is called with the original class object and all + fields right before *attrs* finalizes the class. You can use + this, e.g., to automatically add converters or validators to + fields based on their types. See `transform-fields` for more details. + + :param bool match_args: + If `True` (default), set ``__match_args__`` on the class to support + :pep:`634` (Structural Pattern Matching). It is a tuple of all + non-keyword-only ``__init__`` parameter names on Python 3.10 and later. + Ignored on older Python versions. + + .. versionadded:: 16.0.0 *slots* + .. versionadded:: 16.1.0 *frozen* + .. versionadded:: 16.3.0 *str* + .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. + .. versionchanged:: 17.1.0 + *hash* supports ``None`` as value which is also the default now. + .. versionadded:: 17.3.0 *auto_attribs* + .. versionchanged:: 18.1.0 + If *these* is passed, no attributes are deleted from the class body. + .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. + .. versionadded:: 18.2.0 *weakref_slot* + .. deprecated:: 18.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a + `DeprecationWarning` if the classes compared are subclasses of + each other. ``__eq`` and ``__ne__`` never tried to compared subclasses + to each other. + .. versionchanged:: 19.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider + subclasses comparable anymore. + .. versionadded:: 18.2.0 *kw_only* + .. versionadded:: 18.2.0 *cache_hash* + .. versionadded:: 19.1.0 *auto_exc* + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *auto_detect* + .. versionadded:: 20.1.0 *collect_by_mro* + .. versionadded:: 20.1.0 *getstate_setstate* + .. versionadded:: 20.1.0 *on_setattr* + .. versionadded:: 20.3.0 *field_transformer* + .. versionchanged:: 21.1.0 + ``init=False`` injects ``__attrs_init__`` + .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` + .. versionchanged:: 21.1.0 *cmp* undeprecated + .. versionadded:: 21.3.0 *match_args* + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). + """ + eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) + + # unsafe_hash takes precedence due to PEP 681. + if unsafe_hash is not None: + hash = unsafe_hash + + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + def wrap(cls): + is_frozen = frozen or _has_frozen_base_class(cls) + is_exc = auto_exc is True and issubclass(cls, BaseException) + has_own_setattr = auto_detect and _has_own_attribute( + cls, "__setattr__" + ) + + if has_own_setattr and is_frozen: + raise ValueError("Can't freeze a class with a custom __setattr__.") + + builder = _ClassBuilder( + cls, + these, + slots, + is_frozen, + weakref_slot, + _determine_whether_to_implement( + cls, + getstate_setstate, + auto_detect, + ("__getstate__", "__setstate__"), + default=slots, + ), + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_own_setattr, + field_transformer, + ) + if _determine_whether_to_implement( + cls, repr, auto_detect, ("__repr__",) + ): + builder.add_repr(repr_ns) + if str is True: + builder.add_str() + + eq = _determine_whether_to_implement( + cls, eq_, auto_detect, ("__eq__", "__ne__") + ) + if not is_exc and eq is True: + builder.add_eq() + if not is_exc and _determine_whether_to_implement( + cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") + ): + builder.add_order() + + builder.add_setattr() + + nonlocal hash + if ( + hash is None + and auto_detect is True + and _has_own_attribute(cls, "__hash__") + ): + hash = False + + if hash is not True and hash is not False and hash is not None: + # Can't use `hash in` because 1 == True for example. + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + elif hash is False or (hash is None and eq is False) or is_exc: + # Don't do anything. Should fall back to __object__'s __hash__ + # which is by id. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + elif hash is True or ( + hash is None and eq is True and is_frozen is True + ): + # Build a __hash__ if told so, or if it's safe. + builder.add_hash() + else: + # Raise TypeError on attempts to hash. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + builder.make_unhashable() + + if _determine_whether_to_implement( + cls, init, auto_detect, ("__init__",) + ): + builder.add_init() + else: + builder.add_attrs_init() + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " init must be True." + ) + + if ( + PY310 + and match_args + and not _has_own_attribute(cls, "__match_args__") + ): + builder.add_match_args() + + return builder.build_class() + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +_attrs = attrs +""" +Internal alias so we can use it in functions that take an argument called +*attrs*. +""" + + +def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ is _frozen_setattrs + + +def _generate_unique_filename(cls, func_name): + """ + Create a "filename" suitable for a function being generated. + """ + return ( + f"" + ) + + +def _make_hash(cls, attrs, frozen, cache_hash): + attrs = tuple( + a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) + ) + + tab = " " + + unique_filename = _generate_unique_filename(cls, "hash") + type_hash = hash(unique_filename) + # If eq is custom generated, we need to include the functions in globs + globs = {} + + hash_def = "def __hash__(self" + hash_func = "hash((" + closing_braces = "))" + if not cache_hash: + hash_def += "):" + else: + hash_def += ", *" + + hash_def += ( + ", _cache_wrapper=" + + "__import__('attr._make')._make._CacheHashWrapper):" + ) + hash_func = "_cache_wrapper(" + hash_func + closing_braces += ")" + + method_lines = [hash_def] + + def append_hash_computation_lines(prefix, indent): + """ + Generate the code for actually computing the hash code. + Below this will either be returned directly or used to compute + a value which is then cached, depending on the value of cache_hash + """ + + method_lines.extend( + [ + indent + prefix + hash_func, + indent + f" {type_hash},", + ] + ) + + for a in attrs: + if a.eq_key: + cmp_name = f"_{a.name}_key" + globs[cmp_name] = a.eq_key + method_lines.append( + indent + f" {cmp_name}(self.{a.name})," + ) + else: + method_lines.append(indent + f" self.{a.name},") + + method_lines.append(indent + " " + closing_braces) + + if cache_hash: + method_lines.append(tab + f"if self.{_hash_cache_field} is None:") + if frozen: + append_hash_computation_lines( + f"object.__setattr__(self, '{_hash_cache_field}', ", tab * 2 + ) + method_lines.append(tab * 2 + ")") # close __setattr__ + else: + append_hash_computation_lines( + f"self.{_hash_cache_field} = ", tab * 2 + ) + method_lines.append(tab + f"return self.{_hash_cache_field}") + else: + append_hash_computation_lines("return ", tab) + + script = "\n".join(method_lines) + return _make_method("__hash__", script, unique_filename, globs) + + +def _add_hash(cls, attrs): + """ + Add a hash method to *cls*. + """ + cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) + return cls + + +def _make_ne(): + """ + Create __ne__ method. + """ + + def __ne__(self, other): + """ + Check equality and either forward a NotImplemented or + return the result negated. + """ + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + + return not result + + return __ne__ + + +def _make_eq(cls, attrs): + """ + Create __eq__ method for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.eq] + + unique_filename = _generate_unique_filename(cls, "eq") + lines = [ + "def __eq__(self, other):", + " if other.__class__ is not self.__class__:", + " return NotImplemented", + ] + + # We can't just do a big self.x = other.x and... clause due to + # irregularities like nan == nan is false but (nan,) == (nan,) is true. + globs = {} + if attrs: + lines.append(" return (") + others = [" ) == ("] + for a in attrs: + if a.eq_key: + cmp_name = f"_{a.name}_key" + # Add the key function to the global namespace + # of the evaluated function. + globs[cmp_name] = a.eq_key + lines.append(f" {cmp_name}(self.{a.name}),") + others.append(f" {cmp_name}(other.{a.name}),") + else: + lines.append(f" self.{a.name},") + others.append(f" other.{a.name},") + + lines += others + [" )"] + else: + lines.append(" return True") + + script = "\n".join(lines) + + return _make_method("__eq__", script, unique_filename, globs) + + +def _make_order(cls, attrs): + """ + Create ordering methods for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.order] + + def attrs_to_tuple(obj): + """ + Save us some typing. + """ + return tuple( + key(value) if key else value + for value, key in ( + (getattr(obj, a.name), a.order_key) for a in attrs + ) + ) + + def __lt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) < attrs_to_tuple(other) + + return NotImplemented + + def __le__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) <= attrs_to_tuple(other) + + return NotImplemented + + def __gt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) > attrs_to_tuple(other) + + return NotImplemented + + def __ge__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) >= attrs_to_tuple(other) + + return NotImplemented + + return __lt__, __le__, __gt__, __ge__ + + +def _add_eq(cls, attrs=None): + """ + Add equality methods to *cls* with *attrs*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__eq__ = _make_eq(cls, attrs) + cls.__ne__ = _make_ne() + + return cls + + +def _make_repr(attrs, ns, cls): + unique_filename = _generate_unique_filename(cls, "repr") + # Figure out which attributes to include, and which function to use to + # format them. The a.repr value can be either bool or a custom + # callable. + attr_names_with_reprs = tuple( + (a.name, (repr if a.repr is True else a.repr), a.init) + for a in attrs + if a.repr is not False + ) + globs = { + name + "_repr": r for name, r, _ in attr_names_with_reprs if r != repr + } + globs["_compat"] = _compat + globs["AttributeError"] = AttributeError + globs["NOTHING"] = NOTHING + attribute_fragments = [] + for name, r, i in attr_names_with_reprs: + accessor = ( + "self." + name if i else 'getattr(self, "' + name + '", NOTHING)' + ) + fragment = ( + "%s={%s!r}" % (name, accessor) + if r == repr + else "%s={%s_repr(%s)}" % (name, name, accessor) + ) + attribute_fragments.append(fragment) + repr_fragment = ", ".join(attribute_fragments) + + if ns is None: + cls_name_fragment = '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}' + else: + cls_name_fragment = ns + ".{self.__class__.__name__}" + + lines = [ + "def __repr__(self):", + " try:", + " already_repring = _compat.repr_context.already_repring", + " except AttributeError:", + " already_repring = {id(self),}", + " _compat.repr_context.already_repring = already_repring", + " else:", + " if id(self) in already_repring:", + " return '...'", + " else:", + " already_repring.add(id(self))", + " try:", + f" return f'{cls_name_fragment}({repr_fragment})'", + " finally:", + " already_repring.remove(id(self))", + ] + + return _make_method( + "__repr__", "\n".join(lines), unique_filename, globs=globs + ) + + +def _add_repr(cls, ns=None, attrs=None): + """ + Add a repr method to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__repr__ = _make_repr(attrs, ns, cls) + return cls + + +def fields(cls): + """ + Return the tuple of *attrs* attributes for a class. + + The tuple also allows accessing the fields by their names (see below for + examples). + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + :rtype: tuple (with name accessors) of `attrs.Attribute` + + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + .. versionchanged:: 23.1.0 Add support for generic classes. + """ + generic_base = get_generic_base(cls) + + if generic_base is None and not isinstance(cls, type): + raise TypeError("Passed object must be a class.") + + attrs = getattr(cls, "__attrs_attrs__", None) + + if attrs is None: + if generic_base is not None: + attrs = getattr(generic_base, "__attrs_attrs__", None) + if attrs is not None: + # Even though this is global state, stick it on here to speed + # it up. We rely on `cls` being cached for this to be + # efficient. + cls.__attrs_attrs__ = attrs + return attrs + raise NotAnAttrsClassError(f"{cls!r} is not an attrs-decorated class.") + + return attrs + + +def fields_dict(cls): + """ + Return an ordered dictionary of *attrs* attributes for a class, whose + keys are the attribute names. + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attrs.exceptions.NotAnAttrsClassError: If *cls* is not an *attrs* + class. + + :rtype: dict + + .. versionadded:: 18.1.0 + """ + if not isinstance(cls, type): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError(f"{cls!r} is not an attrs-decorated class.") + return {a.name: a for a in attrs} + + +def validate(inst): + """ + Validate all attributes on *inst* that have a validator. + + Leaves all exceptions through. + + :param inst: Instance of a class with *attrs* attributes. + """ + if _config._run_validators is False: + return + + for a in fields(inst.__class__): + v = a.validator + if v is not None: + v(inst, a, getattr(inst, a.name)) + + +def _is_slot_cls(cls): + return "__slots__" in cls.__dict__ + + +def _is_slot_attr(a_name, base_attr_map): + """ + Check if the attribute name comes from a slot class. + """ + return a_name in base_attr_map and _is_slot_cls(base_attr_map[a_name]) + + +def _make_init( + cls, + attrs, + pre_init, + post_init, + frozen, + slots, + cache_hash, + base_attr_map, + is_exc, + cls_on_setattr, + attrs_init, +): + has_cls_on_setattr = ( + cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP + ) + + if frozen and has_cls_on_setattr: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = cache_hash or frozen + filtered_attrs = [] + attr_dict = {} + for a in attrs: + if not a.init and a.default is NOTHING: + continue + + filtered_attrs.append(a) + attr_dict[a.name] = a + + if a.on_setattr is not None: + if frozen is True: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = True + elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP: + needs_cached_setattr = True + + unique_filename = _generate_unique_filename(cls, "init") + + script, globs, annotations = _attrs_to_init_script( + filtered_attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + needs_cached_setattr, + has_cls_on_setattr, + attrs_init, + ) + if cls.__module__ in sys.modules: + # This makes typing.get_type_hints(CLS.__init__) resolve string types. + globs.update(sys.modules[cls.__module__].__dict__) + + globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) + + if needs_cached_setattr: + # Save the lookup overhead in __init__ if we need to circumvent + # setattr hooks. + globs["_cached_setattr_get"] = _obj_setattr.__get__ + + init = _make_method( + "__attrs_init__" if attrs_init else "__init__", + script, + unique_filename, + globs, + ) + init.__annotations__ = annotations + + return init + + +def _setattr(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*. + """ + return f"_setattr('{attr_name}', {value_var})" + + +def _setattr_with_converter(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*, but run + its converter first. + """ + return "_setattr('%s', %s(%s))" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +def _assign(attr_name, value, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise + relegate to _setattr. + """ + if has_on_setattr: + return _setattr(attr_name, value, True) + + return f"self.{attr_name} = {value}" + + +def _assign_with_converter(attr_name, value_var, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment after + conversion. Otherwise relegate to _setattr_with_converter. + """ + if has_on_setattr: + return _setattr_with_converter(attr_name, value_var, True) + + return "self.%s = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +def _attrs_to_init_script( + attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + needs_cached_setattr, + has_cls_on_setattr, + attrs_init, +): + """ + Return a script of an initializer for *attrs* and a dict of globals. + + The globals are expected by the generated script. + + If *frozen* is True, we cannot set the attributes directly so we use + a cached ``object.__setattr__``. + """ + lines = [] + if pre_init: + lines.append("self.__attrs_pre_init__()") + + if needs_cached_setattr: + lines.append( + # Circumvent the __setattr__ descriptor to save one lookup per + # assignment. + # Note _setattr will be used again below if cache_hash is True + "_setattr = _cached_setattr_get(self)" + ) + + if frozen is True: + if slots is True: + fmt_setter = _setattr + fmt_setter_with_converter = _setattr_with_converter + else: + # Dict frozen classes assign directly to __dict__. + # But only if the attribute doesn't come from an ancestor slot + # class. + # Note _inst_dict will be used again below if cache_hash is True + lines.append("_inst_dict = self.__dict__") + + def fmt_setter(attr_name, value_var, has_on_setattr): + if _is_slot_attr(attr_name, base_attr_map): + return _setattr(attr_name, value_var, has_on_setattr) + + return f"_inst_dict['{attr_name}'] = {value_var}" + + def fmt_setter_with_converter( + attr_name, value_var, has_on_setattr + ): + if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): + return _setattr_with_converter( + attr_name, value_var, has_on_setattr + ) + + return "_inst_dict['%s'] = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + else: + # Not frozen. + fmt_setter = _assign + fmt_setter_with_converter = _assign_with_converter + + args = [] + kw_only_args = [] + attrs_to_validate = [] + + # This is a dictionary of names to validator and converter callables. + # Injecting this into __init__ globals lets us avoid lookups. + names_for_globals = {} + annotations = {"return": None} + + for a in attrs: + if a.validator: + attrs_to_validate.append(a) + + attr_name = a.name + has_on_setattr = a.on_setattr is not None or ( + a.on_setattr is not setters.NO_OP and has_cls_on_setattr + ) + # a.alias is set to maybe-mangled attr_name in _ClassBuilder if not + # explicitly provided + arg_name = a.alias + + has_factory = isinstance(a.default, Factory) + if has_factory and a.default.takes_self: + maybe_self = "self" + else: + maybe_self = "" + + if a.init is False: + if has_factory: + init_factory_name = _init_factory_pat % (a.name,) + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + init_factory_name + f"({maybe_self})", + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + init_factory_name + f"({maybe_self})", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + f"attr_dict['{attr_name}'].default", + has_on_setattr, + ) + ) + elif a.default is not NOTHING and not has_factory: + arg = f"{arg_name}=attr_dict['{attr_name}'].default" + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + elif has_factory: + arg = f"{arg_name}=NOTHING" + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + lines.append(f"if {arg_name} is not NOTHING:") + + init_factory_name = _init_factory_pat % (a.name,) + if a.converter is not None: + lines.append( + " " + + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter_with_converter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append( + " " + fmt_setter(attr_name, arg_name, has_on_setattr) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.kw_only: + kw_only_args.append(arg_name) + else: + args.append(arg_name) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + if a.init is True: + if a.type is not None and a.converter is None: + annotations[arg_name] = a.type + elif a.converter is not None: + # Try to get the type from the converter. + t = _AnnotationExtractor(a.converter).get_first_param_type() + if t: + annotations[arg_name] = t + + if attrs_to_validate: # we can skip this if there are no validators. + names_for_globals["_config"] = _config + lines.append("if _config._run_validators is True:") + for a in attrs_to_validate: + val_name = "__attr_validator_" + a.name + attr_name = "__attr_" + a.name + lines.append(f" {val_name}(self, {attr_name}, self.{a.name})") + names_for_globals[val_name] = a.validator + names_for_globals[attr_name] = a + + if post_init: + lines.append("self.__attrs_post_init__()") + + # because this is set only after __attrs_post_init__ is called, a crash + # will result if post-init tries to access the hash code. This seemed + # preferable to setting this beforehand, in which case alteration to + # field values during post-init combined with post-init accessing the + # hash code would result in silent bugs. + if cache_hash: + if frozen: + if slots: + # if frozen and slots, then _setattr defined above + init_hash_cache = "_setattr('%s', %s)" + else: + # if frozen and not slots, then _inst_dict defined above + init_hash_cache = "_inst_dict['%s'] = %s" + else: + init_hash_cache = "self.%s = %s" + lines.append(init_hash_cache % (_hash_cache_field, "None")) + + # For exceptions we rely on BaseException.__init__ for proper + # initialization. + if is_exc: + vals = ",".join(f"self.{a.name}" for a in attrs if a.init) + + lines.append(f"BaseException.__init__(self, {vals})") + + args = ", ".join(args) + if kw_only_args: + args += "%s*, %s" % ( + ", " if args else "", # leading comma + ", ".join(kw_only_args), # kw_only args + ) + + return ( + "def %s(self, %s):\n %s\n" + % ( + ("__attrs_init__" if attrs_init else "__init__"), + args, + "\n ".join(lines) if lines else "pass", + ), + names_for_globals, + annotations, + ) + + +def _default_init_alias_for(name: str) -> str: + """ + The default __init__ parameter name for a field. + + This performs private-name adjustment via leading-unscore stripping, + and is the default value of Attribute.alias if not provided. + """ + + return name.lstrip("_") + + +class Attribute: + """ + *Read-only* representation of an attribute. + + .. warning:: + + You should never instantiate this class yourself. + + The class has *all* arguments of `attr.ib` (except for ``factory`` + which is only syntactic sugar for ``default=Factory(...)`` plus the + following: + + - ``name`` (`str`): The name of the attribute. + - ``alias`` (`str`): The __init__ parameter name of the attribute, after + any explicit overrides and default private-attribute-name handling. + - ``inherited`` (`bool`): Whether or not that attribute has been inherited + from a base class. + - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The callables + that are used for comparing and ordering objects by this attribute, + respectively. These are set by passing a callable to `attr.ib`'s ``eq``, + ``order``, or ``cmp`` arguments. See also :ref:`comparison customization + `. + + Instances of this class are frequently used for introspection purposes + like: + + - `fields` returns a tuple of them. + - Validators get them passed as the first argument. + - The :ref:`field transformer ` hook receives a list of + them. + - The ``alias`` property exposes the __init__ parameter name of the field, + with any overrides and default private-attribute handling applied. + + + .. versionadded:: 20.1.0 *inherited* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.2.0 *inherited* is not taken into account for + equality checks and hashing anymore. + .. versionadded:: 21.1.0 *eq_key* and *order_key* + .. versionadded:: 22.2.0 *alias* + + For the full version history of the fields, see `attr.ib`. + """ + + __slots__ = ( + "name", + "default", + "validator", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "type", + "converter", + "kw_only", + "inherited", + "on_setattr", + "alias", + ) + + def __init__( + self, + name, + default, + validator, + repr, + cmp, # XXX: unused, remove along with other cmp code. + hash, + init, + inherited, + metadata=None, + type=None, + converter=None, + kw_only=False, + eq=None, + eq_key=None, + order=None, + order_key=None, + on_setattr=None, + alias=None, + ): + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq_key or eq, order_key or order, True + ) + + # Cache this descriptor here to speed things up later. + bound_setattr = _obj_setattr.__get__(self) + + # Despite the big red warning, people *do* instantiate `Attribute` + # themselves. + bound_setattr("name", name) + bound_setattr("default", default) + bound_setattr("validator", validator) + bound_setattr("repr", repr) + bound_setattr("eq", eq) + bound_setattr("eq_key", eq_key) + bound_setattr("order", order) + bound_setattr("order_key", order_key) + bound_setattr("hash", hash) + bound_setattr("init", init) + bound_setattr("converter", converter) + bound_setattr( + "metadata", + ( + types.MappingProxyType(dict(metadata)) # Shallow copy + if metadata + else _empty_metadata_singleton + ), + ) + bound_setattr("type", type) + bound_setattr("kw_only", kw_only) + bound_setattr("inherited", inherited) + bound_setattr("on_setattr", on_setattr) + bound_setattr("alias", alias) + + def __setattr__(self, name, value): + raise FrozenInstanceError() + + @classmethod + def from_counting_attr(cls, name, ca, type=None): + # type holds the annotated value. deal with conflicts: + if type is None: + type = ca.type + elif ca.type is not None: + raise ValueError( + "Type annotation and type argument cannot both be present" + ) + inst_dict = { + k: getattr(ca, k) + for k in Attribute.__slots__ + if k + not in ( + "name", + "validator", + "default", + "type", + "inherited", + ) # exclude methods and deprecated alias + } + return cls( + name=name, + validator=ca._validator, + default=ca._default, + type=type, + cmp=None, + inherited=False, + **inst_dict, + ) + + # Don't use attrs.evolve since fields(Attribute) doesn't work + def evolve(self, **changes): + """ + Copy *self* and apply *changes*. + + This works similarly to `attrs.evolve` but that function does not work + with `Attribute`. + + It is mainly meant to be used for `transform-fields`. + + .. versionadded:: 20.3.0 + """ + new = copy.copy(self) + + new._setattrs(changes.items()) + + return new + + # Don't use _add_pickle since fields(Attribute) doesn't work + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple( + getattr(self, name) if name != "metadata" else dict(self.metadata) + for name in self.__slots__ + ) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + self._setattrs(zip(self.__slots__, state)) + + def _setattrs(self, name_values_pairs): + bound_setattr = _obj_setattr.__get__(self) + for name, value in name_values_pairs: + if name != "metadata": + bound_setattr(name, value) + else: + bound_setattr( + name, + types.MappingProxyType(dict(value)) + if value + else _empty_metadata_singleton, + ) + + +_a = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=(name != "metadata"), + init=True, + inherited=False, + alias=_default_init_alias_for(name), + ) + for name in Attribute.__slots__ +] + +Attribute = _add_hash( + _add_eq( + _add_repr(Attribute, attrs=_a), + attrs=[a for a in _a if a.name != "inherited"], + ), + attrs=[a for a in _a if a.hash and a.name != "inherited"], +) + + +class _CountingAttr: + """ + Intermediate representation of attributes that uses a counter to preserve + the order in which the attributes have been defined. + + *Internal* data structure of the attrs library. Running into is most + likely the result of a bug like a forgotten `@attr.s` decorator. + """ + + __slots__ = ( + "counter", + "_default", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "_validator", + "converter", + "type", + "kw_only", + "on_setattr", + "alias", + ) + __attrs_attrs__ = tuple( + Attribute( + name=name, + alias=_default_init_alias_for(name), + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=True, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ) + for name in ( + "counter", + "_default", + "repr", + "eq", + "order", + "hash", + "init", + "on_setattr", + "alias", + ) + ) + ( + Attribute( + name="metadata", + alias="metadata", + default=None, + validator=None, + repr=True, + cmp=None, + hash=False, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ), + ) + cls_counter = 0 + + def __init__( + self, + default, + validator, + repr, + cmp, + hash, + init, + converter, + metadata, + type, + kw_only, + eq, + eq_key, + order, + order_key, + on_setattr, + alias, + ): + _CountingAttr.cls_counter += 1 + self.counter = _CountingAttr.cls_counter + self._default = default + self._validator = validator + self.converter = converter + self.repr = repr + self.eq = eq + self.eq_key = eq_key + self.order = order + self.order_key = order_key + self.hash = hash + self.init = init + self.metadata = metadata + self.type = type + self.kw_only = kw_only + self.on_setattr = on_setattr + self.alias = alias + + def validator(self, meth): + """ + Decorator that adds *meth* to the list of validators. + + Returns *meth* unchanged. + + .. versionadded:: 17.1.0 + """ + if self._validator is None: + self._validator = meth + else: + self._validator = and_(self._validator, meth) + return meth + + def default(self, meth): + """ + Decorator that allows to set the default for an attribute. + + Returns *meth* unchanged. + + :raises DefaultAlreadySetError: If default has been set before. + + .. versionadded:: 17.1.0 + """ + if self._default is not NOTHING: + raise DefaultAlreadySetError() + + self._default = Factory(meth, takes_self=True) + + return meth + + +_CountingAttr = _add_eq(_add_repr(_CountingAttr)) + + +class Factory: + """ + Stores a factory callable. + + If passed as the default value to `attrs.field`, the factory is used to + generate a new value. + + :param callable factory: A callable that takes either none or exactly one + mandatory positional argument depending on *takes_self*. + :param bool takes_self: Pass the partially initialized instance that is + being initialized as a positional argument. + + .. versionadded:: 17.1.0 *takes_self* + """ + + __slots__ = ("factory", "takes_self") + + def __init__(self, factory, takes_self=False): + self.factory = factory + self.takes_self = takes_self + + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple(getattr(self, name) for name in self.__slots__) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + for name, value in zip(self.__slots__, state): + setattr(self, name, value) + + +_f = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=True, + init=True, + inherited=False, + ) + for name in Factory.__slots__ +] + +Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) + + +def make_class(name, attrs, bases=(object,), **attributes_arguments): + r""" + A quick way to create a new class called *name* with *attrs*. + + :param str name: The name for the new class. + + :param attrs: A list of names or a dictionary of mappings of names to + `attr.ib`\ s / `attrs.field`\ s. + + The order is deduced from the order of the names or attributes inside + *attrs*. Otherwise the order of the definition of the attributes is + used. + :type attrs: `list` or `dict` + + :param tuple bases: Classes that the new class will subclass. + + :param attributes_arguments: Passed unmodified to `attr.s`. + + :return: A new class with *attrs*. + :rtype: type + + .. versionadded:: 17.1.0 *bases* + .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + """ + if isinstance(attrs, dict): + cls_dict = attrs + elif isinstance(attrs, (list, tuple)): + cls_dict = {a: attrib() for a in attrs} + else: + raise TypeError("attrs argument must be a dict or a list.") + + pre_init = cls_dict.pop("__attrs_pre_init__", None) + post_init = cls_dict.pop("__attrs_post_init__", None) + user_init = cls_dict.pop("__init__", None) + + body = {} + if pre_init is not None: + body["__attrs_pre_init__"] = pre_init + if post_init is not None: + body["__attrs_post_init__"] = post_init + if user_init is not None: + body["__init__"] = user_init + + type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body)) + + # For pickling to work, the __module__ variable needs to be set to the + # frame where the class is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + try: + type_.__module__ = sys._getframe(1).f_globals.get( + "__name__", "__main__" + ) + except (AttributeError, ValueError): + pass + + # We do it here for proper warnings with meaningful stacklevel. + cmp = attributes_arguments.pop("cmp", None) + ( + attributes_arguments["eq"], + attributes_arguments["order"], + ) = _determine_attrs_eq_order( + cmp, + attributes_arguments.get("eq"), + attributes_arguments.get("order"), + True, + ) + + return _attrs(these=cls_dict, **attributes_arguments)(type_) + + +# These are required by within this module so we define them here and merely +# import into .validators / .converters. + + +@attrs(slots=True, hash=True) +class _AndValidator: + """ + Compose many validators to a single one. + """ + + _validators = attrib() + + def __call__(self, inst, attr, value): + for v in self._validators: + v(inst, attr, value) + + +def and_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators. + + :param callables validators: Arbitrary number of validators. + + .. versionadded:: 17.1.0 + """ + vals = [] + for validator in validators: + vals.extend( + validator._validators + if isinstance(validator, _AndValidator) + else [validator] + ) + + return _AndValidator(tuple(vals)) + + +def pipe(*converters): + """ + A converter that composes multiple converters into one. + + When called on a value, it runs all wrapped converters, returning the + *last* value. + + Type annotations will be inferred from the wrapped converters', if + they have any. + + :param callables converters: Arbitrary number of converters. + + .. versionadded:: 20.1.0 + """ + + def pipe_converter(val): + for converter in converters: + val = converter(val) + + return val + + if not converters: + # If the converter list is empty, pipe_converter is the identity. + A = typing.TypeVar("A") + pipe_converter.__annotations__ = {"val": A, "return": A} + else: + # Get parameter type from first converter. + t = _AnnotationExtractor(converters[0]).get_first_param_type() + if t: + pipe_converter.__annotations__["val"] = t + + # Get return type from last converter. + rt = _AnnotationExtractor(converters[-1]).get_return_type() + if rt: + pipe_converter.__annotations__["return"] = rt + + return pipe_converter diff --git a/uno/lib/python/poub/attr/_next_gen.py b/uno/lib/python/poub/attr/_next_gen.py new file mode 100644 index 00000000..8f7c0b9a --- /dev/null +++ b/uno/lib/python/poub/attr/_next_gen.py @@ -0,0 +1,232 @@ +# SPDX-License-Identifier: MIT + +""" +These are keyword-only APIs that call `attr.s` and `attr.ib` with different +default values. +""" + + +from functools import partial + +from . import setters +from ._funcs import asdict as _asdict +from ._funcs import astuple as _astuple +from ._make import ( + NOTHING, + _frozen_setattrs, + _ng_default_on_setattr, + attrib, + attrs, +) +from .exceptions import UnannotatedAttributeError + + +def define( + maybe_cls=None, + *, + these=None, + repr=None, + unsafe_hash=None, + hash=None, + init=None, + slots=True, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=None, + kw_only=False, + cache_hash=False, + auto_exc=True, + eq=None, + order=False, + auto_detect=True, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, + match_args=True, +): + r""" + Define an *attrs* class. + + Differences to the classic `attr.s` that it uses underneath: + + - Automatically detect whether or not *auto_attribs* should be `True` (c.f. + *auto_attribs* parameter). + - If *frozen* is `False`, run converters and validators when setting an + attribute by default. + - *slots=True* + + .. caution:: + + Usually this has only upsides and few visible effects in everyday + programming. But it *can* lead to some suprising behaviors, so please + make sure to read :term:`slotted classes`. + - *auto_exc=True* + - *auto_detect=True* + - *order=False* + - Some options that were only relevant on Python 2 or were kept around for + backwards-compatibility have been removed. + + Please note that these are all defaults and you can change them as you + wish. + + :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves + exactly like `attr.s`. If left `None`, `attr.s` will try to guess: + + 1. If any attributes are annotated and no unannotated `attrs.fields`\ s + are found, it assumes *auto_attribs=True*. + 2. Otherwise it assumes *auto_attribs=False* and tries to collect + `attrs.fields`\ s. + + For now, please refer to `attr.s` for the rest of the parameters. + + .. versionadded:: 20.1.0 + .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. + .. versionadded:: 22.2.0 + *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). + """ + + def do_it(cls, auto_attribs): + return attrs( + maybe_cls=cls, + these=these, + repr=repr, + hash=hash, + unsafe_hash=unsafe_hash, + init=init, + slots=slots, + frozen=frozen, + weakref_slot=weakref_slot, + str=str, + auto_attribs=auto_attribs, + kw_only=kw_only, + cache_hash=cache_hash, + auto_exc=auto_exc, + eq=eq, + order=order, + auto_detect=auto_detect, + collect_by_mro=True, + getstate_setstate=getstate_setstate, + on_setattr=on_setattr, + field_transformer=field_transformer, + match_args=match_args, + ) + + def wrap(cls): + """ + Making this a wrapper ensures this code runs during class creation. + + We also ensure that frozen-ness of classes is inherited. + """ + nonlocal frozen, on_setattr + + had_on_setattr = on_setattr not in (None, setters.NO_OP) + + # By default, mutable classes convert & validate on setattr. + if frozen is False and on_setattr is None: + on_setattr = _ng_default_on_setattr + + # However, if we subclass a frozen class, we inherit the immutability + # and disable on_setattr. + for base_cls in cls.__bases__: + if base_cls.__setattr__ is _frozen_setattrs: + if had_on_setattr: + raise ValueError( + "Frozen classes can't use on_setattr " + "(frozen-ness was inherited)." + ) + + on_setattr = setters.NO_OP + break + + if auto_attribs is not None: + return do_it(cls, auto_attribs) + + try: + return do_it(cls, True) + except UnannotatedAttributeError: + return do_it(cls, False) + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +mutable = define +frozen = partial(define, frozen=True, on_setattr=None) + + +def field( + *, + default=NOTHING, + validator=None, + repr=True, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, + alias=None, +): + """ + Identical to `attr.ib`, except keyword-only and with some arguments + removed. + + .. versionadded:: 23.1.0 + The *type* parameter has been re-added; mostly for + {func}`attrs.make_class`. Please note that type checkers ignore this + metadata. + .. versionadded:: 20.1.0 + """ + return attrib( + default=default, + validator=validator, + repr=repr, + hash=hash, + init=init, + metadata=metadata, + type=type, + converter=converter, + factory=factory, + kw_only=kw_only, + eq=eq, + order=order, + on_setattr=on_setattr, + alias=alias, + ) + + +def asdict(inst, *, recurse=True, filter=None, value_serializer=None): + """ + Same as `attr.asdict`, except that collections types are always retained + and dict is always used as *dict_factory*. + + .. versionadded:: 21.3.0 + """ + return _asdict( + inst=inst, + recurse=recurse, + filter=filter, + value_serializer=value_serializer, + retain_collection_types=True, + ) + + +def astuple(inst, *, recurse=True, filter=None): + """ + Same as `attr.astuple`, except that collections types are always retained + and `tuple` is always used as the *tuple_factory*. + + .. versionadded:: 21.3.0 + """ + return _astuple( + inst=inst, recurse=recurse, filter=filter, retain_collection_types=True + ) diff --git a/uno/lib/python/poub/attr/_typing_compat.pyi b/uno/lib/python/poub/attr/_typing_compat.pyi new file mode 100644 index 00000000..ca7b71e9 --- /dev/null +++ b/uno/lib/python/poub/attr/_typing_compat.pyi @@ -0,0 +1,15 @@ +from typing import Any, ClassVar, Protocol + +# MYPY is a special constant in mypy which works the same way as `TYPE_CHECKING`. +MYPY = False + +if MYPY: + # A protocol to be able to statically accept an attrs class. + class AttrsInstance_(Protocol): + __attrs_attrs__: ClassVar[Any] + +else: + # For type checkers without plug-in support use an empty protocol that + # will (hopefully) be combined into a union. + class AttrsInstance_(Protocol): + pass diff --git a/uno/lib/python/poub/attr/_version_info.py b/uno/lib/python/poub/attr/_version_info.py new file mode 100644 index 00000000..51a1312f --- /dev/null +++ b/uno/lib/python/poub/attr/_version_info.py @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: MIT + + +from functools import total_ordering + +from ._funcs import astuple +from ._make import attrib, attrs + + +@total_ordering +@attrs(eq=False, order=False, slots=True, frozen=True) +class VersionInfo: + """ + A version object that can be compared to tuple of length 1--4: + + >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) + True + >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) + True + >>> vi = attr.VersionInfo(19, 2, 0, "final") + >>> vi < (19, 1, 1) + False + >>> vi < (19,) + False + >>> vi == (19, 2,) + True + >>> vi == (19, 2, 1) + False + + .. versionadded:: 19.2 + """ + + year = attrib(type=int) + minor = attrib(type=int) + micro = attrib(type=int) + releaselevel = attrib(type=str) + + @classmethod + def _from_version_string(cls, s): + """ + Parse *s* and return a _VersionInfo. + """ + v = s.split(".") + if len(v) == 3: + v.append("final") + + return cls( + year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] + ) + + def _ensure_tuple(self, other): + """ + Ensure *other* is a tuple of a valid length. + + Returns a possibly transformed *other* and ourselves as a tuple of + the same length as *other*. + """ + + if self.__class__ is other.__class__: + other = astuple(other) + + if not isinstance(other, tuple): + raise NotImplementedError + + if not (1 <= len(other) <= 4): + raise NotImplementedError + + return astuple(self)[: len(other)], other + + def __eq__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + return us == them + + def __lt__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't + # have to do anything special with releaselevel for now. + return us < them diff --git a/uno/lib/python/poub/attr/_version_info.pyi b/uno/lib/python/poub/attr/_version_info.pyi new file mode 100644 index 00000000..45ced086 --- /dev/null +++ b/uno/lib/python/poub/attr/_version_info.pyi @@ -0,0 +1,9 @@ +class VersionInfo: + @property + def year(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... diff --git a/uno/lib/python/poub/attr/converters.py b/uno/lib/python/poub/attr/converters.py new file mode 100644 index 00000000..4cada106 --- /dev/null +++ b/uno/lib/python/poub/attr/converters.py @@ -0,0 +1,144 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful converters. +""" + + +import typing + +from ._compat import _AnnotationExtractor +from ._make import NOTHING, Factory, pipe + + +__all__ = [ + "default_if_none", + "optional", + "pipe", + "to_bool", +] + + +def optional(converter): + """ + A converter that allows an attribute to be optional. An optional attribute + is one which can be set to ``None``. + + Type annotations will be inferred from the wrapped converter's, if it + has any. + + :param callable converter: the converter that is used for non-``None`` + values. + + .. versionadded:: 17.1.0 + """ + + def optional_converter(val): + if val is None: + return None + return converter(val) + + xtr = _AnnotationExtractor(converter) + + t = xtr.get_first_param_type() + if t: + optional_converter.__annotations__["val"] = typing.Optional[t] + + rt = xtr.get_return_type() + if rt: + optional_converter.__annotations__["return"] = typing.Optional[rt] + + return optional_converter + + +def default_if_none(default=NOTHING, factory=None): + """ + A converter that allows to replace ``None`` values by *default* or the + result of *factory*. + + :param default: Value to be used if ``None`` is passed. Passing an instance + of `attrs.Factory` is supported, however the ``takes_self`` option + is *not*. + :param callable factory: A callable that takes no parameters whose result + is used if ``None`` is passed. + + :raises TypeError: If **neither** *default* or *factory* is passed. + :raises TypeError: If **both** *default* and *factory* are passed. + :raises ValueError: If an instance of `attrs.Factory` is passed with + ``takes_self=True``. + + .. versionadded:: 18.2.0 + """ + if default is NOTHING and factory is None: + raise TypeError("Must pass either `default` or `factory`.") + + if default is not NOTHING and factory is not None: + raise TypeError( + "Must pass either `default` or `factory` but not both." + ) + + if factory is not None: + default = Factory(factory) + + if isinstance(default, Factory): + if default.takes_self: + raise ValueError( + "`takes_self` is not supported by default_if_none." + ) + + def default_if_none_converter(val): + if val is not None: + return val + + return default.factory() + + else: + + def default_if_none_converter(val): + if val is not None: + return val + + return default + + return default_if_none_converter + + +def to_bool(val): + """ + Convert "boolean" strings (e.g., from env. vars.) to real booleans. + + Values mapping to :code:`True`: + + - :code:`True` + - :code:`"true"` / :code:`"t"` + - :code:`"yes"` / :code:`"y"` + - :code:`"on"` + - :code:`"1"` + - :code:`1` + + Values mapping to :code:`False`: + + - :code:`False` + - :code:`"false"` / :code:`"f"` + - :code:`"no"` / :code:`"n"` + - :code:`"off"` + - :code:`"0"` + - :code:`0` + + :raises ValueError: for any other value. + + .. versionadded:: 21.3.0 + """ + if isinstance(val, str): + val = val.lower() + truthy = {True, "true", "t", "yes", "y", "on", "1", 1} + falsy = {False, "false", "f", "no", "n", "off", "0", 0} + try: + if val in truthy: + return True + if val in falsy: + return False + except TypeError: + # Raised when "val" is not hashable (e.g., lists) + pass + raise ValueError(f"Cannot convert value to bool: {val}") diff --git a/uno/lib/python/poub/attr/converters.pyi b/uno/lib/python/poub/attr/converters.pyi new file mode 100644 index 00000000..5abb49f6 --- /dev/null +++ b/uno/lib/python/poub/attr/converters.pyi @@ -0,0 +1,13 @@ +from typing import Callable, TypeVar, overload + +from . import _ConverterType + +_T = TypeVar("_T") + +def pipe(*validators: _ConverterType) -> _ConverterType: ... +def optional(converter: _ConverterType) -> _ConverterType: ... +@overload +def default_if_none(default: _T) -> _ConverterType: ... +@overload +def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... +def to_bool(val: str) -> bool: ... diff --git a/uno/lib/python/poub/attr/exceptions.py b/uno/lib/python/poub/attr/exceptions.py new file mode 100644 index 00000000..28834930 --- /dev/null +++ b/uno/lib/python/poub/attr/exceptions.py @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: MIT + + +class FrozenError(AttributeError): + """ + A frozen/immutable instance or attribute have been attempted to be + modified. + + It mirrors the behavior of ``namedtuples`` by using the same error message + and subclassing `AttributeError`. + + .. versionadded:: 20.1.0 + """ + + msg = "can't set attribute" + args = [msg] + + +class FrozenInstanceError(FrozenError): + """ + A frozen instance has been attempted to be modified. + + .. versionadded:: 16.1.0 + """ + + +class FrozenAttributeError(FrozenError): + """ + A frozen attribute has been attempted to be modified. + + .. versionadded:: 20.1.0 + """ + + +class AttrsAttributeNotFoundError(ValueError): + """ + An *attrs* function couldn't find an attribute that the user asked for. + + .. versionadded:: 16.2.0 + """ + + +class NotAnAttrsClassError(ValueError): + """ + A non-*attrs* class has been passed into an *attrs* function. + + .. versionadded:: 16.2.0 + """ + + +class DefaultAlreadySetError(RuntimeError): + """ + A default has been set when defining the field and is attempted to be reset + using the decorator. + + .. versionadded:: 17.1.0 + """ + + +class UnannotatedAttributeError(RuntimeError): + """ + A class with ``auto_attribs=True`` has a field without a type annotation. + + .. versionadded:: 17.3.0 + """ + + +class PythonTooOldError(RuntimeError): + """ + It was attempted to use an *attrs* feature that requires a newer Python + version. + + .. versionadded:: 18.2.0 + """ + + +class NotCallableError(TypeError): + """ + A field requiring a callable has been set with a value that is not + callable. + + .. versionadded:: 19.2.0 + """ + + def __init__(self, msg, value): + super(TypeError, self).__init__(msg, value) + self.msg = msg + self.value = value + + def __str__(self): + return str(self.msg) diff --git a/uno/lib/python/poub/attr/exceptions.pyi b/uno/lib/python/poub/attr/exceptions.pyi new file mode 100644 index 00000000..f2680118 --- /dev/null +++ b/uno/lib/python/poub/attr/exceptions.pyi @@ -0,0 +1,17 @@ +from typing import Any + +class FrozenError(AttributeError): + msg: str = ... + +class FrozenInstanceError(FrozenError): ... +class FrozenAttributeError(FrozenError): ... +class AttrsAttributeNotFoundError(ValueError): ... +class NotAnAttrsClassError(ValueError): ... +class DefaultAlreadySetError(RuntimeError): ... +class UnannotatedAttributeError(RuntimeError): ... +class PythonTooOldError(RuntimeError): ... + +class NotCallableError(TypeError): + msg: str = ... + value: Any = ... + def __init__(self, msg: str, value: Any) -> None: ... diff --git a/uno/lib/python/poub/attr/filters.py b/uno/lib/python/poub/attr/filters.py new file mode 100644 index 00000000..a1e40c98 --- /dev/null +++ b/uno/lib/python/poub/attr/filters.py @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful filters for `attr.asdict`. +""" + +from ._make import Attribute + + +def _split_what(what): + """ + Returns a tuple of `frozenset`s of classes and attributes. + """ + return ( + frozenset(cls for cls in what if isinstance(cls, type)), + frozenset(cls for cls in what if isinstance(cls, str)), + frozenset(cls for cls in what if isinstance(cls, Attribute)), + ) + + +def include(*what): + """ + Include *what*. + + :param what: What to include. + :type what: `list` of classes `type`, field names `str` or + `attrs.Attribute`\\ s + + :rtype: `callable` + + .. versionchanged:: 23.1.0 Accept strings with field names. + """ + cls, names, attrs = _split_what(what) + + def include_(attribute, value): + return ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) + + return include_ + + +def exclude(*what): + """ + Exclude *what*. + + :param what: What to exclude. + :type what: `list` of classes `type`, field names `str` or + `attrs.Attribute`\\ s. + + :rtype: `callable` + + .. versionchanged:: 23.3.0 Accept field name string as input argument + """ + cls, names, attrs = _split_what(what) + + def exclude_(attribute, value): + return not ( + value.__class__ in cls + or attribute.name in names + or attribute in attrs + ) + + return exclude_ diff --git a/uno/lib/python/poub/attr/filters.pyi b/uno/lib/python/poub/attr/filters.pyi new file mode 100644 index 00000000..8a02fa0f --- /dev/null +++ b/uno/lib/python/poub/attr/filters.pyi @@ -0,0 +1,6 @@ +from typing import Any, Union + +from . import Attribute, _FilterType + +def include(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... +def exclude(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... diff --git a/uno/lib/python/poub/attr/py.typed b/uno/lib/python/poub/attr/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/poub/attr/setters.py b/uno/lib/python/poub/attr/setters.py new file mode 100644 index 00000000..12ed6750 --- /dev/null +++ b/uno/lib/python/poub/attr/setters.py @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly used hooks for on_setattr. +""" + + +from . import _config +from .exceptions import FrozenAttributeError + + +def pipe(*setters): + """ + Run all *setters* and return the return value of the last one. + + .. versionadded:: 20.1.0 + """ + + def wrapped_pipe(instance, attrib, new_value): + rv = new_value + + for setter in setters: + rv = setter(instance, attrib, rv) + + return rv + + return wrapped_pipe + + +def frozen(_, __, ___): + """ + Prevent an attribute to be modified. + + .. versionadded:: 20.1.0 + """ + raise FrozenAttributeError() + + +def validate(instance, attrib, new_value): + """ + Run *attrib*'s validator on *new_value* if it has one. + + .. versionadded:: 20.1.0 + """ + if _config._run_validators is False: + return new_value + + v = attrib.validator + if not v: + return new_value + + v(instance, attrib, new_value) + + return new_value + + +def convert(instance, attrib, new_value): + """ + Run *attrib*'s converter -- if it has one -- on *new_value* and return the + result. + + .. versionadded:: 20.1.0 + """ + c = attrib.converter + if c: + return c(new_value) + + return new_value + + +# Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. +# autodata stopped working, so the docstring is inlined in the API docs. +NO_OP = object() diff --git a/uno/lib/python/poub/attr/setters.pyi b/uno/lib/python/poub/attr/setters.pyi new file mode 100644 index 00000000..72f7ce47 --- /dev/null +++ b/uno/lib/python/poub/attr/setters.pyi @@ -0,0 +1,19 @@ +from typing import Any, NewType, NoReturn, TypeVar + +from . import Attribute, _OnSetAttrType + +_T = TypeVar("_T") + +def frozen( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> NoReturn: ... +def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... +def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... + +# convert is allowed to return Any, because they can be chained using pipe. +def convert( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> Any: ... + +_NoOpType = NewType("_NoOpType", object) +NO_OP: _NoOpType diff --git a/uno/lib/python/poub/attr/validators.py b/uno/lib/python/poub/attr/validators.py new file mode 100644 index 00000000..1488554f --- /dev/null +++ b/uno/lib/python/poub/attr/validators.py @@ -0,0 +1,720 @@ +# SPDX-License-Identifier: MIT + +""" +Commonly useful validators. +""" + + +import operator +import re + +from contextlib import contextmanager +from re import Pattern + +from ._config import get_run_validators, set_run_validators +from ._make import _AndValidator, and_, attrib, attrs +from .converters import default_if_none +from .exceptions import NotCallableError + + +__all__ = [ + "and_", + "deep_iterable", + "deep_mapping", + "disabled", + "ge", + "get_disabled", + "gt", + "in_", + "instance_of", + "is_callable", + "le", + "lt", + "matches_re", + "max_len", + "min_len", + "not_", + "optional", + "provides", + "set_disabled", +] + + +def set_disabled(disabled): + """ + Globally disable or enable running validators. + + By default, they are run. + + :param disabled: If ``True``, disable running all validators. + :type disabled: bool + + .. warning:: + + This function is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(not disabled) + + +def get_disabled(): + """ + Return a bool indicating whether validators are currently disabled or not. + + :return: ``True`` if validators are currently disabled. + :rtype: bool + + .. versionadded:: 21.3.0 + """ + return not get_run_validators() + + +@contextmanager +def disabled(): + """ + Context manager that disables running validators within its context. + + .. warning:: + + This context manager is not thread-safe! + + .. versionadded:: 21.3.0 + """ + set_run_validators(False) + try: + yield + finally: + set_run_validators(True) + + +@attrs(repr=False, slots=True, hash=True) +class _InstanceOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not isinstance(value, self.type): + raise TypeError( + "'{name}' must be {type!r} (got {value!r} that is a " + "{actual!r}).".format( + name=attr.name, + type=self.type, + actual=value.__class__, + value=value, + ), + attr, + self.type, + value, + ) + + def __repr__(self): + return "".format( + type=self.type + ) + + +def instance_of(type): + """ + A validator that raises a `TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + `isinstance` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of type + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected type, and the value it + got. + """ + return _InstanceOfValidator(type) + + +@attrs(repr=False, frozen=True, slots=True) +class _MatchesReValidator: + pattern = attrib() + match_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.match_func(value): + raise ValueError( + "'{name}' must match regex {pattern!r}" + " ({value!r} doesn't)".format( + name=attr.name, pattern=self.pattern.pattern, value=value + ), + attr, + self.pattern, + value, + ) + + def __repr__(self): + return "".format( + pattern=self.pattern + ) + + +def matches_re(regex, flags=0, func=None): + r""" + A validator that raises `ValueError` if the initializer is called + with a string that doesn't match *regex*. + + :param regex: a regex string or precompiled pattern to match against + :param int flags: flags that will be passed to the underlying re function + (default 0) + :param callable func: which underlying `re` function to call. Valid options + are `re.fullmatch`, `re.search`, and `re.match`; the default ``None`` + means `re.fullmatch`. For performance reasons, the pattern is always + precompiled using `re.compile`. + + .. versionadded:: 19.2.0 + .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern. + """ + valid_funcs = (re.fullmatch, None, re.search, re.match) + if func not in valid_funcs: + raise ValueError( + "'func' must be one of {}.".format( + ", ".join( + sorted( + e and e.__name__ or "None" for e in set(valid_funcs) + ) + ) + ) + ) + + if isinstance(regex, Pattern): + if flags: + raise TypeError( + "'flags' can only be used with a string pattern; " + "pass flags to re.compile() instead" + ) + pattern = regex + else: + pattern = re.compile(regex, flags) + + if func is re.match: + match_func = pattern.match + elif func is re.search: + match_func = pattern.search + else: + match_func = pattern.fullmatch + + return _MatchesReValidator(pattern, match_func) + + +@attrs(repr=False, slots=True, hash=True) +class _ProvidesValidator: + interface = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.interface.providedBy(value): + raise TypeError( + "'{name}' must provide {interface!r} which {value!r} " + "doesn't.".format( + name=attr.name, interface=self.interface, value=value + ), + attr, + self.interface, + value, + ) + + def __repr__(self): + return "".format( + interface=self.interface + ) + + +def provides(interface): + """ + A validator that raises a `TypeError` if the initializer is called + with an object that does not provide the requested *interface* (checks are + performed using ``interface.providedBy(value)`` (see `zope.interface + `_). + + :param interface: The interface to check for. + :type interface: ``zope.interface.Interface`` + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected interface, and the + value it got. + + .. deprecated:: 23.1.0 + """ + import warnings + + warnings.warn( + "attrs's zope-interface support is deprecated and will be removed in, " + "or after, April 2024.", + DeprecationWarning, + stacklevel=2, + ) + return _ProvidesValidator(interface) + + +@attrs(repr=False, slots=True, hash=True) +class _OptionalValidator: + validator = attrib() + + def __call__(self, inst, attr, value): + if value is None: + return + + self.validator(inst, attr, value) + + def __repr__(self): + return "".format( + what=repr(self.validator) + ) + + +def optional(validator): + """ + A validator that makes an attribute optional. An optional attribute is one + which can be set to ``None`` in addition to satisfying the requirements of + the sub-validator. + + :param Callable | tuple[Callable] | list[Callable] validator: A validator + (or validators) that is used for non-``None`` values. + + .. versionadded:: 15.1.0 + .. versionchanged:: 17.1.0 *validator* can be a list of validators. + .. versionchanged:: 23.1.0 *validator* can also be a tuple of validators. + """ + if isinstance(validator, (list, tuple)): + return _OptionalValidator(_AndValidator(validator)) + + return _OptionalValidator(validator) + + +@attrs(repr=False, slots=True, hash=True) +class _InValidator: + options = attrib() + + def __call__(self, inst, attr, value): + try: + in_options = value in self.options + except TypeError: # e.g. `1 in "abc"` + in_options = False + + if not in_options: + raise ValueError( + "'{name}' must be in {options!r} (got {value!r})".format( + name=attr.name, options=self.options, value=value + ), + attr, + self.options, + value, + ) + + def __repr__(self): + return "".format( + options=self.options + ) + + +def in_(options): + """ + A validator that raises a `ValueError` if the initializer is called + with a value that does not belong in the options provided. The check is + performed using ``value in options``. + + :param options: Allowed options. + :type options: list, tuple, `enum.Enum`, ... + + :raises ValueError: With a human readable error message, the attribute (of + type `attrs.Attribute`), the expected options, and the value it + got. + + .. versionadded:: 17.1.0 + .. versionchanged:: 22.1.0 + The ValueError was incomplete until now and only contained the human + readable error message. Now it contains all the information that has + been promised since 17.1.0. + """ + return _InValidator(options) + + +@attrs(repr=False, slots=False, hash=True) +class _IsCallableValidator: + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not callable(value): + message = ( + "'{name}' must be callable " + "(got {value!r} that is a {actual!r})." + ) + raise NotCallableError( + msg=message.format( + name=attr.name, value=value, actual=value.__class__ + ), + value=value, + ) + + def __repr__(self): + return "" + + +def is_callable(): + """ + A validator that raises a `attrs.exceptions.NotCallableError` if the + initializer is called with a value for this particular attribute + that is not callable. + + .. versionadded:: 19.1.0 + + :raises attrs.exceptions.NotCallableError: With a human readable error + message containing the attribute (`attrs.Attribute`) name, + and the value it got. + """ + return _IsCallableValidator() + + +@attrs(repr=False, slots=True, hash=True) +class _DeepIterable: + member_validator = attrib(validator=is_callable()) + iterable_validator = attrib( + default=None, validator=optional(is_callable()) + ) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.iterable_validator is not None: + self.iterable_validator(inst, attr, value) + + for member in value: + self.member_validator(inst, attr, member) + + def __repr__(self): + iterable_identifier = ( + "" + if self.iterable_validator is None + else f" {self.iterable_validator!r}" + ) + return ( + "" + ).format( + iterable_identifier=iterable_identifier, + member=self.member_validator, + ) + + +def deep_iterable(member_validator, iterable_validator=None): + """ + A validator that performs deep validation of an iterable. + + :param member_validator: Validator(s) to apply to iterable members + :param iterable_validator: Validator to apply to iterable itself + (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + if isinstance(member_validator, (list, tuple)): + member_validator = and_(*member_validator) + return _DeepIterable(member_validator, iterable_validator) + + +@attrs(repr=False, slots=True, hash=True) +class _DeepMapping: + key_validator = attrib(validator=is_callable()) + value_validator = attrib(validator=is_callable()) + mapping_validator = attrib(default=None, validator=optional(is_callable())) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.mapping_validator is not None: + self.mapping_validator(inst, attr, value) + + for key in value: + self.key_validator(inst, attr, key) + self.value_validator(inst, attr, value[key]) + + def __repr__(self): + return ( + "" + ).format(key=self.key_validator, value=self.value_validator) + + +def deep_mapping(key_validator, value_validator, mapping_validator=None): + """ + A validator that performs deep validation of a dictionary. + + :param key_validator: Validator to apply to dictionary keys + :param value_validator: Validator to apply to dictionary values + :param mapping_validator: Validator to apply to top-level mapping + attribute (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + return _DeepMapping(key_validator, value_validator, mapping_validator) + + +@attrs(repr=False, frozen=True, slots=True) +class _NumberValidator: + bound = attrib() + compare_op = attrib() + compare_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.compare_func(value, self.bound): + raise ValueError( + "'{name}' must be {op} {bound}: {value}".format( + name=attr.name, + op=self.compare_op, + bound=self.bound, + value=value, + ) + ) + + def __repr__(self): + return "".format( + op=self.compare_op, bound=self.bound + ) + + +def lt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number larger or equal to *val*. + + :param val: Exclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<", operator.lt) + + +def le(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number greater than *val*. + + :param val: Inclusive upper bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, "<=", operator.le) + + +def ge(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller than *val*. + + :param val: Inclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">=", operator.ge) + + +def gt(val): + """ + A validator that raises `ValueError` if the initializer is called + with a number smaller or equal to *val*. + + :param val: Exclusive lower bound for values + + .. versionadded:: 21.3.0 + """ + return _NumberValidator(val, ">", operator.gt) + + +@attrs(repr=False, frozen=True, slots=True) +class _MaxLengthValidator: + max_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) > self.max_length: + raise ValueError( + "Length of '{name}' must be <= {max}: {len}".format( + name=attr.name, max=self.max_length, len=len(value) + ) + ) + + def __repr__(self): + return f"" + + +def max_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is longer than *length*. + + :param int length: Maximum length of the string or iterable + + .. versionadded:: 21.3.0 + """ + return _MaxLengthValidator(length) + + +@attrs(repr=False, frozen=True, slots=True) +class _MinLengthValidator: + min_length = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if len(value) < self.min_length: + raise ValueError( + "Length of '{name}' must be => {min}: {len}".format( + name=attr.name, min=self.min_length, len=len(value) + ) + ) + + def __repr__(self): + return f"" + + +def min_len(length): + """ + A validator that raises `ValueError` if the initializer is called + with a string or iterable that is shorter than *length*. + + :param int length: Minimum length of the string or iterable + + .. versionadded:: 22.1.0 + """ + return _MinLengthValidator(length) + + +@attrs(repr=False, slots=True, hash=True) +class _SubclassOfValidator: + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not issubclass(value, self.type): + raise TypeError( + "'{name}' must be a subclass of {type!r} " + "(got {value!r}).".format( + name=attr.name, + type=self.type, + value=value, + ), + attr, + self.type, + value, + ) + + def __repr__(self): + return "".format( + type=self.type + ) + + +def _subclass_of(type): + """ + A validator that raises a `TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + `issubclass` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of types + + :raises TypeError: With a human readable error message, the attribute + (of type `attrs.Attribute`), the expected type, and the value it + got. + """ + return _SubclassOfValidator(type) + + +@attrs(repr=False, slots=True, hash=True) +class _NotValidator: + validator = attrib() + msg = attrib( + converter=default_if_none( + "not_ validator child '{validator!r}' " + "did not raise a captured error" + ) + ) + exc_types = attrib( + validator=deep_iterable( + member_validator=_subclass_of(Exception), + iterable_validator=instance_of(tuple), + ), + ) + + def __call__(self, inst, attr, value): + try: + self.validator(inst, attr, value) + except self.exc_types: + pass # suppress error to invert validity + else: + raise ValueError( + self.msg.format( + validator=self.validator, + exc_types=self.exc_types, + ), + attr, + self.validator, + value, + self.exc_types, + ) + + def __repr__(self): + return ( + "" + ).format( + what=self.validator, + exc_types=self.exc_types, + ) + + +def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)): + """ + A validator that wraps and logically 'inverts' the validator passed to it. + It will raise a `ValueError` if the provided validator *doesn't* raise a + `ValueError` or `TypeError` (by default), and will suppress the exception + if the provided validator *does*. + + Intended to be used with existing validators to compose logic without + needing to create inverted variants, for example, ``not_(in_(...))``. + + :param validator: A validator to be logically inverted. + :param msg: Message to raise if validator fails. + Formatted with keys ``exc_types`` and ``validator``. + :type msg: str + :param exc_types: Exception type(s) to capture. + Other types raised by child validators will not be intercepted and + pass through. + + :raises ValueError: With a human readable error message, + the attribute (of type `attrs.Attribute`), + the validator that failed to raise an exception, + the value it got, + and the expected exception types. + + .. versionadded:: 22.2.0 + """ + try: + exc_types = tuple(exc_types) + except TypeError: + exc_types = (exc_types,) + return _NotValidator(validator, msg, exc_types) diff --git a/uno/lib/python/poub/attr/validators.pyi b/uno/lib/python/poub/attr/validators.pyi new file mode 100644 index 00000000..d194a75a --- /dev/null +++ b/uno/lib/python/poub/attr/validators.pyi @@ -0,0 +1,88 @@ +from typing import ( + Any, + AnyStr, + Callable, + Container, + ContextManager, + Iterable, + List, + Mapping, + Match, + Optional, + Pattern, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +from . import _ValidatorType +from . import _ValidatorArgType + +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") +_I = TypeVar("_I", bound=Iterable) +_K = TypeVar("_K") +_V = TypeVar("_V") +_M = TypeVar("_M", bound=Mapping) + +def set_disabled(run: bool) -> None: ... +def get_disabled() -> bool: ... +def disabled() -> ContextManager[None]: ... + +# To be more precise on instance_of use some overloads. +# If there are more than 3 items in the tuple then we fall back to Any +@overload +def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ... +@overload +def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2]] +) -> _ValidatorType[Union[_T1, _T2]]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2], Type[_T3]] +) -> _ValidatorType[Union[_T1, _T2, _T3]]: ... +@overload +def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... +def provides(interface: Any) -> _ValidatorType[Any]: ... +def optional( + validator: Union[ + _ValidatorType[_T], List[_ValidatorType[_T]], Tuple[_ValidatorType[_T]] + ] +) -> _ValidatorType[Optional[_T]]: ... +def in_(options: Container[_T]) -> _ValidatorType[_T]: ... +def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... +def matches_re( + regex: Union[Pattern[AnyStr], AnyStr], + flags: int = ..., + func: Optional[ + Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] + ] = ..., +) -> _ValidatorType[AnyStr]: ... +def deep_iterable( + member_validator: _ValidatorArgType[_T], + iterable_validator: Optional[_ValidatorType[_I]] = ..., +) -> _ValidatorType[_I]: ... +def deep_mapping( + key_validator: _ValidatorType[_K], + value_validator: _ValidatorType[_V], + mapping_validator: Optional[_ValidatorType[_M]] = ..., +) -> _ValidatorType[_M]: ... +def is_callable() -> _ValidatorType[_T]: ... +def lt(val: _T) -> _ValidatorType[_T]: ... +def le(val: _T) -> _ValidatorType[_T]: ... +def ge(val: _T) -> _ValidatorType[_T]: ... +def gt(val: _T) -> _ValidatorType[_T]: ... +def max_len(length: int) -> _ValidatorType[_T]: ... +def min_len(length: int) -> _ValidatorType[_T]: ... +def not_( + validator: _ValidatorType[_T], + *, + msg: Optional[str] = None, + exc_types: Union[Type[Exception], Iterable[Type[Exception]]] = ..., +) -> _ValidatorType[_T]: ... diff --git a/uno/lib/python/poub/attrs/__init__.py b/uno/lib/python/poub/attrs/__init__.py new file mode 100644 index 00000000..0c248156 --- /dev/null +++ b/uno/lib/python/poub/attrs/__init__.py @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: MIT + +from attr import ( + NOTHING, + Attribute, + AttrsInstance, + Factory, + _make_getattr, + assoc, + cmp_using, + define, + evolve, + field, + fields, + fields_dict, + frozen, + has, + make_class, + mutable, + resolve_types, + validate, +) +from attr._next_gen import asdict, astuple + +from . import converters, exceptions, filters, setters, validators + + +__all__ = [ + "__author__", + "__copyright__", + "__description__", + "__doc__", + "__email__", + "__license__", + "__title__", + "__url__", + "__version__", + "__version_info__", + "asdict", + "assoc", + "astuple", + "Attribute", + "AttrsInstance", + "cmp_using", + "converters", + "define", + "evolve", + "exceptions", + "Factory", + "field", + "fields_dict", + "fields", + "filters", + "frozen", + "has", + "make_class", + "mutable", + "NOTHING", + "resolve_types", + "setters", + "validate", + "validators", +] + +__getattr__ = _make_getattr(__name__) diff --git a/uno/lib/python/poub/attrs/__init__.pyi b/uno/lib/python/poub/attrs/__init__.pyi new file mode 100644 index 00000000..9372cfea --- /dev/null +++ b/uno/lib/python/poub/attrs/__init__.pyi @@ -0,0 +1,67 @@ +from typing import ( + Any, + Callable, + Dict, + Mapping, + Optional, + Sequence, + Tuple, + Type, +) + +# Because we need to type our own stuff, we have to make everything from +# attr explicitly public too. +from attr import __author__ as __author__ +from attr import __copyright__ as __copyright__ +from attr import __description__ as __description__ +from attr import __email__ as __email__ +from attr import __license__ as __license__ +from attr import __title__ as __title__ +from attr import __url__ as __url__ +from attr import __version__ as __version__ +from attr import __version_info__ as __version_info__ +from attr import _FilterType +from attr import assoc as assoc +from attr import Attribute as Attribute +from attr import AttrsInstance as AttrsInstance +from attr import cmp_using as cmp_using +from attr import converters as converters +from attr import define as define +from attr import evolve as evolve +from attr import exceptions as exceptions +from attr import Factory as Factory +from attr import field as field +from attr import fields as fields +from attr import fields_dict as fields_dict +from attr import filters as filters +from attr import frozen as frozen +from attr import has as has +from attr import make_class as make_class +from attr import mutable as mutable +from attr import NOTHING as NOTHING +from attr import resolve_types as resolve_types +from attr import setters as setters +from attr import validate as validate +from attr import validators as validators + +# TODO: see definition of attr.asdict/astuple +def asdict( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[ + Callable[[type, Attribute[Any], Any], Any] + ] = ..., + tuple_keys: bool = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: AttrsInstance, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... diff --git a/uno/lib/python/poub/attrs/converters.py b/uno/lib/python/poub/attrs/converters.py new file mode 100644 index 00000000..edfa8d3c --- /dev/null +++ b/uno/lib/python/poub/attrs/converters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.converters import * # noqa diff --git a/uno/lib/python/poub/attrs/exceptions.py b/uno/lib/python/poub/attrs/exceptions.py new file mode 100644 index 00000000..bd9efed2 --- /dev/null +++ b/uno/lib/python/poub/attrs/exceptions.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.exceptions import * # noqa diff --git a/uno/lib/python/poub/attrs/filters.py b/uno/lib/python/poub/attrs/filters.py new file mode 100644 index 00000000..52959005 --- /dev/null +++ b/uno/lib/python/poub/attrs/filters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.filters import * # noqa diff --git a/uno/lib/python/poub/attrs/py.typed b/uno/lib/python/poub/attrs/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/poub/attrs/setters.py b/uno/lib/python/poub/attrs/setters.py new file mode 100644 index 00000000..9b507708 --- /dev/null +++ b/uno/lib/python/poub/attrs/setters.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.setters import * # noqa diff --git a/uno/lib/python/poub/attrs/validators.py b/uno/lib/python/poub/attrs/validators.py new file mode 100644 index 00000000..ab2c9b30 --- /dev/null +++ b/uno/lib/python/poub/attrs/validators.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT + +from attr.validators import * # noqa diff --git a/uno/lib/python/pycparser/__init__.py b/uno/lib/python/pycparser/__init__.py new file mode 100644 index 00000000..d82eb2d6 --- /dev/null +++ b/uno/lib/python/pycparser/__init__.py @@ -0,0 +1,90 @@ +#----------------------------------------------------------------- +# pycparser: __init__.py +# +# This package file exports some convenience functions for +# interacting with pycparser +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- +__all__ = ['c_lexer', 'c_parser', 'c_ast'] +__version__ = '2.21' + +import io +from subprocess import check_output +from .c_parser import CParser + + +def preprocess_file(filename, cpp_path='cpp', cpp_args=''): + """ Preprocess a file using cpp. + + filename: + Name of the file you want to preprocess. + + cpp_path: + cpp_args: + Refer to the documentation of parse_file for the meaning of these + arguments. + + When successful, returns the preprocessed file's contents. + Errors from cpp will be printed out. + """ + path_list = [cpp_path] + if isinstance(cpp_args, list): + path_list += cpp_args + elif cpp_args != '': + path_list += [cpp_args] + path_list += [filename] + + try: + # Note the use of universal_newlines to treat all newlines + # as \n for Python's purpose + text = check_output(path_list, universal_newlines=True) + except OSError as e: + raise RuntimeError("Unable to invoke 'cpp'. " + + 'Make sure its path was passed correctly\n' + + ('Original error: %s' % e)) + + return text + + +def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='', + parser=None): + """ Parse a C file using pycparser. + + filename: + Name of the file you want to parse. + + use_cpp: + Set to True if you want to execute the C pre-processor + on the file prior to parsing it. + + cpp_path: + If use_cpp is True, this is the path to 'cpp' on your + system. If no path is provided, it attempts to just + execute 'cpp', so it must be in your PATH. + + cpp_args: + If use_cpp is True, set this to the command line arguments strings + to cpp. Be careful with quotes - it's best to pass a raw string + (r'') here. For example: + r'-I../utils/fake_libc_include' + If several arguments are required, pass a list of strings. + + parser: + Optional parser object to be used instead of the default CParser + + When successful, an AST is returned. ParseError can be + thrown if the file doesn't parse successfully. + + Errors from cpp will be printed out. + """ + if use_cpp: + text = preprocess_file(filename, cpp_path, cpp_args) + else: + with io.open(filename) as f: + text = f.read() + + if parser is None: + parser = CParser() + return parser.parse(text, filename) diff --git a/uno/lib/python/pycparser/_ast_gen.py b/uno/lib/python/pycparser/_ast_gen.py new file mode 100644 index 00000000..0f7d330b --- /dev/null +++ b/uno/lib/python/pycparser/_ast_gen.py @@ -0,0 +1,336 @@ +#----------------------------------------------------------------- +# _ast_gen.py +# +# Generates the AST Node classes from a specification given in +# a configuration file +# +# The design of this module was inspired by astgen.py from the +# Python 2.5 code-base. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- +from string import Template + + +class ASTCodeGenerator(object): + def __init__(self, cfg_filename='_c_ast.cfg'): + """ Initialize the code generator from a configuration + file. + """ + self.cfg_filename = cfg_filename + self.node_cfg = [NodeCfg(name, contents) + for (name, contents) in self.parse_cfgfile(cfg_filename)] + + def generate(self, file=None): + """ Generates the code into file, an open file buffer. + """ + src = Template(_PROLOGUE_COMMENT).substitute( + cfg_filename=self.cfg_filename) + + src += _PROLOGUE_CODE + for node_cfg in self.node_cfg: + src += node_cfg.generate_source() + '\n\n' + + file.write(src) + + def parse_cfgfile(self, filename): + """ Parse the configuration file and yield pairs of + (name, contents) for each node. + """ + with open(filename, "r") as f: + for line in f: + line = line.strip() + if not line or line.startswith('#'): + continue + colon_i = line.find(':') + lbracket_i = line.find('[') + rbracket_i = line.find(']') + if colon_i < 1 or lbracket_i <= colon_i or rbracket_i <= lbracket_i: + raise RuntimeError("Invalid line in %s:\n%s\n" % (filename, line)) + + name = line[:colon_i] + val = line[lbracket_i + 1:rbracket_i] + vallist = [v.strip() for v in val.split(',')] if val else [] + yield name, vallist + + +class NodeCfg(object): + """ Node configuration. + + name: node name + contents: a list of contents - attributes and child nodes + See comment at the top of the configuration file for details. + """ + + def __init__(self, name, contents): + self.name = name + self.all_entries = [] + self.attr = [] + self.child = [] + self.seq_child = [] + + for entry in contents: + clean_entry = entry.rstrip('*') + self.all_entries.append(clean_entry) + + if entry.endswith('**'): + self.seq_child.append(clean_entry) + elif entry.endswith('*'): + self.child.append(clean_entry) + else: + self.attr.append(entry) + + def generate_source(self): + src = self._gen_init() + src += '\n' + self._gen_children() + src += '\n' + self._gen_iter() + src += '\n' + self._gen_attr_names() + return src + + def _gen_init(self): + src = "class %s(Node):\n" % self.name + + if self.all_entries: + args = ', '.join(self.all_entries) + slots = ', '.join("'{0}'".format(e) for e in self.all_entries) + slots += ", 'coord', '__weakref__'" + arglist = '(self, %s, coord=None)' % args + else: + slots = "'coord', '__weakref__'" + arglist = '(self, coord=None)' + + src += " __slots__ = (%s)\n" % slots + src += " def __init__%s:\n" % arglist + + for name in self.all_entries + ['coord']: + src += " self.%s = %s\n" % (name, name) + + return src + + def _gen_children(self): + src = ' def children(self):\n' + + if self.all_entries: + src += ' nodelist = []\n' + + for child in self.child: + src += ( + ' if self.%(child)s is not None:' + + ' nodelist.append(("%(child)s", self.%(child)s))\n') % ( + dict(child=child)) + + for seq_child in self.seq_child: + src += ( + ' for i, child in enumerate(self.%(child)s or []):\n' + ' nodelist.append(("%(child)s[%%d]" %% i, child))\n') % ( + dict(child=seq_child)) + + src += ' return tuple(nodelist)\n' + else: + src += ' return ()\n' + + return src + + def _gen_iter(self): + src = ' def __iter__(self):\n' + + if self.all_entries: + for child in self.child: + src += ( + ' if self.%(child)s is not None:\n' + + ' yield self.%(child)s\n') % (dict(child=child)) + + for seq_child in self.seq_child: + src += ( + ' for child in (self.%(child)s or []):\n' + ' yield child\n') % (dict(child=seq_child)) + + if not (self.child or self.seq_child): + # Empty generator + src += ( + ' return\n' + + ' yield\n') + else: + # Empty generator + src += ( + ' return\n' + + ' yield\n') + + return src + + def _gen_attr_names(self): + src = " attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')' + return src + + +_PROLOGUE_COMMENT = \ +r'''#----------------------------------------------------------------- +# ** ATTENTION ** +# This code was automatically generated from the file: +# $cfg_filename +# +# Do not modify it directly. Modify the configuration file and +# run the generator again. +# ** ** *** ** ** +# +# pycparser: c_ast.py +# +# AST Node classes. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- + +''' + +_PROLOGUE_CODE = r''' +import sys + +def _repr(obj): + """ + Get the representation of an object, with dedicated pprint-like format for lists. + """ + if isinstance(obj, list): + return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]' + else: + return repr(obj) + +class Node(object): + __slots__ = () + """ Abstract base class for AST nodes. + """ + def __repr__(self): + """ Generates a python representation of the current node + """ + result = self.__class__.__name__ + '(' + + indent = '' + separator = '' + for name in self.__slots__[:-2]: + result += separator + result += indent + result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__))))) + + separator = ',' + indent = '\n ' + (' ' * len(self.__class__.__name__)) + + result += indent + ')' + + return result + + def children(self): + """ A sequence of all children that are Nodes + """ + pass + + def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None): + """ Pretty print the Node and all its attributes and + children (recursively) to a buffer. + + buf: + Open IO buffer into which the Node is printed. + + offset: + Initial offset (amount of leading spaces) + + attrnames: + True if you want to see the attribute names in + name=value pairs. False to only see the values. + + nodenames: + True if you want to see the actual node names + within their parents. + + showcoord: + Do you want the coordinates of each Node to be + displayed. + """ + lead = ' ' * offset + if nodenames and _my_node_name is not None: + buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ') + else: + buf.write(lead + self.__class__.__name__+ ': ') + + if self.attr_names: + if attrnames: + nvlist = [(n, getattr(self,n)) for n in self.attr_names] + attrstr = ', '.join('%s=%s' % nv for nv in nvlist) + else: + vlist = [getattr(self, n) for n in self.attr_names] + attrstr = ', '.join('%s' % v for v in vlist) + buf.write(attrstr) + + if showcoord: + buf.write(' (at %s)' % self.coord) + buf.write('\n') + + for (child_name, child) in self.children(): + child.show( + buf, + offset=offset + 2, + attrnames=attrnames, + nodenames=nodenames, + showcoord=showcoord, + _my_node_name=child_name) + + +class NodeVisitor(object): + """ A base NodeVisitor class for visiting c_ast nodes. + Subclass it and define your own visit_XXX methods, where + XXX is the class name you want to visit with these + methods. + + For example: + + class ConstantVisitor(NodeVisitor): + def __init__(self): + self.values = [] + + def visit_Constant(self, node): + self.values.append(node.value) + + Creates a list of values of all the constant nodes + encountered below the given node. To use it: + + cv = ConstantVisitor() + cv.visit(node) + + Notes: + + * generic_visit() will be called for AST nodes for which + no visit_XXX method was defined. + * The children of nodes for which a visit_XXX was + defined will not be visited - if you need this, call + generic_visit() on the node. + You can use: + NodeVisitor.generic_visit(self, node) + * Modeled after Python's own AST visiting facilities + (the ast module of Python 3.0) + """ + + _method_cache = None + + def visit(self, node): + """ Visit a node. + """ + + if self._method_cache is None: + self._method_cache = {} + + visitor = self._method_cache.get(node.__class__.__name__, None) + if visitor is None: + method = 'visit_' + node.__class__.__name__ + visitor = getattr(self, method, self.generic_visit) + self._method_cache[node.__class__.__name__] = visitor + + return visitor(node) + + def generic_visit(self, node): + """ Called if no explicit visitor function exists for a + node. Implements preorder visiting of the node. + """ + for c in node: + self.visit(c) + +''' diff --git a/uno/lib/python/pycparser/_build_tables.py b/uno/lib/python/pycparser/_build_tables.py new file mode 100644 index 00000000..958381ad --- /dev/null +++ b/uno/lib/python/pycparser/_build_tables.py @@ -0,0 +1,37 @@ +#----------------------------------------------------------------- +# pycparser: _build_tables.py +# +# A dummy for generating the lexing/parsing tables and and +# compiling them into .pyc for faster execution in optimized mode. +# Also generates AST code from the configuration file. +# Should be called from the pycparser directory. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- + +# Insert '.' and '..' as first entries to the search path for modules. +# Restricted environments like embeddable python do not include the +# current working directory on startup. +import sys +sys.path[0:0] = ['.', '..'] + +# Generate c_ast.py +from _ast_gen import ASTCodeGenerator +ast_gen = ASTCodeGenerator('_c_ast.cfg') +ast_gen.generate(open('c_ast.py', 'w')) + +from pycparser import c_parser + +# Generates the tables +# +c_parser.CParser( + lex_optimize=True, + yacc_debug=False, + yacc_optimize=True) + +# Load to compile into .pyc +# +import lextab +import yacctab +import c_ast diff --git a/uno/lib/python/pycparser/_c_ast.cfg b/uno/lib/python/pycparser/_c_ast.cfg new file mode 100644 index 00000000..0626533e --- /dev/null +++ b/uno/lib/python/pycparser/_c_ast.cfg @@ -0,0 +1,195 @@ +#----------------------------------------------------------------- +# pycparser: _c_ast.cfg +# +# Defines the AST Node classes used in pycparser. +# +# Each entry is a Node sub-class name, listing the attributes +# and child nodes of the class: +# * - a child node +# ** - a sequence of child nodes +# - an attribute +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- + +# ArrayDecl is a nested declaration of an array with the given type. +# dim: the dimension (for example, constant 42) +# dim_quals: list of dimension qualifiers, to support C99's allowing 'const' +# and 'static' within the array dimension in function declarations. +ArrayDecl: [type*, dim*, dim_quals] + +ArrayRef: [name*, subscript*] + +# op: =, +=, /= etc. +# +Assignment: [op, lvalue*, rvalue*] + +Alignas: [alignment*] + +BinaryOp: [op, left*, right*] + +Break: [] + +Case: [expr*, stmts**] + +Cast: [to_type*, expr*] + +# Compound statement in C99 is a list of block items (declarations or +# statements). +# +Compound: [block_items**] + +# Compound literal (anonymous aggregate) for C99. +# (type-name) {initializer_list} +# type: the typename +# init: InitList for the initializer list +# +CompoundLiteral: [type*, init*] + +# type: int, char, float, string, etc. +# +Constant: [type, value] + +Continue: [] + +# name: the variable being declared +# quals: list of qualifiers (const, volatile) +# funcspec: list function specifiers (i.e. inline in C99) +# storage: list of storage specifiers (extern, register, etc.) +# type: declaration type (probably nested with all the modifiers) +# init: initialization value, or None +# bitsize: bit field size, or None +# +Decl: [name, quals, align, storage, funcspec, type*, init*, bitsize*] + +DeclList: [decls**] + +Default: [stmts**] + +DoWhile: [cond*, stmt*] + +# Represents the ellipsis (...) parameter in a function +# declaration +# +EllipsisParam: [] + +# An empty statement (a semicolon ';' on its own) +# +EmptyStatement: [] + +# Enumeration type specifier +# name: an optional ID +# values: an EnumeratorList +# +Enum: [name, values*] + +# A name/value pair for enumeration values +# +Enumerator: [name, value*] + +# A list of enumerators +# +EnumeratorList: [enumerators**] + +# A list of expressions separated by the comma operator. +# +ExprList: [exprs**] + +# This is the top of the AST, representing a single C file (a +# translation unit in K&R jargon). It contains a list of +# "external-declaration"s, which is either declarations (Decl), +# Typedef or function definitions (FuncDef). +# +FileAST: [ext**] + +# for (init; cond; next) stmt +# +For: [init*, cond*, next*, stmt*] + +# name: Id +# args: ExprList +# +FuncCall: [name*, args*] + +# type (args) +# +FuncDecl: [args*, type*] + +# Function definition: a declarator for the function name and +# a body, which is a compound statement. +# There's an optional list of parameter declarations for old +# K&R-style definitions +# +FuncDef: [decl*, param_decls**, body*] + +Goto: [name] + +ID: [name] + +# Holder for types that are a simple identifier (e.g. the built +# ins void, char etc. and typedef-defined types) +# +IdentifierType: [names] + +If: [cond*, iftrue*, iffalse*] + +# An initialization list used for compound literals. +# +InitList: [exprs**] + +Label: [name, stmt*] + +# A named initializer for C99. +# The name of a NamedInitializer is a sequence of Nodes, because +# names can be hierarchical and contain constant expressions. +# +NamedInitializer: [name**, expr*] + +# a list of comma separated function parameter declarations +# +ParamList: [params**] + +PtrDecl: [quals, type*] + +Return: [expr*] + +StaticAssert: [cond*, message*] + +# name: struct tag name +# decls: declaration of members +# +Struct: [name, decls**] + +# type: . or -> +# name.field or name->field +# +StructRef: [name*, type, field*] + +Switch: [cond*, stmt*] + +# cond ? iftrue : iffalse +# +TernaryOp: [cond*, iftrue*, iffalse*] + +# A base type declaration +# +TypeDecl: [declname, quals, align, type*] + +# A typedef declaration. +# Very similar to Decl, but without some attributes +# +Typedef: [name, quals, storage, type*] + +Typename: [name, quals, align, type*] + +UnaryOp: [op, expr*] + +# name: union tag name +# decls: declaration of members +# +Union: [name, decls**] + +While: [cond*, stmt*] + +Pragma: [string] diff --git a/uno/lib/python/pycparser/ast_transforms.py b/uno/lib/python/pycparser/ast_transforms.py new file mode 100644 index 00000000..367dcf54 --- /dev/null +++ b/uno/lib/python/pycparser/ast_transforms.py @@ -0,0 +1,164 @@ +#------------------------------------------------------------------------------ +# pycparser: ast_transforms.py +# +# Some utilities used by the parser to create a friendlier AST. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#------------------------------------------------------------------------------ + +from . import c_ast + + +def fix_switch_cases(switch_node): + """ The 'case' statements in a 'switch' come out of parsing with one + child node, so subsequent statements are just tucked to the parent + Compound. Additionally, consecutive (fall-through) case statements + come out messy. This is a peculiarity of the C grammar. The following: + + switch (myvar) { + case 10: + k = 10; + p = k + 1; + return 10; + case 20: + case 30: + return 20; + default: + break; + } + + Creates this tree (pseudo-dump): + + Switch + ID: myvar + Compound: + Case 10: + k = 10 + p = k + 1 + return 10 + Case 20: + Case 30: + return 20 + Default: + break + + The goal of this transform is to fix this mess, turning it into the + following: + + Switch + ID: myvar + Compound: + Case 10: + k = 10 + p = k + 1 + return 10 + Case 20: + Case 30: + return 20 + Default: + break + + A fixed AST node is returned. The argument may be modified. + """ + assert isinstance(switch_node, c_ast.Switch) + if not isinstance(switch_node.stmt, c_ast.Compound): + return switch_node + + # The new Compound child for the Switch, which will collect children in the + # correct order + new_compound = c_ast.Compound([], switch_node.stmt.coord) + + # The last Case/Default node + last_case = None + + # Goes over the children of the Compound below the Switch, adding them + # either directly below new_compound or below the last Case as appropriate + # (for `switch(cond) {}`, block_items would have been None) + for child in (switch_node.stmt.block_items or []): + if isinstance(child, (c_ast.Case, c_ast.Default)): + # If it's a Case/Default: + # 1. Add it to the Compound and mark as "last case" + # 2. If its immediate child is also a Case or Default, promote it + # to a sibling. + new_compound.block_items.append(child) + _extract_nested_case(child, new_compound.block_items) + last_case = new_compound.block_items[-1] + else: + # Other statements are added as children to the last case, if it + # exists. + if last_case is None: + new_compound.block_items.append(child) + else: + last_case.stmts.append(child) + + switch_node.stmt = new_compound + return switch_node + + +def _extract_nested_case(case_node, stmts_list): + """ Recursively extract consecutive Case statements that are made nested + by the parser and add them to the stmts_list. + """ + if isinstance(case_node.stmts[0], (c_ast.Case, c_ast.Default)): + stmts_list.append(case_node.stmts.pop()) + _extract_nested_case(stmts_list[-1], stmts_list) + + +def fix_atomic_specifiers(decl): + """ Atomic specifiers like _Atomic(type) are unusually structured, + conferring a qualifier upon the contained type. + + This function fixes a decl with atomic specifiers to have a sane AST + structure, by removing spurious Typename->TypeDecl pairs and attaching + the _Atomic qualifier in the right place. + """ + # There can be multiple levels of _Atomic in a decl; fix them until a + # fixed point is reached. + while True: + decl, found = _fix_atomic_specifiers_once(decl) + if not found: + break + + # Make sure to add an _Atomic qual on the topmost decl if needed. Also + # restore the declname on the innermost TypeDecl (it gets placed in the + # wrong place during construction). + typ = decl + while not isinstance(typ, c_ast.TypeDecl): + try: + typ = typ.type + except AttributeError: + return decl + if '_Atomic' in typ.quals and '_Atomic' not in decl.quals: + decl.quals.append('_Atomic') + if typ.declname is None: + typ.declname = decl.name + + return decl + + +def _fix_atomic_specifiers_once(decl): + """ Performs one 'fix' round of atomic specifiers. + Returns (modified_decl, found) where found is True iff a fix was made. + """ + parent = decl + grandparent = None + node = decl.type + while node is not None: + if isinstance(node, c_ast.Typename) and '_Atomic' in node.quals: + break + try: + grandparent = parent + parent = node + node = node.type + except AttributeError: + # If we've reached a node without a `type` field, it means we won't + # find what we're looking for at this point; give up the search + # and return the original decl unmodified. + return decl, False + + assert isinstance(parent, c_ast.TypeDecl) + grandparent.type = node.type + if '_Atomic' not in node.type.quals: + node.type.quals.append('_Atomic') + return decl, True diff --git a/uno/lib/python/pycparser/c_ast.py b/uno/lib/python/pycparser/c_ast.py new file mode 100644 index 00000000..6575a2ad --- /dev/null +++ b/uno/lib/python/pycparser/c_ast.py @@ -0,0 +1,1125 @@ +#----------------------------------------------------------------- +# ** ATTENTION ** +# This code was automatically generated from the file: +# _c_ast.cfg +# +# Do not modify it directly. Modify the configuration file and +# run the generator again. +# ** ** *** ** ** +# +# pycparser: c_ast.py +# +# AST Node classes. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- + + +import sys + +def _repr(obj): + """ + Get the representation of an object, with dedicated pprint-like format for lists. + """ + if isinstance(obj, list): + return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]' + else: + return repr(obj) + +class Node(object): + __slots__ = () + """ Abstract base class for AST nodes. + """ + def __repr__(self): + """ Generates a python representation of the current node + """ + result = self.__class__.__name__ + '(' + + indent = '' + separator = '' + for name in self.__slots__[:-2]: + result += separator + result += indent + result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__))))) + + separator = ',' + indent = '\n ' + (' ' * len(self.__class__.__name__)) + + result += indent + ')' + + return result + + def children(self): + """ A sequence of all children that are Nodes + """ + pass + + def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None): + """ Pretty print the Node and all its attributes and + children (recursively) to a buffer. + + buf: + Open IO buffer into which the Node is printed. + + offset: + Initial offset (amount of leading spaces) + + attrnames: + True if you want to see the attribute names in + name=value pairs. False to only see the values. + + nodenames: + True if you want to see the actual node names + within their parents. + + showcoord: + Do you want the coordinates of each Node to be + displayed. + """ + lead = ' ' * offset + if nodenames and _my_node_name is not None: + buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ') + else: + buf.write(lead + self.__class__.__name__+ ': ') + + if self.attr_names: + if attrnames: + nvlist = [(n, getattr(self,n)) for n in self.attr_names] + attrstr = ', '.join('%s=%s' % nv for nv in nvlist) + else: + vlist = [getattr(self, n) for n in self.attr_names] + attrstr = ', '.join('%s' % v for v in vlist) + buf.write(attrstr) + + if showcoord: + buf.write(' (at %s)' % self.coord) + buf.write('\n') + + for (child_name, child) in self.children(): + child.show( + buf, + offset=offset + 2, + attrnames=attrnames, + nodenames=nodenames, + showcoord=showcoord, + _my_node_name=child_name) + + +class NodeVisitor(object): + """ A base NodeVisitor class for visiting c_ast nodes. + Subclass it and define your own visit_XXX methods, where + XXX is the class name you want to visit with these + methods. + + For example: + + class ConstantVisitor(NodeVisitor): + def __init__(self): + self.values = [] + + def visit_Constant(self, node): + self.values.append(node.value) + + Creates a list of values of all the constant nodes + encountered below the given node. To use it: + + cv = ConstantVisitor() + cv.visit(node) + + Notes: + + * generic_visit() will be called for AST nodes for which + no visit_XXX method was defined. + * The children of nodes for which a visit_XXX was + defined will not be visited - if you need this, call + generic_visit() on the node. + You can use: + NodeVisitor.generic_visit(self, node) + * Modeled after Python's own AST visiting facilities + (the ast module of Python 3.0) + """ + + _method_cache = None + + def visit(self, node): + """ Visit a node. + """ + + if self._method_cache is None: + self._method_cache = {} + + visitor = self._method_cache.get(node.__class__.__name__, None) + if visitor is None: + method = 'visit_' + node.__class__.__name__ + visitor = getattr(self, method, self.generic_visit) + self._method_cache[node.__class__.__name__] = visitor + + return visitor(node) + + def generic_visit(self, node): + """ Called if no explicit visitor function exists for a + node. Implements preorder visiting of the node. + """ + for c in node: + self.visit(c) + +class ArrayDecl(Node): + __slots__ = ('type', 'dim', 'dim_quals', 'coord', '__weakref__') + def __init__(self, type, dim, dim_quals, coord=None): + self.type = type + self.dim = dim + self.dim_quals = dim_quals + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + if self.dim is not None: nodelist.append(("dim", self.dim)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + if self.dim is not None: + yield self.dim + + attr_names = ('dim_quals', ) + +class ArrayRef(Node): + __slots__ = ('name', 'subscript', 'coord', '__weakref__') + def __init__(self, name, subscript, coord=None): + self.name = name + self.subscript = subscript + self.coord = coord + + def children(self): + nodelist = [] + if self.name is not None: nodelist.append(("name", self.name)) + if self.subscript is not None: nodelist.append(("subscript", self.subscript)) + return tuple(nodelist) + + def __iter__(self): + if self.name is not None: + yield self.name + if self.subscript is not None: + yield self.subscript + + attr_names = () + +class Assignment(Node): + __slots__ = ('op', 'lvalue', 'rvalue', 'coord', '__weakref__') + def __init__(self, op, lvalue, rvalue, coord=None): + self.op = op + self.lvalue = lvalue + self.rvalue = rvalue + self.coord = coord + + def children(self): + nodelist = [] + if self.lvalue is not None: nodelist.append(("lvalue", self.lvalue)) + if self.rvalue is not None: nodelist.append(("rvalue", self.rvalue)) + return tuple(nodelist) + + def __iter__(self): + if self.lvalue is not None: + yield self.lvalue + if self.rvalue is not None: + yield self.rvalue + + attr_names = ('op', ) + +class Alignas(Node): + __slots__ = ('alignment', 'coord', '__weakref__') + def __init__(self, alignment, coord=None): + self.alignment = alignment + self.coord = coord + + def children(self): + nodelist = [] + if self.alignment is not None: nodelist.append(("alignment", self.alignment)) + return tuple(nodelist) + + def __iter__(self): + if self.alignment is not None: + yield self.alignment + + attr_names = () + +class BinaryOp(Node): + __slots__ = ('op', 'left', 'right', 'coord', '__weakref__') + def __init__(self, op, left, right, coord=None): + self.op = op + self.left = left + self.right = right + self.coord = coord + + def children(self): + nodelist = [] + if self.left is not None: nodelist.append(("left", self.left)) + if self.right is not None: nodelist.append(("right", self.right)) + return tuple(nodelist) + + def __iter__(self): + if self.left is not None: + yield self.left + if self.right is not None: + yield self.right + + attr_names = ('op', ) + +class Break(Node): + __slots__ = ('coord', '__weakref__') + def __init__(self, coord=None): + self.coord = coord + + def children(self): + return () + + def __iter__(self): + return + yield + + attr_names = () + +class Case(Node): + __slots__ = ('expr', 'stmts', 'coord', '__weakref__') + def __init__(self, expr, stmts, coord=None): + self.expr = expr + self.stmts = stmts + self.coord = coord + + def children(self): + nodelist = [] + if self.expr is not None: nodelist.append(("expr", self.expr)) + for i, child in enumerate(self.stmts or []): + nodelist.append(("stmts[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + if self.expr is not None: + yield self.expr + for child in (self.stmts or []): + yield child + + attr_names = () + +class Cast(Node): + __slots__ = ('to_type', 'expr', 'coord', '__weakref__') + def __init__(self, to_type, expr, coord=None): + self.to_type = to_type + self.expr = expr + self.coord = coord + + def children(self): + nodelist = [] + if self.to_type is not None: nodelist.append(("to_type", self.to_type)) + if self.expr is not None: nodelist.append(("expr", self.expr)) + return tuple(nodelist) + + def __iter__(self): + if self.to_type is not None: + yield self.to_type + if self.expr is not None: + yield self.expr + + attr_names = () + +class Compound(Node): + __slots__ = ('block_items', 'coord', '__weakref__') + def __init__(self, block_items, coord=None): + self.block_items = block_items + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.block_items or []): + nodelist.append(("block_items[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.block_items or []): + yield child + + attr_names = () + +class CompoundLiteral(Node): + __slots__ = ('type', 'init', 'coord', '__weakref__') + def __init__(self, type, init, coord=None): + self.type = type + self.init = init + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + if self.init is not None: nodelist.append(("init", self.init)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + if self.init is not None: + yield self.init + + attr_names = () + +class Constant(Node): + __slots__ = ('type', 'value', 'coord', '__weakref__') + def __init__(self, type, value, coord=None): + self.type = type + self.value = value + self.coord = coord + + def children(self): + nodelist = [] + return tuple(nodelist) + + def __iter__(self): + return + yield + + attr_names = ('type', 'value', ) + +class Continue(Node): + __slots__ = ('coord', '__weakref__') + def __init__(self, coord=None): + self.coord = coord + + def children(self): + return () + + def __iter__(self): + return + yield + + attr_names = () + +class Decl(Node): + __slots__ = ('name', 'quals', 'align', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord', '__weakref__') + def __init__(self, name, quals, align, storage, funcspec, type, init, bitsize, coord=None): + self.name = name + self.quals = quals + self.align = align + self.storage = storage + self.funcspec = funcspec + self.type = type + self.init = init + self.bitsize = bitsize + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + if self.init is not None: nodelist.append(("init", self.init)) + if self.bitsize is not None: nodelist.append(("bitsize", self.bitsize)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + if self.init is not None: + yield self.init + if self.bitsize is not None: + yield self.bitsize + + attr_names = ('name', 'quals', 'align', 'storage', 'funcspec', ) + +class DeclList(Node): + __slots__ = ('decls', 'coord', '__weakref__') + def __init__(self, decls, coord=None): + self.decls = decls + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.decls or []): + nodelist.append(("decls[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.decls or []): + yield child + + attr_names = () + +class Default(Node): + __slots__ = ('stmts', 'coord', '__weakref__') + def __init__(self, stmts, coord=None): + self.stmts = stmts + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.stmts or []): + nodelist.append(("stmts[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.stmts or []): + yield child + + attr_names = () + +class DoWhile(Node): + __slots__ = ('cond', 'stmt', 'coord', '__weakref__') + def __init__(self, cond, stmt, coord=None): + self.cond = cond + self.stmt = stmt + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.stmt is not None: nodelist.append(("stmt", self.stmt)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.stmt is not None: + yield self.stmt + + attr_names = () + +class EllipsisParam(Node): + __slots__ = ('coord', '__weakref__') + def __init__(self, coord=None): + self.coord = coord + + def children(self): + return () + + def __iter__(self): + return + yield + + attr_names = () + +class EmptyStatement(Node): + __slots__ = ('coord', '__weakref__') + def __init__(self, coord=None): + self.coord = coord + + def children(self): + return () + + def __iter__(self): + return + yield + + attr_names = () + +class Enum(Node): + __slots__ = ('name', 'values', 'coord', '__weakref__') + def __init__(self, name, values, coord=None): + self.name = name + self.values = values + self.coord = coord + + def children(self): + nodelist = [] + if self.values is not None: nodelist.append(("values", self.values)) + return tuple(nodelist) + + def __iter__(self): + if self.values is not None: + yield self.values + + attr_names = ('name', ) + +class Enumerator(Node): + __slots__ = ('name', 'value', 'coord', '__weakref__') + def __init__(self, name, value, coord=None): + self.name = name + self.value = value + self.coord = coord + + def children(self): + nodelist = [] + if self.value is not None: nodelist.append(("value", self.value)) + return tuple(nodelist) + + def __iter__(self): + if self.value is not None: + yield self.value + + attr_names = ('name', ) + +class EnumeratorList(Node): + __slots__ = ('enumerators', 'coord', '__weakref__') + def __init__(self, enumerators, coord=None): + self.enumerators = enumerators + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.enumerators or []): + nodelist.append(("enumerators[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.enumerators or []): + yield child + + attr_names = () + +class ExprList(Node): + __slots__ = ('exprs', 'coord', '__weakref__') + def __init__(self, exprs, coord=None): + self.exprs = exprs + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.exprs or []): + nodelist.append(("exprs[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.exprs or []): + yield child + + attr_names = () + +class FileAST(Node): + __slots__ = ('ext', 'coord', '__weakref__') + def __init__(self, ext, coord=None): + self.ext = ext + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.ext or []): + nodelist.append(("ext[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.ext or []): + yield child + + attr_names = () + +class For(Node): + __slots__ = ('init', 'cond', 'next', 'stmt', 'coord', '__weakref__') + def __init__(self, init, cond, next, stmt, coord=None): + self.init = init + self.cond = cond + self.next = next + self.stmt = stmt + self.coord = coord + + def children(self): + nodelist = [] + if self.init is not None: nodelist.append(("init", self.init)) + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.next is not None: nodelist.append(("next", self.next)) + if self.stmt is not None: nodelist.append(("stmt", self.stmt)) + return tuple(nodelist) + + def __iter__(self): + if self.init is not None: + yield self.init + if self.cond is not None: + yield self.cond + if self.next is not None: + yield self.next + if self.stmt is not None: + yield self.stmt + + attr_names = () + +class FuncCall(Node): + __slots__ = ('name', 'args', 'coord', '__weakref__') + def __init__(self, name, args, coord=None): + self.name = name + self.args = args + self.coord = coord + + def children(self): + nodelist = [] + if self.name is not None: nodelist.append(("name", self.name)) + if self.args is not None: nodelist.append(("args", self.args)) + return tuple(nodelist) + + def __iter__(self): + if self.name is not None: + yield self.name + if self.args is not None: + yield self.args + + attr_names = () + +class FuncDecl(Node): + __slots__ = ('args', 'type', 'coord', '__weakref__') + def __init__(self, args, type, coord=None): + self.args = args + self.type = type + self.coord = coord + + def children(self): + nodelist = [] + if self.args is not None: nodelist.append(("args", self.args)) + if self.type is not None: nodelist.append(("type", self.type)) + return tuple(nodelist) + + def __iter__(self): + if self.args is not None: + yield self.args + if self.type is not None: + yield self.type + + attr_names = () + +class FuncDef(Node): + __slots__ = ('decl', 'param_decls', 'body', 'coord', '__weakref__') + def __init__(self, decl, param_decls, body, coord=None): + self.decl = decl + self.param_decls = param_decls + self.body = body + self.coord = coord + + def children(self): + nodelist = [] + if self.decl is not None: nodelist.append(("decl", self.decl)) + if self.body is not None: nodelist.append(("body", self.body)) + for i, child in enumerate(self.param_decls or []): + nodelist.append(("param_decls[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + if self.decl is not None: + yield self.decl + if self.body is not None: + yield self.body + for child in (self.param_decls or []): + yield child + + attr_names = () + +class Goto(Node): + __slots__ = ('name', 'coord', '__weakref__') + def __init__(self, name, coord=None): + self.name = name + self.coord = coord + + def children(self): + nodelist = [] + return tuple(nodelist) + + def __iter__(self): + return + yield + + attr_names = ('name', ) + +class ID(Node): + __slots__ = ('name', 'coord', '__weakref__') + def __init__(self, name, coord=None): + self.name = name + self.coord = coord + + def children(self): + nodelist = [] + return tuple(nodelist) + + def __iter__(self): + return + yield + + attr_names = ('name', ) + +class IdentifierType(Node): + __slots__ = ('names', 'coord', '__weakref__') + def __init__(self, names, coord=None): + self.names = names + self.coord = coord + + def children(self): + nodelist = [] + return tuple(nodelist) + + def __iter__(self): + return + yield + + attr_names = ('names', ) + +class If(Node): + __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__') + def __init__(self, cond, iftrue, iffalse, coord=None): + self.cond = cond + self.iftrue = iftrue + self.iffalse = iffalse + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue)) + if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.iftrue is not None: + yield self.iftrue + if self.iffalse is not None: + yield self.iffalse + + attr_names = () + +class InitList(Node): + __slots__ = ('exprs', 'coord', '__weakref__') + def __init__(self, exprs, coord=None): + self.exprs = exprs + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.exprs or []): + nodelist.append(("exprs[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.exprs or []): + yield child + + attr_names = () + +class Label(Node): + __slots__ = ('name', 'stmt', 'coord', '__weakref__') + def __init__(self, name, stmt, coord=None): + self.name = name + self.stmt = stmt + self.coord = coord + + def children(self): + nodelist = [] + if self.stmt is not None: nodelist.append(("stmt", self.stmt)) + return tuple(nodelist) + + def __iter__(self): + if self.stmt is not None: + yield self.stmt + + attr_names = ('name', ) + +class NamedInitializer(Node): + __slots__ = ('name', 'expr', 'coord', '__weakref__') + def __init__(self, name, expr, coord=None): + self.name = name + self.expr = expr + self.coord = coord + + def children(self): + nodelist = [] + if self.expr is not None: nodelist.append(("expr", self.expr)) + for i, child in enumerate(self.name or []): + nodelist.append(("name[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + if self.expr is not None: + yield self.expr + for child in (self.name or []): + yield child + + attr_names = () + +class ParamList(Node): + __slots__ = ('params', 'coord', '__weakref__') + def __init__(self, params, coord=None): + self.params = params + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.params or []): + nodelist.append(("params[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.params or []): + yield child + + attr_names = () + +class PtrDecl(Node): + __slots__ = ('quals', 'type', 'coord', '__weakref__') + def __init__(self, quals, type, coord=None): + self.quals = quals + self.type = type + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + + attr_names = ('quals', ) + +class Return(Node): + __slots__ = ('expr', 'coord', '__weakref__') + def __init__(self, expr, coord=None): + self.expr = expr + self.coord = coord + + def children(self): + nodelist = [] + if self.expr is not None: nodelist.append(("expr", self.expr)) + return tuple(nodelist) + + def __iter__(self): + if self.expr is not None: + yield self.expr + + attr_names = () + +class StaticAssert(Node): + __slots__ = ('cond', 'message', 'coord', '__weakref__') + def __init__(self, cond, message, coord=None): + self.cond = cond + self.message = message + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.message is not None: nodelist.append(("message", self.message)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.message is not None: + yield self.message + + attr_names = () + +class Struct(Node): + __slots__ = ('name', 'decls', 'coord', '__weakref__') + def __init__(self, name, decls, coord=None): + self.name = name + self.decls = decls + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.decls or []): + nodelist.append(("decls[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.decls or []): + yield child + + attr_names = ('name', ) + +class StructRef(Node): + __slots__ = ('name', 'type', 'field', 'coord', '__weakref__') + def __init__(self, name, type, field, coord=None): + self.name = name + self.type = type + self.field = field + self.coord = coord + + def children(self): + nodelist = [] + if self.name is not None: nodelist.append(("name", self.name)) + if self.field is not None: nodelist.append(("field", self.field)) + return tuple(nodelist) + + def __iter__(self): + if self.name is not None: + yield self.name + if self.field is not None: + yield self.field + + attr_names = ('type', ) + +class Switch(Node): + __slots__ = ('cond', 'stmt', 'coord', '__weakref__') + def __init__(self, cond, stmt, coord=None): + self.cond = cond + self.stmt = stmt + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.stmt is not None: nodelist.append(("stmt", self.stmt)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.stmt is not None: + yield self.stmt + + attr_names = () + +class TernaryOp(Node): + __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__') + def __init__(self, cond, iftrue, iffalse, coord=None): + self.cond = cond + self.iftrue = iftrue + self.iffalse = iffalse + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue)) + if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.iftrue is not None: + yield self.iftrue + if self.iffalse is not None: + yield self.iffalse + + attr_names = () + +class TypeDecl(Node): + __slots__ = ('declname', 'quals', 'align', 'type', 'coord', '__weakref__') + def __init__(self, declname, quals, align, type, coord=None): + self.declname = declname + self.quals = quals + self.align = align + self.type = type + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + + attr_names = ('declname', 'quals', 'align', ) + +class Typedef(Node): + __slots__ = ('name', 'quals', 'storage', 'type', 'coord', '__weakref__') + def __init__(self, name, quals, storage, type, coord=None): + self.name = name + self.quals = quals + self.storage = storage + self.type = type + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + + attr_names = ('name', 'quals', 'storage', ) + +class Typename(Node): + __slots__ = ('name', 'quals', 'align', 'type', 'coord', '__weakref__') + def __init__(self, name, quals, align, type, coord=None): + self.name = name + self.quals = quals + self.align = align + self.type = type + self.coord = coord + + def children(self): + nodelist = [] + if self.type is not None: nodelist.append(("type", self.type)) + return tuple(nodelist) + + def __iter__(self): + if self.type is not None: + yield self.type + + attr_names = ('name', 'quals', 'align', ) + +class UnaryOp(Node): + __slots__ = ('op', 'expr', 'coord', '__weakref__') + def __init__(self, op, expr, coord=None): + self.op = op + self.expr = expr + self.coord = coord + + def children(self): + nodelist = [] + if self.expr is not None: nodelist.append(("expr", self.expr)) + return tuple(nodelist) + + def __iter__(self): + if self.expr is not None: + yield self.expr + + attr_names = ('op', ) + +class Union(Node): + __slots__ = ('name', 'decls', 'coord', '__weakref__') + def __init__(self, name, decls, coord=None): + self.name = name + self.decls = decls + self.coord = coord + + def children(self): + nodelist = [] + for i, child in enumerate(self.decls or []): + nodelist.append(("decls[%d]" % i, child)) + return tuple(nodelist) + + def __iter__(self): + for child in (self.decls or []): + yield child + + attr_names = ('name', ) + +class While(Node): + __slots__ = ('cond', 'stmt', 'coord', '__weakref__') + def __init__(self, cond, stmt, coord=None): + self.cond = cond + self.stmt = stmt + self.coord = coord + + def children(self): + nodelist = [] + if self.cond is not None: nodelist.append(("cond", self.cond)) + if self.stmt is not None: nodelist.append(("stmt", self.stmt)) + return tuple(nodelist) + + def __iter__(self): + if self.cond is not None: + yield self.cond + if self.stmt is not None: + yield self.stmt + + attr_names = () + +class Pragma(Node): + __slots__ = ('string', 'coord', '__weakref__') + def __init__(self, string, coord=None): + self.string = string + self.coord = coord + + def children(self): + nodelist = [] + return tuple(nodelist) + + def __iter__(self): + return + yield + + attr_names = ('string', ) + diff --git a/uno/lib/python/pycparser/c_generator.py b/uno/lib/python/pycparser/c_generator.py new file mode 100644 index 00000000..1057b2c6 --- /dev/null +++ b/uno/lib/python/pycparser/c_generator.py @@ -0,0 +1,502 @@ +#------------------------------------------------------------------------------ +# pycparser: c_generator.py +# +# C code generator from pycparser AST nodes. +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#------------------------------------------------------------------------------ +from . import c_ast + + +class CGenerator(object): + """ Uses the same visitor pattern as c_ast.NodeVisitor, but modified to + return a value from each visit method, using string accumulation in + generic_visit. + """ + def __init__(self, reduce_parentheses=False): + """ Constructs C-code generator + + reduce_parentheses: + if True, eliminates needless parentheses on binary operators + """ + # Statements start with indentation of self.indent_level spaces, using + # the _make_indent method. + self.indent_level = 0 + self.reduce_parentheses = reduce_parentheses + + def _make_indent(self): + return ' ' * self.indent_level + + def visit(self, node): + method = 'visit_' + node.__class__.__name__ + return getattr(self, method, self.generic_visit)(node) + + def generic_visit(self, node): + if node is None: + return '' + else: + return ''.join(self.visit(c) for c_name, c in node.children()) + + def visit_Constant(self, n): + return n.value + + def visit_ID(self, n): + return n.name + + def visit_Pragma(self, n): + ret = '#pragma' + if n.string: + ret += ' ' + n.string + return ret + + def visit_ArrayRef(self, n): + arrref = self._parenthesize_unless_simple(n.name) + return arrref + '[' + self.visit(n.subscript) + ']' + + def visit_StructRef(self, n): + sref = self._parenthesize_unless_simple(n.name) + return sref + n.type + self.visit(n.field) + + def visit_FuncCall(self, n): + fref = self._parenthesize_unless_simple(n.name) + return fref + '(' + self.visit(n.args) + ')' + + def visit_UnaryOp(self, n): + if n.op == 'sizeof': + # Always parenthesize the argument of sizeof since it can be + # a name. + return 'sizeof(%s)' % self.visit(n.expr) + else: + operand = self._parenthesize_unless_simple(n.expr) + if n.op == 'p++': + return '%s++' % operand + elif n.op == 'p--': + return '%s--' % operand + else: + return '%s%s' % (n.op, operand) + + # Precedence map of binary operators: + precedence_map = { + # Should be in sync with c_parser.CParser.precedence + # Higher numbers are stronger binding + '||': 0, # weakest binding + '&&': 1, + '|': 2, + '^': 3, + '&': 4, + '==': 5, '!=': 5, + '>': 6, '>=': 6, '<': 6, '<=': 6, + '>>': 7, '<<': 7, + '+': 8, '-': 8, + '*': 9, '/': 9, '%': 9 # strongest binding + } + + def visit_BinaryOp(self, n): + # Note: all binary operators are left-to-right associative + # + # If `n.left.op` has a stronger or equally binding precedence in + # comparison to `n.op`, no parenthesis are needed for the left: + # e.g., `(a*b) + c` is equivalent to `a*b + c`, as well as + # `(a+b) - c` is equivalent to `a+b - c` (same precedence). + # If the left operator is weaker binding than the current, then + # parentheses are necessary: + # e.g., `(a+b) * c` is NOT equivalent to `a+b * c`. + lval_str = self._parenthesize_if( + n.left, + lambda d: not (self._is_simple_node(d) or + self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and + self.precedence_map[d.op] >= self.precedence_map[n.op])) + # If `n.right.op` has a stronger -but not equal- binding precedence, + # parenthesis can be omitted on the right: + # e.g., `a + (b*c)` is equivalent to `a + b*c`. + # If the right operator is weaker or equally binding, then parentheses + # are necessary: + # e.g., `a * (b+c)` is NOT equivalent to `a * b+c` and + # `a - (b+c)` is NOT equivalent to `a - b+c` (same precedence). + rval_str = self._parenthesize_if( + n.right, + lambda d: not (self._is_simple_node(d) or + self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and + self.precedence_map[d.op] > self.precedence_map[n.op])) + return '%s %s %s' % (lval_str, n.op, rval_str) + + def visit_Assignment(self, n): + rval_str = self._parenthesize_if( + n.rvalue, + lambda n: isinstance(n, c_ast.Assignment)) + return '%s %s %s' % (self.visit(n.lvalue), n.op, rval_str) + + def visit_IdentifierType(self, n): + return ' '.join(n.names) + + def _visit_expr(self, n): + if isinstance(n, c_ast.InitList): + return '{' + self.visit(n) + '}' + elif isinstance(n, c_ast.ExprList): + return '(' + self.visit(n) + ')' + else: + return self.visit(n) + + def visit_Decl(self, n, no_type=False): + # no_type is used when a Decl is part of a DeclList, where the type is + # explicitly only for the first declaration in a list. + # + s = n.name if no_type else self._generate_decl(n) + if n.bitsize: s += ' : ' + self.visit(n.bitsize) + if n.init: + s += ' = ' + self._visit_expr(n.init) + return s + + def visit_DeclList(self, n): + s = self.visit(n.decls[0]) + if len(n.decls) > 1: + s += ', ' + ', '.join(self.visit_Decl(decl, no_type=True) + for decl in n.decls[1:]) + return s + + def visit_Typedef(self, n): + s = '' + if n.storage: s += ' '.join(n.storage) + ' ' + s += self._generate_type(n.type) + return s + + def visit_Cast(self, n): + s = '(' + self._generate_type(n.to_type, emit_declname=False) + ')' + return s + ' ' + self._parenthesize_unless_simple(n.expr) + + def visit_ExprList(self, n): + visited_subexprs = [] + for expr in n.exprs: + visited_subexprs.append(self._visit_expr(expr)) + return ', '.join(visited_subexprs) + + def visit_InitList(self, n): + visited_subexprs = [] + for expr in n.exprs: + visited_subexprs.append(self._visit_expr(expr)) + return ', '.join(visited_subexprs) + + def visit_Enum(self, n): + return self._generate_struct_union_enum(n, name='enum') + + def visit_Alignas(self, n): + return '_Alignas({})'.format(self.visit(n.alignment)) + + def visit_Enumerator(self, n): + if not n.value: + return '{indent}{name},\n'.format( + indent=self._make_indent(), + name=n.name, + ) + else: + return '{indent}{name} = {value},\n'.format( + indent=self._make_indent(), + name=n.name, + value=self.visit(n.value), + ) + + def visit_FuncDef(self, n): + decl = self.visit(n.decl) + self.indent_level = 0 + body = self.visit(n.body) + if n.param_decls: + knrdecls = ';\n'.join(self.visit(p) for p in n.param_decls) + return decl + '\n' + knrdecls + ';\n' + body + '\n' + else: + return decl + '\n' + body + '\n' + + def visit_FileAST(self, n): + s = '' + for ext in n.ext: + if isinstance(ext, c_ast.FuncDef): + s += self.visit(ext) + elif isinstance(ext, c_ast.Pragma): + s += self.visit(ext) + '\n' + else: + s += self.visit(ext) + ';\n' + return s + + def visit_Compound(self, n): + s = self._make_indent() + '{\n' + self.indent_level += 2 + if n.block_items: + s += ''.join(self._generate_stmt(stmt) for stmt in n.block_items) + self.indent_level -= 2 + s += self._make_indent() + '}\n' + return s + + def visit_CompoundLiteral(self, n): + return '(' + self.visit(n.type) + '){' + self.visit(n.init) + '}' + + + def visit_EmptyStatement(self, n): + return ';' + + def visit_ParamList(self, n): + return ', '.join(self.visit(param) for param in n.params) + + def visit_Return(self, n): + s = 'return' + if n.expr: s += ' ' + self.visit(n.expr) + return s + ';' + + def visit_Break(self, n): + return 'break;' + + def visit_Continue(self, n): + return 'continue;' + + def visit_TernaryOp(self, n): + s = '(' + self._visit_expr(n.cond) + ') ? ' + s += '(' + self._visit_expr(n.iftrue) + ') : ' + s += '(' + self._visit_expr(n.iffalse) + ')' + return s + + def visit_If(self, n): + s = 'if (' + if n.cond: s += self.visit(n.cond) + s += ')\n' + s += self._generate_stmt(n.iftrue, add_indent=True) + if n.iffalse: + s += self._make_indent() + 'else\n' + s += self._generate_stmt(n.iffalse, add_indent=True) + return s + + def visit_For(self, n): + s = 'for (' + if n.init: s += self.visit(n.init) + s += ';' + if n.cond: s += ' ' + self.visit(n.cond) + s += ';' + if n.next: s += ' ' + self.visit(n.next) + s += ')\n' + s += self._generate_stmt(n.stmt, add_indent=True) + return s + + def visit_While(self, n): + s = 'while (' + if n.cond: s += self.visit(n.cond) + s += ')\n' + s += self._generate_stmt(n.stmt, add_indent=True) + return s + + def visit_DoWhile(self, n): + s = 'do\n' + s += self._generate_stmt(n.stmt, add_indent=True) + s += self._make_indent() + 'while (' + if n.cond: s += self.visit(n.cond) + s += ');' + return s + + def visit_StaticAssert(self, n): + s = '_Static_assert(' + s += self.visit(n.cond) + if n.message: + s += ',' + s += self.visit(n.message) + s += ')' + return s + + def visit_Switch(self, n): + s = 'switch (' + self.visit(n.cond) + ')\n' + s += self._generate_stmt(n.stmt, add_indent=True) + return s + + def visit_Case(self, n): + s = 'case ' + self.visit(n.expr) + ':\n' + for stmt in n.stmts: + s += self._generate_stmt(stmt, add_indent=True) + return s + + def visit_Default(self, n): + s = 'default:\n' + for stmt in n.stmts: + s += self._generate_stmt(stmt, add_indent=True) + return s + + def visit_Label(self, n): + return n.name + ':\n' + self._generate_stmt(n.stmt) + + def visit_Goto(self, n): + return 'goto ' + n.name + ';' + + def visit_EllipsisParam(self, n): + return '...' + + def visit_Struct(self, n): + return self._generate_struct_union_enum(n, 'struct') + + def visit_Typename(self, n): + return self._generate_type(n.type) + + def visit_Union(self, n): + return self._generate_struct_union_enum(n, 'union') + + def visit_NamedInitializer(self, n): + s = '' + for name in n.name: + if isinstance(name, c_ast.ID): + s += '.' + name.name + else: + s += '[' + self.visit(name) + ']' + s += ' = ' + self._visit_expr(n.expr) + return s + + def visit_FuncDecl(self, n): + return self._generate_type(n) + + def visit_ArrayDecl(self, n): + return self._generate_type(n, emit_declname=False) + + def visit_TypeDecl(self, n): + return self._generate_type(n, emit_declname=False) + + def visit_PtrDecl(self, n): + return self._generate_type(n, emit_declname=False) + + def _generate_struct_union_enum(self, n, name): + """ Generates code for structs, unions, and enums. name should be + 'struct', 'union', or 'enum'. + """ + if name in ('struct', 'union'): + members = n.decls + body_function = self._generate_struct_union_body + else: + assert name == 'enum' + members = None if n.values is None else n.values.enumerators + body_function = self._generate_enum_body + s = name + ' ' + (n.name or '') + if members is not None: + # None means no members + # Empty sequence means an empty list of members + s += '\n' + s += self._make_indent() + self.indent_level += 2 + s += '{\n' + s += body_function(members) + self.indent_level -= 2 + s += self._make_indent() + '}' + return s + + def _generate_struct_union_body(self, members): + return ''.join(self._generate_stmt(decl) for decl in members) + + def _generate_enum_body(self, members): + # `[:-2] + '\n'` removes the final `,` from the enumerator list + return ''.join(self.visit(value) for value in members)[:-2] + '\n' + + def _generate_stmt(self, n, add_indent=False): + """ Generation from a statement node. This method exists as a wrapper + for individual visit_* methods to handle different treatment of + some statements in this context. + """ + typ = type(n) + if add_indent: self.indent_level += 2 + indent = self._make_indent() + if add_indent: self.indent_level -= 2 + + if typ in ( + c_ast.Decl, c_ast.Assignment, c_ast.Cast, c_ast.UnaryOp, + c_ast.BinaryOp, c_ast.TernaryOp, c_ast.FuncCall, c_ast.ArrayRef, + c_ast.StructRef, c_ast.Constant, c_ast.ID, c_ast.Typedef, + c_ast.ExprList): + # These can also appear in an expression context so no semicolon + # is added to them automatically + # + return indent + self.visit(n) + ';\n' + elif typ in (c_ast.Compound,): + # No extra indentation required before the opening brace of a + # compound - because it consists of multiple lines it has to + # compute its own indentation. + # + return self.visit(n) + elif typ in (c_ast.If,): + return indent + self.visit(n) + else: + return indent + self.visit(n) + '\n' + + def _generate_decl(self, n): + """ Generation from a Decl node. + """ + s = '' + if n.funcspec: s = ' '.join(n.funcspec) + ' ' + if n.storage: s += ' '.join(n.storage) + ' ' + if n.align: s += self.visit(n.align[0]) + ' ' + s += self._generate_type(n.type) + return s + + def _generate_type(self, n, modifiers=[], emit_declname = True): + """ Recursive generation from a type node. n is the type node. + modifiers collects the PtrDecl, ArrayDecl and FuncDecl modifiers + encountered on the way down to a TypeDecl, to allow proper + generation from it. + """ + typ = type(n) + #~ print(n, modifiers) + + if typ == c_ast.TypeDecl: + s = '' + if n.quals: s += ' '.join(n.quals) + ' ' + s += self.visit(n.type) + + nstr = n.declname if n.declname and emit_declname else '' + # Resolve modifiers. + # Wrap in parens to distinguish pointer to array and pointer to + # function syntax. + # + for i, modifier in enumerate(modifiers): + if isinstance(modifier, c_ast.ArrayDecl): + if (i != 0 and + isinstance(modifiers[i - 1], c_ast.PtrDecl)): + nstr = '(' + nstr + ')' + nstr += '[' + if modifier.dim_quals: + nstr += ' '.join(modifier.dim_quals) + ' ' + nstr += self.visit(modifier.dim) + ']' + elif isinstance(modifier, c_ast.FuncDecl): + if (i != 0 and + isinstance(modifiers[i - 1], c_ast.PtrDecl)): + nstr = '(' + nstr + ')' + nstr += '(' + self.visit(modifier.args) + ')' + elif isinstance(modifier, c_ast.PtrDecl): + if modifier.quals: + nstr = '* %s%s' % (' '.join(modifier.quals), + ' ' + nstr if nstr else '') + else: + nstr = '*' + nstr + if nstr: s += ' ' + nstr + return s + elif typ == c_ast.Decl: + return self._generate_decl(n.type) + elif typ == c_ast.Typename: + return self._generate_type(n.type, emit_declname = emit_declname) + elif typ == c_ast.IdentifierType: + return ' '.join(n.names) + ' ' + elif typ in (c_ast.ArrayDecl, c_ast.PtrDecl, c_ast.FuncDecl): + return self._generate_type(n.type, modifiers + [n], + emit_declname = emit_declname) + else: + return self.visit(n) + + def _parenthesize_if(self, n, condition): + """ Visits 'n' and returns its string representation, parenthesized + if the condition function applied to the node returns True. + """ + s = self._visit_expr(n) + if condition(n): + return '(' + s + ')' + else: + return s + + def _parenthesize_unless_simple(self, n): + """ Common use case for _parenthesize_if + """ + return self._parenthesize_if(n, lambda d: not self._is_simple_node(d)) + + def _is_simple_node(self, n): + """ Returns True for nodes that are "simple" - i.e. nodes that always + have higher precedence than operators. + """ + return isinstance(n, (c_ast.Constant, c_ast.ID, c_ast.ArrayRef, + c_ast.StructRef, c_ast.FuncCall)) diff --git a/uno/lib/python/pycparser/c_lexer.py b/uno/lib/python/pycparser/c_lexer.py new file mode 100644 index 00000000..d68d8ebf --- /dev/null +++ b/uno/lib/python/pycparser/c_lexer.py @@ -0,0 +1,554 @@ +#------------------------------------------------------------------------------ +# pycparser: c_lexer.py +# +# CLexer class: lexer for the C language +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#------------------------------------------------------------------------------ +import re + +from .ply import lex +from .ply.lex import TOKEN + + +class CLexer(object): + """ A lexer for the C language. After building it, set the + input text with input(), and call token() to get new + tokens. + + The public attribute filename can be set to an initial + filename, but the lexer will update it upon #line + directives. + """ + def __init__(self, error_func, on_lbrace_func, on_rbrace_func, + type_lookup_func): + """ Create a new Lexer. + + error_func: + An error function. Will be called with an error + message, line and column as arguments, in case of + an error during lexing. + + on_lbrace_func, on_rbrace_func: + Called when an LBRACE or RBRACE is encountered + (likely to push/pop type_lookup_func's scope) + + type_lookup_func: + A type lookup function. Given a string, it must + return True IFF this string is a name of a type + that was defined with a typedef earlier. + """ + self.error_func = error_func + self.on_lbrace_func = on_lbrace_func + self.on_rbrace_func = on_rbrace_func + self.type_lookup_func = type_lookup_func + self.filename = '' + + # Keeps track of the last token returned from self.token() + self.last_token = None + + # Allow either "# line" or "# " to support GCC's + # cpp output + # + self.line_pattern = re.compile(r'([ \t]*line\W)|([ \t]*\d+)') + self.pragma_pattern = re.compile(r'[ \t]*pragma\W') + + def build(self, **kwargs): + """ Builds the lexer from the specification. Must be + called after the lexer object is created. + + This method exists separately, because the PLY + manual warns against calling lex.lex inside + __init__ + """ + self.lexer = lex.lex(object=self, **kwargs) + + def reset_lineno(self): + """ Resets the internal line number counter of the lexer. + """ + self.lexer.lineno = 1 + + def input(self, text): + self.lexer.input(text) + + def token(self): + self.last_token = self.lexer.token() + return self.last_token + + def find_tok_column(self, token): + """ Find the column of the token in its line. + """ + last_cr = self.lexer.lexdata.rfind('\n', 0, token.lexpos) + return token.lexpos - last_cr + + ######################-- PRIVATE --###################### + + ## + ## Internal auxiliary methods + ## + def _error(self, msg, token): + location = self._make_tok_location(token) + self.error_func(msg, location[0], location[1]) + self.lexer.skip(1) + + def _make_tok_location(self, token): + return (token.lineno, self.find_tok_column(token)) + + ## + ## Reserved keywords + ## + keywords = ( + 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', + 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN', + 'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG', + 'REGISTER', 'OFFSETOF', + 'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', + 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID', + 'VOLATILE', 'WHILE', '__INT128', + ) + + keywords_new = ( + '_BOOL', '_COMPLEX', + '_NORETURN', '_THREAD_LOCAL', '_STATIC_ASSERT', + '_ATOMIC', '_ALIGNOF', '_ALIGNAS', + ) + + keyword_map = {} + + for keyword in keywords: + keyword_map[keyword.lower()] = keyword + + for keyword in keywords_new: + keyword_map[keyword[:2].upper() + keyword[2:].lower()] = keyword + + ## + ## All the tokens recognized by the lexer + ## + tokens = keywords + keywords_new + ( + # Identifiers + 'ID', + + # Type identifiers (identifiers previously defined as + # types with typedef) + 'TYPEID', + + # constants + 'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX', 'INT_CONST_BIN', 'INT_CONST_CHAR', + 'FLOAT_CONST', 'HEX_FLOAT_CONST', + 'CHAR_CONST', + 'WCHAR_CONST', + 'U8CHAR_CONST', + 'U16CHAR_CONST', + 'U32CHAR_CONST', + + # String literals + 'STRING_LITERAL', + 'WSTRING_LITERAL', + 'U8STRING_LITERAL', + 'U16STRING_LITERAL', + 'U32STRING_LITERAL', + + # Operators + 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD', + 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT', + 'LOR', 'LAND', 'LNOT', + 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE', + + # Assignment + 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', + 'PLUSEQUAL', 'MINUSEQUAL', + 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', + 'OREQUAL', + + # Increment/decrement + 'PLUSPLUS', 'MINUSMINUS', + + # Structure dereference (->) + 'ARROW', + + # Conditional operator (?) + 'CONDOP', + + # Delimiters + 'LPAREN', 'RPAREN', # ( ) + 'LBRACKET', 'RBRACKET', # [ ] + 'LBRACE', 'RBRACE', # { } + 'COMMA', 'PERIOD', # . , + 'SEMI', 'COLON', # ; : + + # Ellipsis (...) + 'ELLIPSIS', + + # pre-processor + 'PPHASH', # '#' + 'PPPRAGMA', # 'pragma' + 'PPPRAGMASTR', + ) + + ## + ## Regexes for use in tokens + ## + ## + + # valid C identifiers (K&R2: A.2.3), plus '$' (supported by some compilers) + identifier = r'[a-zA-Z_$][0-9a-zA-Z_$]*' + + hex_prefix = '0[xX]' + hex_digits = '[0-9a-fA-F]+' + bin_prefix = '0[bB]' + bin_digits = '[01]+' + + # integer constants (K&R2: A.2.5.1) + integer_suffix_opt = r'(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?' + decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')' + octal_constant = '0[0-7]*'+integer_suffix_opt + hex_constant = hex_prefix+hex_digits+integer_suffix_opt + bin_constant = bin_prefix+bin_digits+integer_suffix_opt + + bad_octal_constant = '0[0-7]*[89]' + + # character constants (K&R2: A.2.5.2) + # Note: a-zA-Z and '.-~^_!=&;,' are allowed as escape chars to support #line + # directives with Windows paths as filenames (..\..\dir\file) + # For the same reason, decimal_escape allows all digit sequences. We want to + # parse all correct code, even if it means to sometimes parse incorrect + # code. + # + # The original regexes were taken verbatim from the C syntax definition, + # and were later modified to avoid worst-case exponential running time. + # + # simple_escape = r"""([a-zA-Z._~!=&\^\-\\?'"])""" + # decimal_escape = r"""(\d+)""" + # hex_escape = r"""(x[0-9a-fA-F]+)""" + # bad_escape = r"""([\\][^a-zA-Z._~^!=&\^\-\\?'"x0-7])""" + # + # The following modifications were made to avoid the ambiguity that allowed backtracking: + # (https://github.com/eliben/pycparser/issues/61) + # + # - \x was removed from simple_escape, unless it was not followed by a hex digit, to avoid ambiguity with hex_escape. + # - hex_escape allows one or more hex characters, but requires that the next character(if any) is not hex + # - decimal_escape allows one or more decimal characters, but requires that the next character(if any) is not a decimal + # - bad_escape does not allow any decimals (8-9), to avoid conflicting with the permissive decimal_escape. + # + # Without this change, python's `re` module would recursively try parsing each ambiguous escape sequence in multiple ways. + # e.g. `\123` could be parsed as `\1`+`23`, `\12`+`3`, and `\123`. + + simple_escape = r"""([a-wyzA-Z._~!=&\^\-\\?'"]|x(?![0-9a-fA-F]))""" + decimal_escape = r"""(\d+)(?!\d)""" + hex_escape = r"""(x[0-9a-fA-F]+)(?![0-9a-fA-F])""" + bad_escape = r"""([\\][^a-zA-Z._~^!=&\^\-\\?'"x0-9])""" + + escape_sequence = r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))' + + # This complicated regex with lookahead might be slow for strings, so because all of the valid escapes (including \x) allowed + # 0 or more non-escaped characters after the first character, simple_escape+decimal_escape+hex_escape got simplified to + + escape_sequence_start_in_string = r"""(\\[0-9a-zA-Z._~!=&\^\-\\?'"])""" + + cconst_char = r"""([^'\\\n]|"""+escape_sequence+')' + char_const = "'"+cconst_char+"'" + wchar_const = 'L'+char_const + u8char_const = 'u8'+char_const + u16char_const = 'u'+char_const + u32char_const = 'U'+char_const + multicharacter_constant = "'"+cconst_char+"{2,4}'" + unmatched_quote = "('"+cconst_char+"*\\n)|('"+cconst_char+"*$)" + bad_char_const = r"""('"""+cconst_char+"""[^'\n]+')|('')|('"""+bad_escape+r"""[^'\n]*')""" + + # string literals (K&R2: A.2.6) + string_char = r"""([^"\\\n]|"""+escape_sequence_start_in_string+')' + string_literal = '"'+string_char+'*"' + wstring_literal = 'L'+string_literal + u8string_literal = 'u8'+string_literal + u16string_literal = 'u'+string_literal + u32string_literal = 'U'+string_literal + bad_string_literal = '"'+string_char+'*'+bad_escape+string_char+'*"' + + # floating constants (K&R2: A.2.5.3) + exponent_part = r"""([eE][-+]?[0-9]+)""" + fractional_constant = r"""([0-9]*\.[0-9]+)|([0-9]+\.)""" + floating_constant = '(((('+fractional_constant+')'+exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)' + binary_exponent_part = r'''([pP][+-]?[0-9]+)''' + hex_fractional_constant = '((('+hex_digits+r""")?\."""+hex_digits+')|('+hex_digits+r"""\.))""" + hex_floating_constant = '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+binary_exponent_part+'[FfLl]?)' + + ## + ## Lexer states: used for preprocessor \n-terminated directives + ## + states = ( + # ppline: preprocessor line directives + # + ('ppline', 'exclusive'), + + # pppragma: pragma + # + ('pppragma', 'exclusive'), + ) + + def t_PPHASH(self, t): + r'[ \t]*\#' + if self.line_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos): + t.lexer.begin('ppline') + self.pp_line = self.pp_filename = None + elif self.pragma_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos): + t.lexer.begin('pppragma') + else: + t.type = 'PPHASH' + return t + + ## + ## Rules for the ppline state + ## + @TOKEN(string_literal) + def t_ppline_FILENAME(self, t): + if self.pp_line is None: + self._error('filename before line number in #line', t) + else: + self.pp_filename = t.value.lstrip('"').rstrip('"') + + @TOKEN(decimal_constant) + def t_ppline_LINE_NUMBER(self, t): + if self.pp_line is None: + self.pp_line = t.value + else: + # Ignore: GCC's cpp sometimes inserts a numeric flag + # after the file name + pass + + def t_ppline_NEWLINE(self, t): + r'\n' + if self.pp_line is None: + self._error('line number missing in #line', t) + else: + self.lexer.lineno = int(self.pp_line) + + if self.pp_filename is not None: + self.filename = self.pp_filename + + t.lexer.begin('INITIAL') + + def t_ppline_PPLINE(self, t): + r'line' + pass + + t_ppline_ignore = ' \t' + + def t_ppline_error(self, t): + self._error('invalid #line directive', t) + + ## + ## Rules for the pppragma state + ## + def t_pppragma_NEWLINE(self, t): + r'\n' + t.lexer.lineno += 1 + t.lexer.begin('INITIAL') + + def t_pppragma_PPPRAGMA(self, t): + r'pragma' + return t + + t_pppragma_ignore = ' \t' + + def t_pppragma_STR(self, t): + '.+' + t.type = 'PPPRAGMASTR' + return t + + def t_pppragma_error(self, t): + self._error('invalid #pragma directive', t) + + ## + ## Rules for the normal state + ## + t_ignore = ' \t' + + # Newlines + def t_NEWLINE(self, t): + r'\n+' + t.lexer.lineno += t.value.count("\n") + + # Operators + t_PLUS = r'\+' + t_MINUS = r'-' + t_TIMES = r'\*' + t_DIVIDE = r'/' + t_MOD = r'%' + t_OR = r'\|' + t_AND = r'&' + t_NOT = r'~' + t_XOR = r'\^' + t_LSHIFT = r'<<' + t_RSHIFT = r'>>' + t_LOR = r'\|\|' + t_LAND = r'&&' + t_LNOT = r'!' + t_LT = r'<' + t_GT = r'>' + t_LE = r'<=' + t_GE = r'>=' + t_EQ = r'==' + t_NE = r'!=' + + # Assignment operators + t_EQUALS = r'=' + t_TIMESEQUAL = r'\*=' + t_DIVEQUAL = r'/=' + t_MODEQUAL = r'%=' + t_PLUSEQUAL = r'\+=' + t_MINUSEQUAL = r'-=' + t_LSHIFTEQUAL = r'<<=' + t_RSHIFTEQUAL = r'>>=' + t_ANDEQUAL = r'&=' + t_OREQUAL = r'\|=' + t_XOREQUAL = r'\^=' + + # Increment/decrement + t_PLUSPLUS = r'\+\+' + t_MINUSMINUS = r'--' + + # -> + t_ARROW = r'->' + + # ? + t_CONDOP = r'\?' + + # Delimiters + t_LPAREN = r'\(' + t_RPAREN = r'\)' + t_LBRACKET = r'\[' + t_RBRACKET = r'\]' + t_COMMA = r',' + t_PERIOD = r'\.' + t_SEMI = r';' + t_COLON = r':' + t_ELLIPSIS = r'\.\.\.' + + # Scope delimiters + # To see why on_lbrace_func is needed, consider: + # typedef char TT; + # void foo(int TT) { TT = 10; } + # TT x = 5; + # Outside the function, TT is a typedef, but inside (starting and ending + # with the braces) it's a parameter. The trouble begins with yacc's + # lookahead token. If we open a new scope in brace_open, then TT has + # already been read and incorrectly interpreted as TYPEID. So, we need + # to open and close scopes from within the lexer. + # Similar for the TT immediately outside the end of the function. + # + @TOKEN(r'\{') + def t_LBRACE(self, t): + self.on_lbrace_func() + return t + @TOKEN(r'\}') + def t_RBRACE(self, t): + self.on_rbrace_func() + return t + + t_STRING_LITERAL = string_literal + + # The following floating and integer constants are defined as + # functions to impose a strict order (otherwise, decimal + # is placed before the others because its regex is longer, + # and this is bad) + # + @TOKEN(floating_constant) + def t_FLOAT_CONST(self, t): + return t + + @TOKEN(hex_floating_constant) + def t_HEX_FLOAT_CONST(self, t): + return t + + @TOKEN(hex_constant) + def t_INT_CONST_HEX(self, t): + return t + + @TOKEN(bin_constant) + def t_INT_CONST_BIN(self, t): + return t + + @TOKEN(bad_octal_constant) + def t_BAD_CONST_OCT(self, t): + msg = "Invalid octal constant" + self._error(msg, t) + + @TOKEN(octal_constant) + def t_INT_CONST_OCT(self, t): + return t + + @TOKEN(decimal_constant) + def t_INT_CONST_DEC(self, t): + return t + + # Must come before bad_char_const, to prevent it from + # catching valid char constants as invalid + # + @TOKEN(multicharacter_constant) + def t_INT_CONST_CHAR(self, t): + return t + + @TOKEN(char_const) + def t_CHAR_CONST(self, t): + return t + + @TOKEN(wchar_const) + def t_WCHAR_CONST(self, t): + return t + + @TOKEN(u8char_const) + def t_U8CHAR_CONST(self, t): + return t + + @TOKEN(u16char_const) + def t_U16CHAR_CONST(self, t): + return t + + @TOKEN(u32char_const) + def t_U32CHAR_CONST(self, t): + return t + + @TOKEN(unmatched_quote) + def t_UNMATCHED_QUOTE(self, t): + msg = "Unmatched '" + self._error(msg, t) + + @TOKEN(bad_char_const) + def t_BAD_CHAR_CONST(self, t): + msg = "Invalid char constant %s" % t.value + self._error(msg, t) + + @TOKEN(wstring_literal) + def t_WSTRING_LITERAL(self, t): + return t + + @TOKEN(u8string_literal) + def t_U8STRING_LITERAL(self, t): + return t + + @TOKEN(u16string_literal) + def t_U16STRING_LITERAL(self, t): + return t + + @TOKEN(u32string_literal) + def t_U32STRING_LITERAL(self, t): + return t + + # unmatched string literals are caught by the preprocessor + + @TOKEN(bad_string_literal) + def t_BAD_STRING_LITERAL(self, t): + msg = "String contains invalid escape code" + self._error(msg, t) + + @TOKEN(identifier) + def t_ID(self, t): + t.type = self.keyword_map.get(t.value, "ID") + if t.type == 'ID' and self.type_lookup_func(t.value): + t.type = "TYPEID" + return t + + def t_error(self, t): + msg = 'Illegal character %s' % repr(t.value[0]) + self._error(msg, t) diff --git a/uno/lib/python/pycparser/c_parser.py b/uno/lib/python/pycparser/c_parser.py new file mode 100644 index 00000000..640a7594 --- /dev/null +++ b/uno/lib/python/pycparser/c_parser.py @@ -0,0 +1,1936 @@ +#------------------------------------------------------------------------------ +# pycparser: c_parser.py +# +# CParser class: Parser and AST builder for the C language +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#------------------------------------------------------------------------------ +from .ply import yacc + +from . import c_ast +from .c_lexer import CLexer +from .plyparser import PLYParser, ParseError, parameterized, template +from .ast_transforms import fix_switch_cases, fix_atomic_specifiers + + +@template +class CParser(PLYParser): + def __init__( + self, + lex_optimize=True, + lexer=CLexer, + lextab='pycparser.lextab', + yacc_optimize=True, + yacctab='pycparser.yacctab', + yacc_debug=False, + taboutputdir=''): + """ Create a new CParser. + + Some arguments for controlling the debug/optimization + level of the parser are provided. The defaults are + tuned for release/performance mode. + The simple rules for using them are: + *) When tweaking CParser/CLexer, set these to False + *) When releasing a stable parser, set to True + + lex_optimize: + Set to False when you're modifying the lexer. + Otherwise, changes in the lexer won't be used, if + some lextab.py file exists. + When releasing with a stable lexer, set to True + to save the re-generation of the lexer table on + each run. + + lexer: + Set this parameter to define the lexer to use if + you're not using the default CLexer. + + lextab: + Points to the lex table that's used for optimized + mode. Only if you're modifying the lexer and want + some tests to avoid re-generating the table, make + this point to a local lex table file (that's been + earlier generated with lex_optimize=True) + + yacc_optimize: + Set to False when you're modifying the parser. + Otherwise, changes in the parser won't be used, if + some parsetab.py file exists. + When releasing with a stable parser, set to True + to save the re-generation of the parser table on + each run. + + yacctab: + Points to the yacc table that's used for optimized + mode. Only if you're modifying the parser, make + this point to a local yacc table file + + yacc_debug: + Generate a parser.out file that explains how yacc + built the parsing table from the grammar. + + taboutputdir: + Set this parameter to control the location of generated + lextab and yacctab files. + """ + self.clex = lexer( + error_func=self._lex_error_func, + on_lbrace_func=self._lex_on_lbrace_func, + on_rbrace_func=self._lex_on_rbrace_func, + type_lookup_func=self._lex_type_lookup_func) + + self.clex.build( + optimize=lex_optimize, + lextab=lextab, + outputdir=taboutputdir) + self.tokens = self.clex.tokens + + rules_with_opt = [ + 'abstract_declarator', + 'assignment_expression', + 'declaration_list', + 'declaration_specifiers_no_type', + 'designation', + 'expression', + 'identifier_list', + 'init_declarator_list', + 'id_init_declarator_list', + 'initializer_list', + 'parameter_type_list', + 'block_item_list', + 'type_qualifier_list', + 'struct_declarator_list' + ] + + for rule in rules_with_opt: + self._create_opt_rule(rule) + + self.cparser = yacc.yacc( + module=self, + start='translation_unit_or_empty', + debug=yacc_debug, + optimize=yacc_optimize, + tabmodule=yacctab, + outputdir=taboutputdir) + + # Stack of scopes for keeping track of symbols. _scope_stack[-1] is + # the current (topmost) scope. Each scope is a dictionary that + # specifies whether a name is a type. If _scope_stack[n][name] is + # True, 'name' is currently a type in the scope. If it's False, + # 'name' is used in the scope but not as a type (for instance, if we + # saw: int name; + # If 'name' is not a key in _scope_stack[n] then 'name' was not defined + # in this scope at all. + self._scope_stack = [dict()] + + # Keeps track of the last token given to yacc (the lookahead token) + self._last_yielded_token = None + + def parse(self, text, filename='', debug=False): + """ Parses C code and returns an AST. + + text: + A string containing the C source code + + filename: + Name of the file being parsed (for meaningful + error messages) + + debug: + Debug flag to YACC + """ + self.clex.filename = filename + self.clex.reset_lineno() + self._scope_stack = [dict()] + self._last_yielded_token = None + return self.cparser.parse( + input=text, + lexer=self.clex, + debug=debug) + + ######################-- PRIVATE --###################### + + def _push_scope(self): + self._scope_stack.append(dict()) + + def _pop_scope(self): + assert len(self._scope_stack) > 1 + self._scope_stack.pop() + + def _add_typedef_name(self, name, coord): + """ Add a new typedef name (ie a TYPEID) to the current scope + """ + if not self._scope_stack[-1].get(name, True): + self._parse_error( + "Typedef %r previously declared as non-typedef " + "in this scope" % name, coord) + self._scope_stack[-1][name] = True + + def _add_identifier(self, name, coord): + """ Add a new object, function, or enum member name (ie an ID) to the + current scope + """ + if self._scope_stack[-1].get(name, False): + self._parse_error( + "Non-typedef %r previously declared as typedef " + "in this scope" % name, coord) + self._scope_stack[-1][name] = False + + def _is_type_in_scope(self, name): + """ Is *name* a typedef-name in the current scope? + """ + for scope in reversed(self._scope_stack): + # If name is an identifier in this scope it shadows typedefs in + # higher scopes. + in_scope = scope.get(name) + if in_scope is not None: return in_scope + return False + + def _lex_error_func(self, msg, line, column): + self._parse_error(msg, self._coord(line, column)) + + def _lex_on_lbrace_func(self): + self._push_scope() + + def _lex_on_rbrace_func(self): + self._pop_scope() + + def _lex_type_lookup_func(self, name): + """ Looks up types that were previously defined with + typedef. + Passed to the lexer for recognizing identifiers that + are types. + """ + is_type = self._is_type_in_scope(name) + return is_type + + def _get_yacc_lookahead_token(self): + """ We need access to yacc's lookahead token in certain cases. + This is the last token yacc requested from the lexer, so we + ask the lexer. + """ + return self.clex.last_token + + # To understand what's going on here, read sections A.8.5 and + # A.8.6 of K&R2 very carefully. + # + # A C type consists of a basic type declaration, with a list + # of modifiers. For example: + # + # int *c[5]; + # + # The basic declaration here is 'int c', and the pointer and + # the array are the modifiers. + # + # Basic declarations are represented by TypeDecl (from module c_ast) and the + # modifiers are FuncDecl, PtrDecl and ArrayDecl. + # + # The standard states that whenever a new modifier is parsed, it should be + # added to the end of the list of modifiers. For example: + # + # K&R2 A.8.6.2: Array Declarators + # + # In a declaration T D where D has the form + # D1 [constant-expression-opt] + # and the type of the identifier in the declaration T D1 is + # "type-modifier T", the type of the + # identifier of D is "type-modifier array of T" + # + # This is what this method does. The declarator it receives + # can be a list of declarators ending with TypeDecl. It + # tacks the modifier to the end of this list, just before + # the TypeDecl. + # + # Additionally, the modifier may be a list itself. This is + # useful for pointers, that can come as a chain from the rule + # p_pointer. In this case, the whole modifier list is spliced + # into the new location. + def _type_modify_decl(self, decl, modifier): + """ Tacks a type modifier on a declarator, and returns + the modified declarator. + + Note: the declarator and modifier may be modified + """ + #~ print '****' + #~ decl.show(offset=3) + #~ modifier.show(offset=3) + #~ print '****' + + modifier_head = modifier + modifier_tail = modifier + + # The modifier may be a nested list. Reach its tail. + while modifier_tail.type: + modifier_tail = modifier_tail.type + + # If the decl is a basic type, just tack the modifier onto it. + if isinstance(decl, c_ast.TypeDecl): + modifier_tail.type = decl + return modifier + else: + # Otherwise, the decl is a list of modifiers. Reach + # its tail and splice the modifier onto the tail, + # pointing to the underlying basic type. + decl_tail = decl + + while not isinstance(decl_tail.type, c_ast.TypeDecl): + decl_tail = decl_tail.type + + modifier_tail.type = decl_tail.type + decl_tail.type = modifier_head + return decl + + # Due to the order in which declarators are constructed, + # they have to be fixed in order to look like a normal AST. + # + # When a declaration arrives from syntax construction, it has + # these problems: + # * The innermost TypeDecl has no type (because the basic + # type is only known at the uppermost declaration level) + # * The declaration has no variable name, since that is saved + # in the innermost TypeDecl + # * The typename of the declaration is a list of type + # specifiers, and not a node. Here, basic identifier types + # should be separated from more complex types like enums + # and structs. + # + # This method fixes these problems. + def _fix_decl_name_type(self, decl, typename): + """ Fixes a declaration. Modifies decl. + """ + # Reach the underlying basic type + # + type = decl + while not isinstance(type, c_ast.TypeDecl): + type = type.type + + decl.name = type.declname + type.quals = decl.quals[:] + + # The typename is a list of types. If any type in this + # list isn't an IdentifierType, it must be the only + # type in the list (it's illegal to declare "int enum ..") + # If all the types are basic, they're collected in the + # IdentifierType holder. + for tn in typename: + if not isinstance(tn, c_ast.IdentifierType): + if len(typename) > 1: + self._parse_error( + "Invalid multiple types specified", tn.coord) + else: + type.type = tn + return decl + + if not typename: + # Functions default to returning int + # + if not isinstance(decl.type, c_ast.FuncDecl): + self._parse_error( + "Missing type in declaration", decl.coord) + type.type = c_ast.IdentifierType( + ['int'], + coord=decl.coord) + else: + # At this point, we know that typename is a list of IdentifierType + # nodes. Concatenate all the names into a single list. + # + type.type = c_ast.IdentifierType( + [name for id in typename for name in id.names], + coord=typename[0].coord) + return decl + + def _add_declaration_specifier(self, declspec, newspec, kind, append=False): + """ Declaration specifiers are represented by a dictionary + with the entries: + * qual: a list of type qualifiers + * storage: a list of storage type qualifiers + * type: a list of type specifiers + * function: a list of function specifiers + * alignment: a list of alignment specifiers + + This method is given a declaration specifier, and a + new specifier of a given kind. + If `append` is True, the new specifier is added to the end of + the specifiers list, otherwise it's added at the beginning. + Returns the declaration specifier, with the new + specifier incorporated. + """ + spec = declspec or dict(qual=[], storage=[], type=[], function=[], alignment=[]) + + if append: + spec[kind].append(newspec) + else: + spec[kind].insert(0, newspec) + + return spec + + def _build_declarations(self, spec, decls, typedef_namespace=False): + """ Builds a list of declarations all sharing the given specifiers. + If typedef_namespace is true, each declared name is added + to the "typedef namespace", which also includes objects, + functions, and enum constants. + """ + is_typedef = 'typedef' in spec['storage'] + declarations = [] + + # Bit-fields are allowed to be unnamed. + if decls[0].get('bitsize') is not None: + pass + + # When redeclaring typedef names as identifiers in inner scopes, a + # problem can occur where the identifier gets grouped into + # spec['type'], leaving decl as None. This can only occur for the + # first declarator. + elif decls[0]['decl'] is None: + if len(spec['type']) < 2 or len(spec['type'][-1].names) != 1 or \ + not self._is_type_in_scope(spec['type'][-1].names[0]): + coord = '?' + for t in spec['type']: + if hasattr(t, 'coord'): + coord = t.coord + break + self._parse_error('Invalid declaration', coord) + + # Make this look as if it came from "direct_declarator:ID" + decls[0]['decl'] = c_ast.TypeDecl( + declname=spec['type'][-1].names[0], + type=None, + quals=None, + align=spec['alignment'], + coord=spec['type'][-1].coord) + # Remove the "new" type's name from the end of spec['type'] + del spec['type'][-1] + + # A similar problem can occur where the declaration ends up looking + # like an abstract declarator. Give it a name if this is the case. + elif not isinstance(decls[0]['decl'], ( + c_ast.Enum, c_ast.Struct, c_ast.Union, c_ast.IdentifierType)): + decls_0_tail = decls[0]['decl'] + while not isinstance(decls_0_tail, c_ast.TypeDecl): + decls_0_tail = decls_0_tail.type + if decls_0_tail.declname is None: + decls_0_tail.declname = spec['type'][-1].names[0] + del spec['type'][-1] + + for decl in decls: + assert decl['decl'] is not None + if is_typedef: + declaration = c_ast.Typedef( + name=None, + quals=spec['qual'], + storage=spec['storage'], + type=decl['decl'], + coord=decl['decl'].coord) + else: + declaration = c_ast.Decl( + name=None, + quals=spec['qual'], + align=spec['alignment'], + storage=spec['storage'], + funcspec=spec['function'], + type=decl['decl'], + init=decl.get('init'), + bitsize=decl.get('bitsize'), + coord=decl['decl'].coord) + + if isinstance(declaration.type, ( + c_ast.Enum, c_ast.Struct, c_ast.Union, + c_ast.IdentifierType)): + fixed_decl = declaration + else: + fixed_decl = self._fix_decl_name_type(declaration, spec['type']) + + # Add the type name defined by typedef to a + # symbol table (for usage in the lexer) + if typedef_namespace: + if is_typedef: + self._add_typedef_name(fixed_decl.name, fixed_decl.coord) + else: + self._add_identifier(fixed_decl.name, fixed_decl.coord) + + fixed_decl = fix_atomic_specifiers(fixed_decl) + declarations.append(fixed_decl) + + return declarations + + def _build_function_definition(self, spec, decl, param_decls, body): + """ Builds a function definition. + """ + if 'typedef' in spec['storage']: + self._parse_error("Invalid typedef", decl.coord) + + declaration = self._build_declarations( + spec=spec, + decls=[dict(decl=decl, init=None)], + typedef_namespace=True)[0] + + return c_ast.FuncDef( + decl=declaration, + param_decls=param_decls, + body=body, + coord=decl.coord) + + def _select_struct_union_class(self, token): + """ Given a token (either STRUCT or UNION), selects the + appropriate AST class. + """ + if token == 'struct': + return c_ast.Struct + else: + return c_ast.Union + + ## + ## Precedence and associativity of operators + ## + # If this changes, c_generator.CGenerator.precedence_map needs to change as + # well + precedence = ( + ('left', 'LOR'), + ('left', 'LAND'), + ('left', 'OR'), + ('left', 'XOR'), + ('left', 'AND'), + ('left', 'EQ', 'NE'), + ('left', 'GT', 'GE', 'LT', 'LE'), + ('left', 'RSHIFT', 'LSHIFT'), + ('left', 'PLUS', 'MINUS'), + ('left', 'TIMES', 'DIVIDE', 'MOD') + ) + + ## + ## Grammar productions + ## Implementation of the BNF defined in K&R2 A.13 + ## + + # Wrapper around a translation unit, to allow for empty input. + # Not strictly part of the C99 Grammar, but useful in practice. + def p_translation_unit_or_empty(self, p): + """ translation_unit_or_empty : translation_unit + | empty + """ + if p[1] is None: + p[0] = c_ast.FileAST([]) + else: + p[0] = c_ast.FileAST(p[1]) + + def p_translation_unit_1(self, p): + """ translation_unit : external_declaration + """ + # Note: external_declaration is already a list + p[0] = p[1] + + def p_translation_unit_2(self, p): + """ translation_unit : translation_unit external_declaration + """ + p[1].extend(p[2]) + p[0] = p[1] + + # Declarations always come as lists (because they can be + # several in one line), so we wrap the function definition + # into a list as well, to make the return value of + # external_declaration homogeneous. + def p_external_declaration_1(self, p): + """ external_declaration : function_definition + """ + p[0] = [p[1]] + + def p_external_declaration_2(self, p): + """ external_declaration : declaration + """ + p[0] = p[1] + + def p_external_declaration_3(self, p): + """ external_declaration : pp_directive + | pppragma_directive + """ + p[0] = [p[1]] + + def p_external_declaration_4(self, p): + """ external_declaration : SEMI + """ + p[0] = [] + + def p_external_declaration_5(self, p): + """ external_declaration : static_assert + """ + p[0] = p[1] + + def p_static_assert_declaration(self, p): + """ static_assert : _STATIC_ASSERT LPAREN constant_expression COMMA unified_string_literal RPAREN + | _STATIC_ASSERT LPAREN constant_expression RPAREN + """ + if len(p) == 5: + p[0] = [c_ast.StaticAssert(p[3], None, self._token_coord(p, 1))] + else: + p[0] = [c_ast.StaticAssert(p[3], p[5], self._token_coord(p, 1))] + + def p_pp_directive(self, p): + """ pp_directive : PPHASH + """ + self._parse_error('Directives not supported yet', + self._token_coord(p, 1)) + + def p_pppragma_directive(self, p): + """ pppragma_directive : PPPRAGMA + | PPPRAGMA PPPRAGMASTR + """ + if len(p) == 3: + p[0] = c_ast.Pragma(p[2], self._token_coord(p, 2)) + else: + p[0] = c_ast.Pragma("", self._token_coord(p, 1)) + + # In function definitions, the declarator can be followed by + # a declaration list, for old "K&R style" function definitios. + def p_function_definition_1(self, p): + """ function_definition : id_declarator declaration_list_opt compound_statement + """ + # no declaration specifiers - 'int' becomes the default type + spec = dict( + qual=[], + alignment=[], + storage=[], + type=[c_ast.IdentifierType(['int'], + coord=self._token_coord(p, 1))], + function=[]) + + p[0] = self._build_function_definition( + spec=spec, + decl=p[1], + param_decls=p[2], + body=p[3]) + + def p_function_definition_2(self, p): + """ function_definition : declaration_specifiers id_declarator declaration_list_opt compound_statement + """ + spec = p[1] + + p[0] = self._build_function_definition( + spec=spec, + decl=p[2], + param_decls=p[3], + body=p[4]) + + # Note, according to C18 A.2.2 6.7.10 static_assert-declaration _Static_assert + # is a declaration, not a statement. We additionally recognise it as a statement + # to fix parsing of _Static_assert inside the functions. + # + def p_statement(self, p): + """ statement : labeled_statement + | expression_statement + | compound_statement + | selection_statement + | iteration_statement + | jump_statement + | pppragma_directive + | static_assert + """ + p[0] = p[1] + + # A pragma is generally considered a decorator rather than an actual + # statement. Still, for the purposes of analyzing an abstract syntax tree of + # C code, pragma's should not be ignored and were previously treated as a + # statement. This presents a problem for constructs that take a statement + # such as labeled_statements, selection_statements, and + # iteration_statements, causing a misleading structure in the AST. For + # example, consider the following C code. + # + # for (int i = 0; i < 3; i++) + # #pragma omp critical + # sum += 1; + # + # This code will compile and execute "sum += 1;" as the body of the for + # loop. Previous implementations of PyCParser would render the AST for this + # block of code as follows: + # + # For: + # DeclList: + # Decl: i, [], [], [] + # TypeDecl: i, [] + # IdentifierType: ['int'] + # Constant: int, 0 + # BinaryOp: < + # ID: i + # Constant: int, 3 + # UnaryOp: p++ + # ID: i + # Pragma: omp critical + # Assignment: += + # ID: sum + # Constant: int, 1 + # + # This AST misleadingly takes the Pragma as the body of the loop and the + # assignment then becomes a sibling of the loop. + # + # To solve edge cases like these, the pragmacomp_or_statement rule groups + # a pragma and its following statement (which would otherwise be orphaned) + # using a compound block, effectively turning the above code into: + # + # for (int i = 0; i < 3; i++) { + # #pragma omp critical + # sum += 1; + # } + def p_pragmacomp_or_statement(self, p): + """ pragmacomp_or_statement : pppragma_directive statement + | statement + """ + if isinstance(p[1], c_ast.Pragma) and len(p) == 3: + p[0] = c_ast.Compound( + block_items=[p[1], p[2]], + coord=self._token_coord(p, 1)) + else: + p[0] = p[1] + + # In C, declarations can come several in a line: + # int x, *px, romulo = 5; + # + # However, for the AST, we will split them to separate Decl + # nodes. + # + # This rule splits its declarations and always returns a list + # of Decl nodes, even if it's one element long. + # + def p_decl_body(self, p): + """ decl_body : declaration_specifiers init_declarator_list_opt + | declaration_specifiers_no_type id_init_declarator_list_opt + """ + spec = p[1] + + # p[2] (init_declarator_list_opt) is either a list or None + # + if p[2] is None: + # By the standard, you must have at least one declarator unless + # declaring a structure tag, a union tag, or the members of an + # enumeration. + # + ty = spec['type'] + s_u_or_e = (c_ast.Struct, c_ast.Union, c_ast.Enum) + if len(ty) == 1 and isinstance(ty[0], s_u_or_e): + decls = [c_ast.Decl( + name=None, + quals=spec['qual'], + align=spec['alignment'], + storage=spec['storage'], + funcspec=spec['function'], + type=ty[0], + init=None, + bitsize=None, + coord=ty[0].coord)] + + # However, this case can also occur on redeclared identifiers in + # an inner scope. The trouble is that the redeclared type's name + # gets grouped into declaration_specifiers; _build_declarations + # compensates for this. + # + else: + decls = self._build_declarations( + spec=spec, + decls=[dict(decl=None, init=None)], + typedef_namespace=True) + + else: + decls = self._build_declarations( + spec=spec, + decls=p[2], + typedef_namespace=True) + + p[0] = decls + + # The declaration has been split to a decl_body sub-rule and + # SEMI, because having them in a single rule created a problem + # for defining typedefs. + # + # If a typedef line was directly followed by a line using the + # type defined with the typedef, the type would not be + # recognized. This is because to reduce the declaration rule, + # the parser's lookahead asked for the token after SEMI, which + # was the type from the next line, and the lexer had no chance + # to see the updated type symbol table. + # + # Splitting solves this problem, because after seeing SEMI, + # the parser reduces decl_body, which actually adds the new + # type into the table to be seen by the lexer before the next + # line is reached. + def p_declaration(self, p): + """ declaration : decl_body SEMI + """ + p[0] = p[1] + + # Since each declaration is a list of declarations, this + # rule will combine all the declarations and return a single + # list + # + def p_declaration_list(self, p): + """ declaration_list : declaration + | declaration_list declaration + """ + p[0] = p[1] if len(p) == 2 else p[1] + p[2] + + # To know when declaration-specifiers end and declarators begin, + # we require declaration-specifiers to have at least one + # type-specifier, and disallow typedef-names after we've seen any + # type-specifier. These are both required by the spec. + # + def p_declaration_specifiers_no_type_1(self, p): + """ declaration_specifiers_no_type : type_qualifier declaration_specifiers_no_type_opt + """ + p[0] = self._add_declaration_specifier(p[2], p[1], 'qual') + + def p_declaration_specifiers_no_type_2(self, p): + """ declaration_specifiers_no_type : storage_class_specifier declaration_specifiers_no_type_opt + """ + p[0] = self._add_declaration_specifier(p[2], p[1], 'storage') + + def p_declaration_specifiers_no_type_3(self, p): + """ declaration_specifiers_no_type : function_specifier declaration_specifiers_no_type_opt + """ + p[0] = self._add_declaration_specifier(p[2], p[1], 'function') + + # Without this, `typedef _Atomic(T) U` will parse incorrectly because the + # _Atomic qualifier will match, instead of the specifier. + def p_declaration_specifiers_no_type_4(self, p): + """ declaration_specifiers_no_type : atomic_specifier declaration_specifiers_no_type_opt + """ + p[0] = self._add_declaration_specifier(p[2], p[1], 'type') + + def p_declaration_specifiers_no_type_5(self, p): + """ declaration_specifiers_no_type : alignment_specifier declaration_specifiers_no_type_opt + """ + p[0] = self._add_declaration_specifier(p[2], p[1], 'alignment') + + def p_declaration_specifiers_1(self, p): + """ declaration_specifiers : declaration_specifiers type_qualifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True) + + def p_declaration_specifiers_2(self, p): + """ declaration_specifiers : declaration_specifiers storage_class_specifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'storage', append=True) + + def p_declaration_specifiers_3(self, p): + """ declaration_specifiers : declaration_specifiers function_specifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'function', append=True) + + def p_declaration_specifiers_4(self, p): + """ declaration_specifiers : declaration_specifiers type_specifier_no_typeid + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True) + + def p_declaration_specifiers_5(self, p): + """ declaration_specifiers : type_specifier + """ + p[0] = self._add_declaration_specifier(None, p[1], 'type') + + def p_declaration_specifiers_6(self, p): + """ declaration_specifiers : declaration_specifiers_no_type type_specifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True) + + def p_declaration_specifiers_7(self, p): + """ declaration_specifiers : declaration_specifiers alignment_specifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'alignment', append=True) + + def p_storage_class_specifier(self, p): + """ storage_class_specifier : AUTO + | REGISTER + | STATIC + | EXTERN + | TYPEDEF + | _THREAD_LOCAL + """ + p[0] = p[1] + + def p_function_specifier(self, p): + """ function_specifier : INLINE + | _NORETURN + """ + p[0] = p[1] + + def p_type_specifier_no_typeid(self, p): + """ type_specifier_no_typeid : VOID + | _BOOL + | CHAR + | SHORT + | INT + | LONG + | FLOAT + | DOUBLE + | _COMPLEX + | SIGNED + | UNSIGNED + | __INT128 + """ + p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1)) + + def p_type_specifier(self, p): + """ type_specifier : typedef_name + | enum_specifier + | struct_or_union_specifier + | type_specifier_no_typeid + | atomic_specifier + """ + p[0] = p[1] + + # See section 6.7.2.4 of the C11 standard. + def p_atomic_specifier(self, p): + """ atomic_specifier : _ATOMIC LPAREN type_name RPAREN + """ + typ = p[3] + typ.quals.append('_Atomic') + p[0] = typ + + def p_type_qualifier(self, p): + """ type_qualifier : CONST + | RESTRICT + | VOLATILE + | _ATOMIC + """ + p[0] = p[1] + + def p_init_declarator_list(self, p): + """ init_declarator_list : init_declarator + | init_declarator_list COMMA init_declarator + """ + p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]] + + # Returns a {decl= : init=} dictionary + # If there's no initializer, uses None + # + def p_init_declarator(self, p): + """ init_declarator : declarator + | declarator EQUALS initializer + """ + p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None)) + + def p_id_init_declarator_list(self, p): + """ id_init_declarator_list : id_init_declarator + | id_init_declarator_list COMMA init_declarator + """ + p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]] + + def p_id_init_declarator(self, p): + """ id_init_declarator : id_declarator + | id_declarator EQUALS initializer + """ + p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None)) + + # Require at least one type specifier in a specifier-qualifier-list + # + def p_specifier_qualifier_list_1(self, p): + """ specifier_qualifier_list : specifier_qualifier_list type_specifier_no_typeid + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True) + + def p_specifier_qualifier_list_2(self, p): + """ specifier_qualifier_list : specifier_qualifier_list type_qualifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True) + + def p_specifier_qualifier_list_3(self, p): + """ specifier_qualifier_list : type_specifier + """ + p[0] = self._add_declaration_specifier(None, p[1], 'type') + + def p_specifier_qualifier_list_4(self, p): + """ specifier_qualifier_list : type_qualifier_list type_specifier + """ + p[0] = dict(qual=p[1], alignment=[], storage=[], type=[p[2]], function=[]) + + def p_specifier_qualifier_list_5(self, p): + """ specifier_qualifier_list : alignment_specifier + """ + p[0] = dict(qual=[], alignment=[p[1]], storage=[], type=[], function=[]) + + def p_specifier_qualifier_list_6(self, p): + """ specifier_qualifier_list : specifier_qualifier_list alignment_specifier + """ + p[0] = self._add_declaration_specifier(p[1], p[2], 'alignment') + + # TYPEID is allowed here (and in other struct/enum related tag names), because + # struct/enum tags reside in their own namespace and can be named the same as types + # + def p_struct_or_union_specifier_1(self, p): + """ struct_or_union_specifier : struct_or_union ID + | struct_or_union TYPEID + """ + klass = self._select_struct_union_class(p[1]) + # None means no list of members + p[0] = klass( + name=p[2], + decls=None, + coord=self._token_coord(p, 2)) + + def p_struct_or_union_specifier_2(self, p): + """ struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close + | struct_or_union brace_open brace_close + """ + klass = self._select_struct_union_class(p[1]) + if len(p) == 4: + # Empty sequence means an empty list of members + p[0] = klass( + name=None, + decls=[], + coord=self._token_coord(p, 2)) + else: + p[0] = klass( + name=None, + decls=p[3], + coord=self._token_coord(p, 2)) + + + def p_struct_or_union_specifier_3(self, p): + """ struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close + | struct_or_union ID brace_open brace_close + | struct_or_union TYPEID brace_open struct_declaration_list brace_close + | struct_or_union TYPEID brace_open brace_close + """ + klass = self._select_struct_union_class(p[1]) + if len(p) == 5: + # Empty sequence means an empty list of members + p[0] = klass( + name=p[2], + decls=[], + coord=self._token_coord(p, 2)) + else: + p[0] = klass( + name=p[2], + decls=p[4], + coord=self._token_coord(p, 2)) + + def p_struct_or_union(self, p): + """ struct_or_union : STRUCT + | UNION + """ + p[0] = p[1] + + # Combine all declarations into a single list + # + def p_struct_declaration_list(self, p): + """ struct_declaration_list : struct_declaration + | struct_declaration_list struct_declaration + """ + if len(p) == 2: + p[0] = p[1] or [] + else: + p[0] = p[1] + (p[2] or []) + + def p_struct_declaration_1(self, p): + """ struct_declaration : specifier_qualifier_list struct_declarator_list_opt SEMI + """ + spec = p[1] + assert 'typedef' not in spec['storage'] + + if p[2] is not None: + decls = self._build_declarations( + spec=spec, + decls=p[2]) + + elif len(spec['type']) == 1: + # Anonymous struct/union, gcc extension, C1x feature. + # Although the standard only allows structs/unions here, I see no + # reason to disallow other types since some compilers have typedefs + # here, and pycparser isn't about rejecting all invalid code. + # + node = spec['type'][0] + if isinstance(node, c_ast.Node): + decl_type = node + else: + decl_type = c_ast.IdentifierType(node) + + decls = self._build_declarations( + spec=spec, + decls=[dict(decl=decl_type)]) + + else: + # Structure/union members can have the same names as typedefs. + # The trouble is that the member's name gets grouped into + # specifier_qualifier_list; _build_declarations compensates. + # + decls = self._build_declarations( + spec=spec, + decls=[dict(decl=None, init=None)]) + + p[0] = decls + + def p_struct_declaration_2(self, p): + """ struct_declaration : SEMI + """ + p[0] = None + + def p_struct_declaration_3(self, p): + """ struct_declaration : pppragma_directive + """ + p[0] = [p[1]] + + def p_struct_declarator_list(self, p): + """ struct_declarator_list : struct_declarator + | struct_declarator_list COMMA struct_declarator + """ + p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]] + + # struct_declarator passes up a dict with the keys: decl (for + # the underlying declarator) and bitsize (for the bitsize) + # + def p_struct_declarator_1(self, p): + """ struct_declarator : declarator + """ + p[0] = {'decl': p[1], 'bitsize': None} + + def p_struct_declarator_2(self, p): + """ struct_declarator : declarator COLON constant_expression + | COLON constant_expression + """ + if len(p) > 3: + p[0] = {'decl': p[1], 'bitsize': p[3]} + else: + p[0] = {'decl': c_ast.TypeDecl(None, None, None, None), 'bitsize': p[2]} + + def p_enum_specifier_1(self, p): + """ enum_specifier : ENUM ID + | ENUM TYPEID + """ + p[0] = c_ast.Enum(p[2], None, self._token_coord(p, 1)) + + def p_enum_specifier_2(self, p): + """ enum_specifier : ENUM brace_open enumerator_list brace_close + """ + p[0] = c_ast.Enum(None, p[3], self._token_coord(p, 1)) + + def p_enum_specifier_3(self, p): + """ enum_specifier : ENUM ID brace_open enumerator_list brace_close + | ENUM TYPEID brace_open enumerator_list brace_close + """ + p[0] = c_ast.Enum(p[2], p[4], self._token_coord(p, 1)) + + def p_enumerator_list(self, p): + """ enumerator_list : enumerator + | enumerator_list COMMA + | enumerator_list COMMA enumerator + """ + if len(p) == 2: + p[0] = c_ast.EnumeratorList([p[1]], p[1].coord) + elif len(p) == 3: + p[0] = p[1] + else: + p[1].enumerators.append(p[3]) + p[0] = p[1] + + def p_alignment_specifier(self, p): + """ alignment_specifier : _ALIGNAS LPAREN type_name RPAREN + | _ALIGNAS LPAREN constant_expression RPAREN + """ + p[0] = c_ast.Alignas(p[3], self._token_coord(p, 1)) + + def p_enumerator(self, p): + """ enumerator : ID + | ID EQUALS constant_expression + """ + if len(p) == 2: + enumerator = c_ast.Enumerator( + p[1], None, + self._token_coord(p, 1)) + else: + enumerator = c_ast.Enumerator( + p[1], p[3], + self._token_coord(p, 1)) + self._add_identifier(enumerator.name, enumerator.coord) + + p[0] = enumerator + + def p_declarator(self, p): + """ declarator : id_declarator + | typeid_declarator + """ + p[0] = p[1] + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_xxx_declarator_1(self, p): + """ xxx_declarator : direct_xxx_declarator + """ + p[0] = p[1] + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_xxx_declarator_2(self, p): + """ xxx_declarator : pointer direct_xxx_declarator + """ + p[0] = self._type_modify_decl(p[2], p[1]) + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_direct_xxx_declarator_1(self, p): + """ direct_xxx_declarator : yyy + """ + p[0] = c_ast.TypeDecl( + declname=p[1], + type=None, + quals=None, + align=None, + coord=self._token_coord(p, 1)) + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID')) + def p_direct_xxx_declarator_2(self, p): + """ direct_xxx_declarator : LPAREN xxx_declarator RPAREN + """ + p[0] = p[2] + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_direct_xxx_declarator_3(self, p): + """ direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET + """ + quals = (p[3] if len(p) > 5 else []) or [] + # Accept dimension qualifiers + # Per C99 6.7.5.3 p7 + arr = c_ast.ArrayDecl( + type=None, + dim=p[4] if len(p) > 5 else p[3], + dim_quals=quals, + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_direct_xxx_declarator_4(self, p): + """ direct_xxx_declarator : direct_xxx_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET + | direct_xxx_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET + """ + # Using slice notation for PLY objects doesn't work in Python 3 for the + # version of PLY embedded with pycparser; see PLY Google Code issue 30. + # Work around that here by listing the two elements separately. + listed_quals = [item if isinstance(item, list) else [item] + for item in [p[3],p[4]]] + dim_quals = [qual for sublist in listed_quals for qual in sublist + if qual is not None] + arr = c_ast.ArrayDecl( + type=None, + dim=p[5], + dim_quals=dim_quals, + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + # Special for VLAs + # + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_direct_xxx_declarator_5(self, p): + """ direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET + """ + arr = c_ast.ArrayDecl( + type=None, + dim=c_ast.ID(p[4], self._token_coord(p, 4)), + dim_quals=p[3] if p[3] is not None else [], + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID')) + def p_direct_xxx_declarator_6(self, p): + """ direct_xxx_declarator : direct_xxx_declarator LPAREN parameter_type_list RPAREN + | direct_xxx_declarator LPAREN identifier_list_opt RPAREN + """ + func = c_ast.FuncDecl( + args=p[3], + type=None, + coord=p[1].coord) + + # To see why _get_yacc_lookahead_token is needed, consider: + # typedef char TT; + # void foo(int TT) { TT = 10; } + # Outside the function, TT is a typedef, but inside (starting and + # ending with the braces) it's a parameter. The trouble begins with + # yacc's lookahead token. We don't know if we're declaring or + # defining a function until we see LBRACE, but if we wait for yacc to + # trigger a rule on that token, then TT will have already been read + # and incorrectly interpreted as TYPEID. We need to add the + # parameters to the scope the moment the lexer sees LBRACE. + # + if self._get_yacc_lookahead_token().type == "LBRACE": + if func.args is not None: + for param in func.args.params: + if isinstance(param, c_ast.EllipsisParam): break + self._add_identifier(param.name, param.coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=func) + + def p_pointer(self, p): + """ pointer : TIMES type_qualifier_list_opt + | TIMES type_qualifier_list_opt pointer + """ + coord = self._token_coord(p, 1) + # Pointer decls nest from inside out. This is important when different + # levels have different qualifiers. For example: + # + # char * const * p; + # + # Means "pointer to const pointer to char" + # + # While: + # + # char ** const p; + # + # Means "const pointer to pointer to char" + # + # So when we construct PtrDecl nestings, the leftmost pointer goes in + # as the most nested type. + nested_type = c_ast.PtrDecl(quals=p[2] or [], type=None, coord=coord) + if len(p) > 3: + tail_type = p[3] + while tail_type.type is not None: + tail_type = tail_type.type + tail_type.type = nested_type + p[0] = p[3] + else: + p[0] = nested_type + + def p_type_qualifier_list(self, p): + """ type_qualifier_list : type_qualifier + | type_qualifier_list type_qualifier + """ + p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]] + + def p_parameter_type_list(self, p): + """ parameter_type_list : parameter_list + | parameter_list COMMA ELLIPSIS + """ + if len(p) > 2: + p[1].params.append(c_ast.EllipsisParam(self._token_coord(p, 3))) + + p[0] = p[1] + + def p_parameter_list(self, p): + """ parameter_list : parameter_declaration + | parameter_list COMMA parameter_declaration + """ + if len(p) == 2: # single parameter + p[0] = c_ast.ParamList([p[1]], p[1].coord) + else: + p[1].params.append(p[3]) + p[0] = p[1] + + # From ISO/IEC 9899:TC2, 6.7.5.3.11: + # "If, in a parameter declaration, an identifier can be treated either + # as a typedef name or as a parameter name, it shall be taken as a + # typedef name." + # + # Inside a parameter declaration, once we've reduced declaration specifiers, + # if we shift in an LPAREN and see a TYPEID, it could be either an abstract + # declarator or a declarator nested inside parens. This rule tells us to + # always treat it as an abstract declarator. Therefore, we only accept + # `id_declarator`s and `typeid_noparen_declarator`s. + def p_parameter_declaration_1(self, p): + """ parameter_declaration : declaration_specifiers id_declarator + | declaration_specifiers typeid_noparen_declarator + """ + spec = p[1] + if not spec['type']: + spec['type'] = [c_ast.IdentifierType(['int'], + coord=self._token_coord(p, 1))] + p[0] = self._build_declarations( + spec=spec, + decls=[dict(decl=p[2])])[0] + + def p_parameter_declaration_2(self, p): + """ parameter_declaration : declaration_specifiers abstract_declarator_opt + """ + spec = p[1] + if not spec['type']: + spec['type'] = [c_ast.IdentifierType(['int'], + coord=self._token_coord(p, 1))] + + # Parameters can have the same names as typedefs. The trouble is that + # the parameter's name gets grouped into declaration_specifiers, making + # it look like an old-style declaration; compensate. + # + if len(spec['type']) > 1 and len(spec['type'][-1].names) == 1 and \ + self._is_type_in_scope(spec['type'][-1].names[0]): + decl = self._build_declarations( + spec=spec, + decls=[dict(decl=p[2], init=None)])[0] + + # This truly is an old-style parameter declaration + # + else: + decl = c_ast.Typename( + name='', + quals=spec['qual'], + align=None, + type=p[2] or c_ast.TypeDecl(None, None, None, None), + coord=self._token_coord(p, 2)) + typename = spec['type'] + decl = self._fix_decl_name_type(decl, typename) + + p[0] = decl + + def p_identifier_list(self, p): + """ identifier_list : identifier + | identifier_list COMMA identifier + """ + if len(p) == 2: # single parameter + p[0] = c_ast.ParamList([p[1]], p[1].coord) + else: + p[1].params.append(p[3]) + p[0] = p[1] + + def p_initializer_1(self, p): + """ initializer : assignment_expression + """ + p[0] = p[1] + + def p_initializer_2(self, p): + """ initializer : brace_open initializer_list_opt brace_close + | brace_open initializer_list COMMA brace_close + """ + if p[2] is None: + p[0] = c_ast.InitList([], self._token_coord(p, 1)) + else: + p[0] = p[2] + + def p_initializer_list(self, p): + """ initializer_list : designation_opt initializer + | initializer_list COMMA designation_opt initializer + """ + if len(p) == 3: # single initializer + init = p[2] if p[1] is None else c_ast.NamedInitializer(p[1], p[2]) + p[0] = c_ast.InitList([init], p[2].coord) + else: + init = p[4] if p[3] is None else c_ast.NamedInitializer(p[3], p[4]) + p[1].exprs.append(init) + p[0] = p[1] + + def p_designation(self, p): + """ designation : designator_list EQUALS + """ + p[0] = p[1] + + # Designators are represented as a list of nodes, in the order in which + # they're written in the code. + # + def p_designator_list(self, p): + """ designator_list : designator + | designator_list designator + """ + p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]] + + def p_designator(self, p): + """ designator : LBRACKET constant_expression RBRACKET + | PERIOD identifier + """ + p[0] = p[2] + + def p_type_name(self, p): + """ type_name : specifier_qualifier_list abstract_declarator_opt + """ + typename = c_ast.Typename( + name='', + quals=p[1]['qual'][:], + align=None, + type=p[2] or c_ast.TypeDecl(None, None, None, None), + coord=self._token_coord(p, 2)) + + p[0] = self._fix_decl_name_type(typename, p[1]['type']) + + def p_abstract_declarator_1(self, p): + """ abstract_declarator : pointer + """ + dummytype = c_ast.TypeDecl(None, None, None, None) + p[0] = self._type_modify_decl( + decl=dummytype, + modifier=p[1]) + + def p_abstract_declarator_2(self, p): + """ abstract_declarator : pointer direct_abstract_declarator + """ + p[0] = self._type_modify_decl(p[2], p[1]) + + def p_abstract_declarator_3(self, p): + """ abstract_declarator : direct_abstract_declarator + """ + p[0] = p[1] + + # Creating and using direct_abstract_declarator_opt here + # instead of listing both direct_abstract_declarator and the + # lack of it in the beginning of _1 and _2 caused two + # shift/reduce errors. + # + def p_direct_abstract_declarator_1(self, p): + """ direct_abstract_declarator : LPAREN abstract_declarator RPAREN """ + p[0] = p[2] + + def p_direct_abstract_declarator_2(self, p): + """ direct_abstract_declarator : direct_abstract_declarator LBRACKET assignment_expression_opt RBRACKET + """ + arr = c_ast.ArrayDecl( + type=None, + dim=p[3], + dim_quals=[], + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + def p_direct_abstract_declarator_3(self, p): + """ direct_abstract_declarator : LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET + """ + quals = (p[2] if len(p) > 4 else []) or [] + p[0] = c_ast.ArrayDecl( + type=c_ast.TypeDecl(None, None, None, None), + dim=p[3] if len(p) > 4 else p[2], + dim_quals=quals, + coord=self._token_coord(p, 1)) + + def p_direct_abstract_declarator_4(self, p): + """ direct_abstract_declarator : direct_abstract_declarator LBRACKET TIMES RBRACKET + """ + arr = c_ast.ArrayDecl( + type=None, + dim=c_ast.ID(p[3], self._token_coord(p, 3)), + dim_quals=[], + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + def p_direct_abstract_declarator_5(self, p): + """ direct_abstract_declarator : LBRACKET TIMES RBRACKET + """ + p[0] = c_ast.ArrayDecl( + type=c_ast.TypeDecl(None, None, None, None), + dim=c_ast.ID(p[3], self._token_coord(p, 3)), + dim_quals=[], + coord=self._token_coord(p, 1)) + + def p_direct_abstract_declarator_6(self, p): + """ direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN + """ + func = c_ast.FuncDecl( + args=p[3], + type=None, + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=func) + + def p_direct_abstract_declarator_7(self, p): + """ direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN + """ + p[0] = c_ast.FuncDecl( + args=p[2], + type=c_ast.TypeDecl(None, None, None, None), + coord=self._token_coord(p, 1)) + + # declaration is a list, statement isn't. To make it consistent, block_item + # will always be a list + # + def p_block_item(self, p): + """ block_item : declaration + | statement + """ + p[0] = p[1] if isinstance(p[1], list) else [p[1]] + + # Since we made block_item a list, this just combines lists + # + def p_block_item_list(self, p): + """ block_item_list : block_item + | block_item_list block_item + """ + # Empty block items (plain ';') produce [None], so ignore them + p[0] = p[1] if (len(p) == 2 or p[2] == [None]) else p[1] + p[2] + + def p_compound_statement_1(self, p): + """ compound_statement : brace_open block_item_list_opt brace_close """ + p[0] = c_ast.Compound( + block_items=p[2], + coord=self._token_coord(p, 1)) + + def p_labeled_statement_1(self, p): + """ labeled_statement : ID COLON pragmacomp_or_statement """ + p[0] = c_ast.Label(p[1], p[3], self._token_coord(p, 1)) + + def p_labeled_statement_2(self, p): + """ labeled_statement : CASE constant_expression COLON pragmacomp_or_statement """ + p[0] = c_ast.Case(p[2], [p[4]], self._token_coord(p, 1)) + + def p_labeled_statement_3(self, p): + """ labeled_statement : DEFAULT COLON pragmacomp_or_statement """ + p[0] = c_ast.Default([p[3]], self._token_coord(p, 1)) + + def p_selection_statement_1(self, p): + """ selection_statement : IF LPAREN expression RPAREN pragmacomp_or_statement """ + p[0] = c_ast.If(p[3], p[5], None, self._token_coord(p, 1)) + + def p_selection_statement_2(self, p): + """ selection_statement : IF LPAREN expression RPAREN statement ELSE pragmacomp_or_statement """ + p[0] = c_ast.If(p[3], p[5], p[7], self._token_coord(p, 1)) + + def p_selection_statement_3(self, p): + """ selection_statement : SWITCH LPAREN expression RPAREN pragmacomp_or_statement """ + p[0] = fix_switch_cases( + c_ast.Switch(p[3], p[5], self._token_coord(p, 1))) + + def p_iteration_statement_1(self, p): + """ iteration_statement : WHILE LPAREN expression RPAREN pragmacomp_or_statement """ + p[0] = c_ast.While(p[3], p[5], self._token_coord(p, 1)) + + def p_iteration_statement_2(self, p): + """ iteration_statement : DO pragmacomp_or_statement WHILE LPAREN expression RPAREN SEMI """ + p[0] = c_ast.DoWhile(p[5], p[2], self._token_coord(p, 1)) + + def p_iteration_statement_3(self, p): + """ iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """ + p[0] = c_ast.For(p[3], p[5], p[7], p[9], self._token_coord(p, 1)) + + def p_iteration_statement_4(self, p): + """ iteration_statement : FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """ + p[0] = c_ast.For(c_ast.DeclList(p[3], self._token_coord(p, 1)), + p[4], p[6], p[8], self._token_coord(p, 1)) + + def p_jump_statement_1(self, p): + """ jump_statement : GOTO ID SEMI """ + p[0] = c_ast.Goto(p[2], self._token_coord(p, 1)) + + def p_jump_statement_2(self, p): + """ jump_statement : BREAK SEMI """ + p[0] = c_ast.Break(self._token_coord(p, 1)) + + def p_jump_statement_3(self, p): + """ jump_statement : CONTINUE SEMI """ + p[0] = c_ast.Continue(self._token_coord(p, 1)) + + def p_jump_statement_4(self, p): + """ jump_statement : RETURN expression SEMI + | RETURN SEMI + """ + p[0] = c_ast.Return(p[2] if len(p) == 4 else None, self._token_coord(p, 1)) + + def p_expression_statement(self, p): + """ expression_statement : expression_opt SEMI """ + if p[1] is None: + p[0] = c_ast.EmptyStatement(self._token_coord(p, 2)) + else: + p[0] = p[1] + + def p_expression(self, p): + """ expression : assignment_expression + | expression COMMA assignment_expression + """ + if len(p) == 2: + p[0] = p[1] + else: + if not isinstance(p[1], c_ast.ExprList): + p[1] = c_ast.ExprList([p[1]], p[1].coord) + + p[1].exprs.append(p[3]) + p[0] = p[1] + + def p_parenthesized_compound_expression(self, p): + """ assignment_expression : LPAREN compound_statement RPAREN """ + p[0] = p[2] + + def p_typedef_name(self, p): + """ typedef_name : TYPEID """ + p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1)) + + def p_assignment_expression(self, p): + """ assignment_expression : conditional_expression + | unary_expression assignment_operator assignment_expression + """ + if len(p) == 2: + p[0] = p[1] + else: + p[0] = c_ast.Assignment(p[2], p[1], p[3], p[1].coord) + + # K&R2 defines these as many separate rules, to encode + # precedence and associativity. Why work hard ? I'll just use + # the built in precedence/associativity specification feature + # of PLY. (see precedence declaration above) + # + def p_assignment_operator(self, p): + """ assignment_operator : EQUALS + | XOREQUAL + | TIMESEQUAL + | DIVEQUAL + | MODEQUAL + | PLUSEQUAL + | MINUSEQUAL + | LSHIFTEQUAL + | RSHIFTEQUAL + | ANDEQUAL + | OREQUAL + """ + p[0] = p[1] + + def p_constant_expression(self, p): + """ constant_expression : conditional_expression """ + p[0] = p[1] + + def p_conditional_expression(self, p): + """ conditional_expression : binary_expression + | binary_expression CONDOP expression COLON conditional_expression + """ + if len(p) == 2: + p[0] = p[1] + else: + p[0] = c_ast.TernaryOp(p[1], p[3], p[5], p[1].coord) + + def p_binary_expression(self, p): + """ binary_expression : cast_expression + | binary_expression TIMES binary_expression + | binary_expression DIVIDE binary_expression + | binary_expression MOD binary_expression + | binary_expression PLUS binary_expression + | binary_expression MINUS binary_expression + | binary_expression RSHIFT binary_expression + | binary_expression LSHIFT binary_expression + | binary_expression LT binary_expression + | binary_expression LE binary_expression + | binary_expression GE binary_expression + | binary_expression GT binary_expression + | binary_expression EQ binary_expression + | binary_expression NE binary_expression + | binary_expression AND binary_expression + | binary_expression OR binary_expression + | binary_expression XOR binary_expression + | binary_expression LAND binary_expression + | binary_expression LOR binary_expression + """ + if len(p) == 2: + p[0] = p[1] + else: + p[0] = c_ast.BinaryOp(p[2], p[1], p[3], p[1].coord) + + def p_cast_expression_1(self, p): + """ cast_expression : unary_expression """ + p[0] = p[1] + + def p_cast_expression_2(self, p): + """ cast_expression : LPAREN type_name RPAREN cast_expression """ + p[0] = c_ast.Cast(p[2], p[4], self._token_coord(p, 1)) + + def p_unary_expression_1(self, p): + """ unary_expression : postfix_expression """ + p[0] = p[1] + + def p_unary_expression_2(self, p): + """ unary_expression : PLUSPLUS unary_expression + | MINUSMINUS unary_expression + | unary_operator cast_expression + """ + p[0] = c_ast.UnaryOp(p[1], p[2], p[2].coord) + + def p_unary_expression_3(self, p): + """ unary_expression : SIZEOF unary_expression + | SIZEOF LPAREN type_name RPAREN + | _ALIGNOF LPAREN type_name RPAREN + """ + p[0] = c_ast.UnaryOp( + p[1], + p[2] if len(p) == 3 else p[3], + self._token_coord(p, 1)) + + def p_unary_operator(self, p): + """ unary_operator : AND + | TIMES + | PLUS + | MINUS + | NOT + | LNOT + """ + p[0] = p[1] + + def p_postfix_expression_1(self, p): + """ postfix_expression : primary_expression """ + p[0] = p[1] + + def p_postfix_expression_2(self, p): + """ postfix_expression : postfix_expression LBRACKET expression RBRACKET """ + p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord) + + def p_postfix_expression_3(self, p): + """ postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN + | postfix_expression LPAREN RPAREN + """ + p[0] = c_ast.FuncCall(p[1], p[3] if len(p) == 5 else None, p[1].coord) + + def p_postfix_expression_4(self, p): + """ postfix_expression : postfix_expression PERIOD ID + | postfix_expression PERIOD TYPEID + | postfix_expression ARROW ID + | postfix_expression ARROW TYPEID + """ + field = c_ast.ID(p[3], self._token_coord(p, 3)) + p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord) + + def p_postfix_expression_5(self, p): + """ postfix_expression : postfix_expression PLUSPLUS + | postfix_expression MINUSMINUS + """ + p[0] = c_ast.UnaryOp('p' + p[2], p[1], p[1].coord) + + def p_postfix_expression_6(self, p): + """ postfix_expression : LPAREN type_name RPAREN brace_open initializer_list brace_close + | LPAREN type_name RPAREN brace_open initializer_list COMMA brace_close + """ + p[0] = c_ast.CompoundLiteral(p[2], p[5]) + + def p_primary_expression_1(self, p): + """ primary_expression : identifier """ + p[0] = p[1] + + def p_primary_expression_2(self, p): + """ primary_expression : constant """ + p[0] = p[1] + + def p_primary_expression_3(self, p): + """ primary_expression : unified_string_literal + | unified_wstring_literal + """ + p[0] = p[1] + + def p_primary_expression_4(self, p): + """ primary_expression : LPAREN expression RPAREN """ + p[0] = p[2] + + def p_primary_expression_5(self, p): + """ primary_expression : OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN + """ + coord = self._token_coord(p, 1) + p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord), + c_ast.ExprList([p[3], p[5]], coord), + coord) + + def p_offsetof_member_designator(self, p): + """ offsetof_member_designator : identifier + | offsetof_member_designator PERIOD identifier + | offsetof_member_designator LBRACKET expression RBRACKET + """ + if len(p) == 2: + p[0] = p[1] + elif len(p) == 4: + p[0] = c_ast.StructRef(p[1], p[2], p[3], p[1].coord) + elif len(p) == 5: + p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord) + else: + raise NotImplementedError("Unexpected parsing state. len(p): %u" % len(p)) + + def p_argument_expression_list(self, p): + """ argument_expression_list : assignment_expression + | argument_expression_list COMMA assignment_expression + """ + if len(p) == 2: # single expr + p[0] = c_ast.ExprList([p[1]], p[1].coord) + else: + p[1].exprs.append(p[3]) + p[0] = p[1] + + def p_identifier(self, p): + """ identifier : ID """ + p[0] = c_ast.ID(p[1], self._token_coord(p, 1)) + + def p_constant_1(self, p): + """ constant : INT_CONST_DEC + | INT_CONST_OCT + | INT_CONST_HEX + | INT_CONST_BIN + | INT_CONST_CHAR + """ + uCount = 0 + lCount = 0 + for x in p[1][-3:]: + if x in ('l', 'L'): + lCount += 1 + elif x in ('u', 'U'): + uCount += 1 + t = '' + if uCount > 1: + raise ValueError('Constant cannot have more than one u/U suffix.') + elif lCount > 2: + raise ValueError('Constant cannot have more than two l/L suffix.') + prefix = 'unsigned ' * uCount + 'long ' * lCount + p[0] = c_ast.Constant( + prefix + 'int', p[1], self._token_coord(p, 1)) + + def p_constant_2(self, p): + """ constant : FLOAT_CONST + | HEX_FLOAT_CONST + """ + if 'x' in p[1].lower(): + t = 'float' + else: + if p[1][-1] in ('f', 'F'): + t = 'float' + elif p[1][-1] in ('l', 'L'): + t = 'long double' + else: + t = 'double' + + p[0] = c_ast.Constant( + t, p[1], self._token_coord(p, 1)) + + def p_constant_3(self, p): + """ constant : CHAR_CONST + | WCHAR_CONST + | U8CHAR_CONST + | U16CHAR_CONST + | U32CHAR_CONST + """ + p[0] = c_ast.Constant( + 'char', p[1], self._token_coord(p, 1)) + + # The "unified" string and wstring literal rules are for supporting + # concatenation of adjacent string literals. + # I.e. "hello " "world" is seen by the C compiler as a single string literal + # with the value "hello world" + # + def p_unified_string_literal(self, p): + """ unified_string_literal : STRING_LITERAL + | unified_string_literal STRING_LITERAL + """ + if len(p) == 2: # single literal + p[0] = c_ast.Constant( + 'string', p[1], self._token_coord(p, 1)) + else: + p[1].value = p[1].value[:-1] + p[2][1:] + p[0] = p[1] + + def p_unified_wstring_literal(self, p): + """ unified_wstring_literal : WSTRING_LITERAL + | U8STRING_LITERAL + | U16STRING_LITERAL + | U32STRING_LITERAL + | unified_wstring_literal WSTRING_LITERAL + | unified_wstring_literal U8STRING_LITERAL + | unified_wstring_literal U16STRING_LITERAL + | unified_wstring_literal U32STRING_LITERAL + """ + if len(p) == 2: # single literal + p[0] = c_ast.Constant( + 'string', p[1], self._token_coord(p, 1)) + else: + p[1].value = p[1].value.rstrip()[:-1] + p[2][2:] + p[0] = p[1] + + def p_brace_open(self, p): + """ brace_open : LBRACE + """ + p[0] = p[1] + p.set_lineno(0, p.lineno(1)) + + def p_brace_close(self, p): + """ brace_close : RBRACE + """ + p[0] = p[1] + p.set_lineno(0, p.lineno(1)) + + def p_empty(self, p): + 'empty : ' + p[0] = None + + def p_error(self, p): + # If error recovery is added here in the future, make sure + # _get_yacc_lookahead_token still works! + # + if p: + self._parse_error( + 'before: %s' % p.value, + self._coord(lineno=p.lineno, + column=self.clex.find_tok_column(p))) + else: + self._parse_error('At end of input', self.clex.filename) diff --git a/uno/lib/python/pycparser/lextab.py b/uno/lib/python/pycparser/lextab.py new file mode 100644 index 00000000..444b4656 --- /dev/null +++ b/uno/lib/python/pycparser/lextab.py @@ -0,0 +1,10 @@ +# lextab.py. This file automatically created by PLY (version 3.10). Don't edit! +_tabversion = '3.10' +_lextokens = set(('INT_CONST_CHAR', 'VOID', 'LBRACKET', 'WCHAR_CONST', 'FLOAT_CONST', 'MINUS', 'RPAREN', 'STRUCT', 'LONG', 'PLUS', 'ELLIPSIS', 'U32STRING_LITERAL', 'GT', 'GOTO', 'ENUM', 'PERIOD', 'GE', 'INT_CONST_DEC', 'ARROW', '_STATIC_ASSERT', '__INT128', 'HEX_FLOAT_CONST', 'DOUBLE', 'MINUSEQUAL', 'INT_CONST_OCT', 'TIMESEQUAL', 'OR', 'SHORT', 'RETURN', 'RSHIFTEQUAL', '_ALIGNAS', 'RESTRICT', 'STATIC', 'SIZEOF', 'UNSIGNED', 'PLUSPLUS', 'COLON', 'WSTRING_LITERAL', 'DIVIDE', 'FOR', 'UNION', 'EQUALS', 'ELSE', 'ANDEQUAL', 'EQ', 'AND', 'TYPEID', 'LBRACE', 'PPHASH', 'INT', 'SIGNED', 'CONTINUE', 'NOT', 'OREQUAL', 'MOD', 'RSHIFT', 'DEFAULT', '_NORETURN', 'CHAR', 'WHILE', 'DIVEQUAL', '_ALIGNOF', 'EXTERN', 'LNOT', 'CASE', 'LAND', 'REGISTER', 'MODEQUAL', 'NE', 'SWITCH', 'INT_CONST_HEX', '_COMPLEX', 'PPPRAGMASTR', 'PLUSEQUAL', 'U32CHAR_CONST', 'CONDOP', 'U8STRING_LITERAL', 'BREAK', 'VOLATILE', 'PPPRAGMA', 'INLINE', 'INT_CONST_BIN', 'DO', 'U8CHAR_CONST', 'CONST', 'U16STRING_LITERAL', 'LOR', 'CHAR_CONST', 'LSHIFT', 'RBRACE', '_BOOL', 'LE', 'SEMI', '_THREAD_LOCAL', 'LT', 'COMMA', 'U16CHAR_CONST', 'OFFSETOF', '_ATOMIC', 'TYPEDEF', 'XOR', 'AUTO', 'TIMES', 'LPAREN', 'MINUSMINUS', 'ID', 'IF', 'STRING_LITERAL', 'FLOAT', 'XOREQUAL', 'LSHIFTEQUAL', 'RBRACKET')) +_lexreflags = 64 +_lexliterals = '' +_lexstateinfo = {'ppline': 'exclusive', 'pppragma': 'exclusive', 'INITIAL': 'inclusive'} +_lexstatere = {'ppline': [('(?P"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P(0(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|([1-9][0-9]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?))|(?P\\n)|(?Pline)', [None, ('t_ppline_FILENAME', 'FILENAME'), None, None, ('t_ppline_LINE_NUMBER', 'LINE_NUMBER'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_ppline_NEWLINE', 'NEWLINE'), ('t_ppline_PPLINE', 'PPLINE')])], 'pppragma': [('(?P\\n)|(?Ppragma)|(?P.+)', [None, ('t_pppragma_NEWLINE', 'NEWLINE'), ('t_pppragma_PPPRAGMA', 'PPPRAGMA'), ('t_pppragma_STR', 'STR')])], 'INITIAL': [('(?P[ \\t]*\\#)|(?P\\n+)|(?P\\{)|(?P\\})|(?P((((([0-9]*\\.[0-9]+)|([0-9]+\\.))([eE][-+]?[0-9]+)?)|([0-9]+([eE][-+]?[0-9]+)))[FfLl]?))|(?P(0[xX]([0-9a-fA-F]+|((([0-9a-fA-F]+)?\\.[0-9a-fA-F]+)|([0-9a-fA-F]+\\.)))([pP][+-]?[0-9]+)[FfLl]?))|(?P0[xX][0-9a-fA-F]+(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|(?P0[bB][01]+(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)', [None, ('t_PPHASH', 'PPHASH'), ('t_NEWLINE', 'NEWLINE'), ('t_LBRACE', 'LBRACE'), ('t_RBRACE', 'RBRACE'), ('t_FLOAT_CONST', 'FLOAT_CONST'), None, None, None, None, None, None, None, None, None, ('t_HEX_FLOAT_CONST', 'HEX_FLOAT_CONST'), None, None, None, None, None, None, None, ('t_INT_CONST_HEX', 'INT_CONST_HEX'), None, None, None, None, None, None, None, ('t_INT_CONST_BIN', 'INT_CONST_BIN')]), ('(?P0[0-7]*[89])|(?P0[0-7]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|(?P(0(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|([1-9][0-9]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?))|(?P\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F])))){2,4}\')|(?P\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?PL\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?Pu8\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?Pu\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?PU\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')', [None, ('t_BAD_CONST_OCT', 'BAD_CONST_OCT'), ('t_INT_CONST_OCT', 'INT_CONST_OCT'), None, None, None, None, None, None, None, ('t_INT_CONST_DEC', 'INT_CONST_DEC'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_INT_CONST_CHAR', 'INT_CONST_CHAR'), None, None, None, None, None, None, ('t_CHAR_CONST', 'CHAR_CONST'), None, None, None, None, None, None, ('t_WCHAR_CONST', 'WCHAR_CONST'), None, None, None, None, None, None, ('t_U8CHAR_CONST', 'U8CHAR_CONST'), None, None, None, None, None, None, ('t_U16CHAR_CONST', 'U16CHAR_CONST'), None, None, None, None, None, None, ('t_U32CHAR_CONST', 'U32CHAR_CONST')]), ('(?P(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))*\\n)|(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))*$))|(?P(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))[^\'\n]+\')|(\'\')|(\'([\\\\][^a-zA-Z._~^!=&\\^\\-\\\\?\'"x0-9])[^\'\\n]*\'))|(?PL"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?Pu8"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?Pu"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?PU"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*([\\\\][^a-zA-Z._~^!=&\\^\\-\\\\?\'"x0-9])([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P[a-zA-Z_$][0-9a-zA-Z_$]*)|(?P"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P\\.\\.\\.)|(?P\\+\\+)|(?P\\|\\|)|(?P\\^=)|(?P\\|=)|(?P<<=)|(?P>>=)|(?P\\+=)|(?P\\*=)', [None, ('t_UNMATCHED_QUOTE', 'UNMATCHED_QUOTE'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_BAD_CHAR_CONST', 'BAD_CHAR_CONST'), None, None, None, None, None, None, None, None, None, None, ('t_WSTRING_LITERAL', 'WSTRING_LITERAL'), None, None, ('t_U8STRING_LITERAL', 'U8STRING_LITERAL'), None, None, ('t_U16STRING_LITERAL', 'U16STRING_LITERAL'), None, None, ('t_U32STRING_LITERAL', 'U32STRING_LITERAL'), None, None, ('t_BAD_STRING_LITERAL', 'BAD_STRING_LITERAL'), None, None, None, None, None, ('t_ID', 'ID'), (None, 'STRING_LITERAL'), None, None, (None, 'ELLIPSIS'), (None, 'PLUSPLUS'), (None, 'LOR'), (None, 'XOREQUAL'), (None, 'OREQUAL'), (None, 'LSHIFTEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'PLUSEQUAL'), (None, 'TIMESEQUAL')]), ('(?P\\+)|(?P%=)|(?P/=)|(?P\\])|(?P\\?)|(?P\\^)|(?P<<)|(?P<=)|(?P\\()|(?P->)|(?P==)|(?P!=)|(?P--)|(?P\\|)|(?P\\*)|(?P\\[)|(?P>=)|(?P\\))|(?P&&)|(?P>>)|(?P-=)|(?P\\.)|(?P&=)|(?P=)|(?P<)|(?P,)|(?P/)|(?P&)|(?P%)|(?P;)|(?P-)|(?P>)|(?P:)|(?P~)|(?P!)', [None, (None, 'PLUS'), (None, 'MODEQUAL'), (None, 'DIVEQUAL'), (None, 'RBRACKET'), (None, 'CONDOP'), (None, 'XOR'), (None, 'LSHIFT'), (None, 'LE'), (None, 'LPAREN'), (None, 'ARROW'), (None, 'EQ'), (None, 'NE'), (None, 'MINUSMINUS'), (None, 'OR'), (None, 'TIMES'), (None, 'LBRACKET'), (None, 'GE'), (None, 'RPAREN'), (None, 'LAND'), (None, 'RSHIFT'), (None, 'MINUSEQUAL'), (None, 'PERIOD'), (None, 'ANDEQUAL'), (None, 'EQUALS'), (None, 'LT'), (None, 'COMMA'), (None, 'DIVIDE'), (None, 'AND'), (None, 'MOD'), (None, 'SEMI'), (None, 'MINUS'), (None, 'GT'), (None, 'COLON'), (None, 'NOT'), (None, 'LNOT')])]} +_lexstateignore = {'ppline': ' \t', 'pppragma': ' \t', 'INITIAL': ' \t'} +_lexstateerrorf = {'ppline': 't_ppline_error', 'pppragma': 't_pppragma_error', 'INITIAL': 't_error'} +_lexstateeoff = {} diff --git a/uno/lib/python/pycparser/ply/__init__.py b/uno/lib/python/pycparser/ply/__init__.py new file mode 100644 index 00000000..6e53cddc --- /dev/null +++ b/uno/lib/python/pycparser/ply/__init__.py @@ -0,0 +1,5 @@ +# PLY package +# Author: David Beazley (dave@dabeaz.com) + +__version__ = '3.9' +__all__ = ['lex','yacc'] diff --git a/uno/lib/python/pycparser/ply/cpp.py b/uno/lib/python/pycparser/ply/cpp.py new file mode 100644 index 00000000..86273eac --- /dev/null +++ b/uno/lib/python/pycparser/ply/cpp.py @@ -0,0 +1,905 @@ +# ----------------------------------------------------------------------------- +# cpp.py +# +# Author: David Beazley (http://www.dabeaz.com) +# Copyright (C) 2017 +# All rights reserved +# +# This module implements an ANSI-C style lexical preprocessor for PLY. +# ----------------------------------------------------------------------------- +import sys + +# Some Python 3 compatibility shims +if sys.version_info.major < 3: + STRING_TYPES = (str, unicode) +else: + STRING_TYPES = str + xrange = range + +# ----------------------------------------------------------------------------- +# Default preprocessor lexer definitions. These tokens are enough to get +# a basic preprocessor working. Other modules may import these if they want +# ----------------------------------------------------------------------------- + +tokens = ( + 'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT1', 'CPP_COMMENT2', 'CPP_POUND','CPP_DPOUND' +) + +literals = "+-*/%|&~^<>=!?()[]{}.,;:\\\'\"" + +# Whitespace +def t_CPP_WS(t): + r'\s+' + t.lexer.lineno += t.value.count("\n") + return t + +t_CPP_POUND = r'\#' +t_CPP_DPOUND = r'\#\#' + +# Identifier +t_CPP_ID = r'[A-Za-z_][\w_]*' + +# Integer literal +def CPP_INTEGER(t): + r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)' + return t + +t_CPP_INTEGER = CPP_INTEGER + +# Floating literal +t_CPP_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?' + +# String literal +def t_CPP_STRING(t): + r'\"([^\\\n]|(\\(.|\n)))*?\"' + t.lexer.lineno += t.value.count("\n") + return t + +# Character constant 'c' or L'c' +def t_CPP_CHAR(t): + r'(L)?\'([^\\\n]|(\\(.|\n)))*?\'' + t.lexer.lineno += t.value.count("\n") + return t + +# Comment +def t_CPP_COMMENT1(t): + r'(/\*(.|\n)*?\*/)' + ncr = t.value.count("\n") + t.lexer.lineno += ncr + # replace with one space or a number of '\n' + t.type = 'CPP_WS'; t.value = '\n' * ncr if ncr else ' ' + return t + +# Line comment +def t_CPP_COMMENT2(t): + r'(//.*?(\n|$))' + # replace with '/n' + t.type = 'CPP_WS'; t.value = '\n' + return t + +def t_error(t): + t.type = t.value[0] + t.value = t.value[0] + t.lexer.skip(1) + return t + +import re +import copy +import time +import os.path + +# ----------------------------------------------------------------------------- +# trigraph() +# +# Given an input string, this function replaces all trigraph sequences. +# The following mapping is used: +# +# ??= # +# ??/ \ +# ??' ^ +# ??( [ +# ??) ] +# ??! | +# ??< { +# ??> } +# ??- ~ +# ----------------------------------------------------------------------------- + +_trigraph_pat = re.compile(r'''\?\?[=/\'\(\)\!<>\-]''') +_trigraph_rep = { + '=':'#', + '/':'\\', + "'":'^', + '(':'[', + ')':']', + '!':'|', + '<':'{', + '>':'}', + '-':'~' +} + +def trigraph(input): + return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input) + +# ------------------------------------------------------------------ +# Macro object +# +# This object holds information about preprocessor macros +# +# .name - Macro name (string) +# .value - Macro value (a list of tokens) +# .arglist - List of argument names +# .variadic - Boolean indicating whether or not variadic macro +# .vararg - Name of the variadic parameter +# +# When a macro is created, the macro replacement token sequence is +# pre-scanned and used to create patch lists that are later used +# during macro expansion +# ------------------------------------------------------------------ + +class Macro(object): + def __init__(self,name,value,arglist=None,variadic=False): + self.name = name + self.value = value + self.arglist = arglist + self.variadic = variadic + if variadic: + self.vararg = arglist[-1] + self.source = None + +# ------------------------------------------------------------------ +# Preprocessor object +# +# Object representing a preprocessor. Contains macro definitions, +# include directories, and other information +# ------------------------------------------------------------------ + +class Preprocessor(object): + def __init__(self,lexer=None): + if lexer is None: + lexer = lex.lexer + self.lexer = lexer + self.macros = { } + self.path = [] + self.temp_path = [] + + # Probe the lexer for selected tokens + self.lexprobe() + + tm = time.localtime() + self.define("__DATE__ \"%s\"" % time.strftime("%b %d %Y",tm)) + self.define("__TIME__ \"%s\"" % time.strftime("%H:%M:%S",tm)) + self.parser = None + + # ----------------------------------------------------------------------------- + # tokenize() + # + # Utility function. Given a string of text, tokenize into a list of tokens + # ----------------------------------------------------------------------------- + + def tokenize(self,text): + tokens = [] + self.lexer.input(text) + while True: + tok = self.lexer.token() + if not tok: break + tokens.append(tok) + return tokens + + # --------------------------------------------------------------------- + # error() + # + # Report a preprocessor error/warning of some kind + # ---------------------------------------------------------------------- + + def error(self,file,line,msg): + print("%s:%d %s" % (file,line,msg)) + + # ---------------------------------------------------------------------- + # lexprobe() + # + # This method probes the preprocessor lexer object to discover + # the token types of symbols that are important to the preprocessor. + # If this works right, the preprocessor will simply "work" + # with any suitable lexer regardless of how tokens have been named. + # ---------------------------------------------------------------------- + + def lexprobe(self): + + # Determine the token type for identifiers + self.lexer.input("identifier") + tok = self.lexer.token() + if not tok or tok.value != "identifier": + print("Couldn't determine identifier type") + else: + self.t_ID = tok.type + + # Determine the token type for integers + self.lexer.input("12345") + tok = self.lexer.token() + if not tok or int(tok.value) != 12345: + print("Couldn't determine integer type") + else: + self.t_INTEGER = tok.type + self.t_INTEGER_TYPE = type(tok.value) + + # Determine the token type for strings enclosed in double quotes + self.lexer.input("\"filename\"") + tok = self.lexer.token() + if not tok or tok.value != "\"filename\"": + print("Couldn't determine string type") + else: + self.t_STRING = tok.type + + # Determine the token type for whitespace--if any + self.lexer.input(" ") + tok = self.lexer.token() + if not tok or tok.value != " ": + self.t_SPACE = None + else: + self.t_SPACE = tok.type + + # Determine the token type for newlines + self.lexer.input("\n") + tok = self.lexer.token() + if not tok or tok.value != "\n": + self.t_NEWLINE = None + print("Couldn't determine token for newlines") + else: + self.t_NEWLINE = tok.type + + self.t_WS = (self.t_SPACE, self.t_NEWLINE) + + # Check for other characters used by the preprocessor + chars = [ '<','>','#','##','\\','(',')',',','.'] + for c in chars: + self.lexer.input(c) + tok = self.lexer.token() + if not tok or tok.value != c: + print("Unable to lex '%s' required for preprocessor" % c) + + # ---------------------------------------------------------------------- + # add_path() + # + # Adds a search path to the preprocessor. + # ---------------------------------------------------------------------- + + def add_path(self,path): + self.path.append(path) + + # ---------------------------------------------------------------------- + # group_lines() + # + # Given an input string, this function splits it into lines. Trailing whitespace + # is removed. Any line ending with \ is grouped with the next line. This + # function forms the lowest level of the preprocessor---grouping into text into + # a line-by-line format. + # ---------------------------------------------------------------------- + + def group_lines(self,input): + lex = self.lexer.clone() + lines = [x.rstrip() for x in input.splitlines()] + for i in xrange(len(lines)): + j = i+1 + while lines[i].endswith('\\') and (j < len(lines)): + lines[i] = lines[i][:-1]+lines[j] + lines[j] = "" + j += 1 + + input = "\n".join(lines) + lex.input(input) + lex.lineno = 1 + + current_line = [] + while True: + tok = lex.token() + if not tok: + break + current_line.append(tok) + if tok.type in self.t_WS and '\n' in tok.value: + yield current_line + current_line = [] + + if current_line: + yield current_line + + # ---------------------------------------------------------------------- + # tokenstrip() + # + # Remove leading/trailing whitespace tokens from a token list + # ---------------------------------------------------------------------- + + def tokenstrip(self,tokens): + i = 0 + while i < len(tokens) and tokens[i].type in self.t_WS: + i += 1 + del tokens[:i] + i = len(tokens)-1 + while i >= 0 and tokens[i].type in self.t_WS: + i -= 1 + del tokens[i+1:] + return tokens + + + # ---------------------------------------------------------------------- + # collect_args() + # + # Collects comma separated arguments from a list of tokens. The arguments + # must be enclosed in parenthesis. Returns a tuple (tokencount,args,positions) + # where tokencount is the number of tokens consumed, args is a list of arguments, + # and positions is a list of integers containing the starting index of each + # argument. Each argument is represented by a list of tokens. + # + # When collecting arguments, leading and trailing whitespace is removed + # from each argument. + # + # This function properly handles nested parenthesis and commas---these do not + # define new arguments. + # ---------------------------------------------------------------------- + + def collect_args(self,tokenlist): + args = [] + positions = [] + current_arg = [] + nesting = 1 + tokenlen = len(tokenlist) + + # Search for the opening '('. + i = 0 + while (i < tokenlen) and (tokenlist[i].type in self.t_WS): + i += 1 + + if (i < tokenlen) and (tokenlist[i].value == '('): + positions.append(i+1) + else: + self.error(self.source,tokenlist[0].lineno,"Missing '(' in macro arguments") + return 0, [], [] + + i += 1 + + while i < tokenlen: + t = tokenlist[i] + if t.value == '(': + current_arg.append(t) + nesting += 1 + elif t.value == ')': + nesting -= 1 + if nesting == 0: + if current_arg: + args.append(self.tokenstrip(current_arg)) + positions.append(i) + return i+1,args,positions + current_arg.append(t) + elif t.value == ',' and nesting == 1: + args.append(self.tokenstrip(current_arg)) + positions.append(i+1) + current_arg = [] + else: + current_arg.append(t) + i += 1 + + # Missing end argument + self.error(self.source,tokenlist[-1].lineno,"Missing ')' in macro arguments") + return 0, [],[] + + # ---------------------------------------------------------------------- + # macro_prescan() + # + # Examine the macro value (token sequence) and identify patch points + # This is used to speed up macro expansion later on---we'll know + # right away where to apply patches to the value to form the expansion + # ---------------------------------------------------------------------- + + def macro_prescan(self,macro): + macro.patch = [] # Standard macro arguments + macro.str_patch = [] # String conversion expansion + macro.var_comma_patch = [] # Variadic macro comma patch + i = 0 + while i < len(macro.value): + if macro.value[i].type == self.t_ID and macro.value[i].value in macro.arglist: + argnum = macro.arglist.index(macro.value[i].value) + # Conversion of argument to a string + if i > 0 and macro.value[i-1].value == '#': + macro.value[i] = copy.copy(macro.value[i]) + macro.value[i].type = self.t_STRING + del macro.value[i-1] + macro.str_patch.append((argnum,i-1)) + continue + # Concatenation + elif (i > 0 and macro.value[i-1].value == '##'): + macro.patch.append(('c',argnum,i-1)) + del macro.value[i-1] + continue + elif ((i+1) < len(macro.value) and macro.value[i+1].value == '##'): + macro.patch.append(('c',argnum,i)) + i += 1 + continue + # Standard expansion + else: + macro.patch.append(('e',argnum,i)) + elif macro.value[i].value == '##': + if macro.variadic and (i > 0) and (macro.value[i-1].value == ',') and \ + ((i+1) < len(macro.value)) and (macro.value[i+1].type == self.t_ID) and \ + (macro.value[i+1].value == macro.vararg): + macro.var_comma_patch.append(i-1) + i += 1 + macro.patch.sort(key=lambda x: x[2],reverse=True) + + # ---------------------------------------------------------------------- + # macro_expand_args() + # + # Given a Macro and list of arguments (each a token list), this method + # returns an expanded version of a macro. The return value is a token sequence + # representing the replacement macro tokens + # ---------------------------------------------------------------------- + + def macro_expand_args(self,macro,args): + # Make a copy of the macro token sequence + rep = [copy.copy(_x) for _x in macro.value] + + # Make string expansion patches. These do not alter the length of the replacement sequence + + str_expansion = {} + for argnum, i in macro.str_patch: + if argnum not in str_expansion: + str_expansion[argnum] = ('"%s"' % "".join([x.value for x in args[argnum]])).replace("\\","\\\\") + rep[i] = copy.copy(rep[i]) + rep[i].value = str_expansion[argnum] + + # Make the variadic macro comma patch. If the variadic macro argument is empty, we get rid + comma_patch = False + if macro.variadic and not args[-1]: + for i in macro.var_comma_patch: + rep[i] = None + comma_patch = True + + # Make all other patches. The order of these matters. It is assumed that the patch list + # has been sorted in reverse order of patch location since replacements will cause the + # size of the replacement sequence to expand from the patch point. + + expanded = { } + for ptype, argnum, i in macro.patch: + # Concatenation. Argument is left unexpanded + if ptype == 'c': + rep[i:i+1] = args[argnum] + # Normal expansion. Argument is macro expanded first + elif ptype == 'e': + if argnum not in expanded: + expanded[argnum] = self.expand_macros(args[argnum]) + rep[i:i+1] = expanded[argnum] + + # Get rid of removed comma if necessary + if comma_patch: + rep = [_i for _i in rep if _i] + + return rep + + + # ---------------------------------------------------------------------- + # expand_macros() + # + # Given a list of tokens, this function performs macro expansion. + # The expanded argument is a dictionary that contains macros already + # expanded. This is used to prevent infinite recursion. + # ---------------------------------------------------------------------- + + def expand_macros(self,tokens,expanded=None): + if expanded is None: + expanded = {} + i = 0 + while i < len(tokens): + t = tokens[i] + if t.type == self.t_ID: + if t.value in self.macros and t.value not in expanded: + # Yes, we found a macro match + expanded[t.value] = True + + m = self.macros[t.value] + if not m.arglist: + # A simple macro + ex = self.expand_macros([copy.copy(_x) for _x in m.value],expanded) + for e in ex: + e.lineno = t.lineno + tokens[i:i+1] = ex + i += len(ex) + else: + # A macro with arguments + j = i + 1 + while j < len(tokens) and tokens[j].type in self.t_WS: + j += 1 + if tokens[j].value == '(': + tokcount,args,positions = self.collect_args(tokens[j:]) + if not m.variadic and len(args) != len(m.arglist): + self.error(self.source,t.lineno,"Macro %s requires %d arguments" % (t.value,len(m.arglist))) + i = j + tokcount + elif m.variadic and len(args) < len(m.arglist)-1: + if len(m.arglist) > 2: + self.error(self.source,t.lineno,"Macro %s must have at least %d arguments" % (t.value, len(m.arglist)-1)) + else: + self.error(self.source,t.lineno,"Macro %s must have at least %d argument" % (t.value, len(m.arglist)-1)) + i = j + tokcount + else: + if m.variadic: + if len(args) == len(m.arglist)-1: + args.append([]) + else: + args[len(m.arglist)-1] = tokens[j+positions[len(m.arglist)-1]:j+tokcount-1] + del args[len(m.arglist):] + + # Get macro replacement text + rep = self.macro_expand_args(m,args) + rep = self.expand_macros(rep,expanded) + for r in rep: + r.lineno = t.lineno + tokens[i:j+tokcount] = rep + i += len(rep) + del expanded[t.value] + continue + elif t.value == '__LINE__': + t.type = self.t_INTEGER + t.value = self.t_INTEGER_TYPE(t.lineno) + + i += 1 + return tokens + + # ---------------------------------------------------------------------- + # evalexpr() + # + # Evaluate an expression token sequence for the purposes of evaluating + # integral expressions. + # ---------------------------------------------------------------------- + + def evalexpr(self,tokens): + # tokens = tokenize(line) + # Search for defined macros + i = 0 + while i < len(tokens): + if tokens[i].type == self.t_ID and tokens[i].value == 'defined': + j = i + 1 + needparen = False + result = "0L" + while j < len(tokens): + if tokens[j].type in self.t_WS: + j += 1 + continue + elif tokens[j].type == self.t_ID: + if tokens[j].value in self.macros: + result = "1L" + else: + result = "0L" + if not needparen: break + elif tokens[j].value == '(': + needparen = True + elif tokens[j].value == ')': + break + else: + self.error(self.source,tokens[i].lineno,"Malformed defined()") + j += 1 + tokens[i].type = self.t_INTEGER + tokens[i].value = self.t_INTEGER_TYPE(result) + del tokens[i+1:j+1] + i += 1 + tokens = self.expand_macros(tokens) + for i,t in enumerate(tokens): + if t.type == self.t_ID: + tokens[i] = copy.copy(t) + tokens[i].type = self.t_INTEGER + tokens[i].value = self.t_INTEGER_TYPE("0L") + elif t.type == self.t_INTEGER: + tokens[i] = copy.copy(t) + # Strip off any trailing suffixes + tokens[i].value = str(tokens[i].value) + while tokens[i].value[-1] not in "0123456789abcdefABCDEF": + tokens[i].value = tokens[i].value[:-1] + + expr = "".join([str(x.value) for x in tokens]) + expr = expr.replace("&&"," and ") + expr = expr.replace("||"," or ") + expr = expr.replace("!"," not ") + try: + result = eval(expr) + except Exception: + self.error(self.source,tokens[0].lineno,"Couldn't evaluate expression") + result = 0 + return result + + # ---------------------------------------------------------------------- + # parsegen() + # + # Parse an input string/ + # ---------------------------------------------------------------------- + def parsegen(self,input,source=None): + + # Replace trigraph sequences + t = trigraph(input) + lines = self.group_lines(t) + + if not source: + source = "" + + self.define("__FILE__ \"%s\"" % source) + + self.source = source + chunk = [] + enable = True + iftrigger = False + ifstack = [] + + for x in lines: + for i,tok in enumerate(x): + if tok.type not in self.t_WS: break + if tok.value == '#': + # Preprocessor directive + + # insert necessary whitespace instead of eaten tokens + for tok in x: + if tok.type in self.t_WS and '\n' in tok.value: + chunk.append(tok) + + dirtokens = self.tokenstrip(x[i+1:]) + if dirtokens: + name = dirtokens[0].value + args = self.tokenstrip(dirtokens[1:]) + else: + name = "" + args = [] + + if name == 'define': + if enable: + for tok in self.expand_macros(chunk): + yield tok + chunk = [] + self.define(args) + elif name == 'include': + if enable: + for tok in self.expand_macros(chunk): + yield tok + chunk = [] + oldfile = self.macros['__FILE__'] + for tok in self.include(args): + yield tok + self.macros['__FILE__'] = oldfile + self.source = source + elif name == 'undef': + if enable: + for tok in self.expand_macros(chunk): + yield tok + chunk = [] + self.undef(args) + elif name == 'ifdef': + ifstack.append((enable,iftrigger)) + if enable: + if not args[0].value in self.macros: + enable = False + iftrigger = False + else: + iftrigger = True + elif name == 'ifndef': + ifstack.append((enable,iftrigger)) + if enable: + if args[0].value in self.macros: + enable = False + iftrigger = False + else: + iftrigger = True + elif name == 'if': + ifstack.append((enable,iftrigger)) + if enable: + result = self.evalexpr(args) + if not result: + enable = False + iftrigger = False + else: + iftrigger = True + elif name == 'elif': + if ifstack: + if ifstack[-1][0]: # We only pay attention if outer "if" allows this + if enable: # If already true, we flip enable False + enable = False + elif not iftrigger: # If False, but not triggered yet, we'll check expression + result = self.evalexpr(args) + if result: + enable = True + iftrigger = True + else: + self.error(self.source,dirtokens[0].lineno,"Misplaced #elif") + + elif name == 'else': + if ifstack: + if ifstack[-1][0]: + if enable: + enable = False + elif not iftrigger: + enable = True + iftrigger = True + else: + self.error(self.source,dirtokens[0].lineno,"Misplaced #else") + + elif name == 'endif': + if ifstack: + enable,iftrigger = ifstack.pop() + else: + self.error(self.source,dirtokens[0].lineno,"Misplaced #endif") + else: + # Unknown preprocessor directive + pass + + else: + # Normal text + if enable: + chunk.extend(x) + + for tok in self.expand_macros(chunk): + yield tok + chunk = [] + + # ---------------------------------------------------------------------- + # include() + # + # Implementation of file-inclusion + # ---------------------------------------------------------------------- + + def include(self,tokens): + # Try to extract the filename and then process an include file + if not tokens: + return + if tokens: + if tokens[0].value != '<' and tokens[0].type != self.t_STRING: + tokens = self.expand_macros(tokens) + + if tokens[0].value == '<': + # Include <...> + i = 1 + while i < len(tokens): + if tokens[i].value == '>': + break + i += 1 + else: + print("Malformed #include <...>") + return + filename = "".join([x.value for x in tokens[1:i]]) + path = self.path + [""] + self.temp_path + elif tokens[0].type == self.t_STRING: + filename = tokens[0].value[1:-1] + path = self.temp_path + [""] + self.path + else: + print("Malformed #include statement") + return + for p in path: + iname = os.path.join(p,filename) + try: + data = open(iname,"r").read() + dname = os.path.dirname(iname) + if dname: + self.temp_path.insert(0,dname) + for tok in self.parsegen(data,filename): + yield tok + if dname: + del self.temp_path[0] + break + except IOError: + pass + else: + print("Couldn't find '%s'" % filename) + + # ---------------------------------------------------------------------- + # define() + # + # Define a new macro + # ---------------------------------------------------------------------- + + def define(self,tokens): + if isinstance(tokens,STRING_TYPES): + tokens = self.tokenize(tokens) + + linetok = tokens + try: + name = linetok[0] + if len(linetok) > 1: + mtype = linetok[1] + else: + mtype = None + if not mtype: + m = Macro(name.value,[]) + self.macros[name.value] = m + elif mtype.type in self.t_WS: + # A normal macro + m = Macro(name.value,self.tokenstrip(linetok[2:])) + self.macros[name.value] = m + elif mtype.value == '(': + # A macro with arguments + tokcount, args, positions = self.collect_args(linetok[1:]) + variadic = False + for a in args: + if variadic: + print("No more arguments may follow a variadic argument") + break + astr = "".join([str(_i.value) for _i in a]) + if astr == "...": + variadic = True + a[0].type = self.t_ID + a[0].value = '__VA_ARGS__' + variadic = True + del a[1:] + continue + elif astr[-3:] == "..." and a[0].type == self.t_ID: + variadic = True + del a[1:] + # If, for some reason, "." is part of the identifier, strip off the name for the purposes + # of macro expansion + if a[0].value[-3:] == '...': + a[0].value = a[0].value[:-3] + continue + if len(a) > 1 or a[0].type != self.t_ID: + print("Invalid macro argument") + break + else: + mvalue = self.tokenstrip(linetok[1+tokcount:]) + i = 0 + while i < len(mvalue): + if i+1 < len(mvalue): + if mvalue[i].type in self.t_WS and mvalue[i+1].value == '##': + del mvalue[i] + continue + elif mvalue[i].value == '##' and mvalue[i+1].type in self.t_WS: + del mvalue[i+1] + i += 1 + m = Macro(name.value,mvalue,[x[0].value for x in args],variadic) + self.macro_prescan(m) + self.macros[name.value] = m + else: + print("Bad macro definition") + except LookupError: + print("Bad macro definition") + + # ---------------------------------------------------------------------- + # undef() + # + # Undefine a macro + # ---------------------------------------------------------------------- + + def undef(self,tokens): + id = tokens[0].value + try: + del self.macros[id] + except LookupError: + pass + + # ---------------------------------------------------------------------- + # parse() + # + # Parse input text. + # ---------------------------------------------------------------------- + def parse(self,input,source=None,ignore={}): + self.ignore = ignore + self.parser = self.parsegen(input,source) + + # ---------------------------------------------------------------------- + # token() + # + # Method to return individual tokens + # ---------------------------------------------------------------------- + def token(self): + try: + while True: + tok = next(self.parser) + if tok.type not in self.ignore: return tok + except StopIteration: + self.parser = None + return None + +if __name__ == '__main__': + import ply.lex as lex + lexer = lex.lex() + + # Run a preprocessor + import sys + f = open(sys.argv[1]) + input = f.read() + + p = Preprocessor(lexer) + p.parse(input,sys.argv[1]) + while True: + tok = p.token() + if not tok: break + print(p.source, tok) diff --git a/uno/lib/python/pycparser/ply/ctokens.py b/uno/lib/python/pycparser/ply/ctokens.py new file mode 100644 index 00000000..f6f6952d --- /dev/null +++ b/uno/lib/python/pycparser/ply/ctokens.py @@ -0,0 +1,133 @@ +# ---------------------------------------------------------------------- +# ctokens.py +# +# Token specifications for symbols in ANSI C and C++. This file is +# meant to be used as a library in other tokenizers. +# ---------------------------------------------------------------------- + +# Reserved words + +tokens = [ + # Literals (identifier, integer constant, float constant, string constant, char const) + 'ID', 'TYPEID', 'INTEGER', 'FLOAT', 'STRING', 'CHARACTER', + + # Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=) + 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MODULO', + 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT', + 'LOR', 'LAND', 'LNOT', + 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE', + + # Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=) + 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL', + 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL', + + # Increment/decrement (++,--) + 'INCREMENT', 'DECREMENT', + + # Structure dereference (->) + 'ARROW', + + # Ternary operator (?) + 'TERNARY', + + # Delimeters ( ) [ ] { } , . ; : + 'LPAREN', 'RPAREN', + 'LBRACKET', 'RBRACKET', + 'LBRACE', 'RBRACE', + 'COMMA', 'PERIOD', 'SEMI', 'COLON', + + # Ellipsis (...) + 'ELLIPSIS', +] + +# Operators +t_PLUS = r'\+' +t_MINUS = r'-' +t_TIMES = r'\*' +t_DIVIDE = r'/' +t_MODULO = r'%' +t_OR = r'\|' +t_AND = r'&' +t_NOT = r'~' +t_XOR = r'\^' +t_LSHIFT = r'<<' +t_RSHIFT = r'>>' +t_LOR = r'\|\|' +t_LAND = r'&&' +t_LNOT = r'!' +t_LT = r'<' +t_GT = r'>' +t_LE = r'<=' +t_GE = r'>=' +t_EQ = r'==' +t_NE = r'!=' + +# Assignment operators + +t_EQUALS = r'=' +t_TIMESEQUAL = r'\*=' +t_DIVEQUAL = r'/=' +t_MODEQUAL = r'%=' +t_PLUSEQUAL = r'\+=' +t_MINUSEQUAL = r'-=' +t_LSHIFTEQUAL = r'<<=' +t_RSHIFTEQUAL = r'>>=' +t_ANDEQUAL = r'&=' +t_OREQUAL = r'\|=' +t_XOREQUAL = r'\^=' + +# Increment/decrement +t_INCREMENT = r'\+\+' +t_DECREMENT = r'--' + +# -> +t_ARROW = r'->' + +# ? +t_TERNARY = r'\?' + +# Delimeters +t_LPAREN = r'\(' +t_RPAREN = r'\)' +t_LBRACKET = r'\[' +t_RBRACKET = r'\]' +t_LBRACE = r'\{' +t_RBRACE = r'\}' +t_COMMA = r',' +t_PERIOD = r'\.' +t_SEMI = r';' +t_COLON = r':' +t_ELLIPSIS = r'\.\.\.' + +# Identifiers +t_ID = r'[A-Za-z_][A-Za-z0-9_]*' + +# Integer literal +t_INTEGER = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?' + +# Floating literal +t_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?' + +# String literal +t_STRING = r'\"([^\\\n]|(\\.))*?\"' + +# Character constant 'c' or L'c' +t_CHARACTER = r'(L)?\'([^\\\n]|(\\.))*?\'' + +# Comment (C-Style) +def t_COMMENT(t): + r'/\*(.|\n)*?\*/' + t.lexer.lineno += t.value.count('\n') + return t + +# Comment (C++-Style) +def t_CPPCOMMENT(t): + r'//.*\n' + t.lexer.lineno += 1 + return t + + + + + + diff --git a/uno/lib/python/pycparser/ply/lex.py b/uno/lib/python/pycparser/ply/lex.py new file mode 100644 index 00000000..4bdd76ca --- /dev/null +++ b/uno/lib/python/pycparser/ply/lex.py @@ -0,0 +1,1099 @@ +# ----------------------------------------------------------------------------- +# ply: lex.py +# +# Copyright (C) 2001-2017 +# David M. Beazley (Dabeaz LLC) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the David Beazley or Dabeaz LLC may be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- + +__version__ = '3.10' +__tabversion__ = '3.10' + +import re +import sys +import types +import copy +import os +import inspect + +# This tuple contains known string types +try: + # Python 2.6 + StringTypes = (types.StringType, types.UnicodeType) +except AttributeError: + # Python 3.0 + StringTypes = (str, bytes) + +# This regular expression is used to match valid token names +_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$') + +# Exception thrown when invalid token encountered and no default error +# handler is defined. +class LexError(Exception): + def __init__(self, message, s): + self.args = (message,) + self.text = s + + +# Token class. This class is used to represent the tokens produced. +class LexToken(object): + def __str__(self): + return 'LexToken(%s,%r,%d,%d)' % (self.type, self.value, self.lineno, self.lexpos) + + def __repr__(self): + return str(self) + + +# This object is a stand-in for a logging object created by the +# logging module. + +class PlyLogger(object): + def __init__(self, f): + self.f = f + + def critical(self, msg, *args, **kwargs): + self.f.write((msg % args) + '\n') + + def warning(self, msg, *args, **kwargs): + self.f.write('WARNING: ' + (msg % args) + '\n') + + def error(self, msg, *args, **kwargs): + self.f.write('ERROR: ' + (msg % args) + '\n') + + info = critical + debug = critical + + +# Null logger is used when no output is generated. Does nothing. +class NullLogger(object): + def __getattribute__(self, name): + return self + + def __call__(self, *args, **kwargs): + return self + + +# ----------------------------------------------------------------------------- +# === Lexing Engine === +# +# The following Lexer class implements the lexer runtime. There are only +# a few public methods and attributes: +# +# input() - Store a new string in the lexer +# token() - Get the next token +# clone() - Clone the lexer +# +# lineno - Current line number +# lexpos - Current position in the input string +# ----------------------------------------------------------------------------- + +class Lexer: + def __init__(self): + self.lexre = None # Master regular expression. This is a list of + # tuples (re, findex) where re is a compiled + # regular expression and findex is a list + # mapping regex group numbers to rules + self.lexretext = None # Current regular expression strings + self.lexstatere = {} # Dictionary mapping lexer states to master regexs + self.lexstateretext = {} # Dictionary mapping lexer states to regex strings + self.lexstaterenames = {} # Dictionary mapping lexer states to symbol names + self.lexstate = 'INITIAL' # Current lexer state + self.lexstatestack = [] # Stack of lexer states + self.lexstateinfo = None # State information + self.lexstateignore = {} # Dictionary of ignored characters for each state + self.lexstateerrorf = {} # Dictionary of error functions for each state + self.lexstateeoff = {} # Dictionary of eof functions for each state + self.lexreflags = 0 # Optional re compile flags + self.lexdata = None # Actual input data (as a string) + self.lexpos = 0 # Current position in input text + self.lexlen = 0 # Length of the input text + self.lexerrorf = None # Error rule (if any) + self.lexeoff = None # EOF rule (if any) + self.lextokens = None # List of valid tokens + self.lexignore = '' # Ignored characters + self.lexliterals = '' # Literal characters that can be passed through + self.lexmodule = None # Module + self.lineno = 1 # Current line number + self.lexoptimize = False # Optimized mode + + def clone(self, object=None): + c = copy.copy(self) + + # If the object parameter has been supplied, it means we are attaching the + # lexer to a new object. In this case, we have to rebind all methods in + # the lexstatere and lexstateerrorf tables. + + if object: + newtab = {} + for key, ritem in self.lexstatere.items(): + newre = [] + for cre, findex in ritem: + newfindex = [] + for f in findex: + if not f or not f[0]: + newfindex.append(f) + continue + newfindex.append((getattr(object, f[0].__name__), f[1])) + newre.append((cre, newfindex)) + newtab[key] = newre + c.lexstatere = newtab + c.lexstateerrorf = {} + for key, ef in self.lexstateerrorf.items(): + c.lexstateerrorf[key] = getattr(object, ef.__name__) + c.lexmodule = object + return c + + # ------------------------------------------------------------ + # writetab() - Write lexer information to a table file + # ------------------------------------------------------------ + def writetab(self, lextab, outputdir=''): + if isinstance(lextab, types.ModuleType): + raise IOError("Won't overwrite existing lextab module") + basetabmodule = lextab.split('.')[-1] + filename = os.path.join(outputdir, basetabmodule) + '.py' + with open(filename, 'w') as tf: + tf.write('# %s.py. This file automatically created by PLY (version %s). Don\'t edit!\n' % (basetabmodule, __version__)) + tf.write('_tabversion = %s\n' % repr(__tabversion__)) + tf.write('_lextokens = set(%s)\n' % repr(tuple(self.lextokens))) + tf.write('_lexreflags = %s\n' % repr(self.lexreflags)) + tf.write('_lexliterals = %s\n' % repr(self.lexliterals)) + tf.write('_lexstateinfo = %s\n' % repr(self.lexstateinfo)) + + # Rewrite the lexstatere table, replacing function objects with function names + tabre = {} + for statename, lre in self.lexstatere.items(): + titem = [] + for (pat, func), retext, renames in zip(lre, self.lexstateretext[statename], self.lexstaterenames[statename]): + titem.append((retext, _funcs_to_names(func, renames))) + tabre[statename] = titem + + tf.write('_lexstatere = %s\n' % repr(tabre)) + tf.write('_lexstateignore = %s\n' % repr(self.lexstateignore)) + + taberr = {} + for statename, ef in self.lexstateerrorf.items(): + taberr[statename] = ef.__name__ if ef else None + tf.write('_lexstateerrorf = %s\n' % repr(taberr)) + + tabeof = {} + for statename, ef in self.lexstateeoff.items(): + tabeof[statename] = ef.__name__ if ef else None + tf.write('_lexstateeoff = %s\n' % repr(tabeof)) + + # ------------------------------------------------------------ + # readtab() - Read lexer information from a tab file + # ------------------------------------------------------------ + def readtab(self, tabfile, fdict): + if isinstance(tabfile, types.ModuleType): + lextab = tabfile + else: + exec('import %s' % tabfile) + lextab = sys.modules[tabfile] + + if getattr(lextab, '_tabversion', '0.0') != __tabversion__: + raise ImportError('Inconsistent PLY version') + + self.lextokens = lextab._lextokens + self.lexreflags = lextab._lexreflags + self.lexliterals = lextab._lexliterals + self.lextokens_all = self.lextokens | set(self.lexliterals) + self.lexstateinfo = lextab._lexstateinfo + self.lexstateignore = lextab._lexstateignore + self.lexstatere = {} + self.lexstateretext = {} + for statename, lre in lextab._lexstatere.items(): + titem = [] + txtitem = [] + for pat, func_name in lre: + titem.append((re.compile(pat, lextab._lexreflags), _names_to_funcs(func_name, fdict))) + + self.lexstatere[statename] = titem + self.lexstateretext[statename] = txtitem + + self.lexstateerrorf = {} + for statename, ef in lextab._lexstateerrorf.items(): + self.lexstateerrorf[statename] = fdict[ef] + + self.lexstateeoff = {} + for statename, ef in lextab._lexstateeoff.items(): + self.lexstateeoff[statename] = fdict[ef] + + self.begin('INITIAL') + + # ------------------------------------------------------------ + # input() - Push a new string into the lexer + # ------------------------------------------------------------ + def input(self, s): + # Pull off the first character to see if s looks like a string + c = s[:1] + if not isinstance(c, StringTypes): + raise ValueError('Expected a string') + self.lexdata = s + self.lexpos = 0 + self.lexlen = len(s) + + # ------------------------------------------------------------ + # begin() - Changes the lexing state + # ------------------------------------------------------------ + def begin(self, state): + if state not in self.lexstatere: + raise ValueError('Undefined state') + self.lexre = self.lexstatere[state] + self.lexretext = self.lexstateretext[state] + self.lexignore = self.lexstateignore.get(state, '') + self.lexerrorf = self.lexstateerrorf.get(state, None) + self.lexeoff = self.lexstateeoff.get(state, None) + self.lexstate = state + + # ------------------------------------------------------------ + # push_state() - Changes the lexing state and saves old on stack + # ------------------------------------------------------------ + def push_state(self, state): + self.lexstatestack.append(self.lexstate) + self.begin(state) + + # ------------------------------------------------------------ + # pop_state() - Restores the previous state + # ------------------------------------------------------------ + def pop_state(self): + self.begin(self.lexstatestack.pop()) + + # ------------------------------------------------------------ + # current_state() - Returns the current lexing state + # ------------------------------------------------------------ + def current_state(self): + return self.lexstate + + # ------------------------------------------------------------ + # skip() - Skip ahead n characters + # ------------------------------------------------------------ + def skip(self, n): + self.lexpos += n + + # ------------------------------------------------------------ + # opttoken() - Return the next token from the Lexer + # + # Note: This function has been carefully implemented to be as fast + # as possible. Don't make changes unless you really know what + # you are doing + # ------------------------------------------------------------ + def token(self): + # Make local copies of frequently referenced attributes + lexpos = self.lexpos + lexlen = self.lexlen + lexignore = self.lexignore + lexdata = self.lexdata + + while lexpos < lexlen: + # This code provides some short-circuit code for whitespace, tabs, and other ignored characters + if lexdata[lexpos] in lexignore: + lexpos += 1 + continue + + # Look for a regular expression match + for lexre, lexindexfunc in self.lexre: + m = lexre.match(lexdata, lexpos) + if not m: + continue + + # Create a token for return + tok = LexToken() + tok.value = m.group() + tok.lineno = self.lineno + tok.lexpos = lexpos + + i = m.lastindex + func, tok.type = lexindexfunc[i] + + if not func: + # If no token type was set, it's an ignored token + if tok.type: + self.lexpos = m.end() + return tok + else: + lexpos = m.end() + break + + lexpos = m.end() + + # If token is processed by a function, call it + + tok.lexer = self # Set additional attributes useful in token rules + self.lexmatch = m + self.lexpos = lexpos + + newtok = func(tok) + + # Every function must return a token, if nothing, we just move to next token + if not newtok: + lexpos = self.lexpos # This is here in case user has updated lexpos. + lexignore = self.lexignore # This is here in case there was a state change + break + + # Verify type of the token. If not in the token map, raise an error + if not self.lexoptimize: + if newtok.type not in self.lextokens_all: + raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % ( + func.__code__.co_filename, func.__code__.co_firstlineno, + func.__name__, newtok.type), lexdata[lexpos:]) + + return newtok + else: + # No match, see if in literals + if lexdata[lexpos] in self.lexliterals: + tok = LexToken() + tok.value = lexdata[lexpos] + tok.lineno = self.lineno + tok.type = tok.value + tok.lexpos = lexpos + self.lexpos = lexpos + 1 + return tok + + # No match. Call t_error() if defined. + if self.lexerrorf: + tok = LexToken() + tok.value = self.lexdata[lexpos:] + tok.lineno = self.lineno + tok.type = 'error' + tok.lexer = self + tok.lexpos = lexpos + self.lexpos = lexpos + newtok = self.lexerrorf(tok) + if lexpos == self.lexpos: + # Error method didn't change text position at all. This is an error. + raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:]) + lexpos = self.lexpos + if not newtok: + continue + return newtok + + self.lexpos = lexpos + raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos], lexpos), lexdata[lexpos:]) + + if self.lexeoff: + tok = LexToken() + tok.type = 'eof' + tok.value = '' + tok.lineno = self.lineno + tok.lexpos = lexpos + tok.lexer = self + self.lexpos = lexpos + newtok = self.lexeoff(tok) + return newtok + + self.lexpos = lexpos + 1 + if self.lexdata is None: + raise RuntimeError('No input string given with input()') + return None + + # Iterator interface + def __iter__(self): + return self + + def next(self): + t = self.token() + if t is None: + raise StopIteration + return t + + __next__ = next + +# ----------------------------------------------------------------------------- +# ==== Lex Builder === +# +# The functions and classes below are used to collect lexing information +# and build a Lexer object from it. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# _get_regex(func) +# +# Returns the regular expression assigned to a function either as a doc string +# or as a .regex attribute attached by the @TOKEN decorator. +# ----------------------------------------------------------------------------- +def _get_regex(func): + return getattr(func, 'regex', func.__doc__) + +# ----------------------------------------------------------------------------- +# get_caller_module_dict() +# +# This function returns a dictionary containing all of the symbols defined within +# a caller further down the call stack. This is used to get the environment +# associated with the yacc() call if none was provided. +# ----------------------------------------------------------------------------- +def get_caller_module_dict(levels): + f = sys._getframe(levels) + ldict = f.f_globals.copy() + if f.f_globals != f.f_locals: + ldict.update(f.f_locals) + return ldict + +# ----------------------------------------------------------------------------- +# _funcs_to_names() +# +# Given a list of regular expression functions, this converts it to a list +# suitable for output to a table file +# ----------------------------------------------------------------------------- +def _funcs_to_names(funclist, namelist): + result = [] + for f, name in zip(funclist, namelist): + if f and f[0]: + result.append((name, f[1])) + else: + result.append(f) + return result + +# ----------------------------------------------------------------------------- +# _names_to_funcs() +# +# Given a list of regular expression function names, this converts it back to +# functions. +# ----------------------------------------------------------------------------- +def _names_to_funcs(namelist, fdict): + result = [] + for n in namelist: + if n and n[0]: + result.append((fdict[n[0]], n[1])) + else: + result.append(n) + return result + +# ----------------------------------------------------------------------------- +# _form_master_re() +# +# This function takes a list of all of the regex components and attempts to +# form the master regular expression. Given limitations in the Python re +# module, it may be necessary to break the master regex into separate expressions. +# ----------------------------------------------------------------------------- +def _form_master_re(relist, reflags, ldict, toknames): + if not relist: + return [] + regex = '|'.join(relist) + try: + lexre = re.compile(regex, reflags) + + # Build the index to function map for the matching engine + lexindexfunc = [None] * (max(lexre.groupindex.values()) + 1) + lexindexnames = lexindexfunc[:] + + for f, i in lexre.groupindex.items(): + handle = ldict.get(f, None) + if type(handle) in (types.FunctionType, types.MethodType): + lexindexfunc[i] = (handle, toknames[f]) + lexindexnames[i] = f + elif handle is not None: + lexindexnames[i] = f + if f.find('ignore_') > 0: + lexindexfunc[i] = (None, None) + else: + lexindexfunc[i] = (None, toknames[f]) + + return [(lexre, lexindexfunc)], [regex], [lexindexnames] + except Exception: + m = int(len(relist)/2) + if m == 0: + m = 1 + llist, lre, lnames = _form_master_re(relist[:m], reflags, ldict, toknames) + rlist, rre, rnames = _form_master_re(relist[m:], reflags, ldict, toknames) + return (llist+rlist), (lre+rre), (lnames+rnames) + +# ----------------------------------------------------------------------------- +# def _statetoken(s,names) +# +# Given a declaration name s of the form "t_" and a dictionary whose keys are +# state names, this function returns a tuple (states,tokenname) where states +# is a tuple of state names and tokenname is the name of the token. For example, +# calling this with s = "t_foo_bar_SPAM" might return (('foo','bar'),'SPAM') +# ----------------------------------------------------------------------------- +def _statetoken(s, names): + nonstate = 1 + parts = s.split('_') + for i, part in enumerate(parts[1:], 1): + if part not in names and part != 'ANY': + break + + if i > 1: + states = tuple(parts[1:i]) + else: + states = ('INITIAL',) + + if 'ANY' in states: + states = tuple(names) + + tokenname = '_'.join(parts[i:]) + return (states, tokenname) + + +# ----------------------------------------------------------------------------- +# LexerReflect() +# +# This class represents information needed to build a lexer as extracted from a +# user's input file. +# ----------------------------------------------------------------------------- +class LexerReflect(object): + def __init__(self, ldict, log=None, reflags=0): + self.ldict = ldict + self.error_func = None + self.tokens = [] + self.reflags = reflags + self.stateinfo = {'INITIAL': 'inclusive'} + self.modules = set() + self.error = False + self.log = PlyLogger(sys.stderr) if log is None else log + + # Get all of the basic information + def get_all(self): + self.get_tokens() + self.get_literals() + self.get_states() + self.get_rules() + + # Validate all of the information + def validate_all(self): + self.validate_tokens() + self.validate_literals() + self.validate_rules() + return self.error + + # Get the tokens map + def get_tokens(self): + tokens = self.ldict.get('tokens', None) + if not tokens: + self.log.error('No token list is defined') + self.error = True + return + + if not isinstance(tokens, (list, tuple)): + self.log.error('tokens must be a list or tuple') + self.error = True + return + + if not tokens: + self.log.error('tokens is empty') + self.error = True + return + + self.tokens = tokens + + # Validate the tokens + def validate_tokens(self): + terminals = {} + for n in self.tokens: + if not _is_identifier.match(n): + self.log.error("Bad token name '%s'", n) + self.error = True + if n in terminals: + self.log.warning("Token '%s' multiply defined", n) + terminals[n] = 1 + + # Get the literals specifier + def get_literals(self): + self.literals = self.ldict.get('literals', '') + if not self.literals: + self.literals = '' + + # Validate literals + def validate_literals(self): + try: + for c in self.literals: + if not isinstance(c, StringTypes) or len(c) > 1: + self.log.error('Invalid literal %s. Must be a single character', repr(c)) + self.error = True + + except TypeError: + self.log.error('Invalid literals specification. literals must be a sequence of characters') + self.error = True + + def get_states(self): + self.states = self.ldict.get('states', None) + # Build statemap + if self.states: + if not isinstance(self.states, (tuple, list)): + self.log.error('states must be defined as a tuple or list') + self.error = True + else: + for s in self.states: + if not isinstance(s, tuple) or len(s) != 2: + self.log.error("Invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')", repr(s)) + self.error = True + continue + name, statetype = s + if not isinstance(name, StringTypes): + self.log.error('State name %s must be a string', repr(name)) + self.error = True + continue + if not (statetype == 'inclusive' or statetype == 'exclusive'): + self.log.error("State type for state %s must be 'inclusive' or 'exclusive'", name) + self.error = True + continue + if name in self.stateinfo: + self.log.error("State '%s' already defined", name) + self.error = True + continue + self.stateinfo[name] = statetype + + # Get all of the symbols with a t_ prefix and sort them into various + # categories (functions, strings, error functions, and ignore characters) + + def get_rules(self): + tsymbols = [f for f in self.ldict if f[:2] == 't_'] + + # Now build up a list of functions and a list of strings + self.toknames = {} # Mapping of symbols to token names + self.funcsym = {} # Symbols defined as functions + self.strsym = {} # Symbols defined as strings + self.ignore = {} # Ignore strings by state + self.errorf = {} # Error functions by state + self.eoff = {} # EOF functions by state + + for s in self.stateinfo: + self.funcsym[s] = [] + self.strsym[s] = [] + + if len(tsymbols) == 0: + self.log.error('No rules of the form t_rulename are defined') + self.error = True + return + + for f in tsymbols: + t = self.ldict[f] + states, tokname = _statetoken(f, self.stateinfo) + self.toknames[f] = tokname + + if hasattr(t, '__call__'): + if tokname == 'error': + for s in states: + self.errorf[s] = t + elif tokname == 'eof': + for s in states: + self.eoff[s] = t + elif tokname == 'ignore': + line = t.__code__.co_firstlineno + file = t.__code__.co_filename + self.log.error("%s:%d: Rule '%s' must be defined as a string", file, line, t.__name__) + self.error = True + else: + for s in states: + self.funcsym[s].append((f, t)) + elif isinstance(t, StringTypes): + if tokname == 'ignore': + for s in states: + self.ignore[s] = t + if '\\' in t: + self.log.warning("%s contains a literal backslash '\\'", f) + + elif tokname == 'error': + self.log.error("Rule '%s' must be defined as a function", f) + self.error = True + else: + for s in states: + self.strsym[s].append((f, t)) + else: + self.log.error('%s not defined as a function or string', f) + self.error = True + + # Sort the functions by line number + for f in self.funcsym.values(): + f.sort(key=lambda x: x[1].__code__.co_firstlineno) + + # Sort the strings by regular expression length + for s in self.strsym.values(): + s.sort(key=lambda x: len(x[1]), reverse=True) + + # Validate all of the t_rules collected + def validate_rules(self): + for state in self.stateinfo: + # Validate all rules defined by functions + + for fname, f in self.funcsym[state]: + line = f.__code__.co_firstlineno + file = f.__code__.co_filename + module = inspect.getmodule(f) + self.modules.add(module) + + tokname = self.toknames[fname] + if isinstance(f, types.MethodType): + reqargs = 2 + else: + reqargs = 1 + nargs = f.__code__.co_argcount + if nargs > reqargs: + self.log.error("%s:%d: Rule '%s' has too many arguments", file, line, f.__name__) + self.error = True + continue + + if nargs < reqargs: + self.log.error("%s:%d: Rule '%s' requires an argument", file, line, f.__name__) + self.error = True + continue + + if not _get_regex(f): + self.log.error("%s:%d: No regular expression defined for rule '%s'", file, line, f.__name__) + self.error = True + continue + + try: + c = re.compile('(?P<%s>%s)' % (fname, _get_regex(f)), self.reflags) + if c.match(''): + self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file, line, f.__name__) + self.error = True + except re.error as e: + self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file, line, f.__name__, e) + if '#' in _get_regex(f): + self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'", file, line, f.__name__) + self.error = True + + # Validate all rules defined by strings + for name, r in self.strsym[state]: + tokname = self.toknames[name] + if tokname == 'error': + self.log.error("Rule '%s' must be defined as a function", name) + self.error = True + continue + + if tokname not in self.tokens and tokname.find('ignore_') < 0: + self.log.error("Rule '%s' defined for an unspecified token %s", name, tokname) + self.error = True + continue + + try: + c = re.compile('(?P<%s>%s)' % (name, r), self.reflags) + if (c.match('')): + self.log.error("Regular expression for rule '%s' matches empty string", name) + self.error = True + except re.error as e: + self.log.error("Invalid regular expression for rule '%s'. %s", name, e) + if '#' in r: + self.log.error("Make sure '#' in rule '%s' is escaped with '\\#'", name) + self.error = True + + if not self.funcsym[state] and not self.strsym[state]: + self.log.error("No rules defined for state '%s'", state) + self.error = True + + # Validate the error function + efunc = self.errorf.get(state, None) + if efunc: + f = efunc + line = f.__code__.co_firstlineno + file = f.__code__.co_filename + module = inspect.getmodule(f) + self.modules.add(module) + + if isinstance(f, types.MethodType): + reqargs = 2 + else: + reqargs = 1 + nargs = f.__code__.co_argcount + if nargs > reqargs: + self.log.error("%s:%d: Rule '%s' has too many arguments", file, line, f.__name__) + self.error = True + + if nargs < reqargs: + self.log.error("%s:%d: Rule '%s' requires an argument", file, line, f.__name__) + self.error = True + + for module in self.modules: + self.validate_module(module) + + # ----------------------------------------------------------------------------- + # validate_module() + # + # This checks to see if there are duplicated t_rulename() functions or strings + # in the parser input file. This is done using a simple regular expression + # match on each line in the source code of the given module. + # ----------------------------------------------------------------------------- + + def validate_module(self, module): + try: + lines, linen = inspect.getsourcelines(module) + except IOError: + return + + fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(') + sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=') + + counthash = {} + linen += 1 + for line in lines: + m = fre.match(line) + if not m: + m = sre.match(line) + if m: + name = m.group(1) + prev = counthash.get(name) + if not prev: + counthash[name] = linen + else: + filename = inspect.getsourcefile(module) + self.log.error('%s:%d: Rule %s redefined. Previously defined on line %d', filename, linen, name, prev) + self.error = True + linen += 1 + +# ----------------------------------------------------------------------------- +# lex(module) +# +# Build all of the regular expression rules from definitions in the supplied module +# ----------------------------------------------------------------------------- +def lex(module=None, object=None, debug=False, optimize=False, lextab='lextab', + reflags=int(re.VERBOSE), nowarn=False, outputdir=None, debuglog=None, errorlog=None): + + if lextab is None: + lextab = 'lextab' + + global lexer + + ldict = None + stateinfo = {'INITIAL': 'inclusive'} + lexobj = Lexer() + lexobj.lexoptimize = optimize + global token, input + + if errorlog is None: + errorlog = PlyLogger(sys.stderr) + + if debug: + if debuglog is None: + debuglog = PlyLogger(sys.stderr) + + # Get the module dictionary used for the lexer + if object: + module = object + + # Get the module dictionary used for the parser + if module: + _items = [(k, getattr(module, k)) for k in dir(module)] + ldict = dict(_items) + # If no __file__ attribute is available, try to obtain it from the __module__ instead + if '__file__' not in ldict: + ldict['__file__'] = sys.modules[ldict['__module__']].__file__ + else: + ldict = get_caller_module_dict(2) + + # Determine if the module is package of a package or not. + # If so, fix the tabmodule setting so that tables load correctly + pkg = ldict.get('__package__') + if pkg and isinstance(lextab, str): + if '.' not in lextab: + lextab = pkg + '.' + lextab + + # Collect parser information from the dictionary + linfo = LexerReflect(ldict, log=errorlog, reflags=reflags) + linfo.get_all() + if not optimize: + if linfo.validate_all(): + raise SyntaxError("Can't build lexer") + + if optimize and lextab: + try: + lexobj.readtab(lextab, ldict) + token = lexobj.token + input = lexobj.input + lexer = lexobj + return lexobj + + except ImportError: + pass + + # Dump some basic debugging information + if debug: + debuglog.info('lex: tokens = %r', linfo.tokens) + debuglog.info('lex: literals = %r', linfo.literals) + debuglog.info('lex: states = %r', linfo.stateinfo) + + # Build a dictionary of valid token names + lexobj.lextokens = set() + for n in linfo.tokens: + lexobj.lextokens.add(n) + + # Get literals specification + if isinstance(linfo.literals, (list, tuple)): + lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals) + else: + lexobj.lexliterals = linfo.literals + + lexobj.lextokens_all = lexobj.lextokens | set(lexobj.lexliterals) + + # Get the stateinfo dictionary + stateinfo = linfo.stateinfo + + regexs = {} + # Build the master regular expressions + for state in stateinfo: + regex_list = [] + + # Add rules defined by functions first + for fname, f in linfo.funcsym[state]: + line = f.__code__.co_firstlineno + file = f.__code__.co_filename + regex_list.append('(?P<%s>%s)' % (fname, _get_regex(f))) + if debug: + debuglog.info("lex: Adding rule %s -> '%s' (state '%s')", fname, _get_regex(f), state) + + # Now add all of the simple rules + for name, r in linfo.strsym[state]: + regex_list.append('(?P<%s>%s)' % (name, r)) + if debug: + debuglog.info("lex: Adding rule %s -> '%s' (state '%s')", name, r, state) + + regexs[state] = regex_list + + # Build the master regular expressions + + if debug: + debuglog.info('lex: ==== MASTER REGEXS FOLLOW ====') + + for state in regexs: + lexre, re_text, re_names = _form_master_re(regexs[state], reflags, ldict, linfo.toknames) + lexobj.lexstatere[state] = lexre + lexobj.lexstateretext[state] = re_text + lexobj.lexstaterenames[state] = re_names + if debug: + for i, text in enumerate(re_text): + debuglog.info("lex: state '%s' : regex[%d] = '%s'", state, i, text) + + # For inclusive states, we need to add the regular expressions from the INITIAL state + for state, stype in stateinfo.items(): + if state != 'INITIAL' and stype == 'inclusive': + lexobj.lexstatere[state].extend(lexobj.lexstatere['INITIAL']) + lexobj.lexstateretext[state].extend(lexobj.lexstateretext['INITIAL']) + lexobj.lexstaterenames[state].extend(lexobj.lexstaterenames['INITIAL']) + + lexobj.lexstateinfo = stateinfo + lexobj.lexre = lexobj.lexstatere['INITIAL'] + lexobj.lexretext = lexobj.lexstateretext['INITIAL'] + lexobj.lexreflags = reflags + + # Set up ignore variables + lexobj.lexstateignore = linfo.ignore + lexobj.lexignore = lexobj.lexstateignore.get('INITIAL', '') + + # Set up error functions + lexobj.lexstateerrorf = linfo.errorf + lexobj.lexerrorf = linfo.errorf.get('INITIAL', None) + if not lexobj.lexerrorf: + errorlog.warning('No t_error rule is defined') + + # Set up eof functions + lexobj.lexstateeoff = linfo.eoff + lexobj.lexeoff = linfo.eoff.get('INITIAL', None) + + # Check state information for ignore and error rules + for s, stype in stateinfo.items(): + if stype == 'exclusive': + if s not in linfo.errorf: + errorlog.warning("No error rule is defined for exclusive state '%s'", s) + if s not in linfo.ignore and lexobj.lexignore: + errorlog.warning("No ignore rule is defined for exclusive state '%s'", s) + elif stype == 'inclusive': + if s not in linfo.errorf: + linfo.errorf[s] = linfo.errorf.get('INITIAL', None) + if s not in linfo.ignore: + linfo.ignore[s] = linfo.ignore.get('INITIAL', '') + + # Create global versions of the token() and input() functions + token = lexobj.token + input = lexobj.input + lexer = lexobj + + # If in optimize mode, we write the lextab + if lextab and optimize: + if outputdir is None: + # If no output directory is set, the location of the output files + # is determined according to the following rules: + # - If lextab specifies a package, files go into that package directory + # - Otherwise, files go in the same directory as the specifying module + if isinstance(lextab, types.ModuleType): + srcfile = lextab.__file__ + else: + if '.' not in lextab: + srcfile = ldict['__file__'] + else: + parts = lextab.split('.') + pkgname = '.'.join(parts[:-1]) + exec('import %s' % pkgname) + srcfile = getattr(sys.modules[pkgname], '__file__', '') + outputdir = os.path.dirname(srcfile) + try: + lexobj.writetab(lextab, outputdir) + except IOError as e: + errorlog.warning("Couldn't write lextab module %r. %s" % (lextab, e)) + + return lexobj + +# ----------------------------------------------------------------------------- +# runmain() +# +# This runs the lexer as a main program +# ----------------------------------------------------------------------------- + +def runmain(lexer=None, data=None): + if not data: + try: + filename = sys.argv[1] + f = open(filename) + data = f.read() + f.close() + except IndexError: + sys.stdout.write('Reading from standard input (type EOF to end):\n') + data = sys.stdin.read() + + if lexer: + _input = lexer.input + else: + _input = input + _input(data) + if lexer: + _token = lexer.token + else: + _token = token + + while True: + tok = _token() + if not tok: + break + sys.stdout.write('(%s,%r,%d,%d)\n' % (tok.type, tok.value, tok.lineno, tok.lexpos)) + +# ----------------------------------------------------------------------------- +# @TOKEN(regex) +# +# This decorator function can be used to set the regex expression on a function +# when its docstring might need to be set in an alternative way +# ----------------------------------------------------------------------------- + +def TOKEN(r): + def set_regex(f): + if hasattr(r, '__call__'): + f.regex = _get_regex(r) + else: + f.regex = r + return f + return set_regex + +# Alternative spelling of the TOKEN decorator +Token = TOKEN diff --git a/uno/lib/python/pycparser/ply/yacc.py b/uno/lib/python/pycparser/ply/yacc.py new file mode 100644 index 00000000..20b4f286 --- /dev/null +++ b/uno/lib/python/pycparser/ply/yacc.py @@ -0,0 +1,3494 @@ +# ----------------------------------------------------------------------------- +# ply: yacc.py +# +# Copyright (C) 2001-2017 +# David M. Beazley (Dabeaz LLC) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the David Beazley or Dabeaz LLC may be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- +# +# This implements an LR parser that is constructed from grammar rules defined +# as Python functions. The grammer is specified by supplying the BNF inside +# Python documentation strings. The inspiration for this technique was borrowed +# from John Aycock's Spark parsing system. PLY might be viewed as cross between +# Spark and the GNU bison utility. +# +# The current implementation is only somewhat object-oriented. The +# LR parser itself is defined in terms of an object (which allows multiple +# parsers to co-exist). However, most of the variables used during table +# construction are defined in terms of global variables. Users shouldn't +# notice unless they are trying to define multiple parsers at the same +# time using threads (in which case they should have their head examined). +# +# This implementation supports both SLR and LALR(1) parsing. LALR(1) +# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu), +# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles, +# Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced +# by the more efficient DeRemer and Pennello algorithm. +# +# :::::::: WARNING ::::::: +# +# Construction of LR parsing tables is fairly complicated and expensive. +# To make this module run fast, a *LOT* of work has been put into +# optimization---often at the expensive of readability and what might +# consider to be good Python "coding style." Modify the code at your +# own risk! +# ---------------------------------------------------------------------------- + +import re +import types +import sys +import os.path +import inspect +import base64 +import warnings + +__version__ = '3.10' +__tabversion__ = '3.10' + +#----------------------------------------------------------------------------- +# === User configurable parameters === +# +# Change these to modify the default behavior of yacc (if you wish) +#----------------------------------------------------------------------------- + +yaccdebug = True # Debugging mode. If set, yacc generates a + # a 'parser.out' file in the current directory + +debug_file = 'parser.out' # Default name of the debugging file +tab_module = 'parsetab' # Default name of the table module +default_lr = 'LALR' # Default LR table generation method + +error_count = 3 # Number of symbols that must be shifted to leave recovery mode + +yaccdevel = False # Set to True if developing yacc. This turns off optimized + # implementations of certain functions. + +resultlimit = 40 # Size limit of results when running in debug mode. + +pickle_protocol = 0 # Protocol to use when writing pickle files + +# String type-checking compatibility +if sys.version_info[0] < 3: + string_types = basestring +else: + string_types = str + +MAXINT = sys.maxsize + +# This object is a stand-in for a logging object created by the +# logging module. PLY will use this by default to create things +# such as the parser.out file. If a user wants more detailed +# information, they can create their own logging object and pass +# it into PLY. + +class PlyLogger(object): + def __init__(self, f): + self.f = f + + def debug(self, msg, *args, **kwargs): + self.f.write((msg % args) + '\n') + + info = debug + + def warning(self, msg, *args, **kwargs): + self.f.write('WARNING: ' + (msg % args) + '\n') + + def error(self, msg, *args, **kwargs): + self.f.write('ERROR: ' + (msg % args) + '\n') + + critical = debug + +# Null logger is used when no output is generated. Does nothing. +class NullLogger(object): + def __getattribute__(self, name): + return self + + def __call__(self, *args, **kwargs): + return self + +# Exception raised for yacc-related errors +class YaccError(Exception): + pass + +# Format the result message that the parser produces when running in debug mode. +def format_result(r): + repr_str = repr(r) + if '\n' in repr_str: + repr_str = repr(repr_str) + if len(repr_str) > resultlimit: + repr_str = repr_str[:resultlimit] + ' ...' + result = '<%s @ 0x%x> (%s)' % (type(r).__name__, id(r), repr_str) + return result + +# Format stack entries when the parser is running in debug mode +def format_stack_entry(r): + repr_str = repr(r) + if '\n' in repr_str: + repr_str = repr(repr_str) + if len(repr_str) < 16: + return repr_str + else: + return '<%s @ 0x%x>' % (type(r).__name__, id(r)) + +# Panic mode error recovery support. This feature is being reworked--much of the +# code here is to offer a deprecation/backwards compatible transition + +_errok = None +_token = None +_restart = None +_warnmsg = '''PLY: Don't use global functions errok(), token(), and restart() in p_error(). +Instead, invoke the methods on the associated parser instance: + + def p_error(p): + ... + # Use parser.errok(), parser.token(), parser.restart() + ... + + parser = yacc.yacc() +''' + +def errok(): + warnings.warn(_warnmsg) + return _errok() + +def restart(): + warnings.warn(_warnmsg) + return _restart() + +def token(): + warnings.warn(_warnmsg) + return _token() + +# Utility function to call the p_error() function with some deprecation hacks +def call_errorfunc(errorfunc, token, parser): + global _errok, _token, _restart + _errok = parser.errok + _token = parser.token + _restart = parser.restart + r = errorfunc(token) + try: + del _errok, _token, _restart + except NameError: + pass + return r + +#----------------------------------------------------------------------------- +# === LR Parsing Engine === +# +# The following classes are used for the LR parser itself. These are not +# used during table construction and are independent of the actual LR +# table generation algorithm +#----------------------------------------------------------------------------- + +# This class is used to hold non-terminal grammar symbols during parsing. +# It normally has the following attributes set: +# .type = Grammar symbol type +# .value = Symbol value +# .lineno = Starting line number +# .endlineno = Ending line number (optional, set automatically) +# .lexpos = Starting lex position +# .endlexpos = Ending lex position (optional, set automatically) + +class YaccSymbol: + def __str__(self): + return self.type + + def __repr__(self): + return str(self) + +# This class is a wrapper around the objects actually passed to each +# grammar rule. Index lookup and assignment actually assign the +# .value attribute of the underlying YaccSymbol object. +# The lineno() method returns the line number of a given +# item (or 0 if not defined). The linespan() method returns +# a tuple of (startline,endline) representing the range of lines +# for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos) +# representing the range of positional information for a symbol. + +class YaccProduction: + def __init__(self, s, stack=None): + self.slice = s + self.stack = stack + self.lexer = None + self.parser = None + + def __getitem__(self, n): + if isinstance(n, slice): + return [s.value for s in self.slice[n]] + elif n >= 0: + return self.slice[n].value + else: + return self.stack[n].value + + def __setitem__(self, n, v): + self.slice[n].value = v + + def __getslice__(self, i, j): + return [s.value for s in self.slice[i:j]] + + def __len__(self): + return len(self.slice) + + def lineno(self, n): + return getattr(self.slice[n], 'lineno', 0) + + def set_lineno(self, n, lineno): + self.slice[n].lineno = lineno + + def linespan(self, n): + startline = getattr(self.slice[n], 'lineno', 0) + endline = getattr(self.slice[n], 'endlineno', startline) + return startline, endline + + def lexpos(self, n): + return getattr(self.slice[n], 'lexpos', 0) + + def lexspan(self, n): + startpos = getattr(self.slice[n], 'lexpos', 0) + endpos = getattr(self.slice[n], 'endlexpos', startpos) + return startpos, endpos + + def error(self): + raise SyntaxError + +# ----------------------------------------------------------------------------- +# == LRParser == +# +# The LR Parsing engine. +# ----------------------------------------------------------------------------- + +class LRParser: + def __init__(self, lrtab, errorf): + self.productions = lrtab.lr_productions + self.action = lrtab.lr_action + self.goto = lrtab.lr_goto + self.errorfunc = errorf + self.set_defaulted_states() + self.errorok = True + + def errok(self): + self.errorok = True + + def restart(self): + del self.statestack[:] + del self.symstack[:] + sym = YaccSymbol() + sym.type = '$end' + self.symstack.append(sym) + self.statestack.append(0) + + # Defaulted state support. + # This method identifies parser states where there is only one possible reduction action. + # For such states, the parser can make a choose to make a rule reduction without consuming + # the next look-ahead token. This delayed invocation of the tokenizer can be useful in + # certain kinds of advanced parsing situations where the lexer and parser interact with + # each other or change states (i.e., manipulation of scope, lexer states, etc.). + # + # See: https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html#Default-Reductions + def set_defaulted_states(self): + self.defaulted_states = {} + for state, actions in self.action.items(): + rules = list(actions.values()) + if len(rules) == 1 and rules[0] < 0: + self.defaulted_states[state] = rules[0] + + def disable_defaulted_states(self): + self.defaulted_states = {} + + def parse(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None): + if debug or yaccdevel: + if isinstance(debug, int): + debug = PlyLogger(sys.stderr) + return self.parsedebug(input, lexer, debug, tracking, tokenfunc) + elif tracking: + return self.parseopt(input, lexer, debug, tracking, tokenfunc) + else: + return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc) + + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # parsedebug(). + # + # This is the debugging enabled version of parse(). All changes made to the + # parsing engine should be made here. Optimized versions of this function + # are automatically created by the ply/ygen.py script. This script cuts out + # sections enclosed in markers such as this: + # + # #--! DEBUG + # statements + # #--! DEBUG + # + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + def parsedebug(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None): + #--! parsedebug-start + lookahead = None # Current lookahead symbol + lookaheadstack = [] # Stack of lookahead symbols + actions = self.action # Local reference to action table (to avoid lookup on self.) + goto = self.goto # Local reference to goto table (to avoid lookup on self.) + prod = self.productions # Local reference to production list (to avoid lookup on self.) + defaulted_states = self.defaulted_states # Local reference to defaulted states + pslice = YaccProduction(None) # Production object passed to grammar rules + errorcount = 0 # Used during error recovery + + #--! DEBUG + debug.info('PLY: PARSE DEBUG START') + #--! DEBUG + + # If no lexer was given, we will try to use the lex module + if not lexer: + from . import lex + lexer = lex.lexer + + # Set up the lexer and parser objects on pslice + pslice.lexer = lexer + pslice.parser = self + + # If input was supplied, pass to lexer + if input is not None: + lexer.input(input) + + if tokenfunc is None: + # Tokenize function + get_token = lexer.token + else: + get_token = tokenfunc + + # Set the parser() token method (sometimes used in error recovery) + self.token = get_token + + # Set up the state and symbol stacks + + statestack = [] # Stack of parsing states + self.statestack = statestack + symstack = [] # Stack of grammar symbols + self.symstack = symstack + + pslice.stack = symstack # Put in the production + errtoken = None # Err token + + # The start state is assumed to be (0,$end) + + statestack.append(0) + sym = YaccSymbol() + sym.type = '$end' + symstack.append(sym) + state = 0 + while True: + # Get the next symbol on the input. If a lookahead symbol + # is already set, we just use that. Otherwise, we'll pull + # the next token off of the lookaheadstack or from the lexer + + #--! DEBUG + debug.debug('') + debug.debug('State : %s', state) + #--! DEBUG + + if state not in defaulted_states: + if not lookahead: + if not lookaheadstack: + lookahead = get_token() # Get the next token + else: + lookahead = lookaheadstack.pop() + if not lookahead: + lookahead = YaccSymbol() + lookahead.type = '$end' + + # Check the action table + ltype = lookahead.type + t = actions[state].get(ltype) + else: + t = defaulted_states[state] + #--! DEBUG + debug.debug('Defaulted state %s: Reduce using %d', state, -t) + #--! DEBUG + + #--! DEBUG + debug.debug('Stack : %s', + ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()) + #--! DEBUG + + if t is not None: + if t > 0: + # shift a symbol on the stack + statestack.append(t) + state = t + + #--! DEBUG + debug.debug('Action : Shift and goto state %s', t) + #--! DEBUG + + symstack.append(lookahead) + lookahead = None + + # Decrease error count on successful shift + if errorcount: + errorcount -= 1 + continue + + if t < 0: + # reduce a symbol on the stack, emit a production + p = prod[-t] + pname = p.name + plen = p.len + + # Get production function + sym = YaccSymbol() + sym.type = pname # Production name + sym.value = None + + #--! DEBUG + if plen: + debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str, + '['+','.join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+']', + goto[statestack[-1-plen]][pname]) + else: + debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str, [], + goto[statestack[-1]][pname]) + + #--! DEBUG + + if plen: + targ = symstack[-plen-1:] + targ[0] = sym + + #--! TRACKING + if tracking: + t1 = targ[1] + sym.lineno = t1.lineno + sym.lexpos = t1.lexpos + t1 = targ[-1] + sym.endlineno = getattr(t1, 'endlineno', t1.lineno) + sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos) + #--! TRACKING + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # below as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + del symstack[-plen:] + self.state = state + p.callable(pslice) + del statestack[-plen:] + #--! DEBUG + debug.info('Result : %s', format_result(pslice[0])) + #--! DEBUG + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + symstack.extend(targ[1:-1]) # Put the production slice back on the stack + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + else: + + #--! TRACKING + if tracking: + sym.lineno = lexer.lineno + sym.lexpos = lexer.lexpos + #--! TRACKING + + targ = [sym] + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # above as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + self.state = state + p.callable(pslice) + #--! DEBUG + debug.info('Result : %s', format_result(pslice[0])) + #--! DEBUG + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if t == 0: + n = symstack[-1] + result = getattr(n, 'value', None) + #--! DEBUG + debug.info('Done : Returning %s', format_result(result)) + debug.info('PLY: PARSE DEBUG END') + #--! DEBUG + return result + + if t is None: + + #--! DEBUG + debug.error('Error : %s', + ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()) + #--! DEBUG + + # We have some kind of parsing error here. To handle + # this, we are going to push the current token onto + # the tokenstack and replace it with an 'error' token. + # If there are any synchronization rules, they may + # catch it. + # + # In addition to pushing the error token, we call call + # the user defined p_error() function if this is the + # first syntax error. This function is only called if + # errorcount == 0. + if errorcount == 0 or self.errorok: + errorcount = error_count + self.errorok = False + errtoken = lookahead + if errtoken.type == '$end': + errtoken = None # End of file! + if self.errorfunc: + if errtoken and not hasattr(errtoken, 'lexer'): + errtoken.lexer = lexer + self.state = state + tok = call_errorfunc(self.errorfunc, errtoken, self) + if self.errorok: + # User must have done some kind of panic + # mode recovery on their own. The + # returned token is the next lookahead + lookahead = tok + errtoken = None + continue + else: + if errtoken: + if hasattr(errtoken, 'lineno'): + lineno = lookahead.lineno + else: + lineno = 0 + if lineno: + sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type)) + else: + sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type) + else: + sys.stderr.write('yacc: Parse error in input. EOF\n') + return + + else: + errorcount = error_count + + # case 1: the statestack only has 1 entry on it. If we're in this state, the + # entire parse has been rolled back and we're completely hosed. The token is + # discarded and we just keep going. + + if len(statestack) <= 1 and lookahead.type != '$end': + lookahead = None + errtoken = None + state = 0 + # Nuke the pushback stack + del lookaheadstack[:] + continue + + # case 2: the statestack has a couple of entries on it, but we're + # at the end of the file. nuke the top entry and generate an error token + + # Start nuking entries on the stack + if lookahead.type == '$end': + # Whoa. We're really hosed here. Bail out + return + + if lookahead.type != 'error': + sym = symstack[-1] + if sym.type == 'error': + # Hmmm. Error is on top of stack, we'll just nuke input + # symbol and continue + #--! TRACKING + if tracking: + sym.endlineno = getattr(lookahead, 'lineno', sym.lineno) + sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos) + #--! TRACKING + lookahead = None + continue + + # Create the error symbol for the first time and make it the new lookahead symbol + t = YaccSymbol() + t.type = 'error' + + if hasattr(lookahead, 'lineno'): + t.lineno = t.endlineno = lookahead.lineno + if hasattr(lookahead, 'lexpos'): + t.lexpos = t.endlexpos = lookahead.lexpos + t.value = lookahead + lookaheadstack.append(lookahead) + lookahead = t + else: + sym = symstack.pop() + #--! TRACKING + if tracking: + lookahead.lineno = sym.lineno + lookahead.lexpos = sym.lexpos + #--! TRACKING + statestack.pop() + state = statestack[-1] + + continue + + # Call an error function here + raise RuntimeError('yacc: internal parser error!!!\n') + + #--! parsedebug-end + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # parseopt(). + # + # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY! + # This code is automatically generated by the ply/ygen.py script. Make + # changes to the parsedebug() method instead. + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + def parseopt(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None): + #--! parseopt-start + lookahead = None # Current lookahead symbol + lookaheadstack = [] # Stack of lookahead symbols + actions = self.action # Local reference to action table (to avoid lookup on self.) + goto = self.goto # Local reference to goto table (to avoid lookup on self.) + prod = self.productions # Local reference to production list (to avoid lookup on self.) + defaulted_states = self.defaulted_states # Local reference to defaulted states + pslice = YaccProduction(None) # Production object passed to grammar rules + errorcount = 0 # Used during error recovery + + + # If no lexer was given, we will try to use the lex module + if not lexer: + from . import lex + lexer = lex.lexer + + # Set up the lexer and parser objects on pslice + pslice.lexer = lexer + pslice.parser = self + + # If input was supplied, pass to lexer + if input is not None: + lexer.input(input) + + if tokenfunc is None: + # Tokenize function + get_token = lexer.token + else: + get_token = tokenfunc + + # Set the parser() token method (sometimes used in error recovery) + self.token = get_token + + # Set up the state and symbol stacks + + statestack = [] # Stack of parsing states + self.statestack = statestack + symstack = [] # Stack of grammar symbols + self.symstack = symstack + + pslice.stack = symstack # Put in the production + errtoken = None # Err token + + # The start state is assumed to be (0,$end) + + statestack.append(0) + sym = YaccSymbol() + sym.type = '$end' + symstack.append(sym) + state = 0 + while True: + # Get the next symbol on the input. If a lookahead symbol + # is already set, we just use that. Otherwise, we'll pull + # the next token off of the lookaheadstack or from the lexer + + + if state not in defaulted_states: + if not lookahead: + if not lookaheadstack: + lookahead = get_token() # Get the next token + else: + lookahead = lookaheadstack.pop() + if not lookahead: + lookahead = YaccSymbol() + lookahead.type = '$end' + + # Check the action table + ltype = lookahead.type + t = actions[state].get(ltype) + else: + t = defaulted_states[state] + + + if t is not None: + if t > 0: + # shift a symbol on the stack + statestack.append(t) + state = t + + + symstack.append(lookahead) + lookahead = None + + # Decrease error count on successful shift + if errorcount: + errorcount -= 1 + continue + + if t < 0: + # reduce a symbol on the stack, emit a production + p = prod[-t] + pname = p.name + plen = p.len + + # Get production function + sym = YaccSymbol() + sym.type = pname # Production name + sym.value = None + + + if plen: + targ = symstack[-plen-1:] + targ[0] = sym + + #--! TRACKING + if tracking: + t1 = targ[1] + sym.lineno = t1.lineno + sym.lexpos = t1.lexpos + t1 = targ[-1] + sym.endlineno = getattr(t1, 'endlineno', t1.lineno) + sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos) + #--! TRACKING + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # below as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + del symstack[-plen:] + self.state = state + p.callable(pslice) + del statestack[-plen:] + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + symstack.extend(targ[1:-1]) # Put the production slice back on the stack + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + else: + + #--! TRACKING + if tracking: + sym.lineno = lexer.lineno + sym.lexpos = lexer.lexpos + #--! TRACKING + + targ = [sym] + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # above as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + self.state = state + p.callable(pslice) + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if t == 0: + n = symstack[-1] + result = getattr(n, 'value', None) + return result + + if t is None: + + + # We have some kind of parsing error here. To handle + # this, we are going to push the current token onto + # the tokenstack and replace it with an 'error' token. + # If there are any synchronization rules, they may + # catch it. + # + # In addition to pushing the error token, we call call + # the user defined p_error() function if this is the + # first syntax error. This function is only called if + # errorcount == 0. + if errorcount == 0 or self.errorok: + errorcount = error_count + self.errorok = False + errtoken = lookahead + if errtoken.type == '$end': + errtoken = None # End of file! + if self.errorfunc: + if errtoken and not hasattr(errtoken, 'lexer'): + errtoken.lexer = lexer + self.state = state + tok = call_errorfunc(self.errorfunc, errtoken, self) + if self.errorok: + # User must have done some kind of panic + # mode recovery on their own. The + # returned token is the next lookahead + lookahead = tok + errtoken = None + continue + else: + if errtoken: + if hasattr(errtoken, 'lineno'): + lineno = lookahead.lineno + else: + lineno = 0 + if lineno: + sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type)) + else: + sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type) + else: + sys.stderr.write('yacc: Parse error in input. EOF\n') + return + + else: + errorcount = error_count + + # case 1: the statestack only has 1 entry on it. If we're in this state, the + # entire parse has been rolled back and we're completely hosed. The token is + # discarded and we just keep going. + + if len(statestack) <= 1 and lookahead.type != '$end': + lookahead = None + errtoken = None + state = 0 + # Nuke the pushback stack + del lookaheadstack[:] + continue + + # case 2: the statestack has a couple of entries on it, but we're + # at the end of the file. nuke the top entry and generate an error token + + # Start nuking entries on the stack + if lookahead.type == '$end': + # Whoa. We're really hosed here. Bail out + return + + if lookahead.type != 'error': + sym = symstack[-1] + if sym.type == 'error': + # Hmmm. Error is on top of stack, we'll just nuke input + # symbol and continue + #--! TRACKING + if tracking: + sym.endlineno = getattr(lookahead, 'lineno', sym.lineno) + sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos) + #--! TRACKING + lookahead = None + continue + + # Create the error symbol for the first time and make it the new lookahead symbol + t = YaccSymbol() + t.type = 'error' + + if hasattr(lookahead, 'lineno'): + t.lineno = t.endlineno = lookahead.lineno + if hasattr(lookahead, 'lexpos'): + t.lexpos = t.endlexpos = lookahead.lexpos + t.value = lookahead + lookaheadstack.append(lookahead) + lookahead = t + else: + sym = symstack.pop() + #--! TRACKING + if tracking: + lookahead.lineno = sym.lineno + lookahead.lexpos = sym.lexpos + #--! TRACKING + statestack.pop() + state = statestack[-1] + + continue + + # Call an error function here + raise RuntimeError('yacc: internal parser error!!!\n') + + #--! parseopt-end + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # parseopt_notrack(). + # + # Optimized version of parseopt() with line number tracking removed. + # DO NOT EDIT THIS CODE DIRECTLY. This code is automatically generated + # by the ply/ygen.py script. Make changes to the parsedebug() method instead. + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + def parseopt_notrack(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None): + #--! parseopt-notrack-start + lookahead = None # Current lookahead symbol + lookaheadstack = [] # Stack of lookahead symbols + actions = self.action # Local reference to action table (to avoid lookup on self.) + goto = self.goto # Local reference to goto table (to avoid lookup on self.) + prod = self.productions # Local reference to production list (to avoid lookup on self.) + defaulted_states = self.defaulted_states # Local reference to defaulted states + pslice = YaccProduction(None) # Production object passed to grammar rules + errorcount = 0 # Used during error recovery + + + # If no lexer was given, we will try to use the lex module + if not lexer: + from . import lex + lexer = lex.lexer + + # Set up the lexer and parser objects on pslice + pslice.lexer = lexer + pslice.parser = self + + # If input was supplied, pass to lexer + if input is not None: + lexer.input(input) + + if tokenfunc is None: + # Tokenize function + get_token = lexer.token + else: + get_token = tokenfunc + + # Set the parser() token method (sometimes used in error recovery) + self.token = get_token + + # Set up the state and symbol stacks + + statestack = [] # Stack of parsing states + self.statestack = statestack + symstack = [] # Stack of grammar symbols + self.symstack = symstack + + pslice.stack = symstack # Put in the production + errtoken = None # Err token + + # The start state is assumed to be (0,$end) + + statestack.append(0) + sym = YaccSymbol() + sym.type = '$end' + symstack.append(sym) + state = 0 + while True: + # Get the next symbol on the input. If a lookahead symbol + # is already set, we just use that. Otherwise, we'll pull + # the next token off of the lookaheadstack or from the lexer + + + if state not in defaulted_states: + if not lookahead: + if not lookaheadstack: + lookahead = get_token() # Get the next token + else: + lookahead = lookaheadstack.pop() + if not lookahead: + lookahead = YaccSymbol() + lookahead.type = '$end' + + # Check the action table + ltype = lookahead.type + t = actions[state].get(ltype) + else: + t = defaulted_states[state] + + + if t is not None: + if t > 0: + # shift a symbol on the stack + statestack.append(t) + state = t + + + symstack.append(lookahead) + lookahead = None + + # Decrease error count on successful shift + if errorcount: + errorcount -= 1 + continue + + if t < 0: + # reduce a symbol on the stack, emit a production + p = prod[-t] + pname = p.name + plen = p.len + + # Get production function + sym = YaccSymbol() + sym.type = pname # Production name + sym.value = None + + + if plen: + targ = symstack[-plen-1:] + targ[0] = sym + + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # below as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + del symstack[-plen:] + self.state = state + p.callable(pslice) + del statestack[-plen:] + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + symstack.extend(targ[1:-1]) # Put the production slice back on the stack + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + else: + + + targ = [sym] + + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # The code enclosed in this section is duplicated + # above as a performance optimization. Make sure + # changes get made in both locations. + + pslice.slice = targ + + try: + # Call the grammar rule with our special slice object + self.state = state + p.callable(pslice) + symstack.append(sym) + state = goto[statestack[-1]][pname] + statestack.append(state) + except SyntaxError: + # If an error was set. Enter error recovery state + lookaheadstack.append(lookahead) # Save the current lookahead token + statestack.pop() # Pop back one state (before the reduce) + state = statestack[-1] + sym.type = 'error' + sym.value = 'error' + lookahead = sym + errorcount = error_count + self.errorok = False + + continue + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if t == 0: + n = symstack[-1] + result = getattr(n, 'value', None) + return result + + if t is None: + + + # We have some kind of parsing error here. To handle + # this, we are going to push the current token onto + # the tokenstack and replace it with an 'error' token. + # If there are any synchronization rules, they may + # catch it. + # + # In addition to pushing the error token, we call call + # the user defined p_error() function if this is the + # first syntax error. This function is only called if + # errorcount == 0. + if errorcount == 0 or self.errorok: + errorcount = error_count + self.errorok = False + errtoken = lookahead + if errtoken.type == '$end': + errtoken = None # End of file! + if self.errorfunc: + if errtoken and not hasattr(errtoken, 'lexer'): + errtoken.lexer = lexer + self.state = state + tok = call_errorfunc(self.errorfunc, errtoken, self) + if self.errorok: + # User must have done some kind of panic + # mode recovery on their own. The + # returned token is the next lookahead + lookahead = tok + errtoken = None + continue + else: + if errtoken: + if hasattr(errtoken, 'lineno'): + lineno = lookahead.lineno + else: + lineno = 0 + if lineno: + sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type)) + else: + sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type) + else: + sys.stderr.write('yacc: Parse error in input. EOF\n') + return + + else: + errorcount = error_count + + # case 1: the statestack only has 1 entry on it. If we're in this state, the + # entire parse has been rolled back and we're completely hosed. The token is + # discarded and we just keep going. + + if len(statestack) <= 1 and lookahead.type != '$end': + lookahead = None + errtoken = None + state = 0 + # Nuke the pushback stack + del lookaheadstack[:] + continue + + # case 2: the statestack has a couple of entries on it, but we're + # at the end of the file. nuke the top entry and generate an error token + + # Start nuking entries on the stack + if lookahead.type == '$end': + # Whoa. We're really hosed here. Bail out + return + + if lookahead.type != 'error': + sym = symstack[-1] + if sym.type == 'error': + # Hmmm. Error is on top of stack, we'll just nuke input + # symbol and continue + lookahead = None + continue + + # Create the error symbol for the first time and make it the new lookahead symbol + t = YaccSymbol() + t.type = 'error' + + if hasattr(lookahead, 'lineno'): + t.lineno = t.endlineno = lookahead.lineno + if hasattr(lookahead, 'lexpos'): + t.lexpos = t.endlexpos = lookahead.lexpos + t.value = lookahead + lookaheadstack.append(lookahead) + lookahead = t + else: + sym = symstack.pop() + statestack.pop() + state = statestack[-1] + + continue + + # Call an error function here + raise RuntimeError('yacc: internal parser error!!!\n') + + #--! parseopt-notrack-end + +# ----------------------------------------------------------------------------- +# === Grammar Representation === +# +# The following functions, classes, and variables are used to represent and +# manipulate the rules that make up a grammar. +# ----------------------------------------------------------------------------- + +# regex matching identifiers +_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$') + +# ----------------------------------------------------------------------------- +# class Production: +# +# This class stores the raw information about a single production or grammar rule. +# A grammar rule refers to a specification such as this: +# +# expr : expr PLUS term +# +# Here are the basic attributes defined on all productions +# +# name - Name of the production. For example 'expr' +# prod - A list of symbols on the right side ['expr','PLUS','term'] +# prec - Production precedence level +# number - Production number. +# func - Function that executes on reduce +# file - File where production function is defined +# lineno - Line number where production function is defined +# +# The following attributes are defined or optional. +# +# len - Length of the production (number of symbols on right hand side) +# usyms - Set of unique symbols found in the production +# ----------------------------------------------------------------------------- + +class Production(object): + reduced = 0 + def __init__(self, number, name, prod, precedence=('right', 0), func=None, file='', line=0): + self.name = name + self.prod = tuple(prod) + self.number = number + self.func = func + self.callable = None + self.file = file + self.line = line + self.prec = precedence + + # Internal settings used during table construction + + self.len = len(self.prod) # Length of the production + + # Create a list of unique production symbols used in the production + self.usyms = [] + for s in self.prod: + if s not in self.usyms: + self.usyms.append(s) + + # List of all LR items for the production + self.lr_items = [] + self.lr_next = None + + # Create a string representation + if self.prod: + self.str = '%s -> %s' % (self.name, ' '.join(self.prod)) + else: + self.str = '%s -> ' % self.name + + def __str__(self): + return self.str + + def __repr__(self): + return 'Production(' + str(self) + ')' + + def __len__(self): + return len(self.prod) + + def __nonzero__(self): + return 1 + + def __getitem__(self, index): + return self.prod[index] + + # Return the nth lr_item from the production (or None if at the end) + def lr_item(self, n): + if n > len(self.prod): + return None + p = LRItem(self, n) + # Precompute the list of productions immediately following. + try: + p.lr_after = Prodnames[p.prod[n+1]] + except (IndexError, KeyError): + p.lr_after = [] + try: + p.lr_before = p.prod[n-1] + except IndexError: + p.lr_before = None + return p + + # Bind the production function name to a callable + def bind(self, pdict): + if self.func: + self.callable = pdict[self.func] + +# This class serves as a minimal standin for Production objects when +# reading table data from files. It only contains information +# actually used by the LR parsing engine, plus some additional +# debugging information. +class MiniProduction(object): + def __init__(self, str, name, len, func, file, line): + self.name = name + self.len = len + self.func = func + self.callable = None + self.file = file + self.line = line + self.str = str + + def __str__(self): + return self.str + + def __repr__(self): + return 'MiniProduction(%s)' % self.str + + # Bind the production function name to a callable + def bind(self, pdict): + if self.func: + self.callable = pdict[self.func] + + +# ----------------------------------------------------------------------------- +# class LRItem +# +# This class represents a specific stage of parsing a production rule. For +# example: +# +# expr : expr . PLUS term +# +# In the above, the "." represents the current location of the parse. Here +# basic attributes: +# +# name - Name of the production. For example 'expr' +# prod - A list of symbols on the right side ['expr','.', 'PLUS','term'] +# number - Production number. +# +# lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term' +# then lr_next refers to 'expr -> expr PLUS . term' +# lr_index - LR item index (location of the ".") in the prod list. +# lookaheads - LALR lookahead symbols for this item +# len - Length of the production (number of symbols on right hand side) +# lr_after - List of all productions that immediately follow +# lr_before - Grammar symbol immediately before +# ----------------------------------------------------------------------------- + +class LRItem(object): + def __init__(self, p, n): + self.name = p.name + self.prod = list(p.prod) + self.number = p.number + self.lr_index = n + self.lookaheads = {} + self.prod.insert(n, '.') + self.prod = tuple(self.prod) + self.len = len(self.prod) + self.usyms = p.usyms + + def __str__(self): + if self.prod: + s = '%s -> %s' % (self.name, ' '.join(self.prod)) + else: + s = '%s -> ' % self.name + return s + + def __repr__(self): + return 'LRItem(' + str(self) + ')' + +# ----------------------------------------------------------------------------- +# rightmost_terminal() +# +# Return the rightmost terminal from a list of symbols. Used in add_production() +# ----------------------------------------------------------------------------- +def rightmost_terminal(symbols, terminals): + i = len(symbols) - 1 + while i >= 0: + if symbols[i] in terminals: + return symbols[i] + i -= 1 + return None + +# ----------------------------------------------------------------------------- +# === GRAMMAR CLASS === +# +# The following class represents the contents of the specified grammar along +# with various computed properties such as first sets, follow sets, LR items, etc. +# This data is used for critical parts of the table generation process later. +# ----------------------------------------------------------------------------- + +class GrammarError(YaccError): + pass + +class Grammar(object): + def __init__(self, terminals): + self.Productions = [None] # A list of all of the productions. The first + # entry is always reserved for the purpose of + # building an augmented grammar + + self.Prodnames = {} # A dictionary mapping the names of nonterminals to a list of all + # productions of that nonterminal. + + self.Prodmap = {} # A dictionary that is only used to detect duplicate + # productions. + + self.Terminals = {} # A dictionary mapping the names of terminal symbols to a + # list of the rules where they are used. + + for term in terminals: + self.Terminals[term] = [] + + self.Terminals['error'] = [] + + self.Nonterminals = {} # A dictionary mapping names of nonterminals to a list + # of rule numbers where they are used. + + self.First = {} # A dictionary of precomputed FIRST(x) symbols + + self.Follow = {} # A dictionary of precomputed FOLLOW(x) symbols + + self.Precedence = {} # Precedence rules for each terminal. Contains tuples of the + # form ('right',level) or ('nonassoc', level) or ('left',level) + + self.UsedPrecedence = set() # Precedence rules that were actually used by the grammer. + # This is only used to provide error checking and to generate + # a warning about unused precedence rules. + + self.Start = None # Starting symbol for the grammar + + + def __len__(self): + return len(self.Productions) + + def __getitem__(self, index): + return self.Productions[index] + + # ----------------------------------------------------------------------------- + # set_precedence() + # + # Sets the precedence for a given terminal. assoc is the associativity such as + # 'left','right', or 'nonassoc'. level is a numeric level. + # + # ----------------------------------------------------------------------------- + + def set_precedence(self, term, assoc, level): + assert self.Productions == [None], 'Must call set_precedence() before add_production()' + if term in self.Precedence: + raise GrammarError('Precedence already specified for terminal %r' % term) + if assoc not in ['left', 'right', 'nonassoc']: + raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'") + self.Precedence[term] = (assoc, level) + + # ----------------------------------------------------------------------------- + # add_production() + # + # Given an action function, this function assembles a production rule and + # computes its precedence level. + # + # The production rule is supplied as a list of symbols. For example, + # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and + # symbols ['expr','PLUS','term']. + # + # Precedence is determined by the precedence of the right-most non-terminal + # or the precedence of a terminal specified by %prec. + # + # A variety of error checks are performed to make sure production symbols + # are valid and that %prec is used correctly. + # ----------------------------------------------------------------------------- + + def add_production(self, prodname, syms, func=None, file='', line=0): + + if prodname in self.Terminals: + raise GrammarError('%s:%d: Illegal rule name %r. Already defined as a token' % (file, line, prodname)) + if prodname == 'error': + raise GrammarError('%s:%d: Illegal rule name %r. error is a reserved word' % (file, line, prodname)) + if not _is_identifier.match(prodname): + raise GrammarError('%s:%d: Illegal rule name %r' % (file, line, prodname)) + + # Look for literal tokens + for n, s in enumerate(syms): + if s[0] in "'\"": + try: + c = eval(s) + if (len(c) > 1): + raise GrammarError('%s:%d: Literal token %s in rule %r may only be a single character' % + (file, line, s, prodname)) + if c not in self.Terminals: + self.Terminals[c] = [] + syms[n] = c + continue + except SyntaxError: + pass + if not _is_identifier.match(s) and s != '%prec': + raise GrammarError('%s:%d: Illegal name %r in rule %r' % (file, line, s, prodname)) + + # Determine the precedence level + if '%prec' in syms: + if syms[-1] == '%prec': + raise GrammarError('%s:%d: Syntax error. Nothing follows %%prec' % (file, line)) + if syms[-2] != '%prec': + raise GrammarError('%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule' % + (file, line)) + precname = syms[-1] + prodprec = self.Precedence.get(precname) + if not prodprec: + raise GrammarError('%s:%d: Nothing known about the precedence of %r' % (file, line, precname)) + else: + self.UsedPrecedence.add(precname) + del syms[-2:] # Drop %prec from the rule + else: + # If no %prec, precedence is determined by the rightmost terminal symbol + precname = rightmost_terminal(syms, self.Terminals) + prodprec = self.Precedence.get(precname, ('right', 0)) + + # See if the rule is already in the rulemap + map = '%s -> %s' % (prodname, syms) + if map in self.Prodmap: + m = self.Prodmap[map] + raise GrammarError('%s:%d: Duplicate rule %s. ' % (file, line, m) + + 'Previous definition at %s:%d' % (m.file, m.line)) + + # From this point on, everything is valid. Create a new Production instance + pnumber = len(self.Productions) + if prodname not in self.Nonterminals: + self.Nonterminals[prodname] = [] + + # Add the production number to Terminals and Nonterminals + for t in syms: + if t in self.Terminals: + self.Terminals[t].append(pnumber) + else: + if t not in self.Nonterminals: + self.Nonterminals[t] = [] + self.Nonterminals[t].append(pnumber) + + # Create a production and add it to the list of productions + p = Production(pnumber, prodname, syms, prodprec, func, file, line) + self.Productions.append(p) + self.Prodmap[map] = p + + # Add to the global productions list + try: + self.Prodnames[prodname].append(p) + except KeyError: + self.Prodnames[prodname] = [p] + + # ----------------------------------------------------------------------------- + # set_start() + # + # Sets the starting symbol and creates the augmented grammar. Production + # rule 0 is S' -> start where start is the start symbol. + # ----------------------------------------------------------------------------- + + def set_start(self, start=None): + if not start: + start = self.Productions[1].name + if start not in self.Nonterminals: + raise GrammarError('start symbol %s undefined' % start) + self.Productions[0] = Production(0, "S'", [start]) + self.Nonterminals[start].append(0) + self.Start = start + + # ----------------------------------------------------------------------------- + # find_unreachable() + # + # Find all of the nonterminal symbols that can't be reached from the starting + # symbol. Returns a list of nonterminals that can't be reached. + # ----------------------------------------------------------------------------- + + def find_unreachable(self): + + # Mark all symbols that are reachable from a symbol s + def mark_reachable_from(s): + if s in reachable: + return + reachable.add(s) + for p in self.Prodnames.get(s, []): + for r in p.prod: + mark_reachable_from(r) + + reachable = set() + mark_reachable_from(self.Productions[0].prod[0]) + return [s for s in self.Nonterminals if s not in reachable] + + # ----------------------------------------------------------------------------- + # infinite_cycles() + # + # This function looks at the various parsing rules and tries to detect + # infinite recursion cycles (grammar rules where there is no possible way + # to derive a string of only terminals). + # ----------------------------------------------------------------------------- + + def infinite_cycles(self): + terminates = {} + + # Terminals: + for t in self.Terminals: + terminates[t] = True + + terminates['$end'] = True + + # Nonterminals: + + # Initialize to false: + for n in self.Nonterminals: + terminates[n] = False + + # Then propagate termination until no change: + while True: + some_change = False + for (n, pl) in self.Prodnames.items(): + # Nonterminal n terminates iff any of its productions terminates. + for p in pl: + # Production p terminates iff all of its rhs symbols terminate. + for s in p.prod: + if not terminates[s]: + # The symbol s does not terminate, + # so production p does not terminate. + p_terminates = False + break + else: + # didn't break from the loop, + # so every symbol s terminates + # so production p terminates. + p_terminates = True + + if p_terminates: + # symbol n terminates! + if not terminates[n]: + terminates[n] = True + some_change = True + # Don't need to consider any more productions for this n. + break + + if not some_change: + break + + infinite = [] + for (s, term) in terminates.items(): + if not term: + if s not in self.Prodnames and s not in self.Terminals and s != 'error': + # s is used-but-not-defined, and we've already warned of that, + # so it would be overkill to say that it's also non-terminating. + pass + else: + infinite.append(s) + + return infinite + + # ----------------------------------------------------------------------------- + # undefined_symbols() + # + # Find all symbols that were used the grammar, but not defined as tokens or + # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol + # and prod is the production where the symbol was used. + # ----------------------------------------------------------------------------- + def undefined_symbols(self): + result = [] + for p in self.Productions: + if not p: + continue + + for s in p.prod: + if s not in self.Prodnames and s not in self.Terminals and s != 'error': + result.append((s, p)) + return result + + # ----------------------------------------------------------------------------- + # unused_terminals() + # + # Find all terminals that were defined, but not used by the grammar. Returns + # a list of all symbols. + # ----------------------------------------------------------------------------- + def unused_terminals(self): + unused_tok = [] + for s, v in self.Terminals.items(): + if s != 'error' and not v: + unused_tok.append(s) + + return unused_tok + + # ------------------------------------------------------------------------------ + # unused_rules() + # + # Find all grammar rules that were defined, but not used (maybe not reachable) + # Returns a list of productions. + # ------------------------------------------------------------------------------ + + def unused_rules(self): + unused_prod = [] + for s, v in self.Nonterminals.items(): + if not v: + p = self.Prodnames[s][0] + unused_prod.append(p) + return unused_prod + + # ----------------------------------------------------------------------------- + # unused_precedence() + # + # Returns a list of tuples (term,precedence) corresponding to precedence + # rules that were never used by the grammar. term is the name of the terminal + # on which precedence was applied and precedence is a string such as 'left' or + # 'right' corresponding to the type of precedence. + # ----------------------------------------------------------------------------- + + def unused_precedence(self): + unused = [] + for termname in self.Precedence: + if not (termname in self.Terminals or termname in self.UsedPrecedence): + unused.append((termname, self.Precedence[termname][0])) + + return unused + + # ------------------------------------------------------------------------- + # _first() + # + # Compute the value of FIRST1(beta) where beta is a tuple of symbols. + # + # During execution of compute_first1, the result may be incomplete. + # Afterward (e.g., when called from compute_follow()), it will be complete. + # ------------------------------------------------------------------------- + def _first(self, beta): + + # We are computing First(x1,x2,x3,...,xn) + result = [] + for x in beta: + x_produces_empty = False + + # Add all the non- symbols of First[x] to the result. + for f in self.First[x]: + if f == '': + x_produces_empty = True + else: + if f not in result: + result.append(f) + + if x_produces_empty: + # We have to consider the next x in beta, + # i.e. stay in the loop. + pass + else: + # We don't have to consider any further symbols in beta. + break + else: + # There was no 'break' from the loop, + # so x_produces_empty was true for all x in beta, + # so beta produces empty as well. + result.append('') + + return result + + # ------------------------------------------------------------------------- + # compute_first() + # + # Compute the value of FIRST1(X) for all symbols + # ------------------------------------------------------------------------- + def compute_first(self): + if self.First: + return self.First + + # Terminals: + for t in self.Terminals: + self.First[t] = [t] + + self.First['$end'] = ['$end'] + + # Nonterminals: + + # Initialize to the empty set: + for n in self.Nonterminals: + self.First[n] = [] + + # Then propagate symbols until no change: + while True: + some_change = False + for n in self.Nonterminals: + for p in self.Prodnames[n]: + for f in self._first(p.prod): + if f not in self.First[n]: + self.First[n].append(f) + some_change = True + if not some_change: + break + + return self.First + + # --------------------------------------------------------------------- + # compute_follow() + # + # Computes all of the follow sets for every non-terminal symbol. The + # follow set is the set of all symbols that might follow a given + # non-terminal. See the Dragon book, 2nd Ed. p. 189. + # --------------------------------------------------------------------- + def compute_follow(self, start=None): + # If already computed, return the result + if self.Follow: + return self.Follow + + # If first sets not computed yet, do that first. + if not self.First: + self.compute_first() + + # Add '$end' to the follow list of the start symbol + for k in self.Nonterminals: + self.Follow[k] = [] + + if not start: + start = self.Productions[1].name + + self.Follow[start] = ['$end'] + + while True: + didadd = False + for p in self.Productions[1:]: + # Here is the production set + for i, B in enumerate(p.prod): + if B in self.Nonterminals: + # Okay. We got a non-terminal in a production + fst = self._first(p.prod[i+1:]) + hasempty = False + for f in fst: + if f != '' and f not in self.Follow[B]: + self.Follow[B].append(f) + didadd = True + if f == '': + hasempty = True + if hasempty or i == (len(p.prod)-1): + # Add elements of follow(a) to follow(b) + for f in self.Follow[p.name]: + if f not in self.Follow[B]: + self.Follow[B].append(f) + didadd = True + if not didadd: + break + return self.Follow + + + # ----------------------------------------------------------------------------- + # build_lritems() + # + # This function walks the list of productions and builds a complete set of the + # LR items. The LR items are stored in two ways: First, they are uniquely + # numbered and placed in the list _lritems. Second, a linked list of LR items + # is built for each production. For example: + # + # E -> E PLUS E + # + # Creates the list + # + # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ] + # ----------------------------------------------------------------------------- + + def build_lritems(self): + for p in self.Productions: + lastlri = p + i = 0 + lr_items = [] + while True: + if i > len(p): + lri = None + else: + lri = LRItem(p, i) + # Precompute the list of productions immediately following + try: + lri.lr_after = self.Prodnames[lri.prod[i+1]] + except (IndexError, KeyError): + lri.lr_after = [] + try: + lri.lr_before = lri.prod[i-1] + except IndexError: + lri.lr_before = None + + lastlri.lr_next = lri + if not lri: + break + lr_items.append(lri) + lastlri = lri + i += 1 + p.lr_items = lr_items + +# ----------------------------------------------------------------------------- +# == Class LRTable == +# +# This basic class represents a basic table of LR parsing information. +# Methods for generating the tables are not defined here. They are defined +# in the derived class LRGeneratedTable. +# ----------------------------------------------------------------------------- + +class VersionError(YaccError): + pass + +class LRTable(object): + def __init__(self): + self.lr_action = None + self.lr_goto = None + self.lr_productions = None + self.lr_method = None + + def read_table(self, module): + if isinstance(module, types.ModuleType): + parsetab = module + else: + exec('import %s' % module) + parsetab = sys.modules[module] + + if parsetab._tabversion != __tabversion__: + raise VersionError('yacc table file version is out of date') + + self.lr_action = parsetab._lr_action + self.lr_goto = parsetab._lr_goto + + self.lr_productions = [] + for p in parsetab._lr_productions: + self.lr_productions.append(MiniProduction(*p)) + + self.lr_method = parsetab._lr_method + return parsetab._lr_signature + + def read_pickle(self, filename): + try: + import cPickle as pickle + except ImportError: + import pickle + + if not os.path.exists(filename): + raise ImportError + + in_f = open(filename, 'rb') + + tabversion = pickle.load(in_f) + if tabversion != __tabversion__: + raise VersionError('yacc table file version is out of date') + self.lr_method = pickle.load(in_f) + signature = pickle.load(in_f) + self.lr_action = pickle.load(in_f) + self.lr_goto = pickle.load(in_f) + productions = pickle.load(in_f) + + self.lr_productions = [] + for p in productions: + self.lr_productions.append(MiniProduction(*p)) + + in_f.close() + return signature + + # Bind all production function names to callable objects in pdict + def bind_callables(self, pdict): + for p in self.lr_productions: + p.bind(pdict) + + +# ----------------------------------------------------------------------------- +# === LR Generator === +# +# The following classes and functions are used to generate LR parsing tables on +# a grammar. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# digraph() +# traverse() +# +# The following two functions are used to compute set valued functions +# of the form: +# +# F(x) = F'(x) U U{F(y) | x R y} +# +# This is used to compute the values of Read() sets as well as FOLLOW sets +# in LALR(1) generation. +# +# Inputs: X - An input set +# R - A relation +# FP - Set-valued function +# ------------------------------------------------------------------------------ + +def digraph(X, R, FP): + N = {} + for x in X: + N[x] = 0 + stack = [] + F = {} + for x in X: + if N[x] == 0: + traverse(x, N, stack, F, X, R, FP) + return F + +def traverse(x, N, stack, F, X, R, FP): + stack.append(x) + d = len(stack) + N[x] = d + F[x] = FP(x) # F(X) <- F'(x) + + rel = R(x) # Get y's related to x + for y in rel: + if N[y] == 0: + traverse(y, N, stack, F, X, R, FP) + N[x] = min(N[x], N[y]) + for a in F.get(y, []): + if a not in F[x]: + F[x].append(a) + if N[x] == d: + N[stack[-1]] = MAXINT + F[stack[-1]] = F[x] + element = stack.pop() + while element != x: + N[stack[-1]] = MAXINT + F[stack[-1]] = F[x] + element = stack.pop() + +class LALRError(YaccError): + pass + +# ----------------------------------------------------------------------------- +# == LRGeneratedTable == +# +# This class implements the LR table generation algorithm. There are no +# public methods except for write() +# ----------------------------------------------------------------------------- + +class LRGeneratedTable(LRTable): + def __init__(self, grammar, method='LALR', log=None): + if method not in ['SLR', 'LALR']: + raise LALRError('Unsupported method %s' % method) + + self.grammar = grammar + self.lr_method = method + + # Set up the logger + if not log: + log = NullLogger() + self.log = log + + # Internal attributes + self.lr_action = {} # Action table + self.lr_goto = {} # Goto table + self.lr_productions = grammar.Productions # Copy of grammar Production array + self.lr_goto_cache = {} # Cache of computed gotos + self.lr0_cidhash = {} # Cache of closures + + self._add_count = 0 # Internal counter used to detect cycles + + # Diagonistic information filled in by the table generator + self.sr_conflict = 0 + self.rr_conflict = 0 + self.conflicts = [] # List of conflicts + + self.sr_conflicts = [] + self.rr_conflicts = [] + + # Build the tables + self.grammar.build_lritems() + self.grammar.compute_first() + self.grammar.compute_follow() + self.lr_parse_table() + + # Compute the LR(0) closure operation on I, where I is a set of LR(0) items. + + def lr0_closure(self, I): + self._add_count += 1 + + # Add everything in I to J + J = I[:] + didadd = True + while didadd: + didadd = False + for j in J: + for x in j.lr_after: + if getattr(x, 'lr0_added', 0) == self._add_count: + continue + # Add B --> .G to J + J.append(x.lr_next) + x.lr0_added = self._add_count + didadd = True + + return J + + # Compute the LR(0) goto function goto(I,X) where I is a set + # of LR(0) items and X is a grammar symbol. This function is written + # in a way that guarantees uniqueness of the generated goto sets + # (i.e. the same goto set will never be returned as two different Python + # objects). With uniqueness, we can later do fast set comparisons using + # id(obj) instead of element-wise comparison. + + def lr0_goto(self, I, x): + # First we look for a previously cached entry + g = self.lr_goto_cache.get((id(I), x)) + if g: + return g + + # Now we generate the goto set in a way that guarantees uniqueness + # of the result + + s = self.lr_goto_cache.get(x) + if not s: + s = {} + self.lr_goto_cache[x] = s + + gs = [] + for p in I: + n = p.lr_next + if n and n.lr_before == x: + s1 = s.get(id(n)) + if not s1: + s1 = {} + s[id(n)] = s1 + gs.append(n) + s = s1 + g = s.get('$end') + if not g: + if gs: + g = self.lr0_closure(gs) + s['$end'] = g + else: + s['$end'] = gs + self.lr_goto_cache[(id(I), x)] = g + return g + + # Compute the LR(0) sets of item function + def lr0_items(self): + C = [self.lr0_closure([self.grammar.Productions[0].lr_next])] + i = 0 + for I in C: + self.lr0_cidhash[id(I)] = i + i += 1 + + # Loop over the items in C and each grammar symbols + i = 0 + while i < len(C): + I = C[i] + i += 1 + + # Collect all of the symbols that could possibly be in the goto(I,X) sets + asyms = {} + for ii in I: + for s in ii.usyms: + asyms[s] = None + + for x in asyms: + g = self.lr0_goto(I, x) + if not g or id(g) in self.lr0_cidhash: + continue + self.lr0_cidhash[id(g)] = len(C) + C.append(g) + + return C + + # ----------------------------------------------------------------------------- + # ==== LALR(1) Parsing ==== + # + # LALR(1) parsing is almost exactly the same as SLR except that instead of + # relying upon Follow() sets when performing reductions, a more selective + # lookahead set that incorporates the state of the LR(0) machine is utilized. + # Thus, we mainly just have to focus on calculating the lookahead sets. + # + # The method used here is due to DeRemer and Pennelo (1982). + # + # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1) + # Lookahead Sets", ACM Transactions on Programming Languages and Systems, + # Vol. 4, No. 4, Oct. 1982, pp. 615-649 + # + # Further details can also be found in: + # + # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing", + # McGraw-Hill Book Company, (1985). + # + # ----------------------------------------------------------------------------- + + # ----------------------------------------------------------------------------- + # compute_nullable_nonterminals() + # + # Creates a dictionary containing all of the non-terminals that might produce + # an empty production. + # ----------------------------------------------------------------------------- + + def compute_nullable_nonterminals(self): + nullable = set() + num_nullable = 0 + while True: + for p in self.grammar.Productions[1:]: + if p.len == 0: + nullable.add(p.name) + continue + for t in p.prod: + if t not in nullable: + break + else: + nullable.add(p.name) + if len(nullable) == num_nullable: + break + num_nullable = len(nullable) + return nullable + + # ----------------------------------------------------------------------------- + # find_nonterminal_trans(C) + # + # Given a set of LR(0) items, this functions finds all of the non-terminal + # transitions. These are transitions in which a dot appears immediately before + # a non-terminal. Returns a list of tuples of the form (state,N) where state + # is the state number and N is the nonterminal symbol. + # + # The input C is the set of LR(0) items. + # ----------------------------------------------------------------------------- + + def find_nonterminal_transitions(self, C): + trans = [] + for stateno, state in enumerate(C): + for p in state: + if p.lr_index < p.len - 1: + t = (stateno, p.prod[p.lr_index+1]) + if t[1] in self.grammar.Nonterminals: + if t not in trans: + trans.append(t) + return trans + + # ----------------------------------------------------------------------------- + # dr_relation() + # + # Computes the DR(p,A) relationships for non-terminal transitions. The input + # is a tuple (state,N) where state is a number and N is a nonterminal symbol. + # + # Returns a list of terminals. + # ----------------------------------------------------------------------------- + + def dr_relation(self, C, trans, nullable): + dr_set = {} + state, N = trans + terms = [] + + g = self.lr0_goto(C[state], N) + for p in g: + if p.lr_index < p.len - 1: + a = p.prod[p.lr_index+1] + if a in self.grammar.Terminals: + if a not in terms: + terms.append(a) + + # This extra bit is to handle the start state + if state == 0 and N == self.grammar.Productions[0].prod[0]: + terms.append('$end') + + return terms + + # ----------------------------------------------------------------------------- + # reads_relation() + # + # Computes the READS() relation (p,A) READS (t,C). + # ----------------------------------------------------------------------------- + + def reads_relation(self, C, trans, empty): + # Look for empty transitions + rel = [] + state, N = trans + + g = self.lr0_goto(C[state], N) + j = self.lr0_cidhash.get(id(g), -1) + for p in g: + if p.lr_index < p.len - 1: + a = p.prod[p.lr_index + 1] + if a in empty: + rel.append((j, a)) + + return rel + + # ----------------------------------------------------------------------------- + # compute_lookback_includes() + # + # Determines the lookback and includes relations + # + # LOOKBACK: + # + # This relation is determined by running the LR(0) state machine forward. + # For example, starting with a production "N : . A B C", we run it forward + # to obtain "N : A B C ." We then build a relationship between this final + # state and the starting state. These relationships are stored in a dictionary + # lookdict. + # + # INCLUDES: + # + # Computes the INCLUDE() relation (p,A) INCLUDES (p',B). + # + # This relation is used to determine non-terminal transitions that occur + # inside of other non-terminal transition states. (p,A) INCLUDES (p', B) + # if the following holds: + # + # B -> LAT, where T -> epsilon and p' -L-> p + # + # L is essentially a prefix (which may be empty), T is a suffix that must be + # able to derive an empty string. State p' must lead to state p with the string L. + # + # ----------------------------------------------------------------------------- + + def compute_lookback_includes(self, C, trans, nullable): + lookdict = {} # Dictionary of lookback relations + includedict = {} # Dictionary of include relations + + # Make a dictionary of non-terminal transitions + dtrans = {} + for t in trans: + dtrans[t] = 1 + + # Loop over all transitions and compute lookbacks and includes + for state, N in trans: + lookb = [] + includes = [] + for p in C[state]: + if p.name != N: + continue + + # Okay, we have a name match. We now follow the production all the way + # through the state machine until we get the . on the right hand side + + lr_index = p.lr_index + j = state + while lr_index < p.len - 1: + lr_index = lr_index + 1 + t = p.prod[lr_index] + + # Check to see if this symbol and state are a non-terminal transition + if (j, t) in dtrans: + # Yes. Okay, there is some chance that this is an includes relation + # the only way to know for certain is whether the rest of the + # production derives empty + + li = lr_index + 1 + while li < p.len: + if p.prod[li] in self.grammar.Terminals: + break # No forget it + if p.prod[li] not in nullable: + break + li = li + 1 + else: + # Appears to be a relation between (j,t) and (state,N) + includes.append((j, t)) + + g = self.lr0_goto(C[j], t) # Go to next set + j = self.lr0_cidhash.get(id(g), -1) # Go to next state + + # When we get here, j is the final state, now we have to locate the production + for r in C[j]: + if r.name != p.name: + continue + if r.len != p.len: + continue + i = 0 + # This look is comparing a production ". A B C" with "A B C ." + while i < r.lr_index: + if r.prod[i] != p.prod[i+1]: + break + i = i + 1 + else: + lookb.append((j, r)) + for i in includes: + if i not in includedict: + includedict[i] = [] + includedict[i].append((state, N)) + lookdict[(state, N)] = lookb + + return lookdict, includedict + + # ----------------------------------------------------------------------------- + # compute_read_sets() + # + # Given a set of LR(0) items, this function computes the read sets. + # + # Inputs: C = Set of LR(0) items + # ntrans = Set of nonterminal transitions + # nullable = Set of empty transitions + # + # Returns a set containing the read sets + # ----------------------------------------------------------------------------- + + def compute_read_sets(self, C, ntrans, nullable): + FP = lambda x: self.dr_relation(C, x, nullable) + R = lambda x: self.reads_relation(C, x, nullable) + F = digraph(ntrans, R, FP) + return F + + # ----------------------------------------------------------------------------- + # compute_follow_sets() + # + # Given a set of LR(0) items, a set of non-terminal transitions, a readset, + # and an include set, this function computes the follow sets + # + # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)} + # + # Inputs: + # ntrans = Set of nonterminal transitions + # readsets = Readset (previously computed) + # inclsets = Include sets (previously computed) + # + # Returns a set containing the follow sets + # ----------------------------------------------------------------------------- + + def compute_follow_sets(self, ntrans, readsets, inclsets): + FP = lambda x: readsets[x] + R = lambda x: inclsets.get(x, []) + F = digraph(ntrans, R, FP) + return F + + # ----------------------------------------------------------------------------- + # add_lookaheads() + # + # Attaches the lookahead symbols to grammar rules. + # + # Inputs: lookbacks - Set of lookback relations + # followset - Computed follow set + # + # This function directly attaches the lookaheads to productions contained + # in the lookbacks set + # ----------------------------------------------------------------------------- + + def add_lookaheads(self, lookbacks, followset): + for trans, lb in lookbacks.items(): + # Loop over productions in lookback + for state, p in lb: + if state not in p.lookaheads: + p.lookaheads[state] = [] + f = followset.get(trans, []) + for a in f: + if a not in p.lookaheads[state]: + p.lookaheads[state].append(a) + + # ----------------------------------------------------------------------------- + # add_lalr_lookaheads() + # + # This function does all of the work of adding lookahead information for use + # with LALR parsing + # ----------------------------------------------------------------------------- + + def add_lalr_lookaheads(self, C): + # Determine all of the nullable nonterminals + nullable = self.compute_nullable_nonterminals() + + # Find all non-terminal transitions + trans = self.find_nonterminal_transitions(C) + + # Compute read sets + readsets = self.compute_read_sets(C, trans, nullable) + + # Compute lookback/includes relations + lookd, included = self.compute_lookback_includes(C, trans, nullable) + + # Compute LALR FOLLOW sets + followsets = self.compute_follow_sets(trans, readsets, included) + + # Add all of the lookaheads + self.add_lookaheads(lookd, followsets) + + # ----------------------------------------------------------------------------- + # lr_parse_table() + # + # This function constructs the parse tables for SLR or LALR + # ----------------------------------------------------------------------------- + def lr_parse_table(self): + Productions = self.grammar.Productions + Precedence = self.grammar.Precedence + goto = self.lr_goto # Goto array + action = self.lr_action # Action array + log = self.log # Logger for output + + actionp = {} # Action production array (temporary) + + log.info('Parsing method: %s', self.lr_method) + + # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items + # This determines the number of states + + C = self.lr0_items() + + if self.lr_method == 'LALR': + self.add_lalr_lookaheads(C) + + # Build the parser table, state by state + st = 0 + for I in C: + # Loop over each production in I + actlist = [] # List of actions + st_action = {} + st_actionp = {} + st_goto = {} + log.info('') + log.info('state %d', st) + log.info('') + for p in I: + log.info(' (%d) %s', p.number, p) + log.info('') + + for p in I: + if p.len == p.lr_index + 1: + if p.name == "S'": + # Start symbol. Accept! + st_action['$end'] = 0 + st_actionp['$end'] = p + else: + # We are at the end of a production. Reduce! + if self.lr_method == 'LALR': + laheads = p.lookaheads[st] + else: + laheads = self.grammar.Follow[p.name] + for a in laheads: + actlist.append((a, p, 'reduce using rule %d (%s)' % (p.number, p))) + r = st_action.get(a) + if r is not None: + # Whoa. Have a shift/reduce or reduce/reduce conflict + if r > 0: + # Need to decide on shift or reduce here + # By default we favor shifting. Need to add + # some precedence rules here. + + # Shift precedence comes from the token + sprec, slevel = Precedence.get(a, ('right', 0)) + + # Reduce precedence comes from rule being reduced (p) + rprec, rlevel = Productions[p.number].prec + + if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')): + # We really need to reduce here. + st_action[a] = -p.number + st_actionp[a] = p + if not slevel and not rlevel: + log.info(' ! shift/reduce conflict for %s resolved as reduce', a) + self.sr_conflicts.append((st, a, 'reduce')) + Productions[p.number].reduced += 1 + elif (slevel == rlevel) and (rprec == 'nonassoc'): + st_action[a] = None + else: + # Hmmm. Guess we'll keep the shift + if not rlevel: + log.info(' ! shift/reduce conflict for %s resolved as shift', a) + self.sr_conflicts.append((st, a, 'shift')) + elif r < 0: + # Reduce/reduce conflict. In this case, we favor the rule + # that was defined first in the grammar file + oldp = Productions[-r] + pp = Productions[p.number] + if oldp.line > pp.line: + st_action[a] = -p.number + st_actionp[a] = p + chosenp, rejectp = pp, oldp + Productions[p.number].reduced += 1 + Productions[oldp.number].reduced -= 1 + else: + chosenp, rejectp = oldp, pp + self.rr_conflicts.append((st, chosenp, rejectp)) + log.info(' ! reduce/reduce conflict for %s resolved using rule %d (%s)', + a, st_actionp[a].number, st_actionp[a]) + else: + raise LALRError('Unknown conflict in state %d' % st) + else: + st_action[a] = -p.number + st_actionp[a] = p + Productions[p.number].reduced += 1 + else: + i = p.lr_index + a = p.prod[i+1] # Get symbol right after the "." + if a in self.grammar.Terminals: + g = self.lr0_goto(I, a) + j = self.lr0_cidhash.get(id(g), -1) + if j >= 0: + # We are in a shift state + actlist.append((a, p, 'shift and go to state %d' % j)) + r = st_action.get(a) + if r is not None: + # Whoa have a shift/reduce or shift/shift conflict + if r > 0: + if r != j: + raise LALRError('Shift/shift conflict in state %d' % st) + elif r < 0: + # Do a precedence check. + # - if precedence of reduce rule is higher, we reduce. + # - if precedence of reduce is same and left assoc, we reduce. + # - otherwise we shift + + # Shift precedence comes from the token + sprec, slevel = Precedence.get(a, ('right', 0)) + + # Reduce precedence comes from the rule that could have been reduced + rprec, rlevel = Productions[st_actionp[a].number].prec + + if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')): + # We decide to shift here... highest precedence to shift + Productions[st_actionp[a].number].reduced -= 1 + st_action[a] = j + st_actionp[a] = p + if not rlevel: + log.info(' ! shift/reduce conflict for %s resolved as shift', a) + self.sr_conflicts.append((st, a, 'shift')) + elif (slevel == rlevel) and (rprec == 'nonassoc'): + st_action[a] = None + else: + # Hmmm. Guess we'll keep the reduce + if not slevel and not rlevel: + log.info(' ! shift/reduce conflict for %s resolved as reduce', a) + self.sr_conflicts.append((st, a, 'reduce')) + + else: + raise LALRError('Unknown conflict in state %d' % st) + else: + st_action[a] = j + st_actionp[a] = p + + # Print the actions associated with each terminal + _actprint = {} + for a, p, m in actlist: + if a in st_action: + if p is st_actionp[a]: + log.info(' %-15s %s', a, m) + _actprint[(a, m)] = 1 + log.info('') + # Print the actions that were not used. (debugging) + not_used = 0 + for a, p, m in actlist: + if a in st_action: + if p is not st_actionp[a]: + if not (a, m) in _actprint: + log.debug(' ! %-15s [ %s ]', a, m) + not_used = 1 + _actprint[(a, m)] = 1 + if not_used: + log.debug('') + + # Construct the goto table for this state + + nkeys = {} + for ii in I: + for s in ii.usyms: + if s in self.grammar.Nonterminals: + nkeys[s] = None + for n in nkeys: + g = self.lr0_goto(I, n) + j = self.lr0_cidhash.get(id(g), -1) + if j >= 0: + st_goto[n] = j + log.info(' %-30s shift and go to state %d', n, j) + + action[st] = st_action + actionp[st] = st_actionp + goto[st] = st_goto + st += 1 + + # ----------------------------------------------------------------------------- + # write() + # + # This function writes the LR parsing tables to a file + # ----------------------------------------------------------------------------- + + def write_table(self, tabmodule, outputdir='', signature=''): + if isinstance(tabmodule, types.ModuleType): + raise IOError("Won't overwrite existing tabmodule") + + basemodulename = tabmodule.split('.')[-1] + filename = os.path.join(outputdir, basemodulename) + '.py' + try: + f = open(filename, 'w') + + f.write(''' +# %s +# This file is automatically generated. Do not edit. +_tabversion = %r + +_lr_method = %r + +_lr_signature = %r + ''' % (os.path.basename(filename), __tabversion__, self.lr_method, signature)) + + # Change smaller to 0 to go back to original tables + smaller = 1 + + # Factor out names to try and make smaller + if smaller: + items = {} + + for s, nd in self.lr_action.items(): + for name, v in nd.items(): + i = items.get(name) + if not i: + i = ([], []) + items[name] = i + i[0].append(s) + i[1].append(v) + + f.write('\n_lr_action_items = {') + for k, v in items.items(): + f.write('%r:([' % k) + for i in v[0]: + f.write('%r,' % i) + f.write('],[') + for i in v[1]: + f.write('%r,' % i) + + f.write(']),') + f.write('}\n') + + f.write(''' +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items +''') + + else: + f.write('\n_lr_action = { ') + for k, v in self.lr_action.items(): + f.write('(%r,%r):%r,' % (k[0], k[1], v)) + f.write('}\n') + + if smaller: + # Factor out names to try and make smaller + items = {} + + for s, nd in self.lr_goto.items(): + for name, v in nd.items(): + i = items.get(name) + if not i: + i = ([], []) + items[name] = i + i[0].append(s) + i[1].append(v) + + f.write('\n_lr_goto_items = {') + for k, v in items.items(): + f.write('%r:([' % k) + for i in v[0]: + f.write('%r,' % i) + f.write('],[') + for i in v[1]: + f.write('%r,' % i) + + f.write(']),') + f.write('}\n') + + f.write(''' +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +''') + else: + f.write('\n_lr_goto = { ') + for k, v in self.lr_goto.items(): + f.write('(%r,%r):%r,' % (k[0], k[1], v)) + f.write('}\n') + + # Write production table + f.write('_lr_productions = [\n') + for p in self.lr_productions: + if p.func: + f.write(' (%r,%r,%d,%r,%r,%d),\n' % (p.str, p.name, p.len, + p.func, os.path.basename(p.file), p.line)) + else: + f.write(' (%r,%r,%d,None,None,None),\n' % (str(p), p.name, p.len)) + f.write(']\n') + f.close() + + except IOError as e: + raise + + + # ----------------------------------------------------------------------------- + # pickle_table() + # + # This function pickles the LR parsing tables to a supplied file object + # ----------------------------------------------------------------------------- + + def pickle_table(self, filename, signature=''): + try: + import cPickle as pickle + except ImportError: + import pickle + with open(filename, 'wb') as outf: + pickle.dump(__tabversion__, outf, pickle_protocol) + pickle.dump(self.lr_method, outf, pickle_protocol) + pickle.dump(signature, outf, pickle_protocol) + pickle.dump(self.lr_action, outf, pickle_protocol) + pickle.dump(self.lr_goto, outf, pickle_protocol) + + outp = [] + for p in self.lr_productions: + if p.func: + outp.append((p.str, p.name, p.len, p.func, os.path.basename(p.file), p.line)) + else: + outp.append((str(p), p.name, p.len, None, None, None)) + pickle.dump(outp, outf, pickle_protocol) + +# ----------------------------------------------------------------------------- +# === INTROSPECTION === +# +# The following functions and classes are used to implement the PLY +# introspection features followed by the yacc() function itself. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# get_caller_module_dict() +# +# This function returns a dictionary containing all of the symbols defined within +# a caller further down the call stack. This is used to get the environment +# associated with the yacc() call if none was provided. +# ----------------------------------------------------------------------------- + +def get_caller_module_dict(levels): + f = sys._getframe(levels) + ldict = f.f_globals.copy() + if f.f_globals != f.f_locals: + ldict.update(f.f_locals) + return ldict + +# ----------------------------------------------------------------------------- +# parse_grammar() +# +# This takes a raw grammar rule string and parses it into production data +# ----------------------------------------------------------------------------- +def parse_grammar(doc, file, line): + grammar = [] + # Split the doc string into lines + pstrings = doc.splitlines() + lastp = None + dline = line + for ps in pstrings: + dline += 1 + p = ps.split() + if not p: + continue + try: + if p[0] == '|': + # This is a continuation of a previous rule + if not lastp: + raise SyntaxError("%s:%d: Misplaced '|'" % (file, dline)) + prodname = lastp + syms = p[1:] + else: + prodname = p[0] + lastp = prodname + syms = p[2:] + assign = p[1] + if assign != ':' and assign != '::=': + raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file, dline)) + + grammar.append((file, dline, prodname, syms)) + except SyntaxError: + raise + except Exception: + raise SyntaxError('%s:%d: Syntax error in rule %r' % (file, dline, ps.strip())) + + return grammar + +# ----------------------------------------------------------------------------- +# ParserReflect() +# +# This class represents information extracted for building a parser including +# start symbol, error function, tokens, precedence list, action functions, +# etc. +# ----------------------------------------------------------------------------- +class ParserReflect(object): + def __init__(self, pdict, log=None): + self.pdict = pdict + self.start = None + self.error_func = None + self.tokens = None + self.modules = set() + self.grammar = [] + self.error = False + + if log is None: + self.log = PlyLogger(sys.stderr) + else: + self.log = log + + # Get all of the basic information + def get_all(self): + self.get_start() + self.get_error_func() + self.get_tokens() + self.get_precedence() + self.get_pfunctions() + + # Validate all of the information + def validate_all(self): + self.validate_start() + self.validate_error_func() + self.validate_tokens() + self.validate_precedence() + self.validate_pfunctions() + self.validate_modules() + return self.error + + # Compute a signature over the grammar + def signature(self): + parts = [] + try: + if self.start: + parts.append(self.start) + if self.prec: + parts.append(''.join([''.join(p) for p in self.prec])) + if self.tokens: + parts.append(' '.join(self.tokens)) + for f in self.pfuncs: + if f[3]: + parts.append(f[3]) + except (TypeError, ValueError): + pass + return ''.join(parts) + + # ----------------------------------------------------------------------------- + # validate_modules() + # + # This method checks to see if there are duplicated p_rulename() functions + # in the parser module file. Without this function, it is really easy for + # users to make mistakes by cutting and pasting code fragments (and it's a real + # bugger to try and figure out why the resulting parser doesn't work). Therefore, + # we just do a little regular expression pattern matching of def statements + # to try and detect duplicates. + # ----------------------------------------------------------------------------- + + def validate_modules(self): + # Match def p_funcname( + fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(') + + for module in self.modules: + try: + lines, linen = inspect.getsourcelines(module) + except IOError: + continue + + counthash = {} + for linen, line in enumerate(lines): + linen += 1 + m = fre.match(line) + if m: + name = m.group(1) + prev = counthash.get(name) + if not prev: + counthash[name] = linen + else: + filename = inspect.getsourcefile(module) + self.log.warning('%s:%d: Function %s redefined. Previously defined on line %d', + filename, linen, name, prev) + + # Get the start symbol + def get_start(self): + self.start = self.pdict.get('start') + + # Validate the start symbol + def validate_start(self): + if self.start is not None: + if not isinstance(self.start, string_types): + self.log.error("'start' must be a string") + + # Look for error handler + def get_error_func(self): + self.error_func = self.pdict.get('p_error') + + # Validate the error function + def validate_error_func(self): + if self.error_func: + if isinstance(self.error_func, types.FunctionType): + ismethod = 0 + elif isinstance(self.error_func, types.MethodType): + ismethod = 1 + else: + self.log.error("'p_error' defined, but is not a function or method") + self.error = True + return + + eline = self.error_func.__code__.co_firstlineno + efile = self.error_func.__code__.co_filename + module = inspect.getmodule(self.error_func) + self.modules.add(module) + + argcount = self.error_func.__code__.co_argcount - ismethod + if argcount != 1: + self.log.error('%s:%d: p_error() requires 1 argument', efile, eline) + self.error = True + + # Get the tokens map + def get_tokens(self): + tokens = self.pdict.get('tokens') + if not tokens: + self.log.error('No token list is defined') + self.error = True + return + + if not isinstance(tokens, (list, tuple)): + self.log.error('tokens must be a list or tuple') + self.error = True + return + + if not tokens: + self.log.error('tokens is empty') + self.error = True + return + + self.tokens = tokens + + # Validate the tokens + def validate_tokens(self): + # Validate the tokens. + if 'error' in self.tokens: + self.log.error("Illegal token name 'error'. Is a reserved word") + self.error = True + return + + terminals = set() + for n in self.tokens: + if n in terminals: + self.log.warning('Token %r multiply defined', n) + terminals.add(n) + + # Get the precedence map (if any) + def get_precedence(self): + self.prec = self.pdict.get('precedence') + + # Validate and parse the precedence map + def validate_precedence(self): + preclist = [] + if self.prec: + if not isinstance(self.prec, (list, tuple)): + self.log.error('precedence must be a list or tuple') + self.error = True + return + for level, p in enumerate(self.prec): + if not isinstance(p, (list, tuple)): + self.log.error('Bad precedence table') + self.error = True + return + + if len(p) < 2: + self.log.error('Malformed precedence entry %s. Must be (assoc, term, ..., term)', p) + self.error = True + return + assoc = p[0] + if not isinstance(assoc, string_types): + self.log.error('precedence associativity must be a string') + self.error = True + return + for term in p[1:]: + if not isinstance(term, string_types): + self.log.error('precedence items must be strings') + self.error = True + return + preclist.append((term, assoc, level+1)) + self.preclist = preclist + + # Get all p_functions from the grammar + def get_pfunctions(self): + p_functions = [] + for name, item in self.pdict.items(): + if not name.startswith('p_') or name == 'p_error': + continue + if isinstance(item, (types.FunctionType, types.MethodType)): + line = getattr(item, 'co_firstlineno', item.__code__.co_firstlineno) + module = inspect.getmodule(item) + p_functions.append((line, module, name, item.__doc__)) + + # Sort all of the actions by line number; make sure to stringify + # modules to make them sortable, since `line` may not uniquely sort all + # p functions + p_functions.sort(key=lambda p_function: ( + p_function[0], + str(p_function[1]), + p_function[2], + p_function[3])) + self.pfuncs = p_functions + + # Validate all of the p_functions + def validate_pfunctions(self): + grammar = [] + # Check for non-empty symbols + if len(self.pfuncs) == 0: + self.log.error('no rules of the form p_rulename are defined') + self.error = True + return + + for line, module, name, doc in self.pfuncs: + file = inspect.getsourcefile(module) + func = self.pdict[name] + if isinstance(func, types.MethodType): + reqargs = 2 + else: + reqargs = 1 + if func.__code__.co_argcount > reqargs: + self.log.error('%s:%d: Rule %r has too many arguments', file, line, func.__name__) + self.error = True + elif func.__code__.co_argcount < reqargs: + self.log.error('%s:%d: Rule %r requires an argument', file, line, func.__name__) + self.error = True + elif not func.__doc__: + self.log.warning('%s:%d: No documentation string specified in function %r (ignored)', + file, line, func.__name__) + else: + try: + parsed_g = parse_grammar(doc, file, line) + for g in parsed_g: + grammar.append((name, g)) + except SyntaxError as e: + self.log.error(str(e)) + self.error = True + + # Looks like a valid grammar rule + # Mark the file in which defined. + self.modules.add(module) + + # Secondary validation step that looks for p_ definitions that are not functions + # or functions that look like they might be grammar rules. + + for n, v in self.pdict.items(): + if n.startswith('p_') and isinstance(v, (types.FunctionType, types.MethodType)): + continue + if n.startswith('t_'): + continue + if n.startswith('p_') and n != 'p_error': + self.log.warning('%r not defined as a function', n) + if ((isinstance(v, types.FunctionType) and v.__code__.co_argcount == 1) or + (isinstance(v, types.MethodType) and v.__func__.__code__.co_argcount == 2)): + if v.__doc__: + try: + doc = v.__doc__.split(' ') + if doc[1] == ':': + self.log.warning('%s:%d: Possible grammar rule %r defined without p_ prefix', + v.__code__.co_filename, v.__code__.co_firstlineno, n) + except IndexError: + pass + + self.grammar = grammar + +# ----------------------------------------------------------------------------- +# yacc(module) +# +# Build a parser +# ----------------------------------------------------------------------------- + +def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None, + check_recursion=True, optimize=False, write_tables=True, debugfile=debug_file, + outputdir=None, debuglog=None, errorlog=None, picklefile=None): + + if tabmodule is None: + tabmodule = tab_module + + # Reference to the parsing method of the last built parser + global parse + + # If pickling is enabled, table files are not created + if picklefile: + write_tables = 0 + + if errorlog is None: + errorlog = PlyLogger(sys.stderr) + + # Get the module dictionary used for the parser + if module: + _items = [(k, getattr(module, k)) for k in dir(module)] + pdict = dict(_items) + # If no __file__ attribute is available, try to obtain it from the __module__ instead + if '__file__' not in pdict: + pdict['__file__'] = sys.modules[pdict['__module__']].__file__ + else: + pdict = get_caller_module_dict(2) + + if outputdir is None: + # If no output directory is set, the location of the output files + # is determined according to the following rules: + # - If tabmodule specifies a package, files go into that package directory + # - Otherwise, files go in the same directory as the specifying module + if isinstance(tabmodule, types.ModuleType): + srcfile = tabmodule.__file__ + else: + if '.' not in tabmodule: + srcfile = pdict['__file__'] + else: + parts = tabmodule.split('.') + pkgname = '.'.join(parts[:-1]) + exec('import %s' % pkgname) + srcfile = getattr(sys.modules[pkgname], '__file__', '') + outputdir = os.path.dirname(srcfile) + + # Determine if the module is package of a package or not. + # If so, fix the tabmodule setting so that tables load correctly + pkg = pdict.get('__package__') + if pkg and isinstance(tabmodule, str): + if '.' not in tabmodule: + tabmodule = pkg + '.' + tabmodule + + + + # Set start symbol if it's specified directly using an argument + if start is not None: + pdict['start'] = start + + # Collect parser information from the dictionary + pinfo = ParserReflect(pdict, log=errorlog) + pinfo.get_all() + + if pinfo.error: + raise YaccError('Unable to build parser') + + # Check signature against table files (if any) + signature = pinfo.signature() + + # Read the tables + try: + lr = LRTable() + if picklefile: + read_signature = lr.read_pickle(picklefile) + else: + read_signature = lr.read_table(tabmodule) + if optimize or (read_signature == signature): + try: + lr.bind_callables(pinfo.pdict) + parser = LRParser(lr, pinfo.error_func) + parse = parser.parse + return parser + except Exception as e: + errorlog.warning('There was a problem loading the table file: %r', e) + except VersionError as e: + errorlog.warning(str(e)) + except ImportError: + pass + + if debuglog is None: + if debug: + try: + debuglog = PlyLogger(open(os.path.join(outputdir, debugfile), 'w')) + except IOError as e: + errorlog.warning("Couldn't open %r. %s" % (debugfile, e)) + debuglog = NullLogger() + else: + debuglog = NullLogger() + + debuglog.info('Created by PLY version %s (http://www.dabeaz.com/ply)', __version__) + + errors = False + + # Validate the parser information + if pinfo.validate_all(): + raise YaccError('Unable to build parser') + + if not pinfo.error_func: + errorlog.warning('no p_error() function is defined') + + # Create a grammar object + grammar = Grammar(pinfo.tokens) + + # Set precedence level for terminals + for term, assoc, level in pinfo.preclist: + try: + grammar.set_precedence(term, assoc, level) + except GrammarError as e: + errorlog.warning('%s', e) + + # Add productions to the grammar + for funcname, gram in pinfo.grammar: + file, line, prodname, syms = gram + try: + grammar.add_production(prodname, syms, funcname, file, line) + except GrammarError as e: + errorlog.error('%s', e) + errors = True + + # Set the grammar start symbols + try: + if start is None: + grammar.set_start(pinfo.start) + else: + grammar.set_start(start) + except GrammarError as e: + errorlog.error(str(e)) + errors = True + + if errors: + raise YaccError('Unable to build parser') + + # Verify the grammar structure + undefined_symbols = grammar.undefined_symbols() + for sym, prod in undefined_symbols: + errorlog.error('%s:%d: Symbol %r used, but not defined as a token or a rule', prod.file, prod.line, sym) + errors = True + + unused_terminals = grammar.unused_terminals() + if unused_terminals: + debuglog.info('') + debuglog.info('Unused terminals:') + debuglog.info('') + for term in unused_terminals: + errorlog.warning('Token %r defined, but not used', term) + debuglog.info(' %s', term) + + # Print out all productions to the debug log + if debug: + debuglog.info('') + debuglog.info('Grammar') + debuglog.info('') + for n, p in enumerate(grammar.Productions): + debuglog.info('Rule %-5d %s', n, p) + + # Find unused non-terminals + unused_rules = grammar.unused_rules() + for prod in unused_rules: + errorlog.warning('%s:%d: Rule %r defined, but not used', prod.file, prod.line, prod.name) + + if len(unused_terminals) == 1: + errorlog.warning('There is 1 unused token') + if len(unused_terminals) > 1: + errorlog.warning('There are %d unused tokens', len(unused_terminals)) + + if len(unused_rules) == 1: + errorlog.warning('There is 1 unused rule') + if len(unused_rules) > 1: + errorlog.warning('There are %d unused rules', len(unused_rules)) + + if debug: + debuglog.info('') + debuglog.info('Terminals, with rules where they appear') + debuglog.info('') + terms = list(grammar.Terminals) + terms.sort() + for term in terms: + debuglog.info('%-20s : %s', term, ' '.join([str(s) for s in grammar.Terminals[term]])) + + debuglog.info('') + debuglog.info('Nonterminals, with rules where they appear') + debuglog.info('') + nonterms = list(grammar.Nonterminals) + nonterms.sort() + for nonterm in nonterms: + debuglog.info('%-20s : %s', nonterm, ' '.join([str(s) for s in grammar.Nonterminals[nonterm]])) + debuglog.info('') + + if check_recursion: + unreachable = grammar.find_unreachable() + for u in unreachable: + errorlog.warning('Symbol %r is unreachable', u) + + infinite = grammar.infinite_cycles() + for inf in infinite: + errorlog.error('Infinite recursion detected for symbol %r', inf) + errors = True + + unused_prec = grammar.unused_precedence() + for term, assoc in unused_prec: + errorlog.error('Precedence rule %r defined for unknown symbol %r', assoc, term) + errors = True + + if errors: + raise YaccError('Unable to build parser') + + # Run the LRGeneratedTable on the grammar + if debug: + errorlog.debug('Generating %s tables', method) + + lr = LRGeneratedTable(grammar, method, debuglog) + + if debug: + num_sr = len(lr.sr_conflicts) + + # Report shift/reduce and reduce/reduce conflicts + if num_sr == 1: + errorlog.warning('1 shift/reduce conflict') + elif num_sr > 1: + errorlog.warning('%d shift/reduce conflicts', num_sr) + + num_rr = len(lr.rr_conflicts) + if num_rr == 1: + errorlog.warning('1 reduce/reduce conflict') + elif num_rr > 1: + errorlog.warning('%d reduce/reduce conflicts', num_rr) + + # Write out conflicts to the output file + if debug and (lr.sr_conflicts or lr.rr_conflicts): + debuglog.warning('') + debuglog.warning('Conflicts:') + debuglog.warning('') + + for state, tok, resolution in lr.sr_conflicts: + debuglog.warning('shift/reduce conflict for %s in state %d resolved as %s', tok, state, resolution) + + already_reported = set() + for state, rule, rejected in lr.rr_conflicts: + if (state, id(rule), id(rejected)) in already_reported: + continue + debuglog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule) + debuglog.warning('rejected rule (%s) in state %d', rejected, state) + errorlog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule) + errorlog.warning('rejected rule (%s) in state %d', rejected, state) + already_reported.add((state, id(rule), id(rejected))) + + warned_never = [] + for state, rule, rejected in lr.rr_conflicts: + if not rejected.reduced and (rejected not in warned_never): + debuglog.warning('Rule (%s) is never reduced', rejected) + errorlog.warning('Rule (%s) is never reduced', rejected) + warned_never.append(rejected) + + # Write the table file if requested + if write_tables: + try: + lr.write_table(tabmodule, outputdir, signature) + except IOError as e: + errorlog.warning("Couldn't create %r. %s" % (tabmodule, e)) + + # Write a pickled version of the tables + if picklefile: + try: + lr.pickle_table(picklefile, signature) + except IOError as e: + errorlog.warning("Couldn't create %r. %s" % (picklefile, e)) + + # Build the parser + lr.bind_callables(pinfo.pdict) + parser = LRParser(lr, pinfo.error_func) + + parse = parser.parse + return parser diff --git a/uno/lib/python/pycparser/ply/ygen.py b/uno/lib/python/pycparser/ply/ygen.py new file mode 100644 index 00000000..acf5ca1a --- /dev/null +++ b/uno/lib/python/pycparser/ply/ygen.py @@ -0,0 +1,74 @@ +# ply: ygen.py +# +# This is a support program that auto-generates different versions of the YACC parsing +# function with different features removed for the purposes of performance. +# +# Users should edit the method LParser.parsedebug() in yacc.py. The source code +# for that method is then used to create the other methods. See the comments in +# yacc.py for further details. + +import os.path +import shutil + +def get_source_range(lines, tag): + srclines = enumerate(lines) + start_tag = '#--! %s-start' % tag + end_tag = '#--! %s-end' % tag + + for start_index, line in srclines: + if line.strip().startswith(start_tag): + break + + for end_index, line in srclines: + if line.strip().endswith(end_tag): + break + + return (start_index + 1, end_index) + +def filter_section(lines, tag): + filtered_lines = [] + include = True + tag_text = '#--! %s' % tag + for line in lines: + if line.strip().startswith(tag_text): + include = not include + elif include: + filtered_lines.append(line) + return filtered_lines + +def main(): + dirname = os.path.dirname(__file__) + shutil.copy2(os.path.join(dirname, 'yacc.py'), os.path.join(dirname, 'yacc.py.bak')) + with open(os.path.join(dirname, 'yacc.py'), 'r') as f: + lines = f.readlines() + + parse_start, parse_end = get_source_range(lines, 'parsedebug') + parseopt_start, parseopt_end = get_source_range(lines, 'parseopt') + parseopt_notrack_start, parseopt_notrack_end = get_source_range(lines, 'parseopt-notrack') + + # Get the original source + orig_lines = lines[parse_start:parse_end] + + # Filter the DEBUG sections out + parseopt_lines = filter_section(orig_lines, 'DEBUG') + + # Filter the TRACKING sections out + parseopt_notrack_lines = filter_section(parseopt_lines, 'TRACKING') + + # Replace the parser source sections with updated versions + lines[parseopt_notrack_start:parseopt_notrack_end] = parseopt_notrack_lines + lines[parseopt_start:parseopt_end] = parseopt_lines + + lines = [line.rstrip()+'\n' for line in lines] + with open(os.path.join(dirname, 'yacc.py'), 'w') as f: + f.writelines(lines) + + print('Updated yacc.py') + +if __name__ == '__main__': + main() + + + + + diff --git a/uno/lib/python/pycparser/plyparser.py b/uno/lib/python/pycparser/plyparser.py new file mode 100644 index 00000000..b8f4c439 --- /dev/null +++ b/uno/lib/python/pycparser/plyparser.py @@ -0,0 +1,133 @@ +#----------------------------------------------------------------- +# plyparser.py +# +# PLYParser class and other utilities for simplifying programming +# parsers with PLY +# +# Eli Bendersky [https://eli.thegreenplace.net/] +# License: BSD +#----------------------------------------------------------------- + +import warnings + +class Coord(object): + """ Coordinates of a syntactic element. Consists of: + - File name + - Line number + - (optional) column number, for the Lexer + """ + __slots__ = ('file', 'line', 'column', '__weakref__') + def __init__(self, file, line, column=None): + self.file = file + self.line = line + self.column = column + + def __str__(self): + str = "%s:%s" % (self.file, self.line) + if self.column: str += ":%s" % self.column + return str + + +class ParseError(Exception): pass + + +class PLYParser(object): + def _create_opt_rule(self, rulename): + """ Given a rule name, creates an optional ply.yacc rule + for it. The name of the optional rule is + _opt + """ + optname = rulename + '_opt' + + def optrule(self, p): + p[0] = p[1] + + optrule.__doc__ = '%s : empty\n| %s' % (optname, rulename) + optrule.__name__ = 'p_%s' % optname + setattr(self.__class__, optrule.__name__, optrule) + + def _coord(self, lineno, column=None): + return Coord( + file=self.clex.filename, + line=lineno, + column=column) + + def _token_coord(self, p, token_idx): + """ Returns the coordinates for the YaccProduction object 'p' indexed + with 'token_idx'. The coordinate includes the 'lineno' and + 'column'. Both follow the lex semantic, starting from 1. + """ + last_cr = p.lexer.lexer.lexdata.rfind('\n', 0, p.lexpos(token_idx)) + if last_cr < 0: + last_cr = -1 + column = (p.lexpos(token_idx) - (last_cr)) + return self._coord(p.lineno(token_idx), column) + + def _parse_error(self, msg, coord): + raise ParseError("%s: %s" % (coord, msg)) + + +def parameterized(*params): + """ Decorator to create parameterized rules. + + Parameterized rule methods must be named starting with 'p_' and contain + 'xxx', and their docstrings may contain 'xxx' and 'yyy'. These will be + replaced by the given parameter tuples. For example, ``p_xxx_rule()`` with + docstring 'xxx_rule : yyy' when decorated with + ``@parameterized(('id', 'ID'))`` produces ``p_id_rule()`` with the docstring + 'id_rule : ID'. Using multiple tuples produces multiple rules. + """ + def decorate(rule_func): + rule_func._params = params + return rule_func + return decorate + + +def template(cls): + """ Class decorator to generate rules from parameterized rule templates. + + See `parameterized` for more information on parameterized rules. + """ + issued_nodoc_warning = False + for attr_name in dir(cls): + if attr_name.startswith('p_'): + method = getattr(cls, attr_name) + if hasattr(method, '_params'): + # Remove the template method + delattr(cls, attr_name) + # Create parameterized rules from this method; only run this if + # the method has a docstring. This is to address an issue when + # pycparser's users are installed in -OO mode which strips + # docstrings away. + # See: https://github.com/eliben/pycparser/pull/198/ and + # https://github.com/eliben/pycparser/issues/197 + # for discussion. + if method.__doc__ is not None: + _create_param_rules(cls, method) + elif not issued_nodoc_warning: + warnings.warn( + 'parsing methods must have __doc__ for pycparser to work properly', + RuntimeWarning, + stacklevel=2) + issued_nodoc_warning = True + return cls + + +def _create_param_rules(cls, func): + """ Create ply.yacc rules based on a parameterized rule function + + Generates new methods (one per each pair of parameters) based on the + template rule function `func`, and attaches them to `cls`. The rule + function's parameters must be accessible via its `_params` attribute. + """ + for xxx, yyy in func._params: + # Use the template method's body for each new method + def param_rule(self, p): + func(self, p) + + # Substitute in the params for the grammar rule and function name + param_rule.__doc__ = func.__doc__.replace('xxx', xxx).replace('yyy', yyy) + param_rule.__name__ = func.__name__.replace('xxx', xxx) + + # Attach the new method to the class + setattr(cls, param_rule.__name__, param_rule) diff --git a/uno/lib/python/pycparser/yacctab.py b/uno/lib/python/pycparser/yacctab.py new file mode 100644 index 00000000..0622c366 --- /dev/null +++ b/uno/lib/python/pycparser/yacctab.py @@ -0,0 +1,366 @@ + +# yacctab.py +# This file is automatically generated. Do not edit. +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'translation_unit_or_emptyleftLORleftLANDleftORleftXORleftANDleftEQNEleftGTGELTLEleftRSHIFTLSHIFTleftPLUSMINUSleftTIMESDIVIDEMODAUTO BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM EXTERN FLOAT FOR GOTO IF INLINE INT LONG REGISTER OFFSETOF RESTRICT RETURN SHORT SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNED VOID VOLATILE WHILE __INT128 _BOOL _COMPLEX _NORETURN _THREAD_LOCAL _STATIC_ASSERT _ATOMIC _ALIGNOF _ALIGNAS ID TYPEID INT_CONST_DEC INT_CONST_OCT INT_CONST_HEX INT_CONST_BIN INT_CONST_CHAR FLOAT_CONST HEX_FLOAT_CONST CHAR_CONST WCHAR_CONST U8CHAR_CONST U16CHAR_CONST U32CHAR_CONST STRING_LITERAL WSTRING_LITERAL U8STRING_LITERAL U16STRING_LITERAL U32STRING_LITERAL PLUS MINUS TIMES DIVIDE MOD OR AND NOT XOR LSHIFT RSHIFT LOR LAND LNOT LT LE GT GE EQ NE EQUALS TIMESEQUAL DIVEQUAL MODEQUAL PLUSEQUAL MINUSEQUAL LSHIFTEQUAL RSHIFTEQUAL ANDEQUAL XOREQUAL OREQUAL PLUSPLUS MINUSMINUS ARROW CONDOP LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE COMMA PERIOD SEMI COLON ELLIPSIS PPHASH PPPRAGMA PPPRAGMASTRabstract_declarator_opt : empty\n| abstract_declaratorassignment_expression_opt : empty\n| assignment_expressionblock_item_list_opt : empty\n| block_item_listdeclaration_list_opt : empty\n| declaration_listdeclaration_specifiers_no_type_opt : empty\n| declaration_specifiers_no_typedesignation_opt : empty\n| designationexpression_opt : empty\n| expressionid_init_declarator_list_opt : empty\n| id_init_declarator_listidentifier_list_opt : empty\n| identifier_listinit_declarator_list_opt : empty\n| init_declarator_listinitializer_list_opt : empty\n| initializer_listparameter_type_list_opt : empty\n| parameter_type_liststruct_declarator_list_opt : empty\n| struct_declarator_listtype_qualifier_list_opt : empty\n| type_qualifier_list direct_id_declarator : ID\n direct_id_declarator : LPAREN id_declarator RPAREN\n direct_id_declarator : direct_id_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET\n direct_id_declarator : direct_id_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET\n | direct_id_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET\n direct_id_declarator : direct_id_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET\n direct_id_declarator : direct_id_declarator LPAREN parameter_type_list RPAREN\n | direct_id_declarator LPAREN identifier_list_opt RPAREN\n direct_typeid_declarator : TYPEID\n direct_typeid_declarator : LPAREN typeid_declarator RPAREN\n direct_typeid_declarator : direct_typeid_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET\n direct_typeid_declarator : direct_typeid_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET\n | direct_typeid_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET\n direct_typeid_declarator : direct_typeid_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET\n direct_typeid_declarator : direct_typeid_declarator LPAREN parameter_type_list RPAREN\n | direct_typeid_declarator LPAREN identifier_list_opt RPAREN\n direct_typeid_noparen_declarator : TYPEID\n direct_typeid_noparen_declarator : direct_typeid_noparen_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET\n direct_typeid_noparen_declarator : direct_typeid_noparen_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET\n | direct_typeid_noparen_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET\n direct_typeid_noparen_declarator : direct_typeid_noparen_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET\n direct_typeid_noparen_declarator : direct_typeid_noparen_declarator LPAREN parameter_type_list RPAREN\n | direct_typeid_noparen_declarator LPAREN identifier_list_opt RPAREN\n id_declarator : direct_id_declarator\n id_declarator : pointer direct_id_declarator\n typeid_declarator : direct_typeid_declarator\n typeid_declarator : pointer direct_typeid_declarator\n typeid_noparen_declarator : direct_typeid_noparen_declarator\n typeid_noparen_declarator : pointer direct_typeid_noparen_declarator\n translation_unit_or_empty : translation_unit\n | empty\n translation_unit : external_declaration\n translation_unit : translation_unit external_declaration\n external_declaration : function_definition\n external_declaration : declaration\n external_declaration : pp_directive\n | pppragma_directive\n external_declaration : SEMI\n external_declaration : static_assert\n static_assert : _STATIC_ASSERT LPAREN constant_expression COMMA unified_string_literal RPAREN\n | _STATIC_ASSERT LPAREN constant_expression RPAREN\n pp_directive : PPHASH\n pppragma_directive : PPPRAGMA\n | PPPRAGMA PPPRAGMASTR\n function_definition : id_declarator declaration_list_opt compound_statement\n function_definition : declaration_specifiers id_declarator declaration_list_opt compound_statement\n statement : labeled_statement\n | expression_statement\n | compound_statement\n | selection_statement\n | iteration_statement\n | jump_statement\n | pppragma_directive\n | static_assert\n pragmacomp_or_statement : pppragma_directive statement\n | statement\n decl_body : declaration_specifiers init_declarator_list_opt\n | declaration_specifiers_no_type id_init_declarator_list_opt\n declaration : decl_body SEMI\n declaration_list : declaration\n | declaration_list declaration\n declaration_specifiers_no_type : type_qualifier declaration_specifiers_no_type_opt\n declaration_specifiers_no_type : storage_class_specifier declaration_specifiers_no_type_opt\n declaration_specifiers_no_type : function_specifier declaration_specifiers_no_type_opt\n declaration_specifiers_no_type : atomic_specifier declaration_specifiers_no_type_opt\n declaration_specifiers_no_type : alignment_specifier declaration_specifiers_no_type_opt\n declaration_specifiers : declaration_specifiers type_qualifier\n declaration_specifiers : declaration_specifiers storage_class_specifier\n declaration_specifiers : declaration_specifiers function_specifier\n declaration_specifiers : declaration_specifiers type_specifier_no_typeid\n declaration_specifiers : type_specifier\n declaration_specifiers : declaration_specifiers_no_type type_specifier\n declaration_specifiers : declaration_specifiers alignment_specifier\n storage_class_specifier : AUTO\n | REGISTER\n | STATIC\n | EXTERN\n | TYPEDEF\n | _THREAD_LOCAL\n function_specifier : INLINE\n | _NORETURN\n type_specifier_no_typeid : VOID\n | _BOOL\n | CHAR\n | SHORT\n | INT\n | LONG\n | FLOAT\n | DOUBLE\n | _COMPLEX\n | SIGNED\n | UNSIGNED\n | __INT128\n type_specifier : typedef_name\n | enum_specifier\n | struct_or_union_specifier\n | type_specifier_no_typeid\n | atomic_specifier\n atomic_specifier : _ATOMIC LPAREN type_name RPAREN\n type_qualifier : CONST\n | RESTRICT\n | VOLATILE\n | _ATOMIC\n init_declarator_list : init_declarator\n | init_declarator_list COMMA init_declarator\n init_declarator : declarator\n | declarator EQUALS initializer\n id_init_declarator_list : id_init_declarator\n | id_init_declarator_list COMMA init_declarator\n id_init_declarator : id_declarator\n | id_declarator EQUALS initializer\n specifier_qualifier_list : specifier_qualifier_list type_specifier_no_typeid\n specifier_qualifier_list : specifier_qualifier_list type_qualifier\n specifier_qualifier_list : type_specifier\n specifier_qualifier_list : type_qualifier_list type_specifier\n specifier_qualifier_list : alignment_specifier\n specifier_qualifier_list : specifier_qualifier_list alignment_specifier\n struct_or_union_specifier : struct_or_union ID\n | struct_or_union TYPEID\n struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close\n | struct_or_union brace_open brace_close\n struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close\n | struct_or_union ID brace_open brace_close\n | struct_or_union TYPEID brace_open struct_declaration_list brace_close\n | struct_or_union TYPEID brace_open brace_close\n struct_or_union : STRUCT\n | UNION\n struct_declaration_list : struct_declaration\n | struct_declaration_list struct_declaration\n struct_declaration : specifier_qualifier_list struct_declarator_list_opt SEMI\n struct_declaration : SEMI\n struct_declaration : pppragma_directive\n struct_declarator_list : struct_declarator\n | struct_declarator_list COMMA struct_declarator\n struct_declarator : declarator\n struct_declarator : declarator COLON constant_expression\n | COLON constant_expression\n enum_specifier : ENUM ID\n | ENUM TYPEID\n enum_specifier : ENUM brace_open enumerator_list brace_close\n enum_specifier : ENUM ID brace_open enumerator_list brace_close\n | ENUM TYPEID brace_open enumerator_list brace_close\n enumerator_list : enumerator\n | enumerator_list COMMA\n | enumerator_list COMMA enumerator\n alignment_specifier : _ALIGNAS LPAREN type_name RPAREN\n | _ALIGNAS LPAREN constant_expression RPAREN\n enumerator : ID\n | ID EQUALS constant_expression\n declarator : id_declarator\n | typeid_declarator\n pointer : TIMES type_qualifier_list_opt\n | TIMES type_qualifier_list_opt pointer\n type_qualifier_list : type_qualifier\n | type_qualifier_list type_qualifier\n parameter_type_list : parameter_list\n | parameter_list COMMA ELLIPSIS\n parameter_list : parameter_declaration\n | parameter_list COMMA parameter_declaration\n parameter_declaration : declaration_specifiers id_declarator\n | declaration_specifiers typeid_noparen_declarator\n parameter_declaration : declaration_specifiers abstract_declarator_opt\n identifier_list : identifier\n | identifier_list COMMA identifier\n initializer : assignment_expression\n initializer : brace_open initializer_list_opt brace_close\n | brace_open initializer_list COMMA brace_close\n initializer_list : designation_opt initializer\n | initializer_list COMMA designation_opt initializer\n designation : designator_list EQUALS\n designator_list : designator\n | designator_list designator\n designator : LBRACKET constant_expression RBRACKET\n | PERIOD identifier\n type_name : specifier_qualifier_list abstract_declarator_opt\n abstract_declarator : pointer\n abstract_declarator : pointer direct_abstract_declarator\n abstract_declarator : direct_abstract_declarator\n direct_abstract_declarator : LPAREN abstract_declarator RPAREN direct_abstract_declarator : direct_abstract_declarator LBRACKET assignment_expression_opt RBRACKET\n direct_abstract_declarator : LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET\n direct_abstract_declarator : direct_abstract_declarator LBRACKET TIMES RBRACKET\n direct_abstract_declarator : LBRACKET TIMES RBRACKET\n direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN\n direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN\n block_item : declaration\n | statement\n block_item_list : block_item\n | block_item_list block_item\n compound_statement : brace_open block_item_list_opt brace_close labeled_statement : ID COLON pragmacomp_or_statement labeled_statement : CASE constant_expression COLON pragmacomp_or_statement labeled_statement : DEFAULT COLON pragmacomp_or_statement selection_statement : IF LPAREN expression RPAREN pragmacomp_or_statement selection_statement : IF LPAREN expression RPAREN statement ELSE pragmacomp_or_statement selection_statement : SWITCH LPAREN expression RPAREN pragmacomp_or_statement iteration_statement : WHILE LPAREN expression RPAREN pragmacomp_or_statement iteration_statement : DO pragmacomp_or_statement WHILE LPAREN expression RPAREN SEMI iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement iteration_statement : FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement jump_statement : GOTO ID SEMI jump_statement : BREAK SEMI jump_statement : CONTINUE SEMI jump_statement : RETURN expression SEMI\n | RETURN SEMI\n expression_statement : expression_opt SEMI expression : assignment_expression\n | expression COMMA assignment_expression\n assignment_expression : LPAREN compound_statement RPAREN typedef_name : TYPEID assignment_expression : conditional_expression\n | unary_expression assignment_operator assignment_expression\n assignment_operator : EQUALS\n | XOREQUAL\n | TIMESEQUAL\n | DIVEQUAL\n | MODEQUAL\n | PLUSEQUAL\n | MINUSEQUAL\n | LSHIFTEQUAL\n | RSHIFTEQUAL\n | ANDEQUAL\n | OREQUAL\n constant_expression : conditional_expression conditional_expression : binary_expression\n | binary_expression CONDOP expression COLON conditional_expression\n binary_expression : cast_expression\n | binary_expression TIMES binary_expression\n | binary_expression DIVIDE binary_expression\n | binary_expression MOD binary_expression\n | binary_expression PLUS binary_expression\n | binary_expression MINUS binary_expression\n | binary_expression RSHIFT binary_expression\n | binary_expression LSHIFT binary_expression\n | binary_expression LT binary_expression\n | binary_expression LE binary_expression\n | binary_expression GE binary_expression\n | binary_expression GT binary_expression\n | binary_expression EQ binary_expression\n | binary_expression NE binary_expression\n | binary_expression AND binary_expression\n | binary_expression OR binary_expression\n | binary_expression XOR binary_expression\n | binary_expression LAND binary_expression\n | binary_expression LOR binary_expression\n cast_expression : unary_expression cast_expression : LPAREN type_name RPAREN cast_expression unary_expression : postfix_expression unary_expression : PLUSPLUS unary_expression\n | MINUSMINUS unary_expression\n | unary_operator cast_expression\n unary_expression : SIZEOF unary_expression\n | SIZEOF LPAREN type_name RPAREN\n | _ALIGNOF LPAREN type_name RPAREN\n unary_operator : AND\n | TIMES\n | PLUS\n | MINUS\n | NOT\n | LNOT\n postfix_expression : primary_expression postfix_expression : postfix_expression LBRACKET expression RBRACKET postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN\n | postfix_expression LPAREN RPAREN\n postfix_expression : postfix_expression PERIOD ID\n | postfix_expression PERIOD TYPEID\n | postfix_expression ARROW ID\n | postfix_expression ARROW TYPEID\n postfix_expression : postfix_expression PLUSPLUS\n | postfix_expression MINUSMINUS\n postfix_expression : LPAREN type_name RPAREN brace_open initializer_list brace_close\n | LPAREN type_name RPAREN brace_open initializer_list COMMA brace_close\n primary_expression : identifier primary_expression : constant primary_expression : unified_string_literal\n | unified_wstring_literal\n primary_expression : LPAREN expression RPAREN primary_expression : OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN\n offsetof_member_designator : identifier\n | offsetof_member_designator PERIOD identifier\n | offsetof_member_designator LBRACKET expression RBRACKET\n argument_expression_list : assignment_expression\n | argument_expression_list COMMA assignment_expression\n identifier : ID constant : INT_CONST_DEC\n | INT_CONST_OCT\n | INT_CONST_HEX\n | INT_CONST_BIN\n | INT_CONST_CHAR\n constant : FLOAT_CONST\n | HEX_FLOAT_CONST\n constant : CHAR_CONST\n | WCHAR_CONST\n | U8CHAR_CONST\n | U16CHAR_CONST\n | U32CHAR_CONST\n unified_string_literal : STRING_LITERAL\n | unified_string_literal STRING_LITERAL\n unified_wstring_literal : WSTRING_LITERAL\n | U8STRING_LITERAL\n | U16STRING_LITERAL\n | U32STRING_LITERAL\n | unified_wstring_literal WSTRING_LITERAL\n | unified_wstring_literal U8STRING_LITERAL\n | unified_wstring_literal U16STRING_LITERAL\n | unified_wstring_literal U32STRING_LITERAL\n brace_open : LBRACE\n brace_close : RBRACE\n empty : ' + +_lr_action_items = {'INT_CONST_CHAR':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,132,-335,-28,-182,-27,132,-337,-87,-72,-337,132,-286,-285,132,132,-283,-287,-288,132,-284,132,132,132,-336,-183,132,132,-28,-337,132,-28,-337,-337,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,-337,-76,-79,-82,-75,132,-77,132,132,-81,-215,-214,-80,-216,132,-78,132,132,-69,-284,132,132,-284,132,132,-244,-247,-245,-241,-242,-246,-248,132,-250,-251,-243,-249,-12,132,132,-11,132,132,132,132,-234,-233,132,-231,132,132,-217,132,-230,132,-84,-218,132,132,132,-337,-337,-198,132,132,132,-337,-284,-229,-232,132,-221,132,-83,-219,-68,132,-28,-337,132,-11,132,132,-220,132,132,132,-284,132,132,132,-337,132,-225,-224,-222,-84,132,132,132,-226,-223,132,-228,-227,]),'VOID':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[6,-337,-113,-128,6,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,6,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,6,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,6,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,6,-131,-95,-101,-97,6,-53,-126,6,-88,6,6,-93,6,-147,-335,-146,6,-167,-166,-182,-100,-126,6,-87,-90,-94,-92,-61,-72,6,-144,-142,6,6,6,-73,6,-89,6,6,6,-149,-159,-160,-156,-336,6,-183,-30,6,6,-74,6,6,6,6,-174,-175,6,-143,-140,6,-141,-145,-76,-79,-82,-75,-77,6,-81,-215,-214,-80,-216,-78,-127,6,-153,6,-151,-148,-157,-168,-69,-36,-35,6,6,6,-234,-233,6,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,6,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LBRACKET':([2,3,5,6,7,10,11,12,13,18,20,22,23,26,27,30,33,34,35,36,39,42,43,44,46,48,49,50,54,56,58,60,62,68,71,73,76,77,80,81,82,86,96,97,98,100,101,103,104,105,106,109,111,127,132,133,134,136,138,139,140,141,142,143,145,147,148,152,153,154,156,160,161,163,164,166,167,168,169,176,177,187,191,198,199,200,211,216,227,230,235,236,237,238,240,241,261,263,269,275,276,278,279,280,283,310,312,314,316,317,328,340,341,342,344,345,347,355,356,371,376,402,403,404,405,407,411,414,442,443,448,449,453,454,457,458,464,465,470,472,474,482,483,488,489,490,492,511,512,518,519,520,526,527,529,530,531,532,544,545,547,550,551,559,560,563,565,570,571,572,],[-113,-128,-124,-110,-106,-104,-107,-125,-105,-99,-109,-120,-115,-102,-126,-108,-238,-111,-337,-122,-129,-29,-121,-116,-112,117,-123,-117,-119,-114,-130,-118,-103,-96,-98,128,-131,-37,-95,-101,-97,117,-147,-335,-146,-167,-166,-28,-180,-182,-27,-100,-126,128,-317,-321,-318,-303,-324,-330,-313,-319,-144,-301,-314,-142,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,265,-323,-312,282,-149,-336,-183,-181,-30,282,-38,373,-326,-334,-332,-331,-333,-174,-175,-298,-297,-143,-140,282,282,-141,-145,421,-312,-127,-153,-151,-148,-168,-36,-35,282,282,459,-45,-44,-43,-199,373,-296,-295,-294,-293,-292,-305,421,-152,-150,-170,-169,-31,-34,282,459,-39,-42,-202,373,-200,-290,-291,373,-213,-207,-211,-33,-32,-41,-40,-201,549,-307,-209,-208,-210,-212,-51,-50,-306,373,-299,-46,-49,-308,-300,-48,-47,-309,]),'WCHAR_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,133,-335,-28,-182,-27,133,-337,-87,-72,-337,133,-286,-285,133,133,-283,-287,-288,133,-284,133,133,133,-336,-183,133,133,-28,-337,133,-28,-337,-337,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,-337,-76,-79,-82,-75,133,-77,133,133,-81,-215,-214,-80,-216,133,-78,133,133,-69,-284,133,133,-284,133,133,-244,-247,-245,-241,-242,-246,-248,133,-250,-251,-243,-249,-12,133,133,-11,133,133,133,133,-234,-233,133,-231,133,133,-217,133,-230,133,-84,-218,133,133,133,-337,-337,-198,133,133,133,-337,-284,-229,-232,133,-221,133,-83,-219,-68,133,-28,-337,133,-11,133,133,-220,133,133,133,-284,133,133,133,-337,133,-225,-224,-222,-84,133,133,133,-226,-223,133,-228,-227,]),'FLOAT_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,134,-335,-28,-182,-27,134,-337,-87,-72,-337,134,-286,-285,134,134,-283,-287,-288,134,-284,134,134,134,-336,-183,134,134,-28,-337,134,-28,-337,-337,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,-337,-76,-79,-82,-75,134,-77,134,134,-81,-215,-214,-80,-216,134,-78,134,134,-69,-284,134,134,-284,134,134,-244,-247,-245,-241,-242,-246,-248,134,-250,-251,-243,-249,-12,134,134,-11,134,134,134,134,-234,-233,134,-231,134,134,-217,134,-230,134,-84,-218,134,134,134,-337,-337,-198,134,134,134,-337,-284,-229,-232,134,-221,134,-83,-219,-68,134,-28,-337,134,-11,134,134,-220,134,134,134,-284,134,134,134,-337,134,-225,-224,-222,-84,134,134,134,-226,-223,134,-228,-227,]),'MINUS':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,132,133,134,135,136,137,138,139,140,141,143,144,145,146,148,149,150,151,152,153,154,156,158,160,161,162,163,164,165,166,167,168,169,171,173,174,175,176,181,191,198,201,204,205,206,218,219,220,224,227,229,230,231,232,233,234,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,268,273,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,478,480,481,482,483,484,487,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,135,-335,-28,-182,-27,135,-337,-87,-72,-337,135,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-301,-274,-314,135,-327,135,-283,-287,-325,-304,-322,-302,-255,-315,-289,245,-328,-316,-288,-329,-320,-276,-323,135,-284,135,135,-312,135,-336,-183,135,135,-28,-337,135,-28,-337,-274,-337,135,-326,135,-280,135,-277,-334,-332,-331,-333,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,-298,-297,135,135,-279,-278,-337,-76,-79,-82,-75,135,-77,135,135,-81,-215,-214,-80,-216,135,-78,-312,135,135,-69,-284,135,135,-284,135,135,-244,-247,-245,-241,-242,-246,-248,135,-250,-251,-243,-249,-12,135,135,-11,245,245,245,-260,245,245,245,-259,245,245,-257,-256,245,245,245,245,245,-258,-296,-295,-294,-293,-292,-305,135,135,135,135,-234,-233,135,-231,135,135,-217,135,-230,135,-84,-218,135,135,135,-337,-337,-198,135,-281,-282,135,-290,-291,135,-275,-337,-284,-229,-232,135,-221,135,-83,-219,-68,135,-28,-337,135,-11,135,135,-220,135,135,135,-284,135,135,-306,135,-337,-299,135,-225,-224,-222,-84,-300,135,135,135,-226,-223,135,-228,-227,]),'RPAREN':([2,3,5,6,7,10,11,12,13,18,20,22,23,26,27,30,33,34,35,36,39,42,43,44,46,48,49,50,54,56,58,60,62,68,71,73,76,77,80,81,82,86,96,98,100,101,103,104,105,106,107,109,111,118,125,127,129,132,133,134,136,138,139,140,141,142,143,144,145,147,148,152,153,154,156,157,158,159,160,161,162,163,164,166,167,168,169,176,177,178,183,187,191,198,199,200,203,207,208,209,210,211,212,213,215,216,221,222,224,225,230,232,234,235,236,237,238,240,241,261,263,266,268,269,270,271,272,273,274,275,276,277,278,279,280,281,283,294,312,314,316,317,328,340,341,342,343,344,345,346,347,348,355,356,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,408,409,411,414,415,416,417,418,422,433,439,442,443,448,449,452,453,454,457,458,460,461,462,463,464,465,468,476,478,480,482,483,486,487,489,490,492,495,501,503,507,511,512,516,517,518,519,524,525,526,527,529,530,531,532,544,545,547,551,553,556,559,560,563,565,566,567,570,571,572,573,],[-113,-128,-124,-110,-106,-104,-107,-125,-105,-99,-109,-120,-115,-102,-126,-108,-238,-111,-337,-122,-129,-29,-121,-116,-112,-52,-123,-117,-119,-114,-130,-118,-103,-96,-98,-54,-131,-37,-95,-101,-97,-53,-147,-146,-167,-166,-28,-180,-182,-27,200,-100,-126,-337,216,-55,-337,-317,-321,-318,-303,-324,-330,-313,-319,-144,-301,-274,-314,-142,-327,-325,-304,-322,-302,240,-255,241,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-337,-252,312,-149,-336,-183,-181,-30,332,340,-17,341,-186,-337,-18,-184,-191,-38,355,356,-274,-239,-326,-280,-277,-334,-332,-331,-333,-174,-175,-298,-297,407,-279,-143,411,413,-235,-278,-203,-140,-204,-1,-337,-141,-145,-2,-206,-14,-127,-153,-151,-148,-168,-36,-35,-337,-190,-204,-56,-188,-45,-189,-44,-43,476,477,478,479,480,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-310,483,-305,-205,-23,-24,489,490,-337,-13,-218,-152,-150,-170,-169,510,-31,-34,-204,-57,-337,-192,-185,-187,-39,-42,-240,-237,-281,-282,-290,-291,-236,-275,-213,-207,-211,532,535,537,539,-33,-32,544,545,-41,-40,-254,-311,547,-307,-209,-208,-210,-212,-51,-50,-306,-299,-337,568,-46,-49,-308,-300,-337,574,-48,-47,-309,577,]),'STRUCT':([0,1,3,7,10,11,13,14,16,17,19,20,21,25,26,27,29,30,38,39,40,42,45,47,48,52,53,55,58,59,61,62,63,64,65,66,67,75,85,86,87,90,91,93,94,95,97,99,105,118,119,120,121,122,123,124,129,172,174,180,181,182,184,185,186,188,189,190,191,198,200,214,223,229,231,233,239,240,241,267,278,284,285,286,289,291,298,300,301,302,303,305,308,312,313,315,318,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,446,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[24,-337,-128,-106,-104,-107,-105,-64,-60,-67,-66,-109,24,-65,-102,-337,-131,-108,-63,-129,24,-29,-62,-70,-52,-337,-337,-337,-130,24,-71,-103,-337,-9,-131,-91,-10,24,24,-53,-337,-88,24,24,-93,24,-335,24,-182,24,-87,-90,-94,-92,-61,-72,24,24,24,-73,24,-89,24,24,24,-159,-160,-156,-336,-183,-30,24,-74,24,24,24,24,-174,-175,24,24,-76,-79,-82,-75,-77,24,-81,-215,-214,-80,-216,-78,-127,24,24,-157,-69,-36,-35,24,24,24,-234,-233,24,-231,-217,-230,-81,-84,-218,-158,-31,-34,24,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LONG':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[23,-337,-113,-128,23,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,23,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,23,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,23,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,23,-131,-95,-101,-97,23,-53,-126,23,-88,23,23,-93,23,-147,-335,-146,23,-167,-166,-182,-100,-126,23,-87,-90,-94,-92,-61,-72,23,-144,-142,23,23,23,-73,23,-89,23,23,23,-149,-159,-160,-156,-336,23,-183,-30,23,23,-74,23,23,23,23,-174,-175,23,-143,-140,23,-141,-145,-76,-79,-82,-75,-77,23,-81,-215,-214,-80,-216,-78,-127,23,-153,23,-151,-148,-157,-168,-69,-36,-35,23,23,23,-234,-233,23,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,23,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'PLUS':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,132,133,134,135,136,137,138,139,140,141,143,144,145,146,148,149,150,151,152,153,154,156,158,160,161,162,163,164,165,166,167,168,169,171,173,174,175,176,181,191,198,201,204,205,206,218,219,220,224,227,229,230,231,232,233,234,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,268,273,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,478,480,481,482,483,484,487,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,137,-335,-28,-182,-27,137,-337,-87,-72,-337,137,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-301,-274,-314,137,-327,137,-283,-287,-325,-304,-322,-302,-255,-315,-289,249,-328,-316,-288,-329,-320,-276,-323,137,-284,137,137,-312,137,-336,-183,137,137,-28,-337,137,-28,-337,-274,-337,137,-326,137,-280,137,-277,-334,-332,-331,-333,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,-298,-297,137,137,-279,-278,-337,-76,-79,-82,-75,137,-77,137,137,-81,-215,-214,-80,-216,137,-78,-312,137,137,-69,-284,137,137,-284,137,137,-244,-247,-245,-241,-242,-246,-248,137,-250,-251,-243,-249,-12,137,137,-11,249,249,249,-260,249,249,249,-259,249,249,-257,-256,249,249,249,249,249,-258,-296,-295,-294,-293,-292,-305,137,137,137,137,-234,-233,137,-231,137,137,-217,137,-230,137,-84,-218,137,137,137,-337,-337,-198,137,-281,-282,137,-290,-291,137,-275,-337,-284,-229,-232,137,-221,137,-83,-219,-68,137,-28,-337,137,-11,137,137,-220,137,137,137,-284,137,137,-306,137,-337,-299,137,-225,-224,-222,-84,-300,137,137,137,-226,-223,137,-228,-227,]),'ELLIPSIS':([350,],[462,]),'U32STRING_LITERAL':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,139,146,148,149,150,151,153,163,165,166,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,139,-335,-28,-182,-27,139,-337,-87,-72,-337,139,-286,-285,-330,139,-327,139,-283,-287,235,-328,-288,-329,139,-284,139,139,139,-336,-183,139,139,-28,-337,139,-28,-337,-337,139,139,139,-334,-332,-331,-333,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,-337,-76,-79,-82,-75,139,-77,139,139,-81,-215,-214,-80,-216,139,-78,139,139,-69,-284,139,139,-284,139,139,-244,-247,-245,-241,-242,-246,-248,139,-250,-251,-243,-249,-12,139,139,-11,139,139,139,139,-234,-233,139,-231,139,139,-217,139,-230,139,-84,-218,139,139,139,-337,-337,-198,139,139,139,-337,-284,-229,-232,139,-221,139,-83,-219,-68,139,-28,-337,139,-11,139,139,-220,139,139,139,-284,139,139,139,-337,139,-225,-224,-222,-84,139,139,139,-226,-223,139,-228,-227,]),'GT':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,250,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,250,-262,-260,-264,250,-263,-259,-266,250,-257,-256,-265,250,250,250,250,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'GOTO':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,287,-336,-76,-79,-82,-75,-77,287,-81,-215,-214,-80,-216,287,-78,-69,-234,-233,-231,287,-217,-230,287,-84,-218,287,-229,-232,-221,287,-83,-219,-68,287,-220,287,287,-225,-224,-222,-84,287,287,-226,-223,287,-228,-227,]),'ENUM':([0,1,3,7,10,11,13,14,16,17,19,20,21,25,26,27,29,30,38,39,40,42,45,47,48,52,53,55,58,59,61,62,63,64,65,66,67,75,85,86,87,90,91,93,94,95,97,99,105,118,119,120,121,122,123,124,129,172,174,180,181,182,184,185,186,188,189,190,191,198,200,214,223,229,231,233,239,240,241,267,278,284,285,286,289,291,298,300,301,302,303,305,308,312,313,315,318,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,446,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[32,-337,-128,-106,-104,-107,-105,-64,-60,-67,-66,-109,32,-65,-102,-337,-131,-108,-63,-129,32,-29,-62,-70,-52,-337,-337,-337,-130,32,-71,-103,-337,-9,-131,-91,-10,32,32,-53,-337,-88,32,32,-93,32,-335,32,-182,32,-87,-90,-94,-92,-61,-72,32,32,32,-73,32,-89,32,32,32,-159,-160,-156,-336,-183,-30,32,-74,32,32,32,32,-174,-175,32,32,-76,-79,-82,-75,-77,32,-81,-215,-214,-80,-216,-78,-127,32,32,-157,-69,-36,-35,32,32,32,-234,-233,32,-231,-217,-230,-81,-84,-218,-158,-31,-34,32,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'PERIOD':([97,132,133,134,136,138,139,140,141,143,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,227,230,235,236,237,238,261,263,310,371,376,402,403,404,405,407,411,470,472,474,482,483,488,520,526,527,547,550,551,563,565,572,],[-335,-317,-321,-318,-303,-324,-330,-313,-319,-301,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,264,-323,-312,-336,372,-326,-334,-332,-331,-333,-298,-297,-312,-199,372,-296,-295,-294,-293,-292,-305,-202,372,-200,-290,-291,372,-201,548,-307,-306,372,-299,-308,-300,-309,]),'GE':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,254,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,254,-262,-260,-264,254,-263,-259,-266,254,-257,-256,-265,254,254,254,254,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'INT_CONST_DEC':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,140,-335,-28,-182,-27,140,-337,-87,-72,-337,140,-286,-285,140,140,-283,-287,-288,140,-284,140,140,140,-336,-183,140,140,-28,-337,140,-28,-337,-337,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,-337,-76,-79,-82,-75,140,-77,140,140,-81,-215,-214,-80,-216,140,-78,140,140,-69,-284,140,140,-284,140,140,-244,-247,-245,-241,-242,-246,-248,140,-250,-251,-243,-249,-12,140,140,-11,140,140,140,140,-234,-233,140,-231,140,140,-217,140,-230,140,-84,-218,140,140,140,-337,-337,-198,140,140,140,-337,-284,-229,-232,140,-221,140,-83,-219,-68,140,-28,-337,140,-11,140,140,-220,140,140,140,-284,140,140,140,-337,140,-225,-224,-222,-84,140,140,140,-226,-223,140,-228,-227,]),'ARROW':([132,133,134,136,138,139,140,141,143,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,230,235,236,237,238,261,263,310,402,403,404,405,407,411,482,483,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,262,-323,-312,-336,-326,-334,-332,-331,-333,-298,-297,-312,-296,-295,-294,-293,-292,-305,-290,-291,-306,-299,-300,]),'_STATIC_ASSERT':([0,14,16,17,19,25,38,45,47,59,61,97,119,123,124,180,181,191,223,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[41,-64,-60,-67,-66,-65,-63,-62,-70,41,-71,-335,-87,-61,-72,-73,41,-336,-74,-76,-79,-82,-75,-77,41,-81,-215,-214,-80,-216,41,-78,-69,-234,-233,-231,41,-217,-230,41,-84,-218,41,-229,-232,-221,41,-83,-219,-68,41,-220,41,41,-225,-224,-222,-84,41,41,-226,-223,41,-228,-227,]),'CHAR':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[46,-337,-113,-128,46,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,46,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,46,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,46,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,46,-131,-95,-101,-97,46,-53,-126,46,-88,46,46,-93,46,-147,-335,-146,46,-167,-166,-182,-100,-126,46,-87,-90,-94,-92,-61,-72,46,-144,-142,46,46,46,-73,46,-89,46,46,46,-149,-159,-160,-156,-336,46,-183,-30,46,46,-74,46,46,46,46,-174,-175,46,-143,-140,46,-141,-145,-76,-79,-82,-75,-77,46,-81,-215,-214,-80,-216,-78,-127,46,-153,46,-151,-148,-157,-168,-69,-36,-35,46,46,46,-234,-233,46,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,46,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'HEX_FLOAT_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,141,-335,-28,-182,-27,141,-337,-87,-72,-337,141,-286,-285,141,141,-283,-287,-288,141,-284,141,141,141,-336,-183,141,141,-28,-337,141,-28,-337,-337,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,-337,-76,-79,-82,-75,141,-77,141,141,-81,-215,-214,-80,-216,141,-78,141,141,-69,-284,141,141,-284,141,141,-244,-247,-245,-241,-242,-246,-248,141,-250,-251,-243,-249,-12,141,141,-11,141,141,141,141,-234,-233,141,-231,141,141,-217,141,-230,141,-84,-218,141,141,141,-337,-337,-198,141,141,141,-337,-284,-229,-232,141,-221,141,-83,-219,-68,141,-28,-337,141,-11,141,141,-220,141,141,141,-284,141,141,141,-337,141,-225,-224,-222,-84,141,141,141,-226,-223,141,-228,-227,]),'DOUBLE':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[50,-337,-113,-128,50,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,50,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,50,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,50,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,50,-131,-95,-101,-97,50,-53,-126,50,-88,50,50,-93,50,-147,-335,-146,50,-167,-166,-182,-100,-126,50,-87,-90,-94,-92,-61,-72,50,-144,-142,50,50,50,-73,50,-89,50,50,50,-149,-159,-160,-156,-336,50,-183,-30,50,50,-74,50,50,50,50,-174,-175,50,-143,-140,50,-141,-145,-76,-79,-82,-75,-77,50,-81,-215,-214,-80,-216,-78,-127,50,-153,50,-151,-148,-157,-168,-69,-36,-35,50,50,50,-234,-233,50,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,50,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'MINUSEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,358,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'INT_CONST_OCT':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,145,-335,-28,-182,-27,145,-337,-87,-72,-337,145,-286,-285,145,145,-283,-287,-288,145,-284,145,145,145,-336,-183,145,145,-28,-337,145,-28,-337,-337,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,-337,-76,-79,-82,-75,145,-77,145,145,-81,-215,-214,-80,-216,145,-78,145,145,-69,-284,145,145,-284,145,145,-244,-247,-245,-241,-242,-246,-248,145,-250,-251,-243,-249,-12,145,145,-11,145,145,145,145,-234,-233,145,-231,145,145,-217,145,-230,145,-84,-218,145,145,145,-337,-337,-198,145,145,145,-337,-284,-229,-232,145,-221,145,-83,-219,-68,145,-28,-337,145,-11,145,145,-220,145,145,145,-284,145,145,145,-337,145,-225,-224,-222,-84,145,145,145,-226,-223,145,-228,-227,]),'TIMESEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,367,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'OR':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,259,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,259,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,259,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'SHORT':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[2,-337,-113,-128,2,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,2,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,2,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,2,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,2,-131,-95,-101,-97,2,-53,-126,2,-88,2,2,-93,2,-147,-335,-146,2,-167,-166,-182,-100,-126,2,-87,-90,-94,-92,-61,-72,2,-144,-142,2,2,2,-73,2,-89,2,2,2,-149,-159,-160,-156,-336,2,-183,-30,2,2,-74,2,2,2,2,-174,-175,2,-143,-140,2,-141,-145,-76,-79,-82,-75,-77,2,-81,-215,-214,-80,-216,-78,-127,2,-153,2,-151,-148,-157,-168,-69,-36,-35,2,2,2,-234,-233,2,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,2,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'RETURN':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,290,-336,-76,-79,-82,-75,-77,290,-81,-215,-214,-80,-216,290,-78,-69,-234,-233,-231,290,-217,-230,290,-84,-218,290,-229,-232,-221,290,-83,-219,-68,290,-220,290,290,-225,-224,-222,-84,290,290,-226,-223,290,-228,-227,]),'RSHIFTEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,368,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'_ALIGNAS':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,85,86,87,89,90,93,95,96,97,98,99,100,101,109,111,118,119,123,124,129,142,147,174,177,180,181,182,184,185,186,187,188,189,190,191,192,200,211,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[8,8,-113,-128,8,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,8,-120,-115,-65,-102,8,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,8,8,-119,8,-114,-130,8,-118,-71,-103,8,-131,-96,-98,8,-131,-95,-101,-97,8,-53,8,8,-88,8,8,-147,-335,-146,8,-167,-166,-100,-126,8,-87,-61,-72,8,-144,-142,8,8,-73,8,-89,8,8,8,-149,-159,-160,-156,-336,8,-30,8,-74,8,8,8,8,-174,-175,8,-143,-140,8,-141,-145,-76,-79,-82,-75,-77,8,-81,-215,-214,-80,-216,-78,-127,8,-153,8,-151,-148,-157,-168,-69,-36,-35,8,8,8,-234,-233,8,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,8,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'RESTRICT':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,35,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,85,86,87,89,90,93,95,96,97,98,99,100,101,103,105,109,111,117,118,119,123,124,128,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,205,206,211,219,220,223,229,231,233,239,240,241,267,269,275,278,279,280,282,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,459,460,496,497,500,505,506,510,511,512,514,515,536,554,555,557,558,575,576,578,579,],[39,39,-113,-128,39,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,39,-120,-115,-65,-102,39,-131,-108,-238,-111,39,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,39,39,-119,39,-114,-130,39,-118,-71,-103,39,-131,-96,-98,39,-131,-95,-101,-97,39,-53,39,39,-88,39,39,-147,-335,-146,39,-167,-166,39,-182,-100,-126,39,39,-87,-61,-72,39,39,-144,-142,39,39,39,-73,39,-89,39,39,39,-149,-159,-160,-156,-336,39,-183,-30,39,39,39,39,39,-74,39,39,39,39,-174,-175,39,-143,-140,39,-141,-145,39,-76,-79,-82,-75,-77,39,-81,-215,-214,-80,-216,-78,-127,39,-153,39,-151,-148,-157,-168,-69,-36,-35,39,39,39,-234,-233,39,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,39,39,-229,-232,-221,-83,-219,-68,-33,-32,39,39,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'STATIC':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,105,109,111,117,118,119,123,124,128,129,180,181,182,187,191,198,200,205,211,219,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,459,460,496,497,500,505,506,510,511,512,514,536,554,555,557,558,575,576,578,579,],[10,10,-113,-128,10,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,10,-120,-115,-65,-102,10,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,10,10,-119,10,-114,-130,10,-118,-71,-103,10,-131,-96,-98,10,-131,-95,-101,-97,-53,10,10,-88,10,-147,-335,-146,-167,-166,-182,-100,-126,206,10,-87,-61,-72,220,10,-73,10,-89,-149,-336,-183,-30,338,10,353,-74,-174,-175,10,-76,-79,-82,-75,-77,10,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,10,10,10,-234,-233,10,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,515,10,-229,-232,-221,-83,-219,-68,-33,-32,542,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'SIZEOF':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,146,-335,-28,-182,-27,146,-337,-87,-72,-337,146,-286,-285,146,146,-283,-287,-288,146,-284,146,146,146,-336,-183,146,146,-28,-337,146,-28,-337,-337,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,-337,-76,-79,-82,-75,146,-77,146,146,-81,-215,-214,-80,-216,146,-78,146,146,-69,-284,146,146,-284,146,146,-244,-247,-245,-241,-242,-246,-248,146,-250,-251,-243,-249,-12,146,146,-11,146,146,146,146,-234,-233,146,-231,146,146,-217,146,-230,146,-84,-218,146,146,146,-337,-337,-198,146,146,146,-337,-284,-229,-232,146,-221,146,-83,-219,-68,146,-28,-337,146,-11,146,146,-220,146,146,146,-284,146,146,146,-337,146,-225,-224,-222,-84,146,146,146,-226,-223,146,-228,-227,]),'UNSIGNED':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[22,-337,-113,-128,22,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,22,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,22,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,22,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,22,-131,-95,-101,-97,22,-53,-126,22,-88,22,22,-93,22,-147,-335,-146,22,-167,-166,-182,-100,-126,22,-87,-90,-94,-92,-61,-72,22,-144,-142,22,22,22,-73,22,-89,22,22,22,-149,-159,-160,-156,-336,22,-183,-30,22,22,-74,22,22,22,22,-174,-175,22,-143,-140,22,-141,-145,-76,-79,-82,-75,-77,22,-81,-215,-214,-80,-216,-78,-127,22,-153,22,-151,-148,-157,-168,-69,-36,-35,22,22,22,-234,-233,22,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,22,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'UNION':([0,1,3,7,10,11,13,14,16,17,19,20,21,25,26,27,29,30,38,39,40,42,45,47,48,52,53,55,58,59,61,62,63,64,65,66,67,75,85,86,87,90,91,93,94,95,97,99,105,118,119,120,121,122,123,124,129,172,174,180,181,182,184,185,186,188,189,190,191,198,200,214,223,229,231,233,239,240,241,267,278,284,285,286,289,291,298,300,301,302,303,305,308,312,313,315,318,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,446,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[28,-337,-128,-106,-104,-107,-105,-64,-60,-67,-66,-109,28,-65,-102,-337,-131,-108,-63,-129,28,-29,-62,-70,-52,-337,-337,-337,-130,28,-71,-103,-337,-9,-131,-91,-10,28,28,-53,-337,-88,28,28,-93,28,-335,28,-182,28,-87,-90,-94,-92,-61,-72,28,28,28,-73,28,-89,28,28,28,-159,-160,-156,-336,-183,-30,28,-74,28,28,28,28,-174,-175,28,28,-76,-79,-82,-75,-77,28,-81,-215,-214,-80,-216,-78,-127,28,28,-157,-69,-36,-35,28,28,28,-234,-233,28,-231,-217,-230,-81,-84,-218,-158,-31,-34,28,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'COLON':([2,3,5,6,12,22,23,33,34,36,39,42,43,44,46,48,49,50,54,56,58,60,73,74,76,77,86,96,98,100,101,111,127,132,133,134,136,138,139,140,141,142,143,144,145,147,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,178,179,187,191,192,200,216,224,225,230,232,234,235,236,237,238,240,241,261,263,268,269,272,273,275,279,280,295,310,312,314,316,317,324,328,340,341,355,356,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,407,411,431,442,443,445,448,449,453,454,464,465,468,476,478,480,482,483,486,487,511,512,518,519,524,547,551,565,],[-113,-128,-124,-110,-125,-120,-115,-238,-111,-122,-129,-29,-121,-116,-112,-52,-123,-117,-119,-114,-130,-118,-54,-179,-131,-37,-53,-147,-146,-167,-166,-126,-55,-317,-321,-318,-303,-324,-330,-313,-319,-144,-301,-274,-314,-142,-327,-325,-304,-322,-302,-255,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-252,-178,-149,-336,319,-30,-38,-274,-239,-326,-280,-277,-334,-332,-331,-333,-174,-175,-298,-297,-279,-143,-235,-278,-140,-141,-145,429,440,-127,-153,-151,-148,447,-168,-36,-35,-44,-43,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,481,-270,-258,-296,-295,-294,-293,-292,-305,502,-152,-150,319,-170,-169,-31,-34,-39,-42,-240,-237,-281,-282,-290,-291,-236,-275,-33,-32,-41,-40,-254,-306,-299,-300,]),'$end':([0,9,14,16,17,19,25,38,45,47,57,59,61,119,123,124,180,191,223,332,439,510,],[-337,0,-64,-60,-67,-66,-65,-63,-62,-70,-59,-58,-71,-87,-61,-72,-73,-336,-74,-69,-218,-68,]),'WSTRING_LITERAL':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,139,146,148,149,150,151,153,163,165,166,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,148,-335,-28,-182,-27,148,-337,-87,-72,-337,148,-286,-285,-330,148,-327,148,-283,-287,237,-328,-288,-329,148,-284,148,148,148,-336,-183,148,148,-28,-337,148,-28,-337,-337,148,148,148,-334,-332,-331,-333,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,-337,-76,-79,-82,-75,148,-77,148,148,-81,-215,-214,-80,-216,148,-78,148,148,-69,-284,148,148,-284,148,148,-244,-247,-245,-241,-242,-246,-248,148,-250,-251,-243,-249,-12,148,148,-11,148,148,148,148,-234,-233,148,-231,148,148,-217,148,-230,148,-84,-218,148,148,148,-337,-337,-198,148,148,148,-337,-284,-229,-232,148,-221,148,-83,-219,-68,148,-28,-337,148,-11,148,148,-220,148,148,148,-284,148,148,148,-337,148,-225,-224,-222,-84,148,148,148,-226,-223,148,-228,-227,]),'DIVIDE':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,252,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,252,252,252,252,252,252,252,252,252,252,-257,-256,252,252,252,252,252,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'FOR':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,292,-336,-76,-79,-82,-75,-77,292,-81,-215,-214,-80,-216,292,-78,-69,-234,-233,-231,292,-217,-230,292,-84,-218,292,-229,-232,-221,292,-83,-219,-68,292,-220,292,292,-225,-224,-222,-84,292,292,-226,-223,292,-228,-227,]),'PLUSPLUS':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,132,133,134,135,136,137,138,139,140,141,143,145,146,148,149,150,151,152,153,154,156,160,161,163,164,165,166,167,168,169,171,173,174,175,176,181,191,198,201,204,205,206,218,219,220,227,229,230,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,482,483,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,149,-335,-28,-182,-27,149,-337,-87,-72,-337,149,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-301,-314,149,-327,149,-283,-287,-325,-304,-322,-302,-315,-289,-328,-316,-288,-329,-320,263,-323,149,-284,149,149,-312,149,-336,-183,149,149,-28,-337,149,-28,-337,-337,149,-326,149,149,-334,-332,-331,-333,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,-298,-297,149,149,-337,-76,-79,-82,-75,149,-77,149,149,-81,-215,-214,-80,-216,149,-78,-312,149,149,-69,-284,149,149,-284,149,149,-244,-247,-245,-241,-242,-246,-248,149,-250,-251,-243,-249,-12,149,149,-11,-296,-295,-294,-293,-292,-305,149,149,149,149,-234,-233,149,-231,149,149,-217,149,-230,149,-84,-218,149,149,149,-337,-337,-198,149,149,-290,-291,149,-337,-284,-229,-232,149,-221,149,-83,-219,-68,149,-28,-337,149,-11,149,149,-220,149,149,149,-284,149,149,-306,149,-337,-299,149,-225,-224,-222,-84,-300,149,149,149,-226,-223,149,-228,-227,]),'EQUALS':([42,48,73,74,75,77,78,86,110,127,132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,179,191,197,200,216,224,230,232,234,235,236,237,238,261,263,268,273,310,340,341,355,356,371,376,402,403,404,405,407,411,453,454,464,465,470,474,478,480,482,483,487,511,512,518,519,520,547,551,565,],[-29,-52,-54,-179,-178,-37,131,-53,201,-55,-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-178,-336,329,-30,-38,360,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-36,-35,-44,-43,-199,475,-296,-295,-294,-293,-292,-305,-31,-34,-39,-42,-202,-200,-281,-282,-290,-291,-275,-33,-32,-41,-40,-201,-306,-299,-300,]),'ELSE':([61,124,191,284,285,286,289,291,300,303,308,332,424,425,428,435,437,438,439,496,497,500,505,506,510,536,554,555,557,558,575,576,578,579,],[-71,-72,-336,-76,-79,-82,-75,-77,-81,-80,-78,-69,-234,-233,-231,-230,-81,-84,-218,-229,-232,-221,-83,-219,-68,-220,-225,-224,-222,569,-226,-223,-228,-227,]),'ANDEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,365,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'EQ':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,256,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,256,-262,-260,-264,-268,-263,-259,-266,256,-257,-256,-265,256,-267,256,256,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'AND':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,132,133,134,135,136,137,138,139,140,141,143,144,145,146,148,149,150,151,152,153,154,156,158,160,161,162,163,164,165,166,167,168,169,171,173,174,175,176,181,191,198,201,204,205,206,218,219,220,224,227,229,230,231,232,233,234,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,268,273,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,478,480,481,482,483,484,487,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,150,-335,-28,-182,-27,150,-337,-87,-72,-337,150,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-301,-274,-314,150,-327,150,-283,-287,-325,-304,-322,-302,-255,-315,-289,257,-328,-316,-288,-329,-320,-276,-323,150,-284,150,150,-312,150,-336,-183,150,150,-28,-337,150,-28,-337,-274,-337,150,-326,150,-280,150,-277,-334,-332,-331,-333,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,-298,-297,150,150,-279,-278,-337,-76,-79,-82,-75,150,-77,150,150,-81,-215,-214,-80,-216,150,-78,-312,150,150,-69,-284,150,150,-284,150,150,-244,-247,-245,-241,-242,-246,-248,150,-250,-251,-243,-249,-12,150,150,-11,-261,257,-262,-260,-264,-268,-263,-259,-266,257,-257,-256,-265,257,-267,-269,257,-258,-296,-295,-294,-293,-292,-305,150,150,150,150,-234,-233,150,-231,150,150,-217,150,-230,150,-84,-218,150,150,150,-337,-337,-198,150,-281,-282,150,-290,-291,150,-275,-337,-284,-229,-232,150,-221,150,-83,-219,-68,150,-28,-337,150,-11,150,150,-220,150,150,150,-284,150,150,-306,150,-337,-299,150,-225,-224,-222,-84,-300,150,150,150,-226,-223,150,-228,-227,]),'TYPEID':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,71,72,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,103,104,105,106,109,111,118,119,120,121,122,123,124,126,129,142,147,172,174,180,181,182,184,185,186,187,188,189,190,191,192,198,199,200,202,211,214,223,229,231,233,239,240,241,262,264,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,344,350,422,424,425,427,428,432,435,437,438,439,442,443,445,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[33,-337,-113,-128,77,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,33,-120,-115,-154,-65,-102,-126,-155,-131,-108,96,100,-238,-111,-337,-122,-63,-129,33,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,33,-118,-71,-103,-337,-9,-131,-91,-10,-96,77,-98,77,33,-131,-95,-101,-97,33,-53,-126,77,-88,33,33,-93,33,-147,-335,-146,33,-167,-166,-28,-180,-182,-27,-100,-126,33,-87,-90,-94,-92,-61,-72,77,33,-144,-142,33,33,-73,33,-89,33,33,33,-149,-159,-160,-156,-336,77,-183,-181,-30,77,347,33,-74,33,33,33,33,-174,-175,402,404,33,-143,-140,33,-141,-145,-76,-79,-82,-75,-77,33,-81,-215,-214,-80,-216,-78,-127,33,-153,33,-151,-148,-157,-168,-69,-36,-35,33,347,33,33,-234,-233,33,-231,-217,-230,-81,-84,-218,-152,-150,77,-158,-170,-169,-31,-34,33,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LBRACE':([21,24,28,31,32,42,48,61,75,86,88,90,92,93,96,97,98,100,101,119,124,130,131,181,182,191,200,201,227,229,284,285,286,289,291,298,300,301,302,303,305,307,308,332,340,341,369,375,377,413,424,425,428,429,432,435,437,438,439,440,453,454,472,475,477,478,479,488,496,497,500,502,505,506,510,511,512,521,522,535,536,537,539,550,554,555,557,558,569,574,575,576,577,578,579,],[-337,-154,-155,97,97,-29,-52,-71,-337,-53,-7,-88,97,-8,97,-335,97,97,97,-87,-72,97,97,97,-89,-336,-30,97,-337,97,-76,-79,-82,-75,-77,97,-81,-215,-214,-80,-216,97,-78,-69,-36,-35,-12,97,-11,97,-234,-233,-231,97,-217,-230,97,-84,-218,97,-31,-34,-337,-198,97,97,97,-337,-229,-232,-221,97,-83,-219,-68,-33,-32,97,-11,97,-220,97,97,-337,-225,-224,-222,-84,97,97,-226,-223,97,-228,-227,]),'PPHASH':([0,14,16,17,19,25,38,45,47,59,61,119,123,124,180,191,223,332,439,510,],[47,-64,-60,-67,-66,-65,-63,-62,-70,47,-71,-87,-61,-72,-73,-336,-74,-69,-218,-68,]),'INT':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[56,-337,-113,-128,56,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,56,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,56,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,56,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,56,-131,-95,-101,-97,56,-53,-126,56,-88,56,56,-93,56,-147,-335,-146,56,-167,-166,-182,-100,-126,56,-87,-90,-94,-92,-61,-72,56,-144,-142,56,56,56,-73,56,-89,56,56,56,-149,-159,-160,-156,-336,56,-183,-30,56,56,-74,56,56,56,56,-174,-175,56,-143,-140,56,-141,-145,-76,-79,-82,-75,-77,56,-81,-215,-214,-80,-216,-78,-127,56,-153,56,-151,-148,-157,-168,-69,-36,-35,56,56,56,-234,-233,56,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,56,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'SIGNED':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[54,-337,-113,-128,54,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,54,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,54,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,54,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,54,-131,-95,-101,-97,54,-53,-126,54,-88,54,54,-93,54,-147,-335,-146,54,-167,-166,-182,-100,-126,54,-87,-90,-94,-92,-61,-72,54,-144,-142,54,54,54,-73,54,-89,54,54,54,-149,-159,-160,-156,-336,54,-183,-30,54,54,-74,54,54,54,54,-174,-175,54,-143,-140,54,-141,-145,-76,-79,-82,-75,-77,54,-81,-215,-214,-80,-216,-78,-127,54,-153,54,-151,-148,-157,-168,-69,-36,-35,54,54,54,-234,-233,54,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,54,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'CONTINUE':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,293,-336,-76,-79,-82,-75,-77,293,-81,-215,-214,-80,-216,293,-78,-69,-234,-233,-231,293,-217,-230,293,-84,-218,293,-229,-232,-221,293,-83,-219,-68,293,-220,293,293,-225,-224,-222,-84,293,293,-226,-223,293,-228,-227,]),'NOT':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,151,-335,-28,-182,-27,151,-337,-87,-72,-337,151,-286,-285,151,151,-283,-287,-288,151,-284,151,151,151,-336,-183,151,151,-28,-337,151,-28,-337,-337,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,-337,-76,-79,-82,-75,151,-77,151,151,-81,-215,-214,-80,-216,151,-78,151,151,-69,-284,151,151,-284,151,151,-244,-247,-245,-241,-242,-246,-248,151,-250,-251,-243,-249,-12,151,151,-11,151,151,151,151,-234,-233,151,-231,151,151,-217,151,-230,151,-84,-218,151,151,151,-337,-337,-198,151,151,151,-337,-284,-229,-232,151,-221,151,-83,-219,-68,151,-28,-337,151,-11,151,151,-220,151,151,151,-284,151,151,151,-337,151,-225,-224,-222,-84,151,151,151,-226,-223,151,-228,-227,]),'OREQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,366,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'MOD':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,260,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,260,260,260,260,260,260,260,260,260,260,-257,-256,260,260,260,260,260,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'RSHIFT':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,242,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,242,-262,-260,242,242,242,-259,242,242,-257,-256,242,242,242,242,242,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'DEFAULT':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,295,-336,-76,-79,-82,-75,-77,295,-81,-215,-214,-80,-216,295,-78,-69,-234,-233,-231,295,-217,-230,295,-84,-218,295,-229,-232,-221,295,-83,-219,-68,295,-220,295,295,-225,-224,-222,-84,295,295,-226,-223,295,-228,-227,]),'_NORETURN':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[20,20,-113,-128,20,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,20,-120,-115,-65,-102,20,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,20,20,-119,20,-114,-130,20,-118,-71,-103,20,-131,-96,-98,20,-131,-95,-101,-97,-53,20,20,-88,20,-147,-335,-146,-167,-166,-100,-126,20,-87,-61,-72,20,-73,20,-89,-149,-336,-30,20,-74,-174,-175,20,-76,-79,-82,-75,-77,20,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,20,20,20,-234,-233,20,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,20,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'__INT128':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[43,-337,-113,-128,43,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,43,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,43,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,43,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,43,-131,-95,-101,-97,43,-53,-126,43,-88,43,43,-93,43,-147,-335,-146,43,-167,-166,-182,-100,-126,43,-87,-90,-94,-92,-61,-72,43,-144,-142,43,43,43,-73,43,-89,43,43,43,-149,-159,-160,-156,-336,43,-183,-30,43,43,-74,43,43,43,43,-174,-175,43,-143,-140,43,-141,-145,-76,-79,-82,-75,-77,43,-81,-215,-214,-80,-216,-78,-127,43,-153,43,-151,-148,-157,-168,-69,-36,-35,43,43,43,-234,-233,43,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,43,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'WHILE':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,436,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,296,-336,-76,-79,-82,-75,-77,296,-81,-215,-214,-80,-216,296,-78,-69,-234,-233,-231,296,-217,-230,504,296,-84,-218,296,-229,-232,-221,296,-83,-219,-68,296,-220,296,296,-225,-224,-222,-84,296,296,-226,-223,296,-228,-227,]),'U8CHAR_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,154,-335,-28,-182,-27,154,-337,-87,-72,-337,154,-286,-285,154,154,-283,-287,-288,154,-284,154,154,154,-336,-183,154,154,-28,-337,154,-28,-337,-337,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,-337,-76,-79,-82,-75,154,-77,154,154,-81,-215,-214,-80,-216,154,-78,154,154,-69,-284,154,154,-284,154,154,-244,-247,-245,-241,-242,-246,-248,154,-250,-251,-243,-249,-12,154,154,-11,154,154,154,154,-234,-233,154,-231,154,154,-217,154,-230,154,-84,-218,154,154,154,-337,-337,-198,154,154,154,-337,-284,-229,-232,154,-221,154,-83,-219,-68,154,-28,-337,154,-11,154,154,-220,154,154,154,-284,154,154,154,-337,154,-225,-224,-222,-84,154,154,154,-226,-223,154,-228,-227,]),'_ALIGNOF':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,155,-335,-28,-182,-27,155,-337,-87,-72,-337,155,-286,-285,155,155,-283,-287,-288,155,-284,155,155,155,-336,-183,155,155,-28,-337,155,-28,-337,-337,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,-337,-76,-79,-82,-75,155,-77,155,155,-81,-215,-214,-80,-216,155,-78,155,155,-69,-284,155,155,-284,155,155,-244,-247,-245,-241,-242,-246,-248,155,-250,-251,-243,-249,-12,155,155,-11,155,155,155,155,-234,-233,155,-231,155,155,-217,155,-230,155,-84,-218,155,155,155,-337,-337,-198,155,155,155,-337,-284,-229,-232,155,-221,155,-83,-219,-68,155,-28,-337,155,-11,155,155,-220,155,155,155,-284,155,155,155,-337,155,-225,-224,-222,-84,155,155,155,-226,-223,155,-228,-227,]),'EXTERN':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[13,13,-113,-128,13,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,13,-120,-115,-65,-102,13,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,13,13,-119,13,-114,-130,13,-118,-71,-103,13,-131,-96,-98,13,-131,-95,-101,-97,-53,13,13,-88,13,-147,-335,-146,-167,-166,-100,-126,13,-87,-61,-72,13,-73,13,-89,-149,-336,-30,13,-74,-174,-175,13,-76,-79,-82,-75,-77,13,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,13,13,13,-234,-233,13,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,13,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'CASE':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,297,-336,-76,-79,-82,-75,-77,297,-81,-215,-214,-80,-216,297,-78,-69,-234,-233,-231,297,-217,-230,297,-84,-218,297,-229,-232,-221,297,-83,-219,-68,297,-220,297,297,-225,-224,-222,-84,297,297,-226,-223,297,-228,-227,]),'LAND':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,255,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,255,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'REGISTER':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[62,62,-113,-128,62,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,62,-120,-115,-65,-102,62,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,62,62,-119,62,-114,-130,62,-118,-71,-103,62,-131,-96,-98,62,-131,-95,-101,-97,-53,62,62,-88,62,-147,-335,-146,-167,-166,-100,-126,62,-87,-61,-72,62,-73,62,-89,-149,-336,-30,62,-74,-174,-175,62,-76,-79,-82,-75,-77,62,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,62,62,62,-234,-233,62,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,62,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'MODEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,359,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'NE':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,247,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,247,-262,-260,-264,-268,-263,-259,-266,247,-257,-256,-265,247,-267,247,247,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'SWITCH':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,299,-336,-76,-79,-82,-75,-77,299,-81,-215,-214,-80,-216,299,-78,-69,-234,-233,-231,299,-217,-230,299,-84,-218,299,-229,-232,-221,299,-83,-219,-68,299,-220,299,299,-225,-224,-222,-84,299,299,-226,-223,299,-228,-227,]),'INT_CONST_HEX':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,160,-335,-28,-182,-27,160,-337,-87,-72,-337,160,-286,-285,160,160,-283,-287,-288,160,-284,160,160,160,-336,-183,160,160,-28,-337,160,-28,-337,-337,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,-337,-76,-79,-82,-75,160,-77,160,160,-81,-215,-214,-80,-216,160,-78,160,160,-69,-284,160,160,-284,160,160,-244,-247,-245,-241,-242,-246,-248,160,-250,-251,-243,-249,-12,160,160,-11,160,160,160,160,-234,-233,160,-231,160,160,-217,160,-230,160,-84,-218,160,160,160,-337,-337,-198,160,160,160,-337,-284,-229,-232,160,-221,160,-83,-219,-68,160,-28,-337,160,-11,160,160,-220,160,160,160,-284,160,160,160,-337,160,-225,-224,-222,-84,160,160,160,-226,-223,160,-228,-227,]),'_COMPLEX':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[60,-337,-113,-128,60,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,60,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,60,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,60,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,60,-131,-95,-101,-97,60,-53,-126,60,-88,60,60,-93,60,-147,-335,-146,60,-167,-166,-182,-100,-126,60,-87,-90,-94,-92,-61,-72,60,-144,-142,60,60,60,-73,60,-89,60,60,60,-149,-159,-160,-156,-336,60,-183,-30,60,60,-74,60,60,60,60,-174,-175,60,-143,-140,60,-141,-145,-76,-79,-82,-75,-77,60,-81,-215,-214,-80,-216,-78,-127,60,-153,60,-151,-148,-157,-168,-69,-36,-35,60,60,60,-234,-233,60,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,60,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'PPPRAGMASTR':([61,],[124,]),'PLUSEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,362,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'U32CHAR_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,138,-335,-28,-182,-27,138,-337,-87,-72,-337,138,-286,-285,138,138,-283,-287,-288,138,-284,138,138,138,-336,-183,138,138,-28,-337,138,-28,-337,-337,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,-337,-76,-79,-82,-75,138,-77,138,138,-81,-215,-214,-80,-216,138,-78,138,138,-69,-284,138,138,-284,138,138,-244,-247,-245,-241,-242,-246,-248,138,-250,-251,-243,-249,-12,138,138,-11,138,138,138,138,-234,-233,138,-231,138,138,-217,138,-230,138,-84,-218,138,138,138,-337,-337,-198,138,138,138,-337,-284,-229,-232,138,-221,138,-83,-219,-68,138,-28,-337,138,-11,138,138,-220,138,138,138,-284,138,138,138,-337,138,-225,-224,-222,-84,138,138,138,-226,-223,138,-228,-227,]),'CONDOP':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,258,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'U8STRING_LITERAL':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,139,146,148,149,150,151,153,163,165,166,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,163,-335,-28,-182,-27,163,-337,-87,-72,-337,163,-286,-285,-330,163,-327,163,-283,-287,236,-328,-288,-329,163,-284,163,163,163,-336,-183,163,163,-28,-337,163,-28,-337,-337,163,163,163,-334,-332,-331,-333,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,-337,-76,-79,-82,-75,163,-77,163,163,-81,-215,-214,-80,-216,163,-78,163,163,-69,-284,163,163,-284,163,163,-244,-247,-245,-241,-242,-246,-248,163,-250,-251,-243,-249,-12,163,163,-11,163,163,163,163,-234,-233,163,-231,163,163,-217,163,-230,163,-84,-218,163,163,163,-337,-337,-198,163,163,163,-337,-284,-229,-232,163,-221,163,-83,-219,-68,163,-28,-337,163,-11,163,163,-220,163,163,163,-284,163,163,163,-337,163,-225,-224,-222,-84,163,163,163,-226,-223,163,-228,-227,]),'BREAK':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,304,-336,-76,-79,-82,-75,-77,304,-81,-215,-214,-80,-216,304,-78,-69,-234,-233,-231,304,-217,-230,304,-84,-218,304,-229,-232,-221,304,-83,-219,-68,304,-220,304,304,-225,-224,-222,-84,304,304,-226,-223,304,-228,-227,]),'VOLATILE':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,35,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,85,86,87,89,90,93,95,96,97,98,99,100,101,103,105,109,111,117,118,119,123,124,128,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,205,206,211,219,220,223,229,231,233,239,240,241,267,269,275,278,279,280,282,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,459,460,496,497,500,505,506,510,511,512,514,515,536,554,555,557,558,575,576,578,579,],[58,58,-113,-128,58,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,58,-120,-115,-65,-102,58,-131,-108,-238,-111,58,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,58,58,-119,58,-114,-130,58,-118,-71,-103,58,-131,-96,-98,58,-131,-95,-101,-97,58,-53,58,58,-88,58,58,-147,-335,-146,58,-167,-166,58,-182,-100,-126,58,58,-87,-61,-72,58,58,-144,-142,58,58,58,-73,58,-89,58,58,58,-149,-159,-160,-156,-336,58,-183,-30,58,58,58,58,58,-74,58,58,58,58,-174,-175,58,-143,-140,58,-141,-145,58,-76,-79,-82,-75,-77,58,-81,-215,-214,-80,-216,-78,-127,58,-153,58,-151,-148,-157,-168,-69,-36,-35,58,58,58,-234,-233,58,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,58,58,-229,-232,-221,-83,-219,-68,-33,-32,58,58,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'PPPRAGMA':([0,14,16,17,19,25,38,45,47,59,61,97,99,119,123,124,180,181,184,185,186,188,189,190,191,223,284,285,286,289,291,298,300,301,302,303,305,307,308,313,315,318,332,424,425,428,429,432,435,437,438,439,440,446,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[61,-64,-60,-67,-66,-65,-63,-62,-70,61,-71,-335,61,-87,-61,-72,-73,61,61,61,61,-159,-160,-156,-336,-74,-76,-79,-82,-75,-77,61,-81,-215,-214,-80,-216,61,-78,61,61,-157,-69,-234,-233,-231,61,-217,-230,61,-84,-218,61,-158,-229,-232,-221,61,-83,-219,-68,61,-220,61,61,-225,-224,-222,-84,61,61,-226,-223,61,-228,-227,]),'INLINE':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[30,30,-113,-128,30,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,30,-120,-115,-65,-102,30,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,30,30,-119,30,-114,-130,30,-118,-71,-103,30,-131,-96,-98,30,-131,-95,-101,-97,-53,30,30,-88,30,-147,-335,-146,-167,-166,-100,-126,30,-87,-61,-72,30,-73,30,-89,-149,-336,-30,30,-74,-174,-175,30,-76,-79,-82,-75,-77,30,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,30,30,30,-234,-233,30,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,30,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'INT_CONST_BIN':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,164,-335,-28,-182,-27,164,-337,-87,-72,-337,164,-286,-285,164,164,-283,-287,-288,164,-284,164,164,164,-336,-183,164,164,-28,-337,164,-28,-337,-337,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,-337,-76,-79,-82,-75,164,-77,164,164,-81,-215,-214,-80,-216,164,-78,164,164,-69,-284,164,164,-284,164,164,-244,-247,-245,-241,-242,-246,-248,164,-250,-251,-243,-249,-12,164,164,-11,164,164,164,164,-234,-233,164,-231,164,164,-217,164,-230,164,-84,-218,164,164,164,-337,-337,-198,164,164,164,-337,-284,-229,-232,164,-221,164,-83,-219,-68,164,-28,-337,164,-11,164,164,-220,164,164,164,-284,164,164,164,-337,164,-225,-224,-222,-84,164,164,164,-226,-223,164,-228,-227,]),'DO':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,307,-336,-76,-79,-82,-75,-77,307,-81,-215,-214,-80,-216,307,-78,-69,-234,-233,-231,307,-217,-230,307,-84,-218,307,-229,-232,-221,307,-83,-219,-68,307,-220,307,307,-225,-224,-222,-84,307,307,-226,-223,307,-228,-227,]),'LNOT':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,165,-335,-28,-182,-27,165,-337,-87,-72,-337,165,-286,-285,165,165,-283,-287,-288,165,-284,165,165,165,-336,-183,165,165,-28,-337,165,-28,-337,-337,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,-337,-76,-79,-82,-75,165,-77,165,165,-81,-215,-214,-80,-216,165,-78,165,165,-69,-284,165,165,-284,165,165,-244,-247,-245,-241,-242,-246,-248,165,-250,-251,-243,-249,-12,165,165,-11,165,165,165,165,-234,-233,165,-231,165,165,-217,165,-230,165,-84,-218,165,165,165,-337,-337,-198,165,165,165,-337,-284,-229,-232,165,-221,165,-83,-219,-68,165,-28,-337,165,-11,165,165,-220,165,165,165,-284,165,165,165,-337,165,-225,-224,-222,-84,165,165,165,-226,-223,165,-228,-227,]),'CONST':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,35,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,85,86,87,89,90,93,95,96,97,98,99,100,101,103,105,109,111,117,118,119,123,124,128,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,205,206,211,219,220,223,229,231,233,239,240,241,267,269,275,278,279,280,282,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,459,460,496,497,500,505,506,510,511,512,514,515,536,554,555,557,558,575,576,578,579,],[3,3,-113,-128,3,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,3,-120,-115,-65,-102,3,-131,-108,-238,-111,3,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,3,3,-119,3,-114,-130,3,-118,-71,-103,3,-131,-96,-98,3,-131,-95,-101,-97,3,-53,3,3,-88,3,3,-147,-335,-146,3,-167,-166,3,-182,-100,-126,3,3,-87,-61,-72,3,3,-144,-142,3,3,3,-73,3,-89,3,3,3,-149,-159,-160,-156,-336,3,-183,-30,3,3,3,3,3,-74,3,3,3,3,-174,-175,3,-143,-140,3,-141,-145,3,-76,-79,-82,-75,-77,3,-81,-215,-214,-80,-216,-78,-127,3,-153,3,-151,-148,-157,-168,-69,-36,-35,3,3,3,-234,-233,3,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,3,3,-229,-232,-221,-83,-219,-68,-33,-32,3,3,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LSHIFT':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,244,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,244,-262,-260,244,244,244,-259,244,244,-257,-256,244,244,244,244,244,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'LOR':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,243,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'CHAR_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,167,-335,-28,-182,-27,167,-337,-87,-72,-337,167,-286,-285,167,167,-283,-287,-288,167,-284,167,167,167,-336,-183,167,167,-28,-337,167,-28,-337,-337,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,-337,-76,-79,-82,-75,167,-77,167,167,-81,-215,-214,-80,-216,167,-78,167,167,-69,-284,167,167,-284,167,167,-244,-247,-245,-241,-242,-246,-248,167,-250,-251,-243,-249,-12,167,167,-11,167,167,167,167,-234,-233,167,-231,167,167,-217,167,-230,167,-84,-218,167,167,167,-337,-337,-198,167,167,167,-337,-284,-229,-232,167,-221,167,-83,-219,-68,167,-28,-337,167,-11,167,167,-220,167,167,167,-284,167,167,167,-337,167,-225,-224,-222,-84,167,167,167,-226,-223,167,-228,-227,]),'U16STRING_LITERAL':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,139,146,148,149,150,151,153,163,165,166,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,166,-335,-28,-182,-27,166,-337,-87,-72,-337,166,-286,-285,-330,166,-327,166,-283,-287,238,-328,-288,-329,166,-284,166,166,166,-336,-183,166,166,-28,-337,166,-28,-337,-337,166,166,166,-334,-332,-331,-333,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,-337,-76,-79,-82,-75,166,-77,166,166,-81,-215,-214,-80,-216,166,-78,166,166,-69,-284,166,166,-284,166,166,-244,-247,-245,-241,-242,-246,-248,166,-250,-251,-243,-249,-12,166,166,-11,166,166,166,166,-234,-233,166,-231,166,166,-217,166,-230,166,-84,-218,166,166,166,-337,-337,-198,166,166,166,-337,-284,-229,-232,166,-221,166,-83,-219,-68,166,-28,-337,166,-11,166,166,-220,166,166,166,-284,166,166,166,-337,166,-225,-224,-222,-84,166,166,166,-226,-223,166,-228,-227,]),'RBRACE':([61,97,99,119,124,132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,178,181,184,185,186,188,189,190,191,195,196,197,224,225,227,228,230,232,234,235,236,237,238,261,263,268,273,284,285,286,289,291,298,300,301,302,303,305,306,308,309,313,315,318,325,326,327,332,370,374,377,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,424,425,428,432,435,437,438,439,446,450,451,468,469,472,473,476,478,480,482,483,487,496,497,500,505,506,510,523,524,528,536,546,547,550,551,554,555,557,558,565,575,576,578,579,],[-71,-335,191,-87,-72,-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-252,-337,191,191,191,-159,-160,-156,-336,-171,191,-176,-274,-239,-337,-193,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-76,-79,-82,-75,-77,-6,-81,-215,-214,-80,-216,-5,-78,191,191,191,-157,191,191,-172,-69,191,-22,-21,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,-234,-233,-231,-217,-230,-81,-84,-218,-158,-173,-177,-240,-194,191,-196,-237,-281,-282,-290,-291,-275,-229,-232,-221,-83,-219,-68,-195,-254,191,-220,-197,-306,191,-299,-225,-224,-222,-84,-300,-226,-223,-228,-227,]),'_BOOL':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[34,-337,-113,-128,34,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,34,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,34,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,34,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,34,-131,-95,-101,-97,34,-53,-126,34,-88,34,34,-93,34,-147,-335,-146,34,-167,-166,-182,-100,-126,34,-87,-90,-94,-92,-61,-72,34,-144,-142,34,34,34,-73,34,-89,34,34,34,-149,-159,-160,-156,-336,34,-183,-30,34,34,-74,34,34,34,34,-174,-175,34,-143,-140,34,-141,-145,-76,-79,-82,-75,-77,34,-81,-215,-214,-80,-216,-78,-127,34,-153,34,-151,-148,-157,-168,-69,-36,-35,34,34,34,-234,-233,34,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,34,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LE':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,246,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,246,-262,-260,-264,246,-263,-259,-266,246,-257,-256,-265,246,246,246,246,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'SEMI':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,70,71,73,74,75,76,77,78,79,80,81,82,83,84,86,87,89,91,94,96,97,98,99,100,101,108,109,110,111,113,114,115,119,120,121,122,123,124,127,132,133,134,136,138,139,140,141,142,143,144,145,147,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,178,179,180,181,184,185,186,187,188,189,190,191,192,200,216,217,223,224,225,226,228,230,232,234,235,236,237,238,240,241,261,263,268,269,272,273,275,279,280,284,285,286,288,289,290,291,293,294,298,300,301,302,303,304,305,306,307,308,310,312,313,314,315,316,317,318,320,321,322,323,324,328,330,331,332,340,341,355,356,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,423,424,425,426,427,428,429,432,433,435,437,438,439,440,442,443,444,446,448,449,453,454,464,465,468,469,476,478,480,482,483,486,487,496,497,498,499,500,502,505,506,508,509,510,511,512,518,519,523,524,533,534,535,536,537,539,547,551,552,554,555,557,558,565,568,569,574,575,576,577,578,579,],[19,-337,-113,-128,-337,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,-337,-29,-121,-116,-62,-112,-70,-52,-123,-117,119,-337,-337,-119,-337,-114,-130,19,-118,-71,-103,-337,-9,-131,-91,-10,-96,-20,-98,-54,-179,-178,-131,-37,-134,-85,-95,-101,-97,-19,-132,-53,-126,-337,-337,-93,-147,-335,-146,188,-167,-166,-136,-100,-138,-126,-16,-86,-15,-87,-90,-94,-92,-61,-72,-55,-317,-321,-318,-303,-324,-330,-313,-319,-144,-301,-274,-314,-142,-327,-325,-304,-322,-302,-255,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-252,-178,-73,-337,188,188,188,-149,-159,-160,-156,-336,-337,-30,-38,-133,-74,-274,-239,-135,-193,-326,-280,-277,-334,-332,-331,-333,-174,-175,-298,-297,-279,-143,-235,-278,-140,-141,-145,-76,-79,-82,424,-75,425,-77,428,-14,-337,-81,-215,-214,-80,435,-216,-13,-337,-78,-312,-127,188,-153,188,-151,-148,-157,-26,-25,446,-161,-163,-168,-139,-137,-69,-36,-35,-44,-43,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,-292,-305,496,-234,-233,497,-337,-231,-337,-217,-13,-230,-81,-84,-218,-337,-152,-150,-165,-158,-170,-169,-31,-34,-39,-42,-240,-194,-237,-281,-282,-290,-291,-236,-275,-229,-232,533,-337,-221,-337,-83,-219,-162,-164,-68,-33,-32,-41,-40,-195,-254,-337,553,-337,-220,-337,-337,-306,-299,566,-225,-224,-222,-84,-300,575,-337,-337,-226,-223,-337,-228,-227,]),'_THREAD_LOCAL':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[11,11,-113,-128,11,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,11,-120,-115,-65,-102,11,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,11,11,-119,11,-114,-130,11,-118,-71,-103,11,-131,-96,-98,11,-131,-95,-101,-97,-53,11,11,-88,11,-147,-335,-146,-167,-166,-100,-126,11,-87,-61,-72,11,-73,11,-89,-149,-336,-30,11,-74,-174,-175,11,-76,-79,-82,-75,-77,11,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,11,11,11,-234,-233,11,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,11,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'LT':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,248,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,248,-262,-260,-264,248,-263,-259,-266,248,-257,-256,-265,248,248,248,248,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'COMMA':([2,3,5,6,7,10,11,12,13,18,20,22,23,26,27,30,33,34,35,36,39,42,43,44,46,48,49,50,54,56,58,60,62,68,70,71,73,74,75,76,77,78,80,81,82,84,86,96,98,100,101,103,104,105,106,108,109,110,111,113,127,132,133,134,136,138,139,140,141,142,143,144,145,147,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,177,178,179,187,191,195,196,197,198,199,200,203,210,211,212,213,215,216,217,224,225,226,228,230,232,234,235,236,237,238,240,241,261,263,268,269,270,272,273,274,275,276,277,279,280,281,283,294,310,312,314,316,317,320,323,324,325,326,327,328,330,331,340,341,343,344,345,346,347,348,355,356,374,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,414,426,442,443,444,448,449,450,451,453,454,458,461,463,464,465,468,469,473,476,478,480,482,483,486,487,489,490,492,501,503,507,508,509,511,512,518,519,523,524,525,528,529,530,531,532,544,545,546,547,551,556,559,560,564,565,570,571,],[-113,-128,-124,-110,-106,-104,-107,-125,-105,-99,-109,-120,-115,-102,-126,-108,-238,-111,-337,-122,-129,-29,-121,-116,-112,-52,-123,-117,-119,-114,-130,-118,-103,-96,126,-98,-54,-179,-178,-131,-37,-134,-95,-101,-97,-132,-53,-147,-146,-167,-166,-28,-180,-182,-27,-136,-100,-138,-126,202,-55,-317,-321,-318,-303,-324,-330,-313,-319,-144,-301,-274,-314,-142,-327,-325,-304,-322,-302,-255,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-337,-252,-178,-149,-336,-171,327,-176,-183,-181,-30,333,-186,-337,349,350,-191,-38,-133,-274,-239,-135,-193,-326,-280,-277,-334,-332,-331,-333,-174,-175,-298,-297,-279,-143,412,-235,-278,-203,-140,-204,-1,-141,-145,-2,-206,412,-312,-127,-153,-151,-148,445,-161,-163,327,327,-172,-168,-139,-137,-36,-35,-190,-204,-56,-188,-45,-189,-44,-43,472,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,412,-270,-258,-296,-295,-294,-293,412,-292,-310,484,485,-305,-205,412,-152,-150,-165,-170,-169,-173,-177,-31,-34,-57,-192,-187,-39,-42,-240,-194,-196,-237,-281,-282,-290,-291,-236,-275,-213,-207,-211,412,412,412,-162,-164,-33,-32,-41,-40,-195,-254,-311,550,-209,-208,-210,-212,-51,-50,-197,-306,-299,412,-46,-49,412,-300,-48,-47,]),'U16CHAR_CONST':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,169,-335,-28,-182,-27,169,-337,-87,-72,-337,169,-286,-285,169,169,-283,-287,-288,169,-284,169,169,169,-336,-183,169,169,-28,-337,169,-28,-337,-337,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,-337,-76,-79,-82,-75,169,-77,169,169,-81,-215,-214,-80,-216,169,-78,169,169,-69,-284,169,169,-284,169,169,-244,-247,-245,-241,-242,-246,-248,169,-250,-251,-243,-249,-12,169,169,-11,169,169,169,169,-234,-233,169,-231,169,169,-217,169,-230,169,-84,-218,169,169,169,-337,-337,-198,169,169,169,-337,-284,-229,-232,169,-221,169,-83,-219,-68,169,-28,-337,169,-11,169,169,-220,169,169,169,-284,169,169,169,-337,169,-225,-224,-222,-84,169,169,169,-226,-223,169,-228,-227,]),'OFFSETOF':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,137,146,149,150,151,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,170,-335,-28,-182,-27,170,-337,-87,-72,-337,170,-286,-285,170,170,-283,-287,-288,170,-284,170,170,170,-336,-183,170,170,-28,-337,170,-28,-337,-337,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,-337,-76,-79,-82,-75,170,-77,170,170,-81,-215,-214,-80,-216,170,-78,170,170,-69,-284,170,170,-284,170,170,-244,-247,-245,-241,-242,-246,-248,170,-250,-251,-243,-249,-12,170,170,-11,170,170,170,170,-234,-233,170,-231,170,170,-217,170,-230,170,-84,-218,170,170,170,-337,-337,-198,170,170,170,-337,-284,-229,-232,170,-221,170,-83,-219,-68,170,-28,-337,170,-11,170,170,-220,170,170,170,-284,170,170,170,-337,170,-225,-224,-222,-84,170,170,170,-226,-223,170,-228,-227,]),'_ATOMIC':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,35,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,103,105,109,111,117,118,119,120,121,122,123,124,128,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,205,206,211,214,219,220,223,229,231,233,239,240,241,267,269,275,278,279,280,282,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,459,460,496,497,500,505,506,510,511,512,514,515,536,554,555,557,558,575,576,578,579,],[29,65,-113,-128,76,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,65,-120,-115,-65,-102,65,-131,-108,-238,-111,76,-122,-63,-129,112,-29,-121,-116,-62,-112,-70,-52,-123,-117,65,65,-119,65,-114,-130,29,-118,-71,-103,65,-9,-131,-91,-10,-96,-98,65,-131,-95,-101,-97,29,-53,65,76,-88,112,65,-93,29,-147,-335,-146,29,-167,-166,76,-182,-100,-126,76,29,-87,-90,-94,-92,-61,-72,76,29,-144,-142,65,29,76,-73,65,-89,29,29,29,-149,-159,-160,-156,-336,76,-183,-30,76,76,76,112,76,76,-74,29,29,29,29,-174,-175,29,-143,-140,29,-141,-145,76,-76,-79,-82,-75,-77,65,-81,-215,-214,-80,-216,-78,-127,29,-153,29,-151,-148,-157,-168,-69,-36,-35,29,29,29,-234,-233,65,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,76,29,-229,-232,-221,-83,-219,-68,-33,-32,76,76,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'TYPEDEF':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[7,7,-113,-128,7,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,7,-120,-115,-65,-102,7,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,7,7,-119,7,-114,-130,7,-118,-71,-103,7,-131,-96,-98,7,-131,-95,-101,-97,-53,7,7,-88,7,-147,-335,-146,-167,-166,-100,-126,7,-87,-61,-72,7,-73,7,-89,-149,-336,-30,7,-74,-174,-175,7,-76,-79,-82,-75,-77,7,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,7,7,7,-234,-233,7,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,7,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'XOR':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,251,-328,-316,-329,-320,-276,-323,-312,-336,-274,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-261,251,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,251,-267,-269,251,-258,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'AUTO':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,65,68,71,75,76,80,81,82,86,87,89,90,93,96,97,98,100,101,109,111,118,119,123,124,129,180,181,182,187,191,200,211,223,240,241,278,284,285,286,289,291,298,300,301,302,303,305,308,312,314,316,317,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[26,26,-113,-128,26,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,26,-120,-115,-65,-102,26,-131,-108,-238,-111,-122,-63,-129,-29,-121,-116,-62,-112,-70,-52,-123,-117,26,26,-119,26,-114,-130,26,-118,-71,-103,26,-131,-96,-98,26,-131,-95,-101,-97,-53,26,26,-88,26,-147,-335,-146,-167,-166,-100,-126,26,-87,-61,-72,26,-73,26,-89,-149,-336,-30,26,-74,-174,-175,26,-76,-79,-82,-75,-77,26,-81,-215,-214,-80,-216,-78,-127,-153,-151,-148,-168,-69,-36,-35,26,26,26,-234,-233,26,-231,-217,-230,-81,-84,-218,-152,-150,-170,-169,-31,-34,26,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'DIVEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,357,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'TIMES':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,22,23,25,26,27,29,30,33,34,35,36,37,38,39,40,43,44,45,46,47,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,71,76,80,81,82,85,87,89,91,94,96,97,98,100,101,103,104,105,106,109,111,116,117,119,120,121,122,123,124,126,128,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,156,158,160,161,162,163,164,165,166,167,168,169,171,173,174,175,176,177,180,181,187,191,192,198,201,202,204,205,206,211,218,219,220,223,224,227,229,230,231,232,233,234,235,236,237,238,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,268,269,273,275,278,279,280,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,312,314,316,317,319,328,329,332,336,338,339,342,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,442,443,445,447,448,449,459,472,475,477,478,480,481,482,483,484,487,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[35,-337,-113,-128,35,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,-120,-115,-65,-102,-126,-131,-108,-238,-111,-337,-122,35,-63,-129,35,-121,-116,-62,-112,-70,-123,-117,-337,-337,-119,-337,-114,-130,35,-118,-71,-103,-337,-9,-131,-91,-10,-96,35,-98,-131,-95,-101,-97,173,-126,35,35,-93,-147,-335,-146,-167,-166,-28,35,-182,-27,-100,-126,173,-337,-87,-90,-94,-92,-61,-72,35,-337,173,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-144,-301,-274,-314,173,-142,-327,173,-283,-287,-325,-304,-322,-302,-255,-315,-289,253,-328,-316,-288,-329,-320,-276,-323,173,-284,173,173,-312,35,-73,173,-149,-336,35,-183,173,35,336,-28,-337,35,352,-28,-337,-74,-274,-337,173,-326,173,-280,173,-277,-334,-332,-331,-333,-174,-175,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,-298,-297,173,173,-279,-143,-278,-140,35,-141,-145,420,-76,-79,-82,-75,173,-77,173,173,-81,-215,-214,-80,-216,173,-78,-312,-127,-153,-151,-148,173,-168,173,-69,-284,173,173,35,-284,173,173,-244,-247,-245,-241,-242,-246,-248,173,-250,-251,-243,-249,-12,173,173,-11,253,253,253,253,253,253,253,253,253,253,-257,-256,253,253,253,253,253,-258,-296,-295,-294,-293,-292,-305,173,173,173,494,-234,-233,173,-231,173,173,-217,173,-230,173,-84,-218,173,173,-152,-150,35,173,-170,-169,-337,-337,-198,173,-281,-282,173,-290,-291,173,-275,-337,-284,-229,-232,173,-221,173,-83,-219,-68,541,-28,-337,173,-11,173,173,-220,173,173,173,-284,173,173,-306,173,-337,-299,173,-225,-224,-222,-84,-300,173,173,173,-226,-223,173,-228,-227,]),'LPAREN':([0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20,22,23,25,26,27,29,30,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,71,72,73,76,77,80,81,82,85,86,87,89,91,94,96,97,98,100,101,103,104,105,106,109,111,112,116,117,119,120,121,122,123,124,126,127,128,131,132,133,134,135,136,137,138,139,140,141,142,143,145,146,147,148,149,150,151,152,153,154,155,156,160,161,163,164,165,166,167,168,169,170,171,173,174,175,176,177,180,181,187,191,192,198,199,200,201,202,204,205,206,211,216,218,219,220,223,227,229,230,231,233,235,236,237,238,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,269,275,276,278,279,280,282,283,284,285,286,289,290,291,292,296,297,298,299,300,301,302,303,305,307,308,310,311,312,314,316,317,319,328,329,332,336,338,339,340,341,342,344,345,347,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,402,403,404,405,407,411,412,413,414,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,442,443,445,447,448,449,453,454,457,458,459,464,465,472,475,477,481,482,483,484,488,489,490,492,494,496,497,499,500,502,504,505,506,510,511,512,513,514,515,518,519,521,522,529,530,531,532,533,535,536,537,538,539,541,542,543,544,545,547,549,550,551,553,554,555,557,558,559,560,565,566,569,570,571,574,575,576,577,578,579,],[37,-337,-113,-128,69,-124,-110,-106,85,-104,-107,-125,-105,-64,37,-60,-67,-99,-66,-109,-120,-115,-65,-102,-126,95,-108,-238,-111,-337,-122,37,-63,-129,37,116,-29,-121,-116,-62,-112,-70,118,-123,-117,-337,-337,-119,-337,-114,-130,37,-118,-71,-103,-337,-9,95,-91,-10,-96,69,-98,69,129,-131,-37,-95,-101,-97,174,118,-126,69,37,-93,-147,-335,-146,-167,-166,-28,-180,-182,-27,-100,-126,95,174,-337,-87,-90,-94,-92,-61,-72,69,129,-337,229,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-144,-301,-314,231,-142,-327,233,-283,-287,-325,-304,-322,239,-302,-315,-289,-328,-316,-288,-329,-320,266,-323,267,174,-284,229,233,-312,278,-73,229,-149,-336,69,-183,-181,-30,229,69,229,-28,-337,342,-38,229,-28,-337,-74,-337,229,-326,229,229,-334,-332,-331,-333,-174,-175,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,229,174,174,-298,-297,229,229,-143,-140,278,278,-141,-145,-337,422,-76,-79,-82,-75,229,-77,427,430,174,229,434,-81,-215,-214,-80,-216,229,-78,-312,441,-127,-153,-151,-148,174,-168,174,-69,-284,229,229,-36,-35,342,342,460,-45,-284,229,229,-44,-43,-244,-247,-245,-241,-242,-246,-248,229,-250,-251,-243,-249,-12,174,229,-11,-296,-295,-294,-293,-292,-305,229,174,422,229,229,-234,-233,229,-231,229,229,-217,229,-230,229,-84,-218,229,229,-152,-150,69,174,-170,-169,-31,-34,342,460,-337,-39,-42,-337,-198,174,174,-290,-291,229,-337,-213,-207,-211,-284,-229,-232,229,-221,229,538,-83,-219,-68,-33,-32,229,-28,-337,-41,-40,229,-11,-209,-208,-210,-212,229,229,-220,229,229,229,-284,229,229,-51,-50,-306,229,-337,-299,229,-225,-224,-222,-84,-46,-49,-300,229,229,-48,-47,229,-226,-223,229,-228,-227,]),'MINUSMINUS':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,132,133,134,135,136,137,138,139,140,141,143,145,146,148,149,150,151,152,153,154,156,160,161,163,164,165,166,167,168,169,171,173,174,175,176,181,191,198,201,204,205,206,218,219,220,227,229,230,231,233,235,236,237,238,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,263,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,310,319,329,332,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,402,403,404,405,407,411,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,459,472,475,477,481,482,483,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,547,549,550,551,553,554,555,557,558,565,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,175,-335,-28,-182,-27,175,-337,-87,-72,-337,175,-317,-321,-318,-286,-303,-285,-324,-330,-313,-319,-301,-314,175,-327,175,-283,-287,-325,-304,-322,-302,-315,-289,-328,-316,-288,-329,-320,261,-323,175,-284,175,175,-312,175,-336,-183,175,175,-28,-337,175,-28,-337,-337,175,-326,175,175,-334,-332,-331,-333,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,-298,-297,175,175,-337,-76,-79,-82,-75,175,-77,175,175,-81,-215,-214,-80,-216,175,-78,-312,175,175,-69,-284,175,175,-284,175,175,-244,-247,-245,-241,-242,-246,-248,175,-250,-251,-243,-249,-12,175,175,-11,-296,-295,-294,-293,-292,-305,175,175,175,175,-234,-233,175,-231,175,175,-217,175,-230,175,-84,-218,175,175,175,-337,-337,-198,175,175,-290,-291,175,-337,-284,-229,-232,175,-221,175,-83,-219,-68,175,-28,-337,175,-11,175,175,-220,175,175,175,-284,175,175,-306,175,-337,-299,175,-225,-224,-222,-84,-300,175,175,175,-226,-223,175,-228,-227,]),'ID':([0,1,2,3,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,43,44,45,46,47,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,71,72,76,80,81,82,85,87,89,91,94,96,97,98,100,101,102,103,104,105,106,109,111,116,117,118,119,120,121,122,123,124,126,128,129,131,135,137,142,146,147,149,150,151,165,171,173,174,175,180,181,187,191,192,193,194,198,199,201,202,204,205,206,211,218,219,220,223,227,229,231,233,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,262,264,265,266,269,275,279,280,282,284,285,286,287,289,290,291,297,298,300,301,302,303,305,307,308,312,314,316,317,319,327,328,329,332,336,338,339,342,344,349,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,372,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,442,443,445,447,448,449,457,459,460,472,475,477,481,484,485,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,548,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[42,-337,-113,-128,42,-124,-110,-106,-104,-107,-125,-105,-64,42,-60,-67,-99,-66,-109,-120,-115,-154,-65,-102,-126,-155,-131,-108,98,101,-238,-111,-337,-122,42,-63,-129,42,-121,-116,-62,-112,-70,-123,-117,-337,-337,-119,-337,-114,-130,42,-118,-71,-103,-337,-9,-131,-91,-10,-96,42,-98,42,-131,-95,-101,-97,176,-126,42,42,-93,-147,-335,-146,-167,-166,197,-28,-180,-182,-27,-100,-126,176,-337,176,-87,-90,-94,-92,-61,-72,42,-337,176,176,-286,-285,-144,176,-142,176,-283,-287,-288,176,-284,176,176,-73,310,-149,-336,42,197,197,-183,-181,176,42,176,-28,-337,42,176,-28,-337,-74,-337,176,176,176,-174,-175,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,403,405,176,176,-143,-140,-141,-145,-337,-76,-79,-82,423,-75,176,-77,176,310,-81,-215,-214,-80,-216,310,-78,-127,-153,-151,-148,176,197,-168,176,-69,-284,176,176,42,42,176,-284,176,176,-244,-247,-245,-241,-242,-246,-248,176,-250,-251,-243,-249,-12,176,176,176,-11,176,176,176,176,-234,-233,176,-231,310,176,-217,176,-230,310,-84,-218,310,176,-152,-150,42,176,-170,-169,42,-337,176,-337,-198,176,176,176,176,-337,-284,-229,-232,176,-221,310,-83,-219,-68,176,-28,-337,176,-11,176,310,-220,310,176,310,-284,176,176,176,176,-337,176,-225,-224,-222,-84,176,310,310,-226,-223,310,-228,-227,]),'IF':([61,97,119,124,181,191,284,285,286,289,291,298,300,301,302,303,305,307,308,332,424,425,428,429,432,435,437,438,439,440,496,497,500,502,505,506,510,535,536,537,539,554,555,557,558,569,574,575,576,577,578,579,],[-71,-335,-87,-72,311,-336,-76,-79,-82,-75,-77,311,-81,-215,-214,-80,-216,311,-78,-69,-234,-233,-231,311,-217,-230,311,-84,-218,311,-229,-232,-221,311,-83,-219,-68,311,-220,311,311,-225,-224,-222,-84,311,311,-226,-223,311,-228,-227,]),'STRING_LITERAL':([3,39,58,61,76,85,97,103,105,106,116,117,119,124,128,131,135,136,137,146,149,150,151,152,165,171,173,174,175,181,191,198,201,204,205,206,218,219,220,227,229,230,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,282,284,285,286,289,290,291,297,298,300,301,302,303,305,307,308,319,329,332,333,336,338,339,352,353,354,357,358,359,360,361,362,363,364,365,366,367,368,369,373,375,377,412,413,419,421,424,425,427,428,429,430,432,434,435,437,438,439,440,441,447,452,459,472,475,477,481,484,488,494,496,497,499,500,502,505,506,510,513,514,515,521,522,533,535,536,537,538,539,541,542,543,549,550,553,554,555,557,558,566,569,574,575,576,577,578,579,],[-128,-129,-130,-71,-131,152,-335,-28,-182,-27,152,-337,-87,-72,-337,152,-286,230,-285,152,152,-283,-287,-325,-288,152,-284,152,152,152,-336,-183,152,152,-28,-337,152,-28,-337,-337,152,-326,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,-337,-76,-79,-82,-75,152,-77,152,152,-81,-215,-214,-80,-216,152,-78,152,152,-69,152,-284,152,152,-284,152,152,-244,-247,-245,-241,-242,-246,-248,152,-250,-251,-243,-249,-12,152,152,-11,152,152,152,152,-234,-233,152,-231,152,152,-217,152,-230,152,-84,-218,152,152,152,230,-337,-337,-198,152,152,152,-337,-284,-229,-232,152,-221,152,-83,-219,-68,152,-28,-337,152,-11,152,152,-220,152,152,152,-284,152,152,152,-337,152,-225,-224,-222,-84,152,152,152,-226,-223,152,-228,-227,]),'FLOAT':([0,1,2,3,4,5,6,7,10,11,12,13,14,16,17,18,19,20,21,22,23,25,26,27,29,30,33,34,36,38,39,40,42,43,44,45,46,47,48,49,50,52,53,54,55,56,58,59,60,61,62,63,64,65,66,67,68,71,75,76,80,81,82,85,86,87,89,90,91,93,94,95,96,97,98,99,100,101,105,109,111,118,119,120,121,122,123,124,129,142,147,172,174,177,180,181,182,184,185,186,187,188,189,190,191,192,198,200,211,214,223,229,231,233,239,240,241,267,269,275,278,279,280,284,285,286,289,291,298,300,301,302,303,305,308,312,313,314,315,316,317,318,328,332,340,341,342,350,422,424,425,427,428,432,435,437,438,439,442,443,446,448,449,453,454,460,496,497,500,505,506,510,511,512,536,554,555,557,558,575,576,578,579,],[44,-337,-113,-128,44,-124,-110,-106,-104,-107,-125,-105,-64,-60,-67,-99,-66,-109,44,-120,-115,-65,-102,-126,-131,-108,-238,-111,-122,-63,-129,44,-29,-121,-116,-62,-112,-70,-52,-123,-117,-337,-337,-119,-337,-114,-130,44,-118,-71,-103,-337,-9,-131,-91,-10,-96,-98,44,-131,-95,-101,-97,44,-53,-126,44,-88,44,44,-93,44,-147,-335,-146,44,-167,-166,-182,-100,-126,44,-87,-90,-94,-92,-61,-72,44,-144,-142,44,44,44,-73,44,-89,44,44,44,-149,-159,-160,-156,-336,44,-183,-30,44,44,-74,44,44,44,44,-174,-175,44,-143,-140,44,-141,-145,-76,-79,-82,-75,-77,44,-81,-215,-214,-80,-216,-78,-127,44,-153,44,-151,-148,-157,-168,-69,-36,-35,44,44,44,-234,-233,44,-231,-217,-230,-81,-84,-218,-152,-150,-158,-170,-169,-31,-34,44,-229,-232,-221,-83,-219,-68,-33,-32,-220,-225,-224,-222,-84,-226,-223,-228,-227,]),'XOREQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,361,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'LSHIFTEQUAL':([132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,160,161,163,164,166,167,168,169,176,191,224,230,232,234,235,236,237,238,261,263,268,273,310,402,403,404,405,407,411,478,480,482,483,487,547,551,565,],[-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-315,-289,-328,-316,-329,-320,-276,-323,-312,-336,363,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-278,-312,-296,-295,-294,-293,-292,-305,-281,-282,-290,-291,-275,-306,-299,-300,]),'RBRACKET':([3,39,58,76,103,105,106,117,128,132,133,134,136,138,139,140,141,143,144,145,148,152,153,154,156,158,160,161,162,163,164,166,167,168,169,176,178,191,198,204,205,218,219,224,225,230,232,234,235,236,237,238,261,263,268,272,273,282,334,335,336,337,351,352,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,400,401,402,403,404,405,406,407,411,419,420,421,455,456,459,466,467,468,471,476,478,480,482,483,486,487,491,493,494,513,514,524,540,541,547,551,561,562,564,565,],[-128,-129,-130,-131,-28,-182,-27,-337,-337,-317,-321,-318,-303,-324,-330,-313,-319,-301,-274,-314,-327,-325,-304,-322,-302,-255,-315,-289,-253,-328,-316,-329,-320,-276,-323,-312,-252,-336,-183,-337,-28,-337,-28,-274,-239,-326,-280,-277,-334,-332,-331,-333,-298,-297,-279,-235,-278,-337,453,-4,454,-3,464,465,-261,-273,-262,-260,-264,-268,-263,-259,-266,-271,-257,-256,-265,-272,-267,-269,-270,-258,-296,-295,-294,-293,482,-292,-305,-337,492,-337,511,512,-337,518,519,-240,520,-237,-281,-282,-290,-291,-236,-275,529,530,531,-337,-28,-254,559,560,-306,-299,570,571,572,-300,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'expression_statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[284,284,284,284,284,284,284,284,284,284,284,284,284,]),'struct_or_union_specifier':([0,21,40,59,75,85,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'init_declarator_list':([4,89,],[70,70,]),'init_declarator_list_opt':([4,89,],[79,79,]),'iteration_statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[285,285,285,285,285,285,285,285,285,285,285,285,285,]),'static_assert':([0,59,181,298,307,429,437,440,502,535,537,539,569,574,577,],[17,17,286,286,286,286,286,286,286,286,286,286,286,286,286,]),'unified_string_literal':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,333,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,452,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,]),'assignment_expression_opt':([204,218,419,421,513,],[334,351,491,493,540,]),'brace_open':([31,32,92,96,98,100,101,130,131,181,201,229,298,307,375,413,429,437,440,477,478,479,502,521,535,537,539,569,574,577,],[99,102,181,184,185,193,194,181,227,181,227,181,181,181,227,488,181,181,181,488,488,488,181,227,181,181,181,181,181,181,]),'enumerator':([102,193,194,327,],[195,195,195,450,]),'typeid_noparen_declarator':([211,],[348,]),'type_qualifier_list_opt':([35,117,128,206,220,282,459,515,],[104,204,218,339,354,419,513,543,]),'declaration_specifiers_no_type_opt':([1,27,52,53,55,63,87,],[66,94,120,121,122,94,94,]),'expression_opt':([181,298,307,427,429,437,440,499,502,533,535,537,539,553,566,569,574,577,],[288,288,288,498,288,288,288,534,288,552,288,288,288,567,573,288,288,288,]),'designation':([227,472,488,550,],[369,369,369,369,]),'parameter_list':([118,129,278,342,422,460,],[213,213,213,213,213,213,]),'alignment_specifier':([0,1,4,21,27,52,53,55,59,63,75,85,87,89,93,95,99,118,129,174,177,181,184,185,186,192,211,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[53,53,81,53,53,53,53,53,53,53,53,142,53,81,53,142,142,53,53,142,280,53,142,142,142,280,81,142,142,142,142,142,53,53,142,142,53,53,53,53,53,]),'labeled_statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[289,289,289,289,289,289,289,289,289,289,289,289,289,]),'abstract_declarator':([177,211,278,342,],[281,281,418,418,]),'translation_unit':([0,],[59,]),'init_declarator':([4,89,126,202,],[84,84,217,331,]),'direct_abstract_declarator':([177,211,276,278,342,344,457,],[283,283,414,283,283,414,414,]),'designator_list':([227,472,488,550,],[376,376,376,376,]),'identifier':([85,116,118,129,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,349,353,354,364,372,373,375,412,413,419,421,427,429,430,434,437,440,441,447,460,477,481,484,485,499,502,513,521,533,535,537,538,539,542,543,548,549,553,566,569,574,577,],[143,143,215,215,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,461,143,143,143,470,143,143,143,143,143,143,143,143,143,143,143,143,143,143,215,143,143,143,527,143,143,143,143,143,143,143,143,143,143,143,563,143,143,143,143,143,143,]),'offsetof_member_designator':([485,],[526,]),'unary_expression':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[144,144,224,232,234,144,224,273,224,224,224,224,224,224,224,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,224,144,144,224,224,224,144,224,224,144,144,224,224,224,224,224,144,224,224,144,224,224,224,224,224,224,224,224,224,144,144,144,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,]),'abstract_declarator_opt':([177,211,],[274,343,]),'initializer':([131,201,375,521,],[226,330,473,546,]),'direct_id_declarator':([0,4,15,37,40,59,69,72,89,91,126,192,202,211,342,344,445,457,],[48,48,86,48,48,48,48,86,48,48,48,48,48,48,48,86,48,86,]),'struct_declaration_list':([99,184,185,],[186,313,315,]),'pp_directive':([0,59,],[14,14,]),'declaration_list':([21,75,],[93,93,]),'id_init_declarator':([40,91,],[108,108,]),'type_specifier':([0,21,40,59,75,85,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[18,18,109,18,18,147,109,18,147,147,18,18,269,147,18,147,147,147,109,147,147,147,147,147,18,18,147,147,18,18,18,18,18,]),'compound_statement':([92,130,181,229,298,307,429,437,440,502,535,537,539,569,574,577,],[180,223,291,378,291,291,291,291,291,291,291,291,291,291,291,291,]),'pointer':([0,4,37,40,59,69,89,91,104,126,177,192,202,211,278,342,445,],[15,72,15,15,15,72,72,15,199,72,276,72,72,344,276,457,72,]),'typeid_declarator':([4,69,89,126,192,202,445,],[74,125,74,74,74,74,74,]),'id_init_declarator_list':([40,91,],[113,113,]),'declarator':([4,89,126,192,202,445,],[78,78,78,324,78,324,]),'argument_expression_list':([266,],[409,]),'struct_declarator_list_opt':([192,],[322,]),'block_item_list':([181,],[298,]),'parameter_type_list_opt':([278,342,422,],[417,417,495,]),'struct_declarator':([192,445,],[323,508,]),'type_qualifier':([0,1,4,21,27,35,52,53,55,59,63,75,85,87,89,93,95,99,103,117,118,128,129,172,174,177,181,184,185,186,192,205,206,211,219,220,229,231,233,239,267,278,282,298,313,315,342,350,422,427,459,460,514,515,],[52,52,80,52,52,105,52,52,52,52,52,52,105,52,80,52,105,105,198,105,52,105,52,198,105,279,52,105,105,105,279,198,105,80,198,105,105,105,105,105,105,52,105,52,105,105,52,52,52,52,105,52,198,105,]),'assignment_operator':([224,],[364,]),'expression':([174,181,229,231,233,258,265,290,298,307,427,429,430,434,437,440,441,499,502,533,535,537,538,539,549,553,566,569,574,577,],[270,294,270,270,270,399,406,426,294,294,294,294,501,503,294,294,507,294,294,294,294,294,556,294,564,294,294,294,294,294,]),'storage_class_specifier':([0,1,4,21,27,52,53,55,59,63,75,87,89,93,118,129,181,211,278,298,342,350,422,427,460,],[1,1,68,1,1,1,1,1,1,1,1,1,68,1,1,1,1,68,1,1,1,1,1,1,1,]),'unified_wstring_literal':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,]),'translation_unit_or_empty':([0,],[9,]),'initializer_list_opt':([227,],[370,]),'brace_close':([99,184,185,186,196,309,313,315,325,326,370,472,528,550,],[187,314,316,317,328,439,442,443,448,449,469,523,551,565,]),'direct_typeid_declarator':([4,69,72,89,126,192,202,445,],[73,73,127,73,73,73,73,73,]),'external_declaration':([0,59,],[16,123,]),'pragmacomp_or_statement':([307,429,440,502,535,537,539,569,574,577,],[436,500,506,536,554,555,557,576,578,579,]),'type_name':([85,95,174,229,231,233,239,267,],[157,183,271,379,380,381,382,410,]),'typedef_name':([0,21,40,59,75,85,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,]),'pppragma_directive':([0,59,99,181,184,185,186,298,307,313,315,429,437,440,502,535,537,539,569,574,577,],[25,25,189,300,189,189,189,300,437,189,189,437,300,437,437,437,437,437,437,437,437,]),'statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[301,301,438,438,505,438,438,438,438,558,438,438,438,]),'cast_expression':([85,116,131,171,174,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[158,158,158,268,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,487,158,158,158,158,158,158,158,158,158,158,487,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,]),'atomic_specifier':([0,1,21,27,40,52,53,55,59,63,75,85,87,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[27,63,87,63,111,63,63,63,27,63,87,111,63,111,87,111,111,27,27,111,111,87,111,111,111,111,111,111,111,111,111,27,87,111,111,27,27,27,87,27,]),'struct_declarator_list':([192,],[320,]),'empty':([0,1,4,21,27,35,40,52,53,55,63,75,87,89,91,117,118,128,129,177,181,192,204,206,211,218,220,227,278,282,298,307,342,419,421,422,427,429,437,440,459,460,472,488,499,502,513,515,533,535,537,539,550,553,566,569,574,577,],[57,64,83,88,64,106,115,64,64,64,64,88,64,83,115,106,208,106,208,277,306,321,337,106,277,337,106,377,415,106,433,433,415,337,337,415,433,433,433,433,106,208,522,522,433,433,337,106,433,433,433,433,522,433,433,433,433,433,]),'parameter_declaration':([118,129,278,342,350,422,460,],[210,210,210,210,463,210,210,]),'primary_expression':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,]),'declaration':([0,21,59,75,93,181,298,427,],[38,90,38,90,182,302,302,499,]),'declaration_specifiers_no_type':([0,1,21,27,52,53,55,59,63,75,87,93,118,129,181,278,298,342,350,422,427,460,],[40,67,91,67,67,67,67,40,67,91,67,91,214,214,91,214,91,214,214,214,91,214,]),'jump_statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[303,303,303,303,303,303,303,303,303,303,303,303,303,]),'enumerator_list':([102,193,194,],[196,325,326,]),'block_item':([181,298,],[305,432,]),'constant_expression':([85,116,297,319,329,373,447,],[159,203,431,444,451,471,509,]),'identifier_list_opt':([118,129,460,],[207,221,516,]),'constant':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,]),'type_specifier_no_typeid':([0,4,21,40,59,75,85,89,91,93,95,99,118,129,172,174,177,181,184,185,186,192,211,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[12,71,12,12,12,12,12,71,12,12,12,12,12,12,12,12,275,12,12,12,12,275,71,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'struct_declaration':([99,184,185,186,313,315,],[190,190,190,318,318,318,]),'direct_typeid_noparen_declarator':([211,344,],[345,458,]),'id_declarator':([0,4,37,40,59,69,89,91,126,192,202,211,342,445,],[21,75,107,110,21,107,179,110,179,179,179,346,107,179,]),'selection_statement':([181,298,307,429,437,440,502,535,537,539,569,574,577,],[308,308,308,308,308,308,308,308,308,308,308,308,308,]),'postfix_expression':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,]),'initializer_list':([227,488,],[374,528,]),'unary_operator':([85,116,131,146,149,171,174,175,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,413,419,421,427,429,430,434,437,440,441,447,477,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,]),'struct_or_union':([0,21,40,59,75,85,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,]),'block_item_list_opt':([181,],[309,]),'assignment_expression':([131,174,181,201,204,218,229,231,233,258,265,266,290,298,307,338,339,353,354,364,375,412,419,421,427,429,430,434,437,440,441,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[228,272,272,228,335,335,272,272,272,272,272,408,272,272,272,455,456,466,467,468,228,486,335,335,272,272,272,272,272,272,272,525,272,272,335,228,272,272,272,272,272,561,562,272,272,272,272,272,272,]),'designation_opt':([227,472,488,550,],[375,521,375,521,]),'parameter_type_list':([118,129,278,342,422,460,],[209,222,416,416,416,517,]),'type_qualifier_list':([35,85,95,99,117,128,174,184,185,186,206,220,229,231,233,239,267,282,313,315,459,515,],[103,172,172,172,205,219,172,172,172,172,103,103,172,172,172,172,172,103,172,172,514,103,]),'designator':([227,376,472,488,550,],[371,474,371,371,371,]),'id_init_declarator_list_opt':([40,91,],[114,114,]),'declaration_specifiers':([0,21,59,75,93,118,129,181,278,298,342,350,422,427,460,],[4,89,4,89,89,211,211,89,211,89,211,211,211,89,211,]),'identifier_list':([118,129,460,],[212,212,212,]),'declaration_list_opt':([21,75,],[92,130,]),'function_definition':([0,59,],[45,45,]),'binary_expression':([85,116,131,174,181,201,204,218,229,231,233,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,419,421,427,429,430,434,437,440,441,447,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[162,162,162,162,162,162,162,162,162,162,162,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,162,400,401,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,]),'enum_specifier':([0,21,40,59,75,85,91,93,95,99,118,129,172,174,181,184,185,186,214,229,231,233,239,267,278,298,313,315,342,350,422,427,460,],[49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,]),'decl_body':([0,21,59,75,93,181,298,427,],[51,51,51,51,51,51,51,51,]),'function_specifier':([0,1,4,21,27,52,53,55,59,63,75,87,89,93,118,129,181,211,278,298,342,350,422,427,460,],[55,55,82,55,55,55,55,55,55,55,55,55,82,55,55,55,55,82,55,55,55,55,55,55,55,]),'specifier_qualifier_list':([85,95,99,174,184,185,186,229,231,233,239,267,313,315,],[177,177,192,177,192,192,192,177,177,177,177,177,192,192,]),'conditional_expression':([85,116,131,174,181,201,204,218,229,231,233,258,265,266,290,297,298,307,319,329,338,339,353,354,364,373,375,412,419,421,427,429,430,434,437,440,441,447,481,484,499,502,513,521,533,535,537,538,539,542,543,549,553,566,569,574,577,],[178,178,225,225,225,225,225,225,225,225,225,225,225,225,225,178,225,225,178,178,225,225,225,225,225,178,225,225,225,225,225,225,225,225,225,225,225,178,524,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> translation_unit_or_empty","S'",1,None,None,None), + ('abstract_declarator_opt -> empty','abstract_declarator_opt',1,'p_abstract_declarator_opt','plyparser.py',43), + ('abstract_declarator_opt -> abstract_declarator','abstract_declarator_opt',1,'p_abstract_declarator_opt','plyparser.py',44), + ('assignment_expression_opt -> empty','assignment_expression_opt',1,'p_assignment_expression_opt','plyparser.py',43), + ('assignment_expression_opt -> assignment_expression','assignment_expression_opt',1,'p_assignment_expression_opt','plyparser.py',44), + ('block_item_list_opt -> empty','block_item_list_opt',1,'p_block_item_list_opt','plyparser.py',43), + ('block_item_list_opt -> block_item_list','block_item_list_opt',1,'p_block_item_list_opt','plyparser.py',44), + ('declaration_list_opt -> empty','declaration_list_opt',1,'p_declaration_list_opt','plyparser.py',43), + ('declaration_list_opt -> declaration_list','declaration_list_opt',1,'p_declaration_list_opt','plyparser.py',44), + ('declaration_specifiers_no_type_opt -> empty','declaration_specifiers_no_type_opt',1,'p_declaration_specifiers_no_type_opt','plyparser.py',43), + ('declaration_specifiers_no_type_opt -> declaration_specifiers_no_type','declaration_specifiers_no_type_opt',1,'p_declaration_specifiers_no_type_opt','plyparser.py',44), + ('designation_opt -> empty','designation_opt',1,'p_designation_opt','plyparser.py',43), + ('designation_opt -> designation','designation_opt',1,'p_designation_opt','plyparser.py',44), + ('expression_opt -> empty','expression_opt',1,'p_expression_opt','plyparser.py',43), + ('expression_opt -> expression','expression_opt',1,'p_expression_opt','plyparser.py',44), + ('id_init_declarator_list_opt -> empty','id_init_declarator_list_opt',1,'p_id_init_declarator_list_opt','plyparser.py',43), + ('id_init_declarator_list_opt -> id_init_declarator_list','id_init_declarator_list_opt',1,'p_id_init_declarator_list_opt','plyparser.py',44), + ('identifier_list_opt -> empty','identifier_list_opt',1,'p_identifier_list_opt','plyparser.py',43), + ('identifier_list_opt -> identifier_list','identifier_list_opt',1,'p_identifier_list_opt','plyparser.py',44), + ('init_declarator_list_opt -> empty','init_declarator_list_opt',1,'p_init_declarator_list_opt','plyparser.py',43), + ('init_declarator_list_opt -> init_declarator_list','init_declarator_list_opt',1,'p_init_declarator_list_opt','plyparser.py',44), + ('initializer_list_opt -> empty','initializer_list_opt',1,'p_initializer_list_opt','plyparser.py',43), + ('initializer_list_opt -> initializer_list','initializer_list_opt',1,'p_initializer_list_opt','plyparser.py',44), + ('parameter_type_list_opt -> empty','parameter_type_list_opt',1,'p_parameter_type_list_opt','plyparser.py',43), + ('parameter_type_list_opt -> parameter_type_list','parameter_type_list_opt',1,'p_parameter_type_list_opt','plyparser.py',44), + ('struct_declarator_list_opt -> empty','struct_declarator_list_opt',1,'p_struct_declarator_list_opt','plyparser.py',43), + ('struct_declarator_list_opt -> struct_declarator_list','struct_declarator_list_opt',1,'p_struct_declarator_list_opt','plyparser.py',44), + ('type_qualifier_list_opt -> empty','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','plyparser.py',43), + ('type_qualifier_list_opt -> type_qualifier_list','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','plyparser.py',44), + ('direct_id_declarator -> ID','direct_id_declarator',1,'p_direct_id_declarator_1','plyparser.py',126), + ('direct_id_declarator -> LPAREN id_declarator RPAREN','direct_id_declarator',3,'p_direct_id_declarator_2','plyparser.py',126), + ('direct_id_declarator -> direct_id_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET','direct_id_declarator',5,'p_direct_id_declarator_3','plyparser.py',126), + ('direct_id_declarator -> direct_id_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET','direct_id_declarator',6,'p_direct_id_declarator_4','plyparser.py',126), + ('direct_id_declarator -> direct_id_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET','direct_id_declarator',6,'p_direct_id_declarator_4','plyparser.py',127), + ('direct_id_declarator -> direct_id_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET','direct_id_declarator',5,'p_direct_id_declarator_5','plyparser.py',126), + ('direct_id_declarator -> direct_id_declarator LPAREN parameter_type_list RPAREN','direct_id_declarator',4,'p_direct_id_declarator_6','plyparser.py',126), + ('direct_id_declarator -> direct_id_declarator LPAREN identifier_list_opt RPAREN','direct_id_declarator',4,'p_direct_id_declarator_6','plyparser.py',127), + ('direct_typeid_declarator -> TYPEID','direct_typeid_declarator',1,'p_direct_typeid_declarator_1','plyparser.py',126), + ('direct_typeid_declarator -> LPAREN typeid_declarator RPAREN','direct_typeid_declarator',3,'p_direct_typeid_declarator_2','plyparser.py',126), + ('direct_typeid_declarator -> direct_typeid_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET','direct_typeid_declarator',5,'p_direct_typeid_declarator_3','plyparser.py',126), + ('direct_typeid_declarator -> direct_typeid_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET','direct_typeid_declarator',6,'p_direct_typeid_declarator_4','plyparser.py',126), + ('direct_typeid_declarator -> direct_typeid_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET','direct_typeid_declarator',6,'p_direct_typeid_declarator_4','plyparser.py',127), + ('direct_typeid_declarator -> direct_typeid_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET','direct_typeid_declarator',5,'p_direct_typeid_declarator_5','plyparser.py',126), + ('direct_typeid_declarator -> direct_typeid_declarator LPAREN parameter_type_list RPAREN','direct_typeid_declarator',4,'p_direct_typeid_declarator_6','plyparser.py',126), + ('direct_typeid_declarator -> direct_typeid_declarator LPAREN identifier_list_opt RPAREN','direct_typeid_declarator',4,'p_direct_typeid_declarator_6','plyparser.py',127), + ('direct_typeid_noparen_declarator -> TYPEID','direct_typeid_noparen_declarator',1,'p_direct_typeid_noparen_declarator_1','plyparser.py',126), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET','direct_typeid_noparen_declarator',5,'p_direct_typeid_noparen_declarator_3','plyparser.py',126), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET','direct_typeid_noparen_declarator',6,'p_direct_typeid_noparen_declarator_4','plyparser.py',126), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET','direct_typeid_noparen_declarator',6,'p_direct_typeid_noparen_declarator_4','plyparser.py',127), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET','direct_typeid_noparen_declarator',5,'p_direct_typeid_noparen_declarator_5','plyparser.py',126), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LPAREN parameter_type_list RPAREN','direct_typeid_noparen_declarator',4,'p_direct_typeid_noparen_declarator_6','plyparser.py',126), + ('direct_typeid_noparen_declarator -> direct_typeid_noparen_declarator LPAREN identifier_list_opt RPAREN','direct_typeid_noparen_declarator',4,'p_direct_typeid_noparen_declarator_6','plyparser.py',127), + ('id_declarator -> direct_id_declarator','id_declarator',1,'p_id_declarator_1','plyparser.py',126), + ('id_declarator -> pointer direct_id_declarator','id_declarator',2,'p_id_declarator_2','plyparser.py',126), + ('typeid_declarator -> direct_typeid_declarator','typeid_declarator',1,'p_typeid_declarator_1','plyparser.py',126), + ('typeid_declarator -> pointer direct_typeid_declarator','typeid_declarator',2,'p_typeid_declarator_2','plyparser.py',126), + ('typeid_noparen_declarator -> direct_typeid_noparen_declarator','typeid_noparen_declarator',1,'p_typeid_noparen_declarator_1','plyparser.py',126), + ('typeid_noparen_declarator -> pointer direct_typeid_noparen_declarator','typeid_noparen_declarator',2,'p_typeid_noparen_declarator_2','plyparser.py',126), + ('translation_unit_or_empty -> translation_unit','translation_unit_or_empty',1,'p_translation_unit_or_empty','c_parser.py',509), + ('translation_unit_or_empty -> empty','translation_unit_or_empty',1,'p_translation_unit_or_empty','c_parser.py',510), + ('translation_unit -> external_declaration','translation_unit',1,'p_translation_unit_1','c_parser.py',518), + ('translation_unit -> translation_unit external_declaration','translation_unit',2,'p_translation_unit_2','c_parser.py',524), + ('external_declaration -> function_definition','external_declaration',1,'p_external_declaration_1','c_parser.py',534), + ('external_declaration -> declaration','external_declaration',1,'p_external_declaration_2','c_parser.py',539), + ('external_declaration -> pp_directive','external_declaration',1,'p_external_declaration_3','c_parser.py',544), + ('external_declaration -> pppragma_directive','external_declaration',1,'p_external_declaration_3','c_parser.py',545), + ('external_declaration -> SEMI','external_declaration',1,'p_external_declaration_4','c_parser.py',550), + ('external_declaration -> static_assert','external_declaration',1,'p_external_declaration_5','c_parser.py',555), + ('static_assert -> _STATIC_ASSERT LPAREN constant_expression COMMA unified_string_literal RPAREN','static_assert',6,'p_static_assert_declaration','c_parser.py',560), + ('static_assert -> _STATIC_ASSERT LPAREN constant_expression RPAREN','static_assert',4,'p_static_assert_declaration','c_parser.py',561), + ('pp_directive -> PPHASH','pp_directive',1,'p_pp_directive','c_parser.py',569), + ('pppragma_directive -> PPPRAGMA','pppragma_directive',1,'p_pppragma_directive','c_parser.py',575), + ('pppragma_directive -> PPPRAGMA PPPRAGMASTR','pppragma_directive',2,'p_pppragma_directive','c_parser.py',576), + ('function_definition -> id_declarator declaration_list_opt compound_statement','function_definition',3,'p_function_definition_1','c_parser.py',586), + ('function_definition -> declaration_specifiers id_declarator declaration_list_opt compound_statement','function_definition',4,'p_function_definition_2','c_parser.py',604), + ('statement -> labeled_statement','statement',1,'p_statement','c_parser.py',619), + ('statement -> expression_statement','statement',1,'p_statement','c_parser.py',620), + ('statement -> compound_statement','statement',1,'p_statement','c_parser.py',621), + ('statement -> selection_statement','statement',1,'p_statement','c_parser.py',622), + ('statement -> iteration_statement','statement',1,'p_statement','c_parser.py',623), + ('statement -> jump_statement','statement',1,'p_statement','c_parser.py',624), + ('statement -> pppragma_directive','statement',1,'p_statement','c_parser.py',625), + ('statement -> static_assert','statement',1,'p_statement','c_parser.py',626), + ('pragmacomp_or_statement -> pppragma_directive statement','pragmacomp_or_statement',2,'p_pragmacomp_or_statement','c_parser.py',674), + ('pragmacomp_or_statement -> statement','pragmacomp_or_statement',1,'p_pragmacomp_or_statement','c_parser.py',675), + ('decl_body -> declaration_specifiers init_declarator_list_opt','decl_body',2,'p_decl_body','c_parser.py',694), + ('decl_body -> declaration_specifiers_no_type id_init_declarator_list_opt','decl_body',2,'p_decl_body','c_parser.py',695), + ('declaration -> decl_body SEMI','declaration',2,'p_declaration','c_parser.py',755), + ('declaration_list -> declaration','declaration_list',1,'p_declaration_list','c_parser.py',764), + ('declaration_list -> declaration_list declaration','declaration_list',2,'p_declaration_list','c_parser.py',765), + ('declaration_specifiers_no_type -> type_qualifier declaration_specifiers_no_type_opt','declaration_specifiers_no_type',2,'p_declaration_specifiers_no_type_1','c_parser.py',775), + ('declaration_specifiers_no_type -> storage_class_specifier declaration_specifiers_no_type_opt','declaration_specifiers_no_type',2,'p_declaration_specifiers_no_type_2','c_parser.py',780), + ('declaration_specifiers_no_type -> function_specifier declaration_specifiers_no_type_opt','declaration_specifiers_no_type',2,'p_declaration_specifiers_no_type_3','c_parser.py',785), + ('declaration_specifiers_no_type -> atomic_specifier declaration_specifiers_no_type_opt','declaration_specifiers_no_type',2,'p_declaration_specifiers_no_type_4','c_parser.py',792), + ('declaration_specifiers_no_type -> alignment_specifier declaration_specifiers_no_type_opt','declaration_specifiers_no_type',2,'p_declaration_specifiers_no_type_5','c_parser.py',797), + ('declaration_specifiers -> declaration_specifiers type_qualifier','declaration_specifiers',2,'p_declaration_specifiers_1','c_parser.py',802), + ('declaration_specifiers -> declaration_specifiers storage_class_specifier','declaration_specifiers',2,'p_declaration_specifiers_2','c_parser.py',807), + ('declaration_specifiers -> declaration_specifiers function_specifier','declaration_specifiers',2,'p_declaration_specifiers_3','c_parser.py',812), + ('declaration_specifiers -> declaration_specifiers type_specifier_no_typeid','declaration_specifiers',2,'p_declaration_specifiers_4','c_parser.py',817), + ('declaration_specifiers -> type_specifier','declaration_specifiers',1,'p_declaration_specifiers_5','c_parser.py',822), + ('declaration_specifiers -> declaration_specifiers_no_type type_specifier','declaration_specifiers',2,'p_declaration_specifiers_6','c_parser.py',827), + ('declaration_specifiers -> declaration_specifiers alignment_specifier','declaration_specifiers',2,'p_declaration_specifiers_7','c_parser.py',832), + ('storage_class_specifier -> AUTO','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',837), + ('storage_class_specifier -> REGISTER','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',838), + ('storage_class_specifier -> STATIC','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',839), + ('storage_class_specifier -> EXTERN','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',840), + ('storage_class_specifier -> TYPEDEF','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',841), + ('storage_class_specifier -> _THREAD_LOCAL','storage_class_specifier',1,'p_storage_class_specifier','c_parser.py',842), + ('function_specifier -> INLINE','function_specifier',1,'p_function_specifier','c_parser.py',847), + ('function_specifier -> _NORETURN','function_specifier',1,'p_function_specifier','c_parser.py',848), + ('type_specifier_no_typeid -> VOID','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',853), + ('type_specifier_no_typeid -> _BOOL','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',854), + ('type_specifier_no_typeid -> CHAR','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',855), + ('type_specifier_no_typeid -> SHORT','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',856), + ('type_specifier_no_typeid -> INT','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',857), + ('type_specifier_no_typeid -> LONG','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',858), + ('type_specifier_no_typeid -> FLOAT','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',859), + ('type_specifier_no_typeid -> DOUBLE','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',860), + ('type_specifier_no_typeid -> _COMPLEX','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',861), + ('type_specifier_no_typeid -> SIGNED','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',862), + ('type_specifier_no_typeid -> UNSIGNED','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',863), + ('type_specifier_no_typeid -> __INT128','type_specifier_no_typeid',1,'p_type_specifier_no_typeid','c_parser.py',864), + ('type_specifier -> typedef_name','type_specifier',1,'p_type_specifier','c_parser.py',869), + ('type_specifier -> enum_specifier','type_specifier',1,'p_type_specifier','c_parser.py',870), + ('type_specifier -> struct_or_union_specifier','type_specifier',1,'p_type_specifier','c_parser.py',871), + ('type_specifier -> type_specifier_no_typeid','type_specifier',1,'p_type_specifier','c_parser.py',872), + ('type_specifier -> atomic_specifier','type_specifier',1,'p_type_specifier','c_parser.py',873), + ('atomic_specifier -> _ATOMIC LPAREN type_name RPAREN','atomic_specifier',4,'p_atomic_specifier','c_parser.py',879), + ('type_qualifier -> CONST','type_qualifier',1,'p_type_qualifier','c_parser.py',886), + ('type_qualifier -> RESTRICT','type_qualifier',1,'p_type_qualifier','c_parser.py',887), + ('type_qualifier -> VOLATILE','type_qualifier',1,'p_type_qualifier','c_parser.py',888), + ('type_qualifier -> _ATOMIC','type_qualifier',1,'p_type_qualifier','c_parser.py',889), + ('init_declarator_list -> init_declarator','init_declarator_list',1,'p_init_declarator_list','c_parser.py',894), + ('init_declarator_list -> init_declarator_list COMMA init_declarator','init_declarator_list',3,'p_init_declarator_list','c_parser.py',895), + ('init_declarator -> declarator','init_declarator',1,'p_init_declarator','c_parser.py',903), + ('init_declarator -> declarator EQUALS initializer','init_declarator',3,'p_init_declarator','c_parser.py',904), + ('id_init_declarator_list -> id_init_declarator','id_init_declarator_list',1,'p_id_init_declarator_list','c_parser.py',909), + ('id_init_declarator_list -> id_init_declarator_list COMMA init_declarator','id_init_declarator_list',3,'p_id_init_declarator_list','c_parser.py',910), + ('id_init_declarator -> id_declarator','id_init_declarator',1,'p_id_init_declarator','c_parser.py',915), + ('id_init_declarator -> id_declarator EQUALS initializer','id_init_declarator',3,'p_id_init_declarator','c_parser.py',916), + ('specifier_qualifier_list -> specifier_qualifier_list type_specifier_no_typeid','specifier_qualifier_list',2,'p_specifier_qualifier_list_1','c_parser.py',923), + ('specifier_qualifier_list -> specifier_qualifier_list type_qualifier','specifier_qualifier_list',2,'p_specifier_qualifier_list_2','c_parser.py',928), + ('specifier_qualifier_list -> type_specifier','specifier_qualifier_list',1,'p_specifier_qualifier_list_3','c_parser.py',933), + ('specifier_qualifier_list -> type_qualifier_list type_specifier','specifier_qualifier_list',2,'p_specifier_qualifier_list_4','c_parser.py',938), + ('specifier_qualifier_list -> alignment_specifier','specifier_qualifier_list',1,'p_specifier_qualifier_list_5','c_parser.py',943), + ('specifier_qualifier_list -> specifier_qualifier_list alignment_specifier','specifier_qualifier_list',2,'p_specifier_qualifier_list_6','c_parser.py',948), + ('struct_or_union_specifier -> struct_or_union ID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','c_parser.py',956), + ('struct_or_union_specifier -> struct_or_union TYPEID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','c_parser.py',957), + ('struct_or_union_specifier -> struct_or_union brace_open struct_declaration_list brace_close','struct_or_union_specifier',4,'p_struct_or_union_specifier_2','c_parser.py',967), + ('struct_or_union_specifier -> struct_or_union brace_open brace_close','struct_or_union_specifier',3,'p_struct_or_union_specifier_2','c_parser.py',968), + ('struct_or_union_specifier -> struct_or_union ID brace_open struct_declaration_list brace_close','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','c_parser.py',985), + ('struct_or_union_specifier -> struct_or_union ID brace_open brace_close','struct_or_union_specifier',4,'p_struct_or_union_specifier_3','c_parser.py',986), + ('struct_or_union_specifier -> struct_or_union TYPEID brace_open struct_declaration_list brace_close','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','c_parser.py',987), + ('struct_or_union_specifier -> struct_or_union TYPEID brace_open brace_close','struct_or_union_specifier',4,'p_struct_or_union_specifier_3','c_parser.py',988), + ('struct_or_union -> STRUCT','struct_or_union',1,'p_struct_or_union','c_parser.py',1004), + ('struct_or_union -> UNION','struct_or_union',1,'p_struct_or_union','c_parser.py',1005), + ('struct_declaration_list -> struct_declaration','struct_declaration_list',1,'p_struct_declaration_list','c_parser.py',1012), + ('struct_declaration_list -> struct_declaration_list struct_declaration','struct_declaration_list',2,'p_struct_declaration_list','c_parser.py',1013), + ('struct_declaration -> specifier_qualifier_list struct_declarator_list_opt SEMI','struct_declaration',3,'p_struct_declaration_1','c_parser.py',1021), + ('struct_declaration -> SEMI','struct_declaration',1,'p_struct_declaration_2','c_parser.py',1059), + ('struct_declaration -> pppragma_directive','struct_declaration',1,'p_struct_declaration_3','c_parser.py',1064), + ('struct_declarator_list -> struct_declarator','struct_declarator_list',1,'p_struct_declarator_list','c_parser.py',1069), + ('struct_declarator_list -> struct_declarator_list COMMA struct_declarator','struct_declarator_list',3,'p_struct_declarator_list','c_parser.py',1070), + ('struct_declarator -> declarator','struct_declarator',1,'p_struct_declarator_1','c_parser.py',1078), + ('struct_declarator -> declarator COLON constant_expression','struct_declarator',3,'p_struct_declarator_2','c_parser.py',1083), + ('struct_declarator -> COLON constant_expression','struct_declarator',2,'p_struct_declarator_2','c_parser.py',1084), + ('enum_specifier -> ENUM ID','enum_specifier',2,'p_enum_specifier_1','c_parser.py',1092), + ('enum_specifier -> ENUM TYPEID','enum_specifier',2,'p_enum_specifier_1','c_parser.py',1093), + ('enum_specifier -> ENUM brace_open enumerator_list brace_close','enum_specifier',4,'p_enum_specifier_2','c_parser.py',1098), + ('enum_specifier -> ENUM ID brace_open enumerator_list brace_close','enum_specifier',5,'p_enum_specifier_3','c_parser.py',1103), + ('enum_specifier -> ENUM TYPEID brace_open enumerator_list brace_close','enum_specifier',5,'p_enum_specifier_3','c_parser.py',1104), + ('enumerator_list -> enumerator','enumerator_list',1,'p_enumerator_list','c_parser.py',1109), + ('enumerator_list -> enumerator_list COMMA','enumerator_list',2,'p_enumerator_list','c_parser.py',1110), + ('enumerator_list -> enumerator_list COMMA enumerator','enumerator_list',3,'p_enumerator_list','c_parser.py',1111), + ('alignment_specifier -> _ALIGNAS LPAREN type_name RPAREN','alignment_specifier',4,'p_alignment_specifier','c_parser.py',1122), + ('alignment_specifier -> _ALIGNAS LPAREN constant_expression RPAREN','alignment_specifier',4,'p_alignment_specifier','c_parser.py',1123), + ('enumerator -> ID','enumerator',1,'p_enumerator','c_parser.py',1128), + ('enumerator -> ID EQUALS constant_expression','enumerator',3,'p_enumerator','c_parser.py',1129), + ('declarator -> id_declarator','declarator',1,'p_declarator','c_parser.py',1144), + ('declarator -> typeid_declarator','declarator',1,'p_declarator','c_parser.py',1145), + ('pointer -> TIMES type_qualifier_list_opt','pointer',2,'p_pointer','c_parser.py',1257), + ('pointer -> TIMES type_qualifier_list_opt pointer','pointer',3,'p_pointer','c_parser.py',1258), + ('type_qualifier_list -> type_qualifier','type_qualifier_list',1,'p_type_qualifier_list','c_parser.py',1287), + ('type_qualifier_list -> type_qualifier_list type_qualifier','type_qualifier_list',2,'p_type_qualifier_list','c_parser.py',1288), + ('parameter_type_list -> parameter_list','parameter_type_list',1,'p_parameter_type_list','c_parser.py',1293), + ('parameter_type_list -> parameter_list COMMA ELLIPSIS','parameter_type_list',3,'p_parameter_type_list','c_parser.py',1294), + ('parameter_list -> parameter_declaration','parameter_list',1,'p_parameter_list','c_parser.py',1302), + ('parameter_list -> parameter_list COMMA parameter_declaration','parameter_list',3,'p_parameter_list','c_parser.py',1303), + ('parameter_declaration -> declaration_specifiers id_declarator','parameter_declaration',2,'p_parameter_declaration_1','c_parser.py',1322), + ('parameter_declaration -> declaration_specifiers typeid_noparen_declarator','parameter_declaration',2,'p_parameter_declaration_1','c_parser.py',1323), + ('parameter_declaration -> declaration_specifiers abstract_declarator_opt','parameter_declaration',2,'p_parameter_declaration_2','c_parser.py',1334), + ('identifier_list -> identifier','identifier_list',1,'p_identifier_list','c_parser.py',1366), + ('identifier_list -> identifier_list COMMA identifier','identifier_list',3,'p_identifier_list','c_parser.py',1367), + ('initializer -> assignment_expression','initializer',1,'p_initializer_1','c_parser.py',1376), + ('initializer -> brace_open initializer_list_opt brace_close','initializer',3,'p_initializer_2','c_parser.py',1381), + ('initializer -> brace_open initializer_list COMMA brace_close','initializer',4,'p_initializer_2','c_parser.py',1382), + ('initializer_list -> designation_opt initializer','initializer_list',2,'p_initializer_list','c_parser.py',1390), + ('initializer_list -> initializer_list COMMA designation_opt initializer','initializer_list',4,'p_initializer_list','c_parser.py',1391), + ('designation -> designator_list EQUALS','designation',2,'p_designation','c_parser.py',1402), + ('designator_list -> designator','designator_list',1,'p_designator_list','c_parser.py',1410), + ('designator_list -> designator_list designator','designator_list',2,'p_designator_list','c_parser.py',1411), + ('designator -> LBRACKET constant_expression RBRACKET','designator',3,'p_designator','c_parser.py',1416), + ('designator -> PERIOD identifier','designator',2,'p_designator','c_parser.py',1417), + ('type_name -> specifier_qualifier_list abstract_declarator_opt','type_name',2,'p_type_name','c_parser.py',1422), + ('abstract_declarator -> pointer','abstract_declarator',1,'p_abstract_declarator_1','c_parser.py',1434), + ('abstract_declarator -> pointer direct_abstract_declarator','abstract_declarator',2,'p_abstract_declarator_2','c_parser.py',1442), + ('abstract_declarator -> direct_abstract_declarator','abstract_declarator',1,'p_abstract_declarator_3','c_parser.py',1447), + ('direct_abstract_declarator -> LPAREN abstract_declarator RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_1','c_parser.py',1457), + ('direct_abstract_declarator -> direct_abstract_declarator LBRACKET assignment_expression_opt RBRACKET','direct_abstract_declarator',4,'p_direct_abstract_declarator_2','c_parser.py',1461), + ('direct_abstract_declarator -> LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET','direct_abstract_declarator',4,'p_direct_abstract_declarator_3','c_parser.py',1472), + ('direct_abstract_declarator -> direct_abstract_declarator LBRACKET TIMES RBRACKET','direct_abstract_declarator',4,'p_direct_abstract_declarator_4','c_parser.py',1482), + ('direct_abstract_declarator -> LBRACKET TIMES RBRACKET','direct_abstract_declarator',3,'p_direct_abstract_declarator_5','c_parser.py',1493), + ('direct_abstract_declarator -> direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',4,'p_direct_abstract_declarator_6','c_parser.py',1502), + ('direct_abstract_declarator -> LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_7','c_parser.py',1512), + ('block_item -> declaration','block_item',1,'p_block_item','c_parser.py',1523), + ('block_item -> statement','block_item',1,'p_block_item','c_parser.py',1524), + ('block_item_list -> block_item','block_item_list',1,'p_block_item_list','c_parser.py',1531), + ('block_item_list -> block_item_list block_item','block_item_list',2,'p_block_item_list','c_parser.py',1532), + ('compound_statement -> brace_open block_item_list_opt brace_close','compound_statement',3,'p_compound_statement_1','c_parser.py',1538), + ('labeled_statement -> ID COLON pragmacomp_or_statement','labeled_statement',3,'p_labeled_statement_1','c_parser.py',1544), + ('labeled_statement -> CASE constant_expression COLON pragmacomp_or_statement','labeled_statement',4,'p_labeled_statement_2','c_parser.py',1548), + ('labeled_statement -> DEFAULT COLON pragmacomp_or_statement','labeled_statement',3,'p_labeled_statement_3','c_parser.py',1552), + ('selection_statement -> IF LPAREN expression RPAREN pragmacomp_or_statement','selection_statement',5,'p_selection_statement_1','c_parser.py',1556), + ('selection_statement -> IF LPAREN expression RPAREN statement ELSE pragmacomp_or_statement','selection_statement',7,'p_selection_statement_2','c_parser.py',1560), + ('selection_statement -> SWITCH LPAREN expression RPAREN pragmacomp_or_statement','selection_statement',5,'p_selection_statement_3','c_parser.py',1564), + ('iteration_statement -> WHILE LPAREN expression RPAREN pragmacomp_or_statement','iteration_statement',5,'p_iteration_statement_1','c_parser.py',1569), + ('iteration_statement -> DO pragmacomp_or_statement WHILE LPAREN expression RPAREN SEMI','iteration_statement',7,'p_iteration_statement_2','c_parser.py',1573), + ('iteration_statement -> FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement','iteration_statement',9,'p_iteration_statement_3','c_parser.py',1577), + ('iteration_statement -> FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement','iteration_statement',8,'p_iteration_statement_4','c_parser.py',1581), + ('jump_statement -> GOTO ID SEMI','jump_statement',3,'p_jump_statement_1','c_parser.py',1586), + ('jump_statement -> BREAK SEMI','jump_statement',2,'p_jump_statement_2','c_parser.py',1590), + ('jump_statement -> CONTINUE SEMI','jump_statement',2,'p_jump_statement_3','c_parser.py',1594), + ('jump_statement -> RETURN expression SEMI','jump_statement',3,'p_jump_statement_4','c_parser.py',1598), + ('jump_statement -> RETURN SEMI','jump_statement',2,'p_jump_statement_4','c_parser.py',1599), + ('expression_statement -> expression_opt SEMI','expression_statement',2,'p_expression_statement','c_parser.py',1604), + ('expression -> assignment_expression','expression',1,'p_expression','c_parser.py',1611), + ('expression -> expression COMMA assignment_expression','expression',3,'p_expression','c_parser.py',1612), + ('assignment_expression -> LPAREN compound_statement RPAREN','assignment_expression',3,'p_parenthesized_compound_expression','c_parser.py',1624), + ('typedef_name -> TYPEID','typedef_name',1,'p_typedef_name','c_parser.py',1628), + ('assignment_expression -> conditional_expression','assignment_expression',1,'p_assignment_expression','c_parser.py',1632), + ('assignment_expression -> unary_expression assignment_operator assignment_expression','assignment_expression',3,'p_assignment_expression','c_parser.py',1633), + ('assignment_operator -> EQUALS','assignment_operator',1,'p_assignment_operator','c_parser.py',1646), + ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1647), + ('assignment_operator -> TIMESEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1648), + ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1649), + ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1650), + ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1651), + ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1652), + ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1653), + ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1654), + ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1655), + ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','c_parser.py',1656), + ('constant_expression -> conditional_expression','constant_expression',1,'p_constant_expression','c_parser.py',1661), + ('conditional_expression -> binary_expression','conditional_expression',1,'p_conditional_expression','c_parser.py',1665), + ('conditional_expression -> binary_expression CONDOP expression COLON conditional_expression','conditional_expression',5,'p_conditional_expression','c_parser.py',1666), + ('binary_expression -> cast_expression','binary_expression',1,'p_binary_expression','c_parser.py',1674), + ('binary_expression -> binary_expression TIMES binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1675), + ('binary_expression -> binary_expression DIVIDE binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1676), + ('binary_expression -> binary_expression MOD binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1677), + ('binary_expression -> binary_expression PLUS binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1678), + ('binary_expression -> binary_expression MINUS binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1679), + ('binary_expression -> binary_expression RSHIFT binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1680), + ('binary_expression -> binary_expression LSHIFT binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1681), + ('binary_expression -> binary_expression LT binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1682), + ('binary_expression -> binary_expression LE binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1683), + ('binary_expression -> binary_expression GE binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1684), + ('binary_expression -> binary_expression GT binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1685), + ('binary_expression -> binary_expression EQ binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1686), + ('binary_expression -> binary_expression NE binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1687), + ('binary_expression -> binary_expression AND binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1688), + ('binary_expression -> binary_expression OR binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1689), + ('binary_expression -> binary_expression XOR binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1690), + ('binary_expression -> binary_expression LAND binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1691), + ('binary_expression -> binary_expression LOR binary_expression','binary_expression',3,'p_binary_expression','c_parser.py',1692), + ('cast_expression -> unary_expression','cast_expression',1,'p_cast_expression_1','c_parser.py',1700), + ('cast_expression -> LPAREN type_name RPAREN cast_expression','cast_expression',4,'p_cast_expression_2','c_parser.py',1704), + ('unary_expression -> postfix_expression','unary_expression',1,'p_unary_expression_1','c_parser.py',1708), + ('unary_expression -> PLUSPLUS unary_expression','unary_expression',2,'p_unary_expression_2','c_parser.py',1712), + ('unary_expression -> MINUSMINUS unary_expression','unary_expression',2,'p_unary_expression_2','c_parser.py',1713), + ('unary_expression -> unary_operator cast_expression','unary_expression',2,'p_unary_expression_2','c_parser.py',1714), + ('unary_expression -> SIZEOF unary_expression','unary_expression',2,'p_unary_expression_3','c_parser.py',1719), + ('unary_expression -> SIZEOF LPAREN type_name RPAREN','unary_expression',4,'p_unary_expression_3','c_parser.py',1720), + ('unary_expression -> _ALIGNOF LPAREN type_name RPAREN','unary_expression',4,'p_unary_expression_3','c_parser.py',1721), + ('unary_operator -> AND','unary_operator',1,'p_unary_operator','c_parser.py',1729), + ('unary_operator -> TIMES','unary_operator',1,'p_unary_operator','c_parser.py',1730), + ('unary_operator -> PLUS','unary_operator',1,'p_unary_operator','c_parser.py',1731), + ('unary_operator -> MINUS','unary_operator',1,'p_unary_operator','c_parser.py',1732), + ('unary_operator -> NOT','unary_operator',1,'p_unary_operator','c_parser.py',1733), + ('unary_operator -> LNOT','unary_operator',1,'p_unary_operator','c_parser.py',1734), + ('postfix_expression -> primary_expression','postfix_expression',1,'p_postfix_expression_1','c_parser.py',1739), + ('postfix_expression -> postfix_expression LBRACKET expression RBRACKET','postfix_expression',4,'p_postfix_expression_2','c_parser.py',1743), + ('postfix_expression -> postfix_expression LPAREN argument_expression_list RPAREN','postfix_expression',4,'p_postfix_expression_3','c_parser.py',1747), + ('postfix_expression -> postfix_expression LPAREN RPAREN','postfix_expression',3,'p_postfix_expression_3','c_parser.py',1748), + ('postfix_expression -> postfix_expression PERIOD ID','postfix_expression',3,'p_postfix_expression_4','c_parser.py',1753), + ('postfix_expression -> postfix_expression PERIOD TYPEID','postfix_expression',3,'p_postfix_expression_4','c_parser.py',1754), + ('postfix_expression -> postfix_expression ARROW ID','postfix_expression',3,'p_postfix_expression_4','c_parser.py',1755), + ('postfix_expression -> postfix_expression ARROW TYPEID','postfix_expression',3,'p_postfix_expression_4','c_parser.py',1756), + ('postfix_expression -> postfix_expression PLUSPLUS','postfix_expression',2,'p_postfix_expression_5','c_parser.py',1762), + ('postfix_expression -> postfix_expression MINUSMINUS','postfix_expression',2,'p_postfix_expression_5','c_parser.py',1763), + ('postfix_expression -> LPAREN type_name RPAREN brace_open initializer_list brace_close','postfix_expression',6,'p_postfix_expression_6','c_parser.py',1768), + ('postfix_expression -> LPAREN type_name RPAREN brace_open initializer_list COMMA brace_close','postfix_expression',7,'p_postfix_expression_6','c_parser.py',1769), + ('primary_expression -> identifier','primary_expression',1,'p_primary_expression_1','c_parser.py',1774), + ('primary_expression -> constant','primary_expression',1,'p_primary_expression_2','c_parser.py',1778), + ('primary_expression -> unified_string_literal','primary_expression',1,'p_primary_expression_3','c_parser.py',1782), + ('primary_expression -> unified_wstring_literal','primary_expression',1,'p_primary_expression_3','c_parser.py',1783), + ('primary_expression -> LPAREN expression RPAREN','primary_expression',3,'p_primary_expression_4','c_parser.py',1788), + ('primary_expression -> OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN','primary_expression',6,'p_primary_expression_5','c_parser.py',1792), + ('offsetof_member_designator -> identifier','offsetof_member_designator',1,'p_offsetof_member_designator','c_parser.py',1800), + ('offsetof_member_designator -> offsetof_member_designator PERIOD identifier','offsetof_member_designator',3,'p_offsetof_member_designator','c_parser.py',1801), + ('offsetof_member_designator -> offsetof_member_designator LBRACKET expression RBRACKET','offsetof_member_designator',4,'p_offsetof_member_designator','c_parser.py',1802), + ('argument_expression_list -> assignment_expression','argument_expression_list',1,'p_argument_expression_list','c_parser.py',1814), + ('argument_expression_list -> argument_expression_list COMMA assignment_expression','argument_expression_list',3,'p_argument_expression_list','c_parser.py',1815), + ('identifier -> ID','identifier',1,'p_identifier','c_parser.py',1824), + ('constant -> INT_CONST_DEC','constant',1,'p_constant_1','c_parser.py',1828), + ('constant -> INT_CONST_OCT','constant',1,'p_constant_1','c_parser.py',1829), + ('constant -> INT_CONST_HEX','constant',1,'p_constant_1','c_parser.py',1830), + ('constant -> INT_CONST_BIN','constant',1,'p_constant_1','c_parser.py',1831), + ('constant -> INT_CONST_CHAR','constant',1,'p_constant_1','c_parser.py',1832), + ('constant -> FLOAT_CONST','constant',1,'p_constant_2','c_parser.py',1851), + ('constant -> HEX_FLOAT_CONST','constant',1,'p_constant_2','c_parser.py',1852), + ('constant -> CHAR_CONST','constant',1,'p_constant_3','c_parser.py',1868), + ('constant -> WCHAR_CONST','constant',1,'p_constant_3','c_parser.py',1869), + ('constant -> U8CHAR_CONST','constant',1,'p_constant_3','c_parser.py',1870), + ('constant -> U16CHAR_CONST','constant',1,'p_constant_3','c_parser.py',1871), + ('constant -> U32CHAR_CONST','constant',1,'p_constant_3','c_parser.py',1872), + ('unified_string_literal -> STRING_LITERAL','unified_string_literal',1,'p_unified_string_literal','c_parser.py',1883), + ('unified_string_literal -> unified_string_literal STRING_LITERAL','unified_string_literal',2,'p_unified_string_literal','c_parser.py',1884), + ('unified_wstring_literal -> WSTRING_LITERAL','unified_wstring_literal',1,'p_unified_wstring_literal','c_parser.py',1894), + ('unified_wstring_literal -> U8STRING_LITERAL','unified_wstring_literal',1,'p_unified_wstring_literal','c_parser.py',1895), + ('unified_wstring_literal -> U16STRING_LITERAL','unified_wstring_literal',1,'p_unified_wstring_literal','c_parser.py',1896), + ('unified_wstring_literal -> U32STRING_LITERAL','unified_wstring_literal',1,'p_unified_wstring_literal','c_parser.py',1897), + ('unified_wstring_literal -> unified_wstring_literal WSTRING_LITERAL','unified_wstring_literal',2,'p_unified_wstring_literal','c_parser.py',1898), + ('unified_wstring_literal -> unified_wstring_literal U8STRING_LITERAL','unified_wstring_literal',2,'p_unified_wstring_literal','c_parser.py',1899), + ('unified_wstring_literal -> unified_wstring_literal U16STRING_LITERAL','unified_wstring_literal',2,'p_unified_wstring_literal','c_parser.py',1900), + ('unified_wstring_literal -> unified_wstring_literal U32STRING_LITERAL','unified_wstring_literal',2,'p_unified_wstring_literal','c_parser.py',1901), + ('brace_open -> LBRACE','brace_open',1,'p_brace_open','c_parser.py',1911), + ('brace_close -> RBRACE','brace_close',1,'p_brace_close','c_parser.py',1917), + ('empty -> ','empty',0,'p_empty','c_parser.py',1923), +] diff --git a/uno/lib/python/rdflib-6.3.2.dist-info/LICENSE b/uno/lib/python/rdflib-6.3.2.dist-info/LICENSE deleted file mode 100644 index 26039b46..00000000 --- a/uno/lib/python/rdflib-6.3.2.dist-info/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2002-2023, RDFLib Team -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/uno/lib/python/rdflib-6.3.2.dist-info/METADATA b/uno/lib/python/rdflib-6.3.2.dist-info/METADATA deleted file mode 100644 index 71486632..00000000 --- a/uno/lib/python/rdflib-6.3.2.dist-info/METADATA +++ /dev/null @@ -1,274 +0,0 @@ -Metadata-Version: 2.1 -Name: rdflib -Version: 6.3.2 -Summary: RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information. -Home-page: https://github.com/RDFLib/rdflib -License: BSD-3-Clause -Author: Daniel 'eikeon' Krech -Author-email: eikeon@eikeon.com -Maintainer: RDFLib Team -Maintainer-email: rdflib-dev@googlegroups.com -Requires-Python: >=3.7,<4.0 -Classifier: License :: OSI Approved :: BSD License -Classifier: Natural Language :: English -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Provides-Extra: berkeleydb -Provides-Extra: html -Provides-Extra: lxml -Provides-Extra: networkx -Requires-Dist: berkeleydb (>=18.1.0,<19.0.0) ; extra == "berkeleydb" -Requires-Dist: html5lib (>=1.0,<2.0) ; extra == "html" -Requires-Dist: importlib-metadata (>=4.0.0,<5.0.0) ; python_version >= "3.7" and python_version < "3.8" -Requires-Dist: isodate (>=0.6.0,<0.7.0) -Requires-Dist: lxml (>=4.3.0,<5.0.0) ; extra == "lxml" -Requires-Dist: networkx (>=2.0.0,<3.0.0) ; extra == "networkx" -Requires-Dist: pyparsing (>=2.1.0,<4) -Project-URL: Documentation, https://rdflib.readthedocs.org/ -Project-URL: Repository, https://github.com/RDFLib/rdflib -Description-Content-Type: text/markdown - -![](docs/_static/RDFlib.png) - -RDFLib -====== -[![Build Status](https://github.com/RDFLib/rdflib/actions/workflows/validate.yaml/badge.svg?branch=main)](https://github.com/RDFLib/rdflib/actions?query=branch%3Amain) -[![Documentation Status](https://readthedocs.org/projects/rdflib/badge/?version=latest)](https://rdflib.readthedocs.io/en/latest/?badge=latest) -[![Coveralls branch](https://img.shields.io/coveralls/RDFLib/rdflib/main.svg)](https://coveralls.io/r/RDFLib/rdflib?branch=main) - -[![GitHub stars](https://img.shields.io/github/stars/RDFLib/rdflib.svg)](https://github.com/RDFLib/rdflib/stargazers) -[![Downloads](https://pepy.tech/badge/rdflib/week)](https://pepy.tech/project/rdflib) -[![PyPI](https://img.shields.io/pypi/v/rdflib.svg)](https://pypi.python.org/pypi/rdflib) -[![PyPI](https://img.shields.io/pypi/pyversions/rdflib.svg)](https://pypi.python.org/pypi/rdflib) -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6845245.svg)](https://doi.org/10.5281/zenodo.6845245) - -[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/RDFLib/rdflib) -[![Gitter](https://badges.gitter.im/RDFLib/rdflib.svg)](https://gitter.im/RDFLib/rdflib?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[![Matrix](https://img.shields.io/matrix/rdflib:matrix.org?label=matrix.org%20chat)](https://matrix.to/#/#RDFLib_rdflib:gitter.im) - -RDFLib is a pure Python package for working with [RDF](http://www.w3.org/RDF/). RDFLib contains most things you need to work with RDF, including: - -* parsers and serializers for RDF/XML, N3, NTriples, N-Quads, Turtle, TriX, Trig and JSON-LD -* a Graph interface which can be backed by any one of a number of Store implementations -* store implementations for in-memory, persistent on disk (Berkeley DB) and remote SPARQL endpoints -* a SPARQL 1.1 implementation - supporting SPARQL 1.1 Queries and Update statements -* SPARQL function extension mechanisms - -## RDFlib Family of packages -The RDFlib community maintains many RDF-related Python code repositories with different purposes. For example: - -* [rdflib](https://github.com/RDFLib/rdflib) - the RDFLib core -* [sparqlwrapper](https://github.com/RDFLib/sparqlwrapper) - a simple Python wrapper around a SPARQL service to remotely execute your queries -* [pyLODE](https://github.com/RDFLib/pyLODE) - An OWL ontology documentation tool using Python and templating, based on LODE. -* [pyrdfa3](https://github.com/RDFLib/pyrdfa3) - RDFa 1.1 distiller/parser library: can extract RDFa 1.1/1.0 from (X)HTML, SVG, or XML in general. -* [pymicrodata](https://github.com/RDFLib/pymicrodata) - A module to extract RDF from an HTML5 page annotated with microdata. -* [pySHACL](https://github.com/RDFLib/pySHACL) - A pure Python module which allows for the validation of RDF graphs against SHACL graphs. -* [OWL-RL](https://github.com/RDFLib/OWL-RL) - A simple implementation of the OWL2 RL Profile which expands the graph with all possible triples that OWL RL defines. - -Please see the list for all packages/repositories here: - -* - -Help with maintenance of all of the RDFLib family of packages is always welcome and appreciated. - -## Versions & Releases - -* `6.4.0a0` current `main` branch -* `6.x.y` current release and support Python 3.7+ only. Many improvements over 5.0.0 - * see [Releases](https://github.com/RDFLib/rdflib/releases) -* `5.x.y` supports Python 2.7 and 3.4+ and is [mostly backwards compatible with 4.2.2](https://rdflib.readthedocs.io/en/stable/upgrade4to5.html). - -See for the release overview. - -## Documentation -See for our documentation built from the code. Note that there are `latest`, `stable` `5.0.0` and `4.2.2` documentation versions, matching releases. - -## Installation -The stable release of RDFLib may be installed with Python's package management tool *pip*: - - $ pip install rdflib - -Alternatively manually download the package from the Python Package -Index (PyPI) at https://pypi.python.org/pypi/rdflib - -The current version of RDFLib is 6.3.2, see the ``CHANGELOG.md`` file for what's new in this release. - -### Installation of the current main branch (for developers) - -With *pip* you can also install rdflib from the git repository with one of the following options: - - $ pip install git+https://github.com/rdflib/rdflib@main - -or - - $ pip install -e git+https://github.com/rdflib/rdflib@main#egg=rdflib - -or from your locally cloned repository you can install it with one of the following options: - - $ poetry install # installs into a poetry-managed venv - -or - - $ pip install -e . - -## Getting Started -RDFLib aims to be a pythonic RDF API. RDFLib's main data object is a `Graph` which is a Python collection -of RDF *Subject, Predicate, Object* Triples: - -To create graph and load it with RDF data from DBPedia then print the results: - -```python -from rdflib import Graph -g = Graph() -g.parse('http://dbpedia.org/resource/Semantic_Web') - -for s, p, o in g: - print(s, p, o) -``` -The components of the triples are URIs (resources) or Literals -(values). - -URIs are grouped together by *namespace*, common namespaces are included in RDFLib: - -```python -from rdflib.namespace import DC, DCTERMS, DOAP, FOAF, SKOS, OWL, RDF, RDFS, VOID, XMLNS, XSD -``` - -You can use them like this: - -```python -from rdflib import Graph, URIRef, Literal -from rdflib.namespace import RDFS, XSD - -g = Graph() -semweb = URIRef('http://dbpedia.org/resource/Semantic_Web') -type = g.value(semweb, RDFS.label) -``` -Where `RDFS` is the RDFS namespace, `XSD` the XML Schema Datatypes namespace and `g.value` returns an object of the triple-pattern given (or an arbitrary one if multiple exist). - -Or like this, adding a triple to a graph `g`: - -```python -g.add(( - URIRef("http://example.com/person/nick"), - FOAF.givenName, - Literal("Nick", datatype=XSD.string) -)) -``` -The triple (in n-triples notation) ` "Nick"^^ .` -is created where the property `FOAF.givenName` is the URI `` and `XSD.string` is the -URI ``. - -You can bind namespaces to prefixes to shorten the URIs for RDF/XML, Turtle, N3, TriG, TriX & JSON-LD serializations: - - ```python -g.bind("foaf", FOAF) -g.bind("xsd", XSD) -``` -This will allow the n-triples triple above to be serialised like this: - ```python -print(g.serialize(format="turtle")) -``` - -With these results: -```turtle -PREFIX foaf: -PREFIX xsd: - - foaf:givenName "Nick"^^xsd:string . -``` - -New Namespaces can also be defined: - -```python -dbpedia = Namespace('http://dbpedia.org/ontology/') - -abstracts = list(x for x in g.objects(semweb, dbpedia['abstract']) if x.language=='en') -``` - -See also [./examples](./examples) - - -## Features -The library contains parsers and serializers for RDF/XML, N3, -NTriples, N-Quads, Turtle, TriX, JSON-LD, RDFa and Microdata. - -The library presents a Graph interface which can be backed by -any one of a number of Store implementations. - -This core RDFLib package includes store implementations for -in-memory storage and persistent storage on top of the Berkeley DB. - -A SPARQL 1.1 implementation is included - supporting SPARQL 1.1 Queries and Update statements. - -RDFLib is open source and is maintained on [GitHub](https://github.com/RDFLib/rdflib/). RDFLib releases, current and previous -are listed on [PyPI](https://pypi.python.org/pypi/rdflib/) - -Multiple other projects are contained within the RDFlib "family", see . - -## Running tests - -### Running the tests on the host - -Run the test suite with `pytest`. -```shell -poetry install -poetry run pytest -``` - -### Running test coverage on the host with coverage report - -Run the test suite and generate a HTML coverage report with `pytest` and `pytest-cov`. -```shell -poetry run pytest --cov -``` - -### Viewing test coverage - -Once tests have produced HTML output of the coverage report, view it by running: -```shell -poetry run pytest --cov --cov-report term --cov-report html -python -m http.server --directory=htmlcov -``` - -## Contributing - -RDFLib survives and grows via user contributions! -Please read our [contributing guide](https://rdflib.readthedocs.io/en/latest/CONTRIBUTING.html) and [developers guide](https://rdflib.readthedocs.io/en/latest/developers.html) to get started. -Please consider lodging Pull Requests here: - -* - -To get a development environment consider using Gitpod or Google Cloud Shell. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/RDFLib/rdflib) -[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.svg)](https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FRDFLib%2Frdflib&cloudshell_git_branch=main&cloudshell_open_in_editor=README.md) - -You can also raise issues here: - -* - -## Support & Contacts -For general "how do I..." queries, please use https://stackoverflow.com and tag your question with `rdflib`. -Existing questions: - -* - -If you want to contact the rdflib maintainers, please do so via: - -* the rdflib-dev mailing list: -* the chat, which is available at [gitter](https://gitter.im/RDFLib/rdflib) or via matrix [#RDFLib_rdflib:gitter.im](https://matrix.to/#/#RDFLib_rdflib:gitter.im) - diff --git a/uno/lib/python/rdflib-6.3.2.dist-info/RECORD b/uno/lib/python/rdflib-6.3.2.dist-info/RECORD deleted file mode 100644 index b4d50d97..00000000 --- a/uno/lib/python/rdflib-6.3.2.dist-info/RECORD +++ /dev/null @@ -1,124 +0,0 @@ -rdflib/__init__.py,sha256=r4RJPZfS-y8tkweqi3VMShVovZuoXIOX-sTJ5KUQ9hM,4914 -rdflib/_type_checking.py,sha256=QOCqprG-RTEIsIT3YgtGEx712nWDhEXgnAFIRJe2Qug,1032 -rdflib/collection.py,sha256=FPyEPSEdw4eDfh2jUeXyUQXulcDh8GvVJ6DpmlbI6Fk,9771 -rdflib/compare.py,sha256=-Vup5uIfARfTqqv3xLq8fua7Zv39vNM80fKi0tGetDg,22033 -rdflib/compat.py,sha256=hjTBPb0Uj5ZFo5p8cx0ZQOQy4IfN8yKdHZ10Wrq9VcY,2325 -rdflib/container.py,sha256=KRdoRNmM6fnBosgA96oVdZPRYa9JYxXFDAmkIArngi8,7925 -rdflib/events.py,sha256=8ZUgsDE_H47Xt6eQl7eqzFzp4W8LRiAmeVexbPRj_5Q,2615 -rdflib/exceptions.py,sha256=OALbblWjlXLEBn2nNKiCvm24Ke3boPLA5fcojvlztW8,814 -rdflib/extras/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24 -rdflib/extras/cmdlineutils.py,sha256=n-eqTrZ9U_fQPGCK0zUrT2cXIScQ6oRhoo3JyUnOfaw,1829 -rdflib/extras/describer.py,sha256=5thYfQJKZCZJIBeO_YvcZIZ-S-pFJ5-LQegEcr0INCI,9354 -rdflib/extras/external_graph_libs.py,sha256=k5utYzGMdIhik3RFXMixjUYBbAAfxOQBRqZmPTBK-Wo,12029 -rdflib/extras/infixowl.py,sha256=sEgs7DmndFmSQ1UIwd5Tfi1Kvp33umINd2FEWsB0ajQ,76908 -rdflib/graph.py,sha256=x8M0HcOd0awpWGstQ-GA5HkwUKqJzBp90RmPmIDx1wE,108827 -rdflib/namespace/_BRICK.py,sha256=fQpcoCALN1-rZykCAwz5VdypbkEqbXRuSCvvh45uBgQ,123998 -rdflib/namespace/_CSVW.py,sha256=XtQKdk8Vxl5if2Wzl4p0fuuo9rzZM_zFlpfMWoyK2a4,12928 -rdflib/namespace/_DC.py,sha256=IU9RWUmoTvDEL9_wv4jLCmYlEE3FX291cPax0imfV7Y,1641 -rdflib/namespace/_DCAM.py,sha256=JxvGJe95380fDIvZsgUhIGYGI9aIF7aF_4hf6RjY63Y,887 -rdflib/namespace/_DCAT.py,sha256=ltjH9-wp2TyrEMVvo6lX03GBCqlTwrUuTvUxw9D3TiU,5442 -rdflib/namespace/_DCMITYPE.py,sha256=MC2f0ChRgWho8hS9Rv1dGO3LY_g1WP1WPkwcYfh6d6c,1337 -rdflib/namespace/_DCTERMS.py,sha256=8LCPDwZx_K8I-nk5WEezehfun6z6OFYdHn8r4tC8H2A,9884 -rdflib/namespace/_DOAP.py,sha256=qBbPU-rL80ZJIkbTW1wgq8EtaHLaY6LiXbZXTtNzckk,3873 -rdflib/namespace/_FOAF.py,sha256=rT0zvxAjM6B6l9eDqwH8XMhAaz2ySA1YesrSGO1ROqg,6199 -rdflib/namespace/_GEO.py,sha256=IfBBhOPjH3SJSAOkE_JYKjHsAbn2hZoIn3rSd3gDD9Q,6551 -rdflib/namespace/_ODRL2.py,sha256=_T_TB2UTl2i7pssXZK8ecuC6nJlRoI2SHPmafYg_brI,21998 -rdflib/namespace/_ORG.py,sha256=zhobrfzEmjam_W0JeZKKJxIcvID3SE1TcWKjrD8CIuo,13207 -rdflib/namespace/_OWL.py,sha256=-uG0FXSjNPGLBUJZ9xX7nCo1dCvJ4T7AtGrDkOQFX3w,10352 -rdflib/namespace/_PROF.py,sha256=QKYhG7ulMe_6wKS5Ye6FZ_oghKeVmo7Qdcupk7vMlyQ,2807 -rdflib/namespace/_PROV.py,sha256=5dkEWKeGRibu-gWFI3WtML1Bg1lzN4Ui7j_xH80ejfo,24068 -rdflib/namespace/_QB.py,sha256=RVXs0-XUHjQbSfyJm-T3mxYuZSnzQFgmfOygklFdCis,5381 -rdflib/namespace/_RDF.py,sha256=icPqdMkOC1ukMJDyGFR6nWdC7KsMp1cuHX2_587SXnc,2249 -rdflib/namespace/_RDFS.py,sha256=Gw0zTb0B0VTn2pvwI3bQYEqjH91JguG_XSy3den7DDA,1488 -rdflib/namespace/_SDO.py,sha256=YgYfLhwfCoxZIjvJaRDmOW7VweMqRCMzTylddjXJJv0,420221 -rdflib/namespace/_SH.py,sha256=3mxc7QrOhxsvAe0Ys_awGnT_atKyxWaDZ_ECbwDI9ZM,23033 -rdflib/namespace/_SKOS.py,sha256=yYiRT62_AplpN5IosRkkP7JdPbmm4hp0sl3ZmhPp7qc,4635 -rdflib/namespace/_SOSA.py,sha256=Imck98BrRVRrOgtCetqOOjmfi4wpFHIZkUOi11Rkp_A,6261 -rdflib/namespace/_SSN.py,sha256=sbJN_bIMYAI-cEYWg5NIt5Z29rHlS4Ee4fEsfAFXFcE,3197 -rdflib/namespace/_TIME.py,sha256=sClbp9BOR3-9BlNcA798HhxJ7ENWluUZPV0R2VuqBLs,12888 -rdflib/namespace/_VANN.py,sha256=pKantDMzEu_wfOFT7zXYIhFlsgTJu_ylgv5PCpRGLJE,1232 -rdflib/namespace/_VOID.py,sha256=_5e4fX7Io-Hbl4AxRapoTbZuug-Ob2xURoS_LUH-5WI,4641 -rdflib/namespace/_WGS.py,sha256=riNm_SfY5qLMjI4gLGgFi0LKsO1bingDenMYkLhSIfk,635 -rdflib/namespace/_XSD.py,sha256=IYTGG82-8RKQIrwcPNPGCGlDxK3Pyx0C6l4PdfkivdY,6196 -rdflib/namespace/__init__.py,sha256=7nKf2pvBSEFVQjini2BYT1GHk7YRcYdrDojSgF11gBE,31879 -rdflib/parser.py,sha256=6-7kN6zoS3rvVX7nNhYx91KpMemi1daF82Ag1WhNhx8,16454 -rdflib/paths.py,sha256=eK5sfrr7zTrph6Co82eV5OKSN1HrWuNVR9mz6c1X-fs,21875 -rdflib/plugin.py,sha256=FdEQnZYmnmbKeeav9EQz7NrI8WFWOCE0NivGv5X3Hus,12863 -rdflib/plugins/__init__.py,sha256=39nGkLLAy54hfMDO9jCpUoaAcVeDdmKCKB3xRQ7KnkA,111 -rdflib/plugins/parsers/RDFVOC.py,sha256=k_IsOaBkCeR_bKlxk_jPz36S_-5f5ha5FKdGP3iapXw,439 -rdflib/plugins/parsers/__init__.py,sha256=ekSQ4YBr0bT86j5BplDSgH-SoHHF3gZP_xShRG6Z6Dk,9 -rdflib/plugins/parsers/hext.py,sha256=lqXFVUs_G3EF2jIOS3vAu36ch0DfCRJFE9gnMczu9ws,4182 -rdflib/plugins/parsers/jsonld.py,sha256=tqFCMFhaSAh7KHLUfeRihN4u7XLLQsx8Qj-PoBRgJQ4,20467 -rdflib/plugins/parsers/notation3.py,sha256=750JeXldlK4pQUeN3dQL3urfGjaSOwyIUvBvX4Pc-kw,67246 -rdflib/plugins/parsers/nquads.py,sha256=DMzVF0NzzGqHjXWTUDTd1cFU9n3veSBwQvC2TigQnmE,4288 -rdflib/plugins/parsers/ntriples.py,sha256=PkbfjGh-rRE-7IrPBZXjSthFZJ9sTu4OWnH-bID69Q4,12420 -rdflib/plugins/parsers/rdfxml.py,sha256=qAKPmkpZ3mqWYrRyw5hJDkxkpPaOTCgazqjX-LRoqVs,25263 -rdflib/plugins/parsers/trig.py,sha256=8SYeBtxHQURvkvLtXQmY6Er1f4lY9ilaYitisWnlOOQ,5102 -rdflib/plugins/parsers/trix.py,sha256=eIeMWe7CfAqEYiAR5epM0e-oA3CH-CJxZhYOvdVo6hs,9622 -rdflib/plugins/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -rdflib/plugins/serializers/hext.py,sha256=Q8YfKgVxVQkOFSWcfz5UQRp1_K7E0OPJ6wfXCEwB8-8,4701 -rdflib/plugins/serializers/jsonld.py,sha256=7-z5eJWdumas5HSX-jswH6iYFwvrPg2NqAWs7PflxLE,12575 -rdflib/plugins/serializers/longturtle.py,sha256=DriSg4DKfCt-OdGnT27HKDs7togXcYJkVQa6avvriSc,9593 -rdflib/plugins/serializers/n3.py,sha256=vD-tXiNPvjaGYsatfAxocoSFcQo76ZyZFMFcVe0Cx_c,2896 -rdflib/plugins/serializers/nquads.py,sha256=gF47Hj7IFQSM_rjyceIZ5N3TDiE5GnHeeHvKubbFl8Q,1781 -rdflib/plugins/serializers/nt.py,sha256=XzmG8YOm5YkHa4yk8qDbfA1BMm5KFlfKz22Bnlp8DE8,3314 -rdflib/plugins/serializers/rdfxml.py,sha256=ZtqemqDVkfll0hs2HOYYXiK7WIXIppuhUbrXUuF8M3s,13539 -rdflib/plugins/serializers/trig.py,sha256=zrzScgZpQYuC7rMa-NzJ7NpUTzBKH1CUEVOlng_wqiE,3850 -rdflib/plugins/serializers/trix.py,sha256=sGvoisA26j54MgH2hTSp6kfZIZwjct2uaxghNzBEg_E,3345 -rdflib/plugins/serializers/turtle.py,sha256=fqZbx8S86m-UD53HvqKQFtnK7uelHdp58QFMgWH1WWY,13867 -rdflib/plugins/serializers/xmlwriter.py,sha256=_cxXNWnu9J-diM7uoBGnEqBHELRJcVxLbUGxL_s37mQ,3367 -rdflib/plugins/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -rdflib/plugins/shared/jsonld/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -rdflib/plugins/shared/jsonld/context.py,sha256=WP92fhKIe-VWYH83uqyXOjXtAcf4PMZVs6z3U7hBWeg,21891 -rdflib/plugins/shared/jsonld/errors.py,sha256=PvGcGPapJCWN-xTQOmRDtkA2YQcywFCYdsCUk3S_2z8,445 -rdflib/plugins/shared/jsonld/keys.py,sha256=O0QRWObHQ8_4RpcmSMoAKkH3b4DTzw3Oo40bSk4aYOM,558 -rdflib/plugins/shared/jsonld/util.py,sha256=rCxJ8zt5L9PzYRSbUuo8ndjh9-iNGYpqQrPOJgvFc9Q,4102 -rdflib/plugins/sparql/__init__.py,sha256=NxQ5qTbaZcEQ9Ddf86RgFCPG6TMeuXq5hIWITGOba3o,1512 -rdflib/plugins/sparql/aggregates.py,sha256=6q5DclOi2qtlG9H7IcvdiJEJKqEFdwt-GAtRPAj0ic4,10366 -rdflib/plugins/sparql/algebra.py,sha256=-YH5WJqlcQdUMrE3N0L4gtaYCk845uKOLw7klJ6JN48,59105 -rdflib/plugins/sparql/datatypes.py,sha256=Q9E1iP7Qt2KlIT_EjSsHkYjhz8uR472NRwpFGc8LoNc,2546 -rdflib/plugins/sparql/evaluate.py,sha256=yaaGGoaSWsAiNU9w5lt7dz8O0cp-br-DJ95SHxUGzLM,22207 -rdflib/plugins/sparql/evalutils.py,sha256=pNEuuJ3G0QeMKjRgEhJBHif2hyPJEYlK9KwLkSx0_WY,4924 -rdflib/plugins/sparql/operators.py,sha256=rOC3IHN4Hv0Yx4mj7TwLx92PpLg8DqBViIjJmbXV_MA,36673 -rdflib/plugins/sparql/parser.py,sha256=Acggx5pwLtto-gDcxojiscgi1wtYYZ7WoPyYrAgcmyA,51216 -rdflib/plugins/sparql/parserutils.py,sha256=mP1weVQnEnTtm6kufPW2KJpPYafIRiuWAXs6G2vyGcQ,9214 -rdflib/plugins/sparql/processor.py,sha256=FCRU1NWDydjTXYcz_xfd3CVbtIeU04JzYG1h0v_4Xhg,4809 -rdflib/plugins/sparql/results/__init__.py,sha256=4N9RA47kn1q0uOiRJddc_TpU9tiibuoq2pmUG2dio18,58 -rdflib/plugins/sparql/results/csvresults.py,sha256=TyiVdZvp6sXCEHQdFU5VYq35O5YYSuPZWD548kPLGwA,3328 -rdflib/plugins/sparql/results/graph.py,sha256=6slf96keAyM3w0stGN9jdJQl2xnPnYSrOv5AcqTX9QQ,530 -rdflib/plugins/sparql/results/jsonresults.py,sha256=TvPiIJQVT-sLp05gjdn41FkHpGLNX4BL4CTUHHZkCGs,4365 -rdflib/plugins/sparql/results/rdfresults.py,sha256=cDet4nnhObu84newOaCTvSSDuoQjE2aNu3xGZgtU2bE,2744 -rdflib/plugins/sparql/results/tsvresults.py,sha256=A1wc7Q6drXAi1fUgLmIxYWpO5rNLZJWpxPaHXFVqvx0,3105 -rdflib/plugins/sparql/results/txtresults.py,sha256=r9KERRdMeafxK3EufGY6yHgrSqriJcyXsC_5GnrphMk,3014 -rdflib/plugins/sparql/results/xmlresults.py,sha256=IHnAiUlyTxaoI5djl8HL__IBOLzxe_fcJdecnTFtEqg,12171 -rdflib/plugins/sparql/sparql.py,sha256=myNPTGY2s0hyrh2JqGX36LnA-5ZCL3rcDfN3rvV-U6w,14204 -rdflib/plugins/sparql/update.py,sha256=gJsD_0KXOwoRzmVC1fIjnaWykLeTfi92er_RmENyT9A,11476 -rdflib/plugins/stores/__init__.py,sha256=NGddME-fuVX1SBSkNld2FBLchmKR8rNs5mi3EL3Top8,67 -rdflib/plugins/stores/auditable.py,sha256=cofyzSi31XYvNooiYPSuOsTFlxUAKTo6EBF5e2_0PDs,7878 -rdflib/plugins/stores/berkeleydb.py,sha256=GmMNiT5GJ8ZuZr4HTTJrfkVaXtj4OS6vJODHrgPI7ds,29955 -rdflib/plugins/stores/concurrent.py,sha256=svTI4ucVXhBpOs9Kt0fdkdwkgIAs1bgnX0MFq2rdfqs,2721 -rdflib/plugins/stores/memory.py,sha256=zJeh2y_UfRwPeNnIP3LQch686cujmPDy3SrLq9ONb4M,30220 -rdflib/plugins/stores/regexmatching.py,sha256=kWEIO54loxTH8jQmLgVea-SRYbE1rPc-J9yCMwK8aQY,6495 -rdflib/plugins/stores/sparqlconnector.py,sha256=LSJvlp_MHizb_LieZv9564xCdUuXBLkJ7K61jWJF6yY,6408 -rdflib/plugins/stores/sparqlstore.py,sha256=l6kXcC3NU96ar1X3Av4RJdLD5dwB5_eINfqNOfjVl3Q,39745 -rdflib/py.typed,sha256=KT9WNyn4878ZisihNjjF3Bm2qu8R9s2F5irJrg8vxhQ,66 -rdflib/query.py,sha256=pbk3AyJQW6q-vxnrYyoBSl09b-UgXYKfCwNMZ5uuCZ8,15015 -rdflib/resource.py,sha256=ieGTLR9--4dRhDt9Bv7Vn1IyNaAWp066Fv2NLTSOHqc,14016 -rdflib/serializer.py,sha256=ro9br9F_qyvlGXSVPczyxR7j4SlYAS4hjEulRZMpJcQ,1312 -rdflib/store.py,sha256=AvBG6vFFat5VDtQXADC3dONqWXhYhXBbZ9q65S8XDHY,16087 -rdflib/term.py,sha256=l3Zo0r5i2hsgHHikwcy7Ok8BPcxrdV-TIXC39DwLTbU,85774 -rdflib/tools/__init__.py,sha256=YzY7Eyz4zw8Ib5fl5bv4bQXzbAbsVxa2LrybTtJDYw0,58 -rdflib/tools/chunk_serializer.py,sha256=yfUqLuzzbHeTfVfqPigyNbMy3DqOcschLsbsGKzrBBY,4794 -rdflib/tools/csv2rdf.py,sha256=A9MVhGcNnI02NQiXemffXrVAm2G51dMSBsST0wrY5yY,14901 -rdflib/tools/defined_namespace_creator.py,sha256=4KnN-oHbyXxfq1M9sH8tPiX2wr_Lda06BsE3fzUVEvY,6121 -rdflib/tools/graphisomorphism.py,sha256=XZuTVFRmbDdYwMro9ODUdmEAU7k01GDT-vl178OgQL4,3369 -rdflib/tools/rdf2dot.py,sha256=J6cB3Zn901viwDSJqpIWFh5n0ovcQEgLwzbpwaAsVdw,4184 -rdflib/tools/rdfpipe.py,sha256=4OoqtQveONH1HsxEr408sc7BNFrEmu2GovJoCiWW63I,5428 -rdflib/tools/rdfs2dot.py,sha256=kO9I-oMB4vmSfWP95R-gc0myphT7TKsu3OVjcYnxjDQ,3655 -rdflib/util.py,sha256=9b49N9GsdI45p09Vh-KqqNa8P1PB0a4upaT9DWKwjSk,17625 -rdflib/void.py,sha256=mqZWOnX8rTCJgtVN4rvEiehSEpt_yUsaQpGilY0G5jE,4159 -rdflib-6.3.2.dist-info/LICENSE,sha256=QLs8x8_kSarESidSixxxoZrGSCfW5n-YnnJVl1rHk9A,1524 -rdflib-6.3.2.dist-info/METADATA,sha256=km_cUCfi2a_TOwy4k3XqBIDmN7dj2mr0lR1aUKe7KAY,11572 -rdflib-6.3.2.dist-info/WHEEL,sha256=kLuE8m1WYU0Ig0_YEGrXyTtiJvKPpLpDEiChiNyei5Y,88 -rdflib-6.3.2.dist-info/entry_points.txt,sha256=UJ2UwT8m9TvV7UrdJM2fcEREwExL_RQVEfnID-Qnkdk,212 -rdflib-6.3.2.dist-info/RECORD,, diff --git a/uno/lib/python/rdflib-6.3.2.dist-info/WHEEL b/uno/lib/python/rdflib-6.3.2.dist-info/WHEEL deleted file mode 100644 index 9f287336..00000000 --- a/uno/lib/python/rdflib-6.3.2.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: poetry-core 1.5.1 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/uno/lib/python/rdflib-6.3.2.dist-info/entry_points.txt b/uno/lib/python/rdflib-6.3.2.dist-info/entry_points.txt deleted file mode 100644 index e2543c7d..00000000 --- a/uno/lib/python/rdflib-6.3.2.dist-info/entry_points.txt +++ /dev/null @@ -1,7 +0,0 @@ -[console_scripts] -csv2rdf=rdflib.tools.csv2rdf:main -rdf2dot=rdflib.tools.rdf2dot:main -rdfgraphisomorphism=rdflib.tools.graphisomorphism:main -rdfpipe=rdflib.tools.rdfpipe:main -rdfs2dot=rdflib.tools.rdfs2dot:main - diff --git a/uno/lib/python/rdflib/__init__.py b/uno/lib/python/rdflib/__init__.py index 0a7610f3..9b9f34d8 100644 --- a/uno/lib/python/rdflib/__init__.py +++ b/uno/lib/python/rdflib/__init__.py @@ -45,17 +45,18 @@ import logging import sys -if sys.version_info < (3, 8): - # importlib is only available in Python 3.8+; for 3.7 we must do this: - import importlib_metadata as metadata -else: - from importlib import metadata +#if sys.version_info < (3, 8): +# # importlib is only available in Python 3.8+; for 3.7 we must do this: +# import importlib_metadata as metadata +#else: +# from importlib import metadata -_DISTRIBUTION_METADATA = metadata.metadata("rdflib") +#_DISTRIBUTION_METADATA = metadata.metadata("rdflib") __docformat__ = "restructuredtext en" -__version__: str = _DISTRIBUTION_METADATA["Version"] +#__version__: str = _DISTRIBUTION_METADATA["Version"] +__version__ = "7.0.0" __date__ = "2023-03-26" __all__ = [ diff --git a/uno/lib/python/setuptools/__init__.py b/uno/lib/python/setuptools/__init__.py index 35d7bd1c..563ca1c4 100644 --- a/uno/lib/python/setuptools/__init__.py +++ b/uno/lib/python/setuptools/__init__.py @@ -5,22 +5,18 @@ import re import _distutils_hack.override # noqa: F401 - import distutils.core from distutils.errors import DistutilsOptionError from distutils.util import convert_path as _convert_path +from . import logging, monkey +from . import version as _version_module +from .depends import Require +from .discovery import PackageFinder, PEP420PackageFinder +from .dist import Distribution +from .extension import Extension from .warnings import SetuptoolsDeprecationWarning -import setuptools.version -from setuptools.extension import Extension -from setuptools.dist import Distribution -from setuptools.depends import Require -from setuptools.discovery import PackageFinder, PEP420PackageFinder -from . import monkey -from . import logging - - __all__ = [ 'setup', 'Distribution', @@ -32,7 +28,7 @@ 'find_namespace_packages', ] -__version__ = setuptools.version.__version__ +__version__ = _version_module.__version__ bootstrap_install_from = None @@ -257,7 +253,7 @@ def convert_path(pathname): Its direct usage by 3rd-party packages is considered improper and the function may be removed in the future. """, - due_date=(2023, 12, 13) # initial deprecation 2022-03-25, see #3201 + due_date=(2023, 12, 13), # initial deprecation 2022-03-25, see #3201 ) return _convert_path(pathname) diff --git a/uno/lib/python/setuptools/_core_metadata.py b/uno/lib/python/setuptools/_core_metadata.py new file mode 100644 index 00000000..6c904c3c --- /dev/null +++ b/uno/lib/python/setuptools/_core_metadata.py @@ -0,0 +1,258 @@ +""" +Handling of Core Metadata for Python packages (including reading and writing). + +See: https://packaging.python.org/en/latest/specifications/core-metadata/ +""" +import os +import stat +import textwrap +from email import message_from_file +from email.message import Message +from tempfile import NamedTemporaryFile +from typing import Optional, List + +from distutils.util import rfc822_escape + +from . import _normalization, _reqs +from .extern.packaging.markers import Marker +from .extern.packaging.requirements import Requirement +from .extern.packaging.version import Version +from .warnings import SetuptoolsDeprecationWarning + + +def get_metadata_version(self): + mv = getattr(self, 'metadata_version', None) + if mv is None: + mv = Version('2.1') + self.metadata_version = mv + return mv + + +def rfc822_unescape(content: str) -> str: + """Reverse RFC-822 escaping by removing leading whitespaces from content.""" + lines = content.splitlines() + if len(lines) == 1: + return lines[0].lstrip() + return '\n'.join((lines[0].lstrip(), textwrap.dedent('\n'.join(lines[1:])))) + + +def _read_field_from_msg(msg: Message, field: str) -> Optional[str]: + """Read Message header field.""" + value = msg[field] + if value == 'UNKNOWN': + return None + return value + + +def _read_field_unescaped_from_msg(msg: Message, field: str) -> Optional[str]: + """Read Message header field and apply rfc822_unescape.""" + value = _read_field_from_msg(msg, field) + if value is None: + return value + return rfc822_unescape(value) + + +def _read_list_from_msg(msg: Message, field: str) -> Optional[List[str]]: + """Read Message header field and return all results as list.""" + values = msg.get_all(field, None) + if values == []: + return None + return values + + +def _read_payload_from_msg(msg: Message) -> Optional[str]: + value = msg.get_payload().strip() + if value == 'UNKNOWN' or not value: + return None + return value + + +def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = message_from_file(file) + + self.metadata_version = Version(msg['metadata-version']) + self.name = _read_field_from_msg(msg, 'name') + self.version = _read_field_from_msg(msg, 'version') + self.description = _read_field_from_msg(msg, 'summary') + # we are filling author only. + self.author = _read_field_from_msg(msg, 'author') + self.maintainer = None + self.author_email = _read_field_from_msg(msg, 'author-email') + self.maintainer_email = None + self.url = _read_field_from_msg(msg, 'home-page') + self.download_url = _read_field_from_msg(msg, 'download-url') + self.license = _read_field_unescaped_from_msg(msg, 'license') + + self.long_description = _read_field_unescaped_from_msg(msg, 'description') + if self.long_description is None and self.metadata_version >= Version('2.1'): + self.long_description = _read_payload_from_msg(msg) + self.description = _read_field_from_msg(msg, 'summary') + + if 'keywords' in msg: + self.keywords = _read_field_from_msg(msg, 'keywords').split(',') + + self.platforms = _read_list_from_msg(msg, 'platform') + self.classifiers = _read_list_from_msg(msg, 'classifier') + + # PEP 314 - these fields only exist in 1.1 + if self.metadata_version == Version('1.1'): + self.requires = _read_list_from_msg(msg, 'requires') + self.provides = _read_list_from_msg(msg, 'provides') + self.obsoletes = _read_list_from_msg(msg, 'obsoletes') + else: + self.requires = None + self.provides = None + self.obsoletes = None + + self.license_files = _read_list_from_msg(msg, 'license-file') + + +def single_line(val): + """ + Quick and dirty validation for Summary pypa/setuptools#1390. + """ + if '\n' in val: + # TODO: Replace with `raise ValueError("newlines not allowed")` + # after reviewing #2893. + msg = "newlines are not allowed in `summary` and will break in the future" + SetuptoolsDeprecationWarning.emit("Invalid config.", msg) + # due_date is undefined. Controversial change, there was a lot of push back. + val = val.strip().split('\n')[0] + return val + + +def write_pkg_info(self, base_dir): + """Write the PKG-INFO file into the release tree.""" + temp = "" + final = os.path.join(base_dir, 'PKG-INFO') + try: + # Use a temporary file while writing to avoid race conditions + # (e.g. `importlib.metadata` reading `.egg-info/PKG-INFO`): + with NamedTemporaryFile("w", encoding="utf-8", dir=base_dir, delete=False) as f: + temp = f.name + self.write_pkg_file(f) + permissions = stat.S_IMODE(os.lstat(temp).st_mode) + os.chmod(temp, permissions | stat.S_IRGRP | stat.S_IROTH) + os.replace(temp, final) # atomic operation. + finally: + if temp and os.path.exists(temp): + os.remove(temp) + + +# Based on Python 3.5 version +def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME + """Write the PKG-INFO format data to a file object.""" + version = self.get_metadata_version() + + def write_field(key, value): + file.write("%s: %s\n" % (key, value)) + + write_field('Metadata-Version', str(version)) + write_field('Name', self.get_name()) + write_field('Version', self.get_version()) + + summary = self.get_description() + if summary: + write_field('Summary', single_line(summary)) + + optional_fields = ( + ('Home-page', 'url'), + ('Download-URL', 'download_url'), + ('Author', 'author'), + ('Author-email', 'author_email'), + ('Maintainer', 'maintainer'), + ('Maintainer-email', 'maintainer_email'), + ) + + for field, attr in optional_fields: + attr_val = getattr(self, attr, None) + if attr_val is not None: + write_field(field, attr_val) + + license = self.get_license() + if license: + write_field('License', rfc822_escape(license)) + + for project_url in self.project_urls.items(): + write_field('Project-URL', '%s, %s' % project_url) + + keywords = ','.join(self.get_keywords()) + if keywords: + write_field('Keywords', keywords) + + platforms = self.get_platforms() or [] + for platform in platforms: + write_field('Platform', platform) + + self._write_list(file, 'Classifier', self.get_classifiers()) + + # PEP 314 + self._write_list(file, 'Requires', self.get_requires()) + self._write_list(file, 'Provides', self.get_provides()) + self._write_list(file, 'Obsoletes', self.get_obsoletes()) + + # Setuptools specific for PEP 345 + if hasattr(self, 'python_requires'): + write_field('Requires-Python', self.python_requires) + + # PEP 566 + if self.long_description_content_type: + write_field('Description-Content-Type', self.long_description_content_type) + + self._write_list(file, 'License-File', self.license_files or []) + _write_requirements(self, file) + + long_description = self.get_long_description() + if long_description: + file.write("\n%s" % long_description) + if not long_description.endswith("\n"): + file.write("\n") + + +def _write_requirements(self, file): + for req in _reqs.parse(self.install_requires): + file.write(f"Requires-Dist: {req}\n") + + processed_extras = {} + for augmented_extra, reqs in self.extras_require.items(): + # Historically, setuptools allows "augmented extras": `:` + unsafe_extra, _, condition = augmented_extra.partition(":") + unsafe_extra = unsafe_extra.strip() + extra = _normalization.safe_extra(unsafe_extra) + + if extra: + _write_provides_extra(file, processed_extras, extra, unsafe_extra) + for req in _reqs.parse_strings(reqs): + r = _include_extra(req, extra, condition.strip()) + file.write(f"Requires-Dist: {r}\n") + + return processed_extras + + +def _include_extra(req: str, extra: str, condition: str) -> Requirement: + r = Requirement(req) # create a fresh object that can be modified + parts = ( + f"({r.marker})" if r.marker else None, + f"({condition})" if condition else None, + f"extra == {extra!r}" if extra else None, + ) + r.marker = Marker(" and ".join(x for x in parts if x)) + return r + + +def _write_provides_extra(file, processed_extras, safe, unsafe): + previous = processed_extras.get(safe) + if previous == unsafe: + SetuptoolsDeprecationWarning.emit( + 'Ambiguity during "extra" normalization for dependencies.', + f""" + {previous!r} and {unsafe!r} normalize to the same value:\n + {safe!r}\n + In future versions, setuptools might halt the build process. + """, + see_url="https://peps.python.org/pep-0685/", + ) + else: + processed_extras[safe] = unsafe + file.write(f"Provides-Extra: {safe}\n") diff --git a/uno/lib/python/setuptools/_distutils/_functools.py b/uno/lib/python/setuptools/_distutils/_functools.py index e7053bac..e03365ea 100644 --- a/uno/lib/python/setuptools/_distutils/_functools.py +++ b/uno/lib/python/setuptools/_distutils/_functools.py @@ -1,3 +1,4 @@ +import collections.abc import functools @@ -18,3 +19,55 @@ def wrapper(param, *args, **kwargs): return func(param, *args, **kwargs) return wrapper + + +# from jaraco.functools 4.0 +@functools.singledispatch +def _splat_inner(args, func): + """Splat args to func.""" + return func(*args) + + +@_splat_inner.register +def _(args: collections.abc.Mapping, func): + """Splat kargs to func as kwargs.""" + return func(**args) + + +def splat(func): + """ + Wrap func to expect its parameters to be passed positionally in a tuple. + + Has a similar effect to that of ``itertools.starmap`` over + simple ``map``. + + >>> import itertools, operator + >>> pairs = [(-1, 1), (0, 2)] + >>> _ = tuple(itertools.starmap(print, pairs)) + -1 1 + 0 2 + >>> _ = tuple(map(splat(print), pairs)) + -1 1 + 0 2 + + The approach generalizes to other iterators that don't have a "star" + equivalent, such as a "starfilter". + + >>> list(filter(splat(operator.add), pairs)) + [(0, 2)] + + Splat also accepts a mapping argument. + + >>> def is_nice(msg, code): + ... return "smile" in msg or code == 0 + >>> msgs = [ + ... dict(msg='smile!', code=20), + ... dict(msg='error :(', code=1), + ... dict(msg='unknown', code=0), + ... ] + >>> for msg in filter(splat(is_nice), msgs): + ... print(msg) + {'msg': 'smile!', 'code': 20} + {'msg': 'unknown', 'code': 0} + """ + return functools.wraps(func)(functools.partial(_splat_inner, func=func)) diff --git a/uno/lib/python/setuptools/_distutils/_modified.py b/uno/lib/python/setuptools/_distutils/_modified.py new file mode 100644 index 00000000..fbb95a8f --- /dev/null +++ b/uno/lib/python/setuptools/_distutils/_modified.py @@ -0,0 +1,72 @@ +"""Timestamp comparison of files and groups of files.""" + +import functools +import os.path + +from .errors import DistutilsFileError +from .py39compat import zip_strict +from ._functools import splat + + +def _newer(source, target): + return not os.path.exists(target) or ( + os.path.getmtime(source) > os.path.getmtime(target) + ) + + +def newer(source, target): + """ + Is source modified more recently than target. + + Returns True if 'source' is modified more recently than + 'target' or if 'target' does not exist. + + Raises DistutilsFileError if 'source' does not exist. + """ + if not os.path.exists(source): + raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(source)) + + return _newer(source, target) + + +def newer_pairwise(sources, targets, newer=newer): + """ + Filter filenames where sources are newer than targets. + + Walk two filename iterables in parallel, testing if each source is newer + than its corresponding target. Returns a pair of lists (sources, + targets) where source is newer than target, according to the semantics + of 'newer()'. + """ + newer_pairs = filter(splat(newer), zip_strict(sources, targets)) + return tuple(map(list, zip(*newer_pairs))) or ([], []) + + +def newer_group(sources, target, missing='error'): + """ + Is target out-of-date with respect to any file in sources. + + Return True if 'target' is out-of-date with respect to any file + listed in 'sources'. In other words, if 'target' exists and is newer + than every file in 'sources', return False; otherwise return True. + ``missing`` controls how to handle a missing source file: + + - error (default): allow the ``stat()`` call to fail. + - ignore: silently disregard any missing source files. + - newer: treat missing source files as "target out of date". This + mode is handy in "dry-run" mode: it will pretend to carry out + commands that wouldn't work because inputs are missing, but + that doesn't matter because dry-run won't run the commands. + """ + + def missing_as_newer(source): + return missing == 'newer' and not os.path.exists(source) + + ignored = os.path.exists if missing == 'ignore' else None + return any( + missing_as_newer(source) or _newer(source, target) + for source in filter(ignored, sources) + ) + + +newer_pairwise_group = functools.partial(newer_pairwise, newer=newer_group) diff --git a/uno/lib/python/setuptools/_distutils/bcppcompiler.py b/uno/lib/python/setuptools/_distutils/bcppcompiler.py index ba45ea2b..3c2ba154 100644 --- a/uno/lib/python/setuptools/_distutils/bcppcompiler.py +++ b/uno/lib/python/setuptools/_distutils/bcppcompiler.py @@ -24,7 +24,7 @@ ) from .ccompiler import CCompiler, gen_preprocess_options from .file_util import write_file -from .dep_util import newer +from ._modified import newer from ._log import log diff --git a/uno/lib/python/setuptools/_distutils/ccompiler.py b/uno/lib/python/setuptools/_distutils/ccompiler.py index 1818fce9..c1c7d547 100644 --- a/uno/lib/python/setuptools/_distutils/ccompiler.py +++ b/uno/lib/python/setuptools/_distutils/ccompiler.py @@ -18,7 +18,7 @@ from .spawn import spawn from .file_util import move_file from .dir_util import mkpath -from .dep_util import newer_group +from ._modified import newer_group from .util import split_quoted, execute from ._log import log diff --git a/uno/lib/python/setuptools/_distutils/cmd.py b/uno/lib/python/setuptools/_distutils/cmd.py index 3860c3ff..8fdcbc0e 100644 --- a/uno/lib/python/setuptools/_distutils/cmd.py +++ b/uno/lib/python/setuptools/_distutils/cmd.py @@ -10,7 +10,7 @@ import logging from .errors import DistutilsOptionError -from . import util, dir_util, file_util, archive_util, dep_util +from . import util, dir_util, file_util, archive_util, _modified from ._log import log @@ -428,7 +428,7 @@ def make_file( # If 'outfile' must be regenerated (either because it doesn't # exist, is out-of-date, or the 'force' flag is true) then # perform the action that presumably regenerates it - if self.force or dep_util.newer_group(infiles, outfile): + if self.force or _modified.newer_group(infiles, outfile): self.execute(func, args, exec_msg, level) # Otherwise, print the "skip" message else: diff --git a/uno/lib/python/setuptools/_distutils/command/build_ext.py b/uno/lib/python/setuptools/_distutils/command/build_ext.py index fbeec342..b48f4626 100644 --- a/uno/lib/python/setuptools/_distutils/command/build_ext.py +++ b/uno/lib/python/setuptools/_distutils/command/build_ext.py @@ -19,7 +19,7 @@ ) from ..sysconfig import customize_compiler, get_python_version from ..sysconfig import get_config_h_filename -from ..dep_util import newer_group +from .._modified import newer_group from ..extension import Extension from ..util import get_platform from distutils._log import log diff --git a/uno/lib/python/setuptools/_distutils/command/build_scripts.py b/uno/lib/python/setuptools/_distutils/command/build_scripts.py index ce222f1e..1a4d67f4 100644 --- a/uno/lib/python/setuptools/_distutils/command/build_scripts.py +++ b/uno/lib/python/setuptools/_distutils/command/build_scripts.py @@ -7,7 +7,7 @@ from stat import ST_MODE from distutils import sysconfig from ..core import Command -from ..dep_util import newer +from .._modified import newer from ..util import convert_path from distutils._log import log import tokenize diff --git a/uno/lib/python/setuptools/_distutils/dep_util.py b/uno/lib/python/setuptools/_distutils/dep_util.py index 48da8641..09a8a2e1 100644 --- a/uno/lib/python/setuptools/_distutils/dep_util.py +++ b/uno/lib/python/setuptools/_distutils/dep_util.py @@ -1,96 +1,14 @@ -"""distutils.dep_util +import warnings -Utility functions for simple, timestamp-based dependency of files -and groups of files; also, function based entirely on such -timestamp dependency analysis.""" +from . import _modified -import os -from .errors import DistutilsFileError - -def newer(source, target): - """Return true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. Return false if - both exist and 'target' is the same age or younger than 'source'. - Raise DistutilsFileError if 'source' does not exist. - """ - if not os.path.exists(source): - raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(source)) - if not os.path.exists(target): - return 1 - - from stat import ST_MTIME - - mtime1 = os.stat(source)[ST_MTIME] - mtime2 = os.stat(target)[ST_MTIME] - - return mtime1 > mtime2 - - -# newer () - - -def newer_pairwise(sources, targets): - """Walk two filename lists in parallel, testing if each source is newer - than its corresponding target. Return a pair of lists (sources, - targets) where source is newer than target, according to the semantics - of 'newer()'. - """ - if len(sources) != len(targets): - raise ValueError("'sources' and 'targets' must be same length") - - # build a pair of lists (sources, targets) where source is newer - n_sources = [] - n_targets = [] - for i in range(len(sources)): - if newer(sources[i], targets[i]): - n_sources.append(sources[i]) - n_targets.append(targets[i]) - - return (n_sources, n_targets) - - -# newer_pairwise () - - -def newer_group(sources, target, missing='error'): - """Return true if 'target' is out-of-date with respect to any file - listed in 'sources'. In other words, if 'target' exists and is newer - than every file in 'sources', return false; otherwise return true. - 'missing' controls what we do when a source file is missing; the - default ("error") is to blow up with an OSError from inside 'stat()'; - if it is "ignore", we silently drop any missing source files; if it is - "newer", any missing source files make us assume that 'target' is - out-of-date (this is handy in "dry-run" mode: it'll make you pretend to - carry out commands that wouldn't work because inputs are missing, but - that doesn't matter because you're not actually going to run the - commands). - """ - # If the target doesn't even exist, then it's definitely out-of-date. - if not os.path.exists(target): - return 1 - - # Otherwise we have to find out the hard way: if *any* source file - # is more recent than 'target', then 'target' is out-of-date and - # we can immediately return true. If we fall through to the end - # of the loop, then 'target' is up-to-date and we return false. - from stat import ST_MTIME - - target_mtime = os.stat(target)[ST_MTIME] - for source in sources: - if not os.path.exists(source): - if missing == 'error': # blow up when we stat() the file - pass - elif missing == 'ignore': # missing source dropped from - continue # target's dependency list - elif missing == 'newer': # missing source means target is - return 1 # out-of-date - - source_mtime = os.stat(source)[ST_MTIME] - if source_mtime > target_mtime: - return 1 - else: - return 0 - - -# newer_group () +def __getattr__(name): + if name not in ['newer', 'newer_group', 'newer_pairwise']: + raise AttributeError(name) + warnings.warn( + "dep_util is Deprecated. Use functions from setuptools instead.", + DeprecationWarning, + stacklevel=2, + ) + return getattr(_modified, name) diff --git a/uno/lib/python/setuptools/_distutils/file_util.py b/uno/lib/python/setuptools/_distutils/file_util.py index 7c699066..3f3e21b5 100644 --- a/uno/lib/python/setuptools/_distutils/file_util.py +++ b/uno/lib/python/setuptools/_distutils/file_util.py @@ -108,7 +108,7 @@ def copy_file( # noqa: C901 # changing it (ie. it's not already a hard/soft link to src OR # (not update) and (src newer than dst). - from distutils.dep_util import newer + from distutils._modified import newer from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE if not os.path.isfile(src): diff --git a/uno/lib/python/setuptools/_distutils/py39compat.py b/uno/lib/python/setuptools/_distutils/py39compat.py index c43e5f10..1b436d76 100644 --- a/uno/lib/python/setuptools/_distutils/py39compat.py +++ b/uno/lib/python/setuptools/_distutils/py39compat.py @@ -1,5 +1,7 @@ -import sys +import functools +import itertools import platform +import sys def add_ext_suffix_39(vars): @@ -20,3 +22,45 @@ def add_ext_suffix_39(vars): needs_ext_suffix = sys.version_info < (3, 10) and platform.system() == 'Windows' add_ext_suffix = add_ext_suffix_39 if needs_ext_suffix else lambda vars: None + + +# from more_itertools +class UnequalIterablesError(ValueError): + def __init__(self, details=None): + msg = 'Iterables have different lengths' + if details is not None: + msg += (': index 0 has length {}; index {} has length {}').format(*details) + + super().__init__(msg) + + +# from more_itertools +def _zip_equal_generator(iterables): + _marker = object() + for combo in itertools.zip_longest(*iterables, fillvalue=_marker): + for val in combo: + if val is _marker: + raise UnequalIterablesError() + yield combo + + +# from more_itertools +def _zip_equal(*iterables): + # Check whether the iterables are all the same size. + try: + first_size = len(iterables[0]) + for i, it in enumerate(iterables[1:], 1): + size = len(it) + if size != first_size: + raise UnequalIterablesError(details=(first_size, i, size)) + # All sizes are equal, we can use the built-in zip. + return zip(*iterables) + # If any one of the iterables didn't have a length, start reading + # them until one runs out. + except TypeError: + return _zip_equal_generator(iterables) + + +zip_strict = ( + _zip_equal if sys.version_info < (3, 10) else functools.partial(zip, strict=True) +) diff --git a/uno/lib/python/setuptools/_distutils/unixccompiler.py b/uno/lib/python/setuptools/_distutils/unixccompiler.py index 6ca2332a..bd8db9ac 100644 --- a/uno/lib/python/setuptools/_distutils/unixccompiler.py +++ b/uno/lib/python/setuptools/_distutils/unixccompiler.py @@ -20,7 +20,7 @@ import itertools from . import sysconfig -from .dep_util import newer +from ._modified import newer from .ccompiler import CCompiler, gen_preprocess_options, gen_lib_options from .errors import DistutilsExecError, CompileError, LibError, LinkError from ._log import log diff --git a/uno/lib/python/setuptools/_distutils/util.py b/uno/lib/python/setuptools/_distutils/util.py index 7ef47176..7ae914f7 100644 --- a/uno/lib/python/setuptools/_distutils/util.py +++ b/uno/lib/python/setuptools/_distutils/util.py @@ -14,7 +14,7 @@ import functools from .errors import DistutilsPlatformError, DistutilsByteCompileError -from .dep_util import newer +from ._modified import newer from .spawn import spawn from ._log import log diff --git a/uno/lib/python/setuptools/_entry_points.py b/uno/lib/python/setuptools/_entry_points.py index a2346342..747a6906 100644 --- a/uno/lib/python/setuptools/_entry_points.py +++ b/uno/lib/python/setuptools/_entry_points.py @@ -54,8 +54,8 @@ def load(eps): Given a Distribution.entry_points, produce EntryPoints. """ groups = itertools.chain.from_iterable( - load_group(value, group) - for group, value in eps.items()) + load_group(value, group) for group, value in eps.items() + ) return validate(metadata.EntryPoints(groups)) @@ -81,14 +81,8 @@ def render(eps: metadata.EntryPoints): by_group = operator.attrgetter('group') groups = itertools.groupby(sorted(eps, key=by_group), by_group) - return '\n'.join( - f'[{group}]\n{render_items(items)}\n' - for group, items in groups - ) + return '\n'.join(f'[{group}]\n{render_items(items)}\n' for group, items in groups) def render_items(eps): - return '\n'.join( - f'{ep.name} = {ep.value}' - for ep in sorted(eps) - ) + return '\n'.join(f'{ep.name} = {ep.value}' for ep in sorted(eps)) diff --git a/uno/lib/python/setuptools/_imp.py b/uno/lib/python/setuptools/_imp.py index 6b489019..9d4ead0e 100644 --- a/uno/lib/python/setuptools/_imp.py +++ b/uno/lib/python/setuptools/_imp.py @@ -20,8 +20,8 @@ def find_spec(module, paths): finder = ( importlib.machinery.PathFinder().find_spec - if isinstance(paths, list) else - importlib.util.find_spec + if isinstance(paths, list) + else importlib.util.find_spec ) return finder(module, paths) @@ -37,13 +37,19 @@ def find_module(module, paths=None): kind = -1 file = None static = isinstance(spec.loader, type) - if spec.origin == 'frozen' or static and issubclass( - spec.loader, importlib.machinery.FrozenImporter): + if ( + spec.origin == 'frozen' + or static + and issubclass(spec.loader, importlib.machinery.FrozenImporter) + ): kind = PY_FROZEN path = None # imp compabilty suffix = mode = '' # imp compatibility - elif spec.origin == 'built-in' or static and issubclass( - spec.loader, importlib.machinery.BuiltinImporter): + elif ( + spec.origin == 'built-in' + or static + and issubclass(spec.loader, importlib.machinery.BuiltinImporter) + ): kind = C_BUILTIN path = None # imp compabilty suffix = mode = '' # imp compatibility diff --git a/uno/lib/python/setuptools/_importlib.py b/uno/lib/python/setuptools/_importlib.py index 5ae94b47..bd2b01e2 100644 --- a/uno/lib/python/setuptools/_importlib.py +++ b/uno/lib/python/setuptools/_importlib.py @@ -22,7 +22,7 @@ def disable_importlib_metadata_finder(metadata): This problem is likely to be solved by installing an updated version of `importlib-metadata`. """, - see_url="https://github.com/python/importlib_metadata/issues/396" + see_url="https://github.com/python/importlib_metadata/issues/396", ) # Ensure a descriptive message is shown. raise # This exception can be suppressed by _distutils_hack @@ -39,6 +39,7 @@ def disable_importlib_metadata_finder(metadata): if sys.version_info < (3, 10): from setuptools.extern import importlib_metadata as metadata + disable_importlib_metadata_finder(metadata) else: import importlib.metadata as metadata # noqa: F401 diff --git a/uno/lib/python/setuptools/_normalization.py b/uno/lib/python/setuptools/_normalization.py index 31899f7a..eee4fb77 100644 --- a/uno/lib/python/setuptools/_normalization.py +++ b/uno/lib/python/setuptools/_normalization.py @@ -7,13 +7,14 @@ from typing import Union from .extern import packaging -from .warnings import SetuptoolsDeprecationWarning _Path = Union[str, Path] # https://packaging.python.org/en/latest/specifications/core-metadata/#name _VALID_NAME = re.compile(r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.I) _UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9.]+", re.I) +_NON_ALPHANUMERIC = re.compile(r"[^A-Z0-9]+", re.I) +_PEP440_FALLBACK = re.compile(r"^v?(?P(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.I) def safe_identifier(name: str) -> str: @@ -41,6 +42,8 @@ def safe_name(component: str) -> str: def safe_version(version: str) -> str: """Convert an arbitrary string into a valid version string. + Can still raise an ``InvalidVersion`` exception. + To avoid exceptions use ``best_effort_version``. >>> safe_version("1988 12 25") '1988.12.25' >>> safe_version("v0.2.1") @@ -64,32 +67,45 @@ def safe_version(version: str) -> str: def best_effort_version(version: str) -> str: """Convert an arbitrary string into a version-like string. + Fallback when ``safe_version`` is not safe enough. >>> best_effort_version("v0.2 beta") '0.2b0' - - >>> import warnings - >>> warnings.simplefilter("ignore", category=SetuptoolsDeprecationWarning) >>> best_effort_version("ubuntu lts") - 'ubuntu.lts' + '0.dev0+sanitized.ubuntu.lts' + >>> best_effort_version("0.23ubuntu1") + '0.23.dev0+sanitized.ubuntu1' + >>> best_effort_version("0.23-") + '0.23.dev0+sanitized' + >>> best_effort_version("0.-_") + '0.dev0+sanitized' + >>> best_effort_version("42.+?1") + '42.dev0+sanitized.1' """ - # See pkg_resources.safe_version + # See pkg_resources._forgiving_version try: return safe_version(version) except packaging.version.InvalidVersion: - SetuptoolsDeprecationWarning.emit( - f"Invalid version: {version!r}.", - f""" - Version {version!r} is not valid according to PEP 440. - - Please make sure to specify a valid version for your package. - Also note that future releases of setuptools may halt the build process - if an invalid version is given. - """, - see_url="https://peps.python.org/pep-0440/", - due_date=(2023, 9, 26), # See setuptools/dist _validate_version - ) v = version.replace(' ', '.') - return safe_name(v) + match = _PEP440_FALLBACK.search(v) + if match: + safe = match["safe"] + rest = v[len(safe) :] + else: + safe = "0" + rest = version + safe_rest = _NON_ALPHANUMERIC.sub(".", rest).strip(".") + local = f"sanitized.{safe_rest}".strip(".") + return safe_version(f"{safe}.dev0+{local}") + + +def safe_extra(extra: str) -> str: + """Normalize extra name according to PEP 685 + >>> safe_extra("_FrIeNdLy-._.-bArD") + 'friendly-bard' + >>> safe_extra("FrIeNdLy-._.-bArD__._-") + 'friendly-bard' + """ + return _NON_ALPHANUMERIC.sub("-", extra).strip("-").lower() def filename_component(value: str) -> str: diff --git a/uno/lib/python/setuptools/_reqs.py b/uno/lib/python/setuptools/_reqs.py index 5d5b927f..7d7130d5 100644 --- a/uno/lib/python/setuptools/_reqs.py +++ b/uno/lib/python/setuptools/_reqs.py @@ -1,3 +1,4 @@ +from functools import lru_cache from typing import Callable, Iterable, Iterator, TypeVar, Union, overload import setuptools.extern.jaraco.text as text @@ -7,6 +8,12 @@ _StrOrIter = Union[str, Iterable[str]] +parse_req: Callable[[str], Requirement] = lru_cache()(Requirement) +# Setuptools parses the same requirement many times +# (e.g. first for validation than for normalisation), +# so it might be worth to cache. + + def parse_strings(strs: _StrOrIter) -> Iterator[str]: """ Yield requirement strings for each specification in `strs`. @@ -26,7 +33,7 @@ def parse(strs: _StrOrIter, parser: Callable[[str], _T]) -> Iterator[_T]: ... -def parse(strs, parser=Requirement): +def parse(strs, parser=parse_req): """ Replacement for ``pkg_resources.parse_requirements`` that uses ``packaging``. """ diff --git a/uno/lib/python/setuptools/_vendor/importlib_metadata/py.typed b/uno/lib/python/setuptools/_vendor/importlib_metadata/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/setuptools/_vendor/importlib_resources/py.typed b/uno/lib/python/setuptools/_vendor/importlib_resources/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/setuptools/_vendor/more_itertools/__init__.pyi b/uno/lib/python/setuptools/_vendor/more_itertools/__init__.pyi new file mode 100644 index 00000000..96f6e36c --- /dev/null +++ b/uno/lib/python/setuptools/_vendor/more_itertools/__init__.pyi @@ -0,0 +1,2 @@ +from .more import * +from .recipes import * diff --git a/uno/lib/python/setuptools/_vendor/more_itertools/more.pyi b/uno/lib/python/setuptools/_vendor/more_itertools/more.pyi new file mode 100644 index 00000000..2fba9cb3 --- /dev/null +++ b/uno/lib/python/setuptools/_vendor/more_itertools/more.pyi @@ -0,0 +1,480 @@ +"""Stubs for more_itertools.more""" + +from typing import ( + Any, + Callable, + Container, + Dict, + Generic, + Hashable, + Iterable, + Iterator, + List, + Optional, + Reversible, + Sequence, + Sized, + Tuple, + Union, + TypeVar, + type_check_only, +) +from types import TracebackType +from typing_extensions import ContextManager, Protocol, Type, overload + +# Type and type variable definitions +_T = TypeVar('_T') +_U = TypeVar('_U') +_V = TypeVar('_V') +_W = TypeVar('_W') +_T_co = TypeVar('_T_co', covariant=True) +_GenFn = TypeVar('_GenFn', bound=Callable[..., Iterator[object]]) +_Raisable = Union[BaseException, 'Type[BaseException]'] + +@type_check_only +class _SizedIterable(Protocol[_T_co], Sized, Iterable[_T_co]): ... + +@type_check_only +class _SizedReversible(Protocol[_T_co], Sized, Reversible[_T_co]): ... + +def chunked( + iterable: Iterable[_T], n: int, strict: bool = ... +) -> Iterator[List[_T]]: ... +@overload +def first(iterable: Iterable[_T]) -> _T: ... +@overload +def first(iterable: Iterable[_T], default: _U) -> Union[_T, _U]: ... +@overload +def last(iterable: Iterable[_T]) -> _T: ... +@overload +def last(iterable: Iterable[_T], default: _U) -> Union[_T, _U]: ... +@overload +def nth_or_last(iterable: Iterable[_T], n: int) -> _T: ... +@overload +def nth_or_last( + iterable: Iterable[_T], n: int, default: _U +) -> Union[_T, _U]: ... + +class peekable(Generic[_T], Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> peekable[_T]: ... + def __bool__(self) -> bool: ... + @overload + def peek(self) -> _T: ... + @overload + def peek(self, default: _U) -> Union[_T, _U]: ... + def prepend(self, *items: _T) -> None: ... + def __next__(self) -> _T: ... + @overload + def __getitem__(self, index: int) -> _T: ... + @overload + def __getitem__(self, index: slice) -> List[_T]: ... + +def collate(*iterables: Iterable[_T], **kwargs: Any) -> Iterable[_T]: ... +def consumer(func: _GenFn) -> _GenFn: ... +def ilen(iterable: Iterable[object]) -> int: ... +def iterate(func: Callable[[_T], _T], start: _T) -> Iterator[_T]: ... +def with_iter( + context_manager: ContextManager[Iterable[_T]], +) -> Iterator[_T]: ... +def one( + iterable: Iterable[_T], + too_short: Optional[_Raisable] = ..., + too_long: Optional[_Raisable] = ..., +) -> _T: ... +def distinct_permutations( + iterable: Iterable[_T], r: Optional[int] = ... +) -> Iterator[Tuple[_T, ...]]: ... +def intersperse( + e: _U, iterable: Iterable[_T], n: int = ... +) -> Iterator[Union[_T, _U]]: ... +def unique_to_each(*iterables: Iterable[_T]) -> List[List[_T]]: ... +@overload +def windowed( + seq: Iterable[_T], n: int, *, step: int = ... +) -> Iterator[Tuple[Optional[_T], ...]]: ... +@overload +def windowed( + seq: Iterable[_T], n: int, fillvalue: _U, step: int = ... +) -> Iterator[Tuple[Union[_T, _U], ...]]: ... +def substrings(iterable: Iterable[_T]) -> Iterator[Tuple[_T, ...]]: ... +def substrings_indexes( + seq: Sequence[_T], reverse: bool = ... +) -> Iterator[Tuple[Sequence[_T], int, int]]: ... + +class bucket(Generic[_T, _U], Container[_U]): + def __init__( + self, + iterable: Iterable[_T], + key: Callable[[_T], _U], + validator: Optional[Callable[[object], object]] = ..., + ) -> None: ... + def __contains__(self, value: object) -> bool: ... + def __iter__(self) -> Iterator[_U]: ... + def __getitem__(self, value: object) -> Iterator[_T]: ... + +def spy( + iterable: Iterable[_T], n: int = ... +) -> Tuple[List[_T], Iterator[_T]]: ... +def interleave(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def interleave_longest(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def collapse( + iterable: Iterable[Any], + base_type: Optional[type] = ..., + levels: Optional[int] = ..., +) -> Iterator[Any]: ... +@overload +def side_effect( + func: Callable[[_T], object], + iterable: Iterable[_T], + chunk_size: None = ..., + before: Optional[Callable[[], object]] = ..., + after: Optional[Callable[[], object]] = ..., +) -> Iterator[_T]: ... +@overload +def side_effect( + func: Callable[[List[_T]], object], + iterable: Iterable[_T], + chunk_size: int, + before: Optional[Callable[[], object]] = ..., + after: Optional[Callable[[], object]] = ..., +) -> Iterator[_T]: ... +def sliced( + seq: Sequence[_T], n: int, strict: bool = ... +) -> Iterator[Sequence[_T]]: ... +def split_at( + iterable: Iterable[_T], + pred: Callable[[_T], object], + maxsplit: int = ..., + keep_separator: bool = ..., +) -> Iterator[List[_T]]: ... +def split_before( + iterable: Iterable[_T], pred: Callable[[_T], object], maxsplit: int = ... +) -> Iterator[List[_T]]: ... +def split_after( + iterable: Iterable[_T], pred: Callable[[_T], object], maxsplit: int = ... +) -> Iterator[List[_T]]: ... +def split_when( + iterable: Iterable[_T], + pred: Callable[[_T, _T], object], + maxsplit: int = ..., +) -> Iterator[List[_T]]: ... +def split_into( + iterable: Iterable[_T], sizes: Iterable[Optional[int]] +) -> Iterator[List[_T]]: ... +@overload +def padded( + iterable: Iterable[_T], + *, + n: Optional[int] = ..., + next_multiple: bool = ... +) -> Iterator[Optional[_T]]: ... +@overload +def padded( + iterable: Iterable[_T], + fillvalue: _U, + n: Optional[int] = ..., + next_multiple: bool = ..., +) -> Iterator[Union[_T, _U]]: ... +@overload +def repeat_last(iterable: Iterable[_T]) -> Iterator[_T]: ... +@overload +def repeat_last( + iterable: Iterable[_T], default: _U +) -> Iterator[Union[_T, _U]]: ... +def distribute(n: int, iterable: Iterable[_T]) -> List[Iterator[_T]]: ... +@overload +def stagger( + iterable: Iterable[_T], + offsets: _SizedIterable[int] = ..., + longest: bool = ..., +) -> Iterator[Tuple[Optional[_T], ...]]: ... +@overload +def stagger( + iterable: Iterable[_T], + offsets: _SizedIterable[int] = ..., + longest: bool = ..., + fillvalue: _U = ..., +) -> Iterator[Tuple[Union[_T, _U], ...]]: ... + +class UnequalIterablesError(ValueError): + def __init__( + self, details: Optional[Tuple[int, int, int]] = ... + ) -> None: ... + +def zip_equal(*iterables: Iterable[_T]) -> Iterator[Tuple[_T, ...]]: ... +@overload +def zip_offset( + *iterables: Iterable[_T], offsets: _SizedIterable[int], longest: bool = ... +) -> Iterator[Tuple[Optional[_T], ...]]: ... +@overload +def zip_offset( + *iterables: Iterable[_T], + offsets: _SizedIterable[int], + longest: bool = ..., + fillvalue: _U +) -> Iterator[Tuple[Union[_T, _U], ...]]: ... +def sort_together( + iterables: Iterable[Iterable[_T]], + key_list: Iterable[int] = ..., + key: Optional[Callable[..., Any]] = ..., + reverse: bool = ..., +) -> List[Tuple[_T, ...]]: ... +def unzip(iterable: Iterable[Sequence[_T]]) -> Tuple[Iterator[_T], ...]: ... +def divide(n: int, iterable: Iterable[_T]) -> List[Iterator[_T]]: ... +def always_iterable( + obj: object, + base_type: Union[ + type, Tuple[Union[type, Tuple[Any, ...]], ...], None + ] = ..., +) -> Iterator[Any]: ... +def adjacent( + predicate: Callable[[_T], bool], + iterable: Iterable[_T], + distance: int = ..., +) -> Iterator[Tuple[bool, _T]]: ... +def groupby_transform( + iterable: Iterable[_T], + keyfunc: Optional[Callable[[_T], _U]] = ..., + valuefunc: Optional[Callable[[_T], _V]] = ..., + reducefunc: Optional[Callable[..., _W]] = ..., +) -> Iterator[Tuple[_T, _W]]: ... + +class numeric_range(Generic[_T, _U], Sequence[_T], Hashable, Reversible[_T]): + @overload + def __init__(self, __stop: _T) -> None: ... + @overload + def __init__(self, __start: _T, __stop: _T) -> None: ... + @overload + def __init__(self, __start: _T, __stop: _T, __step: _U) -> None: ... + def __bool__(self) -> bool: ... + def __contains__(self, elem: object) -> bool: ... + def __eq__(self, other: object) -> bool: ... + @overload + def __getitem__(self, key: int) -> _T: ... + @overload + def __getitem__(self, key: slice) -> numeric_range[_T, _U]: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[_T]: ... + def __len__(self) -> int: ... + def __reduce__( + self, + ) -> Tuple[Type[numeric_range[_T, _U]], Tuple[_T, _T, _U]]: ... + def __repr__(self) -> str: ... + def __reversed__(self) -> Iterator[_T]: ... + def count(self, value: _T) -> int: ... + def index(self, value: _T) -> int: ... # type: ignore + +def count_cycle( + iterable: Iterable[_T], n: Optional[int] = ... +) -> Iterable[Tuple[int, _T]]: ... +def mark_ends( + iterable: Iterable[_T], +) -> Iterable[Tuple[bool, bool, _T]]: ... +def locate( + iterable: Iterable[object], + pred: Callable[..., Any] = ..., + window_size: Optional[int] = ..., +) -> Iterator[int]: ... +def lstrip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... +def rstrip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... +def strip( + iterable: Iterable[_T], pred: Callable[[_T], object] +) -> Iterator[_T]: ... + +class islice_extended(Generic[_T], Iterator[_T]): + def __init__( + self, iterable: Iterable[_T], *args: Optional[int] + ) -> None: ... + def __iter__(self) -> islice_extended[_T]: ... + def __next__(self) -> _T: ... + def __getitem__(self, index: slice) -> islice_extended[_T]: ... + +def always_reversible(iterable: Iterable[_T]) -> Iterator[_T]: ... +def consecutive_groups( + iterable: Iterable[_T], ordering: Callable[[_T], int] = ... +) -> Iterator[Iterator[_T]]: ... +@overload +def difference( + iterable: Iterable[_T], + func: Callable[[_T, _T], _U] = ..., + *, + initial: None = ... +) -> Iterator[Union[_T, _U]]: ... +@overload +def difference( + iterable: Iterable[_T], func: Callable[[_T, _T], _U] = ..., *, initial: _U +) -> Iterator[_U]: ... + +class SequenceView(Generic[_T], Sequence[_T]): + def __init__(self, target: Sequence[_T]) -> None: ... + @overload + def __getitem__(self, index: int) -> _T: ... + @overload + def __getitem__(self, index: slice) -> Sequence[_T]: ... + def __len__(self) -> int: ... + +class seekable(Generic[_T], Iterator[_T]): + def __init__( + self, iterable: Iterable[_T], maxlen: Optional[int] = ... + ) -> None: ... + def __iter__(self) -> seekable[_T]: ... + def __next__(self) -> _T: ... + def __bool__(self) -> bool: ... + @overload + def peek(self) -> _T: ... + @overload + def peek(self, default: _U) -> Union[_T, _U]: ... + def elements(self) -> SequenceView[_T]: ... + def seek(self, index: int) -> None: ... + +class run_length: + @staticmethod + def encode(iterable: Iterable[_T]) -> Iterator[Tuple[_T, int]]: ... + @staticmethod + def decode(iterable: Iterable[Tuple[_T, int]]) -> Iterator[_T]: ... + +def exactly_n( + iterable: Iterable[_T], n: int, predicate: Callable[[_T], object] = ... +) -> bool: ... +def circular_shifts(iterable: Iterable[_T]) -> List[Tuple[_T, ...]]: ... +def make_decorator( + wrapping_func: Callable[..., _U], result_index: int = ... +) -> Callable[..., Callable[[Callable[..., Any]], Callable[..., _U]]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None = ..., + reducefunc: None = ..., +) -> Dict[_U, List[_T]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: None = ..., +) -> Dict[_U, List[_V]]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: None = ..., + reducefunc: Callable[[List[_T]], _W] = ..., +) -> Dict[_U, _W]: ... +@overload +def map_reduce( + iterable: Iterable[_T], + keyfunc: Callable[[_T], _U], + valuefunc: Callable[[_T], _V], + reducefunc: Callable[[List[_V]], _W], +) -> Dict[_U, _W]: ... +def rlocate( + iterable: Iterable[_T], + pred: Callable[..., object] = ..., + window_size: Optional[int] = ..., +) -> Iterator[int]: ... +def replace( + iterable: Iterable[_T], + pred: Callable[..., object], + substitutes: Iterable[_U], + count: Optional[int] = ..., + window_size: int = ..., +) -> Iterator[Union[_T, _U]]: ... +def partitions(iterable: Iterable[_T]) -> Iterator[List[List[_T]]]: ... +def set_partitions( + iterable: Iterable[_T], k: Optional[int] = ... +) -> Iterator[List[List[_T]]]: ... + +class time_limited(Generic[_T], Iterator[_T]): + def __init__( + self, limit_seconds: float, iterable: Iterable[_T] + ) -> None: ... + def __iter__(self) -> islice_extended[_T]: ... + def __next__(self) -> _T: ... + +@overload +def only( + iterable: Iterable[_T], *, too_long: Optional[_Raisable] = ... +) -> Optional[_T]: ... +@overload +def only( + iterable: Iterable[_T], default: _U, too_long: Optional[_Raisable] = ... +) -> Union[_T, _U]: ... +def ichunked(iterable: Iterable[_T], n: int) -> Iterator[Iterator[_T]]: ... +def distinct_combinations( + iterable: Iterable[_T], r: int +) -> Iterator[Tuple[_T, ...]]: ... +def filter_except( + validator: Callable[[Any], object], + iterable: Iterable[_T], + *exceptions: Type[BaseException] +) -> Iterator[_T]: ... +def map_except( + function: Callable[[Any], _U], + iterable: Iterable[_T], + *exceptions: Type[BaseException] +) -> Iterator[_U]: ... +def sample( + iterable: Iterable[_T], + k: int, + weights: Optional[Iterable[float]] = ..., +) -> List[_T]: ... +def is_sorted( + iterable: Iterable[_T], + key: Optional[Callable[[_T], _U]] = ..., + reverse: bool = False, +) -> bool: ... + +class AbortThread(BaseException): + pass + +class callback_iter(Generic[_T], Iterator[_T]): + def __init__( + self, + func: Callable[..., Any], + callback_kwd: str = ..., + wait_seconds: float = ..., + ) -> None: ... + def __enter__(self) -> callback_iter[_T]: ... + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> Optional[bool]: ... + def __iter__(self) -> callback_iter[_T]: ... + def __next__(self) -> _T: ... + def _reader(self) -> Iterator[_T]: ... + @property + def done(self) -> bool: ... + @property + def result(self) -> Any: ... + +def windowed_complete( + iterable: Iterable[_T], n: int +) -> Iterator[Tuple[_T, ...]]: ... +def all_unique( + iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = ... +) -> bool: ... +def nth_product(index: int, *args: Iterable[_T]) -> Tuple[_T, ...]: ... +def nth_permutation( + iterable: Iterable[_T], r: int, index: int +) -> Tuple[_T, ...]: ... +def value_chain(*args: Union[_T, Iterable[_T]]) -> Iterable[_T]: ... +def product_index(element: Iterable[_T], *args: Iterable[_T]) -> int: ... +def combination_index( + element: Iterable[_T], iterable: Iterable[_T] +) -> int: ... +def permutation_index( + element: Iterable[_T], iterable: Iterable[_T] +) -> int: ... + +class countable(Generic[_T], Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> countable[_T]: ... + def __next__(self) -> _T: ... diff --git a/uno/lib/python/setuptools/_vendor/more_itertools/py.typed b/uno/lib/python/setuptools/_vendor/more_itertools/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/setuptools/_vendor/more_itertools/recipes.pyi b/uno/lib/python/setuptools/_vendor/more_itertools/recipes.pyi new file mode 100644 index 00000000..5e39d963 --- /dev/null +++ b/uno/lib/python/setuptools/_vendor/more_itertools/recipes.pyi @@ -0,0 +1,103 @@ +"""Stubs for more_itertools.recipes""" +from typing import ( + Any, + Callable, + Iterable, + Iterator, + List, + Optional, + Tuple, + TypeVar, + Union, +) +from typing_extensions import overload, Type + +# Type and type variable definitions +_T = TypeVar('_T') +_U = TypeVar('_U') + +def take(n: int, iterable: Iterable[_T]) -> List[_T]: ... +def tabulate( + function: Callable[[int], _T], start: int = ... +) -> Iterator[_T]: ... +def tail(n: int, iterable: Iterable[_T]) -> Iterator[_T]: ... +def consume(iterator: Iterable[object], n: Optional[int] = ...) -> None: ... +@overload +def nth(iterable: Iterable[_T], n: int) -> Optional[_T]: ... +@overload +def nth(iterable: Iterable[_T], n: int, default: _U) -> Union[_T, _U]: ... +def all_equal(iterable: Iterable[object]) -> bool: ... +def quantify( + iterable: Iterable[_T], pred: Callable[[_T], bool] = ... +) -> int: ... +def pad_none(iterable: Iterable[_T]) -> Iterator[Optional[_T]]: ... +def padnone(iterable: Iterable[_T]) -> Iterator[Optional[_T]]: ... +def ncycles(iterable: Iterable[_T], n: int) -> Iterator[_T]: ... +def dotproduct(vec1: Iterable[object], vec2: Iterable[object]) -> object: ... +def flatten(listOfLists: Iterable[Iterable[_T]]) -> Iterator[_T]: ... +def repeatfunc( + func: Callable[..., _U], times: Optional[int] = ..., *args: Any +) -> Iterator[_U]: ... +def pairwise(iterable: Iterable[_T]) -> Iterator[Tuple[_T, _T]]: ... +@overload +def grouper( + iterable: Iterable[_T], n: int +) -> Iterator[Tuple[Optional[_T], ...]]: ... +@overload +def grouper( + iterable: Iterable[_T], n: int, fillvalue: _U +) -> Iterator[Tuple[Union[_T, _U], ...]]: ... +@overload +def grouper( # Deprecated interface + iterable: int, n: Iterable[_T] +) -> Iterator[Tuple[Optional[_T], ...]]: ... +@overload +def grouper( # Deprecated interface + iterable: int, n: Iterable[_T], fillvalue: _U +) -> Iterator[Tuple[Union[_T, _U], ...]]: ... +def roundrobin(*iterables: Iterable[_T]) -> Iterator[_T]: ... +def partition( + pred: Optional[Callable[[_T], object]], iterable: Iterable[_T] +) -> Tuple[Iterator[_T], Iterator[_T]]: ... +def powerset(iterable: Iterable[_T]) -> Iterator[Tuple[_T, ...]]: ... +def unique_everseen( + iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = ... +) -> Iterator[_T]: ... +def unique_justseen( + iterable: Iterable[_T], key: Optional[Callable[[_T], object]] = ... +) -> Iterator[_T]: ... +@overload +def iter_except( + func: Callable[[], _T], exception: Type[BaseException], first: None = ... +) -> Iterator[_T]: ... +@overload +def iter_except( + func: Callable[[], _T], + exception: Type[BaseException], + first: Callable[[], _U], +) -> Iterator[Union[_T, _U]]: ... +@overload +def first_true( + iterable: Iterable[_T], *, pred: Optional[Callable[[_T], object]] = ... +) -> Optional[_T]: ... +@overload +def first_true( + iterable: Iterable[_T], + default: _U, + pred: Optional[Callable[[_T], object]] = ..., +) -> Union[_T, _U]: ... +def random_product( + *args: Iterable[_T], repeat: int = ... +) -> Tuple[_T, ...]: ... +def random_permutation( + iterable: Iterable[_T], r: Optional[int] = ... +) -> Tuple[_T, ...]: ... +def random_combination(iterable: Iterable[_T], r: int) -> Tuple[_T, ...]: ... +def random_combination_with_replacement( + iterable: Iterable[_T], r: int +) -> Tuple[_T, ...]: ... +def nth_combination( + iterable: Iterable[_T], r: int, index: int +) -> Tuple[_T, ...]: ... +def prepend(value: _T, iterator: Iterable[_U]) -> Iterator[Union[_T, _U]]: ... +def convolve(signal: Iterable[_T], kernel: Iterable[_T]) -> Iterator[_T]: ... diff --git a/uno/lib/python/setuptools/_vendor/packaging/py.typed b/uno/lib/python/setuptools/_vendor/packaging/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/uno/lib/python/setuptools/_vendor/tomli/py.typed b/uno/lib/python/setuptools/_vendor/tomli/py.typed new file mode 100644 index 00000000..7632ecf7 --- /dev/null +++ b/uno/lib/python/setuptools/_vendor/tomli/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561 diff --git a/uno/lib/python/setuptools/archive_util.py b/uno/lib/python/setuptools/archive_util.py index d8e10c13..6b8460bd 100644 --- a/uno/lib/python/setuptools/archive_util.py +++ b/uno/lib/python/setuptools/archive_util.py @@ -11,8 +11,13 @@ from ._path import ensure_directory __all__ = [ - "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter", - "UnrecognizedFormat", "extraction_drivers", "unpack_directory", + "unpack_archive", + "unpack_zipfile", + "unpack_tarfile", + "default_filter", + "UnrecognizedFormat", + "extraction_drivers", + "unpack_directory", ] @@ -25,9 +30,7 @@ def default_filter(src, dst): return dst -def unpack_archive( - filename, extract_dir, progress_filter=default_filter, - drivers=None): +def unpack_archive(filename, extract_dir, progress_filter=default_filter, drivers=None): """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` `progress_filter` is a function taking two arguments: a source path @@ -56,13 +59,11 @@ def unpack_archive( else: return else: - raise UnrecognizedFormat( - "Not a recognized archive type: %s" % filename - ) + raise UnrecognizedFormat("Not a recognized archive type: %s" % filename) def unpack_directory(filename, extract_dir, progress_filter=default_filter): - """"Unpack" a directory, using the same interface as for archives + """ "Unpack" a directory, using the same interface as for archives Raises ``UnrecognizedFormat`` if `filename` is not a directory """ @@ -136,7 +137,8 @@ def _unpack_zipfile_obj(zipfile_obj, extract_dir, progress_filter=default_filter def _resolve_tar_file_or_dir(tar_obj, tar_member_obj): """Resolve any links and extract link targets as normal files.""" while tar_member_obj is not None and ( - tar_member_obj.islnk() or tar_member_obj.issym()): + tar_member_obj.islnk() or tar_member_obj.issym() + ): linkpath = tar_member_obj.linkname if tar_member_obj.issym(): base = posixpath.dirname(tar_member_obj.name) @@ -144,9 +146,8 @@ def _resolve_tar_file_or_dir(tar_obj, tar_member_obj): linkpath = posixpath.normpath(linkpath) tar_member_obj = tar_obj._getmember(linkpath) - is_file_or_dir = ( - tar_member_obj is not None and - (tar_member_obj.isfile() or tar_member_obj.isdir()) + is_file_or_dir = tar_member_obj is not None and ( + tar_member_obj.isfile() or tar_member_obj.isdir() ) if is_file_or_dir: return tar_member_obj @@ -198,7 +199,9 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): ) from e for member, final_dst in _iter_open_tar( - tarobj, extract_dir, progress_filter, + tarobj, + extract_dir, + progress_filter, ): try: # XXX Ugh diff --git a/uno/lib/python/setuptools/build_meta.py b/uno/lib/python/setuptools/build_meta.py index ee8ef13f..6da80d70 100644 --- a/uno/lib/python/setuptools/build_meta.py +++ b/uno/lib/python/setuptools/build_meta.py @@ -47,16 +47,18 @@ from distutils.util import strtobool -__all__ = ['get_requires_for_build_sdist', - 'get_requires_for_build_wheel', - 'prepare_metadata_for_build_wheel', - 'build_wheel', - 'build_sdist', - 'get_requires_for_build_editable', - 'prepare_metadata_for_build_editable', - 'build_editable', - '__legacy__', - 'SetupRequirementsError'] +__all__ = [ + 'get_requires_for_build_sdist', + 'get_requires_for_build_wheel', + 'prepare_metadata_for_build_wheel', + 'build_wheel', + 'build_sdist', + 'get_requires_for_build_editable', + 'prepare_metadata_for_build_editable', + 'build_editable', + '__legacy__', + 'SetupRequirementsError', +] SETUPTOOLS_ENABLE_FEATURES = os.getenv("SETUPTOOLS_ENABLE_FEATURES", "").lower() LEGACY_EDITABLE = "legacy-editable" in SETUPTOOLS_ENABLE_FEATURES.replace("_", "-") @@ -106,21 +108,20 @@ def no_install_setup_requires(): def _get_immediate_subdirectories(a_dir): - return [name for name in os.listdir(a_dir) - if os.path.isdir(os.path.join(a_dir, name))] + return [ + name for name in os.listdir(a_dir) if os.path.isdir(os.path.join(a_dir, name)) + ] def _file_with_extension(directory, extension): - matching = ( - f for f in os.listdir(directory) - if f.endswith(extension) - ) + matching = (f for f in os.listdir(directory) if f.endswith(extension)) try: - file, = matching + (file,) = matching except ValueError: raise ValueError( 'No distribution was found. Ensure that `setup.py` ' - 'is not empty and that it calls `setup()`.') + 'is not empty and that it calls `setup()`.' + ) return file @@ -159,6 +160,7 @@ class _ConfigSettingsTranslator: """Translate ``config_settings`` into distutils-style command arguments. Only a limited number of options is currently supported. """ + # See pypa/setuptools#1928 pypa/setuptools#2491 def _get_config(self, key: str, config_settings: _ConfigSettings) -> List[str]: @@ -183,11 +185,6 @@ def _get_config(self, key: str, config_settings: _ConfigSettings) -> List[str]: opts = cfg.get(key) or [] return shlex.split(opts) if isinstance(opts, str) else opts - def _valid_global_options(self): - """Global options accepted by setuptools (e.g. quiet or verbose).""" - options = (opt[:2] for opt in setuptools.dist.Distribution.global_options) - return {flag for long_and_short in options for flag in long_and_short if flag} - def _global_args(self, config_settings: _ConfigSettings) -> Iterator[str]: """ Let the user specify ``verbose`` or ``quiet`` + escape hatch via @@ -218,9 +215,7 @@ def _global_args(self, config_settings: _ConfigSettings) -> Iterator[str]: level = str(cfg.get("quiet") or cfg.get("--quiet") or "1") yield ("-v" if level.lower() in falsey else "-q") - valid = self._valid_global_options() - args = self._get_config("--global-option", config_settings) - yield from (arg for arg in args if arg.strip("-") in valid) + yield from self._get_config("--global-option", config_settings) def __dist_info_args(self, config_settings: _ConfigSettings) -> Iterator[str]: """ @@ -228,7 +223,7 @@ def __dist_info_args(self, config_settings: _ConfigSettings) -> Iterator[str]: .. warning:: We cannot use this yet as it requires the ``sdist`` and ``bdist_wheel`` - commands run in ``build_sdist`` and ``build_wheel`` to re-use the egg-info + commands run in ``build_sdist`` and ``build_wheel`` to reuse the egg-info directory created in ``prepare_metadata_for_build_wheel``. >>> fn = _ConfigSettingsTranslator()._ConfigSettingsTranslator__dist_info_args @@ -282,33 +277,11 @@ def _arbitrary_args(self, config_settings: _ConfigSettings) -> Iterator[str]: ['foo'] >>> list(fn({'--build-option': 'foo bar'})) ['foo', 'bar'] - >>> warnings.simplefilter('error', SetuptoolsDeprecationWarning) - >>> list(fn({'--global-option': 'foo'})) # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - SetuptoolsDeprecationWarning: ...arguments given via `--global-option`... + >>> list(fn({'--global-option': 'foo'})) + [] """ - args = self._get_config("--global-option", config_settings) - global_opts = self._valid_global_options() - bad_args = [] - - for arg in args: - if arg.strip("-") not in global_opts: - bad_args.append(arg) - yield arg - yield from self._get_config("--build-option", config_settings) - if bad_args: - SetuptoolsDeprecationWarning.emit( - "Incompatible `config_settings` passed to build backend.", - f""" - The arguments {bad_args!r} were given via `--global-option`. - Please use `--build-option` instead, - `--global-option` is reserved for flags like `--verbose` or `--quiet`. - """, - due_date=(2023, 9, 26), # Warning introduced in v64.0.1, 11/Aug/2022. - ) - class _BuildMetaBackend(_ConfigSettingsTranslator): def _get_build_requires(self, config_settings, requirements): @@ -316,7 +289,6 @@ def _get_build_requires(self, config_settings, requirements): *sys.argv[:1], *self._global_args(config_settings), "egg_info", - *self._arbitrary_args(config_settings), ] try: with Distribution.patch(): @@ -335,7 +307,19 @@ def run_setup(self, setup_script='setup.py'): with _open_setup_script(__file__) as f: code = f.read().replace(r'\r\n', r'\n') - exec(code, locals()) + try: + exec(code, locals()) + except SystemExit as e: + if e.code: + raise + # We ignore exit code indicating success + SetuptoolsDeprecationWarning.emit( + "Running `setup.py` directly as CLI tool is deprecated.", + "Please avoid using `sys.exit(0)` or similar statements " + "that don't fit in the paradigm of a configuration file.", + see_url="https://blog.ganssle.io/articles/2021/10/" + "setup-py-deprecated.html", + ) def get_requires_for_build_wheel(self, config_settings=None): return self._get_build_requires(config_settings, requirements=['wheel']) @@ -367,13 +351,15 @@ def _find_info_directory(self, metadata_directory: str, suffix: str) -> Path: msg = f"No {suffix} directory found in {metadata_directory}" raise errors.InternalError(msg) - def prepare_metadata_for_build_wheel(self, metadata_directory, - config_settings=None): + def prepare_metadata_for_build_wheel( + self, metadata_directory, config_settings=None + ): sys.argv = [ *sys.argv[:1], *self._global_args(config_settings), "dist_info", - "--output-dir", metadata_directory, + "--output-dir", + metadata_directory, "--keep-egg-info", ] with no_install_setup_requires(): @@ -382,26 +368,27 @@ def prepare_metadata_for_build_wheel(self, metadata_directory, self._bubble_up_info_directory(metadata_directory, ".egg-info") return self._bubble_up_info_directory(metadata_directory, ".dist-info") - def _build_with_temp_dir(self, setup_command, result_extension, - result_directory, config_settings): + def _build_with_temp_dir( + self, setup_command, result_extension, result_directory, config_settings + ): result_directory = os.path.abspath(result_directory) # Build in a temporary directory, then copy to the target. os.makedirs(result_directory, exist_ok=True) temp_opts = {"prefix": ".tmp-", "dir": result_directory} + with tempfile.TemporaryDirectory(**temp_opts) as tmp_dist_dir: sys.argv = [ *sys.argv[:1], *self._global_args(config_settings), *setup_command, - "--dist-dir", tmp_dist_dir, - *self._arbitrary_args(config_settings), + "--dist-dir", + tmp_dist_dir, ] with no_install_setup_requires(): self.run_setup() - result_basename = _file_with_extension( - tmp_dist_dir, result_extension) + result_basename = _file_with_extension(tmp_dist_dir, result_extension) result_path = os.path.join(result_directory, result_basename) if os.path.exists(result_path): # os.rename will fail overwriting on non-Unix. @@ -410,16 +397,21 @@ def _build_with_temp_dir(self, setup_command, result_extension, return result_basename - def build_wheel(self, wheel_directory, config_settings=None, - metadata_directory=None): + def build_wheel( + self, wheel_directory, config_settings=None, metadata_directory=None + ): with suppress_known_deprecation(): - return self._build_with_temp_dir(['bdist_wheel'], '.whl', - wheel_directory, config_settings) + return self._build_with_temp_dir( + ['bdist_wheel', *self._arbitrary_args(config_settings)], + '.whl', + wheel_directory, + config_settings, + ) def build_sdist(self, sdist_directory, config_settings=None): - return self._build_with_temp_dir(['sdist', '--formats', 'gztar'], - '.tar.gz', sdist_directory, - config_settings) + return self._build_with_temp_dir( + ['sdist', '--formats', 'gztar'], '.tar.gz', sdist_directory, config_settings + ) def _get_dist_info_dir(self, metadata_directory: Optional[str]) -> Optional[str]: if not metadata_directory: @@ -429,7 +421,6 @@ def _get_dist_info_dir(self, metadata_directory: Optional[str]) -> Optional[str] return str(dist_info_candidates[0]) if dist_info_candidates else None if not LEGACY_EDITABLE: - # PEP660 hooks: # build_editable # get_requires_for_build_editable @@ -449,8 +440,9 @@ def build_editable( def get_requires_for_build_editable(self, config_settings=None): return self.get_requires_for_build_wheel(config_settings) - def prepare_metadata_for_build_editable(self, metadata_directory, - config_settings=None): + def prepare_metadata_for_build_editable( + self, metadata_directory, config_settings=None + ): return self.prepare_metadata_for_build_wheel( metadata_directory, config_settings ) @@ -467,11 +459,12 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): packaging mechanism, and will eventually be removed. """ + def run_setup(self, setup_script='setup.py'): # In order to maintain compatibility with scripts assuming that # the setup.py script is in a directory on the PYTHONPATH, inject # '' into sys.path. (pypa/setuptools#1642) - sys_path = list(sys.path) # Save the original path + sys_path = list(sys.path) # Save the original path script_dir = os.path.dirname(os.path.abspath(setup_script)) if script_dir not in sys.path: @@ -484,8 +477,7 @@ def run_setup(self, setup_script='setup.py'): sys.argv[0] = setup_script try: - super(_BuildMetaLegacyBackend, - self).run_setup(setup_script=setup_script) + super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script) finally: # While PEP 517 frontends should be calling each hook in a fresh # subprocess according to the standard (and thus it should not be diff --git a/uno/lib/python/setuptools/command/_requirestxt.py b/uno/lib/python/setuptools/command/_requirestxt.py new file mode 100644 index 00000000..32bae2c4 --- /dev/null +++ b/uno/lib/python/setuptools/command/_requirestxt.py @@ -0,0 +1,128 @@ +"""Helper code used to generate ``requires.txt`` files in the egg-info directory. + +The ``requires.txt`` file has an specific format: + - Environment markers need to be part of the section headers and + should not be part of the requirement spec itself. + +See https://setuptools.pypa.io/en/latest/deprecated/python_eggs.html#requires-txt +""" +import io +from collections import defaultdict +from itertools import filterfalse +from typing import Dict, List, Tuple, Mapping, TypeVar + +from .. import _reqs +from ..extern.jaraco.text import yield_lines +from ..extern.packaging.requirements import Requirement + + +# dict can work as an ordered set +_T = TypeVar("_T") +_Ordered = Dict[_T, None] +_ordered = dict +_StrOrIter = _reqs._StrOrIter + + +def _prepare( + install_requires: _StrOrIter, extras_require: Mapping[str, _StrOrIter] +) -> Tuple[List[str], Dict[str, List[str]]]: + """Given values for ``install_requires`` and ``extras_require`` + create modified versions in a way that can be written in ``requires.txt`` + """ + extras = _convert_extras_requirements(extras_require) + return _move_install_requirements_markers(install_requires, extras) + + +def _convert_extras_requirements( + extras_require: _StrOrIter, +) -> Mapping[str, _Ordered[Requirement]]: + """ + Convert requirements in `extras_require` of the form + `"extra": ["barbazquux; {marker}"]` to + `"extra:{marker}": ["barbazquux"]`. + """ + output: Mapping[str, _Ordered[Requirement]] = defaultdict(dict) + for section, v in extras_require.items(): + # Do not strip empty sections. + output[section] + for r in _reqs.parse(v): + output[section + _suffix_for(r)].setdefault(r) + + return output + + +def _move_install_requirements_markers( + install_requires: _StrOrIter, extras_require: Mapping[str, _Ordered[Requirement]] +) -> Tuple[List[str], Dict[str, List[str]]]: + """ + The ``requires.txt`` file has an specific format: + - Environment markers need to be part of the section headers and + should not be part of the requirement spec itself. + + Move requirements in ``install_requires`` that are using environment + markers ``extras_require``. + """ + + # divide the install_requires into two sets, simple ones still + # handled by install_requires and more complex ones handled by extras_require. + + inst_reqs = list(_reqs.parse(install_requires)) + simple_reqs = filter(_no_marker, inst_reqs) + complex_reqs = filterfalse(_no_marker, inst_reqs) + simple_install_requires = list(map(str, simple_reqs)) + + for r in complex_reqs: + extras_require[':' + str(r.marker)].setdefault(r) + + expanded_extras = dict( + # list(dict.fromkeys(...)) ensures a list of unique strings + (k, list(dict.fromkeys(str(r) for r in map(_clean_req, v)))) + for k, v in extras_require.items() + ) + + return simple_install_requires, expanded_extras + + +def _suffix_for(req): + """Return the 'extras_require' suffix for a given requirement.""" + return ':' + str(req.marker) if req.marker else '' + + +def _clean_req(req): + """Given a Requirement, remove environment markers and return it""" + r = Requirement(str(req)) # create a copy before modifying + r.marker = None + return r + + +def _no_marker(req): + return not req.marker + + +def _write_requirements(stream, reqs): + lines = yield_lines(reqs or ()) + + def append_cr(line): + return line + '\n' + + lines = map(append_cr, lines) + stream.writelines(lines) + + +def write_requirements(cmd, basename, filename): + dist = cmd.distribution + data = io.StringIO() + install_requires, extras_require = _prepare( + dist.install_requires or (), dist.extras_require or {} + ) + _write_requirements(data, install_requires) + for extra in sorted(extras_require): + data.write('\n[{extra}]\n'.format(**vars())) + _write_requirements(data, extras_require[extra]) + cmd.write_or_delete_file("requirements", filename, data.getvalue()) + + +def write_setup_requirements(cmd, basename, filename): + data = io.StringIO() + _write_requirements(data, cmd.distribution.setup_requires) + cmd.write_or_delete_file("setup-requirements", filename, data.getvalue()) diff --git a/uno/lib/python/setuptools/command/alias.py b/uno/lib/python/setuptools/command/alias.py index 452a9244..e7b4d545 100644 --- a/uno/lib/python/setuptools/command/alias.py +++ b/uno/lib/python/setuptools/command/alias.py @@ -49,7 +49,7 @@ def run(self): return elif len(self.args) == 1: - alias, = self.args + (alias,) = self.args if self.remove: command = None elif alias in aliases: diff --git a/uno/lib/python/setuptools/command/bdist_egg.py b/uno/lib/python/setuptools/command/bdist_egg.py index 33f483cf..bdece56b 100644 --- a/uno/lib/python/setuptools/command/bdist_egg.py +++ b/uno/lib/python/setuptools/command/bdist_egg.py @@ -41,7 +41,8 @@ def sorted_walk(dir): def write_stub(resource, pyfile): - _stub_template = textwrap.dedent(""" + _stub_template = textwrap.dedent( + """ def __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, importlib.util @@ -51,7 +52,8 @@ def __bootstrap__(): mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) __bootstrap__() - """).lstrip() + """ + ).lstrip() with open(pyfile, 'w') as f: f.write(_stub_template % resource) @@ -60,24 +62,25 @@ class bdist_egg(Command): description = "create an \"egg\" distribution" user_options = [ - ('bdist-dir=', 'b', - "temporary directory for creating the distribution"), - ('plat-name=', 'p', "platform name to embed in generated filenames " - "(by default uses `pkg_resources.get_build_platform()`)"), - ('exclude-source-files', None, - "remove all .py files from the generated egg"), - ('keep-temp', 'k', - "keep the pseudo-installation tree around after " + - "creating the distribution archive"), - ('dist-dir=', 'd', - "directory to put final built distributions in"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), + ('bdist-dir=', 'b', "temporary directory for creating the distribution"), + ( + 'plat-name=', + 'p', + "platform name to embed in generated filenames " + "(by default uses `pkg_resources.get_build_platform()`)", + ), + ('exclude-source-files', None, "remove all .py files from the generated egg"), + ( + 'keep-temp', + 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive", + ), + ('dist-dir=', 'd', "directory to put final built distributions in"), + ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ] - boolean_options = [ - 'keep-temp', 'skip-build', 'exclude-source-files' - ] + boolean_options = ['keep-temp', 'skip-build', 'exclude-source-files'] def initialize_options(self): self.bdist_dir = None @@ -127,7 +130,7 @@ def do_install_data(self): if normalized == site_packages or normalized.startswith( site_packages + os.sep ): - item = realpath[len(site_packages) + 1:], item[1] + item = realpath[len(site_packages) + 1 :], item[1] # XXX else: raise ??? self.distribution.data_files.append(item) @@ -167,10 +170,9 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME all_outputs, ext_outputs = self.get_ext_outputs() self.stubs = [] to_compile = [] - for (p, ext_name) in enumerate(ext_outputs): + for p, ext_name in enumerate(ext_outputs): filename, ext = os.path.splitext(ext_name) - pyfile = os.path.join(self.bdist_dir, strip_module(filename) + - '.py') + pyfile = os.path.join(self.bdist_dir, strip_module(filename) + '.py') self.stubs.append(pyfile) log.info("creating stub loader for %s", ext_name) if not self.dry_run: @@ -190,8 +192,7 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME if self.distribution.scripts: script_dir = os.path.join(egg_info, 'scripts') log.info("installing scripts to %s", script_dir) - self.call_command('install_scripts', install_dir=script_dir, - no_ep=1) + self.call_command('install_scripts', install_dir=script_dir, no_ep=1) self.copy_metadata_to(egg_info) native_libs = os.path.join(egg_info, "native_libs.txt") @@ -208,9 +209,7 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME if not self.dry_run: os.unlink(native_libs) - write_safety_flag( - os.path.join(archive_root, 'EGG-INFO'), self.zip_safe() - ) + write_safety_flag(os.path.join(archive_root, 'EGG-INFO'), self.zip_safe()) if os.path.exists(os.path.join(self.egg_info, 'depends.txt')): log.warn( @@ -222,14 +221,20 @@ def run(self): # noqa: C901 # is too complex (14) # FIXME self.zap_pyfiles() # Make the archive - make_zipfile(self.egg_output, archive_root, verbose=self.verbose, - dry_run=self.dry_run, mode=self.gen_header()) + make_zipfile( + self.egg_output, + archive_root, + verbose=self.verbose, + dry_run=self.dry_run, + mode=self.gen_header(), + ) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) # Add to 'Distribution.dist_files' so that the "upload" command works getattr(self.distribution, 'dist_files', []).append( - ('bdist_egg', get_python_version(), self.egg_output)) + ('bdist_egg', get_python_version(), self.egg_output) + ) def zap_pyfiles(self): log.info("Removing .py files from temporary directory") @@ -246,11 +251,8 @@ def zap_pyfiles(self): pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) - path_new = os.path.join( - base, os.pardir, m.group('name') + '.pyc') - log.info( - "Renaming file from [%s] to [%s]" - % (path_old, path_new)) + path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') + log.info("Renaming file from [%s] to [%s]" % (path_old, path_new)) try: os.remove(path_new) except OSError: @@ -275,7 +277,7 @@ def copy_metadata_to(self, target_dir): prefix = os.path.join(norm_egg_info, '') for path in self.ei_cmd.filelist.files: if path.startswith(prefix): - target = os.path.join(target_dir, path[len(prefix):]) + target = os.path.join(target_dir, path[len(prefix) :]) ensure_directory(target) self.copy_file(path, target) @@ -291,8 +293,7 @@ def get_ext_outputs(self): if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS: all_outputs.append(paths[base] + filename) for filename in dirs: - paths[os.path.join(base, filename)] = (paths[base] + - filename + '/') + paths[os.path.join(base, filename)] = paths[base] + filename + '/' if self.distribution.has_ext_modules(): build_cmd = self.get_finalized_command('build_ext') @@ -365,7 +366,7 @@ def scan_module(egg_dir, base, name, stubs): filename = os.path.join(base, name) if filename[:-1] in stubs: return True # Extension module - pkg = base[len(egg_dir) + 1:].replace(os.sep, '.') + pkg = base[len(egg_dir) + 1 :].replace(os.sep, '.') module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0] if sys.version_info < (3, 7): skip = 12 # skip magic & date & file size @@ -383,9 +384,17 @@ def scan_module(egg_dir, base, name, stubs): safe = False if 'inspect' in symbols: for bad in [ - 'getsource', 'getabsfile', 'getsourcefile', 'getfile' - 'getsourcelines', 'findsource', 'getcomments', 'getframeinfo', - 'getinnerframes', 'getouterframes', 'stack', 'trace' + 'getsource', + 'getabsfile', + 'getsourcefile', + 'getfile' 'getsourcelines', + 'findsource', + 'getcomments', + 'getframeinfo', + 'getinnerframes', + 'getouterframes', + 'stack', + 'trace', ]: if bad in symbols: log.warn("%s: module MAY be using inspect.%s", module, bad) @@ -410,20 +419,19 @@ def can_scan(): # CPython, PyPy, etc. return True log.warn("Unable to analyze compiled code on this platform.") - log.warn("Please ask the author to include a 'zip_safe'" - " setting (either True or False) in the package's setup.py") + log.warn( + "Please ask the author to include a 'zip_safe'" + " setting (either True or False) in the package's setup.py" + ) # Attribute names of options for commands that might need to be convinced to # install to the egg build directory -INSTALL_DIRECTORY_ATTRS = [ - 'install_lib', 'install_dir', 'install_data', 'install_base' -] +INSTALL_DIRECTORY_ATTRS = ['install_lib', 'install_dir', 'install_data', 'install_base'] -def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, - mode='w'): +def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, mode='w'): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed @@ -439,7 +447,7 @@ def visit(z, dirname, names): for name in names: path = os.path.normpath(os.path.join(dirname, name)) if os.path.isfile(path): - p = path[len(base_dir) + 1:] + p = path[len(base_dir) + 1 :] if not dry_run: z.write(path, p) log.debug("adding '%s'", p) diff --git a/uno/lib/python/setuptools/command/bdist_rpm.py b/uno/lib/python/setuptools/command/bdist_rpm.py index 047a6d08..30b7c233 100644 --- a/uno/lib/python/setuptools/command/bdist_rpm.py +++ b/uno/lib/python/setuptools/command/bdist_rpm.py @@ -20,7 +20,7 @@ def run(self): Use bdist_wheel (wheel packages) instead. """, see_url="https://github.com/pypa/setuptools/issues/1988", - due_date=(2023, 10, 30) # Deprecation introduced in 22 Oct 2021. + due_date=(2023, 10, 30), # Deprecation introduced in 22 Oct 2021. ) # ensure distro name is up-to-date @@ -33,11 +33,8 @@ def _make_spec_file(self): spec = [ line.replace( "setup.py install ", - "setup.py install --single-version-externally-managed " - ).replace( - "%setup", - "%setup -n %{name}-%{unmangled_version}" - ) + "setup.py install --single-version-externally-managed ", + ).replace("%setup", "%setup -n %{name}-%{unmangled_version}") for line in spec ] return spec diff --git a/uno/lib/python/setuptools/command/build_clib.py b/uno/lib/python/setuptools/command/build_clib.py index 09483e69..acd4d1d3 100644 --- a/uno/lib/python/setuptools/command/build_clib.py +++ b/uno/lib/python/setuptools/command/build_clib.py @@ -1,7 +1,12 @@ import distutils.command.build_clib as orig from distutils.errors import DistutilsSetupError from distutils import log -from setuptools.dep_util import newer_pairwise_group + +try: + from distutils._modified import newer_pairwise_group +except ImportError: + # fallback for SETUPTOOLS_USE_DISTUTILS=stdlib + from .._distutils._modified import newer_pairwise_group class build_clib(orig.build_clib): @@ -21,13 +26,14 @@ class build_clib(orig.build_clib): """ def build_libraries(self, libraries): - for (lib_name, build_info) in libraries: + for lib_name, build_info in libraries: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'sources' must be present and must be " - "a list of source filenames" % lib_name) + "a list of source filenames" % lib_name + ) sources = sorted(list(sources)) log.info("building '%s' library", lib_name) @@ -40,7 +46,8 @@ def build_libraries(self, libraries): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "type 'source: list'" % lib_name + ) dependencies = [] # Get the global dependencies that are specified by the '' key. @@ -50,7 +57,8 @@ def build_libraries(self, libraries): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "type 'source: list'" % lib_name + ) # Build the list to be used by newer_pairwise_group # each source will be auto-added to its dependencies. @@ -62,7 +70,8 @@ def build_libraries(self, libraries): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "type 'source: list'" % lib_name + ) src_deps.extend(extra_deps) dependencies.append(src_deps) @@ -71,10 +80,7 @@ def build_libraries(self, libraries): output_dir=self.build_temp, ) - if ( - newer_pairwise_group(dependencies, expected_objects) - != ([], []) - ): + if newer_pairwise_group(dependencies, expected_objects) != ([], []): # First, compile the source code to object files in the library # directory. (This should probably change to putting object # files in a temporary build directory.) @@ -87,15 +93,12 @@ def build_libraries(self, libraries): macros=macros, include_dirs=include_dirs, extra_postargs=cflags, - debug=self.debug + debug=self.debug, ) # Now "link" the object files together into a static library. # (On Unix at least, this isn't really linking -- it just # builds an archive. Whatever.) self.compiler.create_static_lib( - expected_objects, - lib_name, - output_dir=self.build_clib, - debug=self.debug + expected_objects, lib_name, output_dir=self.build_clib, debug=self.debug ) diff --git a/uno/lib/python/setuptools/command/build_ext.py b/uno/lib/python/setuptools/command/build_ext.py index cbfe3ec1..9a80781c 100644 --- a/uno/lib/python/setuptools/command/build_ext.py +++ b/uno/lib/python/setuptools/command/build_ext.py @@ -4,6 +4,7 @@ from importlib.machinery import EXTENSION_SUFFIXES from importlib.util import cache_from_source as _compiled_file_name from typing import Dict, Iterator, List, Tuple +from pathlib import Path from distutils.command.build_ext import build_ext as _du_build_ext from distutils.ccompiler import new_compiler @@ -16,6 +17,7 @@ try: # Attempt to use Cython for building extensions, if available from Cython.Distutils.build_ext import build_ext as _build_ext + # Additionally, assert that the compiler module will load # also. Ref #1229. __import__('Cython.Compiler.Main') @@ -35,8 +37,9 @@ def _customize_compiler_for_shlib(compiler): tmp = _CONFIG_VARS.copy() try: # XXX Help! I don't have any idea whether these are right... - _CONFIG_VARS['LDSHARED'] = ( - "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup") + _CONFIG_VARS[ + 'LDSHARED' + ] = "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup" _CONFIG_VARS['CCSHARED'] = " -dynamiclib" _CONFIG_VARS['SO'] = ".dylib" customize_compiler(compiler) @@ -56,6 +59,7 @@ def _customize_compiler_for_shlib(compiler): elif os.name != 'nt': try: import dl + use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW') except ImportError: pass @@ -155,7 +159,7 @@ def get_ext_filename(self, fullname): ext = self.ext_map[fullname] use_abi3 = getattr(ext, 'py_limited_api') and get_abi3_suffix() if use_abi3: - filename = filename[:-len(so_ext)] + filename = filename[: -len(so_ext)] so_ext = get_abi3_suffix() filename = filename + so_ext if isinstance(ext, Library): @@ -177,8 +181,7 @@ def finalize_options(self): _build_ext.finalize_options(self) self.extensions = self.extensions or [] self.check_extensions_list(self.extensions) - self.shlibs = [ext for ext in self.extensions - if isinstance(ext, Library)] + self.shlibs = [ext for ext in self.extensions if isinstance(ext, Library)] if self.shlibs: self.setup_shlib_compiler() for ext in self.extensions: @@ -215,7 +218,7 @@ def setup_shlib_compiler(self): compiler.set_include_dirs(self.include_dirs) if self.define is not None: # 'define' option is a list of (name,value) tuples - for (name, value) in self.define: + for name, value in self.define: compiler.define_macro(name, value) if self.undef is not None: for macro in self.undef: @@ -259,6 +262,47 @@ def links_to_dynamic(self, ext): pkg = '.'.join(ext._full_name.split('.')[:-1] + ['']) return any(pkg + libname in libnames for libname in ext.libraries) + def get_source_files(self) -> List[str]: + return [*_build_ext.get_source_files(self), *self._get_internal_depends()] + + def _get_internal_depends(self) -> Iterator[str]: + """Yield ``ext.depends`` that are contained by the project directory""" + project_root = Path(self.distribution.src_root or os.curdir).resolve() + depends = (dep for ext in self.extensions for dep in ext.depends) + + def skip(orig_path: str, reason: str) -> None: + log.info( + "dependency %s won't be automatically " + "included in the manifest: the path %s", + orig_path, + reason, + ) + + for dep in depends: + path = Path(dep) + + if path.is_absolute(): + skip(dep, "must be relative") + continue + + if ".." in path.parts: + skip(dep, "can't have `..` segments") + continue + + try: + resolved = (project_root / path).resolve(strict=True) + except OSError: + skip(dep, "doesn't exist") + continue + + try: + resolved.relative_to(project_root) + except ValueError: + skip(dep, "must be inside the project root") + continue + + yield path.as_posix() + def get_outputs(self) -> List[str]: if self.inplace: return list(self.get_output_mapping().keys()) @@ -297,32 +341,33 @@ def _write_stub_file(self, stub_file: str, ext: Extension, compile=False): if not self.dry_run: f = open(stub_file, 'w') f.write( - '\n'.join([ - "def __bootstrap__():", - " global __bootstrap__, __file__, __loader__", - " import sys, os, pkg_resources, importlib.util" + - if_dl(", dl"), - " __file__ = pkg_resources.resource_filename" - "(__name__,%r)" - % os.path.basename(ext._file_name), - " del __bootstrap__", - " if '__loader__' in globals():", - " del __loader__", - if_dl(" old_flags = sys.getdlopenflags()"), - " old_dir = os.getcwd()", - " try:", - " os.chdir(os.path.dirname(__file__))", - if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), - " spec = importlib.util.spec_from_file_location(", - " __name__, __file__)", - " mod = importlib.util.module_from_spec(spec)", - " spec.loader.exec_module(mod)", - " finally:", - if_dl(" sys.setdlopenflags(old_flags)"), - " os.chdir(old_dir)", - "__bootstrap__()", - "" # terminal \n - ]) + '\n'.join( + [ + "def __bootstrap__():", + " global __bootstrap__, __file__, __loader__", + " import sys, os, pkg_resources, importlib.util" + + if_dl(", dl"), + " __file__ = pkg_resources.resource_filename" + "(__name__,%r)" % os.path.basename(ext._file_name), + " del __bootstrap__", + " if '__loader__' in globals():", + " del __loader__", + if_dl(" old_flags = sys.getdlopenflags()"), + " old_dir = os.getcwd()", + " try:", + " os.chdir(os.path.dirname(__file__))", + if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), + " spec = importlib.util.spec_from_file_location(", + " __name__, __file__)", + " mod = importlib.util.module_from_spec(spec)", + " spec.loader.exec_module(mod)", + " finally:", + if_dl(" sys.setdlopenflags(old_flags)"), + " os.chdir(old_dir)", + "__bootstrap__()", + "", # terminal \n + ] + ) ) f.close() if compile: @@ -331,12 +376,12 @@ def _write_stub_file(self, stub_file: str, ext: Extension, compile=False): def _compile_and_remove_stub(self, stub_file: str): from distutils.util import byte_compile - byte_compile([stub_file], optimize=0, - force=True, dry_run=self.dry_run) + byte_compile([stub_file], optimize=0, force=True, dry_run=self.dry_run) optimize = self.get_finalized_command('install_lib').optimize if optimize > 0: - byte_compile([stub_file], optimize=optimize, - force=True, dry_run=self.dry_run) + byte_compile( + [stub_file], optimize=optimize, force=True, dry_run=self.dry_run + ) if os.path.exists(stub_file) and not self.dry_run: os.unlink(stub_file) @@ -345,25 +390,55 @@ def _compile_and_remove_stub(self, stub_file: str): # Build shared libraries # def link_shared_object( - self, objects, output_libname, output_dir=None, libraries=None, - library_dirs=None, runtime_library_dirs=None, export_symbols=None, - debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, - target_lang=None): + self, + objects, + output_libname, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None, + ): self.link( - self.SHARED_LIBRARY, objects, output_libname, - output_dir, libraries, library_dirs, runtime_library_dirs, - export_symbols, debug, extra_preargs, extra_postargs, - build_temp, target_lang + self.SHARED_LIBRARY, + objects, + output_libname, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + export_symbols, + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang, ) + else: # Build static libraries everywhere else libtype = 'static' def link_shared_object( - self, objects, output_libname, output_dir=None, libraries=None, - library_dirs=None, runtime_library_dirs=None, export_symbols=None, - debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, - target_lang=None): + self, + objects, + output_libname, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None, + ): # XXX we need to either disallow these attrs on Library instances, # or warn/abort here if set, or something... # libraries=None, library_dirs=None, runtime_library_dirs=None, @@ -378,6 +453,4 @@ def link_shared_object( # a different prefix basename = basename[3:] - self.create_static_lib( - objects, basename, output_dir, debug, target_lang - ) + self.create_static_lib(objects, basename, output_dir, debug, target_lang) diff --git a/uno/lib/python/setuptools/command/build_py.py b/uno/lib/python/setuptools/command/build_py.py index f094496e..cbdd05aa 100644 --- a/uno/lib/python/setuptools/command/build_py.py +++ b/uno/lib/python/setuptools/command/build_py.py @@ -5,7 +5,6 @@ import os import fnmatch import textwrap -import io import distutils.errors import itertools import stat @@ -16,6 +15,9 @@ from ..warnings import SetuptoolsDeprecationWarning +_IMPLICIT_DATA_FILES = ('*.pyi', 'py.typed') + + def make_writable(target): os.chmod(target, os.stat(target).st_mode | stat.S_IWRITE) @@ -29,6 +31,7 @@ class build_py(orig.build_py): Also, this version of the 'build_py' command allows you to specify both 'py_modules' and 'packages' in the same setup operation. """ + editable_mode: bool = False existing_egg_info_dir: Optional[str] = None #: Private API, internal use only. @@ -40,14 +43,16 @@ def finalize_options(self): del self.__dict__['data_files'] self.__updated_files = [] - def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, - link=None, level=1): + def copy_file( + self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1 + ): # Overwrite base class to allow using links if link: infile = str(Path(infile).resolve()) outfile = str(Path(outfile).resolve()) - return super().copy_file(infile, outfile, preserve_mode, preserve_times, - link, level) + return super().copy_file( + infile, outfile, preserve_mode, preserve_times, link, level + ) def run(self): """Build modules, packages, and copy data files to build directory""" @@ -113,6 +118,7 @@ def find_data_files(self, package, src_dir): self.package_data, package, src_dir, + extra_patterns=_IMPLICIT_DATA_FILES, ) globs_expanded = map(partial(glob, recursive=True), patterns) # flatten the expanded globs into an iterable of matches @@ -140,7 +146,7 @@ def get_output_mapping(self) -> Dict[str, str]: def _get_module_mapping(self) -> Iterator[Tuple[str, str]]: """Iterate over all modules producing (dest, src) pairs.""" - for (package, module, module_file) in self.find_all_modules(): + for package, module, module_file in self.find_all_modules(): package = package.split('.') filename = self.get_module_outfile(self.build_lib, package, module) yield (filename, module_file) @@ -242,7 +248,7 @@ def check_package(self, package, package_dir): else: return init_py - with io.open(init_py, 'rb') as f: + with open(init_py, 'rb') as f: contents = f.read() if b'declare_namespace' not in contents: raise distutils.errors.DistutilsError( @@ -282,7 +288,7 @@ def exclude_data_files(self, package, src_dir, files): return list(unique_everseen(keepers)) @staticmethod - def _get_platform_patterns(spec, package, src_dir): + def _get_platform_patterns(spec, package, src_dir, extra_patterns=[]): """ yield platform-specific path patterns (suitable for glob or fn_match) from a glob-based spec (such as @@ -290,6 +296,7 @@ def _get_platform_patterns(spec, package, src_dir): matching package in src_dir. """ raw_patterns = itertools.chain( + extra_patterns, spec.get('', []), spec.get(package, []), ) @@ -371,7 +378,7 @@ def __init__(self): self._already_warned = set() def is_module(self, file): - return file.endswith(".py") and file[:-len(".py")].isidentifier() + return file.endswith(".py") and file[: -len(".py")].isidentifier() def importable_subpackage(self, parent, file): pkg = Path(file).parent diff --git a/uno/lib/python/setuptools/command/develop.py b/uno/lib/python/setuptools/command/develop.py index 20e3e171..ea3e48e5 100644 --- a/uno/lib/python/setuptools/command/develop.py +++ b/uno/lib/python/setuptools/command/develop.py @@ -3,7 +3,6 @@ from distutils.errors import DistutilsOptionError import os import glob -import io from setuptools.command.easy_install import easy_install from setuptools import _path @@ -90,9 +89,7 @@ def _resolve_setup_path(egg_base, install_dir, egg_path): path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') if path_to_setup != os.curdir: path_to_setup = '../' * (path_to_setup.count('/') + 1) - resolved = _path.normpath( - os.path.join(install_dir, egg_path, path_to_setup) - ) + resolved = _path.normpath(os.path.join(install_dir, egg_path, path_to_setup)) curdir = _path.normpath(os.curdir) if resolved != curdir: raise DistutilsOptionError( @@ -156,7 +153,7 @@ def install_egg_scripts(self, dist): for script_name in self.distribution.scripts or []: script_path = os.path.abspath(convert_path(script_name)) script_name = os.path.basename(script_path) - with io.open(script_path) as strm: + with open(script_path) as strm: script_text = strm.read() self.install_script(dist, script_name, script_text, script_path) diff --git a/uno/lib/python/setuptools/command/dist_info.py b/uno/lib/python/setuptools/command/dist_info.py index 99d3976d..5ef32216 100644 --- a/uno/lib/python/setuptools/command/dist_info.py +++ b/uno/lib/python/setuptools/command/dist_info.py @@ -12,7 +12,6 @@ from pathlib import Path from .. import _normalization -from ..warnings import SetuptoolsDeprecationWarning class dist_info(Command): @@ -24,11 +23,12 @@ class dist_info(Command): description = "DO NOT CALL DIRECTLY, INTERNAL ONLY: create .dist-info directory" user_options = [ - ('egg-base=', 'e', "directory containing .egg-info directories" - " (default: top of the source tree)" - " DEPRECATED: use --output-dir."), - ('output-dir=', 'o', "directory inside of which the .dist-info will be" - "created (default: top of the source tree)"), + ( + 'output-dir=', + 'o', + "directory inside of which the .dist-info will be" + "created (default: top of the source tree)", + ), ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"), ('tag-build=', 'b', "Specify explicit tag to add to version number"), ('no-date', 'D', "Don't include date stamp [default]"), @@ -39,7 +39,6 @@ class dist_info(Command): negative_opt = {'no-date': 'tag-date'} def initialize_options(self): - self.egg_base = None self.output_dir = None self.name = None self.dist_info_dir = None @@ -48,13 +47,6 @@ def initialize_options(self): self.keep_egg_info = False def finalize_options(self): - if self.egg_base: - msg = "--egg-base is deprecated for dist_info command. Use --output-dir." - SetuptoolsDeprecationWarning.emit(msg, due_date=(2023, 9, 26)) - # This command is internal to setuptools, therefore it should be safe - # to remove the deprecated support soon. - self.output_dir = self.egg_base or self.output_dir - dist = self.distribution project_dir = dist.src_root or os.curdir self.output_dir = Path(self.output_dir or project_dir) diff --git a/uno/lib/python/setuptools/command/easy_install.py b/uno/lib/python/setuptools/command/easy_install.py index 0b8d1159..5d6fd5ca 100644 --- a/uno/lib/python/setuptools/command/easy_install.py +++ b/uno/lib/python/setuptools/command/easy_install.py @@ -14,8 +14,10 @@ from distutils.util import get_platform from distutils.util import convert_path, subst_vars from distutils.errors import ( - DistutilsArgError, DistutilsOptionError, - DistutilsError, DistutilsPlatformError, + DistutilsArgError, + DistutilsOptionError, + DistutilsError, + DistutilsPlatformError, ) from distutils import log, dir_util from distutils.command.build_scripts import first_line_re @@ -49,16 +51,27 @@ from setuptools.command import setopt from setuptools.archive_util import unpack_archive from setuptools.package_index import ( - PackageIndex, parse_requirement_arg, URL_SCHEME, + PackageIndex, + parse_requirement_arg, + URL_SCHEME, ) from setuptools.command import bdist_egg, egg_info from setuptools.warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning from setuptools.wheel import Wheel from pkg_resources import ( - normalize_path, resource_string, - get_distribution, find_distributions, Environment, Requirement, - Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, - VersionConflict, DEVELOP_DIST, + normalize_path, + resource_string, + get_distribution, + find_distributions, + Environment, + Requirement, + Distribution, + PathMetadata, + EggMetadata, + WorkingSet, + DistributionNotFound, + VersionConflict, + DEVELOP_DIST, ) import pkg_resources from .. import py312compat @@ -70,7 +83,9 @@ warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) __all__ = [ - 'easy_install', 'PthDistributions', 'extract_wininst_cfg', + 'easy_install', + 'PthDistributions', + 'extract_wininst_cfg', 'get_exe_prefixes', ] @@ -97,6 +112,7 @@ def _one_liner(text): class easy_install(Command): """Manage a download/build/install process""" + description = "Find/get/install Python packages" command_consumes_arguments = True @@ -111,30 +127,39 @@ class easy_install(Command): ("always-copy", "a", "Copy all needed packages to install dir"), ("index-url=", "i", "base URL of Python Package Index"), ("find-links=", "f", "additional URL(s) to search for packages"), - ("build-directory=", "b", - "download/extract/build in DIR; keep the results"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - ('record=', None, - "filename in which to record list of installed files"), + ("build-directory=", "b", "download/extract/build in DIR; keep the results"), + ( + 'optimize=', + 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]", + ), + ('record=', None, "filename in which to record list of installed files"), ('always-unzip', 'Z', "don't install as a zipfile, no matter what"), ('site-dirs=', 'S', "list of directories where .pth files work"), ('editable', 'e', "Install specified packages in editable form"), ('no-deps', 'N', "don't install dependencies"), ('allow-hosts=', 'H', "pattern(s) that hostnames must match"), - ('local-snapshots-ok', 'l', - "allow building eggs from local checkouts"), + ('local-snapshots-ok', 'l', "allow building eggs from local checkouts"), ('version', None, "print version information and exit"), - ('no-find-links', None, - "Don't load find-links defined in packages being installed"), - ('user', None, "install in user site-package '%s'" % site.USER_SITE) + ( + 'no-find-links', + None, + "Don't load find-links defined in packages being installed", + ), + ('user', None, "install in user site-package '%s'" % site.USER_SITE), ] boolean_options = [ - 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', + 'zip-ok', + 'multi-version', + 'exclude-scripts', + 'upgrade', + 'always-copy', 'editable', - 'no-deps', 'local-snapshots-ok', 'version', - 'user' + 'no-deps', + 'local-snapshots-ok', + 'version', + 'user', ] negative_opt = {'always-unzip': 'zip-ok'} @@ -187,7 +212,8 @@ def initialize_options(self): def delete_blockers(self, blockers): extant_blockers = ( - filename for filename in blockers + filename + for filename in blockers if os.path.exists(filename) or os.path.islink(filename) ) list(map(self._delete_path, extant_blockers)) @@ -219,25 +245,31 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME self.config_vars = dict(sysconfig.get_config_vars()) - self.config_vars.update({ - 'dist_name': self.distribution.get_name(), - 'dist_version': self.distribution.get_version(), - 'dist_fullname': self.distribution.get_fullname(), - 'py_version': py_version, - 'py_version_short': f'{sys.version_info.major}.{sys.version_info.minor}', - 'py_version_nodot': f'{sys.version_info.major}{sys.version_info.minor}', - 'sys_prefix': self.config_vars['prefix'], - 'sys_exec_prefix': self.config_vars['exec_prefix'], - # Only python 3.2+ has abiflags - 'abiflags': getattr(sys, 'abiflags', ''), - 'platlibdir': getattr(sys, 'platlibdir', 'lib'), - }) + self.config_vars.update( + { + 'dist_name': self.distribution.get_name(), + 'dist_version': self.distribution.get_version(), + 'dist_fullname': self.distribution.get_fullname(), + 'py_version': py_version, + 'py_version_short': ( + f'{sys.version_info.major}.{sys.version_info.minor}' + ), + 'py_version_nodot': f'{sys.version_info.major}{sys.version_info.minor}', + 'sys_prefix': self.config_vars['prefix'], + 'sys_exec_prefix': self.config_vars['exec_prefix'], + # Only python 3.2+ has abiflags + 'abiflags': getattr(sys, 'abiflags', ''), + 'platlibdir': getattr(sys, 'platlibdir', 'lib'), + } + ) with contextlib.suppress(AttributeError): # only for distutils outside stdlib - self.config_vars.update({ - 'implementation_lower': install._get_implementation().lower(), - 'implementation': install._get_implementation(), - }) + self.config_vars.update( + { + 'implementation_lower': install._get_implementation().lower(), + 'implementation': install._get_implementation(), + } + ) # pypa/distutils#113 Python 3.9 compat self.config_vars.setdefault( @@ -256,7 +288,9 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME self.expand_dirs() self._expand( - 'install_dir', 'script_dir', 'build_directory', + 'install_dir', + 'script_dir', + 'build_directory', 'site_dirs', ) # If a non-default installation directory was specified, default the @@ -270,13 +304,9 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME # Let install_dir get set by install_lib command, which in turn # gets its info from the install command, and takes into account # --prefix and --home and all that other crud. - self.set_undefined_options( - 'install_lib', ('install_dir', 'install_dir') - ) + self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) # Likewise, set default script_dir from 'install_scripts.install_dir' - self.set_undefined_options( - 'install_scripts', ('install_dir', 'script_dir') - ) + self.set_undefined_options('install_scripts', ('install_dir', 'script_dir')) if self.user and self.install_purelib: self.install_dir = self.install_purelib @@ -302,7 +332,9 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME hosts = ['*'] if self.package_index is None: self.package_index = self.create_index( - self.index_url, search_path=self.shadow_path, hosts=hosts, + self.index_url, + search_path=self.shadow_path, + hosts=hosts, ) self.local_index = Environment(self.shadow_path + sys.path) @@ -324,7 +356,8 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME ) if not self.args: raise DistutilsArgError( - "No urls, filenames, or requirements specified (see --help)") + "No urls, filenames, or requirements specified (see --help)" + ) self.outputs = [] @@ -334,17 +367,12 @@ def _process_site_dirs(site_dirs): return normpath = map(normalize_path, sys.path) - site_dirs = [ - os.path.expanduser(s.strip()) for s in - site_dirs.split(',') - ] + site_dirs = [os.path.expanduser(s.strip()) for s in site_dirs.split(',')] for d in site_dirs: if not os.path.isdir(d): log.warn("%s (in --site-dirs) does not exist", d) elif normalize_path(d) not in normpath: - raise DistutilsOptionError( - d + " (in --site-dirs) is not on sys.path" - ) + raise DistutilsOptionError(d + " (in --site-dirs) is not on sys.path") else: yield normalize_path(d) @@ -355,9 +383,7 @@ def _validate_optimize(value): if value not in range(3): raise ValueError except ValueError as e: - raise DistutilsOptionError( - "--optimize must be 0, 1, or 2" - ) from e + raise DistutilsOptionError("--optimize must be 0, 1, or 2") from e return value @@ -423,9 +449,9 @@ def run(self, show_deprecation=True): from distutils import file_util self.execute( - file_util.write_file, (self.record, outputs), - "writing list of installed files to '%s'" % - self.record + file_util.write_file, + (self.record, outputs), + "writing list of installed files to '%s'" % self.record, ) self.warn_deprecated_options() finally: @@ -454,7 +480,7 @@ def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME if not os.path.exists(instdir): try: os.makedirs(instdir) - except (OSError, IOError): + except OSError: self.cant_write_to_target() # Is it a configured, PYTHONPATH, implicit, or explicit site dir? @@ -472,7 +498,7 @@ def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME os.unlink(testfile) open(testfile, 'w').close() os.unlink(testfile) - except (OSError, IOError): + except OSError: self.cant_write_to_target() if not is_site_dir and not self.multi_version: @@ -490,7 +516,8 @@ def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME self.pth_file = None # don't create a .pth file self.install_dir = instdir - __cant_write_msg = textwrap.dedent(""" + __cant_write_msg = textwrap.dedent( + """ can't create or remove files in install directory The following error occurred while trying to add or remove files in the @@ -502,15 +529,19 @@ def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME the distutils default setting) was: %s - """).lstrip() # noqa + """ + ).lstrip() # noqa - __not_exists_id = textwrap.dedent(""" + __not_exists_id = textwrap.dedent( + """ This directory does not currently exist. Please create it and try again, or choose a different installation directory (using the -d or --install-dir option). - """).lstrip() # noqa + """ + ).lstrip() # noqa - __access_msg = textwrap.dedent(""" + __access_msg = textwrap.dedent( + """ Perhaps your account does not have write access to this directory? If the installation directory is a system-owned directory, you may need to sign in as the administrator or "root" account. If you do not have administrative @@ -524,10 +555,14 @@ def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME https://setuptools.pypa.io/en/latest/deprecated/easy_install.html Please make the appropriate changes for your system and try again. - """).lstrip() # noqa + """ + ).lstrip() # noqa def cant_write_to_target(self): - msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) + msg = self.__cant_write_msg % ( + sys.exc_info()[1], + self.install_dir, + ) if not os.path.exists(self.install_dir): msg += '\n' + self.__not_exists_id @@ -542,19 +577,24 @@ def check_pth_processing(self): pth_file = self.pseudo_tempname() + ".pth" ok_file = pth_file + '.ok' ok_exists = os.path.exists(ok_file) - tmpl = _one_liner(""" + tmpl = ( + _one_liner( + """ import os f = open({ok_file!r}, 'w') f.write('OK') f.close() - """) + '\n' + """ + ) + + '\n' + ) try: if ok_exists: os.unlink(ok_file) dirname = os.path.dirname(ok_file) os.makedirs(dirname, exist_ok=True) f = open(pth_file, 'w') - except (OSError, IOError): + except OSError: self.cant_write_to_target() else: try: @@ -565,10 +605,7 @@ def check_pth_processing(self): if os.name == 'nt': dirname, basename = os.path.split(executable) alt = os.path.join(dirname, 'pythonw.exe') - use_alt = ( - basename.lower() == 'python.exe' and - os.path.exists(alt) - ) + use_alt = basename.lower() == 'python.exe' and os.path.exists(alt) if use_alt: # use pythonw.exe to avoid opening a console window executable = alt @@ -578,10 +615,7 @@ def check_pth_processing(self): spawn([executable, '-E', '-c', 'pass'], 0) if os.path.exists(ok_file): - log.info( - "TEST PASSED: %s appears to support .pth files", - instdir - ) + log.info("TEST PASSED: %s appears to support .pth files", instdir) return True finally: if f: @@ -603,8 +637,7 @@ def install_egg_scripts(self, dist): # __pycache__ directory, so skip it. continue self.install_script( - dist, script_name, - dist.get_metadata('scripts/' + script_name) + dist, script_name, dist.get_metadata('scripts/' + script_name) ) self.install_wrapper_scripts(dist) @@ -620,8 +653,7 @@ def not_editable(self, spec): if self.editable: raise DistutilsArgError( "Invalid argument %r: you can't use filenames or URLs " - "with --editable (except via the --find-links option)." - % (spec,) + "with --editable (except via the --find-links option)." % (spec,) ) def check_editable(self, spec): @@ -630,8 +662,8 @@ def check_editable(self, spec): if os.path.exists(os.path.join(self.build_directory, spec.key)): raise DistutilsArgError( - "%r already exists in %s; can't do a checkout there" % - (spec.key, self.build_directory) + "%r already exists in %s; can't do a checkout there" + % (spec.key, self.build_directory) ) @contextlib.contextmanager @@ -661,8 +693,12 @@ def easy_install(self, spec, deps=False): self.check_editable(spec) dist = self.package_index.fetch_distribution( - spec, tmpdir, self.upgrade, self.editable, - not self.always_copy, self.local_index + spec, + tmpdir, + self.upgrade, + self.editable, + not self.always_copy, + self.local_index, ) if dist is None: msg = "Could not find suitable distribution for %r" % spec @@ -677,15 +713,14 @@ def easy_install(self, spec, deps=False): return self.install_item(spec, dist.location, tmpdir, deps) def install_item(self, spec, download, tmpdir, deps, install_needed=False): - # Installation is also needed if file in tmpdir or is not an egg install_needed = install_needed or self.always_copy install_needed = install_needed or os.path.dirname(download) == tmpdir install_needed = install_needed or not download.endswith('.egg') install_needed = install_needed or ( - self.always_copy_from is not None and - os.path.dirname(normalize_path(download)) == - normalize_path(self.always_copy_from) + self.always_copy_from is not None + and os.path.dirname(normalize_path(download)) + == normalize_path(self.always_copy_from) ) if spec and not install_needed: @@ -721,7 +756,11 @@ def select_scheme(self, name): # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 - self, requirement, dist, deps=True, *info, + self, + requirement, + dist, + deps=True, + *info, ): self.update_pth(dist) self.package_index.add(dist) @@ -731,8 +770,7 @@ def process_distribution( # noqa: C901 self.install_egg_scripts(dist) self.installed_projects[dist.key] = dist log.info(self.installation_report(requirement, dist, *info)) - if (dist.has_metadata('dependency_links.txt') and - not self.no_find_links): + if dist.has_metadata('dependency_links.txt') and not self.no_find_links: self.package_index.add_find_links( dist.get_metadata_lines('dependency_links.txt') ) @@ -773,9 +811,7 @@ def should_unzip(self, dist): def maybe_move(self, spec, dist_filename, setup_base): dst = os.path.join(self.build_directory, spec.key) if os.path.exists(dst): - msg = ( - "%r already exists in %s; build directory %s will not be kept" - ) + msg = "%r already exists in %s; build directory %s will not be kept" log.warn(msg, spec.key, self.build_directory, setup_base) return setup_base if os.path.isdir(dist_filename): @@ -852,9 +888,7 @@ def install_eggs(self, spec, dist_filename, tmpdir): '.whl': self.install_wheel, } try: - install_dist = installer_map[ - dist_filename.lower()[-4:] - ] + install_dist = installer_map[dist_filename.lower()[-4:]] except KeyError: pass else: @@ -867,8 +901,11 @@ def install_eggs(self, spec, dist_filename, tmpdir): elif os.path.isdir(dist_filename): setup_base = os.path.abspath(dist_filename) - if (setup_base.startswith(tmpdir) # something we downloaded - and self.build_directory and spec is not None): + if ( + setup_base.startswith(tmpdir) # something we downloaded + and self.build_directory + and spec is not None + ): setup_base = self.maybe_move(spec, dist_filename, setup_base) # Find the setup.py file @@ -878,13 +915,12 @@ def install_eggs(self, spec, dist_filename, tmpdir): setups = glob(os.path.join(setup_base, '*', 'setup.py')) if not setups: raise DistutilsError( - "Couldn't find a setup script in %s" % - os.path.abspath(dist_filename) + "Couldn't find a setup script in %s" + % os.path.abspath(dist_filename) ) if len(setups) > 1: raise DistutilsError( - "Multiple setup scripts in %s" % - os.path.abspath(dist_filename) + "Multiple setup scripts in %s" % os.path.abspath(dist_filename) ) setup_script = setups[0] @@ -897,8 +933,7 @@ def install_eggs(self, spec, dist_filename, tmpdir): def egg_distribution(self, egg_path): if os.path.isdir(egg_path): - metadata = PathMetadata(egg_path, os.path.join(egg_path, - 'EGG-INFO')) + metadata = PathMetadata(egg_path, os.path.join(egg_path, 'EGG-INFO')) else: metadata = EggMetadata(zipimport.zipimporter(egg_path)) return Distribution.from_filename(egg_path, metadata=metadata) @@ -944,10 +979,8 @@ def install_egg(self, egg_path, tmpdir): # noqa: C901 self.execute( f, (egg_path, destination), - (m + " %s to %s") % ( - os.path.basename(egg_path), - os.path.dirname(destination) - ), + (m + " %s to %s") + % (os.path.basename(egg_path), os.path.dirname(destination)), ) update_dist_caches( destination, @@ -971,7 +1004,8 @@ def install_exe(self, dist_filename, tmpdir): dist = Distribution( None, project_name=cfg.get('metadata', 'name'), - version=cfg.get('metadata', 'version'), platform=get_platform(), + version=cfg.get('metadata', 'version'), + platform=get_platform(), ) # Convert the .exe to an unpacked egg @@ -994,13 +1028,15 @@ def install_exe(self, dist_filename, tmpdir): f.close() script_dir = os.path.join(_egg_info, 'scripts') # delete entry-point scripts to avoid duping - self.delete_blockers([ - os.path.join(script_dir, args[0]) - for args in ScriptWriter.get_args(dist) - ]) + self.delete_blockers( + [os.path.join(script_dir, args[0]) for args in ScriptWriter.get_args(dist)] + ) # Build .egg file from tmpdir bdist_egg.make_zipfile( - egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run, + egg_path, + egg_tmp, + verbose=self.verbose, + dry_run=self.dry_run, ) # install the .egg return self.install_egg(egg_path, tmpdir) @@ -1018,7 +1054,7 @@ def process(src, dst): s = src.lower() for old, new in prefixes: if s.startswith(old): - src = new + src[len(old):] + src = new + src[len(old) :] parts = src.split('/') dst = os.path.join(egg_tmp, *parts) dl = dst.lower() @@ -1048,8 +1084,8 @@ def process(src, dst): bdist_egg.write_stub(resource, pyfile) self.byte_compile(to_compile) # compile .py's bdist_egg.write_safety_flag( - os.path.join(egg_tmp, 'EGG-INFO'), - bdist_egg.analyze_egg(egg_tmp, stubs)) # write zip-safety flag + os.path.join(egg_tmp, 'EGG-INFO'), bdist_egg.analyze_egg(egg_tmp, stubs) + ) # write zip-safety flag for name in 'top_level', 'native_libs': if locals()[name]: @@ -1078,17 +1114,16 @@ def install_wheel(self, wheel_path, tmpdir): self.execute( wheel.install_as_egg, (destination,), - ("Installing %s to %s") % ( - os.path.basename(wheel_path), - os.path.dirname(destination) - ), + ("Installing %s to %s") + % (os.path.basename(wheel_path), os.path.dirname(destination)), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) self.add_output(destination) return self.egg_distribution(destination) - __mv_warning = textwrap.dedent(""" + __mv_warning = textwrap.dedent( + """ Because this distribution was installed --multi-version, before you can import modules from this package in an application, you will need to 'import pkg_resources' and then use a 'require()' call similar to one of @@ -1097,13 +1132,16 @@ def install_wheel(self, wheel_path, tmpdir): pkg_resources.require("%(name)s") # latest installed version pkg_resources.require("%(name)s==%(version)s") # this exact version pkg_resources.require("%(name)s>=%(version)s") # this version or higher - """).lstrip() # noqa + """ + ).lstrip() # noqa - __id_warning = textwrap.dedent(""" + __id_warning = textwrap.dedent( + """ Note also that the installation directory must be on sys.path at runtime for this to work. (e.g. by being the application's script directory, by being on PYTHONPATH, or by being added to sys.path by your code.) - """) # noqa + """ + ) # noqa def installation_report(self, req, dist, what="Installed"): """Helpful installation message for display to package users""" @@ -1119,7 +1157,8 @@ def installation_report(self, req, dist, what="Installed"): extras = '' # TODO: self.report_extras(req, dist) return msg % locals() - __editable_msg = textwrap.dedent(""" + __editable_msg = textwrap.dedent( + """ Extracted editable version of %(spec)s to %(dirname)s If it uses setuptools in its setup script, you can activate it in @@ -1128,7 +1167,8 @@ def installation_report(self, req, dist, what="Installed"): %(python)s setup.py develop See the setuptools documentation for the "develop" command for more info. - """).lstrip() # noqa + """ + ).lstrip() # noqa def report_editable(self, spec, setup_script): dirname = os.path.dirname(setup_script) @@ -1147,15 +1187,11 @@ def run_setup(self, setup_script, setup_base, args): args.insert(0, '-q') if self.dry_run: args.insert(0, '-n') - log.info( - "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args) - ) + log.info("Running %s %s", setup_script[len(setup_base) + 1 :], ' '.join(args)) try: run_setup(setup_script, args) except SystemExit as v: - raise DistutilsError( - "Setup script exited with %s" % (v.args[0],) - ) from v + raise DistutilsError("Setup script exited with %s" % (v.args[0],)) from v def build_and_install(self, setup_script, setup_base): args = ['bdist_egg', '--dist-dir'] @@ -1174,8 +1210,7 @@ def build_and_install(self, setup_script, setup_base): for dist in all_eggs[key]: eggs.append(self.install_egg(dist.location, setup_base)) if not eggs and not self.dry_run: - log.warn("No eggs found in %s (setup script problem?)", - dist_dir) + log.warn("No eggs found in %s (setup script problem?)", dist_dir) return eggs finally: _rmtree(dist_dir) @@ -1192,7 +1227,11 @@ def _set_fetcher_options(self, base): # to the setup.cfg file. ei_opts = self.distribution.get_option_dict('easy_install').copy() fetch_directives = ( - 'find_links', 'site_dirs', 'index_url', 'optimize', 'allow_hosts', + 'find_links', + 'site_dirs', + 'index_url', + 'optimize', + 'allow_hosts', ) fetch_options = {} for key, val in ei_opts.items(): @@ -1282,13 +1321,16 @@ def byte_compile(self, to_compile): byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run) if self.optimize: byte_compile( - to_compile, optimize=self.optimize, force=1, + to_compile, + optimize=self.optimize, + force=1, dry_run=self.dry_run, ) finally: log.set_verbosity(self.verbose) # restore original verbosity - __no_default_msg = textwrap.dedent(""" + __no_default_msg = textwrap.dedent( + """ bad install directory or PYTHONPATH You are attempting to install a package to a directory that is not @@ -1318,7 +1360,8 @@ def byte_compile(self, to_compile): Please make the appropriate changes for your system and try again. - """).strip() + """ + ).strip() def create_home_path(self): """Create directories under ~.""" @@ -1390,20 +1433,24 @@ def get_site_dirs(): if sys.platform in ('os2emx', 'riscos'): sitedirs.append(os.path.join(prefix, "Lib", "site-packages")) elif os.sep == '/': - sitedirs.extend([ - os.path.join( - prefix, - "lib", - "python{}.{}".format(*sys.version_info), - "site-packages", - ), - os.path.join(prefix, "lib", "site-python"), - ]) + sitedirs.extend( + [ + os.path.join( + prefix, + "lib", + "python{}.{}".format(*sys.version_info), + "site-packages", + ), + os.path.join(prefix, "lib", "site-python"), + ] + ) else: - sitedirs.extend([ - prefix, - os.path.join(prefix, "lib", "site-packages"), - ]) + sitedirs.extend( + [ + prefix, + os.path.join(prefix, "lib", "site-packages"), + ] + ) if sys.platform != 'darwin': continue @@ -1631,8 +1678,9 @@ def save(self): last_paths.remove(path) # also, re-check that all paths are still valid before saving them for path in self.paths[:]: - if path not in last_paths \ - and not path.startswith(('import ', 'from ', '#')): + if path not in last_paths and not path.startswith( + ('import ', 'from ', '#') + ): absolute_path = os.path.join(self.basedir, path) if not os.path.exists(absolute_path): self.paths.remove(path) @@ -1665,12 +1713,11 @@ def _wrap_lines(lines): def add(self, dist): """Add `dist` to the distribution map""" - new_path = ( - dist.location not in self.paths and ( - dist.location not in self.sitedirs or - # account for '.' being in PYTHONPATH - dist.location == os.getcwd() - ) + new_path = dist.location not in self.paths and ( + dist.location not in self.sitedirs + or + # account for '.' being in PYTHONPATH + dist.location == os.getcwd() ) if new_path: self.paths.append(dist.location) @@ -1708,18 +1755,22 @@ def _wrap_lines(cls, lines): yield line yield cls.postlude - prelude = _one_liner(""" + prelude = _one_liner( + """ import sys sys.__plen = len(sys.path) - """) - postlude = _one_liner(""" + """ + ) + postlude = _one_liner( + """ import sys new = sys.path[sys.__plen:] del sys.path[sys.__plen:] p = getattr(sys, '__egginsert', 0) sys.path[p:p] = new sys.__egginsert = p + len(new) - """) + """ + ) if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite': @@ -1843,8 +1894,10 @@ def _collect_zipimporter_cache_entries(normalized_path, cache): prefix_len = len(normalized_path) for p in cache: np = normalize_path(p) - if (np.startswith(normalized_path) and - np[prefix_len:prefix_len + 1] in (os.sep, '')): + if np.startswith(normalized_path) and np[prefix_len : prefix_len + 1] in ( + os.sep, + '', + ): result.append(p) return result @@ -1890,8 +1943,10 @@ def clear_and_remove_cached_zip_archive_directory_data(path, old_entry): old_entry.clear() _update_zipimporter_cache( - normalized_path, zipimport._zip_directory_cache, - updater=clear_and_remove_cached_zip_archive_directory_data) + normalized_path, + zipimport._zip_directory_cache, + updater=clear_and_remove_cached_zip_archive_directory_data, + ) # PyPy Python implementation does not allow directly writing to the @@ -1903,8 +1958,7 @@ def clear_and_remove_cached_zip_archive_directory_data(path, old_entry): # instead of being automatically corrected to use the new correct zip archive # directory information. if '__pypy__' in sys.builtin_module_names: - _replace_zip_directory_cache_data = \ - _remove_and_clear_zip_directory_cache_data + _replace_zip_directory_cache_data = _remove_and_clear_zip_directory_cache_data else: def _replace_zip_directory_cache_data(normalized_path): @@ -1922,8 +1976,10 @@ def replace_cached_zip_archive_directory_data(path, old_entry): return old_entry _update_zipimporter_cache( - normalized_path, zipimport._zip_directory_cache, - updater=replace_cached_zip_archive_directory_data) + normalized_path, + zipimport._zip_directory_cache, + updater=replace_cached_zip_archive_directory_data, + ) def is_python(text, filename=''): @@ -1939,9 +1995,9 @@ def is_python(text, filename=''): def is_sh(executable): """Determine if the specified executable is a .sh (contains a #! line)""" try: - with io.open(executable, encoding='latin-1') as fp: + with open(executable, encoding='latin-1') as fp: magic = fp.read(2) - except (OSError, IOError): + except OSError: return executable return magic == '#!' @@ -1952,8 +2008,7 @@ def nt_quote_arg(arg): def is_python_script(script_text, filename): - """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. - """ + """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.""" if filename.endswith('.py') or filename.endswith('.pyw'): return True # extension says it's Python if is_python(script_text, filename): @@ -2060,7 +2115,8 @@ def _strip_quotes(item): @staticmethod def _render(items): cmdline = subprocess.list2cmdline( - CommandSpec._strip_quotes(item.strip()) for item in items) + CommandSpec._strip_quotes(item.strip()) for item in items + ) return '#!' + cmdline + '\n' @@ -2078,7 +2134,8 @@ class ScriptWriter: gui apps. """ - template = textwrap.dedent(r""" + template = textwrap.dedent( + r""" # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r import re import sys @@ -2111,7 +2168,8 @@ def importlib_load_entry_point(spec, group, name): if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit(load_entry_point(%(spec)r, %(group)r, %(name)r)()) - """).lstrip() + """ + ).lstrip() command_spec_class = CommandSpec @@ -2242,8 +2300,9 @@ def _get_script_args(cls, type_, name, header, script_text): blockers = [name + x for x in old] yield (name + ext, hdr + script_text, 't', blockers) yield ( - name + '.exe', get_win_launcher(launcher_type), - 'b' # write in binary mode + name + '.exe', + get_win_launcher(launcher_type), + 'b', # write in binary mode ) if not is_64bit(): # install a manifest for the launcher to prevent Windows diff --git a/uno/lib/python/setuptools/command/editable_wheel.py b/uno/lib/python/setuptools/command/editable_wheel.py index ffcc2cc0..79c839f8 100644 --- a/uno/lib/python/setuptools/command/editable_wheel.py +++ b/uno/lib/python/setuptools/command/editable_wheel.py @@ -11,6 +11,7 @@ """ import logging +import io import os import shutil import sys @@ -340,7 +341,7 @@ def _create_wheel_file(self, bdist_wheel): with unpacked_wheel as unpacked, build_lib as lib, build_tmp as tmp: unpacked_dist_info = Path(unpacked, Path(self.dist_info_dir).name) shutil.copytree(self.dist_info_dir, unpacked_dist_info) - self._install_namespaces(unpacked, dist_info.name) + self._install_namespaces(unpacked, dist_name) files, mapping = self._run_build_commands(dist_name, unpacked, lib, tmp) strategy = self._select_strategy(dist_name, tag, lib) with strategy, WheelFile(wheel_path, "w") as wheel_obj: @@ -401,7 +402,7 @@ def __init__(self, dist: Distribution, name: str, path_entries: List[Path]): def __call__(self, wheel: "WheelFile", files: List[str], mapping: Dict[str, str]): entries = "\n".join((str(p.resolve()) for p in self.path_entries)) - contents = bytes(f"{entries}\n", "utf-8") + contents = _encode_pth(f"{entries}\n") wheel.writestr(f"__editable__.{self.name}.pth", contents) def __enter__(self): @@ -426,8 +427,10 @@ class _LinkTree(_StaticPth): By collocating ``auxiliary_dir`` and the original source code, limitations with hardlinks should be avoided. """ + def __init__( - self, dist: Distribution, + self, + dist: Distribution, name: str, auxiliary_dir: _Path, build_lib: _Path, @@ -457,10 +460,7 @@ def _create_file(self, relative_output: str, src_file: str, link=None): def _create_links(self, outputs, output_mapping): self.auxiliary_dir.mkdir(parents=True, exist_ok=True) link_type = "sym" if _can_symlink_files(self.auxiliary_dir) else "hard" - mappings = { - self._normalize_output(k): v - for k, v in output_mapping.items() - } + mappings = {self._normalize_output(k): v for k, v in output_mapping.items()} mappings.pop(None, None) # remove files that are not relative to build_lib for output in outputs: @@ -498,17 +498,29 @@ def __call__(self, wheel: "WheelFile", files: List[str], mapping: Dict[str, str] package_dir = self.dist.package_dir or {} roots = _find_package_roots(top_level, package_dir, src_root) - namespaces_: Dict[str, List[str]] = dict(chain( - _find_namespaces(self.dist.packages or [], roots), - ((ns, []) for ns in _find_virtual_namespaces(roots)), - )) + namespaces_: Dict[str, List[str]] = dict( + chain( + _find_namespaces(self.dist.packages or [], roots), + ((ns, []) for ns in _find_virtual_namespaces(roots)), + ) + ) + + legacy_namespaces = { + pkg: find_package_path(pkg, roots, self.dist.src_root or "") + for pkg in self.dist.namespace_packages or [] + } + + mapping = {**roots, **legacy_namespaces} + # ^-- We need to explicitly add the legacy_namespaces to the mapping to be + # able to import their modules even if another package sharing the same + # namespace is installed in a conventional (non-editable) way. name = f"__editable__.{self.name}.finder" finder = _normalization.safe_identifier(name) - content = bytes(_finder_template(name, roots, namespaces_), "utf-8") + content = bytes(_finder_template(name, mapping, namespaces_), "utf-8") wheel.writestr(f"{finder}.py", content) - content = bytes(f"import {finder}; {finder}.install()", "utf-8") + content = _encode_pth(f"import {finder}; {finder}.install()") wheel.writestr(f"__editable__.{self.name}.pth", content) def __enter__(self): @@ -524,6 +536,24 @@ def __exit__(self, _exc_type, _exc_value, _traceback): InformationOnly.emit("Editable installation.", msg) +def _encode_pth(content: str) -> bytes: + """.pth files are always read with 'locale' encoding, the recommendation + from the cpython core developers is to write them as ``open(path, "w")`` + and ignore warnings (see python/cpython#77102, pypa/setuptools#3937). + This function tries to simulate this behaviour without having to create an + actual file, in a way that supports a range of active Python versions. + (There seems to be some variety in the way different version of Python handle + ``encoding=None``, not all of them use ``locale.getpreferredencoding(False)``). + """ + encoding = "locale" if sys.version_info >= (3, 10) else None + with io.BytesIO() as buffer: + wrapper = io.TextIOWrapper(buffer, encoding) + wrapper.write(content) + wrapper.flush() + buffer.seek(0) + return buffer.read() + + def _can_symlink_files(base_dir: Path) -> bool: with TemporaryDirectory(dir=str(base_dir.resolve())) as tmp: path1, path2 = Path(tmp, "file1.txt"), Path(tmp, "file2.txt") @@ -575,10 +605,7 @@ def _simple_layout( >>> _simple_layout([], {"a": "_a", "": "src"}, "/tmp/myproj") False """ - layout = { - pkg: find_package_path(pkg, package_dir, project_dir) - for pkg in packages - } + layout = {pkg: find_package_path(pkg, package_dir, project_dir) for pkg in packages} if not layout: return set(package_dir) in ({}, {""}) parent = os.path.commonpath([_parent_path(k, v) for k, v in layout.items()]) @@ -598,7 +625,7 @@ def _parent_path(pkg, pkg_path): >>> _parent_path("b", "src/c") 'src/c' """ - parent = pkg_path[:-len(pkg)] if pkg_path.endswith(pkg) else pkg_path + parent = pkg_path[: -len(pkg)] if pkg_path.endswith(pkg) else pkg_path return parent.rstrip("/" + os.sep) @@ -714,9 +741,8 @@ def _is_nested(pkg: str, pkg_path: str, parent: str, parent_path: str) -> bool: """ norm_pkg_path = _path.normpath(pkg_path) rest = pkg.replace(parent, "", 1).strip(".").split(".") - return ( - pkg.startswith(parent) - and norm_pkg_path == _path.normpath(Path(parent_path, *rest)) + return pkg.startswith(parent) and norm_pkg_path == _path.normpath( + Path(parent_path, *rest) ) @@ -736,9 +762,9 @@ def __init__(self, distribution, installation_dir, editable_name, src_root): self.outputs = [] self.dry_run = False - def _get_target(self): + def _get_nspkg_file(self): """Installation target.""" - return os.path.join(self.installation_dir, self.editable_name) + return os.path.join(self.installation_dir, self.editable_name + self.nspkg_ext) def _get_root(self): """Where the modules/packages should be loaded from.""" @@ -747,7 +773,7 @@ def _get_root(self): _FINDER_TEMPLATE = """\ import sys -from importlib.machinery import ModuleSpec +from importlib.machinery import ModuleSpec, PathFinder from importlib.machinery import all_suffixes as module_suffixes from importlib.util import spec_from_file_location from itertools import chain @@ -761,11 +787,22 @@ def _get_root(self): class _EditableFinder: # MetaPathFinder @classmethod def find_spec(cls, fullname, path=None, target=None): - for pkg, pkg_path in reversed(list(MAPPING.items())): - if fullname == pkg or fullname.startswith(f"{{pkg}}."): - rest = fullname.replace(pkg, "", 1).strip(".").split(".") - return cls._find_spec(fullname, Path(pkg_path, *rest)) - + extra_path = [] + + # Top-level packages and modules (we know these exist in the FS) + if fullname in MAPPING: + pkg_path = MAPPING[fullname] + return cls._find_spec(fullname, Path(pkg_path)) + + # Handle immediate children modules (required for namespaces to work) + # To avoid problems with case sensitivity in the file system we delegate + # to the importlib.machinery implementation. + parent, _, child = fullname.rpartition(".") + if parent and parent in MAPPING: + return PathFinder.find_spec(fullname, path=[MAPPING[parent], *extra_path]) + + # Other levels of nesting should be handled automatically by importlib + # using the parent path. return None @classmethod diff --git a/uno/lib/python/setuptools/command/egg_info.py b/uno/lib/python/setuptools/command/egg_info.py index 66228f9b..7c7f57aa 100644 --- a/uno/lib/python/setuptools/command/egg_info.py +++ b/uno/lib/python/setuptools/command/egg_info.py @@ -12,12 +12,12 @@ import os import re import sys -import io import time import collections from .._importlib import metadata from .. import _entry_points, _normalization +from . import _requirestxt from setuptools import Command from setuptools.command.sdist import sdist @@ -28,7 +28,6 @@ from setuptools.glob import glob from setuptools.extern import packaging -from setuptools.extern.jaraco.text import yield_lines from ..warnings import SetuptoolsDeprecationWarning @@ -93,7 +92,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME pat += re.escape(char) else: # Grab the insides of the [brackets] - inner = chunk[i + 1:inner_i] + inner = chunk[i + 1 : inner_i] char_class = '' # Class negation @@ -128,7 +127,7 @@ def name(self): def tagged_version(self): tagged = self._maybe_tag(self.distribution.get_version()) - return _normalization.best_effort_version(tagged) + return _normalization.safe_version(tagged) def _maybe_tag(self, version): """ @@ -136,7 +135,8 @@ def _maybe_tag(self, version): in which case the version string already contains all tags. """ return ( - version if self.vtags and self._already_tagged(version) + version + if self.vtags and self._already_tagged(version) else version + self.vtags ) @@ -148,7 +148,10 @@ def _already_tagged(self, version: str) -> bool: def _safe_tags(self) -> str: # To implement this we can rely on `safe_version` pretending to be version 0 # followed by tags. Then we simply discard the starting 0 (fake version number) - return _normalization.best_effort_version(f"0{self.vtags}")[1:] + try: + return _normalization.safe_version(f"0{self.vtags}")[1:] + except packaging.version.InvalidVersion: + return _normalization.safe_name(self.vtags.replace(' ', '.')) def tags(self) -> str: version = '' @@ -157,6 +160,7 @@ def tags(self) -> str: if self.tag_date: version += time.strftime("%Y%m%d") return version + vtags = property(tags) @@ -164,8 +168,12 @@ class egg_info(InfoCommon, Command): description = "create a distribution's .egg-info directory" user_options = [ - ('egg-base=', 'e', "directory containing .egg-info directories" - " (default: top of the source tree)"), + ( + 'egg-base=', + 'e', + "directory containing .egg-info directories" + " (default: top of the source tree)", + ), ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"), ('tag-build=', 'b', "Specify explicit tag to add to version number"), ('no-date', 'D', "Don't include date stamp [default]"), @@ -193,6 +201,7 @@ def tag_svn_revision(self): @tag_svn_revision.setter def tag_svn_revision(self, value): pass + #################################### def save_version_info(self, filename): @@ -223,8 +232,8 @@ def finalize_options(self): packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( - "Invalid distribution name or version syntax: %s-%s" % - (self.egg_name, self.egg_version) + "Invalid distribution name or version syntax: %s-%s" + % (self.egg_name, self.egg_version) ) from e if self.egg_base is None: @@ -269,9 +278,7 @@ def write_or_delete_file(self, what, filename, data, force=False): self.write_file(what, filename, data) elif os.path.exists(filename): if data is None and not force: - log.warn( - "%s not set in setup(), but %s exists", what, filename - ) + log.warn("%s not set in setup(), but %s exists", what, filename) return else: self.delete_file(filename) @@ -344,31 +351,28 @@ def process_template_line(self, line): 'global-include': self.global_include, 'global-exclude': self.global_exclude, 'recursive-include': functools.partial( - self.recursive_include, dir, + self.recursive_include, + dir, ), 'recursive-exclude': functools.partial( - self.recursive_exclude, dir, + self.recursive_exclude, + dir, ), 'graft': self.graft, 'prune': self.prune, } log_map = { 'include': "warning: no files found matching '%s'", - 'exclude': ( - "warning: no previously-included files found " - "matching '%s'" - ), + 'exclude': ("warning: no previously-included files found " "matching '%s'"), 'global-include': ( - "warning: no files found matching '%s' " - "anywhere in distribution" + "warning: no files found matching '%s' " "anywhere in distribution" ), 'global-exclude': ( "warning: no previously-included files matching " "'%s' found anywhere in distribution" ), 'recursive-include': ( - "warning: no files found matching '%s' " - "under directory '%s'" + "warning: no files found matching '%s' " "under directory '%s'" ), 'recursive-exclude': ( "warning: no previously-included files matching " @@ -382,8 +386,7 @@ def process_template_line(self, line): process_action = action_map[action] except KeyError: raise DistutilsInternalError( - "this cannot happen: invalid action '{action!s}'". - format(action=action), + "this cannot happen: invalid action '{action!s}'".format(action=action), ) # OK, now we know that the action is valid and we have the @@ -393,14 +396,12 @@ def process_template_line(self, line): action_is_recursive = action.startswith('recursive-') if action in {'graft', 'prune'}: patterns = [dir_pattern] - extra_log_args = (dir, ) if action_is_recursive else () + extra_log_args = (dir,) if action_is_recursive else () log_tmpl = log_map[action] self.debug_print( ' '.join( - [action] + - ([dir] if action_is_recursive else []) + - patterns, + [action] + ([dir] if action_is_recursive else []) + patterns, ) ) for pattern in patterns: @@ -436,8 +437,7 @@ def recursive_include(self, dir, pattern): Include all files anywhere in 'dir/' that match the pattern. """ full_pattern = os.path.join(dir, '**', pattern) - found = [f for f in glob(full_pattern, recursive=True) - if not os.path.isdir(f)] + found = [f for f in glob(full_pattern, recursive=True) if not os.path.isdir(f)] self.extend(found) return bool(found) @@ -623,8 +623,9 @@ def prune_file_list(self): self.filelist.prune(build.build_base) self.filelist.prune(base_dir) sep = re.escape(os.sep) - self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep, - is_regex=1) + self.filelist.exclude_pattern( + r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep, is_regex=1 + ) def _safe_data_files(self, build_py): """ @@ -693,38 +694,14 @@ def warn_depends_obsolete(cmd, basename, filename): """ -def _write_requirements(stream, reqs): - lines = yield_lines(reqs or ()) - - def append_cr(line): - return line + '\n' - lines = map(append_cr, lines) - stream.writelines(lines) - - -def write_requirements(cmd, basename, filename): - dist = cmd.distribution - data = io.StringIO() - _write_requirements(data, dist.install_requires) - extras_require = dist.extras_require or {} - for extra in sorted(extras_require): - data.write('\n[{extra}]\n'.format(**vars())) - _write_requirements(data, extras_require[extra]) - cmd.write_or_delete_file("requirements", filename, data.getvalue()) - - -def write_setup_requirements(cmd, basename, filename): - data = io.StringIO() - _write_requirements(data, cmd.distribution.setup_requires) - cmd.write_or_delete_file("setup-requirements", filename, data.getvalue()) +# Export API used in entry_points +write_requirements = _requirestxt.write_requirements +write_setup_requirements = _requirestxt.write_setup_requirements def write_toplevel_names(cmd, basename, filename): pkgs = dict.fromkeys( - [ - k.split('.', 1)[0] - for k in cmd.distribution.iter_distribution_names() - ] + [k.split('.', 1)[0] for k in cmd.distribution.iter_distribution_names()] ) cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') diff --git a/uno/lib/python/setuptools/command/install.py b/uno/lib/python/setuptools/command/install.py index 73caacb0..606cce9d 100644 --- a/uno/lib/python/setuptools/command/install.py +++ b/uno/lib/python/setuptools/command/install.py @@ -17,11 +17,15 @@ class install(orig.install): user_options = orig.install.user_options + [ ('old-and-unmanageable', None, "Try not to use this!"), - ('single-version-externally-managed', None, - "used by system package builders to create 'flat' eggs"), + ( + 'single-version-externally-managed', + None, + "used by system package builders to create 'flat' eggs", + ), ] boolean_options = orig.install.boolean_options + [ - 'old-and-unmanageable', 'single-version-externally-managed', + 'old-and-unmanageable', + 'single-version-externally-managed', ] new_commands = [ ('install_egg_info', lambda self: True), @@ -100,7 +104,7 @@ def _called_from_setup(run_frame): frames = inspect.getouterframes(run_frame) for frame in frames[2:4]: - caller, = frame[:1] + (caller,) = frame[:1] info = inspect.getframeinfo(caller) caller_module = caller.f_globals.get('__name__', '') @@ -108,17 +112,16 @@ def _called_from_setup(run_frame): # Starting from v61.0.0 setuptools overwrites dist.run_command continue - return ( - caller_module == 'distutils.dist' - and info.function == 'run_commands' - ) + return caller_module == 'distutils.dist' and info.function == 'run_commands' def do_egg_install(self): - easy_install = self.distribution.get_command_class('easy_install') cmd = easy_install( - self.distribution, args="x", root=self.root, record=self.record, + self.distribution, + args="x", + root=self.root, + record=self.record, ) cmd.ensure_finalized() # finalize before bdist_egg munges install cmd cmd.always_copy_from = '.' # make sure local-dir eggs get installed @@ -139,7 +142,6 @@ def do_egg_install(self): # XXX Python 3.1 doesn't see _nc if this is inside the class -install.sub_commands = ( - [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + - install.new_commands -) +install.sub_commands = [ + cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc +] + install.new_commands diff --git a/uno/lib/python/setuptools/command/install_egg_info.py b/uno/lib/python/setuptools/command/install_egg_info.py index 1c549c98..a1d2e818 100644 --- a/uno/lib/python/setuptools/command/install_egg_info.py +++ b/uno/lib/python/setuptools/command/install_egg_info.py @@ -20,8 +20,7 @@ def initialize_options(self): self.install_dir = None def finalize_options(self): - self.set_undefined_options('install_lib', - ('install_dir', 'install_dir')) + self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) ei_cmd = self.get_finalized_command("egg_info") basename = f"{ei_cmd._get_egg_basename()}.egg-info" self.source = ei_cmd.egg_info @@ -36,9 +35,7 @@ def run(self): self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: ensure_directory(self.target) - self.execute( - self.copytree, (), "Copying %s to %s" % (self.source, self.target) - ) + self.execute(self.copytree, (), "Copying %s to %s" % (self.source, self.target)) self.install_namespaces() def get_outputs(self): diff --git a/uno/lib/python/setuptools/command/install_lib.py b/uno/lib/python/setuptools/command/install_lib.py index 2e9d8757..32ff65e7 100644 --- a/uno/lib/python/setuptools/command/install_lib.py +++ b/uno/lib/python/setuptools/command/install_lib.py @@ -77,16 +77,20 @@ def _gen_exclusion_paths(): if not hasattr(sys, 'implementation'): return - base = os.path.join( - '__pycache__', '__init__.' + sys.implementation.cache_tag) + base = os.path.join('__pycache__', '__init__.' + sys.implementation.cache_tag) yield base + '.pyc' yield base + '.pyo' yield base + '.opt-1.pyc' yield base + '.opt-2.pyc' def copy_tree( - self, infile, outfile, - preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 + self, + infile, + outfile, + preserve_mode=1, + preserve_times=1, + preserve_symlinks=0, + level=1, ): assert preserve_mode and preserve_times and not preserve_symlinks exclude = self.get_exclusions() @@ -103,8 +107,7 @@ def copy_tree( def pf(src, dst): if dst in exclude: - log.warn("Skipping installation of %s (namespace package)", - dst) + log.warn("Skipping installation of %s (namespace package)", dst) return False log.info("copying %s -> %s", src, os.path.dirname(dst)) diff --git a/uno/lib/python/setuptools/command/install_scripts.py b/uno/lib/python/setuptools/command/install_scripts.py index 8b3133f1..72b2e45c 100644 --- a/uno/lib/python/setuptools/command/install_scripts.py +++ b/uno/lib/python/setuptools/command/install_scripts.py @@ -1,6 +1,5 @@ from distutils import log import distutils.command.install_scripts as orig -from distutils.errors import DistutilsModuleError import os import sys @@ -32,20 +31,14 @@ def _install_ep_scripts(self): ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( - ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), - ei_cmd.egg_name, ei_cmd.egg_version, + ei_cmd.egg_base, + PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), + ei_cmd.egg_name, + ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') exec_param = getattr(bs_cmd, 'executable', None) - try: - bw_cmd = self.get_finalized_command("bdist_wininst") - is_wininst = getattr(bw_cmd, '_is_running', False) - except (ImportError, DistutilsModuleError): - is_wininst = False writer = ei.ScriptWriter - if is_wininst: - exec_param = "python.exe" - writer = ei.WindowsScriptWriter if exec_param == sys.executable: # In case the path to the Python executable contains a space, wrap # it so it's not split up. diff --git a/uno/lib/python/setuptools/command/rotate.py b/uno/lib/python/setuptools/command/rotate.py index 74795ba9..cfb78ce5 100644 --- a/uno/lib/python/setuptools/command/rotate.py +++ b/uno/lib/python/setuptools/command/rotate.py @@ -37,9 +37,7 @@ def finalize_options(self): except ValueError as e: raise DistutilsOptionError("--keep must be an integer") from e if isinstance(self.match, str): - self.match = [ - convert_path(p.strip()) for p in self.match.split(',') - ] + self.match = [convert_path(p.strip()) for p in self.match.split(',')] self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) def run(self): @@ -54,8 +52,8 @@ def run(self): files.reverse() log.info("%d file(s) matching %s", len(files), pattern) - files = files[self.keep:] - for (t, f) in files: + files = files[self.keep :] + for t, f in files: log.info("Deleting %s", f) if not self.dry_run: if os.path.isdir(f): diff --git a/uno/lib/python/setuptools/command/saveopts.py b/uno/lib/python/setuptools/command/saveopts.py index 611cec55..f175de10 100644 --- a/uno/lib/python/setuptools/command/saveopts.py +++ b/uno/lib/python/setuptools/command/saveopts.py @@ -11,7 +11,6 @@ def run(self): settings = {} for cmd in dist.command_options: - if cmd == 'saveopts': continue # don't save our own options! diff --git a/uno/lib/python/setuptools/command/sdist.py b/uno/lib/python/setuptools/command/sdist.py index 730011ab..5f45fb5d 100644 --- a/uno/lib/python/setuptools/command/sdist.py +++ b/uno/lib/python/setuptools/command/sdist.py @@ -2,7 +2,6 @@ import distutils.command.sdist as orig import os import sys -import io import contextlib from itertools import chain @@ -23,18 +22,27 @@ class sdist(orig.sdist): """Smart sdist that finds anything supported by revision control""" user_options = [ - ('formats=', None, - "formats for source distribution (comma-separated list)"), - ('keep-temp', 'k', - "keep the distribution tree around after creating " + - "archive file(s)"), - ('dist-dir=', 'd', - "directory to put the source distribution archive(s) in " - "[default: dist]"), - ('owner=', 'u', - "Owner name used when creating a tar file [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file [default: current group]"), + ('formats=', None, "formats for source distribution (comma-separated list)"), + ( + 'keep-temp', + 'k', + "keep the distribution tree around after creating " + "archive file(s)", + ), + ( + 'dist-dir=', + 'd', + "directory to put the source distribution archive(s) in " "[default: dist]", + ), + ( + 'owner=', + 'u', + "Owner name used when creating a tar file [default: current user]", + ), + ( + 'group=', + 'g', + "Group name used when creating a tar file [default: current group]", + ), ] negative_opt = {} @@ -159,8 +167,7 @@ def check_readme(self): return else: self.warn( - "standard file not found: should have one of " + - ', '.join(self.READMES) + "standard file not found: should have one of " + ', '.join(self.READMES) ) def make_release_tree(self, base_dir, files): @@ -181,10 +188,9 @@ def _manifest_is_not_generated(self): if not os.path.isfile(self.manifest): return False - with io.open(self.manifest, 'rb') as fp: + with open(self.manifest, 'rb') as fp: first_line = fp.readline() - return (first_line != - '# file GENERATED by distutils, do NOT edit\n'.encode()) + return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode() def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to diff --git a/uno/lib/python/setuptools/command/setopt.py b/uno/lib/python/setuptools/command/setopt.py index 6358c045..f9a60751 100644 --- a/uno/lib/python/setuptools/command/setopt.py +++ b/uno/lib/python/setuptools/command/setopt.py @@ -18,15 +18,11 @@ def config_file(kind="local"): if kind == 'local': return 'setup.cfg' if kind == 'global': - return os.path.join( - os.path.dirname(distutils.__file__), 'distutils.cfg' - ) + return os.path.join(os.path.dirname(distutils.__file__), 'distutils.cfg') if kind == 'user': dot = os.name == 'posix' and '.' or '' return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) - raise ValueError( - "config_file() type must be 'local', 'global', or 'user'", kind - ) + raise ValueError("config_file() type must be 'local', 'global', or 'user'", kind) def edit_config(filename, settings, dry_run=False): @@ -51,19 +47,16 @@ def edit_config(filename, settings, dry_run=False): opts.add_section(section) for option, value in options.items(): if value is None: - log.debug( - "Deleting %s.%s from %s", - section, option, filename - ) + log.debug("Deleting %s.%s from %s", section, option, filename) opts.remove_option(section, option) if not opts.options(section): - log.info("Deleting empty [%s] section from %s", - section, filename) + log.info( + "Deleting empty [%s] section from %s", section, filename + ) opts.remove_section(section) else: log.debug( - "Setting %s.%s to %r in %s", - section, option, value, filename + "Setting %s.%s to %r in %s", section, option, value, filename ) opts.set(section, option, value) @@ -77,16 +70,14 @@ class option_base(Command): """Abstract base class for commands that mess with config files""" user_options = [ - ('global-config', 'g', - "save options to the site-wide distutils.cfg file"), - ('user-config', 'u', - "save options to the current user's pydistutils.cfg file"), - ('filename=', 'f', - "configuration file to use (default=setup.cfg)"), + ('global-config', 'g', "save options to the site-wide distutils.cfg file"), + ('user-config', 'u', "save options to the current user's pydistutils.cfg file"), + ('filename=', 'f', "configuration file to use (default=setup.cfg)"), ] boolean_options = [ - 'global-config', 'user-config', + 'global-config', + 'user-config', ] def initialize_options(self): @@ -106,10 +97,9 @@ def finalize_options(self): filenames.append(config_file('local')) if len(filenames) > 1: raise DistutilsOptionError( - "Must specify only one configuration file option", - filenames + "Must specify only one configuration file option", filenames ) - self.filename, = filenames + (self.filename,) = filenames class setopt(option_base): @@ -142,8 +132,7 @@ def finalize_options(self): def run(self): edit_config( - self.filename, { - self.command: {self.option.replace('-', '_'): self.set_value} - }, - self.dry_run + self.filename, + {self.command: {self.option.replace('-', '_'): self.set_value}}, + self.dry_run, ) diff --git a/uno/lib/python/setuptools/command/test.py b/uno/lib/python/setuptools/command/test.py index 8dde513c..5fce6660 100644 --- a/uno/lib/python/setuptools/command/test.py +++ b/uno/lib/python/setuptools/command/test.py @@ -95,7 +95,6 @@ def initialize_options(self): self.test_runner = None def finalize_options(self): - if self.test_suite and self.test_module: msg = "You may specify a module or a suite, but not both" raise DistutilsOptionError(msg) diff --git a/uno/lib/python/setuptools/command/upload_docs.py b/uno/lib/python/setuptools/command/upload_docs.py index 077c9d2f..32c9abd7 100644 --- a/uno/lib/python/setuptools/command/upload_docs.py +++ b/uno/lib/python/setuptools/command/upload_docs.py @@ -8,7 +8,6 @@ from distutils import log from distutils.errors import DistutilsOptionError import os -import socket import zipfile import tempfile import shutil @@ -35,10 +34,12 @@ class upload_docs(upload): description = 'Upload documentation to sites other than PyPi such as devpi' user_options = [ - ('repository=', 'r', - "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), - ('show-response', None, - 'display full response text from server'), + ( + 'repository=', + 'r', + "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY, + ), + ('show-response', None, 'display full response text from server'), ('upload-dir=', None, 'directory to upload'), ] boolean_options = upload.boolean_options @@ -59,7 +60,8 @@ def initialize_options(self): def finalize_options(self): log.warn( "Upload_docs command is deprecated. Use Read the Docs " - "(https://readthedocs.org) instead.") + "(https://readthedocs.org) instead." + ) upload.finalize_options(self) if self.upload_dir is None: if self.has_sphinx(): @@ -83,7 +85,7 @@ def create_zipfile(self, filename): raise DistutilsOptionError(tmpl % self.target_dir) for name in files: full = os.path.join(root, name) - relative = root[len(self.target_dir):].lstrip(os.path.sep) + relative = root[len(self.target_dir) :].lstrip(os.path.sep) dest = os.path.join(relative, name) zip_file.write(full, dest) finally: @@ -141,7 +143,10 @@ def _build_multipart(cls, data): boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = b'\n--' + boundary.encode('ascii') end_boundary = sep_boundary + b'--' - end_items = end_boundary, b"\n", + end_items = ( + end_boundary, + b"\n", + ) builder = functools.partial( cls._build_part, sep_boundary=sep_boundary, @@ -174,8 +179,9 @@ def upload_file(self, filename): # build the Request # We can't use urllib2 since we need to send the Basic # auth right with the first request - schema, netloc, url, params, query, fragments = \ - urllib.parse.urlparse(self.repository) + schema, netloc, url, params, query, fragments = urllib.parse.urlparse( + self.repository + ) assert not params and not query and not fragments if schema == 'http': conn = http.client.HTTPConnection(netloc) @@ -194,7 +200,7 @@ def upload_file(self, filename): conn.putheader('Authorization', auth) conn.endheaders() conn.send(body) - except socket.error as e: + except OSError as e: self.announce(str(e), log.ERROR) return diff --git a/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py b/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py index 3091e3b5..80318d5d 100644 --- a/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py +++ b/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py @@ -12,12 +12,25 @@ from collections.abc import Mapping from email.headerregistry import Address from functools import partial, reduce +from inspect import cleandoc from itertools import chain from types import MappingProxyType -from typing import (TYPE_CHECKING, Any, Callable, Dict, List, Optional, Set, Tuple, - Type, Union, cast) - -from ..warnings import SetuptoolsWarning, SetuptoolsDeprecationWarning +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + List, + Optional, + Set, + Tuple, + Type, + Union, + cast, +) + +from ..errors import RemovedConfigError +from ..warnings import SetuptoolsWarning if TYPE_CHECKING: from setuptools._importlib import metadata # noqa @@ -79,12 +92,13 @@ def _apply_tool_table(dist: "Distribution", config: dict, filename: _Path): for field, value in tool_table.items(): norm_key = json_compatible_key(field) - if norm_key in TOOL_TABLE_DEPRECATIONS: - suggestion, kwargs = TOOL_TABLE_DEPRECATIONS[norm_key] - msg = f"The parameter `{norm_key}` is deprecated, {suggestion}" - SetuptoolsDeprecationWarning.emit( - "Deprecated config", msg, **kwargs # type: ignore - ) + if norm_key in TOOL_TABLE_REMOVALS: + suggestion = cleandoc(TOOL_TABLE_REMOVALS[norm_key]) + msg = f""" + The parameter `tool.setuptools.{field}` was long deprecated + and has been removed from `pyproject.toml`. + """ + raise RemovedConfigError("\n".join([cleandoc(msg), suggestion])) norm_key = TOOL_TABLE_RENAMES.get(norm_key, norm_key) _set_config(dist, norm_key, value) @@ -94,13 +108,13 @@ def _apply_tool_table(dist: "Distribution", config: dict, filename: _Path): def _handle_missing_dynamic(dist: "Distribution", project_table: dict): """Be temporarily forgiving with ``dynamic`` fields not listed in ``dynamic``""" - # TODO: Set fields back to `None` once the feature stabilizes dynamic = set(project_table.get("dynamic", [])) for field, getter in _PREVIOUSLY_DEFINED.items(): if not (field in project_table or field in dynamic): value = getter(dist) if value: - _WouldIgnoreField.emit(field=field, value=value) + _MissingDynamic.emit(field=field, value=value) + project_table[field] = _RESET_PREVIOUSLY_DEFINED.get(field) def json_compatible_key(key: str) -> str: @@ -201,12 +215,12 @@ def _dependencies(dist: "Distribution", val: list, _root_dir): if getattr(dist, "install_requires", []): msg = "`install_requires` overwritten in `pyproject.toml` (dependencies)" SetuptoolsWarning.emit(msg) - _set_config(dist, "install_requires", val) + dist.install_requires = val def _optional_dependencies(dist: "Distribution", val: dict, _root_dir): - existing = getattr(dist, "extras_require", {}) - _set_config(dist, "extras_require", {**existing, **val}) + existing = getattr(dist, "extras_require", None) or {} + dist.extras_require = {**existing, **val} def _unify_entry_points(project_table: dict): @@ -215,14 +229,18 @@ def _unify_entry_points(project_table: dict): renaming = {"scripts": "console_scripts", "gui_scripts": "gui_scripts"} for key, value in list(project.items()): # eager to allow modifications norm_key = json_compatible_key(key) - if norm_key in renaming and value: + if norm_key in renaming: + # Don't skip even if value is empty (reason: reset missing `dynamic`) entry_points[renaming[norm_key]] = project.pop(key) if entry_points: project["entry-points"] = { name: [f"{k} = {v}" for k, v in group.items()] for name, group in entry_points.items() + if group # now we can skip empty groups } + # Sometimes this will set `project["entry-points"] = {}`, and that is + # intentional (for reseting configurations that are missing `dynamic`). def _copy_command_options(pyproject: dict, dist: "Distribution", filename: _Path): @@ -285,6 +303,16 @@ def _get_previous_entrypoints(dist: "Distribution") -> Dict[str, list]: return {k: v for k, v in value.items() if k not in ignore} +def _get_previous_scripts(dist: "Distribution") -> Optional[list]: + value = getattr(dist, "entry_points", None) or {} + return value.get("console_scripts") + + +def _get_previous_gui_scripts(dist: "Distribution") -> Optional[list]: + value = getattr(dist, "entry_points", None) or {} + return value.get("gui_scripts") + + def _attrgetter(attr): """ Similar to ``operator.attrgetter`` but returns None if ``attr`` is not found @@ -312,9 +340,11 @@ def _some_attrgetter(*items): >>> _some_attrgetter("d", "e", "f")(obj) is None True """ + def _acessor(obj): values = (_attrgetter(i)(obj) for i in items) return next((i for i in values if i is not None), None) + return _acessor @@ -330,15 +360,20 @@ def _acessor(obj): } TOOL_TABLE_RENAMES = {"script_files": "scripts"} -TOOL_TABLE_DEPRECATIONS = { - "namespace_packages": ( - "consider using implicit namespaces instead (PEP 420).", - {"due_date": (2023, 10, 30)}, # warning introduced in May 2022 - ) +TOOL_TABLE_REMOVALS = { + "namespace_packages": """ + Please migrate to implicit native namespaces instead. + See https://packaging.python.org/en/latest/guides/packaging-namespace-packages/. + """, } -SETUPTOOLS_PATCHES = {"long_description_content_type", "project_urls", - "provides_extras", "license_file", "license_files"} +SETUPTOOLS_PATCHES = { + "long_description_content_type", + "project_urls", + "provides_extras", + "license_file", + "license_files", +} _PREVIOUSLY_DEFINED = { "name": _attrgetter("metadata.name"), @@ -353,19 +388,34 @@ def _acessor(obj): "classifiers": _attrgetter("metadata.classifiers"), "urls": _attrgetter("metadata.project_urls"), "entry-points": _get_previous_entrypoints, - "dependencies": _some_attrgetter("_orig_install_requires", "install_requires"), - "optional-dependencies": _some_attrgetter("_orig_extras_require", "extras_require"), + "scripts": _get_previous_scripts, + "gui-scripts": _get_previous_gui_scripts, + "dependencies": _attrgetter("install_requires"), + "optional-dependencies": _attrgetter("extras_require"), } -class _WouldIgnoreField(SetuptoolsDeprecationWarning): - _SUMMARY = "`{field}` defined outside of `pyproject.toml` would be ignored." +_RESET_PREVIOUSLY_DEFINED: dict = { + # Fix improper setting: given in `setup.py`, but not listed in `dynamic` + # dict: pyproject name => value to which reset + "license": {}, + "authors": [], + "maintainers": [], + "keywords": [], + "classifiers": [], + "urls": {}, + "entry-points": {}, + "scripts": {}, + "gui-scripts": {}, + "dependencies": [], + "optional-dependencies": [], +} - _DETAILS = """ - ########################################################################## - # configuration would be ignored/result in error due to `pyproject.toml` # - ########################################################################## +class _MissingDynamic(SetuptoolsWarning): + _SUMMARY = "`{field}` defined outside of `pyproject.toml` is ignored." + + _DETAILS = """ The following seems to be defined outside of `pyproject.toml`: `{field} = {value!r}` @@ -375,12 +425,14 @@ class _WouldIgnoreField(SetuptoolsDeprecationWarning): https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ - For the time being, `setuptools` will still consider the given value (as a - **transitional** measure), but please note that future releases of setuptools will - follow strictly the standard. - - To prevent this warning, you can list `{field}` under `dynamic` or alternatively + To prevent this problem, you can list `{field}` under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. """ - _DUE_DATE = (2023, 10, 30) # Initially introduced in 27 May 2022 + # TODO: Consider removing this check in the future? + # There is a trade-off here between improving "debug-ability" and the cost + # of running/testing/maintaining these unnecessary checks... + + @classmethod + def details(cls, field: str, value: Any) -> str: + return cls._DETAILS.format(field=field, value=value) diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py b/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py index 52e18da2..b81d13c1 100644 --- a/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py +++ b/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py @@ -1049,4 +1049,4 @@ def validate_https___packaging_python_org_en_latest_specifications_declaring_pro raise JsonSchemaValueException("" + (name_prefix or "data") + ".email must be idn-email", value=data__email, name="" + (name_prefix or "data") + ".email", definition={'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}, rule='format') if data_keys: raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, rule='additionalProperties') - return data \ No newline at end of file + return data diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/formats.py b/uno/lib/python/setuptools/config/_validate_pyproject/formats.py index 486d5260..e7396166 100644 --- a/uno/lib/python/setuptools/config/_validate_pyproject/formats.py +++ b/uno/lib/python/setuptools/config/_validate_pyproject/formats.py @@ -95,7 +95,7 @@ def pep508_versionspec(value: str) -> bool: # versionspec return False # Let's pretend we have a dependency called `requirement` with the given - # version spec, then we can re-use the pep508 function for validation: + # version spec, then we can reuse the pep508 function for validation: return pep508(f"requirement{value}") diff --git a/uno/lib/python/setuptools/config/expand.py b/uno/lib/python/setuptools/config/expand.py index 30988843..1bc71de5 100644 --- a/uno/lib/python/setuptools/config/expand.py +++ b/uno/lib/python/setuptools/config/expand.py @@ -19,7 +19,6 @@ """ import ast import importlib -import io import os import pathlib import sys @@ -39,7 +38,7 @@ Tuple, TypeVar, Union, - cast + cast, ) from pathlib import Path from types import ModuleType @@ -101,14 +100,16 @@ def glob_relative( expanded_values = [] root_dir = root_dir or os.getcwd() for value in patterns: - # Has globby characters? if any(char in value for char in glob_characters): # then expand the glob pattern while keeping paths *relative*: glob_path = os.path.abspath(os.path.join(root_dir, value)) - expanded_values.extend(sorted( - os.path.relpath(path, root_dir).replace(os.sep, "/") - for path in iglob(glob_path, recursive=True))) + expanded_values.extend( + sorted( + os.path.relpath(path, root_dir).replace(os.sep, "/") + for path in iglob(glob_path, recursive=True) + ) + ) else: # take the value as-is @@ -145,7 +146,7 @@ def _filter_existing_files(filepaths: Iterable[_Path]) -> Iterator[_Path]: def _read_file(filepath: Union[bytes, _Path]) -> str: - with io.open(filepath, encoding='utf-8') as f: + with open(filepath, encoding='utf-8') as f: return f.read() @@ -160,7 +161,7 @@ def _assert_local(filepath: _Path, root_dir: str): def read_attr( attr_desc: str, package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None + root_dir: Optional[_Path] = None, ): """Reads the value of an attribute from a module. @@ -243,7 +244,7 @@ def _find_module( path_start = os.path.join(parent_path, *module_name.split(".")) candidates = chain( (f"{path_start}.py", os.path.join(path_start, "__init__.py")), - iglob(f"{path_start}.*") + iglob(f"{path_start}.*"), ) module_path = next((x for x in candidates if os.path.isfile(x)), None) return parent_path, module_path, module_name @@ -252,7 +253,7 @@ def _find_module( def resolve_class( qualified_class_name: str, package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None + root_dir: Optional[_Path] = None, ) -> Callable: """Given a qualified class name, return the associated class object""" root_dir = root_dir or os.getcwd() @@ -268,7 +269,7 @@ def resolve_class( def cmdclass( values: Dict[str, str], package_dir: Optional[Mapping[str, str]] = None, - root_dir: Optional[_Path] = None + root_dir: Optional[_Path] = None, ) -> Dict[str, Callable]: """Given a dictionary mapping command names to strings for qualified class names, apply :func:`resolve_class` to the dict values. @@ -281,7 +282,7 @@ def find_packages( namespaces=True, fill_package_dir: Optional[Dict[str, str]] = None, root_dir: Optional[_Path] = None, - **kwargs + **kwargs, ) -> List[str]: """Works similarly to :func:`setuptools.find_packages`, but with all arguments given as keyword arguments. Moreover, ``where`` can be given @@ -322,8 +323,7 @@ def find_packages( pkgs = PackageFinder.find(package_path, **kwargs) packages.extend(pkgs) if pkgs and not ( - fill_package_dir.get("") == path - or os.path.samefile(package_path, root_dir) + fill_package_dir.get("") == path or os.path.samefile(package_path, root_dir) ): fill_package_dir.update(construct_package_dir(pkgs, path)) diff --git a/uno/lib/python/setuptools/config/pyprojecttoml.py b/uno/lib/python/setuptools/config/pyprojecttoml.py index ceb2dbe3..379ef222 100644 --- a/uno/lib/python/setuptools/config/pyprojecttoml.py +++ b/uno/lib/python/setuptools/config/pyprojecttoml.py @@ -14,10 +14,10 @@ from functools import partial from typing import TYPE_CHECKING, Callable, Dict, Mapping, Optional, Set, Union -from ..errors import FileError, OptionError +from ..errors import FileError, InvalidConfigError from ..warnings import SetuptoolsWarning from . import expand as _expand -from ._apply_pyprojecttoml import _PREVIOUSLY_DEFINED, _WouldIgnoreField +from ._apply_pyprojecttoml import _PREVIOUSLY_DEFINED, _MissingDynamic from ._apply_pyprojecttoml import apply as _apply if TYPE_CHECKING: @@ -106,9 +106,8 @@ def read_configuration( if not asdict or not (project_table or setuptools_table): return {} # User is not using pyproject to configure setuptools - if setuptools_table: - # TODO: Remove the following once the feature stabilizes: - _BetaConfiguration.emit() + if "distutils" in tool_table: + _ExperimentalConfiguration.emit(subject="[tool.distutils]") # There is an overall sense in the community that making include_package_data=True # the default would be an improvement. @@ -266,7 +265,7 @@ def _ensure_previously_set(self, dist: "Distribution", field: str): "Some dynamic fields need to be specified via `tool.setuptools.dynamic`" "\nothers must be specified via the equivalent attribute in `setup.py`." ) - raise OptionError(msg) + raise InvalidConfigError(msg) def _expand_directive( self, specifier: str, directive, package_dir: Mapping[str, str] @@ -331,9 +330,7 @@ def _set_scripts(field: str, group: str): if group in groups: value = groups.pop(group) if field not in self.dynamic: - _WouldIgnoreField.emit(field=field, value=value) - # TODO: Don't set field when support for pyproject.toml stabilizes - # instead raise an error as specified in PEP 621 + raise InvalidConfigError(_MissingDynamic.details(field, value)) expanded[field] = value _set_scripts("scripts", "console_scripts") @@ -362,11 +359,13 @@ def _obtain_optional_dependencies(self, dist: "Distribution"): optional_dependencies_map = self.dynamic_cfg["optional-dependencies"] assert isinstance(optional_dependencies_map, dict) return { - group: _parse_requirements_list(self._expand_directive( - f"tool.setuptools.dynamic.optional-dependencies.{group}", - directive, - {}, - )) + group: _parse_requirements_list( + self._expand_directive( + f"tool.setuptools.dynamic.optional-dependencies.{group}", + directive, + {}, + ) + ) for group, directive in optional_dependencies_map.items() } self._ensure_previously_set(dist, "optional-dependencies") @@ -433,5 +432,8 @@ def __exit__(self, exc_type, exc_value, traceback): return super().__exit__(exc_type, exc_value, traceback) -class _BetaConfiguration(SetuptoolsWarning): - _SUMMARY = "Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*." +class _ExperimentalConfiguration(SetuptoolsWarning): + _SUMMARY = ( + "`{subject}` in `pyproject.toml` is still *experimental* " + "and likely to change in future releases." + ) diff --git a/uno/lib/python/setuptools/config/setupcfg.py b/uno/lib/python/setuptools/config/setupcfg.py index bb355590..1a0e4154 100644 --- a/uno/lib/python/setuptools/config/setupcfg.py +++ b/uno/lib/python/setuptools/config/setupcfg.py @@ -556,23 +556,9 @@ def parsers(self): 'platforms': parse_list, 'keywords': parse_list, 'provides': parse_list, - 'requires': self._deprecated_config_handler( - parse_list, - "The requires parameter is deprecated, please use " - "install_requires for runtime dependencies.", - due_date=(2023, 10, 30), - # Warning introduced in 27 Oct 2018 - ), 'obsoletes': parse_list, 'classifiers': self._get_parser_compound(parse_file, parse_list), 'license': exclude_files_parser('license'), - 'license_file': self._deprecated_config_handler( - exclude_files_parser('license_file'), - "The license_file parameter is deprecated, " - "use license_files instead.", - due_date=(2023, 10, 30), - # Warning introduced in 23 May 2021 - ), 'license_files': parse_list, 'description': parse_file, 'long_description': parse_file, diff --git a/uno/lib/python/setuptools/dep_util.py b/uno/lib/python/setuptools/dep_util.py index 521eb716..998ffa20 100644 --- a/uno/lib/python/setuptools/dep_util.py +++ b/uno/lib/python/setuptools/dep_util.py @@ -1,25 +1,16 @@ -from distutils.dep_util import newer_group +from ._distutils import _modified +from .warnings import SetuptoolsDeprecationWarning -# yes, this is was almost entirely copy-pasted from -# 'newer_pairwise()', this is just another convenience -# function. -def newer_pairwise_group(sources_groups, targets): - """Walk both arguments in parallel, testing if each source group is newer - than its corresponding target. Returns a pair of lists (sources_groups, - targets) where sources is newer than target, according to the semantics - of 'newer_group()'. - """ - if len(sources_groups) != len(targets): - raise ValueError( - "'sources_group' and 'targets' must be the same length") - - # build a pair of lists (sources_groups, targets) where source is newer - n_sources = [] - n_targets = [] - for i in range(len(sources_groups)): - if newer_group(sources_groups[i], targets[i]): - n_sources.append(sources_groups[i]) - n_targets.append(targets[i]) - - return n_sources, n_targets +def __getattr__(name): + if name not in ['newer_group', 'newer_pairwise_group']: + raise AttributeError(name) + SetuptoolsDeprecationWarning.emit( + "dep_util is Deprecated. Use functions from setuptools.modified instead.", + "Please use `setuptools.modified` instead of `setuptools.dep_util`.", + see_url="https://github.com/pypa/setuptools/pull/4069", + due_date=(2024, 5, 21), + # Warning added in v69.0.0 on 2023/11/20, + # See https://github.com/pypa/setuptools/discussions/4128 + ) + return getattr(_modified, name) diff --git a/uno/lib/python/setuptools/depends.py b/uno/lib/python/setuptools/depends.py index adffd12d..42907d9b 100644 --- a/uno/lib/python/setuptools/depends.py +++ b/uno/lib/python/setuptools/depends.py @@ -3,26 +3,23 @@ import contextlib import dis -from setuptools.extern.packaging import version -from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE from . import _imp +from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE +from .extern.packaging.version import Version -__all__ = [ - 'Require', 'find_module', 'get_module_constant', 'extract_constant' -] +__all__ = ['Require', 'find_module', 'get_module_constant', 'extract_constant'] class Require: """A prerequisite to building or installing a distribution""" def __init__( - self, name, requested_version, module, homepage='', - attribute=None, format=None): - + self, name, requested_version, module, homepage='', attribute=None, format=None + ): if format is None and requested_version is not None: - format = version.Version + format = Version if format is not None: requested_version = format(requested_version) @@ -40,8 +37,12 @@ def full_name(self): def version_ok(self, version): """Is 'version' sufficiently up-to-date?""" - return self.attribute is None or self.format is None or \ - str(version) != "unknown" and self.format(version) >= self.requested_version + return ( + self.attribute is None + or self.format is None + or str(version) != "unknown" + and self.format(version) >= self.requested_version + ) def get_version(self, paths=None, default="unknown"): """Get version number of installed module, 'None', or 'default' @@ -87,6 +88,7 @@ def maybe_close(f): def empty(): yield return + if not f: return empty() @@ -140,9 +142,9 @@ def extract_constant(code, symbol, default=-1): name_idx = list(code.co_names).index(symbol) - STORE_NAME = 90 - STORE_GLOBAL = 97 - LOAD_CONST = 100 + STORE_NAME = dis.opmap['STORE_NAME'] + STORE_GLOBAL = dis.opmap['STORE_GLOBAL'] + LOAD_CONST = dis.opmap['LOAD_CONST'] const = default diff --git a/uno/lib/python/setuptools/discovery.py b/uno/lib/python/setuptools/discovery.py index 3110b727..25962863 100644 --- a/uno/lib/python/setuptools/discovery.py +++ b/uno/lib/python/setuptools/discovery.py @@ -51,7 +51,7 @@ Mapping, Optional, Tuple, - Union + Union, ) import _distutils_hack.override # noqa: F401 @@ -100,7 +100,7 @@ def find( cls, where: _Path = '.', exclude: Iterable[str] = (), - include: Iterable[str] = ('*',) + include: Iterable[str] = ('*',), ) -> List[str]: """Return a list of all Python items (packages or modules, depending on the finder implementation) found within directory 'where'. @@ -213,11 +213,13 @@ class FlatLayoutPackageFinder(PEP420PackageFinder): _EXCLUDE = ( "ci", "bin", + "debian", "doc", "docs", "documentation", "manpages", "news", + "newsfragments", "changelog", "test", "tests", @@ -362,7 +364,8 @@ def _explicitly_specified(self, ignore_ext_modules: bool) -> bool: self.dist.packages is not None or self.dist.py_modules is not None or ext_modules - or hasattr(self.dist, "configuration") and self.dist.configuration + or hasattr(self.dist, "configuration") + and self.dist.configuration # ^ Some projects use numpy.distutils.misc_util.Configuration ) @@ -554,7 +557,7 @@ def find_parent_package( packages = sorted(packages, key=len) common_ancestors = [] for i, name in enumerate(packages): - if not all(n.startswith(f"{name}.") for n in packages[i+1:]): + if not all(n.startswith(f"{name}.") for n in packages[i + 1 :]): # Since packages are sorted by length, this condition is able # to find a list of all common ancestors. # When there is divergence (e.g. multiple root packages) diff --git a/uno/lib/python/setuptools/dist.py b/uno/lib/python/setuptools/dist.py index 4458a580..222e8a76 100644 --- a/uno/lib/python/setuptools/dist.py +++ b/uno/lib/python/setuptools/dist.py @@ -1,232 +1,43 @@ __all__ = ['Distribution'] + import io -import sys -import re -import os -import numbers -import distutils.log -import distutils.core -import distutils.cmd -import distutils.dist -import distutils.command -from distutils.util import strtobool -from distutils.debug import DEBUG -from distutils.fancy_getopt import translate_longopt -from glob import iglob import itertools -import textwrap +import numbers +import os +import re +import sys from contextlib import suppress -from typing import List, Optional, Set, TYPE_CHECKING +from glob import iglob from pathlib import Path +from typing import List, Optional, Set -from collections import defaultdict -from email import message_from_file - +import distutils.cmd +import distutils.command +import distutils.core +import distutils.dist +import distutils.log +from distutils.debug import DEBUG from distutils.errors import DistutilsOptionError, DistutilsSetupError -from distutils.util import rfc822_escape - -from setuptools.extern import packaging -from setuptools.extern import ordered_set -from setuptools.extern.more_itertools import unique_everseen, partition +from distutils.fancy_getopt import translate_longopt +from distutils.util import strtobool -import setuptools -import setuptools.command -from setuptools import windows_support -from setuptools.monkey import get_unpatched -from setuptools.config import setupcfg, pyprojecttoml -from setuptools.discovery import ConfigDiscovery +from .extern.more_itertools import partition, unique_everseen +from .extern.ordered_set import OrderedSet +from .extern.packaging.markers import InvalidMarker, Marker +from .extern.packaging.specifiers import InvalidSpecifier, SpecifierSet +from .extern.packaging.version import Version -from setuptools.extern.packaging import version -from . import _reqs from . import _entry_points from . import _normalization +from . import _reqs +from . import command as _ # noqa -- imported for side-effects from ._importlib import metadata +from .config import setupcfg, pyprojecttoml +from .discovery import ConfigDiscovery +from .monkey import get_unpatched from .warnings import InformationOnly, SetuptoolsDeprecationWarning -if TYPE_CHECKING: - from email.message import Message - -__import__('setuptools.extern.packaging.specifiers') -__import__('setuptools.extern.packaging.version') - - -def get_metadata_version(self): - mv = getattr(self, 'metadata_version', None) - if mv is None: - mv = version.Version('2.1') - self.metadata_version = mv - return mv - - -def rfc822_unescape(content: str) -> str: - """Reverse RFC-822 escaping by removing leading whitespaces from content.""" - lines = content.splitlines() - if len(lines) == 1: - return lines[0].lstrip() - return '\n'.join((lines[0].lstrip(), textwrap.dedent('\n'.join(lines[1:])))) - - -def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]: - """Read Message header field.""" - value = msg[field] - if value == 'UNKNOWN': - return None - return value - - -def _read_field_unescaped_from_msg(msg: "Message", field: str) -> Optional[str]: - """Read Message header field and apply rfc822_unescape.""" - value = _read_field_from_msg(msg, field) - if value is None: - return value - return rfc822_unescape(value) - - -def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]: - """Read Message header field and return all results as list.""" - values = msg.get_all(field, None) - if values == []: - return None - return values - - -def _read_payload_from_msg(msg: "Message") -> Optional[str]: - value = msg.get_payload().strip() - if value == 'UNKNOWN' or not value: - return None - return value - - -def read_pkg_file(self, file): - """Reads the metadata values from a file object.""" - msg = message_from_file(file) - - self.metadata_version = version.Version(msg['metadata-version']) - self.name = _read_field_from_msg(msg, 'name') - self.version = _read_field_from_msg(msg, 'version') - self.description = _read_field_from_msg(msg, 'summary') - # we are filling author only. - self.author = _read_field_from_msg(msg, 'author') - self.maintainer = None - self.author_email = _read_field_from_msg(msg, 'author-email') - self.maintainer_email = None - self.url = _read_field_from_msg(msg, 'home-page') - self.download_url = _read_field_from_msg(msg, 'download-url') - self.license = _read_field_unescaped_from_msg(msg, 'license') - - self.long_description = _read_field_unescaped_from_msg(msg, 'description') - if ( - self.long_description is None and - self.metadata_version >= version.Version('2.1') - ): - self.long_description = _read_payload_from_msg(msg) - self.description = _read_field_from_msg(msg, 'summary') - - if 'keywords' in msg: - self.keywords = _read_field_from_msg(msg, 'keywords').split(',') - - self.platforms = _read_list_from_msg(msg, 'platform') - self.classifiers = _read_list_from_msg(msg, 'classifier') - - # PEP 314 - these fields only exist in 1.1 - if self.metadata_version == version.Version('1.1'): - self.requires = _read_list_from_msg(msg, 'requires') - self.provides = _read_list_from_msg(msg, 'provides') - self.obsoletes = _read_list_from_msg(msg, 'obsoletes') - else: - self.requires = None - self.provides = None - self.obsoletes = None - - self.license_files = _read_list_from_msg(msg, 'license-file') - - -def single_line(val): - """ - Quick and dirty validation for Summary pypa/setuptools#1390. - """ - if '\n' in val: - # TODO: Replace with `raise ValueError("newlines not allowed")` - # after reviewing #2893. - msg = "newlines are not allowed in `summary` and will break in the future" - SetuptoolsDeprecationWarning.emit("Invalid config.", msg) - # due_date is undefined. Controversial change, there was a lot of push back. - val = val.strip().split('\n')[0] - return val - - -# Based on Python 3.5 version -def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME - """Write the PKG-INFO format data to a file object.""" - version = self.get_metadata_version() - - def write_field(key, value): - file.write("%s: %s\n" % (key, value)) - - write_field('Metadata-Version', str(version)) - write_field('Name', self.get_name()) - write_field('Version', self.get_version()) - - summary = self.get_description() - if summary: - write_field('Summary', single_line(summary)) - - optional_fields = ( - ('Home-page', 'url'), - ('Download-URL', 'download_url'), - ('Author', 'author'), - ('Author-email', 'author_email'), - ('Maintainer', 'maintainer'), - ('Maintainer-email', 'maintainer_email'), - ) - - for field, attr in optional_fields: - attr_val = getattr(self, attr, None) - if attr_val is not None: - write_field(field, attr_val) - - license = self.get_license() - if license: - write_field('License', rfc822_escape(license)) - - for project_url in self.project_urls.items(): - write_field('Project-URL', '%s, %s' % project_url) - - keywords = ','.join(self.get_keywords()) - if keywords: - write_field('Keywords', keywords) - - platforms = self.get_platforms() or [] - for platform in platforms: - write_field('Platform', platform) - - self._write_list(file, 'Classifier', self.get_classifiers()) - - # PEP 314 - self._write_list(file, 'Requires', self.get_requires()) - self._write_list(file, 'Provides', self.get_provides()) - self._write_list(file, 'Obsoletes', self.get_obsoletes()) - - # Setuptools specific for PEP 345 - if hasattr(self, 'python_requires'): - write_field('Requires-Python', self.python_requires) - - # PEP 566 - if self.long_description_content_type: - write_field('Description-Content-Type', self.long_description_content_type) - if self.provides_extras: - for extra in self.provides_extras: - write_field('Provides-Extra', extra) - - self._write_list(file, 'License-File', self.license_files or []) - - long_description = self.get_long_description() - if long_description: - file.write("\n%s" % long_description) - if not long_description.endswith("\n"): - file.write("\n") - sequence = tuple, list @@ -300,7 +111,7 @@ def _check_extra(extra, reqs): name, sep, marker = extra.partition(':') try: _check_marker(marker) - except packaging.markers.InvalidMarker: + except InvalidMarker: msg = f"Invalid environment marker: {marker} ({extra!r})" raise DistutilsSetupError(msg) from None list(_reqs.parse(reqs)) @@ -309,7 +120,7 @@ def _check_extra(extra, reqs): def _check_marker(marker): if not marker: return - m = packaging.markers.Marker(marker) + m = Marker(marker) m.evaluate() @@ -345,8 +156,8 @@ def check_requirements(dist, attr, value): def check_specifier(dist, attr, value): """Verify that value is a valid version specifier""" try: - packaging.specifiers.SpecifierSet(value) - except (packaging.specifiers.InvalidSpecifier, AttributeError) as error: + SpecifierSet(value) + except (InvalidSpecifier, AttributeError) as error: tmpl = ( "{attr!r} must be a string " "containing valid version specifiers; {error}" ) @@ -449,9 +260,11 @@ class Distribution(_Distribution): _DISTUTILS_UNSUPPORTED_METADATA = { 'long_description_content_type': lambda: None, 'project_urls': dict, - 'provides_extras': ordered_set.OrderedSet, + 'provides_extras': OrderedSet, 'license_file': lambda: None, 'license_files': lambda: None, + 'install_requires': list, + 'extras_require': dict, } _patched_dist = None @@ -483,32 +296,22 @@ def __init__(self, attrs=None): self.setup_requires = attrs.pop('setup_requires', []) for ep in metadata.entry_points(group='distutils.setup_keywords'): vars(self).setdefault(ep.name, None) - _Distribution.__init__( - self, - { - k: v - for k, v in attrs.items() - if k not in self._DISTUTILS_UNSUPPORTED_METADATA - }, - ) + + metadata_only = set(self._DISTUTILS_UNSUPPORTED_METADATA) + metadata_only -= {"install_requires", "extras_require"} + dist_attrs = {k: v for k, v in attrs.items() if k not in metadata_only} + _Distribution.__init__(self, dist_attrs) # Private API (setuptools-use only, not restricted to Distribution) # Stores files that are referenced by the configuration and need to be in the # sdist (e.g. `version = file: VERSION.txt`) self._referenced_files: Set[str] = set() - # Save the original dependencies before they are processed into the egg format - self._orig_extras_require = {} - self._orig_install_requires = [] - self._tmp_extras_require = defaultdict(ordered_set.OrderedSet) - self.set_defaults = ConfigDiscovery(self) self._set_metadata_defaults(attrs) - self.metadata.version = self._normalize_version( - self._validate_version(self.metadata.version) - ) + self.metadata.version = self._normalize_version(self.metadata.version) self._finalize_requires() def _validate_metadata(self): @@ -536,38 +339,18 @@ def _set_metadata_defaults(self, attrs): @staticmethod def _normalize_version(version): - if isinstance(version, setuptools.sic) or version is None: - return version - - normalized = str(packaging.version.Version(version)) - if version != normalized: - InformationOnly.emit(f"Normalizing '{version}' to '{normalized}'") - return normalized - return version + from . import sic - @staticmethod - def _validate_version(version): if isinstance(version, numbers.Number): # Some people apparently take "version number" too literally :) version = str(version) + elif isinstance(version, sic) or version is None: + return version - if version is not None: - try: - packaging.version.Version(version) - except (packaging.version.InvalidVersion, TypeError): - SetuptoolsDeprecationWarning.emit( - f"Invalid version: {version!r}.", - """ - The version specified is not a valid version according to PEP 440. - This may not work as expected with newer versions of - setuptools, pip, and PyPI. - """, - see_url="https://peps.python.org/pep-0440/", - due_date=(2023, 9, 26), - # Warning initially introduced in 26 Sept 2014 - # pypa/packaging already removed legacy versions. - ) - return setuptools.sic(version) + normalized = str(Version(version)) + if version != normalized: + InformationOnly.emit(f"Normalizing '{version}' to '{normalized}'") + return normalized return version def _finalize_requires(self): @@ -578,81 +361,25 @@ def _finalize_requires(self): if getattr(self, 'python_requires', None): self.metadata.python_requires = self.python_requires - if getattr(self, 'extras_require', None): - # Save original before it is messed by _convert_extras_requirements - self._orig_extras_require = self._orig_extras_require or self.extras_require + self._normalize_requires() + self.metadata.install_requires = self.install_requires + self.metadata.extras_require = self.extras_require + + if self.extras_require: for extra in self.extras_require.keys(): - # Since this gets called multiple times at points where the - # keys have become 'converted' extras, ensure that we are only - # truly adding extras we haven't seen before here. + # Setuptools allows a weird ": syntax for extras extra = extra.split(':')[0] if extra: self.metadata.provides_extras.add(extra) - if getattr(self, 'install_requires', None) and not self._orig_install_requires: - # Save original before it is messed by _move_install_requirements_markers - self._orig_install_requires = self.install_requires - - self._convert_extras_requirements() - self._move_install_requirements_markers() - - def _convert_extras_requirements(self): - """ - Convert requirements in `extras_require` of the form - `"extra": ["barbazquux; {marker}"]` to - `"extra:{marker}": ["barbazquux"]`. - """ - spec_ext_reqs = getattr(self, 'extras_require', None) or {} - tmp = defaultdict(ordered_set.OrderedSet) - self._tmp_extras_require = getattr(self, '_tmp_extras_require', tmp) - for section, v in spec_ext_reqs.items(): - # Do not strip empty sections. - self._tmp_extras_require[section] - for r in _reqs.parse(v): - suffix = self._suffix_for(r) - self._tmp_extras_require[section + suffix].append(r) - - @staticmethod - def _suffix_for(req): - """ - For a requirement, return the 'extras_require' suffix for - that requirement. - """ - return ':' + str(req.marker) if req.marker else '' - - def _move_install_requirements_markers(self): - """ - Move requirements in `install_requires` that are using environment - markers `extras_require`. - """ - - # divide the install_requires into two sets, simple ones still - # handled by install_requires and more complex ones handled - # by extras_require. - - def is_simple_req(req): - return not req.marker - - spec_inst_reqs = getattr(self, 'install_requires', None) or () - inst_reqs = list(_reqs.parse(spec_inst_reqs)) - simple_reqs = filter(is_simple_req, inst_reqs) - complex_reqs = itertools.filterfalse(is_simple_req, inst_reqs) - self.install_requires = list(map(str, simple_reqs)) - - for r in complex_reqs: - self._tmp_extras_require[':' + str(r.marker)].append(r) - self.extras_require = dict( - # list(dict.fromkeys(...)) ensures a list of unique strings - (k, list(dict.fromkeys(str(r) for r in map(self._clean_req, v)))) - for k, v in self._tmp_extras_require.items() - ) - - def _clean_req(self, req): - """ - Given a Requirement, remove environment markers and return it. - """ - req.marker = None - return req + def _normalize_requires(self): + """Make sure requirement-related attributes exist and are normalized""" + install_requires = getattr(self, "install_requires", None) or [] + extras_require = getattr(self, "extras_require", None) or {} + self.install_requires = list(map(str, _reqs.parse(install_requires))) + self.extras_require = { + k: list(map(str, _reqs.parse(v or []))) for k, v in extras_require.items() + } def _finalize_license_files(self): """Compute names of all license files which should be included.""" @@ -729,7 +456,7 @@ def _parse_config_files(self, filenames=None): # noqa: C901 parser = ConfigParser() parser.optionxform = str for filename in filenames: - with io.open(filename, encoding='utf-8') as reader: + with open(filename, encoding='utf-8') as reader: if DEBUG: self.announce(" reading {filename}".format(**locals())) parser.read_file(reader) @@ -756,7 +483,7 @@ def _parse_config_files(self, filenames=None): # noqa: C901 # If there was a "global" section in the config file, use it # to set Distribution options. - for (opt, (src, val)) in self.command_options['global'].items(): + for opt, (src, val) in self.command_options['global'].items(): alias = self.negative_opt.get(opt) if alias: val = not strtobool(val) @@ -776,10 +503,12 @@ def warn_dash_deprecation(self, opt, section): return opt underscore_opt = opt.replace('-', '_') - commands = list(itertools.chain( - distutils.command.__all__, - self._setuptools_commands(), - )) + commands = list( + itertools.chain( + distutils.command.__all__, + self._setuptools_commands(), + ) + ) if ( not section.startswith('options') and section != 'metadata' @@ -795,7 +524,7 @@ def warn_dash_deprecation(self, opt, section): versions. Please use the underscore name {underscore_opt!r} instead. """, see_docs="userguide/declarative_config.html", - due_date=(2023, 9, 26), + due_date=(2024, 9, 26), # Warning initially introduced in 3 Mar 2021 ) return underscore_opt @@ -819,7 +548,7 @@ def make_option_lowercase(self, opt, section): future versions. Please use lowercase {lowercase_opt!r} instead. """, see_docs="userguide/declarative_config.html", - due_date=(2023, 9, 26), + due_date=(2024, 9, 26), # Warning initially introduced in 6 Mar 2021 ) return lowercase_opt @@ -843,7 +572,7 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 if DEBUG: self.announce(" setting options for '%s' command:" % command_name) - for (option, (source, value)) in option_dict.items(): + for option, (source, value) in option_dict.items(): if DEBUG: self.announce(" %s = %s (from %s)" % (option, value, source)) try: @@ -902,7 +631,7 @@ def parse_config_files(self, filenames=None, ignore_option_errors=False): def fetch_build_eggs(self, requires): """Resolve pre-setup requirements""" - from setuptools.installer import _fetch_build_eggs + from .installer import _fetch_build_eggs return _fetch_build_eggs(self, requires) @@ -945,6 +674,8 @@ def _finalize_setup_keywords(self): ep.load()(self, ep.name, value) def get_egg_cache_dir(self): + from . import windows_support + egg_cache_dir = os.path.join(os.curdir, '.eggs') if not os.path.exists(egg_cache_dir): os.mkdir(egg_cache_dir) @@ -965,7 +696,7 @@ def get_egg_cache_dir(self): def fetch_build_egg(self, req): """Fetch an egg needed for building""" - from setuptools.installer import fetch_build_egg + from .installer import fetch_build_egg return fetch_build_egg(self, req) @@ -1153,9 +884,7 @@ def get_cmdline_options(self): d = {} for cmd, opts in self.command_options.items(): - for opt, (src, val) in opts.items(): - if src != "command line": continue diff --git a/uno/lib/python/setuptools/errors.py b/uno/lib/python/setuptools/errors.py index ec7fb3b6..67a5a1df 100644 --- a/uno/lib/python/setuptools/errors.py +++ b/uno/lib/python/setuptools/errors.py @@ -29,6 +29,14 @@ BaseError = _distutils_errors.DistutilsError +class InvalidConfigError(OptionError): + """Error used for invalid configurations.""" + + +class RemovedConfigError(OptionError): + """Error used for configurations that were deprecated and removed.""" + + class RemovedCommandError(BaseError, RuntimeError): """Error used for commands that have been removed in setuptools. diff --git a/uno/lib/python/setuptools/extern/__init__.py b/uno/lib/python/setuptools/extern/__init__.py index bfd4d2d4..67c4a455 100644 --- a/uno/lib/python/setuptools/extern/__init__.py +++ b/uno/lib/python/setuptools/extern/__init__.py @@ -58,7 +58,8 @@ def find_spec(self, fullname, path=None, target=None): """Return a module spec for vendored names.""" return ( importlib.util.spec_from_loader(fullname, self) - if self._module_matches_namespace(fullname) else None + if self._module_matches_namespace(fullname) + else None ) def install(self): diff --git a/uno/lib/python/setuptools/glob.py b/uno/lib/python/setuptools/glob.py index 87062b81..647b9bc6 100644 --- a/uno/lib/python/setuptools/glob.py +++ b/uno/lib/python/setuptools/glob.py @@ -155,8 +155,7 @@ def _isrecursive(pattern): def escape(pathname): - """Escape all special characters. - """ + """Escape all special characters.""" # Escaping is done by wrapping any of "*?[" between square brackets. # Metacharacters do not work in the drive part and shouldn't be escaped. drive, pathname = os.path.splitdrive(pathname) diff --git a/uno/lib/python/setuptools/installer.py b/uno/lib/python/setuptools/installer.py index 44ed0da2..e83f959a 100644 --- a/uno/lib/python/setuptools/installer.py +++ b/uno/lib/python/setuptools/installer.py @@ -55,8 +55,10 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) # # take precedence. opts = dist.get_option_dict('easy_install') if 'allow_hosts' in opts: - raise DistutilsError('the `allow-hosts` option is not supported ' - 'when using pip to install requirements.') + raise DistutilsError( + 'the `allow-hosts` option is not supported ' + 'when using pip to install requirements.' + ) quiet = 'PIP_QUIET' not in os.environ and 'PIP_VERBOSE' not in os.environ if 'PIP_INDEX_URL' in os.environ: index_url = None @@ -65,8 +67,7 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) # else: index_url = None find_links = ( - _fixup_find_links(opts['find_links'][1])[:] if 'find_links' in opts - else [] + _fixup_find_links(opts['find_links'][1])[:] if 'find_links' in opts else [] ) if dist.dependency_links: find_links.extend(dist.dependency_links) @@ -77,10 +78,14 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) # return egg_dist with tempfile.TemporaryDirectory() as tmpdir: cmd = [ - sys.executable, '-m', 'pip', + sys.executable, + '-m', + 'pip', '--disable-pip-version-check', - 'wheel', '--no-deps', - '-w', tmpdir, + 'wheel', + '--no-deps', + '-w', + tmpdir, ] if quiet: cmd.append('--quiet') @@ -100,9 +105,11 @@ def _fetch_build_egg_no_warn(dist, req): # noqa: C901 # is too complex (16) # dist_location = os.path.join(eggs_dir, wheel.egg_name()) wheel.install_as_egg(dist_location) dist_metadata = pkg_resources.PathMetadata( - dist_location, os.path.join(dist_location, 'EGG-INFO')) + dist_location, os.path.join(dist_location, 'EGG-INFO') + ) dist = pkg_resources.Distribution.from_filename( - dist_location, metadata=dist_metadata) + dist_location, metadata=dist_metadata + ) return dist diff --git a/uno/lib/python/setuptools/logging.py b/uno/lib/python/setuptools/logging.py index 0653878f..ceca99ca 100644 --- a/uno/lib/python/setuptools/logging.py +++ b/uno/lib/python/setuptools/logging.py @@ -22,7 +22,8 @@ def configure(): out_handler.addFilter(_not_warning) handlers = err_handler, out_handler logging.basicConfig( - format="{message}", style='{', handlers=handlers, level=logging.DEBUG) + format="{message}", style='{', handlers=handlers, level=logging.DEBUG + ) if inspect.ismodule(distutils.dist.log): monkey.patch_func(set_threshold, distutils.log, 'set_threshold') # For some reason `distutils.log` module is getting cached in `distutils.dist` @@ -33,5 +34,5 @@ def configure(): def set_threshold(level): - logging.root.setLevel(level*10) + logging.root.setLevel(level * 10) return set_threshold.unpatched(level) diff --git a/uno/lib/python/setuptools/modified.py b/uno/lib/python/setuptools/modified.py new file mode 100644 index 00000000..af6ceeac --- /dev/null +++ b/uno/lib/python/setuptools/modified.py @@ -0,0 +1,8 @@ +from ._distutils._modified import ( + newer, + newer_pairwise, + newer_group, + newer_pairwise_group, +) + +__all__ = ['newer', 'newer_pairwise', 'newer_group', 'newer_pairwise_group'] diff --git a/uno/lib/python/setuptools/monkey.py b/uno/lib/python/setuptools/monkey.py index 50653fc7..6c8a2f12 100644 --- a/uno/lib/python/setuptools/monkey.py +++ b/uno/lib/python/setuptools/monkey.py @@ -2,15 +2,15 @@ Monkey patching of distutils. """ -import sys -import distutils.filelist +import functools +import inspect import platform +import sys import types -import functools from importlib import import_module -import inspect -import setuptools +import distutils.filelist + __all__ = [] """ @@ -35,9 +35,11 @@ def _get_mro(cls): def get_unpatched(item): lookup = ( - get_unpatched_class if isinstance(item, type) else - get_unpatched_function if isinstance(item, types.FunctionType) else - lambda item: None + get_unpatched_class + if isinstance(item, type) + else get_unpatched_function + if isinstance(item, types.FunctionType) + else lambda item: None ) return lookup(item) @@ -49,9 +51,7 @@ def get_unpatched_class(cls): first. """ external_bases = ( - cls - for cls in _get_mro(cls) - if not cls.__module__.startswith('setuptools') + cls for cls in _get_mro(cls) if not cls.__module__.startswith('setuptools') ) base = next(external_bases) if not base.__module__.startswith('distutils'): @@ -61,20 +61,21 @@ def get_unpatched_class(cls): def patch_all(): + import setuptools + # we can't patch distutils.cmd, alas distutils.core.Command = setuptools.Command has_issue_12885 = sys.version_info <= (3, 5, 3) if has_issue_12885: - # fix findall bug in distutils (http://bugs.python.org/issue12885) + # fix findall bug in distutils (https://bugs.python.org/issue12885) distutils.filelist.findall = setuptools.findall - needs_warehouse = ( - (3, 4) < sys.version_info < (3, 4, 6) - or - (3, 5) < sys.version_info <= (3, 5, 3) - ) + needs_warehouse = (3, 4) < sys.version_info < (3, 4, 6) or ( + 3, + 5, + ) < sys.version_info <= (3, 5, 3) if needs_warehouse: warehouse = 'https://upload.pypi.org/legacy/' @@ -90,17 +91,24 @@ def patch_all(): distutils.core.Extension = setuptools.extension.Extension distutils.extension.Extension = setuptools.extension.Extension if 'distutils.command.build_ext' in sys.modules: - sys.modules['distutils.command.build_ext'].Extension = ( - setuptools.extension.Extension - ) + sys.modules[ + 'distutils.command.build_ext' + ].Extension = setuptools.extension.Extension patch_for_msvc_specialized_compiler() def _patch_distribution_metadata(): + from . import _core_metadata + """Patch write_pkg_file and read_pkg_file for higher metadata standards""" - for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'): - new_val = getattr(setuptools.dist, attr) + for attr in ( + 'write_pkg_info', + 'write_pkg_file', + 'read_pkg_file', + 'get_metadata_version', + ): + new_val = getattr(_core_metadata, attr) setattr(distutils.dist.DistributionMetadata, attr, new_val) diff --git a/uno/lib/python/setuptools/msvc.py b/uno/lib/python/setuptools/msvc.py index 4a08dffe..a910a64b 100644 --- a/uno/lib/python/setuptools/msvc.py +++ b/uno/lib/python/setuptools/msvc.py @@ -45,7 +45,7 @@ def _msvc14_find_vc2015(): winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\VisualStudio\SxS\VC7", 0, - winreg.KEY_READ | winreg.KEY_WOW64_32KEY + winreg.KEY_READ | winreg.KEY_WOW64_32KEY, ) except OSError: return None, None @@ -92,14 +92,25 @@ def _msvc14_find_vc2017(): for component in suitable_components: # Workaround for `-requiresAny` (only available on VS 2017 > 15.6) with contextlib.suppress(CalledProcessError, OSError, UnicodeDecodeError): - path = subprocess.check_output([ - join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), - "-latest", - "-prerelease", - "-requires", component, - "-property", "installationPath", - "-products", "*", - ]).decode(encoding="mbcs", errors="strict").strip() + path = ( + subprocess.check_output( + [ + join( + root, "Microsoft Visual Studio", "Installer", "vswhere.exe" + ), + "-latest", + "-prerelease", + "-requires", + component, + "-property", + "installationPath", + "-products", + "*", + ] + ) + .decode(encoding="mbcs", errors="strict") + .strip() + ) path = join(path, "VC", "Auxiliary", "Build") if isdir(path): @@ -112,7 +123,7 @@ def _msvc14_find_vc2017(): 'x86': 'x86', 'x86_amd64': 'x64', 'x86_arm': 'arm', - 'x86_arm64': 'arm64' + 'x86_arm64': 'arm64', } @@ -127,11 +138,20 @@ def _msvc14_find_vcvarsall(plat_spec): vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' if best_dir: - vcredist = join(best_dir, "..", "..", "redist", "MSVC", "**", - vcruntime_plat, "Microsoft.VC14*.CRT", - "vcruntime140.dll") + vcredist = join( + best_dir, + "..", + "..", + "redist", + "MSVC", + "**", + vcruntime_plat, + "Microsoft.VC14*.CRT", + "vcruntime140.dll", + ) try: import glob + vcruntime = glob.glob(vcredist, recursive=True)[-1] except (ImportError, OSError, LookupError): vcruntime = None @@ -139,8 +159,13 @@ def _msvc14_find_vcvarsall(plat_spec): if not best_dir: best_version, best_dir = _msvc14_find_vc2015() if best_version: - vcruntime = join(best_dir, 'redist', vcruntime_plat, - "Microsoft.VC140.CRT", "vcruntime140.dll") + vcruntime = join( + best_dir, + 'redist', + vcruntime_plat, + "Microsoft.VC140.CRT", + "vcruntime140.dll", + ) if not best_dir: return None, None @@ -158,16 +183,11 @@ def _msvc14_find_vcvarsall(plat_spec): def _msvc14_get_vc_env(plat_spec): """Python 3.8 "distutils/_msvccompiler.py" backport""" if "DISTUTILS_USE_SDK" in environ: - return { - key.lower(): value - for key, value in environ.items() - } + return {key.lower(): value for key, value in environ.items()} vcvarsall, vcruntime = _msvc14_find_vcvarsall(plat_spec) if not vcvarsall: - raise distutils.errors.DistutilsPlatformError( - "Unable to find vcvarsall.bat" - ) + raise distutils.errors.DistutilsPlatformError("Unable to find vcvarsall.bat") try: out = subprocess.check_output( @@ -181,8 +201,7 @@ def _msvc14_get_vc_env(plat_spec): env = { key.lower(): value - for key, _, value in - (line.partition('=') for line in out.splitlines()) + for key, _, value in (line.partition('=') for line in out.splitlines()) if key and value } @@ -247,11 +266,13 @@ def _augment_exception(exc, version, arch=''): message += msdownload % 8279 elif version >= 14.0: # For VC++ 14.X Redirect user to latest Visual C++ Build Tools - message += (' Get it with "Microsoft C++ Build Tools": ' - r'https://visualstudio.microsoft.com' - r'/visual-cpp-build-tools/') + message += ( + ' Get it with "Microsoft C++ Build Tools": ' + r'https://visualstudio.microsoft.com' + r'/visual-cpp-build-tools/' + ) - exc.args = (message, ) + exc.args = (message,) class PlatformInfo: @@ -263,6 +284,7 @@ class PlatformInfo: arch: str Target architecture. """ + current_cpu = environ.get('processor_architecture', '').lower() def __init__(self, arch): @@ -278,7 +300,7 @@ def target_cpu(self): str Target CPU """ - return self.arch[self.arch.find('_') + 1:] + return self.arch[self.arch.find('_') + 1 :] def target_is_x86(self): """ @@ -319,9 +341,11 @@ def current_dir(self, hidex86=False, x64=False): subfolder: '\target', or '' (see hidex86 parameter) """ return ( - '' if (self.current_cpu == 'x86' and hidex86) else - r'\x64' if (self.current_cpu == 'amd64' and x64) else - r'\%s' % self.current_cpu + '' + if (self.current_cpu == 'x86' and hidex86) + else r'\x64' + if (self.current_cpu == 'amd64' and x64) + else r'\%s' % self.current_cpu ) def target_dir(self, hidex86=False, x64=False): @@ -341,9 +365,11 @@ def target_dir(self, hidex86=False, x64=False): subfolder: '\current', or '' (see hidex86 parameter) """ return ( - '' if (self.target_cpu == 'x86' and hidex86) else - r'\x64' if (self.target_cpu == 'amd64' and x64) else - r'\%s' % self.target_cpu + '' + if (self.target_cpu == 'x86' and hidex86) + else r'\x64' + if (self.target_cpu == 'amd64' and x64) + else r'\%s' % self.target_cpu ) def cross_dir(self, forcex86=False): @@ -364,8 +390,9 @@ def cross_dir(self, forcex86=False): """ current = 'x86' if forcex86 else self.current_cpu return ( - '' if self.target_cpu == current else - self.target_dir().replace('\\', '\\%s_' % current) + '' + if self.target_cpu == current + else self.target_dir().replace('\\', '\\%s_' % current) ) @@ -378,10 +405,13 @@ class RegistryInfo: platform_info: PlatformInfo "PlatformInfo" instance. """ - HKEYS = (winreg.HKEY_USERS, - winreg.HKEY_CURRENT_USER, - winreg.HKEY_LOCAL_MACHINE, - winreg.HKEY_CLASSES_ROOT) + + HKEYS = ( + winreg.HKEY_USERS, + winreg.HKEY_CURRENT_USER, + winreg.HKEY_LOCAL_MACHINE, + winreg.HKEY_CLASSES_ROOT, + ) def __init__(self, platform_info): self.pi = platform_info @@ -537,17 +567,17 @@ def lookup(self, key, name): bkey = None try: bkey = openkey(hkey, ms(key), 0, key_read) - except (OSError, IOError): + except OSError: if not self.pi.current_is_x86(): try: bkey = openkey(hkey, ms(key, True), 0, key_read) - except (OSError, IOError): + except OSError: continue else: continue try: return winreg.QueryValueEx(bkey, name)[0] - except (OSError, IOError): + except OSError: pass finally: if bkey: @@ -579,8 +609,7 @@ def __init__(self, registry_info, vc_ver=None): self.known_vs_paths = self.find_programdata_vs_vers() # Except for VS15+, VC version is aligned with VS version - self.vs_ver = self.vc_ver = ( - vc_ver or self._find_latest_available_vs_ver()) + self.vs_ver = self.vc_ver = vc_ver or self._find_latest_available_vs_ver() def _find_latest_available_vs_ver(self): """ @@ -595,7 +624,8 @@ def _find_latest_available_vs_ver(self): if not (reg_vc_vers or self.known_vs_paths): raise distutils.errors.DistutilsPlatformError( - 'No Microsoft Visual C++ version found') + 'No Microsoft Visual C++ version found' + ) vc_vers = set(reg_vc_vers) vc_vers.update(self.known_vs_paths) @@ -616,7 +646,7 @@ def find_reg_vs_vers(self): for hkey, key in itertools.product(self.ri.HKEYS, vckeys): try: bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ) - except (OSError, IOError): + except OSError: continue with bkey: subkeys, values, _ = winreg.QueryInfoKey(bkey) @@ -643,13 +673,12 @@ def find_programdata_vs_vers(self): float version as key, path as value. """ vs_versions = {} - instances_dir = \ - r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances' + instances_dir = r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances' try: hashed_names = listdir(instances_dir) - except (OSError, IOError): + except OSError: # Directory not exists with all Visual Studio versions return vs_versions @@ -665,10 +694,11 @@ def find_programdata_vs_vers(self): listdir(join(vs_path, r'VC\Tools\MSVC')) # Store version and path - vs_versions[self._as_float_version( - state['installationVersion'])] = vs_path + vs_versions[ + self._as_float_version(state['installationVersion']) + ] = vs_path - except (OSError, IOError, KeyError): + except (OSError, KeyError): # Skip if "state.json" file is missing or bad format continue @@ -702,8 +732,9 @@ def VSInstallDir(self): path """ # Default path - default = join(self.ProgramFilesx86, - 'Microsoft Visual Studio %0.1f' % self.vs_ver) + default = join( + self.ProgramFilesx86, 'Microsoft Visual Studio %0.1f' % self.vs_ver + ) # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default @@ -753,7 +784,7 @@ def _guess_vc(self): vc_ver = listdir(guess_vc)[-1] self.vc_ver = self._as_float_version(vc_ver) return join(guess_vc, vc_ver) - except (OSError, IOError, IndexError): + except (OSError, IndexError): return '' def _guess_vc_legacy(self): @@ -765,8 +796,9 @@ def _guess_vc_legacy(self): str path """ - default = join(self.ProgramFilesx86, - r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver) + default = join( + self.ProgramFilesx86, r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver + ) # Try to get "VC++ for Python" path from registry as default path reg_path = join(self.ri.vc_for_python, '%0.1f' % self.vs_ver) @@ -835,7 +867,7 @@ def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME if not sdkdir or not isdir(sdkdir): # If fail, use default new path for ver in self.WindowsSdkVersion: - intver = ver[:ver.rfind('.')] + intver = ver[: ver.rfind('.')] path = r'Microsoft SDKs\Windows Kits\%s' % intver d = join(self.ProgramFiles, path) if isdir(d): @@ -915,8 +947,7 @@ def UniversalCRTSdkDir(self): # Find path of the more recent Kit for ver in vers: - sdkdir = self.ri.lookup(self.ri.windows_kits_roots, - 'kitsroot%s' % ver) + sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot%s' % ver) if sdkdir: return sdkdir or '' @@ -943,10 +974,11 @@ def NetFxSdkVersion(self): versions """ # Set FxSdk versions for specified VS version - return (('4.7.2', '4.7.1', '4.7', - '4.6.2', '4.6.1', '4.6', - '4.5.2', '4.5.1', '4.5') - if self.vs_ver >= 14.0 else ()) + return ( + ('4.7.2', '4.7.1', '4.7', '4.6.2', '4.6.1', '4.6', '4.5.2', '4.5.1', '4.5') + if self.vs_ver >= 14.0 + else () + ) @property def NetFxSdkDir(self): @@ -1071,8 +1103,7 @@ def _use_last_dir_name(path, prefix=''): matching_dirs = ( dir_name for dir_name in reversed(listdir(path)) - if isdir(join(path, dir_name)) and - dir_name.startswith(prefix) + if isdir(join(path, dir_name)) and dir_name.startswith(prefix) ) return next(matching_dirs, None) or '' @@ -1164,8 +1195,10 @@ def VCIncludes(self): list of str paths """ - return [join(self.si.VCInstallDir, 'Include'), - join(self.si.VCInstallDir, r'ATLMFC\Include')] + return [ + join(self.si.VCInstallDir, 'Include'), + join(self.si.VCInstallDir, r'ATLMFC\Include'), + ] @property def VCLibraries(self): @@ -1225,14 +1258,15 @@ def VCTools(self): tools += [join(si.VCInstallDir, path)] elif self.vs_ver >= 15.0: - host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else - r'bin\HostX64%s') - tools += [join( - si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] + host_dir = ( + r'bin\HostX86%s' if self.pi.current_is_x86() else r'bin\HostX64%s' + ) + tools += [join(si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] if self.pi.current_cpu != self.pi.target_cpu: - tools += [join( - si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] + tools += [ + join(si.VCInstallDir, host_dir % self.pi.current_dir(x64=True)) + ] else: tools += [join(si.VCInstallDir, 'Bin')] @@ -1279,9 +1313,11 @@ def OSIncludes(self): sdkver = self._sdk_subdir else: sdkver = '' - return [join(include, '%sshared' % sdkver), - join(include, '%sum' % sdkver), - join(include, '%swinrt' % sdkver)] + return [ + join(include, '%sshared' % sdkver), + join(include, '%sum' % sdkver), + join(include, '%swinrt' % sdkver), + ] @property def OSLibpath(self): @@ -1306,16 +1342,18 @@ def OSLibpath(self): libpath += [ ref, join(self.si.WindowsSdkDir, 'UnionMetadata'), - join( - ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'), + join(ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'), join(ref, 'Windows.Foundation.FoundationContract', '1.0.0.0'), + join(ref, 'Windows.Networking.Connectivity.WwanContract', '1.0.0.0'), join( - ref, 'Windows.Networking.Connectivity.WwanContract', - '1.0.0.0'), - join( - self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs', - '%0.1f' % self.vs_ver, 'References', 'CommonConfiguration', - 'neutral'), + self.si.WindowsSdkDir, + 'ExtensionSDKs', + 'Microsoft.VCLibs', + '%0.1f' % self.vs_ver, + 'References', + 'CommonConfiguration', + 'neutral', + ), ] return libpath @@ -1416,11 +1454,9 @@ def FxTools(self): tools = [] if include32: - tools += [join(si.FrameworkDir32, ver) - for ver in si.FrameworkVersion32] + tools += [join(si.FrameworkDir32, ver) for ver in si.FrameworkVersion32] if include64: - tools += [join(si.FrameworkDir64, ver) - for ver in si.FrameworkVersion64] + tools += [join(si.FrameworkDir64, ver) for ver in si.FrameworkVersion64] return tools @property @@ -1596,9 +1632,11 @@ def VCRuntimeRedist(self): prefixes += [join(tools_path, 'redist')] # VS14 legacy path # CRT directory - crt_dirs = ('Microsoft.VC%d.CRT' % (self.vc_ver * 10), - # Sometime store in directory with VS version instead of VC - 'Microsoft.VC%d.CRT' % (int(self.vs_ver) * 10)) + crt_dirs = ( + 'Microsoft.VC%d.CRT' % (self.vc_ver * 10), + # Sometime store in directory with VS version instead of VC + 'Microsoft.VC%d.CRT' % (int(self.vs_ver) * 10), + ) # vcruntime path for prefix, crt_dir in itertools.product(prefixes, crt_dirs): @@ -1621,36 +1659,47 @@ def return_env(self, exists=True): environment """ env = dict( - include=self._build_paths('include', - [self.VCIncludes, - self.OSIncludes, - self.UCRTIncludes, - self.NetFxSDKIncludes], - exists), - lib=self._build_paths('lib', - [self.VCLibraries, - self.OSLibraries, - self.FxTools, - self.UCRTLibraries, - self.NetFxSDKLibraries], - exists), - libpath=self._build_paths('libpath', - [self.VCLibraries, - self.FxTools, - self.VCStoreRefs, - self.OSLibpath], - exists), - path=self._build_paths('path', - [self.VCTools, - self.VSTools, - self.VsTDb, - self.SdkTools, - self.SdkSetup, - self.FxTools, - self.MSBuild, - self.HTMLHelpWorkshop, - self.FSharp], - exists), + include=self._build_paths( + 'include', + [ + self.VCIncludes, + self.OSIncludes, + self.UCRTIncludes, + self.NetFxSDKIncludes, + ], + exists, + ), + lib=self._build_paths( + 'lib', + [ + self.VCLibraries, + self.OSLibraries, + self.FxTools, + self.UCRTLibraries, + self.NetFxSDKLibraries, + ], + exists, + ), + libpath=self._build_paths( + 'libpath', + [self.VCLibraries, self.FxTools, self.VCStoreRefs, self.OSLibpath], + exists, + ), + path=self._build_paths( + 'path', + [ + self.VCTools, + self.VSTools, + self.VsTDb, + self.SdkTools, + self.SdkSetup, + self.FxTools, + self.MSBuild, + self.HTMLHelpWorkshop, + self.FSharp, + ], + exists, + ), ) if self.vs_ver >= 14 and isfile(self.VCRuntimeRedist): env['py_vcruntime_redist'] = self.VCRuntimeRedist diff --git a/uno/lib/python/setuptools/namespaces.py b/uno/lib/python/setuptools/namespaces.py index 44939e1c..3332f864 100644 --- a/uno/lib/python/setuptools/namespaces.py +++ b/uno/lib/python/setuptools/namespaces.py @@ -7,15 +7,13 @@ class Installer: - nspkg_ext = '-nspkg.pth' def install_namespaces(self): nsp = self._get_all_ns_packages() if not nsp: return - filename, ext = os.path.splitext(self._get_target()) - filename += self.nspkg_ext + filename = self._get_nspkg_file() self.outputs.append(filename) log.info("Installing %s", filename) lines = map(self._gen_nspkg_line, nsp) @@ -29,13 +27,16 @@ def install_namespaces(self): f.writelines(lines) def uninstall_namespaces(self): - filename, ext = os.path.splitext(self._get_target()) - filename += self.nspkg_ext + filename = self._get_nspkg_file() if not os.path.exists(filename): return log.info("Removing %s", filename) os.remove(filename) + def _get_nspkg_file(self): + filename, _ = os.path.splitext(self._get_target()) + return filename + self.nspkg_ext + def _get_target(self): return self.target @@ -52,18 +53,13 @@ def _get_target(self): "importlib.machinery.PathFinder.find_spec(%(pkg)r, " "[os.path.dirname(p)])))" ), - ( - "m = m or " - "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))" - ), + ("m = m or " "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))"), "mp = (m or []) and m.__dict__.setdefault('__path__',[])", "(p not in mp) and mp.append(p)", ) "lines for the namespace installer" - _nspkg_tmpl_multi = ( - 'm and setattr(sys.modules[%(parent)r], %(child)r, m)', - ) + _nspkg_tmpl_multi = ('m and setattr(sys.modules[%(parent)r], %(child)r, m)',) "additional line(s) when a parent package is indicated" def _get_root(self): @@ -81,7 +77,7 @@ def _gen_nspkg_line(self, pkg): def _get_all_ns_packages(self): """Return sorted list of all package namespaces""" pkgs = self.distribution.namespace_packages or [] - return sorted(flatten(map(self._pkg_names, pkgs))) + return sorted(set(flatten(map(self._pkg_names, pkgs)))) @staticmethod def _pkg_names(pkg): diff --git a/uno/lib/python/setuptools/package_index.py b/uno/lib/python/setuptools/package_index.py index 3130acef..3cedd510 100644 --- a/uno/lib/python/setuptools/package_index.py +++ b/uno/lib/python/setuptools/package_index.py @@ -195,7 +195,7 @@ def interpret_distro_name( '-'.join(parts[p:]), py_version=py_version, precedence=precedence, - platform=platform + platform=platform, ) @@ -305,7 +305,7 @@ def __init__( ca_bundle=None, verify_ssl=True, *args, - **kw + **kw, ): super().__init__(*args, **kw) self.index_url = index_url + "/"[: not index_url.endswith('/')] @@ -634,7 +634,6 @@ def find(req, env=None): # Find a matching distribution; may be called more than once for dist in env[req.key]: - if dist.precedence == DEVELOP_DIST and not develop_ok: if dist not in skipped: self.warn( @@ -807,7 +806,7 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) '%s returned a bad status line. The server might be ' 'down, %s' % (url, v.line) ) from v - except (http.client.HTTPException, socket.error) as v: + except (http.client.HTTPException, OSError) as v: if warning: self.warn(warning, v) else: diff --git a/uno/lib/python/setuptools/warnings.py b/uno/lib/python/setuptools/warnings.py index 4ea782e5..b3e252ca 100644 --- a/uno/lib/python/setuptools/warnings.py +++ b/uno/lib/python/setuptools/warnings.py @@ -29,7 +29,7 @@ def emit( see_docs: Optional[str] = None, see_url: Optional[str] = None, stacklevel: int = 2, - **kwargs + **kwargs, ): """Private: reserved for ``setuptools`` internal use only""" # Default values: @@ -63,15 +63,16 @@ def _format( ( f"\nBy {due_date:%Y-%b-%d}, you need to update your project and remove " "deprecated calls\nor your builds will no longer be supported." - if due_date and due_date > today else None + if due_date and due_date > today + else None ), ( "\nThis deprecation is overdue, please update your project and remove " "deprecated\ncalls to avoid build errors in the future." - if due_date and due_date < today else None + if due_date and due_date < today + else None ), - (f"\nSee {see_url} for details." if see_url else None) - + (f"\nSee {see_url} for details." if see_url else None), ] parts = [x for x in possible_parts if x] if parts: diff --git a/uno/lib/python/setuptools/wheel.py b/uno/lib/python/setuptools/wheel.py index 850e43cd..c6eabddc 100644 --- a/uno/lib/python/setuptools/wheel.py +++ b/uno/lib/python/setuptools/wheel.py @@ -23,10 +23,10 @@ r"""^(?P.+?)-(?P\d.*?) ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) )\.whl$""", - re.VERBOSE).match + re.VERBOSE, +).match -NAMESPACE_PACKAGE_INIT = \ - "__import__('pkg_resources').declare_namespace(__name__)\n" +NAMESPACE_PACKAGE_INIT = "__import__('pkg_resources').declare_namespace(__name__)\n" @functools.lru_cache(maxsize=None) @@ -65,6 +65,7 @@ def disable_info_traces(): Temporarily disable info traces. """ from distutils import log + saved = log.set_threshold(log.WARN) try: yield @@ -73,7 +74,6 @@ def disable_info_traces(): class Wheel: - def __init__(self, filename): match = WHEEL_NAME(os.path.basename(filename)) if match is None: @@ -95,19 +95,22 @@ def is_compatible(self): return next((True for t in self.tags() if t in _get_supported_tags()), False) def egg_name(self): - return _egg_basename( - self.project_name, - self.version, - platform=(None if self.platform == 'any' else get_platform()), - ) + ".egg" + return ( + _egg_basename( + self.project_name, + self.version, + platform=(None if self.platform == 'any' else get_platform()), + ) + + ".egg" + ) def get_dist_info(self, zf): # find the correct name of the .dist-info dir in the wheel file for member in zf.namelist(): dirname = posixpath.dirname(member) - if (dirname.endswith('.dist-info') and - canonicalize_name(dirname).startswith( - canonicalize_name(self.project_name))): + if dirname.endswith('.dist-info') and canonicalize_name(dirname).startswith( + canonicalize_name(self.project_name) + ): return dirname raise ValueError("unsupported wheel format. .dist-info not found") @@ -138,18 +141,16 @@ def get_metadata(name): wheel_metadata = get_metadata('WHEEL') # Check wheel format version is supported. wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) - wheel_v1 = ( - parse_version('1.0') <= wheel_version < parse_version('2.0dev0') - ) + wheel_v1 = parse_version('1.0') <= wheel_version < parse_version('2.0dev0') if not wheel_v1: - raise ValueError( - 'unsupported wheel format version: %s' % wheel_version) + raise ValueError('unsupported wheel format version: %s' % wheel_version) # Extract to target directory. _unpack_zipfile_obj(zf, destination_eggdir) # Convert metadata. dist_info = os.path.join(destination_eggdir, dist_info) dist = pkg_resources.Distribution.from_location( - destination_eggdir, dist_info, + destination_eggdir, + dist_info, metadata=pkg_resources.PathMetadata(destination_eggdir, dist_info), ) @@ -159,6 +160,7 @@ def get_metadata(name): def raw_req(req): req.marker = None return str(req) + install_requires = list(map(raw_req, dist.requires())) extras_require = { extra: [ @@ -192,8 +194,7 @@ def _move_data_entries(destination_eggdir, dist_data): dist_data = os.path.join(destination_eggdir, dist_data) dist_data_scripts = os.path.join(dist_data, 'scripts') if os.path.exists(dist_data_scripts): - egg_info_scripts = os.path.join( - destination_eggdir, 'EGG-INFO', 'scripts') + egg_info_scripts = os.path.join(destination_eggdir, 'EGG-INFO', 'scripts') os.mkdir(egg_info_scripts) for entry in os.listdir(dist_data_scripts): # Remove bytecode, as it's not properly handled @@ -206,18 +207,20 @@ def _move_data_entries(destination_eggdir, dist_data): os.path.join(egg_info_scripts, entry), ) os.rmdir(dist_data_scripts) - for subdir in filter(os.path.exists, ( - os.path.join(dist_data, d) - for d in ('data', 'headers', 'purelib', 'platlib') - )): + for subdir in filter( + os.path.exists, + ( + os.path.join(dist_data, d) + for d in ('data', 'headers', 'purelib', 'platlib') + ), + ): unpack(subdir, destination_eggdir) if os.path.exists(dist_data): os.rmdir(dist_data) @staticmethod def _fix_namespace_packages(egg_info, destination_eggdir): - namespace_packages = os.path.join( - egg_info, 'namespace_packages.txt') + namespace_packages = os.path.join(egg_info, 'namespace_packages.txt') if os.path.exists(namespace_packages): with open(namespace_packages) as fp: namespace_packages = fp.read().split() diff --git a/uno/lib/python/setuptools/windows_support.py b/uno/lib/python/setuptools/windows_support.py index 1ca64fbb..8299ac1c 100644 --- a/uno/lib/python/setuptools/windows_support.py +++ b/uno/lib/python/setuptools/windows_support.py @@ -12,11 +12,12 @@ def hide_file(path): """ Set the hidden attribute on a file or directory. - From http://stackoverflow.com/questions/19622133/ + From https://stackoverflow.com/questions/19622133/ `path` must be text. """ import ctypes + __import__('ctypes.wintypes') SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD diff --git a/uno/lib/python/urllib3/__init__.py b/uno/lib/python/urllib3/__init__.py index 7ddfad20..46c89762 100644 --- a/uno/lib/python/urllib3/__init__.py +++ b/uno/lib/python/urllib3/__init__.py @@ -32,35 +32,18 @@ else: if not ssl.OPENSSL_VERSION.startswith("OpenSSL "): # Defensive: warnings.warn( - "urllib3 v2.0 only supports OpenSSL 1.1.1+, currently " + "urllib3 v2 only supports OpenSSL 1.1.1+, currently " f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. " "See: https://github.com/urllib3/urllib3/issues/3020", exceptions.NotOpenSSLWarning, ) elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1): # Defensive: raise ImportError( - "urllib3 v2.0 only supports OpenSSL 1.1.1+, currently " + "urllib3 v2 only supports OpenSSL 1.1.1+, currently " f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. " "See: https://github.com/urllib3/urllib3/issues/2168" ) -# === NOTE TO REPACKAGERS AND VENDORS === -# Please delete this block, this logic is only -# for urllib3 being distributed via PyPI. -# See: https://github.com/urllib3/urllib3/issues/2680 -try: - import urllib3_secure_extra # type: ignore # noqa: F401 -except ModuleNotFoundError: - pass -else: - warnings.warn( - "'urllib3[secure]' extra is deprecated and will be removed " - "in urllib3 v2.1.0. Read more in this issue: " - "https://github.com/urllib3/urllib3/issues/2680", - category=DeprecationWarning, - stacklevel=2, - ) - __author__ = "Andrey Petrov (andrey.petrov@shazow.net)" __license__ = "MIT" __version__ = __version__ @@ -81,6 +64,7 @@ "make_headers", "proxy_from_url", "request", + "BaseHTTPResponse", ) logging.getLogger(__name__).addHandler(NullHandler()) diff --git a/uno/lib/python/urllib3/_base_connection.py b/uno/lib/python/urllib3/_base_connection.py index 3afed765..bb349c74 100644 --- a/uno/lib/python/urllib3/_base_connection.py +++ b/uno/lib/python/urllib3/_base_connection.py @@ -28,8 +28,7 @@ class _ResponseOptions(typing.NamedTuple): if typing.TYPE_CHECKING: import ssl - - from typing_extensions import Literal, Protocol + from typing import Literal, Protocol from .response import BaseHTTPResponse @@ -151,7 +150,7 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: _TYPE_SOCKET_OPTIONS | None = ..., proxy: Url | None = None, proxy_config: ProxyConfig | None = None, diff --git a/uno/lib/python/urllib3/_collections.py b/uno/lib/python/urllib3/_collections.py index 3e43afbc..55b03247 100644 --- a/uno/lib/python/urllib3/_collections.py +++ b/uno/lib/python/urllib3/_collections.py @@ -8,7 +8,9 @@ if typing.TYPE_CHECKING: # We can only import Protocol if TYPE_CHECKING because it's a development # dependency, and is not available at runtime. - from typing_extensions import Protocol + from typing import Protocol + + from typing_extensions import Self class HasGettableStringKeys(Protocol): def keys(self) -> typing.Iterator[str]: @@ -239,7 +241,7 @@ class HTTPHeaderDict(typing.MutableMapping[str, str]): def __init__(self, headers: ValidHTTPHeaderSource | None = None, **kwargs: str): super().__init__() - self._container = {} # 'dict' is insert-ordered in Python 3.7+ + self._container = {} # 'dict' is insert-ordered if headers is not None: if isinstance(headers, HTTPHeaderDict): self._copy_from(headers) @@ -391,6 +393,24 @@ def getlist( # meets our external interface requirement of `Union[List[str], _DT]`. return vals[1:] + def _prepare_for_method_change(self) -> Self: + """ + Remove content-specific header fields before changing the request + method to GET or HEAD according to RFC 9110, Section 15.4. + """ + content_specific_headers = [ + "Content-Encoding", + "Content-Language", + "Content-Location", + "Content-Type", + "Content-Length", + "Digest", + "Last-Modified", + ] + for header in content_specific_headers: + self.discard(header) + return self + # Backwards compatibility for httplib getheaders = getlist getallmatchingheaders = getlist @@ -432,3 +452,32 @@ def _has_value_for_header(self, header_name: str, potential_value: str) -> bool: if header_name in self: return potential_value in self._container[header_name.lower()][1:] return False + + def __ior__(self, other: object) -> HTTPHeaderDict: + # Supports extending a header dict in-place using operator |= + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + self.extend(maybe_constructable) + return self + + def __or__(self, other: object) -> HTTPHeaderDict: + # Supports merging header dicts using operator | + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = self.copy() + result.extend(maybe_constructable) + return result + + def __ror__(self, other: object) -> HTTPHeaderDict: + # Supports merging header dicts using operator | when other is on left side + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = type(self)(maybe_constructable) + result.extend(self) + return result diff --git a/uno/lib/python/urllib3/_version.py b/uno/lib/python/urllib3/_version.py index e85dd3af..409ba3f5 100644 --- a/uno/lib/python/urllib3/_version.py +++ b/uno/lib/python/urllib3/_version.py @@ -1,4 +1,4 @@ # This file is protected via CODEOWNERS from __future__ import annotations -__version__ = "2.0.3" +__version__ = "2.1.0" diff --git a/uno/lib/python/urllib3/connection.py b/uno/lib/python/urllib3/connection.py index 50f5e616..38a2fd6d 100644 --- a/uno/lib/python/urllib3/connection.py +++ b/uno/lib/python/urllib3/connection.py @@ -5,6 +5,7 @@ import os import re import socket +import sys import typing import warnings from http.client import HTTPConnection as _HTTPConnection @@ -13,7 +14,7 @@ from socket import timeout as SocketTimeout if typing.TYPE_CHECKING: - from typing_extensions import Literal + from typing import Literal from .response import HTTPResponse from .util.ssl_ import _TYPE_PEER_CERT_RET_DICT @@ -76,6 +77,8 @@ class BaseSSLError(BaseException): # type: ignore[no-redef] _CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") +_HAS_SYS_AUDIT = hasattr(sys, "audit") + class HTTPConnection(_HTTPConnection): """ @@ -134,7 +137,7 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: None | (connection._TYPE_SOCKET_OPTIONS) = default_socket_options, proxy: Url | None = None, @@ -216,6 +219,10 @@ def _new_conn(self) -> socket.socket: self, f"Failed to establish a new connection: {e}" ) from e + # Audit hooks are only available in Python 3.8+ + if _HAS_SYS_AUDIT: + sys.audit("http.client.connect", self, self.host, self.port) + return sock def set_tunnel( @@ -505,7 +512,7 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: None | (connection._TYPE_SOCKET_OPTIONS) = HTTPConnection.default_socket_options, proxy: Url | None = None, @@ -750,10 +757,9 @@ def _ssl_wrap_socket_and_match_hostname( ): context.check_hostname = False - # Try to load OS default certs if none are given. - # We need to do the hasattr() check for our custom - # pyOpenSSL and SecureTransport SSLContext objects - # because neither support load_default_certs(). + # Try to load OS default certs if none are given. We need to do the hasattr() check + # for custom pyOpenSSL SSLContext objects because they don't support + # load_default_certs(). if ( not ca_certs and not ca_cert_dir diff --git a/uno/lib/python/urllib3/connectionpool.py b/uno/lib/python/urllib3/connectionpool.py index 2479405b..70048b7a 100644 --- a/uno/lib/python/urllib3/connectionpool.py +++ b/uno/lib/python/urllib3/connectionpool.py @@ -11,6 +11,7 @@ from types import TracebackType from ._base_connection import _TYPE_BODY +from ._collections import HTTPHeaderDict from ._request_methods import RequestMethods from .connection import ( BaseSSLError, @@ -52,8 +53,7 @@ if typing.TYPE_CHECKING: import ssl - - from typing_extensions import Literal + from typing import Literal from ._base_connection import BaseHTTPConnection, BaseHTTPSConnection @@ -893,7 +893,11 @@ def urlopen( # type: ignore[override] redirect_location = redirect and response.get_redirect_location() if redirect_location: if response.status == 303: + # Change the method according to RFC 9110, Section 15.4.4. method = "GET" + # And lose the body not to transfer anything sensitive. + body = None + headers = HTTPHeaderDict(headers)._prepare_for_method_change() try: retries = retries.increment(method, url, response=response, _pool=self) diff --git a/uno/lib/python/urllib3/contrib/_securetransport/bindings.py b/uno/lib/python/urllib3/contrib/_securetransport/bindings.py deleted file mode 100644 index 3e4cd466..00000000 --- a/uno/lib/python/urllib3/contrib/_securetransport/bindings.py +++ /dev/null @@ -1,430 +0,0 @@ -# type: ignore - -""" -This module uses ctypes to bind a whole bunch of functions and constants from -SecureTransport. The goal here is to provide the low-level API to -SecureTransport. These are essentially the C-level functions and constants, and -they're pretty gross to work with. - -This code is a bastardised version of the code found in Will Bond's oscrypto -library. An enormous debt is owed to him for blazing this trail for us. For -that reason, this code should be considered to be covered both by urllib3's -license and by oscrypto's: - - Copyright (c) 2015-2016 Will Bond - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -""" - -from __future__ import annotations - -import platform -from ctypes import ( - CDLL, - CFUNCTYPE, - POINTER, - c_bool, - c_byte, - c_char_p, - c_int32, - c_long, - c_size_t, - c_uint32, - c_ulong, - c_void_p, -) -from ctypes.util import find_library - -if platform.system() != "Darwin": - raise ImportError("Only macOS is supported") - -version = platform.mac_ver()[0] -version_info = tuple(map(int, version.split("."))) -if version_info < (10, 8): - raise OSError( - f"Only OS X 10.8 and newer are supported, not {version_info[0]}.{version_info[1]}" - ) - - -def load_cdll(name: str, macos10_16_path: str) -> CDLL: - """Loads a CDLL by name, falling back to known path on 10.16+""" - try: - # Big Sur is technically 11 but we use 10.16 due to the Big Sur - # beta being labeled as 10.16. - path: str | None - if version_info >= (10, 16): - path = macos10_16_path - else: - path = find_library(name) - if not path: - raise OSError # Caught and reraised as 'ImportError' - return CDLL(path, use_errno=True) - except OSError: - raise ImportError(f"The library {name} failed to load") from None - - -Security = load_cdll( - "Security", "/System/Library/Frameworks/Security.framework/Security" -) -CoreFoundation = load_cdll( - "CoreFoundation", - "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", -) - - -Boolean = c_bool -CFIndex = c_long -CFStringEncoding = c_uint32 -CFData = c_void_p -CFString = c_void_p -CFArray = c_void_p -CFMutableArray = c_void_p -CFDictionary = c_void_p -CFError = c_void_p -CFType = c_void_p -CFTypeID = c_ulong - -CFTypeRef = POINTER(CFType) -CFAllocatorRef = c_void_p - -OSStatus = c_int32 - -CFDataRef = POINTER(CFData) -CFStringRef = POINTER(CFString) -CFArrayRef = POINTER(CFArray) -CFMutableArrayRef = POINTER(CFMutableArray) -CFDictionaryRef = POINTER(CFDictionary) -CFArrayCallBacks = c_void_p -CFDictionaryKeyCallBacks = c_void_p -CFDictionaryValueCallBacks = c_void_p - -SecCertificateRef = POINTER(c_void_p) -SecExternalFormat = c_uint32 -SecExternalItemType = c_uint32 -SecIdentityRef = POINTER(c_void_p) -SecItemImportExportFlags = c_uint32 -SecItemImportExportKeyParameters = c_void_p -SecKeychainRef = POINTER(c_void_p) -SSLProtocol = c_uint32 -SSLCipherSuite = c_uint32 -SSLContextRef = POINTER(c_void_p) -SecTrustRef = POINTER(c_void_p) -SSLConnectionRef = c_uint32 -SecTrustResultType = c_uint32 -SecTrustOptionFlags = c_uint32 -SSLProtocolSide = c_uint32 -SSLConnectionType = c_uint32 -SSLSessionOption = c_uint32 - - -try: - Security.SecItemImport.argtypes = [ - CFDataRef, - CFStringRef, - POINTER(SecExternalFormat), - POINTER(SecExternalItemType), - SecItemImportExportFlags, - POINTER(SecItemImportExportKeyParameters), - SecKeychainRef, - POINTER(CFArrayRef), - ] - Security.SecItemImport.restype = OSStatus - - Security.SecCertificateGetTypeID.argtypes = [] - Security.SecCertificateGetTypeID.restype = CFTypeID - - Security.SecIdentityGetTypeID.argtypes = [] - Security.SecIdentityGetTypeID.restype = CFTypeID - - Security.SecKeyGetTypeID.argtypes = [] - Security.SecKeyGetTypeID.restype = CFTypeID - - Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef] - Security.SecCertificateCreateWithData.restype = SecCertificateRef - - Security.SecCertificateCopyData.argtypes = [SecCertificateRef] - Security.SecCertificateCopyData.restype = CFDataRef - - Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SecIdentityCreateWithCertificate.argtypes = [ - CFTypeRef, - SecCertificateRef, - POINTER(SecIdentityRef), - ] - Security.SecIdentityCreateWithCertificate.restype = OSStatus - - Security.SecKeychainCreate.argtypes = [ - c_char_p, - c_uint32, - c_void_p, - Boolean, - c_void_p, - POINTER(SecKeychainRef), - ] - Security.SecKeychainCreate.restype = OSStatus - - Security.SecKeychainDelete.argtypes = [SecKeychainRef] - Security.SecKeychainDelete.restype = OSStatus - - Security.SecPKCS12Import.argtypes = [ - CFDataRef, - CFDictionaryRef, - POINTER(CFArrayRef), - ] - Security.SecPKCS12Import.restype = OSStatus - - SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) - SSLWriteFunc = CFUNCTYPE( - OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t) - ) - - Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc] - Security.SSLSetIOFuncs.restype = OSStatus - - Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t] - Security.SSLSetPeerID.restype = OSStatus - - Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef] - Security.SSLSetCertificate.restype = OSStatus - - Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean] - Security.SSLSetCertificateAuthorities.restype = OSStatus - - Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef] - Security.SSLSetConnection.restype = OSStatus - - Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t] - Security.SSLSetPeerDomainName.restype = OSStatus - - Security.SSLHandshake.argtypes = [SSLContextRef] - Security.SSLHandshake.restype = OSStatus - - Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] - Security.SSLRead.restype = OSStatus - - Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] - Security.SSLWrite.restype = OSStatus - - Security.SSLClose.argtypes = [SSLContextRef] - Security.SSLClose.restype = OSStatus - - Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)] - Security.SSLGetNumberSupportedCiphers.restype = OSStatus - - Security.SSLGetSupportedCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t), - ] - Security.SSLGetSupportedCiphers.restype = OSStatus - - Security.SSLSetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - c_size_t, - ] - Security.SSLSetEnabledCiphers.restype = OSStatus - - Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)] - Security.SSLGetNumberEnabledCiphers.restype = OSStatus - - Security.SSLGetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t), - ] - Security.SSLGetEnabledCiphers.restype = OSStatus - - Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)] - Security.SSLGetNegotiatedCipher.restype = OSStatus - - Security.SSLGetNegotiatedProtocolVersion.argtypes = [ - SSLContextRef, - POINTER(SSLProtocol), - ] - Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus - - Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)] - Security.SSLCopyPeerTrust.restype = OSStatus - - Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef] - Security.SecTrustSetAnchorCertificates.restype = OSStatus - - Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean] - Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus - - Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)] - Security.SecTrustEvaluate.restype = OSStatus - - Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef] - Security.SecTrustGetCertificateCount.restype = CFIndex - - Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex] - Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef - - Security.SSLCreateContext.argtypes = [ - CFAllocatorRef, - SSLProtocolSide, - SSLConnectionType, - ] - Security.SSLCreateContext.restype = SSLContextRef - - Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean] - Security.SSLSetSessionOption.restype = OSStatus - - Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol] - Security.SSLSetProtocolVersionMin.restype = OSStatus - - Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol] - Security.SSLSetProtocolVersionMax.restype = OSStatus - - try: - Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef] - Security.SSLSetALPNProtocols.restype = OSStatus - except AttributeError: - # Supported only in 10.12+ - pass - - Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SSLReadFunc = SSLReadFunc - Security.SSLWriteFunc = SSLWriteFunc - Security.SSLContextRef = SSLContextRef - Security.SSLProtocol = SSLProtocol - Security.SSLCipherSuite = SSLCipherSuite - Security.SecIdentityRef = SecIdentityRef - Security.SecKeychainRef = SecKeychainRef - Security.SecTrustRef = SecTrustRef - Security.SecTrustResultType = SecTrustResultType - Security.SecExternalFormat = SecExternalFormat - Security.OSStatus = OSStatus - - Security.kSecImportExportPassphrase = CFStringRef.in_dll( - Security, "kSecImportExportPassphrase" - ) - Security.kSecImportItemIdentity = CFStringRef.in_dll( - Security, "kSecImportItemIdentity" - ) - - # CoreFoundation time! - CoreFoundation.CFRetain.argtypes = [CFTypeRef] - CoreFoundation.CFRetain.restype = CFTypeRef - - CoreFoundation.CFRelease.argtypes = [CFTypeRef] - CoreFoundation.CFRelease.restype = None - - CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef] - CoreFoundation.CFGetTypeID.restype = CFTypeID - - CoreFoundation.CFStringCreateWithCString.argtypes = [ - CFAllocatorRef, - c_char_p, - CFStringEncoding, - ] - CoreFoundation.CFStringCreateWithCString.restype = CFStringRef - - CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] - CoreFoundation.CFStringGetCStringPtr.restype = c_char_p - - CoreFoundation.CFStringGetCString.argtypes = [ - CFStringRef, - c_char_p, - CFIndex, - CFStringEncoding, - ] - CoreFoundation.CFStringGetCString.restype = c_bool - - CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex] - CoreFoundation.CFDataCreate.restype = CFDataRef - - CoreFoundation.CFDataGetLength.argtypes = [CFDataRef] - CoreFoundation.CFDataGetLength.restype = CFIndex - - CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef] - CoreFoundation.CFDataGetBytePtr.restype = c_void_p - - CoreFoundation.CFDictionaryCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - POINTER(CFTypeRef), - CFIndex, - CFDictionaryKeyCallBacks, - CFDictionaryValueCallBacks, - ] - CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef - - CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef] - CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef - - CoreFoundation.CFArrayCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - CFIndex, - CFArrayCallBacks, - ] - CoreFoundation.CFArrayCreate.restype = CFArrayRef - - CoreFoundation.CFArrayCreateMutable.argtypes = [ - CFAllocatorRef, - CFIndex, - CFArrayCallBacks, - ] - CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef - - CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p] - CoreFoundation.CFArrayAppendValue.restype = None - - CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] - CoreFoundation.CFArrayGetCount.restype = CFIndex - - CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] - CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p - - CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( - CoreFoundation, "kCFAllocatorDefault" - ) - CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeArrayCallBacks" - ) - CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeDictionaryKeyCallBacks" - ) - CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeDictionaryValueCallBacks" - ) - - CoreFoundation.CFTypeRef = CFTypeRef - CoreFoundation.CFArrayRef = CFArrayRef - CoreFoundation.CFStringRef = CFStringRef - CoreFoundation.CFDictionaryRef = CFDictionaryRef - -except AttributeError: - raise ImportError("Error initializing ctypes") from None - - -class CFConst: - """ - A class object that acts as essentially a namespace for CoreFoundation - constants. - """ - - kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) diff --git a/uno/lib/python/urllib3/contrib/_securetransport/low_level.py b/uno/lib/python/urllib3/contrib/_securetransport/low_level.py deleted file mode 100644 index e2356997..00000000 --- a/uno/lib/python/urllib3/contrib/_securetransport/low_level.py +++ /dev/null @@ -1,474 +0,0 @@ -""" -Low-level helpers for the SecureTransport bindings. - -These are Python functions that are not directly related to the high-level APIs -but are necessary to get them to work. They include a whole bunch of low-level -CoreFoundation messing about and memory management. The concerns in this module -are almost entirely about trying to avoid memory leaks and providing -appropriate and useful assistance to the higher-level code. -""" -from __future__ import annotations - -import base64 -import ctypes -import itertools -import os -import re -import ssl -import struct -import tempfile -import typing - -from .bindings import ( # type: ignore[attr-defined] - CFArray, - CFConst, - CFData, - CFDictionary, - CFMutableArray, - CFString, - CFTypeRef, - CoreFoundation, - SecKeychainRef, - Security, -) - -# This regular expression is used to grab PEM data out of a PEM bundle. -_PEM_CERTS_RE = re.compile( - b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL -) - - -def _cf_data_from_bytes(bytestring: bytes) -> CFData: - """ - Given a bytestring, create a CFData object from it. This CFData object must - be CFReleased by the caller. - """ - return CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) - ) - - -def _cf_dictionary_from_tuples( - tuples: list[tuple[typing.Any, typing.Any]] -) -> CFDictionary: - """ - Given a list of Python tuples, create an associated CFDictionary. - """ - dictionary_size = len(tuples) - - # We need to get the dictionary keys and values out in the same order. - keys = (t[0] for t in tuples) - values = (t[1] for t in tuples) - cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) - cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) - - return CoreFoundation.CFDictionaryCreate( - CoreFoundation.kCFAllocatorDefault, - cf_keys, - cf_values, - dictionary_size, - CoreFoundation.kCFTypeDictionaryKeyCallBacks, - CoreFoundation.kCFTypeDictionaryValueCallBacks, - ) - - -def _cfstr(py_bstr: bytes) -> CFString: - """ - Given a Python binary data, create a CFString. - The string must be CFReleased by the caller. - """ - c_str = ctypes.c_char_p(py_bstr) - cf_str = CoreFoundation.CFStringCreateWithCString( - CoreFoundation.kCFAllocatorDefault, - c_str, - CFConst.kCFStringEncodingUTF8, - ) - return cf_str - - -def _create_cfstring_array(lst: list[bytes]) -> CFMutableArray: - """ - Given a list of Python binary data, create an associated CFMutableArray. - The array must be CFReleased by the caller. - - Raises an ssl.SSLError on failure. - """ - cf_arr = None - try: - cf_arr = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - if not cf_arr: - raise MemoryError("Unable to allocate memory!") - for item in lst: - cf_str = _cfstr(item) - if not cf_str: - raise MemoryError("Unable to allocate memory!") - try: - CoreFoundation.CFArrayAppendValue(cf_arr, cf_str) - finally: - CoreFoundation.CFRelease(cf_str) - except BaseException as e: - if cf_arr: - CoreFoundation.CFRelease(cf_arr) - raise ssl.SSLError(f"Unable to allocate array: {e}") from None - return cf_arr - - -def _cf_string_to_unicode(value: CFString) -> str | None: - """ - Creates a Unicode string from a CFString object. Used entirely for error - reporting. - - Yes, it annoys me quite a lot that this function is this complex. - """ - value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) - - string = CoreFoundation.CFStringGetCStringPtr( - value_as_void_p, CFConst.kCFStringEncodingUTF8 - ) - if string is None: - buffer = ctypes.create_string_buffer(1024) - result = CoreFoundation.CFStringGetCString( - value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8 - ) - if not result: - raise OSError("Error copying C string from CFStringRef") - string = buffer.value - if string is not None: - string = string.decode("utf-8") - return string # type: ignore[no-any-return] - - -def _assert_no_error( - error: int, exception_class: type[BaseException] | None = None -) -> None: - """ - Checks the return code and throws an exception if there is an error to - report - """ - if error == 0: - return - - cf_error_string = Security.SecCopyErrorMessageString(error, None) - output = _cf_string_to_unicode(cf_error_string) - CoreFoundation.CFRelease(cf_error_string) - - if output is None or output == "": - output = f"OSStatus {error}" - - if exception_class is None: - exception_class = ssl.SSLError - - raise exception_class(output) - - -def _cert_array_from_pem(pem_bundle: bytes) -> CFArray: - """ - Given a bundle of certs in PEM format, turns them into a CFArray of certs - that can be used to validate a cert chain. - """ - # Normalize the PEM bundle's line endings. - pem_bundle = pem_bundle.replace(b"\r\n", b"\n") - - der_certs = [ - base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle) - ] - if not der_certs: - raise ssl.SSLError("No root certificates specified") - - cert_array = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - if not cert_array: - raise ssl.SSLError("Unable to allocate memory!") - - try: - for der_bytes in der_certs: - certdata = _cf_data_from_bytes(der_bytes) - if not certdata: - raise ssl.SSLError("Unable to allocate memory!") - cert = Security.SecCertificateCreateWithData( - CoreFoundation.kCFAllocatorDefault, certdata - ) - CoreFoundation.CFRelease(certdata) - if not cert: - raise ssl.SSLError("Unable to build cert object!") - - CoreFoundation.CFArrayAppendValue(cert_array, cert) - CoreFoundation.CFRelease(cert) - except Exception: - # We need to free the array before the exception bubbles further. - # We only want to do that if an error occurs: otherwise, the caller - # should free. - CoreFoundation.CFRelease(cert_array) - raise - - return cert_array - - -def _is_cert(item: CFTypeRef) -> bool: - """ - Returns True if a given CFTypeRef is a certificate. - """ - expected = Security.SecCertificateGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected # type: ignore[no-any-return] - - -def _is_identity(item: CFTypeRef) -> bool: - """ - Returns True if a given CFTypeRef is an identity. - """ - expected = Security.SecIdentityGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected # type: ignore[no-any-return] - - -def _temporary_keychain() -> tuple[SecKeychainRef, str]: - """ - This function creates a temporary Mac keychain that we can use to work with - credentials. This keychain uses a one-time password and a temporary file to - store the data. We expect to have one keychain per socket. The returned - SecKeychainRef must be freed by the caller, including calling - SecKeychainDelete. - - Returns a tuple of the SecKeychainRef and the path to the temporary - directory that contains it. - """ - # Unfortunately, SecKeychainCreate requires a path to a keychain. This - # means we cannot use mkstemp to use a generic temporary file. Instead, - # we're going to create a temporary directory and a filename to use there. - # This filename will be 8 random bytes expanded into base64. We also need - # some random bytes to password-protect the keychain we're creating, so we - # ask for 40 random bytes. - random_bytes = os.urandom(40) - filename = base64.b16encode(random_bytes[:8]).decode("utf-8") - password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 - tempdirectory = tempfile.mkdtemp() - - keychain_path = os.path.join(tempdirectory, filename).encode("utf-8") - - # We now want to create the keychain itself. - keychain = Security.SecKeychainRef() - status = Security.SecKeychainCreate( - keychain_path, len(password), password, False, None, ctypes.byref(keychain) - ) - _assert_no_error(status) - - # Having created the keychain, we want to pass it off to the caller. - return keychain, tempdirectory - - -def _load_items_from_file( - keychain: SecKeychainRef, path: str -) -> tuple[list[CFTypeRef], list[CFTypeRef]]: - """ - Given a single file, loads all the trust objects from it into arrays and - the keychain. - Returns a tuple of lists: the first list is a list of identities, the - second a list of certs. - """ - certificates = [] - identities = [] - result_array = None - - with open(path, "rb") as f: - raw_filedata = f.read() - - try: - filedata = CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata) - ) - result_array = CoreFoundation.CFArrayRef() - result = Security.SecItemImport( - filedata, # cert data - None, # Filename, leaving it out for now - None, # What the type of the file is, we don't care - None, # what's in the file, we don't care - 0, # import flags - None, # key params, can include passphrase in the future - keychain, # The keychain to insert into - ctypes.byref(result_array), # Results - ) - _assert_no_error(result) - - # A CFArray is not very useful to us as an intermediary - # representation, so we are going to extract the objects we want - # and then free the array. We don't need to keep hold of keys: the - # keychain already has them! - result_count = CoreFoundation.CFArrayGetCount(result_array) - for index in range(result_count): - item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index) - item = ctypes.cast(item, CoreFoundation.CFTypeRef) - - if _is_cert(item): - CoreFoundation.CFRetain(item) - certificates.append(item) - elif _is_identity(item): - CoreFoundation.CFRetain(item) - identities.append(item) - finally: - if result_array: - CoreFoundation.CFRelease(result_array) - - CoreFoundation.CFRelease(filedata) - - return (identities, certificates) - - -def _load_client_cert_chain(keychain: SecKeychainRef, *paths: str | None) -> CFArray: - """ - Load certificates and maybe keys from a number of files. Has the end goal - of returning a CFArray containing one SecIdentityRef, and then zero or more - SecCertificateRef objects, suitable for use as a client certificate trust - chain. - """ - # Ok, the strategy. - # - # This relies on knowing that macOS will not give you a SecIdentityRef - # unless you have imported a key into a keychain. This is a somewhat - # artificial limitation of macOS (for example, it doesn't necessarily - # affect iOS), but there is nothing inside Security.framework that lets you - # get a SecIdentityRef without having a key in a keychain. - # - # So the policy here is we take all the files and iterate them in order. - # Each one will use SecItemImport to have one or more objects loaded from - # it. We will also point at a keychain that macOS can use to work with the - # private key. - # - # Once we have all the objects, we'll check what we actually have. If we - # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, - # we'll take the first certificate (which we assume to be our leaf) and - # ask the keychain to give us a SecIdentityRef with that cert's associated - # key. - # - # We'll then return a CFArray containing the trust chain: one - # SecIdentityRef and then zero-or-more SecCertificateRef objects. The - # responsibility for freeing this CFArray will be with the caller. This - # CFArray must remain alive for the entire connection, so in practice it - # will be stored with a single SSLSocket, along with the reference to the - # keychain. - certificates = [] - identities = [] - - # Filter out bad paths. - filtered_paths = (path for path in paths if path) - - try: - for file_path in filtered_paths: - new_identities, new_certs = _load_items_from_file(keychain, file_path) - identities.extend(new_identities) - certificates.extend(new_certs) - - # Ok, we have everything. The question is: do we have an identity? If - # not, we want to grab one from the first cert we have. - if not identities: - new_identity = Security.SecIdentityRef() - status = Security.SecIdentityCreateWithCertificate( - keychain, certificates[0], ctypes.byref(new_identity) - ) - _assert_no_error(status) - identities.append(new_identity) - - # We now want to release the original certificate, as we no longer - # need it. - CoreFoundation.CFRelease(certificates.pop(0)) - - # We now need to build a new CFArray that holds the trust chain. - trust_chain = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - for item in itertools.chain(identities, certificates): - # ArrayAppendValue does a CFRetain on the item. That's fine, - # because the finally block will release our other refs to them. - CoreFoundation.CFArrayAppendValue(trust_chain, item) - - return trust_chain - finally: - for obj in itertools.chain(identities, certificates): - CoreFoundation.CFRelease(obj) - - -TLS_PROTOCOL_VERSIONS = { - "SSLv2": (0, 2), - "SSLv3": (3, 0), - "TLSv1": (3, 1), - "TLSv1.1": (3, 2), - "TLSv1.2": (3, 3), -} - - -def _build_tls_unknown_ca_alert(version: str) -> bytes: - """ - Builds a TLS alert record for an unknown CA. - """ - ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version] - severity_fatal = 0x02 - description_unknown_ca = 0x30 - msg = struct.pack(">BB", severity_fatal, description_unknown_ca) - msg_len = len(msg) - record_type_alert = 0x15 - record = struct.pack(">BBBH", record_type_alert, ver_maj, ver_min, msg_len) + msg - return record - - -class SecurityConst: - """ - A class object that acts as essentially a namespace for Security constants. - """ - - kSSLSessionOptionBreakOnServerAuth = 0 - - kSSLProtocol2 = 1 - kSSLProtocol3 = 2 - kTLSProtocol1 = 4 - kTLSProtocol11 = 7 - kTLSProtocol12 = 8 - # SecureTransport does not support TLS 1.3 even if there's a constant for it - kTLSProtocol13 = 10 - kTLSProtocolMaxSupported = 999 - - kSSLClientSide = 1 - kSSLStreamType = 0 - - kSecFormatPEMSequence = 10 - - kSecTrustResultInvalid = 0 - kSecTrustResultProceed = 1 - # This gap is present on purpose: this was kSecTrustResultConfirm, which - # is deprecated. - kSecTrustResultDeny = 3 - kSecTrustResultUnspecified = 4 - kSecTrustResultRecoverableTrustFailure = 5 - kSecTrustResultFatalTrustFailure = 6 - kSecTrustResultOtherError = 7 - - errSSLProtocol = -9800 - errSSLWouldBlock = -9803 - errSSLClosedGraceful = -9805 - errSSLClosedNoNotify = -9816 - errSSLClosedAbort = -9806 - - errSSLXCertChainInvalid = -9807 - errSSLCrypto = -9809 - errSSLInternal = -9810 - errSSLCertExpired = -9814 - errSSLCertNotYetValid = -9815 - errSSLUnknownRootCert = -9812 - errSSLNoRootCert = -9813 - errSSLHostNameMismatch = -9843 - errSSLPeerHandshakeFail = -9824 - errSSLPeerUserCancelled = -9839 - errSSLWeakPeerEphemeralDHKey = -9850 - errSSLServerAuthCompleted = -9841 - errSSLRecordOverflow = -9847 - - errSecVerifyFailed = -67808 - errSecNoTrustSettings = -25263 - errSecItemNotFound = -25300 - errSecInvalidTrustSettings = -25262 diff --git a/uno/lib/python/urllib3/contrib/pyopenssl.py b/uno/lib/python/urllib3/contrib/pyopenssl.py index 0089cd27..3987d632 100644 --- a/uno/lib/python/urllib3/contrib/pyopenssl.py +++ b/uno/lib/python/urllib3/contrib/pyopenssl.py @@ -8,10 +8,10 @@ * `pyOpenSSL`_ (tested with 16.0.0) * `cryptography`_ (minimum 1.3.4, from pyopenssl) -* `idna`_ (minimum 2.0, from cryptography) +* `idna`_ (minimum 2.0) -However, pyOpenSSL depends on cryptography, which depends on idna, so while we -use all three directly here we end up having relatively few packages required. +However, pyOpenSSL depends on cryptography, so while we use all three directly here we +end up having relatively few packages required. You can install them with the following command: @@ -54,21 +54,12 @@ class UnsupportedExtension(Exception): # type: ignore[no-redef] import logging import ssl import typing -import warnings from io import BytesIO from socket import socket as socket_cls from socket import timeout from .. import util -warnings.warn( - "'urllib3.contrib.pyopenssl' module is deprecated and will be removed " - "in urllib3 v2.1.0. Read more in this issue: " - "https://github.com/urllib3/urllib3/issues/2680", - category=DeprecationWarning, - stacklevel=2, -) - if typing.TYPE_CHECKING: from OpenSSL.crypto import X509 # type: ignore[import] diff --git a/uno/lib/python/urllib3/contrib/securetransport.py b/uno/lib/python/urllib3/contrib/securetransport.py deleted file mode 100644 index 11beb3df..00000000 --- a/uno/lib/python/urllib3/contrib/securetransport.py +++ /dev/null @@ -1,913 +0,0 @@ -""" -SecureTranport support for urllib3 via ctypes. - -This makes platform-native TLS available to urllib3 users on macOS without the -use of a compiler. This is an important feature because the Python Package -Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL -that ships with macOS is not capable of doing TLSv1.2. The only way to resolve -this is to give macOS users an alternative solution to the problem, and that -solution is to use SecureTransport. - -We use ctypes here because this solution must not require a compiler. That's -because pip is not allowed to require a compiler either. - -This is not intended to be a seriously long-term solution to this problem. -The hope is that PEP 543 will eventually solve this issue for us, at which -point we can retire this contrib module. But in the short term, we need to -solve the impending tire fire that is Python on Mac without this kind of -contrib module. So...here we are. - -To use this module, simply import and inject it:: - - import urllib3.contrib.securetransport - urllib3.contrib.securetransport.inject_into_urllib3() - -Happy TLSing! - -This code is a bastardised version of the code found in Will Bond's oscrypto -library. An enormous debt is owed to him for blazing this trail for us. For -that reason, this code should be considered to be covered both by urllib3's -license and by oscrypto's: - -.. code-block:: - - Copyright (c) 2015-2016 Will Bond - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -""" - -from __future__ import annotations - -import contextlib -import ctypes -import errno -import os.path -import shutil -import socket -import ssl -import struct -import threading -import typing -import warnings -import weakref -from socket import socket as socket_cls - -from .. import util -from ._securetransport.bindings import ( # type: ignore[attr-defined] - CoreFoundation, - Security, -) -from ._securetransport.low_level import ( - SecurityConst, - _assert_no_error, - _build_tls_unknown_ca_alert, - _cert_array_from_pem, - _create_cfstring_array, - _load_client_cert_chain, - _temporary_keychain, -) - -warnings.warn( - "'urllib3.contrib.securetransport' module is deprecated and will be removed " - "in urllib3 v2.1.0. Read more in this issue: " - "https://github.com/urllib3/urllib3/issues/2681", - category=DeprecationWarning, - stacklevel=2, -) - -if typing.TYPE_CHECKING: - from typing_extensions import Literal - -__all__ = ["inject_into_urllib3", "extract_from_urllib3"] - -orig_util_SSLContext = util.ssl_.SSLContext - -# This dictionary is used by the read callback to obtain a handle to the -# calling wrapped socket. This is a pretty silly approach, but for now it'll -# do. I feel like I should be able to smuggle a handle to the wrapped socket -# directly in the SSLConnectionRef, but for now this approach will work I -# guess. -# -# We need to lock around this structure for inserts, but we don't do it for -# reads/writes in the callbacks. The reasoning here goes as follows: -# -# 1. It is not possible to call into the callbacks before the dictionary is -# populated, so once in the callback the id must be in the dictionary. -# 2. The callbacks don't mutate the dictionary, they only read from it, and -# so cannot conflict with any of the insertions. -# -# This is good: if we had to lock in the callbacks we'd drastically slow down -# the performance of this code. -_connection_refs: weakref.WeakValueDictionary[ - int, WrappedSocket -] = weakref.WeakValueDictionary() -_connection_ref_lock = threading.Lock() - -# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over -# for no better reason than we need *a* limit, and this one is right there. -SSL_WRITE_BLOCKSIZE = 16384 - -# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of -# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. -# TLSv1 to 1.2 are supported on macOS 10.8+ -_protocol_to_min_max = { - util.ssl_.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), # type: ignore[attr-defined] - util.ssl_.PROTOCOL_TLS_CLIENT: ( # type: ignore[attr-defined] - SecurityConst.kTLSProtocol1, - SecurityConst.kTLSProtocol12, - ), -} - -if hasattr(ssl, "PROTOCOL_SSLv2"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( - SecurityConst.kSSLProtocol2, - SecurityConst.kSSLProtocol2, - ) -if hasattr(ssl, "PROTOCOL_SSLv3"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( - SecurityConst.kSSLProtocol3, - SecurityConst.kSSLProtocol3, - ) -if hasattr(ssl, "PROTOCOL_TLSv1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( - SecurityConst.kTLSProtocol1, - SecurityConst.kTLSProtocol1, - ) -if hasattr(ssl, "PROTOCOL_TLSv1_1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( - SecurityConst.kTLSProtocol11, - SecurityConst.kTLSProtocol11, - ) -if hasattr(ssl, "PROTOCOL_TLSv1_2"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( - SecurityConst.kTLSProtocol12, - SecurityConst.kTLSProtocol12, - ) - - -_tls_version_to_st: dict[int, int] = { - ssl.TLSVersion.MINIMUM_SUPPORTED: SecurityConst.kTLSProtocol1, - ssl.TLSVersion.TLSv1: SecurityConst.kTLSProtocol1, - ssl.TLSVersion.TLSv1_1: SecurityConst.kTLSProtocol11, - ssl.TLSVersion.TLSv1_2: SecurityConst.kTLSProtocol12, - ssl.TLSVersion.MAXIMUM_SUPPORTED: SecurityConst.kTLSProtocol12, -} - - -def inject_into_urllib3() -> None: - """ - Monkey-patch urllib3 with SecureTransport-backed SSL-support. - """ - util.SSLContext = SecureTransportContext # type: ignore[assignment] - util.ssl_.SSLContext = SecureTransportContext # type: ignore[assignment] - util.IS_SECURETRANSPORT = True - util.ssl_.IS_SECURETRANSPORT = True - - -def extract_from_urllib3() -> None: - """ - Undo monkey-patching by :func:`inject_into_urllib3`. - """ - util.SSLContext = orig_util_SSLContext - util.ssl_.SSLContext = orig_util_SSLContext - util.IS_SECURETRANSPORT = False - util.ssl_.IS_SECURETRANSPORT = False - - -def _read_callback( - connection_id: int, data_buffer: int, data_length_pointer: bytearray -) -> int: - """ - SecureTransport read callback. This is called by ST to request that data - be returned from the socket. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - requested_length = data_length_pointer[0] - - timeout = wrapped_socket.gettimeout() - error = None - read_count = 0 - - try: - while read_count < requested_length: - if timeout is None or timeout >= 0: - if not util.wait_for_read(base_socket, timeout): - raise OSError(errno.EAGAIN, "timed out") - - remaining = requested_length - read_count - buffer = (ctypes.c_char * remaining).from_address( - data_buffer + read_count - ) - chunk_size = base_socket.recv_into(buffer, remaining) - read_count += chunk_size - if not chunk_size: - if not read_count: - return SecurityConst.errSSLClosedGraceful - break - except OSError as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = read_count - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = read_count - - if read_count != requested_length: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -def _write_callback( - connection_id: int, data_buffer: int, data_length_pointer: bytearray -) -> int: - """ - SecureTransport write callback. This is called by ST to request that data - actually be sent on the network. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - bytes_to_write = data_length_pointer[0] - data = ctypes.string_at(data_buffer, bytes_to_write) - - timeout = wrapped_socket.gettimeout() - error = None - sent = 0 - - try: - while sent < bytes_to_write: - if timeout is None or timeout >= 0: - if not util.wait_for_write(base_socket, timeout): - raise OSError(errno.EAGAIN, "timed out") - chunk_sent = base_socket.send(data) - sent += chunk_sent - - # This has some needless copying here, but I'm not sure there's - # much value in optimising this data path. - data = data[chunk_sent:] - except OSError as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = sent - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = sent - - if sent != bytes_to_write: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -# We need to keep these two objects references alive: if they get GC'd while -# in use then SecureTransport could attempt to call a function that is in freed -# memory. That would be...uh...bad. Yeah, that's the word. Bad. -_read_callback_pointer = Security.SSLReadFunc(_read_callback) -_write_callback_pointer = Security.SSLWriteFunc(_write_callback) - - -class WrappedSocket: - """ - API-compatibility wrapper for Python's OpenSSL wrapped socket object. - """ - - def __init__(self, socket: socket_cls) -> None: - self.socket = socket - self.context = None - self._io_refs = 0 - self._closed = False - self._real_closed = False - self._exception: Exception | None = None - self._keychain = None - self._keychain_dir: str | None = None - self._client_cert_chain = None - - # We save off the previously-configured timeout and then set it to - # zero. This is done because we use select and friends to handle the - # timeouts, but if we leave the timeout set on the lower socket then - # Python will "kindly" call select on that socket again for us. Avoid - # that by forcing the timeout to zero. - self._timeout = self.socket.gettimeout() - self.socket.settimeout(0) - - @contextlib.contextmanager - def _raise_on_error(self) -> typing.Generator[None, None, None]: - """ - A context manager that can be used to wrap calls that do I/O from - SecureTransport. If any of the I/O callbacks hit an exception, this - context manager will correctly propagate the exception after the fact. - This avoids silently swallowing those exceptions. - - It also correctly forces the socket closed. - """ - self._exception = None - - # We explicitly don't catch around this yield because in the unlikely - # event that an exception was hit in the block we don't want to swallow - # it. - yield - if self._exception is not None: - exception, self._exception = self._exception, None - self._real_close() - raise exception - - def _set_alpn_protocols(self, protocols: list[bytes] | None) -> None: - """ - Sets up the ALPN protocols on the context. - """ - if not protocols: - return - protocols_arr = _create_cfstring_array(protocols) - try: - result = Security.SSLSetALPNProtocols(self.context, protocols_arr) - _assert_no_error(result) - finally: - CoreFoundation.CFRelease(protocols_arr) - - def _custom_validate(self, verify: bool, trust_bundle: bytes | None) -> None: - """ - Called when we have set custom validation. We do this in two cases: - first, when cert validation is entirely disabled; and second, when - using a custom trust DB. - Raises an SSLError if the connection is not trusted. - """ - # If we disabled cert validation, just say: cool. - if not verify or trust_bundle is None: - return - - successes = ( - SecurityConst.kSecTrustResultUnspecified, - SecurityConst.kSecTrustResultProceed, - ) - try: - trust_result = self._evaluate_trust(trust_bundle) - if trust_result in successes: - return - reason = f"error code: {int(trust_result)}" - exc = None - except Exception as e: - # Do not trust on error - reason = f"exception: {e!r}" - exc = e - - # SecureTransport does not send an alert nor shuts down the connection. - rec = _build_tls_unknown_ca_alert(self.version()) - self.socket.sendall(rec) - # close the connection immediately - # l_onoff = 1, activate linger - # l_linger = 0, linger for 0 seoncds - opts = struct.pack("ii", 1, 0) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts) - self._real_close() - raise ssl.SSLError(f"certificate verify failed, {reason}") from exc - - def _evaluate_trust(self, trust_bundle: bytes) -> int: - # We want data in memory, so load it up. - if os.path.isfile(trust_bundle): - with open(trust_bundle, "rb") as f: - trust_bundle = f.read() - - cert_array = None - trust = Security.SecTrustRef() - - try: - # Get a CFArray that contains the certs we want. - cert_array = _cert_array_from_pem(trust_bundle) - - # Ok, now the hard part. We want to get the SecTrustRef that ST has - # created for this connection, shove our CAs into it, tell ST to - # ignore everything else it knows, and then ask if it can build a - # chain. This is a buuuunch of code. - result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) - _assert_no_error(result) - if not trust: - raise ssl.SSLError("Failed to copy trust reference") - - result = Security.SecTrustSetAnchorCertificates(trust, cert_array) - _assert_no_error(result) - - result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) - _assert_no_error(result) - - trust_result = Security.SecTrustResultType() - result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result)) - _assert_no_error(result) - finally: - if trust: - CoreFoundation.CFRelease(trust) - - if cert_array is not None: - CoreFoundation.CFRelease(cert_array) - - return trust_result.value # type: ignore[no-any-return] - - def handshake( - self, - server_hostname: bytes | str | None, - verify: bool, - trust_bundle: bytes | None, - min_version: int, - max_version: int, - client_cert: str | None, - client_key: str | None, - client_key_passphrase: typing.Any, - alpn_protocols: list[bytes] | None, - ) -> None: - """ - Actually performs the TLS handshake. This is run automatically by - wrapped socket, and shouldn't be needed in user code. - """ - # First, we do the initial bits of connection setup. We need to create - # a context, set its I/O funcs, and set the connection reference. - self.context = Security.SSLCreateContext( - None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType - ) - result = Security.SSLSetIOFuncs( - self.context, _read_callback_pointer, _write_callback_pointer - ) - _assert_no_error(result) - - # Here we need to compute the handle to use. We do this by taking the - # id of self modulo 2**31 - 1. If this is already in the dictionary, we - # just keep incrementing by one until we find a free space. - with _connection_ref_lock: - handle = id(self) % 2147483647 - while handle in _connection_refs: - handle = (handle + 1) % 2147483647 - _connection_refs[handle] = self - - result = Security.SSLSetConnection(self.context, handle) - _assert_no_error(result) - - # If we have a server hostname, we should set that too. - # RFC6066 Section 3 tells us not to use SNI when the host is an IP, but we have - # to do it anyway to match server_hostname against the server certificate - if server_hostname: - if not isinstance(server_hostname, bytes): - server_hostname = server_hostname.encode("utf-8") - - result = Security.SSLSetPeerDomainName( - self.context, server_hostname, len(server_hostname) - ) - _assert_no_error(result) - - # Setup the ALPN protocols. - self._set_alpn_protocols(alpn_protocols) - - # Set the minimum and maximum TLS versions. - result = Security.SSLSetProtocolVersionMin(self.context, min_version) - _assert_no_error(result) - - result = Security.SSLSetProtocolVersionMax(self.context, max_version) - _assert_no_error(result) - - # If there's a trust DB, we need to use it. We do that by telling - # SecureTransport to break on server auth. We also do that if we don't - # want to validate the certs at all: we just won't actually do any - # authing in that case. - if not verify or trust_bundle is not None: - result = Security.SSLSetSessionOption( - self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True - ) - _assert_no_error(result) - - # If there's a client cert, we need to use it. - if client_cert: - self._keychain, self._keychain_dir = _temporary_keychain() - self._client_cert_chain = _load_client_cert_chain( - self._keychain, client_cert, client_key - ) - result = Security.SSLSetCertificate(self.context, self._client_cert_chain) - _assert_no_error(result) - - while True: - with self._raise_on_error(): - result = Security.SSLHandshake(self.context) - - if result == SecurityConst.errSSLWouldBlock: - raise socket.timeout("handshake timed out") - elif result == SecurityConst.errSSLServerAuthCompleted: - self._custom_validate(verify, trust_bundle) - continue - else: - _assert_no_error(result) - break - - def fileno(self) -> int: - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self) -> None: - if self._io_refs > 0: - self._io_refs -= 1 - if self._closed: - self.close() - - def recv(self, bufsiz: int) -> bytes: - buffer = ctypes.create_string_buffer(bufsiz) - bytes_read = self.recv_into(buffer, bufsiz) - data = buffer[:bytes_read] - return typing.cast(bytes, data) - - def recv_into( - self, buffer: ctypes.Array[ctypes.c_char], nbytes: int | None = None - ) -> int: - # Read short on EOF. - if self._real_closed: - return 0 - - if nbytes is None: - nbytes = len(buffer) - - buffer = (ctypes.c_char * nbytes).from_buffer(buffer) - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLRead( - self.context, buffer, nbytes, ctypes.byref(processed_bytes) - ) - - # There are some result codes that we want to treat as "not always - # errors". Specifically, those are errSSLWouldBlock, - # errSSLClosedGraceful, and errSSLClosedNoNotify. - if result == SecurityConst.errSSLWouldBlock: - # If we didn't process any bytes, then this was just a time out. - # However, we can get errSSLWouldBlock in situations when we *did* - # read some data, and in those cases we should just read "short" - # and return. - if processed_bytes.value == 0: - # Timed out, no data read. - raise socket.timeout("recv timed out") - elif result in ( - SecurityConst.errSSLClosedGraceful, - SecurityConst.errSSLClosedNoNotify, - ): - # The remote peer has closed this connection. We should do so as - # well. Note that we don't actually return here because in - # principle this could actually be fired along with return data. - # It's unlikely though. - self._real_close() - else: - _assert_no_error(result) - - # Ok, we read and probably succeeded. We should return whatever data - # was actually read. - return processed_bytes.value - - def settimeout(self, timeout: float) -> None: - self._timeout = timeout - - def gettimeout(self) -> float | None: - return self._timeout - - def send(self, data: bytes) -> int: - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLWrite( - self.context, data, len(data), ctypes.byref(processed_bytes) - ) - - if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: - # Timed out - raise socket.timeout("send timed out") - else: - _assert_no_error(result) - - # We sent, and probably succeeded. Tell them how much we sent. - return processed_bytes.value - - def sendall(self, data: bytes) -> None: - total_sent = 0 - while total_sent < len(data): - sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]) - total_sent += sent - - def shutdown(self) -> None: - with self._raise_on_error(): - Security.SSLClose(self.context) - - def close(self) -> None: - self._closed = True - # TODO: should I do clean shutdown here? Do I have to? - if self._io_refs <= 0: - self._real_close() - - def _real_close(self) -> None: - self._real_closed = True - if self.context: - CoreFoundation.CFRelease(self.context) - self.context = None - if self._client_cert_chain: - CoreFoundation.CFRelease(self._client_cert_chain) - self._client_cert_chain = None - if self._keychain: - Security.SecKeychainDelete(self._keychain) - CoreFoundation.CFRelease(self._keychain) - shutil.rmtree(self._keychain_dir) - self._keychain = self._keychain_dir = None - return self.socket.close() - - def getpeercert(self, binary_form: bool = False) -> bytes | None: - # Urgh, annoying. - # - # Here's how we do this: - # - # 1. Call SSLCopyPeerTrust to get hold of the trust object for this - # connection. - # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. - # 3. To get the CN, call SecCertificateCopyCommonName and process that - # string so that it's of the appropriate type. - # 4. To get the SAN, we need to do something a bit more complex: - # a. Call SecCertificateCopyValues to get the data, requesting - # kSecOIDSubjectAltName. - # b. Mess about with this dictionary to try to get the SANs out. - # - # This is gross. Really gross. It's going to be a few hundred LoC extra - # just to repeat something that SecureTransport can *already do*. So my - # operating assumption at this time is that what we want to do is - # instead to just flag to urllib3 that it shouldn't do its own hostname - # validation when using SecureTransport. - if not binary_form: - raise ValueError("SecureTransport only supports dumping binary certs") - trust = Security.SecTrustRef() - certdata = None - der_bytes = None - - try: - # Grab the trust store. - result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) - _assert_no_error(result) - if not trust: - # Probably we haven't done the handshake yet. No biggie. - return None - - cert_count = Security.SecTrustGetCertificateCount(trust) - if not cert_count: - # Also a case that might happen if we haven't handshaked. - # Handshook? Handshaken? - return None - - leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) - assert leaf - - # Ok, now we want the DER bytes. - certdata = Security.SecCertificateCopyData(leaf) - assert certdata - - data_length = CoreFoundation.CFDataGetLength(certdata) - data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) - der_bytes = ctypes.string_at(data_buffer, data_length) - finally: - if certdata: - CoreFoundation.CFRelease(certdata) - if trust: - CoreFoundation.CFRelease(trust) - - return der_bytes - - def version(self) -> str: - protocol = Security.SSLProtocol() - result = Security.SSLGetNegotiatedProtocolVersion( - self.context, ctypes.byref(protocol) - ) - _assert_no_error(result) - if protocol.value == SecurityConst.kTLSProtocol13: - raise ssl.SSLError("SecureTransport does not support TLS 1.3") - elif protocol.value == SecurityConst.kTLSProtocol12: - return "TLSv1.2" - elif protocol.value == SecurityConst.kTLSProtocol11: - return "TLSv1.1" - elif protocol.value == SecurityConst.kTLSProtocol1: - return "TLSv1" - elif protocol.value == SecurityConst.kSSLProtocol3: - return "SSLv3" - elif protocol.value == SecurityConst.kSSLProtocol2: - return "SSLv2" - else: - raise ssl.SSLError(f"Unknown TLS version: {protocol!r}") - - -def makefile( - self: socket_cls, - mode: ( - Literal["r"] | Literal["w"] | Literal["rw"] | Literal["wr"] | Literal[""] - ) = "r", - buffering: int | None = None, - *args: typing.Any, - **kwargs: typing.Any, -) -> typing.BinaryIO | typing.TextIO: - # We disable buffering with SecureTransport because it conflicts with - # the buffering that ST does internally (see issue #1153 for more). - buffering = 0 - return socket_cls.makefile(self, mode, buffering, *args, **kwargs) - - -WrappedSocket.makefile = makefile # type: ignore[attr-defined] - - -class SecureTransportContext: - """ - I am a wrapper class for the SecureTransport library, to translate the - interface of the standard library ``SSLContext`` object to calls into - SecureTransport. - """ - - def __init__(self, protocol: int) -> None: - self._minimum_version: int = ssl.TLSVersion.MINIMUM_SUPPORTED - self._maximum_version: int = ssl.TLSVersion.MAXIMUM_SUPPORTED - if protocol not in (None, ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS_CLIENT): - self._min_version, self._max_version = _protocol_to_min_max[protocol] - - self._options = 0 - self._verify = False - self._trust_bundle: bytes | None = None - self._client_cert: str | None = None - self._client_key: str | None = None - self._client_key_passphrase = None - self._alpn_protocols: list[bytes] | None = None - - @property - def check_hostname(self) -> Literal[True]: - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - return True - - @check_hostname.setter - def check_hostname(self, value: typing.Any) -> None: - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - - @property - def options(self) -> int: - # TODO: Well, crap. - # - # So this is the bit of the code that is the most likely to cause us - # trouble. Essentially we need to enumerate all of the SSL options that - # users might want to use and try to see if we can sensibly translate - # them, or whether we should just ignore them. - return self._options - - @options.setter - def options(self, value: int) -> None: - # TODO: Update in line with above. - self._options = value - - @property - def verify_mode(self) -> int: - return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE - - @verify_mode.setter - def verify_mode(self, value: int) -> None: - self._verify = value == ssl.CERT_REQUIRED - - def set_default_verify_paths(self) -> None: - # So, this has to do something a bit weird. Specifically, what it does - # is nothing. - # - # This means that, if we had previously had load_verify_locations - # called, this does not undo that. We need to do that because it turns - # out that the rest of the urllib3 code will attempt to load the - # default verify paths if it hasn't been told about any paths, even if - # the context itself was sometime earlier. We resolve that by just - # ignoring it. - pass - - def load_default_certs(self) -> None: - return self.set_default_verify_paths() - - def set_ciphers(self, ciphers: typing.Any) -> None: - raise ValueError("SecureTransport doesn't support custom cipher strings") - - def load_verify_locations( - self, - cafile: str | None = None, - capath: str | None = None, - cadata: bytes | None = None, - ) -> None: - # OK, we only really support cadata and cafile. - if capath is not None: - raise ValueError("SecureTransport does not support cert directories") - - # Raise if cafile does not exist. - if cafile is not None: - with open(cafile): - pass - - self._trust_bundle = cafile or cadata # type: ignore[assignment] - - def load_cert_chain( - self, - certfile: str, - keyfile: str | None = None, - password: str | None = None, - ) -> None: - self._client_cert = certfile - self._client_key = keyfile - self._client_cert_passphrase = password - - def set_alpn_protocols(self, protocols: list[str | bytes]) -> None: - """ - Sets the ALPN protocols that will later be set on the context. - - Raises a NotImplementedError if ALPN is not supported. - """ - if not hasattr(Security, "SSLSetALPNProtocols"): - raise NotImplementedError( - "SecureTransport supports ALPN only in macOS 10.12+" - ) - self._alpn_protocols = [util.util.to_bytes(p, "ascii") for p in protocols] - - def wrap_socket( - self, - sock: socket_cls, - server_side: bool = False, - do_handshake_on_connect: bool = True, - suppress_ragged_eofs: bool = True, - server_hostname: bytes | str | None = None, - ) -> WrappedSocket: - # So, what do we do here? Firstly, we assert some properties. This is a - # stripped down shim, so there is some functionality we don't support. - # See PEP 543 for the real deal. - assert not server_side - assert do_handshake_on_connect - assert suppress_ragged_eofs - - # Ok, we're good to go. Now we want to create the wrapped socket object - # and store it in the appropriate place. - wrapped_socket = WrappedSocket(sock) - - # Now we can handshake - wrapped_socket.handshake( - server_hostname, - self._verify, - self._trust_bundle, - _tls_version_to_st[self._minimum_version], - _tls_version_to_st[self._maximum_version], - self._client_cert, - self._client_key, - self._client_key_passphrase, - self._alpn_protocols, - ) - return wrapped_socket - - @property - def minimum_version(self) -> int: - return self._minimum_version - - @minimum_version.setter - def minimum_version(self, minimum_version: int) -> None: - self._minimum_version = minimum_version - - @property - def maximum_version(self) -> int: - return self._maximum_version - - @maximum_version.setter - def maximum_version(self, maximum_version: int) -> None: - self._maximum_version = maximum_version diff --git a/uno/lib/python/urllib3/contrib/socks.py b/uno/lib/python/urllib3/contrib/socks.py index 5e552dda..6c3bb764 100644 --- a/uno/lib/python/urllib3/contrib/socks.py +++ b/uno/lib/python/urllib3/contrib/socks.py @@ -71,19 +71,16 @@ except ImportError: ssl = None # type: ignore[assignment] -try: - from typing import TypedDict - - class _TYPE_SOCKS_OPTIONS(TypedDict): - socks_version: int - proxy_host: str | None - proxy_port: str | None - username: str | None - password: str | None - rdns: bool - -except ImportError: # Python 3.7 - _TYPE_SOCKS_OPTIONS = typing.Dict[str, typing.Any] # type: ignore[misc, assignment] +from typing import TypedDict + + +class _TYPE_SOCKS_OPTIONS(TypedDict): + socks_version: int + proxy_host: str | None + proxy_port: str | None + username: str | None + password: str | None + rdns: bool class SOCKSConnection(HTTPConnection): diff --git a/uno/lib/python/urllib3/poolmanager.py b/uno/lib/python/urllib3/poolmanager.py index 02b2f622..32da0a00 100644 --- a/uno/lib/python/urllib3/poolmanager.py +++ b/uno/lib/python/urllib3/poolmanager.py @@ -7,7 +7,7 @@ from types import TracebackType from urllib.parse import urljoin -from ._collections import RecentlyUsedContainer +from ._collections import HTTPHeaderDict, RecentlyUsedContainer from ._request_methods import RequestMethods from .connection import ProxyConfig from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme @@ -26,8 +26,7 @@ if typing.TYPE_CHECKING: import ssl - - from typing_extensions import Literal + from typing import Literal __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"] @@ -39,6 +38,7 @@ "cert_file", "cert_reqs", "ca_certs", + "ca_cert_data", "ssl_version", "ssl_minimum_version", "ssl_maximum_version", @@ -74,6 +74,7 @@ class PoolKey(typing.NamedTuple): key_cert_file: str | None key_cert_reqs: str | None key_ca_certs: str | None + key_ca_cert_data: str | bytes | None key_ssl_version: int | str | None key_ssl_minimum_version: ssl.TLSVersion | None key_ssl_maximum_version: ssl.TLSVersion | None @@ -449,9 +450,12 @@ def urlopen( # type: ignore[override] # Support relative URLs for redirecting. redirect_location = urljoin(url, redirect_location) - # RFC 7231, Section 6.4.4 if response.status == 303: + # Change the method according to RFC 9110, Section 15.4.4. method = "GET" + # And lose the body not to transfer anything sensitive. + kw["body"] = None + kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change() retries = kw.get("retries") if not isinstance(retries, Retry): diff --git a/uno/lib/python/urllib3/response.py b/uno/lib/python/urllib3/response.py index 50e4d88f..37936f93 100644 --- a/uno/lib/python/urllib3/response.py +++ b/uno/lib/python/urllib3/response.py @@ -58,7 +58,7 @@ from .util.retry import Retry if typing.TYPE_CHECKING: - from typing_extensions import Literal + from typing import Literal from .connectionpool import HTTPConnectionPool @@ -208,7 +208,9 @@ def _get_decoder(mode: str) -> ContentDecoder: if "," in mode: return MultiDecoder(mode) - if mode == "gzip": + # According to RFC 9110 section 8.4.1.3, recipients should + # consider x-gzip equivalent to gzip + if mode in ("gzip", "x-gzip"): return GzipDecoder() if brotli is not None and mode == "br": @@ -280,7 +282,7 @@ def get(self, n: int) -> bytes: class BaseHTTPResponse(io.IOBase): - CONTENT_DECODERS = ["gzip", "deflate"] + CONTENT_DECODERS = ["gzip", "x-gzip", "deflate"] if brotli is not None: CONTENT_DECODERS += ["br"] if zstd is not None: @@ -767,13 +769,9 @@ def _fp_read(self, amt: int | None = None) -> bytes: assert self._fp c_int_max = 2**31 - 1 if ( - ( - (amt and amt > c_int_max) - or (self.length_remaining and self.length_remaining > c_int_max) - ) - and not util.IS_SECURETRANSPORT - and (util.IS_PYOPENSSL or sys.version_info < (3, 10)) - ): + (amt and amt > c_int_max) + or (self.length_remaining and self.length_remaining > c_int_max) + ) and (util.IS_PYOPENSSL or sys.version_info < (3, 10)): buffer = io.BytesIO() # Besides `max_chunk_amt` being a maximum chunk size, it # affects memory overhead of reading a response by this @@ -878,11 +876,7 @@ def read( data = self._raw_read(amt) - flush_decoder = False - if amt is None: - flush_decoder = True - elif amt != 0 and not data: - flush_decoder = True + flush_decoder = amt is None or (amt != 0 and not data) if not data and len(self._decoded_buffer) == 0: return data diff --git a/uno/lib/python/urllib3/util/__init__.py b/uno/lib/python/urllib3/util/__init__.py index ff56c55b..53412603 100644 --- a/uno/lib/python/urllib3/util/__init__.py +++ b/uno/lib/python/urllib3/util/__init__.py @@ -8,7 +8,6 @@ from .ssl_ import ( ALPN_PROTOCOLS, IS_PYOPENSSL, - IS_SECURETRANSPORT, SSLContext, assert_fingerprint, create_urllib3_context, @@ -22,7 +21,6 @@ __all__ = ( "IS_PYOPENSSL", - "IS_SECURETRANSPORT", "SSLContext", "ALPN_PROTOCOLS", "Retry", diff --git a/uno/lib/python/urllib3/util/request.py b/uno/lib/python/urllib3/util/request.py index def099d7..e6905ffc 100644 --- a/uno/lib/python/urllib3/util/request.py +++ b/uno/lib/python/urllib3/util/request.py @@ -9,7 +9,7 @@ from .util import to_bytes if typing.TYPE_CHECKING: - from typing_extensions import Final + from typing import Final # Pass as a value within ``headers`` to skip # emitting some HTTP headers that are added automatically. @@ -223,7 +223,7 @@ def chunk_readable() -> typing.Iterable[bytes]: nonlocal body, blocksize encode = isinstance(body, io.TextIOBase) while True: - datablock = body.read(blocksize) # type: ignore[union-attr] + datablock = body.read(blocksize) if not datablock: break if encode: diff --git a/uno/lib/python/urllib3/util/retry.py b/uno/lib/python/urllib3/util/retry.py index ea48afe3..7572bfd2 100644 --- a/uno/lib/python/urllib3/util/retry.py +++ b/uno/lib/python/urllib3/util/retry.py @@ -187,7 +187,7 @@ class Retry: RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) #: Default headers to be used for ``remove_headers_on_redirect`` - DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"]) + DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) #: Default maximum backoff time. DEFAULT_BACKOFF_MAX = 120 diff --git a/uno/lib/python/urllib3/util/ssl_.py b/uno/lib/python/urllib3/util/ssl_.py index 3314b903..e0a7c04a 100644 --- a/uno/lib/python/urllib3/util/ssl_.py +++ b/uno/lib/python/urllib3/util/ssl_.py @@ -16,7 +16,6 @@ SSLTransport = None HAS_NEVER_CHECK_COMMON_NAME = False IS_PYOPENSSL = False -IS_SECURETRANSPORT = False ALPN_PROTOCOLS = ["http/1.1"] _TYPE_VERSION_INFO = typing.Tuple[int, int, int, str, int] @@ -26,39 +25,41 @@ def _is_bpo_43522_fixed( - implementation_name: str, version_info: _TYPE_VERSION_INFO + implementation_name: str, + version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: - """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ where setting - SSLContext.hostname_checks_common_name to False works. - - PyPy 7.3.7 doesn't work as it doesn't ship with OpenSSL 1.1.1l+ - so we're waiting for a version of PyPy that works before - allowing this function to return 'True'. + """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ and PyPy 7.3.8+ where + setting SSLContext.hostname_checks_common_name to False works. Outside of CPython and PyPy we don't know which implementations work or not so we conservatively use our hostname matching as we know that works on all implementations. https://github.com/urllib3/urllib3/issues/2192#issuecomment-821832963 - https://foss.heptapod.net/pypy/pypy/-/issues/3539# + https://foss.heptapod.net/pypy/pypy/-/issues/3539 """ - if implementation_name != "cpython": + if implementation_name == "pypy": + # https://foss.heptapod.net/pypy/pypy/-/issues/3129 + return pypy_version_info >= (7, 3, 8) # type: ignore[operator] + elif implementation_name == "cpython": + major_minor = version_info[:2] + micro = version_info[2] + return ( + (major_minor == (3, 8) and micro >= 9) + or (major_minor == (3, 9) and micro >= 3) + or major_minor >= (3, 10) + ) + else: # Defensive: return False - major_minor = version_info[:2] - micro = version_info[2] - return ( - (major_minor == (3, 8) and micro >= 9) - or (major_minor == (3, 9) and micro >= 3) - or major_minor >= (3, 10) - ) - def _is_has_never_check_common_name_reliable( openssl_version: str, openssl_version_number: int, implementation_name: str, version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: # As of May 2023, all released versions of LibreSSL fail to reject certificates with # only common names, see https://github.com/urllib3/urllib3/pull/3024 @@ -71,14 +72,13 @@ def _is_has_never_check_common_name_reliable( return is_openssl and ( is_openssl_issue_14579_fixed - or _is_bpo_43522_fixed(implementation_name, version_info) + or _is_bpo_43522_fixed(implementation_name, version_info, pypy_version_info) ) if typing.TYPE_CHECKING: from ssl import VerifyMode - - from typing_extensions import Literal, TypedDict + from typing import Literal, TypedDict from .ssltransport import SSLTransport as SSLTransportType @@ -117,6 +117,7 @@ class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False): OPENSSL_VERSION_NUMBER, sys.implementation.name, sys.version_info, + sys.pypy_version_info if sys.implementation.name == "pypy" else None, # type: ignore[attr-defined] ): HAS_NEVER_CHECK_COMMON_NAME = False @@ -319,12 +320,13 @@ def create_urllib3_context( # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is # necessary for conditional client cert authentication with TLS 1.3. # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older - # versions of Python. We only enable on Python 3.7.4+ or if certificate - # verification is enabled to work around Python issue #37428 + # versions of Python. We only enable if certificate verification is enabled to work + # around Python issue #37428 # See: https://bugs.python.org/issue37428 - if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr( - context, "post_handshake_auth", None - ) is not None: + if ( + cert_reqs == ssl.CERT_REQUIRED + and getattr(context, "post_handshake_auth", None) is not None + ): context.post_handshake_auth = True # The order of the below lines setting verify_mode and check_hostname @@ -341,7 +343,7 @@ def create_urllib3_context( try: context.hostname_checks_common_name = False - except AttributeError: + except AttributeError: # Defensive: for CPython < 3.8.9 and 3.9.3; for PyPy < 7.3.8 pass # Enable logging of TLS session keys via defacto standard environment variable @@ -408,8 +410,10 @@ def ssl_wrap_socket( tls_in_tls: bool = False, ) -> ssl.SSLSocket | SSLTransportType: """ - All arguments except for server_hostname, ssl_context, and ca_cert_dir have - the same meaning as they do when using :func:`ssl.wrap_socket`. + All arguments except for server_hostname, ssl_context, tls_in_tls, ca_cert_data and + ca_cert_dir have the same meaning as they do when using + :func:`ssl.create_default_context`, :meth:`ssl.SSLContext.load_cert_chain`, + :meth:`ssl.SSLContext.set_ciphers` and :meth:`ssl.SSLContext.wrap_socket`. :param server_hostname: When SNI is supported, the expected hostname of the certificate diff --git a/uno/lib/python/urllib3/util/ssltransport.py b/uno/lib/python/urllib3/util/ssltransport.py index 5ec86473..fa9f2b37 100644 --- a/uno/lib/python/urllib3/util/ssltransport.py +++ b/uno/lib/python/urllib3/util/ssltransport.py @@ -8,7 +8,7 @@ from ..exceptions import ProxySchemeUnsupported if typing.TYPE_CHECKING: - from typing_extensions import Literal + from typing import Literal from .ssl_ import _TYPE_PEER_CERT_RET, _TYPE_PEER_CERT_RET_DICT diff --git a/uno/lib/python/urllib3/util/timeout.py b/uno/lib/python/urllib3/util/timeout.py index ec090f69..f044625c 100644 --- a/uno/lib/python/urllib3/util/timeout.py +++ b/uno/lib/python/urllib3/util/timeout.py @@ -8,7 +8,7 @@ from ..exceptions import TimeoutStateError if typing.TYPE_CHECKING: - from typing_extensions import Final + from typing import Final class _TYPE_DEFAULT(Enum): diff --git a/uno/lib/python/validators/__init__.py b/uno/lib/python/validators/__init__.py index f623e12f..a7ca68eb 100644 --- a/uno/lib/python/validators/__init__.py +++ b/uno/lib/python/validators/__init__.py @@ -1,35 +1,80 @@ +"""Validate Anything!""" + +# local from .between import between from .btc_address import btc_address -from .card import ( - amex, - card_number, - diners, - discover, - jcb, - mastercard, - unionpay, - visa -) +from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa +from .country_code import country_code from .domain import domain from .email import email -from .extremes import Max, Min from .hashes import md5, sha1, sha224, sha256, sha512 -from .i18n import fi_business_id, fi_ssn +from .hostname import hostname +from .i18n import es_cif, es_doi, es_nie, es_nif, fi_business_id, fi_ssn from .iban import iban -from .ip_address import ipv4, ipv4_cidr, ipv6, ipv6_cidr +from .ip_address import ipv4, ipv6 from .length import length from .mac_address import mac_address from .slug import slug -from .truthy import truthy from .url import url -from .utils import ValidationFailure, validator +from .utils import ValidationError, validator from .uuid import uuid -__all__ = ('between', 'domain', 'email', 'Max', 'Min', 'md5', 'sha1', 'sha224', - 'sha256', 'sha512', 'fi_business_id', 'fi_ssn', 'iban', 'ipv4', - 'ipv4_cidr', 'ipv6', 'ipv6_cidr', 'length', 'mac_address', 'slug', - 'truthy', 'url', 'ValidationFailure', 'validator', 'uuid', - 'card_number', 'visa', 'mastercard', 'amex', 'unionpay', 'diners', - 'jcb', 'discover', 'btc_address') +# from .crypto_addresses import eth_address + +__all__ = ( + # ... + "between", + # crypto addresses + "btc_address", + # "eth_address", + # cards + "amex", + "card_number", + "diners", + "discover", + "jcb", + "mastercard", + "visa", + "unionpay", + # ... + "country_code", + # ... + "domain", + # ... + "email", + # hashes + "md5", + "sha1", + "sha224", + "sha256", + "sha512", + # ... + "hostname", + # i18n + "es_cif", + "es_doi", + "es_nie", + "es_nif", + "fi_business_id", + "fi_ssn", + # ... + "iban", + # ip addresses + "ipv4", + "ipv6", + # ... + "length", + # ... + "mac_address", + # ... + "slug", + # ... + "url", + # ... + "uuid", + # utils + "ValidationError", + "validator", +) -__version__ = '0.20.0' +__version__ = "0.22.0" diff --git a/uno/lib/python/validators/_extremes.py b/uno/lib/python/validators/_extremes.py new file mode 100644 index 00000000..717189e9 --- /dev/null +++ b/uno/lib/python/validators/_extremes.py @@ -0,0 +1,51 @@ +"""Extremes.""" + +# standard +from functools import total_ordering +from typing import Any + + +@total_ordering +class AbsMax: + """An object that is greater than any other object (except itself). + + Inspired by https://pypi.python.org/pypi/Extremes. + + Examples: + >>> from sys import maxint + >>> AbsMax > AbsMin + # Output: True + >>> AbsMax > maxint + # Output: True + >>> AbsMax > 99999999999999999 + # Output: True + + > *New in version 0.2.0*. + """ + + def __ge__(self, other: Any): + """GreaterThanOrEqual.""" + return other is not AbsMax + + +@total_ordering +class AbsMin: + """An object that is less than any other object (except itself). + + Inspired by https://pypi.python.org/pypi/Extremes. + + Examples: + >>> from sys import maxint + >>> AbsMin < -maxint + # Output: True + >>> AbsMin < None + # Output: True + >>> AbsMin < '' + # Output: True + + > *New in version 0.2.0*. + """ + + def __le__(self, other: Any): + """LessThanOrEqual.""" + return other is not AbsMin diff --git a/uno/lib/python/validators/between.py b/uno/lib/python/validators/between.py index 46f223c9..77c9ae35 100644 --- a/uno/lib/python/validators/between.py +++ b/uno/lib/python/validators/between.py @@ -1,61 +1,98 @@ -from .extremes import Max, Min +"""Between.""" + +# standard +from datetime import datetime +from typing import TypeVar, Union + +# local +from ._extremes import AbsMax, AbsMin from .utils import validator +PossibleValueTypes = TypeVar("PossibleValueTypes", int, float, str, datetime) + @validator -def between(value, min=None, max=None): - """ - Validate that a number is between minimum and/or maximum value. +def between( + value: PossibleValueTypes, + /, + *, + min_val: Union[PossibleValueTypes, AbsMin, None] = None, + max_val: Union[PossibleValueTypes, AbsMax, None] = None, +): + """Validate that a number is between minimum and/or maximum value. This will work with any comparable type, such as floats, decimals and dates - not just integers. + not just integers. This validator is originally based on [WTForms-NumberRange-Validator][1]. - This validator is originally based on `WTForms NumberRange validator`_. + [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L166-L220 - .. _WTForms NumberRange validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py + Examples: + >>> from datetime import datetime + >>> between(5, min_val=2) + # Output: True + >>> between(13.2, min_val=13, max_val=14) + # Output: True + >>> between(500, max_val=400) + # Output: ValidationError(func=between, args=...) + >>> between( + ... datetime(2000, 11, 11), + ... min_val=datetime(1999, 11, 11) + ... ) + # Output: True - Examples:: + Args: + value: + Value which is to be compared. + min_val: + The minimum required value of the number. + If not provided, minimum value will not be checked. + max_val: + The maximum value of the number. + If not provided, maximum value will not be checked. - >>> from datetime import datetime + Returns: + (Literal[True]): + If `value` is in between the given conditions. + (ValidationError): + If `value` is not in between the given conditions. - >>> between(5, min=2) - True + Raises: + ValueError: If both `min_val` and `max_val` are `None`, + or if `min_val` is greater than `max_val`. + TypeError: If there's a type mismatch before comparison. - >>> between(13.2, min=13, max=14) - True + Note: + - `PossibleValueTypes` = `TypeVar("PossibleValueTypes", int, float, str, datetime)` + - Either one of `min_val` or `max_val` must be provided. - >>> between(500, max=400) - ValidationFailure(func=between, args=...) + > *New in version 0.2.0*. + """ + if not value: + return False - >>> between( - ... datetime(2000, 11, 11), - ... min=datetime(1999, 11, 11) - ... ) - True + if min_val is max_val is None: + raise ValueError("At least one of either `min_val` or `max_val` must be specified") - :param min: - The minimum required value of the number. If not provided, minimum - value will not be checked. - :param max: - The maximum value of the number. If not provided, maximum value - will not be checked. + if max_val is None: + max_val = AbsMax() + if min_val is None: + min_val = AbsMin() - .. versionadded:: 0.2 - """ - if min is None and max is None: - raise AssertionError( - 'At least one of `min` or `max` must be specified.' - ) - if min is None: - min = Min - if max is None: - max = Max - try: - min_gt_max = min > max - except TypeError: - min_gt_max = max < min - if min_gt_max: - raise AssertionError('`min` cannot be more than `max`.') - - return min <= value and max >= value + if isinstance(min_val, AbsMin): + if type(value) is type(max_val): + return min_val <= value <= max_val + raise TypeError("`value` and `max_val` must be of same type") + + if isinstance(max_val, AbsMax): + if type(value) is type(min_val): + return min_val <= value <= max_val + raise TypeError("`value` and `min_val` must be of same type") + + if type(min_val) is type(max_val): + if min_val > max_val: + raise ValueError("`min_val` cannot be more than `max_val`") + if type(value) is type(min_val): # or is type(max_val) + return min_val <= value <= max_val + raise TypeError("`value` and (`min_val` or `max_val`) must be of same type") + + raise TypeError("`value` and `min_val` and `max_val` must be of same type") diff --git a/uno/lib/python/validators/btc_address.py b/uno/lib/python/validators/btc_address.py index 35ada853..204ab194 100644 --- a/uno/lib/python/validators/btc_address.py +++ b/uno/lib/python/validators/btc_address.py @@ -1,55 +1,60 @@ -import re +"""BTC Address.""" + +# standard from hashlib import sha256 +import re +# local from .utils import validator -segwit_pattern = re.compile( - r'^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$') - - -def validate_segwit_address(addr): - return segwit_pattern.match(addr) - -def decode_base58(addr): +def _decode_base58(addr: str): + """Decode base58.""" alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - return sum([ - (58 ** e) * alphabet.index(i) - for e, i in enumerate(addr[::-1]) - ]) + return sum((58**enm) * alphabet.index(idx) for enm, idx in enumerate(addr[::-1])) -def validate_old_btc_address(addr): - "Validate P2PKH and P2SH type address" - if not len(addr) in range(25, 35): +def _validate_old_btc_address(addr: str): + """Validate P2PKH and P2SH type address.""" + if len(addr) not in range(25, 35): return False - decoded_bytes = decode_base58(addr).to_bytes(25, "big") - header = decoded_bytes[:-4] - checksum = decoded_bytes[-4:] + decoded_bytes = _decode_base58(addr).to_bytes(25, "big") + header, checksum = decoded_bytes[:-4], decoded_bytes[-4:] return checksum == sha256(sha256(header).digest()).digest()[:4] @validator -def btc_address(value): - """ - Return whether or not given value is a valid bitcoin address. - - If the value is valid bitcoin address this function returns ``True``, - otherwise :class:`~validators.utils.ValidationFailure`. +def btc_address(value: str, /): + """Return whether or not given value is a valid bitcoin address. Full validation is implemented for P2PKH and P2SH addresses. - For segwit addresses a regexp is used to provide a reasonable estimate - on whether the address is valid. - - Examples:: + For segwit addresses a regexp is used to provide a reasonable + estimate on whether the address is valid. + Examples: >>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69') - True + # Output: True + >>> btc_address('1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2') + # Output: ValidationError(func=btc_address, args=...) - :param value: Bitcoin address string to validate + Args: + value: + Bitcoin address string to validate. + + Returns: + (Literal[True]): + If `value` is a valid bitcoin address. + (ValidationError): + If `value` is an invalid bitcoin address. + + > *New in version 0.18.0*. """ - if not value or not isinstance(value, str): + if not value: return False - if value[:2] in ("bc", "tb"): - return validate_segwit_address(value) - return validate_old_btc_address(value) + + return ( + # segwit pattern + re.compile(r"^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$").match(value) + if value[:2] in ("bc", "tb") + else _validate_old_btc_address(value) + ) diff --git a/uno/lib/python/validators/card.py b/uno/lib/python/validators/card.py index 8b8cbeea..d8aa0f1b 100644 --- a/uno/lib/python/validators/card.py +++ b/uno/lib/python/validators/card.py @@ -1,183 +1,226 @@ +"""Card.""" + +# standard import re +# local from .utils import validator @validator -def card_number(value): - """ - Return whether or not given value is a valid card number. - - This validator is based on Luhn algorithm. +def card_number(value: str, /): + """Return whether or not given value is a valid generic card number. - .. luhn: - https://github.com/mmcloughlin/luhn + This validator is based on [Luhn's algorithm][1]. - Examples:: + [1]: https://github.com/mmcloughlin/luhn + Examples: >>> card_number('4242424242424242') - True - + # Output: True >>> card_number('4242424242424241') - ValidationFailure(func=card_number, args={'value': '4242424242424241'}) + # Output: ValidationError(func=card_number, args={'value': '4242424242424241'}) + + Args: + value: + Generic card number string to validate - .. versionadded:: 0.15.0 + Returns: + (Literal[True]): + If `value` is a valid generic card number. + (ValidationError): + If `value` is an invalid generic card number. - :param value: card number string to validate + > *New in version 0.15.0*. """ + if not value: + return False try: digits = list(map(int, value)) odd_sum = sum(digits[-1::-2]) - even_sum = sum([sum(divmod(2 * d, 10)) for d in digits[-2::-2]]) + even_sum = sum(sum(divmod(2 * d, 10)) for d in digits[-2::-2]) return (odd_sum + even_sum) % 10 == 0 except ValueError: return False @validator -def visa(value): - """ - Return whether or not given value is a valid Visa card number. - - Examples:: +def visa(value: str, /): + """Return whether or not given value is a valid Visa card number. + Examples: >>> visa('4242424242424242') - True - + # Output: True >>> visa('2223003122003222') - ValidationFailure(func=visa, args={'value': '2223003122003222'}) + # Output: ValidationError(func=visa, args={'value': '2223003122003222'}) - .. versionadded:: 0.15.0 + Args: + value: + Visa card number string to validate - :param value: Visa card number string to validate + Returns: + (Literal[True]): + If `value` is a valid Visa card number. + (ValidationError): + If `value` is an invalid Visa card number. + + > *New in version 0.15.0*. """ - pattern = re.compile(r'^4') + pattern = re.compile(r"^4") return card_number(value) and len(value) == 16 and pattern.match(value) @validator -def mastercard(value): - """ - Return whether or not given value is a valid Mastercard card number. - - Examples:: +def mastercard(value: str, /): + """Return whether or not given value is a valid Mastercard card number. + Examples: >>> mastercard('5555555555554444') - True - + # Output: True >>> mastercard('4242424242424242') - ValidationFailure(func=mastercard, args={'value': '4242424242424242'}) + # Output: ValidationError(func=mastercard, args={'value': '4242424242424242'}) - .. versionadded:: 0.15.0 + Args: + value: + Mastercard card number string to validate - :param value: Mastercard card number string to validate + Returns: + (Literal[True]): + If `value` is a valid Mastercard card number. + (ValidationError): + If `value` is an invalid Mastercard card number. + + > *New in version 0.15.0*. """ - pattern = re.compile(r'^(51|52|53|54|55|22|23|24|25|26|27)') + pattern = re.compile(r"^(51|52|53|54|55|22|23|24|25|26|27)") return card_number(value) and len(value) == 16 and pattern.match(value) @validator -def amex(value): - """ - Return whether or not given value is a valid American Express card number. - - Examples:: +def amex(value: str, /): + """Return whether or not given value is a valid American Express card number. + Examples: >>> amex('378282246310005') - True - + # Output: True >>> amex('4242424242424242') - ValidationFailure(func=amex, args={'value': '4242424242424242'}) + # Output: ValidationError(func=amex, args={'value': '4242424242424242'}) - .. versionadded:: 0.15.0 + Args: + value: + American Express card number string to validate - :param value: American Express card number string to validate + Returns: + (Literal[True]): + If `value` is a valid American Express card number. + (ValidationError): + If `value` is an invalid American Express card number. + + > *New in version 0.15.0*. """ - pattern = re.compile(r'^(34|37)') + pattern = re.compile(r"^(34|37)") return card_number(value) and len(value) == 15 and pattern.match(value) @validator -def unionpay(value): - """ - Return whether or not given value is a valid UnionPay card number. - - Examples:: +def unionpay(value: str, /): + """Return whether or not given value is a valid UnionPay card number. + Examples: >>> unionpay('6200000000000005') - True - + # Output: True >>> unionpay('4242424242424242') - ValidationFailure(func=unionpay, args={'value': '4242424242424242'}) + # Output: ValidationError(func=unionpay, args={'value': '4242424242424242'}) + + Args: + value: + UnionPay card number string to validate - .. versionadded:: 0.15.0 + Returns: + (Literal[True]): + If `value` is a valid UnionPay card number. + (ValidationError): + If `value` is an invalid UnionPay card number. - :param value: UnionPay card number string to validate + > *New in version 0.15.0*. """ - pattern = re.compile(r'^62') + pattern = re.compile(r"^62") return card_number(value) and len(value) == 16 and pattern.match(value) @validator -def diners(value): - """ - Return whether or not given value is a valid Diners Club card number. - - Examples:: +def diners(value: str, /): + """Return whether or not given value is a valid Diners Club card number. + Examples: >>> diners('3056930009020004') - True - + # Output: True >>> diners('4242424242424242') - ValidationFailure(func=diners, args={'value': '4242424242424242'}) + # Output: ValidationError(func=diners, args={'value': '4242424242424242'}) + + Args: + value: + Diners Club card number string to validate - .. versionadded:: 0.15.0 + Returns: + (Literal[True]): + If `value` is a valid Diners Club card number. + (ValidationError): + If `value` is an invalid Diners Club card number. - :param value: Diners Club card number string to validate + > *New in version 0.15.0*. """ - pattern = re.compile(r'^(30|36|38|39)') - return ( - card_number(value) and len(value) in [14, 16] and pattern.match(value) - ) + pattern = re.compile(r"^(30|36|38|39)") + return card_number(value) and len(value) in {14, 16} and pattern.match(value) @validator -def jcb(value): - """ - Return whether or not given value is a valid JCB card number. - - Examples:: +def jcb(value: str, /): + """Return whether or not given value is a valid JCB card number. + Examples: >>> jcb('3566002020360505') - True - + # Output: True >>> jcb('4242424242424242') - ValidationFailure(func=jcb, args={'value': '4242424242424242'}) + # Output: ValidationError(func=jcb, args={'value': '4242424242424242'}) + + Args: + value: + JCB card number string to validate - .. versionadded:: 0.15.0 + Returns: + (Literal[True]): + If `value` is a valid JCB card number. + (ValidationError): + If `value` is an invalid JCB card number. - :param value: JCB card number string to validate + > *New in version 0.15.0*. """ - pattern = re.compile(r'^35') + pattern = re.compile(r"^35") return card_number(value) and len(value) == 16 and pattern.match(value) @validator -def discover(value): - """ - Return whether or not given value is a valid Discover card number. - - Examples:: +def discover(value: str, /): + """Return whether or not given value is a valid Discover card number. + Examples: >>> discover('6011111111111117') - True - + # Output: True >>> discover('4242424242424242') - ValidationFailure(func=discover, args={'value': '4242424242424242'}) + # Output: ValidationError(func=discover, args={'value': '4242424242424242'}) + + Args: + value: + Discover card number string to validate - .. versionadded:: 0.15.0 + Returns: + (Literal[True]): + If `value` is a valid Discover card number. + (ValidationError): + If `value` is an invalid Discover card number. - :param value: Discover card number string to validate + > *New in version 0.15.0*. """ - pattern = re.compile(r'^(60|64|65)') + pattern = re.compile(r"^(60|64|65)") return card_number(value) and len(value) == 16 and pattern.match(value) diff --git a/uno/lib/python/validators/country_code.py b/uno/lib/python/validators/country_code.py new file mode 100644 index 00000000..822f2ea6 --- /dev/null +++ b/uno/lib/python/validators/country_code.py @@ -0,0 +1,162 @@ +"""Country Codes.""" + +# local +from validators.utils import validator + +# fmt: off +alpha_2 = { + "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", + "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", + "BT", "BV", "BW", "BY", "BZ", + "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", + "CX", "CY", "CZ", + "DE", "DJ", "DK", "DM", "DO", "DZ", + "EC", "EE", "EG", "EH", "ER", "ES", "ET", + "FI", "FJ", "FK", "FM", "FO", "FR", + "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", + "GU", "GW", "GY", + "HK", "HM", "HN", "HR", "HT", "HU", + "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", + "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", + "KM", "KN", "KP", "KR", "KW", "KY", "KZ", + "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", + "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", + "MT", "MU", "MV", "MW", "MX", "MY", "MZ", + "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", + "OM", + "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", + "QA", + "RE", "RO", "RS", "RU", "RW", + "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", + "ST", "SV", "SX", "SY", "SZ", + "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", + "UA", "UG", "UM", "US", "UY", "UZ", + "VC", "VE", "VG", "VI", "VN", "VU", + "WF", "WS", + "YE", "YT", + "ZA", "ZM", "ZW", +} +alpha_3 = { + "ABW", "AFG", "AGO", "AIA", "ALA", "ALB", "AND", "ARE", "ARG", "ARM", "ASM", "ATA", "ATF", + "ATG", "AUS", "AUT", "AZE", + "BDI", "BEL", "BEN", "BES", "BFA", "BGD", "BGR", "BHR", "BHS", "BIH", "BLM", "BLR", "BLZ", + "BMU", "BOL", "BRA", "BRB", "BRN", "BTN", "BVT", "BWA", + "CAF", "CAN", "CCK", "CHE", "CHL", "CHN", "CIV", "CMR", "COD", "COG", "COK", "COL", "COM", + "CPV", "CRI", "CUB", "CUW", "CXR", "CYM", "CYP", "CZE", + "DEU", "DJI", "DMA", "DNK", "DOM", "DZA", + "ECU", "EGY", "ERI", "ESH", "ESP", "EST", "ETH", + "FIN", "FJI", "FLK", "FRA", "FRO", "FSM", + "GAB", "GBR", "GEO", "GGY", "GHA", "GIB", "GIN", "GLP", "GMB", "GNB", "GNQ", "GRC", "GRD", + "GRL", "GTM", "GUF", "GUM", "GUY", + "HKG", "HMD", "HND", "HRV", "HTI", "HUN", + "IDN", "IMN", "IND", "IOT", "IRL", "IRN", "IRQ", "ISL", "ISR", "ITA", + "JAM", "JEY", "JOR", "JPN", + "KAZ", "KEN", "KGZ", "KHM", "KIR", "KNA", "KOR", "KWT", + "LAO", "LBN", "LBR", "LBY", "LCA", "LIE", "LKA", "LSO", "LTU", "LUX", "LVA", + "MAC", "MAF", "MAR", "MCO", "MDA", "MDG", "MDV", "MEX", "MHL", "MKD", "MLI", "MLT", "MMR", + "MNE", "MNG", "MNP", "MOZ", "MRT", "MSR", "MTQ", "MUS", "MWI", "MYS", "MYT", + "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NIU", "NLD", "NOR", "NPL", "NRU", "NZL", + "OMN", + "PAK", "PAN", "PCN", "PER", "PHL", "PLW", "PNG", "POL", "PRI", "PRK", "PRT", "PRY", "PSE", + "PYF", + "QAT", + "REU", "ROU", "RUS", "RWA", + "SAU", "SDN", "SEN", "SGP", "SGS", "SHN", "SJM", "SLB", "SLE", "SLV", "SMR", "SOM", "SPM", + "SRB", "SSD", "STP", "SUR", "SVK", "SVN", "SWE", "SWZ", "SXM", "SYC", "SYR", + "TCA", "TCD", "TGO", "THA", "TJK", "TKL", "TKM", "TLS", "TON", "TTO", "TUN", "TUR", "TUV", + "TWN", "TZA", + "UGA", "UKR", "UMI", "URY", "USA", "UZB", + "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", + "WLF", "WSM", + "YEM", + "ZAF", "ZMB", "ZWE", +} +numeric = { + "004", "008", "010", "012", "016", "020", "024", "028", "031", "032", + "036", "040", "044", "048", "050", "051", "052", "056", "060", "064", + "068", "070", "072", "074", "076", "084", "086", "090", "092", "096", + "100", "104", "108", "112", "116", "120", "124", "132", "136", "140", + "144", "148", "152", "156", "158", "162", "166", "170", "174", "175", + "178", "180", "184", "188", "191", "192", "196", "203", "204", "208", + "212", "214", "218", "222", "226", "231", "232", "233", "234", "238", + "239", "242", "246", "248", "250", "254", "258", "260", "262", "266", + "268", "270", "275", "276", "288", "292", "296", "300", "304", "308", + "312", "316", "320", "324", "328", "332", "334", "340", "344", "348", + "352", "356", "360", "364", "368", "372", "376", "380", "384", "388", + "392", "398", "400", "404", "408", "410", "414", "417", "418", "422", + "426", "428", "430", "434", "438", "440", "442", "446", "450", "454", + "458", "462", "466", "470", "474", "478", "480", "484", "492", "496", + "498", "499", "500", "504", "508", "512", "516", "520", "524", "528", + "531", "533", "534", "535", "540", "548", "554", "558", "562", "566", + "570", "574", "578", "580", "581", "583", "584", "585", "586", "591", + "598", "600", "604", "608", "612", "616", "620", "624", "626", "630", + "634", "638", "642", "643", "646", "652", "654", "659", "660", "662", + "663", "666", "670", "674", "678", "682", "686", "688", "690", "694", + "702", "703", "704", "705", "706", "710", "716", "724", "728", "729", + "732", "740", "744", "748", "752", "756", "760", "762", "764", "768", + "772", "776", "780", "784", "788", "792", "795", "796", "798", "800", + "804", "807", "818", "826", "831", "832", "833", "834", "840", "850", + "854", "858", "860", "862", "876", "882", "887", "894", +} +# fmt: on + + +def get_code_type(format_type: str): + """Returns the type of country code.""" + if format_type.isdigit(): + return "numeric" + if format_type.isalpha(): + if len(format_type) == 2: + return "alpha2" + if len(format_type) == 3: + return "alpha3" + return "invalid" + + +@validator +def country_code(value: str, /, *, iso_format: str = "auto"): + """Validates given country code. + + This performs a case-sensitive [ISO 3166][1] country code validation. + + [1]: https://www.iso.org/iso-3166-country-codes.html + + Examples: + >>> country_code('GB', iso_format='alpha3') + # Output: False + >>> country_code('USA') + # Output: True + >>> country_code('840', iso_format='numeric') + # Output: True + >>> country_code('iN', iso_format='alpha2') + # Output: False + >>> country_code('ZWE', iso_format='alpha3') + # Output: True + + Args: + value: + Country code string to validate. + iso_format: + ISO format to be used. Available options are: + `auto`, `alpha2`, `alpha3` and `numeric`. + + Returns: + (Literal[True]): + If `value` is a valid country code. + (ValidationError): + If `value` is an invalid country code. + """ + if not value: + return False + + if not (1 < len(value) < 4): + return False + + if iso_format == "auto" and (iso_format := get_code_type(value)) == "invalid": + return False + + if iso_format == "alpha2": + return value in alpha_2 + if iso_format == "alpha3": + return value in alpha_3 + return value in numeric if iso_format == "numeric" else False diff --git a/uno/lib/python/validators/domain.py b/uno/lib/python/validators/domain.py index d9bf44f0..bdc5b769 100644 --- a/uno/lib/python/validators/domain.py +++ b/uno/lib/python/validators/domain.py @@ -1,54 +1,62 @@ +"""Domain.""" + +# standard import re +# local from .utils import validator -pattern = re.compile( - r'^(?:[a-zA-Z0-9]' # First character of the domain - r'(?:[a-zA-Z0-9-_]{0,61}[A-Za-z0-9])?\.)' # Sub domain + hostname - r'+[A-Za-z0-9][A-Za-z0-9-_]{0,61}' # First 61 characters of the gTLD - r'[A-Za-z]$' # Last character of the gTLD -) - - -def to_unicode(obj, charset='utf-8', errors='strict'): - if obj is None: - return None - if not isinstance(obj, bytes): - return str(obj) - return obj.decode(charset, errors) - @validator -def domain(value): - """ - Return whether or not given value is a valid domain. - - If the value is valid domain name this function returns ``True``, otherwise - :class:`~validators.utils.ValidationFailure`. - - Examples:: +def domain(value: str, /, *, rfc_1034: bool = False, rfc_2782: bool = False): + """Return whether or not given value is a valid domain. + Examples: >>> domain('example.com') - True - + # Output: True >>> domain('example.com/') - ValidationFailure(func=domain, ...) - - - Supports IDN domains as well:: - + # Output: ValidationError(func=domain, ...) + >>> # Supports IDN domains as well:: >>> domain('xn----gtbspbbmkef.xn--p1ai') - True - - .. versionadded:: 0.9 - - .. versionchanged:: 0.10 - - Added support for internationalized domain name (IDN) validation. - - :param value: domain string to validate + # Output: True + + Args: + value: + Domain string to validate. + rfc_1034: + Allow trailing dot in domain name. + Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). + rfc_2782: + Domain name is of type service record. + Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). + + + Returns: + (Literal[True]): + If `value` is a valid domain name. + (ValidationError): + If `value` is an invalid domain name. + + Note: + - *In version 0.10.0*: + - Added support for internationalized domain name (IDN) validation. + + > *New in version 0.9.0*. """ + if not value: + return False try: - return pattern.match(to_unicode(value).encode('idna').decode('ascii')) - except (UnicodeError, AttributeError): + return not re.search(r"\s", value) and re.match( + # First character of the domain + rf"^(?:[a-zA-Z0-9{'_'if rfc_2782 else ''}]" + # Sub domain + hostname + + r"(?:[a-zA-Z0-9-_]{0,61}[A-Za-z0-9])?\.)" + # First 61 characters of the gTLD + + r"+[A-Za-z0-9][A-Za-z0-9-_]{0,61}" + # Last character of the gTLD + + rf"[A-Za-z]{r'.$' if rfc_1034 else r'$'}", + value.encode("idna").decode("utf-8"), + re.IGNORECASE, + ) + except UnicodeError: return False diff --git a/uno/lib/python/validators/email.py b/uno/lib/python/validators/email.py index 229c8e46..760dbd3a 100644 --- a/uno/lib/python/validators/email.py +++ b/uno/lib/python/validators/email.py @@ -1,75 +1,99 @@ +"""eMail.""" + +# standard import re +# local +from .hostname import hostname from .utils import validator -user_regex = re.compile( - # dot-atom - r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+" - r"(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" - # quoted-string - r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|' - r"""\\[\001-\011\013\014\016-\177])*"$)""", - re.IGNORECASE -) -domain_regex = re.compile( - # domain - r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+' - r'(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?$)' - # literal form, ipv4 address (SMTP 4.1.3) - r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)' - r'(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', - re.IGNORECASE) -domain_whitelist = ['localhost'] - @validator -def email(value, whitelist=None): - """ - Validate an email address. - - This validator is based on `Django's email validator`_. Returns - ``True`` on success and :class:`~validators.utils.ValidationFailure` - when validation fails. - - Examples:: - +def email( + value: str, + /, + *, + ipv6_address: bool = False, + ipv4_address: bool = False, + simple_host: bool = False, + rfc_1034: bool = False, + rfc_2782: bool = False, +): + """Validate an email address. + + This was inspired from [Django's email validator][1]. + Also ref: [RFC 1034][2], [RFC 5321][3] and [RFC 5322][4]. + + [1]: https://github.com/django/django/blob/main/django/core/validators.py#L174 + [2]: https://www.rfc-editor.org/rfc/rfc1034 + [3]: https://www.rfc-editor.org/rfc/rfc5321 + [4]: https://www.rfc-editor.org/rfc/rfc5322 + + Examples: >>> email('someone@example.com') - True - + # Output: True >>> email('bogus@@') - ValidationFailure(func=email, ...) - - .. _Django's email validator: - https://github.com/django/django/blob/master/django/core/validators.py - - .. versionadded:: 0.1 - - :param value: value to validate - :param whitelist: domain names to whitelist - - :copyright: (c) Django Software Foundation and individual contributors. - :license: BSD + # Output: ValidationError(email=email, args={'value': 'bogus@@'}) + + Args: + value: + eMail string to validate. + ipv6_address: + When the domain part is an IPv6 address. + ipv4_address: + When the domain part is an IPv4 address. + simple_host: + When the domain part is a simple hostname. + rfc_1034: + Allow trailing dot in domain name. + Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). + rfc_2782: + Domain name is of type service record. + Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). + + Returns: + (Literal[True]): + If `value` is a valid eMail. + (ValidationError): + If `value` is an invalid eMail. + + > *New in version 0.1.0*. """ - - if whitelist is None: - whitelist = domain_whitelist - - if not value or '@' not in value: + if not value or value.count("@") != 1: return False - user_part, domain_part = value.rsplit('@', 1) - - if not user_regex.match(user_part): - return False + username_part, domain_part = value.rsplit("@", 1) - if len(user_part.encode("utf-8")) > 64: + if len(username_part) > 64 or len(domain_part) > 253: + # ref: RFC 1034 and 5231 return False - if domain_part not in whitelist and not domain_regex.match(domain_part): - # Try for possible IDN domain-part - try: - domain_part = domain_part.encode('idna').decode('ascii') - return domain_regex.match(domain_part) - except UnicodeError: + if ipv6_address or ipv4_address: + if domain_part.startswith("[") and domain_part.endswith("]"): + # ref: RFC 5321 + domain_part = domain_part.lstrip("[").rstrip("]") + else: return False - return True + + return ( + bool( + hostname( + domain_part, + skip_ipv6_addr=not ipv6_address, + skip_ipv4_addr=not ipv4_address, + may_have_port=False, + maybe_simple=simple_host, + rfc_1034=rfc_1034, + rfc_2782=rfc_2782, + ) + ) + if re.match( + # dot-atom + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" + # quoted-string + + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)', + username_part, + re.IGNORECASE, + ) + else False + ) diff --git a/uno/lib/python/validators/extremes.py b/uno/lib/python/validators/extremes.py deleted file mode 100644 index 43d168a7..00000000 --- a/uno/lib/python/validators/extremes.py +++ /dev/null @@ -1,61 +0,0 @@ -from functools import total_ordering - - -@total_ordering -class Min(object): - """ - An object that is less than any other object (except itself). - - Inspired by https://pypi.python.org/pypi/Extremes - - Examples:: - - >>> import sys - - >>> Min < -sys.maxint - True - - >>> Min < None - True - - >>> Min < '' - True - - .. versionadded:: 0.2 - """ - def __lt__(self, other): - if other is Min: - return False - return True - - -@total_ordering -class Max(object): - """ - An object that is greater than any other object (except itself). - - Inspired by https://pypi.python.org/pypi/Extremes - - Examples:: - - >>> import sys - - >>> Max > Min - True - - >>> Max > sys.maxint - True - - >>> Max > 99999999999999999 - True - - .. versionadded:: 0.2 - """ - def __gt__(self, other): - if other is Max: - return False - return True - - -Min = Min() -Max = Max() diff --git a/uno/lib/python/validators/hashes.py b/uno/lib/python/validators/hashes.py index 4db7f78e..69f8f96c 100644 --- a/uno/lib/python/validators/hashes.py +++ b/uno/lib/python/validators/hashes.py @@ -1,121 +1,139 @@ +"""Hashes.""" + +# standard import re +# local from .utils import validator -md5_regex = re.compile( - r"^[0-9a-f]{32}$", - re.IGNORECASE -) -sha1_regex = re.compile( - r"^[0-9a-f]{40}$", - re.IGNORECASE -) -sha224_regex = re.compile( - r"^[0-9a-f]{56}$", - re.IGNORECASE -) -sha256_regex = re.compile( - r"^[0-9a-f]{64}$", - re.IGNORECASE -) -sha512_regex = re.compile( - r"^[0-9a-f]{128}$", - re.IGNORECASE -) - @validator -def md5(value): - """ - Return whether or not given value is a valid MD5 hash. - - Examples:: +def md5(value: str, /): + """Return whether or not given value is a valid MD5 hash. + Examples: >>> md5('d41d8cd98f00b204e9800998ecf8427e') - True - + # Output: True >>> md5('900zz11') - ValidationFailure(func=md5, args={'value': '900zz11'}) + # Output: ValidationError(func=md5, args={'value': '900zz11'}) - :param value: MD5 string to validate - """ - return md5_regex.match(value) + Args: + value: + MD5 string to validate. + Returns: + (Literal[True]): + If `value` is a valid MD5 hash. + (ValidationError): + If `value` is an invalid MD5 hash. -@validator -def sha1(value): + > *New in version 0.12.1* """ - Return whether or not given value is a valid SHA1 hash. + return re.match(r"^[0-9a-f]{32}$", value, re.IGNORECASE) if value else False - Examples:: - >>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709') - True +@validator +def sha1(value: str, /): + """Return whether or not given value is a valid SHA1 hash. + Examples: + >>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709') + # Output: True >>> sha1('900zz11') - ValidationFailure(func=sha1, args={'value': '900zz11'}) + # Output: ValidationError(func=sha1, args={'value': '900zz11'}) - :param value: SHA1 string to validate - """ - return sha1_regex.match(value) + Args: + value: + SHA1 string to validate. + Returns: + (Literal[True]): + If `value` is a valid SHA1 hash. + (ValidationError): + If `value` is an invalid SHA1 hash. -@validator -def sha224(value): + > *New in version 0.12.1* """ - Return whether or not given value is a valid SHA224 hash. + return re.match(r"^[0-9a-f]{40}$", value, re.IGNORECASE) if value else False - Examples:: - >>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f') - True +@validator +def sha224(value: str, /): + """Return whether or not given value is a valid SHA224 hash. + Examples: + >>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f') + # Output: True >>> sha224('900zz11') - ValidationFailure(func=sha224, args={'value': '900zz11'}) + # Output: ValidationError(func=sha224, args={'value': '900zz11'}) - :param value: SHA224 string to validate - """ - return sha224_regex.match(value) + Args: + value: + SHA224 string to validate. + Returns: + (Literal[True]): + If `value` is a valid SHA224 hash. + (ValidationError): + If `value` is an invalid SHA224 hash. -@validator -def sha256(value): + > *New in version 0.12.1* """ - Return whether or not given value is a valid SHA256 hash. + return re.match(r"^[0-9a-f]{56}$", value, re.IGNORECASE) if value else False - Examples:: +@validator +def sha256(value: str, /): + """Return whether or not given value is a valid SHA256 hash. + + Examples: >>> sha256( - ... 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b' - ... '855' + ... 'e3b0c44298fc1c149afbf4c8996fb924' + ... '27ae41e4649b934ca495991b7852b855' ... ) - True - + # Output: True >>> sha256('900zz11') - ValidationFailure(func=sha256, args={'value': '900zz11'}) + # Output: ValidationError(func=sha256, args={'value': '900zz11'}) - :param value: SHA256 string to validate - """ - return sha256_regex.match(value) + Args: + value: + SHA256 string to validate. + Returns: + (Literal[True]): + If `value` is a valid SHA256 hash. + (ValidationError): + If `value` is an invalid SHA256 hash. -@validator -def sha512(value): + > *New in version 0.12.1* """ - Return whether or not given value is a valid SHA512 hash. + return re.match(r"^[0-9a-f]{64}$", value, re.IGNORECASE) if value else False + - Examples:: +@validator +def sha512(value: str, /): + """Return whether or not given value is a valid SHA512 hash. + Examples: >>> sha512( ... 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce' ... '9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af9' ... '27da3e' ... ) - True - + # Output: True >>> sha512('900zz11') - ValidationFailure(func=sha512, args={'value': '900zz11'}) + # Output: ValidationError(func=sha512, args={'value': '900zz11'}) + + Args: + value: + SHA512 string to validate. + + Returns: + (Literal[True]): + If `value` is a valid SHA512 hash. + (ValidationError): + If `value` is an invalid SHA512 hash. - :param value: SHA512 string to validate + > *New in version 0.12.1* """ - return sha512_regex.match(value) + return re.match(r"^[0-9a-f]{128}$", value, re.IGNORECASE) if value else False diff --git a/uno/lib/python/validators/hostname.py b/uno/lib/python/validators/hostname.py new file mode 100644 index 00000000..04d06e7f --- /dev/null +++ b/uno/lib/python/validators/hostname.py @@ -0,0 +1,126 @@ +"""Hostname.""" + +# standard +from functools import lru_cache +import re + +from .domain import domain + +# local +from .ip_address import ipv4, ipv6 +from .utils import validator + + +@lru_cache +def _port_regex(): + """Port validation regex.""" + return re.compile( + r"^\:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|" + + r"6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3})$", + ) + + +@lru_cache +def _simple_hostname_regex(): + """Simple hostname validation regex.""" + # {0,59} because two characters are already matched at + # the beginning and at the end, making the range {1, 61} + return re.compile(r"^(?!-)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,59}[a-zA-Z0-9])?(?>> hostname("ubuntu-pc:443") + # Output: True + >>> hostname("this-pc") + # Output: True + >>> hostname("xn----gtbspbbmkef.xn--p1ai:65535") + # Output: True + >>> hostname("_example.com") + # Output: True + >>> hostname("123.5.77.88:31000") + # Output: True + >>> hostname("12.12.12.12") + # Output: True + >>> hostname("[::1]:22") + # Output: True + >>> hostname("dead:beef:0:0:0:0000:42:1") + # Output: True + >>> hostname("[0:0:0:0:0:ffff:1.2.3.4]:-65538") + # Output: ValidationError(func=hostname, ...) + >>> hostname("[0:&:b:c:@:e:f::]:9999") + # Output: ValidationError(func=hostname, ...) + + Args: + value: + Hostname string to validate. + skip_ipv6_addr: + When hostname string cannot be an IPv6 address. + skip_ipv4_addr: + When hostname string cannot be an IPv4 address. + may_have_port: + Hostname string may contain port number. + maybe_simple: + Hostname string maybe only hyphens and alpha-numerals. + rfc_1034: + Allow trailing dot in domain/host name. + Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). + rfc_2782: + Domain/Host name is of type service record. + Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). + + Returns: + (Literal[True]): + If `value` is a valid hostname. + (ValidationError): + If `value` is an invalid hostname. + + > *New in version 0.21.0*. + """ + if not value: + return False + + if may_have_port and (host_seg := _port_validator(value)): + return ( + (_simple_hostname_regex().match(host_seg) if maybe_simple else False) + or domain(host_seg, rfc_1034=rfc_1034, rfc_2782=rfc_2782) + or (False if skip_ipv4_addr else ipv4(host_seg, cidr=False)) + or (False if skip_ipv6_addr else ipv6(host_seg, cidr=False)) + ) + + return ( + (_simple_hostname_regex().match(value) if maybe_simple else False) + or domain(value, rfc_1034=rfc_1034, rfc_2782=rfc_2782) + or (False if skip_ipv4_addr else ipv4(value, cidr=False)) + or (False if skip_ipv6_addr else ipv6(value, cidr=False)) + ) diff --git a/uno/lib/python/validators/i18n/__init__.py b/uno/lib/python/validators/i18n/__init__.py index 12775c6c..822a3fbc 100644 --- a/uno/lib/python/validators/i18n/__init__.py +++ b/uno/lib/python/validators/i18n/__init__.py @@ -1,4 +1,9 @@ -# TODO: remove, let the user import it if they really want it -from .fi import fi_business_id, fi_ssn # noqa +"""Country.""" -__all__ = ('fi_business_id', 'fi_ssn') +# isort: skip_file + +# local +from .es import es_cif, es_doi, es_nie, es_nif +from .fi import fi_business_id, fi_ssn + +__all__ = ("fi_business_id", "fi_ssn", "es_cif", "es_doi", "es_nie", "es_nif") diff --git a/uno/lib/python/validators/i18n/es.py b/uno/lib/python/validators/i18n/es.py index ed2e2a63..2c396b09 100644 --- a/uno/lib/python/validators/i18n/es.py +++ b/uno/lib/python/validators/i18n/es.py @@ -1,200 +1,185 @@ -# -*- coding: utf-8 -*- -from validators.utils import validator - -__all__ = ('es_cif', 'es_nif', 'es_nie', 'es_doi',) +"""Spain.""" +# standard +from typing import Dict, Set -def nif_nie_validation(doi, number_by_letter, special_cases): - """ - Validate if the doi is a NIF or a NIE. - :param doi: DOI to validate. - :return: boolean if it's valid. - """ - doi = doi.upper() - if doi in special_cases: - return False +# local +from validators.utils import validator - table = 'TRWAGMYFPDXBNJZSQVHLCKE' - if len(doi) != 9: +def _nif_nie_validation(value: str, number_by_letter: Dict[str, str], special_cases: Set[str]): + """Validate if the doi is a NIF or a NIE.""" + if value in special_cases or len(value) != 9: return False - - control = doi[8] - - # If it is not a DNI, convert the first letter to the corresponding - # digit - numbers = number_by_letter.get(doi[0], doi[0]) + doi[1:8] - - return numbers.isdigit() and control == table[int(numbers) % 23] + value = value.upper() + table = "TRWAGMYFPDXBNJZSQVHLCKE" + # If it is not a DNI, convert the first + # letter to the corresponding digit + numbers = number_by_letter.get(value[0], value[0]) + value[1:8] + # doi[8] is control + return numbers.isdigit() and value[8] == table[int(numbers) % 23] @validator -def es_cif(doi): - """ - Validate a Spanish CIF. +def es_cif(value: str, /): + """Validate a Spanish CIF. Each company in Spain prior to 2008 had a distinct CIF and has been - discontinued. For more information see `wikipedia.org/cif`_. + discontinued. For more information see [wikipedia.org/cif][1]. The new replacement is to use NIF for absolutely everything. The issue is - that there are "types" of NIFs now: company, person[citizen vs recident] + that there are "types" of NIFs now: company, person [citizen or resident] all distinguished by the first character of the DOI. For this reason we - will continue to call CIF NIFs that are used for companies. - - This validator is based on `generadordni.es`_. + will continue to call CIFs NIFs, that are used for companies. - .. _generadordni.es: - https://generadordni.es/ + This validator is based on [generadordni.es][2]. - .. _wikipedia.org/cif: - https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal - - Examples:: + [1]: https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal + [2]: https://generadordni.es/ + Examples: >>> es_cif('B25162520') - True - + # Output: True >>> es_cif('B25162529') - ValidationFailure(func=es_cif, args=...) + # Output: ValidationError(func=es_cif, args=...) - .. versionadded:: 0.13.0 + Args: + value: + DOI string which is to be validated. - :param doi: DOI to validate - """ - doi = doi.upper() + Returns: + (Literal[True]): + If `value` is a valid DOI string. + (ValidationError): + If `value` is an invalid DOI string. - if len(doi) != 9: + > *New in version 0.13.0*. + """ + if not value or len(value) != 9: return False - - table = 'JABCDEFGHI' - first_chr = doi[0] - doi_body = doi[1:8] - control = doi[8] - + value = value.upper() + table = "JABCDEFGHI" + first_chr = value[0] + doi_body = value[1:8] + control = value[8] if not doi_body.isdigit(): return False - - odd_result = 0 - even_result = 0 - for index, char in enumerate(doi_body): - if index % 2 == 0: - # Multiply each each odd position doi digit by 2 and sum it all - # together - odd_result += sum(map(int, str(int(char) * 2))) - else: - even_result += int(char) - - res = (10 - (even_result + odd_result) % 10) % 10 - - if first_chr in 'ABEH': # Number type + res = ( + 10 + - sum( + # Multiply each positionally even doi + # digit by 2 and sum it all together + sum(map(int, str(int(char) * 2))) if index % 2 == 0 else int(char) + for index, char in enumerate(doi_body) + ) + % 10 + ) % 10 + if first_chr in "ABEH": # Number type return str(res) == control - elif first_chr in 'PSQW': # Letter type + if first_chr in "PSQW": # Letter type return table[res] == control - elif first_chr not in 'CDFGJNRUV': - return False - - return control == str(res) or control == table[res] + return control in {str(res), table[res]} if first_chr in "CDFGJNRUV" else False @validator -def es_nif(doi): - """ - Validate a Spanish NIF. +def es_nif(value: str, /): + """Validate a Spanish NIF. Each entity, be it person or company in Spain has a distinct NIF. Since we've designated CIF to be a company NIF, this NIF is only for person. - For more information see `wikipedia.org/nif`_. - - This validator is based on `generadordni.es`_. - - .. _generadordni.es: - https://generadordni.es/ + For more information see [wikipedia.org/nif][1]. This validator + is based on [generadordni.es][2]. - .. _wikipedia.org/nif: - https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal - - Examples:: + [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal + [2]: https://generadordni.es/ + Examples: >>> es_nif('26643189N') - True - + # Output: True >>> es_nif('26643189X') - ValidationFailure(func=es_nif, args=...) + # Output: ValidationError(func=es_nif, args=...) - .. versionadded:: 0.13.0 + Args: + value: + DOI string which is to be validated. - :param doi: DOI to validate - """ - number_by_letter = {'L': '0', 'M': '0', 'K': '0'} - special_cases = ['X0000000T', '00000000T', '00000001R'] - return nif_nie_validation(doi, number_by_letter, special_cases) + Returns: + (Literal[True]): + If `value` is a valid DOI string. + (ValidationError): + If `value` is an invalid DOI string. - -@validator -def es_nie(doi): + > *New in version 0.13.0*. """ - Validate a Spanish NIE. - - The NIE is a tax identification number in Spain, known in Spanish as the - NIE, or more formally the Número de identidad de extranjero. For more - information see `wikipedia.org/nie`_. + number_by_letter = {"L": "0", "M": "0", "K": "0"} + special_cases = {"X0000000T", "00000000T", "00000001R"} + return _nif_nie_validation(value, number_by_letter, special_cases) - This validator is based on `generadordni.es`_. - .. _generadordni.es: - https://generadordni.es/ +@validator +def es_nie(value: str, /): + """Validate a Spanish NIE. - .. _wikipedia.org/nie: - https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero + The NIE is a tax identification number in Spain, known in Spanish + as the NIE, or more formally the Número de identidad de extranjero. + For more information see [wikipedia.org/nie][1]. This validator + is based on [generadordni.es][2]. - Examples:: + [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero + [2]: https://generadordni.es/ + Examples: >>> es_nie('X0095892M') - True - + # Output: True >>> es_nie('X0095892X') - ValidationFailure(func=es_nie, args=...) + # Output: ValidationError(func=es_nie, args=...) - .. versionadded:: 0.13.0 + Args: + value: + DOI string which is to be validated. - :param doi: DOI to validate - """ - number_by_letter = {'X': '0', 'Y': '1', 'Z': '2'} - special_cases = ['X0000000T'] + Returns: + (Literal[True]): + If `value` is a valid DOI string. + (ValidationError): + If `value` is an invalid DOI string. + > *New in version 0.13.0*. + """ + number_by_letter = {"X": "0", "Y": "1", "Z": "2"} # NIE must must start with X Y or Z - if not doi or doi[0] not in number_by_letter.keys(): - return False - - return nif_nie_validation(doi, number_by_letter, special_cases) + if value and value[0] in number_by_letter: + return _nif_nie_validation(value, number_by_letter, {"X0000000T"}) + return False @validator -def es_doi(doi): - """ - Validate a Spanish DOI. +def es_doi(value: str, /): + """Validate a Spanish DOI. - A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. For more - information see `wikipedia.org/doi`_. + A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. + For more information see [wikipedia.org/doi][1]. This validator + is based on [generadordni.es][2]. - This validator is based on `generadordni.es`_. - - .. _generadordni.es: - https://generadordni.es/ - - .. _wikipedia.org/doi: - https://es.wikipedia.org/wiki/Identificador_de_objeto_digital - - Examples:: + [1]: https://es.wikipedia.org/wiki/Identificador_de_objeto_digital + [2]: https://generadordni.es/ + Examples: >>> es_doi('X0095892M') - True - + # Output: True >>> es_doi('X0095892X') - ValidationFailure(func=es_doi, args=...) + # Output: ValidationError(func=es_doi, args=...) + + Args: + value: + DOI string which is to be validated. - .. versionadded:: 0.13.0 + Returns: + (Literal[True]): + If `value` is a valid DOI string. + (ValidationError): + If `value` is an invalid DOI string. - :param doi: DOI to validate + > *New in version 0.13.0*. """ - return es_nie(doi) or es_nif(doi) or es_cif(doi) + return es_nie(value) or es_nif(value) or es_cif(value) diff --git a/uno/lib/python/validators/i18n/fi.py b/uno/lib/python/validators/i18n/fi.py index 2e5eb578..68579362 100644 --- a/uno/lib/python/validators/i18n/fi.py +++ b/uno/lib/python/validators/i18n/fi.py @@ -1,94 +1,117 @@ +"""Finland.""" + +# standard +from functools import lru_cache import re +# local from validators.utils import validator -business_id_pattern = re.compile(r'^[0-9]{7}-[0-9]$') -ssn_checkmarks = '0123456789ABCDEFHJKLMNPRSTUVWXY' -ssn_pattern = re.compile( - r"""^ - (?P(0[1-9]|[1-2]\d|3[01]) - (0[1-9]|1[012]) - (\d{{2}})) - [A+-] - (?P(\d{{3}})) - (?P[{checkmarks}])$""".format(checkmarks=ssn_checkmarks), - re.VERBOSE -) + +@lru_cache +def _business_id_pattern(): + """Business ID Pattern.""" + return re.compile(r"^[0-9]{7}-[0-9]$") + + +@lru_cache +def _ssn_pattern(ssn_check_marks: str): + """SSN Pattern.""" + return re.compile( + r"""^ + (?P(0[1-9]|[1-2]\d|3[01]) + (0[1-9]|1[012]) + (\d{{2}})) + [ABCDEFYXWVU+-] + (?P(\d{{3}})) + (?P[{check_marks}])$""".format( + check_marks=ssn_check_marks + ), + re.VERBOSE, + ) @validator -def fi_business_id(business_id): - """ - Validate a Finnish Business ID. +def fi_business_id(value: str, /): + """Validate a Finnish Business ID. Each company in Finland has a distinct business id. For more - information see `Finnish Trade Register`_ + information see [Finnish Trade Register][1] - .. _Finnish Trade Register: - http://en.wikipedia.org/wiki/Finnish_Trade_Register - - Examples:: + [1]: http://en.wikipedia.org/wiki/Finnish_Trade_Register + Examples: >>> fi_business_id('0112038-9') # Fast Monkeys Ltd - True - + # Output: True >>> fi_business_id('1234567-8') # Bogus ID - ValidationFailure(func=fi_business_id, ...) + # Output: ValidationError(func=fi_business_id, ...) + + Args: + value: + Business ID string to be validated. + + Returns: + (Literal[True]): + If `value` is a valid finnish business id. + (ValidationError): + If `value` is an invalid finnish business id. - .. versionadded:: 0.4 - .. versionchanged:: 0.5 - Method renamed from ``finnish_business_id`` to ``fi_business_id`` + Note: + - *In version 0.5.0*: + - Function renamed from `finnish_business_id` to `fi_business_id` - :param business_id: business_id to validate + > *New in version 0.4.0*. """ - if not business_id or not re.match(business_id_pattern, business_id): + if not value: + return False + if not re.match(_business_id_pattern(), value): return False factors = [7, 9, 10, 5, 8, 4, 2] - numbers = map(int, business_id[:7]) - checksum = int(business_id[8]) - sum_ = sum(f * n for f, n in zip(factors, numbers)) - modulo = sum_ % 11 - return (11 - modulo == checksum) or (modulo == 0 and checksum == 0) + numbers = map(int, value[:7]) + checksum = int(value[8]) + modulo = sum(f * n for f, n in zip(factors, numbers)) % 11 + return (11 - modulo == checksum) or (modulo == checksum == 0) @validator -def fi_ssn(ssn, allow_temporal_ssn=True): - """ - Validate a Finnish Social Security Number. +def fi_ssn(value: str, /, *, allow_temporal_ssn: bool = True): + """Validate a Finnish Social Security Number. - This validator is based on `django-localflavor-fi`_. + This validator is based on [django-localflavor-fi][1]. - .. _django-localflavor-fi: - https://github.com/django/django-localflavor-fi/ - - Examples:: + [1]: https://github.com/django/django-localflavor-fi/ + Examples: >>> fi_ssn('010101-0101') - True - + # Output: True >>> fi_ssn('101010-0102') - ValidationFailure(func=fi_ssn, args=...) - - .. versionadded:: 0.5 - - :param ssn: Social Security Number to validate - :param allow_temporal_ssn: - Whether to accept temporal SSN numbers. Temporal SSN numbers are the - ones where the serial is in the range [900-999]. By default temporal - SSN numbers are valid. - + # Output: ValidationError(func=fi_ssn, args=...) + + Args: + value: + Social Security Number to be validated. + allow_temporal_ssn: + Whether to accept temporal SSN numbers. Temporal SSN numbers are the + ones where the serial is in the range [900-999]. By default temporal + SSN numbers are valid. + + Returns: + (Literal[True]): + If `value` is a valid finnish SSN. + (ValidationError): + If `value` is an invalid finnish SSN. + + > *New in version 0.5.0*. """ - if not ssn: + if not value: return False - - result = re.match(ssn_pattern, ssn) - if not result: + ssn_check_marks = "0123456789ABCDEFHJKLMNPRSTUVWXY" + if not (result := re.match(_ssn_pattern(ssn_check_marks), value)): return False gd = result.groupdict() - checksum = int(gd['date'] + gd['serial']) + checksum = int(gd["date"] + gd["serial"]) return ( - int(gd['serial']) >= 2 and - (allow_temporal_ssn or int(gd['serial']) <= 899) and - ssn_checkmarks[checksum % len(ssn_checkmarks)] == - gd['checksum'] + int(gd["serial"]) >= 2 + and (allow_temporal_ssn or int(gd["serial"]) <= 899) + and ssn_check_marks[checksum % len(ssn_check_marks)] == gd["checksum"] ) diff --git a/uno/lib/python/validators/iban.py b/uno/lib/python/validators/iban.py index 7413d127..ca75d0c3 100644 --- a/uno/lib/python/validators/iban.py +++ b/uno/lib/python/validators/iban.py @@ -1,52 +1,48 @@ +"""IBAN.""" + +# standard import re +# local from .utils import validator -regex = ( - r'^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$' -) -pattern = re.compile(regex) - -def char_value(char): - """A=10, B=11, ..., Z=35 - """ - if char.isdigit(): - return int(char) - else: - return 10 + ord(char) - ord('A') +def _char_value(char: str): + """A=10, B=11, ..., Z=35.""" + return char if char.isdigit() else str(10 + ord(char) - ord("A")) -def modcheck(value): - """Check if the value string passes the mod97-test. - """ +def _mod_check(value: str): + """Check if the value string passes the mod97-test.""" # move country code and check numbers to end rearranged = value[4:] + value[:4] - # convert letters to numbers - converted = [char_value(char) for char in rearranged] - # interpret as integer - integerized = int(''.join([str(i) for i in converted])) - return (integerized % 97 == 1) + return int("".join(_char_value(char) for char in rearranged)) % 97 == 1 @validator -def iban(value): - """ - Return whether or not given value is a valid IBAN code. - - If the value is a valid IBAN this function returns ``True``, otherwise - :class:`~validators.utils.ValidationFailure`. - - Examples:: +def iban(value: str, /): + """Return whether or not given value is a valid IBAN code. + Examples: >>> iban('DE29100500001061045672') - True - + # Output: True >>> iban('123456') - ValidationFailure(func=iban, ...) + # Output: ValidationError(func=iban, ...) + + Args: + value: + IBAN string to validate. - .. versionadded:: 0.8 + Returns: + (Literal[True]): + If `value` is a valid IBAN code. + (ValidationError): + If `value` is an invalid IBAN code. - :param value: IBAN string to validate + > *New in version 0.8.0* """ - return pattern.match(value) and modcheck(value) + return ( + (re.match(r"^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$", value) and _mod_check(value)) + if value + else False + ) diff --git a/uno/lib/python/validators/ip_address.py b/uno/lib/python/validators/ip_address.py index e0c061db..e6d01f65 100644 --- a/uno/lib/python/validators/ip_address.py +++ b/uno/lib/python/validators/ip_address.py @@ -1,156 +1,121 @@ +"""IP Address.""" + +# standard +from ipaddress import ( + AddressValueError, + IPv4Address, + IPv4Network, + IPv6Address, + IPv6Network, + NetmaskValueError, +) + +# local from .utils import validator @validator -def ipv4(value): - """ - Return whether a given value is a valid IP version 4 address. - - This validator is based on `WTForms IPAddress validator`_ +def ipv4(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bool = True): + """Returns whether a given value is a valid IPv4 address. - .. _WTForms IPAddress validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py + From Python version 3.9.5 leading zeros are no longer tolerated + and are treated as an error. The initial version of ipv4 validator + was inspired from [WTForms IPAddress validator][1]. - Examples:: + [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py + Examples: >>> ipv4('123.0.0.7') - True - + # Output: True + >>> ipv4('1.1.1.1/8') + # Output: True >>> ipv4('900.80.70.11') - ValidationFailure(func=ipv4, args={'value': '900.80.70.11'}) - - .. versionadded:: 0.2 - - :param value: IP address string to validate + # Output: ValidationError(func=ipv4, args={'value': '900.80.70.11'}) + + Args: + value: + IP address string to validate. + cidr: + IP address string may contain CIDR notation + strict: + IP address string is strictly in CIDR notation + host_bit: + If `False` and host bits (along with network bits) _are_ set in the supplied + address, this function raises a validation error. ref [IPv4Network][2]. + [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Network + + Returns: + (Literal[True]): + If `value` is a valid IPv4 address. + (ValidationError): + If `value` is an invalid IPv4 address. + + Note: + - *In version 0.14.0*: + - Add supports for CIDR notation + + > *New in version 0.2.0* """ - groups = value.split(".") - if ( - len(groups) != 4 - or any(not x.isdigit() for x in groups) - or any(len(x) > 3 for x in groups) - ): + if not value: return False - return all(0 <= int(part) < 256 for part in groups) - - -@validator -def ipv4_cidr(value): - """ - Return whether a given value is a valid CIDR-notated IP version 4 - address range. - - This validator is based on RFC4632 3.1. - - Examples:: - - >>> ipv4_cidr('1.1.1.1/8') - True - - >>> ipv4_cidr('1.1.1.1') - ValidationFailure(func=ipv4_cidr, args={'value': '1.1.1.1'}) - """ try: - prefix, suffix = value.split('/', 2) - except ValueError: + if cidr: + if strict and value.count("/") != 1: + raise ValueError("IPv4 address was expected in CIDR notation") + return IPv4Network(value, strict=not host_bit) + return IPv4Address(value) + except (ValueError, AddressValueError, NetmaskValueError): return False - if not ipv4(prefix) or not suffix.isdigit(): - return False - return 0 <= int(suffix) <= 32 @validator -def ipv6(value): - """ - Return whether a given value is a valid IP version 6 address - (including IPv4-mapped IPv6 addresses). +def ipv6(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bool = True): + """Returns if a given value is a valid IPv6 address. - This validator is based on `WTForms IPAddress validator`_. + Including IPv4-mapped IPv6 addresses. The initial version of ipv6 validator + was inspired from [WTForms IPAddress validator][1]. - .. _WTForms IPAddress validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py - - Examples:: - - >>> ipv6('abcd:ef::42:1') - True + [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py + Examples: >>> ipv6('::ffff:192.0.2.128') - True - - >>> ipv6('::192.0.2.128') - True - + # Output: True + >>> ipv6('::1/128') + # Output: True >>> ipv6('abc.0.0.1') - ValidationFailure(func=ipv6, args={'value': 'abc.0.0.1'}) - - .. versionadded:: 0.2 - - :param value: IP address string to validate + # Output: ValidationError(func=ipv6, args={'value': 'abc.0.0.1'}) + + Args: + value: + IP address string to validate. + cidr: + IP address string may contain CIDR annotation + strict: + IP address string is strictly in CIDR notation + host_bit: + If `False` and host bits (along with network bits) _are_ set in the supplied + address, this function raises a validation error. ref [IPv6Network][2]. + [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Network + + Returns: + (Literal[True]): + If `value` is a valid IPv6 address. + (ValidationError): + If `value` is an invalid IPv6 address. + + Note: + - *In version 0.14.0*: + - Add supports for CIDR notation + + > *New in version 0.2.0* """ - ipv6_groups = value.split(':') - if len(ipv6_groups) == 1: + if not value: return False - ipv4_groups = ipv6_groups[-1].split('.') - - if len(ipv4_groups) > 1: - if not ipv4(ipv6_groups[-1]): - return False - ipv6_groups = ipv6_groups[:-1] - else: - ipv4_groups = [] - - count_blank = 0 - for part in ipv6_groups: - if not part: - count_blank += 1 - continue - try: - num = int(part, 16) - except ValueError: - return False - else: - if not 0 <= num <= 65536 or len(part) > 4: - return False - - max_groups = 6 if ipv4_groups else 8 - part_count = len(ipv6_groups) - count_blank - if count_blank == 0 and part_count == max_groups: - # no :: -> must have size of max_groups - return True - elif count_blank == 1 and ipv6_groups[-1] and ipv6_groups[0] and part_count < max_groups: - # one :: inside the address or prefix or suffix : -> filter least two cases - return True - elif count_blank == 2 and part_count < max_groups and ( - ((ipv6_groups[0] and not ipv6_groups[-1]) or (not ipv6_groups[0] and ipv6_groups[-1])) or ipv4_groups): - # leading or trailing :: or : at end and begin -> filter last case - # Check if it has ipv4 groups because they get removed from the ipv6_groups - return True - elif count_blank == 3 and part_count == 0: - # :: is the address -> filter everything else - return True - return False - - -@validator -def ipv6_cidr(value): - """ - Returns whether a given value is a valid CIDR-notated IP version 6 - address range. - - This validator is based on RFC4632 3.1. - - Examples:: - - >>> ipv6_cidr('::1/128') - True - - >>> ipv6_cidr('::1') - ValidationFailure(func=ipv6_cidr, args={'value': '::1'}) - """ try: - prefix, suffix = value.split('/', 2) - except ValueError: - return False - if not ipv6(prefix) or not suffix.isdigit(): + if cidr: + if strict and value.count("/") != 1: + raise ValueError("IPv6 address was expected in CIDR notation") + return IPv6Network(value, strict=not host_bit) + return IPv6Address(value) + except (ValueError, AddressValueError, NetmaskValueError): return False - return 0 <= int(suffix) <= 128 diff --git a/uno/lib/python/validators/length.py b/uno/lib/python/validators/length.py index d0f91fd3..92a274d3 100644 --- a/uno/lib/python/validators/length.py +++ b/uno/lib/python/validators/length.py @@ -1,37 +1,38 @@ +"""Length.""" + +# local from .between import between from .utils import validator @validator -def length(value, min=None, max=None): - """ - Return whether or not the length of given string is within a specified - range. - - Examples:: - - >>> length('something', min=2) - True - - >>> length('something', min=9, max=9) - True - - >>> length('something', max=5) - ValidationFailure(func=length, ...) - - :param value: - The string to validate. - :param min: - The minimum required length of the string. If not provided, minimum - length will not be checked. - :param max: - The maximum length of the string. If not provided, maximum length - will not be checked. - - .. versionadded:: 0.2 +def length(value: str, /, *, min_val: int = 0, max_val: int = 0): + """Return whether or not the length of given string is within a specified range. + + Examples: + >>> length('something', min_val=2) + # Output: True + >>> length('something', min_val=9, max_val=9) + # Output: True + >>> length('something', max_val=5) + # Output: ValidationError(func=length, ...) + + Args: + value: + The string to validate. + min_val: + The minimum required length of the string. If not provided, + minimum length will not be checked. + max_val: + The maximum length of the string. If not provided, + maximum length will not be checked. + + Returns: + (Literal[True]): + If `len(value)` is in between the given conditions. + (ValidationError): + If `len(value)` is not in between the given conditions. + + > *New in version 0.2.0*. """ - if (min is not None and min < 0) or (max is not None and max < 0): - raise AssertionError( - '`min` and `max` need to be greater than zero.' - ) - return between(len(value), min=min, max=max) + return between(len(value), min_val=min_val, max_val=max_val) if value else False diff --git a/uno/lib/python/validators/mac_address.py b/uno/lib/python/validators/mac_address.py index bdb19947..e58d13c9 100644 --- a/uno/lib/python/validators/mac_address.py +++ b/uno/lib/python/validators/mac_address.py @@ -1,33 +1,36 @@ +"""MAC Address.""" + +# standard import re +# local from .utils import validator -pattern = re.compile(r'^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$') - @validator -def mac_address(value): - """ - Return whether or not given value is a valid MAC address. - - If the value is valid MAC address this function returns ``True``, - otherwise :class:`~validators.utils.ValidationFailure`. +def mac_address(value: str, /): + """Return whether or not given value is a valid MAC address. - This validator is based on `WTForms MacAddress validator`_. + This validator is based on [WTForms MacAddress validator][1]. - .. _WTForms MacAddress validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py - - Examples:: + [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L482 + Examples: >>> mac_address('01:23:45:67:ab:CD') - True - + # Output: True >>> mac_address('00:00:00:00:00') - ValidationFailure(func=mac_address, args={'value': '00:00:00:00:00'}) + # Output: ValidationError(func=mac_address, args={'value': '00:00:00:00:00'}) + + Args: + value: + MAC address string to validate. - .. versionadded:: 0.2 + Returns: + (Literal[True]): + If `value` is a valid MAC address. + (ValidationError): + If `value` is an invalid MAC address. - :param value: Mac address string to validate + > *New in version 0.2.0*. """ - return pattern.match(value) + return re.match(r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", value) if value else False diff --git a/uno/lib/python/validators/slug.py b/uno/lib/python/validators/slug.py index 83bfd4b1..4373dbd7 100644 --- a/uno/lib/python/validators/slug.py +++ b/uno/lib/python/validators/slug.py @@ -1,28 +1,35 @@ +"""Slug.""" + +# standard import re +# local from .utils import validator -slug_regex = re.compile(r'^[-a-zA-Z0-9_]+$') - @validator -def slug(value): - """ - Validate whether or not given value is valid slug. +def slug(value: str, /): + """Validate whether or not given value is valid slug. - Valid slug can contain only alphanumeric characters, hyphens and - underscores. - - Examples:: + Valid slug can contain only lowercase alphanumeric characters and hyphens. + It starts and ends with these lowercase alphanumeric characters. + Examples: + >>> slug('my-slug-2134') + # Output: True >>> slug('my.slug') - ValidationFailure(func=slug, args={'value': 'my.slug'}) + # Output: ValidationError(func=slug, args={'value': 'my.slug'}) - >>> slug('my-slug-2134') - True + Args: + value: + Slug string to validate. - .. versionadded:: 0.6 + Returns: + (Literal[True]): + If `value` is a valid slug. + (ValidationError): + If `value` is an invalid slug. - :param value: value to validate + > *New in version 0.6.0*. """ - return slug_regex.match(value) + return re.match(r"^[a-z0-9]+(?:-[a-z0-9]+)*$", value) if value else False diff --git a/uno/lib/python/validators/truthy.py b/uno/lib/python/validators/truthy.py deleted file mode 100644 index 517149aa..00000000 --- a/uno/lib/python/validators/truthy.py +++ /dev/null @@ -1,39 +0,0 @@ -from .utils import validator - - -@validator -def truthy(value): - """ - Validate that given value is not a falsey value. - - This validator is based on `WTForms DataRequired validator`_. - - .. _WTForms DataRequired validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py - - Examples:: - - >>> truthy(1) - True - - >>> truthy('someone') - True - - >>> truthy(0) - ValidationFailure(func=truthy, args={'value': 0}) - - >>> truthy(' ') - ValidationFailure(func=truthy, args={'value': ' '}) - - >>> truthy(False) - ValidationFailure(func=truthy, args={'value': False}) - - >>> truthy(None) - ValidationFailure(func=truthy, args={'value': None}) - - .. versionadded:: 0.2 - """ - return ( - value and - (not isinstance(value, str) or value.strip()) - ) diff --git a/uno/lib/python/validators/url.py b/uno/lib/python/validators/url.py index 37d946cb..16698b1f 100644 --- a/uno/lib/python/validators/url.py +++ b/uno/lib/python/validators/url.py @@ -1,154 +1,218 @@ +"""URL.""" + +# standard +from functools import lru_cache import re +from urllib.parse import unquote, urlsplit +# local +from .hostname import hostname from .utils import validator -ip_middle_octet = r"(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5]))" -ip_last_octet = r"(?:\.(?:0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5]))" - -regex = re.compile( # noqa: W605 - r"^" - # protocol identifier - r"(?:(?:https?|ftp)://)" - # user:pass authentication - r"(?:[-a-z\u00a1-\uffff0-9._~%!$&'()*+,;=:]+" - r"(?::[-a-z0-9._~%!$&'()*+,;=:]*)?@)?" - r"(?:" - r"(?P" - # IP address exclusion - # private & local networks - r"(?:(?:10|127)" + ip_middle_octet + r"{2}" + ip_last_octet + r")|" - r"(?:(?:169\.254|192\.168)" + ip_middle_octet + ip_last_octet + r")|" - r"(?:172\.(?:1[6-9]|2\d|3[0-1])" + ip_middle_octet + ip_last_octet + r"))" - r"|" - # private & local hosts - r"(?P" - r"(?:localhost))" - r"|" - # IP address dotted notation octets - # excludes loopback network 0.0.0.0 - # excludes reserved space >= 224.0.0.0 - # excludes network & broadcast addresses - # (first & last IP address of each class) - r"(?P" - r"(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])" - r"" + ip_middle_octet + r"{2}" - r"" + ip_last_octet + r")" - r"|" - # IPv6 RegEx from https://stackoverflow.com/a/17871737 - r"\[(" - # 1:2:3:4:5:6:7:8 - r"([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" - # 1:: 1:2:3:4:5:6:7:: - r"([0-9a-fA-F]{1,4}:){1,7}:|" - # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8 - r"([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" - # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8 - r"([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" - # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8 - r"([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" - # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8 - r"([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" - # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8 - r"([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" - # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8 - r"[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" - # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 :: - r":((:[0-9a-fA-F]{1,4}){1,7}|:)|" - # fe80::7:8%eth0 fe80::7:8%1 - # (link-local IPv6 addresses with zone index) - r"fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|" - r"::(ffff(:0{1,4}){0,1}:){0,1}" - r"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}" - # ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 - # (IPv4-mapped IPv6 addresses and IPv4-translated addresses) - r"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|" - r"([0-9a-fA-F]{1,4}:){1,4}:" - r"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}" - # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 - # (IPv4-Embedded IPv6 Address) - r"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])" - r")\]|" - # host name - r"(?:(?:(?:xn--[-]{0,2})|[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]-?)*" - r"[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]+)" - # domain name - r"(?:\.(?:(?:xn--[-]{0,2})|[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]-?)*" - r"[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]+)*" - # TLD identifier - r"(?:\.(?:(?:xn--[-]{0,2}[a-z\u00a1-\uffff\U00010000-\U0010ffff0-9]{2,})|" - r"[a-z\u00a1-\uffff\U00010000-\U0010ffff]{2,}))" - r")" - # port number - r"(?::\d{2,5})?" - # resource path - r"(?:/[-a-z\u00a1-\uffff\U00010000-\U0010ffff0-9._~%!$&'()*+,;=:@/]*)?" - # query string - r"(?:\?\S*)?" - # fragment - r"(?:#\S*)?" - r"$", - re.UNICODE | re.IGNORECASE -) - -pattern = re.compile(regex) - - -@validator -def url(value, public=False): - """ - Return whether or not given value is a valid URL. - - If the value is valid URL this function returns ``True``, otherwise - :class:`~validators.utils.ValidationFailure`. - This validator is based on the wonderful `URL validator of dperini`_. - - .. _URL validator of dperini: - https://gist.github.com/dperini/729294 - - Examples:: - - >>> url('http://foobar.dk') - True - - >>> url('ftp://foobar.dk') - True - - >>> url('http://10.0.0.1') - True +@lru_cache +def _username_regex(): + return re.compile( + # dot-atom + r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" + # non-quoted-string + + r"|^([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*$)", + re.IGNORECASE, + ) - >>> url('http://foobar.d') - ValidationFailure(func=url, ...) - >>> url('http://10.0.0.1', public=True) - ValidationFailure(func=url, ...) +@lru_cache +def _path_regex(): + return re.compile( + # allowed symbols + r"^[\/a-zA-Z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\@\%" + # emoticons / emoji + + r"\U0001F600-\U0001F64F" + # multilingual unicode ranges + + r"\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$", + re.IGNORECASE, + ) - .. versionadded:: 0.2 - .. versionchanged:: 0.10.2 +@lru_cache +def _query_regex(): + return re.compile(r"&?(\w+=?[^\s&]*)", re.IGNORECASE) - Added support for various exotic URLs and fixed various false - positives. - .. versionchanged:: 0.10.3 +def _validate_scheme(value: str): + """Validate scheme.""" + # More schemes will be considered later. + return ( + value in {"ftp", "ftps", "git", "http", "https", "rtsp", "sftp", "ssh", "telnet"} + if value + else False + ) - Added ``public`` parameter. - .. versionchanged:: 0.11.0 +def _confirm_ipv6_skip(value: str, skip_ipv6_addr: bool): + """Confirm skip IPv6 check.""" + return skip_ipv6_addr or value.count(":") < 2 or not value.startswith("[") + + +def _validate_auth_segment(value: str): + """Validate authentication segment.""" + if not value: + return True + if (colon_count := value.count(":")) > 1: + # everything before @ is then considered as a username + # this is a bad practice, but syntactically valid URL + return _username_regex().match(unquote(value)) + if colon_count < 1: + return _username_regex().match(value) + username, password = value.rsplit(":", 1) + return _username_regex().match(username) and all( + char_to_avoid not in password for char_to_avoid in ("/", "?", "#", "@") + ) - Made the regular expression this function uses case insensitive. - .. versionchanged:: 0.11.3 +def _validate_netloc( + value: str, + skip_ipv6_addr: bool, + skip_ipv4_addr: bool, + may_have_port: bool, + simple_host: bool, + rfc_1034: bool, + rfc_2782: bool, +): + """Validate netloc.""" + if not value or value.count("@") > 1: + return False + if value.count("@") < 1: + return hostname( + value + if _confirm_ipv6_skip(value, skip_ipv6_addr) or "]:" in value + else value.lstrip("[").replace("]", "", 1), + skip_ipv6_addr=_confirm_ipv6_skip(value, skip_ipv6_addr), + skip_ipv4_addr=skip_ipv4_addr, + may_have_port=may_have_port, + maybe_simple=simple_host, + rfc_1034=rfc_1034, + rfc_2782=rfc_2782, + ) + basic_auth, host = value.rsplit("@", 1) + return hostname( + host + if _confirm_ipv6_skip(host, skip_ipv6_addr) or "]:" in value + else host.lstrip("[").replace("]", "", 1), + skip_ipv6_addr=_confirm_ipv6_skip(host, skip_ipv6_addr), + skip_ipv4_addr=skip_ipv4_addr, + may_have_port=may_have_port, + maybe_simple=simple_host, + rfc_1034=rfc_1034, + rfc_2782=rfc_2782, + ) and _validate_auth_segment(basic_auth) + + +def _validate_optionals(path: str, query: str, fragment: str): + """Validate path query and fragments.""" + optional_segments = True + if path: + optional_segments &= bool(_path_regex().match(path)) + if query: + optional_segments &= bool(_query_regex().match(query)) + if fragment: + fragment = fragment.lstrip("/") if fragment.startswith("/") else fragment + optional_segments &= all(char_to_avoid not in fragment for char_to_avoid in ("/", "?")) + return optional_segments - Added support for URLs containing localhost - :param value: URL address string to validate - :param public: (default=False) Set True to only allow a public IP address +@validator +def url( + value: str, + /, + *, + skip_ipv6_addr: bool = False, + skip_ipv4_addr: bool = False, + may_have_port: bool = True, + simple_host: bool = False, + rfc_1034: bool = False, + rfc_2782: bool = False, +): + r"""Return whether or not given value is a valid URL. + + This validator was inspired from [URL validator of dperini][1]. + The following diagram is from [urlly][2]. + + foo://admin:hunter1@example.com:8042/over/there?name=ferret#nose + \_/ \___/ \_____/ \_________/ \__/\_________/ \_________/ \__/ + | | | | | | | | + scheme username password hostname port path query fragment + + [1]: https://gist.github.com/dperini/729294 + [2]: https://github.com/treeform/urlly + + Examples: + >>> url('http://duck.com') + # Output: True + >>> url('ftp://foobar.dk') + # Output: True + >>> url('http://10.0.0.1') + # Output: True + >>> url('http://example.com/">user@example.com') + # Output: ValidationError(func=url, ...) + + Args: + value: + URL string to validate. + skip_ipv6_addr: + When URL string cannot contain an IPv6 address. + skip_ipv4_addr: + When URL string cannot contain an IPv4 address. + may_have_port: + URL string may contain port number. + simple_host: + URL string maybe only hyphens and alpha-numerals. + rfc_1034: + Allow trailing dot in domain/host name. + Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). + rfc_2782: + Domain/Host name is of type service record. + Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). + + Returns: + (Literal[True]): + If `value` is a valid slug. + (ValidationError): + If `value` is an invalid slug. + + Note: + - *In version 0.11.3*: + - Added support for URLs containing localhost. + - *In version 0.11.0*: + - Made the regular expression case insensitive. + - *In version 0.10.3*: + - Added a `public` parameter. + - *In version 0.10.2*: + - Added support for various exotic URLs. + - Fixed various false positives. + + > *New in version 0.2.0*. """ - result = pattern.match(value) - if not public: - return result - - return result and not any( - (result.groupdict().get(key) for key in ('private_ip', 'private_host')) + if not value or re.search(r"\s", value): + # url must not contain any white + # spaces, they must be encoded + return False + + try: + scheme, netloc, path, query, fragment = urlsplit(value) + except ValueError: + return False + + return ( + _validate_scheme(scheme) + and _validate_netloc( + netloc, + skip_ipv6_addr, + skip_ipv4_addr, + may_have_port, + simple_host, + rfc_1034, + rfc_2782, + ) + and _validate_optionals(path, query, fragment) ) diff --git a/uno/lib/python/validators/utils.py b/uno/lib/python/validators/utils.py index 3044477b..3ecaac5f 100644 --- a/uno/lib/python/validators/utils.py +++ b/uno/lib/python/validators/utils.py @@ -1,85 +1,82 @@ -import inspect -import itertools -from collections import OrderedDict +"""Utils.""" -from decorator import decorator +# standard +from functools import wraps +from inspect import getfullargspec +from itertools import chain +from typing import Any, Callable, Dict -class ValidationFailure(Exception): - def __init__(self, func, args): - self.func = func - self.__dict__.update(args) +class ValidationError(Exception): + """Exception class when validation failure occurs.""" + + def __init__(self, function: Callable[..., Any], arg_dict: Dict[str, Any], message: str = ""): + """Initialize Validation Failure.""" + if message: + self.reason = message + self.func = function + self.__dict__.update(arg_dict) def __repr__(self): - return u'ValidationFailure(func={func}, args={args})'.format( - func=self.func.__name__, - args=dict( - [(k, v) for (k, v) in self.__dict__.items() if k != 'func'] - ) + """Repr Validation Failure.""" + return ( + f"ValidationError(func={self.func.__name__}, " + + f"args={({k: v for (k, v) in self.__dict__.items() if k != 'func'})})" ) def __str__(self): - return repr(self) - - def __unicode__(self): + """Str Validation Failure.""" return repr(self) def __bool__(self): - return False - - def __nonzero__(self): + """Bool Validation Failure.""" return False -def func_args_as_dict(func, args, kwargs): - """ - Return given function's positional and key value arguments as an ordered - dictionary. - """ - _getargspec = inspect.getfullargspec - - arg_names = list( - OrderedDict.fromkeys( - itertools.chain( - _getargspec(func)[0], - kwargs.keys() - ) - ) - ) - return OrderedDict( - list(zip(arg_names, args)) + - list(kwargs.items()) +def _func_args_as_dict(func: Callable[..., Any], *args: Any, **kwargs: Any): + """Return function's positional and key value arguments as an ordered dictionary.""" + return dict( + list(zip(dict.fromkeys(chain(getfullargspec(func)[0], kwargs.keys())), args)) + + list(kwargs.items()) ) -def validator(func, *args, **kwargs): - """ - A decorator that makes given function validator. +def validator(func: Callable[..., Any]): + """A decorator that makes given function validator. - Whenever the given function is called and returns ``False`` value - this decorator returns :class:`ValidationFailure` object. - - Example:: + Whenever the given `func` returns `False` this + decorator returns `ValidationError` object. + Examples: >>> @validator ... def even(value): ... return not (value % 2) - >>> even(4) - True - + # Output: True >>> even(5) - ValidationFailure(func=even, args={'value': 5}) + # Output: ValidationError(func=even, args={'value': 5}) + + Args: + func: + Function which is to be decorated. + + Returns: + (Callable[..., ValidationError | Literal[True]]): + A decorator which returns either `ValidationError` + or `Literal[True]`. - :param func: function to decorate - :param args: positional function arguments - :param kwargs: key value function arguments + > *New in version 2013.10.21*. """ - def wrapper(func, *args, **kwargs): - value = func(*args, **kwargs) - if not value: - return ValidationFailure( - func, func_args_as_dict(func, args, kwargs) + + @wraps(func) + def wrapper(*args: Any, **kwargs: Any): + try: + return ( + True + if func(*args, **kwargs) + else ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) ) - return True - return decorator(wrapper, func) + except Exception as exp: + return ValidationError(func, _func_args_as_dict(func, *args, **kwargs), str(exp)) + + return wrapper diff --git a/uno/lib/python/validators/uuid.py b/uno/lib/python/validators/uuid.py index 20080088..dd981363 100644 --- a/uno/lib/python/validators/uuid.py +++ b/uno/lib/python/validators/uuid.py @@ -1,41 +1,47 @@ -from __future__ import absolute_import +"""UUID.""" +# standard import re +from typing import Union from uuid import UUID +# local from .utils import validator -pattern = re.compile(r'^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') - @validator -def uuid(value): - """ - Return whether or not given value is a valid UUID. - - If the value is valid UUID this function returns ``True``, otherwise - :class:`~validators.utils.ValidationFailure`. - - This validator is based on `WTForms UUID validator`_. +def uuid(value: Union[str, UUID], /): + """Return whether or not given value is a valid UUID-v4 string. - .. _WTForms UUID validator: - https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py + This validator is based on [WTForms UUID validator][1]. - Examples:: + [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L539 + Examples: >>> uuid('2bc1c94f-0deb-43e9-92a1-4775189ec9f8') - True - + # Output: True >>> uuid('2bc1c94f 0deb-43e9-92a1-4775189ec9f8') - ValidationFailure(func=uuid, ...) + # Output: ValidationError(func=uuid, ...) + + Args: + value: + UUID string or object to validate. - .. versionadded:: 0.2 + Returns: + (Literal[True]): + If `value` is a valid UUID. + (ValidationError): + If `value` is an invalid UUID. - :param value: UUID value to validate + > *New in version 0.2.0*. """ + if not value: + return False if isinstance(value, UUID): return True try: - return pattern.match(value) - except TypeError: + return UUID(value) or re.match( + r"^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$", value + ) + except ValueError: return False diff --git a/uno/lib/uno/jdbcdriver/configuration.py b/uno/lib/uno/jdbcdriver/configuration.py index 58601e12..a5a4517a 100644 --- a/uno/lib/uno/jdbcdriver/configuration.py +++ b/uno/lib/uno/jdbcdriver/configuration.py @@ -31,7 +31,7 @@ g_extension = 'jdbcDriverOOo' g_identifier = 'io.github.prrvchr.%s' % g_extension g_service = '%s.Driver' % g_identifier -g_version = '1.0.7' +g_version = '1.0.8' # jdbcDriverOOo resource strings files and folder g_resource = 'resource' diff --git a/uno/lib/uno/logger/dialog/__init__.py b/uno/lib/uno/logger/dialog/__init__.py index cfd0bf07..efb514ee 100644 --- a/uno/lib/uno/logger/dialog/__init__.py +++ b/uno/lib/uno/logger/dialog/__init__.py @@ -29,5 +29,5 @@ from .logmanager import LogManager -from .loglistener import LoggerListener +from .loghandler import LoggerListener diff --git a/uno/lib/uno/logger/dialog/loghandler.py b/uno/lib/uno/logger/dialog/loghandler.py index c3ed5ff7..41f0d14a 100644 --- a/uno/lib/uno/logger/dialog/loghandler.py +++ b/uno/lib/uno/logger/dialog/loghandler.py @@ -69,7 +69,7 @@ def callHandlerMethod(self, dialog, event, method): handled = True return handled except Exception as e: - msg = "Error: %s" % traceback.format_exc() + msg = f"Error: {traceback.format_exc()}" print(msg) def getSupportedMethodNames(self): @@ -95,43 +95,42 @@ def callHandlerMethod(self, dialog, event, method): handled = True return handled except Exception as e: - msg = "Error: %s" % traceback.format_exc() + msg = f"Error: {traceback.format_exc()}" print(msg) def getSupportedMethodNames(self): return ('LogInfo', ) -class PoolListener(unohelper.Base, - XModifyListener): +class LoggerListener(unohelper.Base, + XModifyListener): def __init__(self, manager): self._manager = manager # XModifyListener def modified(self, event): try: - print("PoolListener.modified()") - self._manager.updateLoggers() + self._manager.updateLogger() except Exception as e: - msg = "Error: %s" % traceback.format_exc() + msg = f"Error: {traceback.format_exc()}" print(msg) def disposing(self, event): pass -class LoggerListener(unohelper.Base, - XModifyListener): +class PoolListener(unohelper.Base, + XModifyListener): def __init__(self, manager): self._manager = manager # XModifyListener def modified(self, event): try: - print("LoggerListener.modified()") - self._manager.updateLogger() + print("PoolListener.modified()") + self._manager.updateLoggers() except Exception as e: - msg = "Error: %s" % traceback.format_exc() + msg = f"Error: {traceback.format_exc()}" print(msg) def disposing(self, event): diff --git a/uno/lib/uno/logger/dialog/loglistener.py b/uno/lib/uno/logger/dialog/loglistener.py deleted file mode 100644 index 91470b68..00000000 --- a/uno/lib/uno/logger/dialog/loglistener.py +++ /dev/null @@ -1,71 +0,0 @@ -#! -# -*- coding: utf-8 -*- - -""" -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020 https://prrvchr.github.io ║ -║ ║ -║ Permission is hereby granted, free of charge, to any person obtaining ║ -║ a copy of this software and associated documentation files (the "Software"), ║ -║ to deal in the Software without restriction, including without limitation ║ -║ the rights to use, copy, modify, merge, publish, distribute, sublicense, ║ -║ and/or sell copies of the Software, and to permit persons to whom the Software ║ -║ is furnished to do so, subject to the following conditions: ║ -║ ║ -║ The above copyright notice and this permission notice shall be included in ║ -║ all copies or substantial portions of the Software. ║ -║ ║ -║ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ║ -║ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ║ -║ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ║ -║ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ║ -║ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ║ -║ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE ║ -║ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -""" - -import unohelper - -from com.sun.star.util import XModifyListener - -import traceback - - -class PoolListener(unohelper.Base, - XModifyListener): - def __init__(self, manager): - self._manager = manager - - # XModifyListener - def modified(self, event): - try: - print("PoolListener.modified()") - self._manager.updateLoggers() - except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) - - def disposing(self, event): - pass - - -class LoggerListener(unohelper.Base, - XModifyListener): - def __init__(self, manager): - self._manager = manager - - # XModifyListener - def modified(self, event): - try: - print("LoggerListener.modified()") - self._manager.updateLogger() - except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) - - def disposing(self, event): - pass - diff --git a/uno/lib/uno/logger/dialog/logmanager.py b/uno/lib/uno/logger/dialog/logmanager.py index ded21ca6..b6a2e231 100644 --- a/uno/lib/uno/logger/dialog/logmanager.py +++ b/uno/lib/uno/logger/dialog/logmanager.py @@ -40,9 +40,8 @@ from .loghandler import WindowHandler from .loghandler import DialogHandler - -from .loglistener import PoolListener -from .loglistener import LoggerListener +from .loghandler import LoggerListener +from .loghandler import PoolListener from ..loghelper import getLoggerName @@ -58,7 +57,7 @@ class LogManager(unohelper.Base): def __init__(self, ctx, parent, infos, filter, *defaults): self._ctx = ctx - self._model = LogModel(ctx, PoolListener(self), *defaults) + self._model = LogModel(ctx, PoolListener(self), defaults) self._view = LogWindow(ctx, WindowHandler(self), parent) self._infos = infos self._filter = filter @@ -87,7 +86,7 @@ def loadSetting(self): self.disableHandler() self._view.setLogSetting(self._model.loadSetting()) - # LogManager setter methods called by PoolListener + # LogManager setter methods called by LoggerListener def updateLoggers(self): logger = self._view.getLogger() loggers = self._model.getLoggerNames(self._filter) diff --git a/uno/lib/uno/logger/dialog/logmodel.py b/uno/lib/uno/logger/dialog/logmodel.py index b197791c..2d3bfca7 100644 --- a/uno/lib/uno/logger/dialog/logmodel.py +++ b/uno/lib/uno/logger/dialog/logmodel.py @@ -49,7 +49,7 @@ class LogModel(LogController): - def __init__(self, ctx, listener, *names): + def __init__(self, ctx, listener, names): self._ctx = ctx self._basename = g_basename self._pool = LoggerPool(ctx) diff --git a/uno/lib/uno/logger/logger.py b/uno/lib/uno/logger/logger.py index cc0800ee..585177fe 100644 --- a/uno/lib/uno/logger/logger.py +++ b/uno/lib/uno/logger/logger.py @@ -78,11 +78,11 @@ def hasEntryForId(self, resource): return False return self._resolver.hasEntryForId(resource) - def resolveString(self, resource, args): + def resolveString(self, resource, arguments): if self.hasEntryForId(resource): msg = self._resolver.resolveString(resource) - if args: - msg = msg % args + if arguments: + msg = msg.format(*arguments) else: msg = resource return msg diff --git a/uno/lib/uno/logger/loggerpool.py b/uno/lib/uno/logger/loggerpool.py index a0b1abba..16e049e4 100644 --- a/uno/lib/uno/logger/loggerpool.py +++ b/uno/lib/uno/logger/loggerpool.py @@ -98,7 +98,6 @@ def _getNamedLogger(self, name): toadd = name not in LoggerPool._loggers if toadd: LoggerPool._loggers[name] = [] - print("LoggerPool._getNamedLogger() %s" % name) logger = self._pool.getNamedLogger(name) if toadd: self._notifyListener() diff --git a/uno/lib/uno/logger/loghelper.py b/uno/lib/uno/logger/loghelper.py index 6b1d6826..989b3cda 100644 --- a/uno/lib/uno/logger/loghelper.py +++ b/uno/lib/uno/logger/loghelper.py @@ -39,6 +39,7 @@ from .loggerpool import LoggerPool +from ..unotool import checkVersion from ..unotool import createService from ..unotool import getConfiguration from ..unotool import getFileSequence @@ -54,6 +55,8 @@ from ..configuration import g_defaultlog from ..configuration import g_basename +import importlib +import os, sys import traceback @@ -134,7 +137,7 @@ def _getErrorMessage(self, resource): return self._resolveErrorMessage(resolver, resource) def _resolveErrorMessage(self, resolver, resource): - return resolver.resolveString(151) % (resource, self._url, self._basename) + return resolver.resolveString(121).format(resource, self._url, self._basename) # This LogController allows using listener and access content of logger @@ -163,8 +166,32 @@ def dispose(self): self._logger.removeModifyListener(self._listener) def logInfos(self, level, infos, clazz, method): - for resource, info in infos.items(): - msg = self._resolver.resolveString(resource) % info + msg = self._resolver.resolveString(111).format(' '.join(sys.version.split())) + self._logger.logp(level, clazz, method, msg) + msg = self._resolver.resolveString(112).format(os.pathsep.join(sys.path)) + self._logger.logp(level, clazz, method, msg) + for name, info in infos.items(): + try: + mod = importlib.import_module(name) + except Exception as e: + msg = self._resolver.resolveString(113).format(name, e, traceback.format_exc()) + else: + attr, minimum = info + unknown = '' + path = getattr(mod, '__file__', unknown) + if not path: + path = unknown + if attr is None: + msg = self._resolver.resolveString(114).format(name, minimum, path) + elif hasattr(mod, attr): + version = getattr(mod, attr) + if minimum is None or checkVersion(version, minimum): + msg = self._resolver.resolveString(114).format(name, version, path) + else: + msg = self._resolver.resolveString(115).format(name, version, path, minimum) + else: + modattr = ', '.join(dir(mod)) + msg = self._resolver.resolveString(116).format(name, path, modattr) self._logger.logp(level, clazz, method, msg) def clearLogger(self): @@ -172,13 +199,11 @@ def clearLogger(self): sf = getSimpleFile(self._ctx) if sf.exists(url): sf.kill(url) - print("LogController.clearLogger() 1") - msg = self._resolver.resolveString(161) + msg = self._resolver.resolveString(131) handler = RollerHandler(self._ctx, self.Name) self.addRollerHandler(handler) self._logMessage(SEVERE, msg, 'Logger', 'clearLogger()') self.removeRollerHandler(handler) - print("LogController.clearLogger() 2") def addModifyListener(self, listener): self._logger.addModifyListener(listener) diff --git a/uno/lib/uno/oauth2/configuration.py b/uno/lib/uno/oauth2/configuration.py index da997e8a..e1a47e4b 100644 --- a/uno/lib/uno/oauth2/configuration.py +++ b/uno/lib/uno/oauth2/configuration.py @@ -31,7 +31,7 @@ g_extension = 'OAuth2OOo' g_identifier = 'io.github.prrvchr.%s' % g_extension g_service = '%s.OAuth2Service' % g_identifier -g_version = '1.2.3' +g_version = '1.2.4' g_oauth2 = g_service diff --git a/uno/lib/uno/options/ucb/optionsmanager.py b/uno/lib/uno/options/ucb/optionsmanager.py index c12808ff..2049d7aa 100644 --- a/uno/lib/uno/options/ucb/optionsmanager.py +++ b/uno/lib/uno/options/ucb/optionsmanager.py @@ -39,6 +39,7 @@ from ..configuration import g_identifier from ..configuration import g_defaultlog +from ..configuration import g_synclog from collections import OrderedDict import os @@ -54,7 +55,7 @@ def __init__(self, ctx, window): resumable = self._model.isResumable() data = self._model.getViewData() self._view = OptionsView(window, exist, resumable, data) - self._logger = LogManager(ctx, window.Peer, self._getInfos(), g_identifier, g_defaultlog) + self._logger = LogManager(ctx, window.Peer, self._getInfos(), g_identifier, g_defaultlog, g_synclog) def saveSetting(self): share, name, index, timeout, download, upload = self._view.getViewData() @@ -74,7 +75,7 @@ def enableTimeout(self, enabled): def viewData(self): url = self._model.getDatasourceUrl() - getDesktop(self._ctx).loadComponentFromURL(url, '_blank', 0, ()) + getDesktop(self._ctx).loadComponentFromURL(url, '_default', 0, ()) def download(self): self._view.setStep(1) @@ -84,17 +85,9 @@ def upload(self): def _getInfos(self): infos = OrderedDict() - version = ' '.join(sys.version.split()) - infos[111] = version - path = os.pathsep.join(sys.path) - infos[112] = path - # Required modules for ijson - try: - import ijson - except Exception as e: - infos[136] = self._getExceptionMsg(e) - else: - infos[137] = ijson.__version__, ijson.__file__ + infos['ijson'] = ('__version__', '3.2.2') + infos['packaging'] = ('__version__', '23.1') + infos['six'] = ('__version__', '1.16.0') return infos def _getExceptionMsg(self, e): diff --git a/uno/lib/uno/ucb/contentprovider.py b/uno/lib/uno/ucb/contentprovider.py index 858661e8..65b8ee2b 100644 --- a/uno/lib/uno/ucb/contentprovider.py +++ b/uno/lib/uno/ucb/contentprovider.py @@ -35,6 +35,8 @@ from com.sun.star.lang import XServiceInfo +from com.sun.star.sdbc import SQLException + from com.sun.star.ucb import XContentIdentifierFactory from com.sun.star.ucb import XContentProvider from com.sun.star.ucb import XParameterizedContentProvider @@ -47,9 +49,9 @@ from .datasource import DataSource from .unotool import checkVersion -from .unotool import createService +from .unotool import createMessageBox from .unotool import getExtensionVersion -from .unotool import parseUrl +from .unotool import getParentWindow from .dbtool import getConnectionUrl @@ -70,6 +72,7 @@ from .configuration import g_identifier from .configuration import g_defaultlog from .configuration import g_scheme +from .configuration import g_separator import traceback @@ -83,7 +86,6 @@ def __init__(self, ctx, logger, authority, arguments): self._authority = authority self._cls = '%sContentProvider' % arguments self._services = ('com.sun.star.ucb.ContentProvider', g_identifier + '.ContentProvider') - self._transformer = createService(ctx, 'com.sun.star.util.URLTransformer') self._logger = logger self._logger.logprb(INFO, self._cls, '__init__()', 201, arguments) @@ -97,34 +99,40 @@ def _datasource(self): # XContentIdentifierFactory def createContentIdentifier(self, url): - identifier = Identifier(self._getContentIdentifierUrl(url)) + identifier = Identifier(url) self._logger.logprb(INFO, self._cls, 'createContentIdentifier()', 211, url, identifier.getContentIdentifier()) return identifier # XContentProvider def queryContent(self, identifier): try: - print("ContentProvider.queryContent() 1 ******************************************") - content = self._datasource.queryContent(self, self._authority, identifier) + url = identifier.getContentIdentifier() + print("ContentProvider.queryContent() 1 url: %s **********************************" % url) + content = self._datasource.queryContent(self, self._authority, url) print("ContentProvider.queryContent() 2 ******************************************") - self._logger.logprb(INFO, self._cls, 'queryContent()', 231, identifier.getContentIdentifier()) + self._logger.logprb(INFO, self._cls, 'queryContent()', 231, url) return content except IllegalIdentifierException as e: + print("ContentProvider.queryContent() 3 ******************************************") self._logger.logprb(INFO, self._cls, 'queryContent()', 232, e.Message) raise e except Exception as e: + print("ContentProvider.queryContent() 4 ******************************************") msg = self._logger.resolveString(233, traceback.format_exc()) self._logger.logp(SEVERE, self._cls, 'queryContent()', msg) print(msg) def compareContentIds(self, id1, id2): - url1, url2 = id1.getContentIdentifier(), id2.getContentIdentifier() - if url1 == url2: - self._logger.logprb(INFO, self._cls, 'compareContentIds()', 241, url1, url2) - compare = 0 - else: - self._logger.logprb(INFO, self._cls, 'compareContentIds()', 242, url1, url2) + uri1 = self._datasource.parseIdentifier(id1) + uri2 = self._datasource.parseIdentifier(id2) + auth1 = uri1.getAuthority() if uri1.hasAuthority() else self._datasource.getDefaultUser() + auth2 = uri2.getAuthority() if uri2.hasAuthority() else self._datasource.getDefaultUser() + if (auth1 != auth2 or uri1.getPath() != uri2.getPath()): + self._logger.logprb(INFO, self._cls, 'compareContentIds()', 242, uri1.getUriReference(), uri2.getUriReference()) compare = -1 + else: + self._logger.logprb(INFO, self._cls, 'compareContentIds()', 241, uri1.getUriReference(), uri2.getUriReference()) + compare = 0 return compare # XServiceInfo @@ -136,49 +144,43 @@ def getSupportedServiceNames(self): return self._services # Private methods - def _getContentIdentifierUrl(self, url): - # FIXME: Sometimes the url can end with a dot, it must be deleted - url = url.rstrip('.') - uri = parseUrl(self._transformer, url) - if uri is not None: - uri = self._transformer.getPresentation(uri, True) - return uri if uri else url - def _getDataSource(self): oauth2 = getOAuth2Version(self._ctx) driver = getExtensionVersion(self._ctx, g_jdbcid) if oauth2 is None: - self._logException(221, g_oauth2ext, ' ', g_extension) - raise self._getException(221, g_oauth2ext, '\n', g_extension) + msg = self._getExceptionMessage(221, g_oauth2ext, g_oauth2ext, g_extension) + raise IllegalIdentifierException(msg, self) elif not checkVersion(oauth2, g_oauth2ver): - self._logException(222, oauth2, g_oauth2ext, ' ', g_oauth2ver) - raise self._getException(222, oauth2, g_oauth2ext, '\n', g_oauth2ver) + msg = self._getExceptionMessage(223, g_oauth2ext, oauth2, g_oauth2ext, g_oauth2ver) + raise IllegalIdentifierException(msg, self) elif driver is None: - self._logException(221, g_jdbcext, ' ', g_extension) - raise self._getException(221, g_jdbcext, '\n', g_extension) + msg = self._getExceptionMessage(221, g_jdbcext, g_jdbcext, g_extension) + raise IllegalIdentifierException(msg, self) elif not checkVersion(driver, g_jdbcver): - self._logException(222, driver, g_jdbcext, ' ', g_jdbcver) - raise self._getException(222, driver, g_jdbcext, '\n', g_jdbcver) + msg = self._getExceptionMessage(223, g_jdbcext, driver, g_jdbcext, g_jdbcver) + raise IllegalIdentifierException(msg, self) else: - path = g_folder + '/' + g_scheme + path = g_folder + g_separator + g_scheme url = getConnectionUrl(self._ctx, path) try: database = DataBase(self._ctx, self._logger, url) except SQLException as e: - self._logException(223, url, ' ', e.Message) - raise self._getException(223, url, '\n', e.Message) + msg = self._getExceptionMessage(225, g_extension, url, e.Message) + raise IllegalIdentifierException(msg, self) else: if not database.isUptoDate(): - self._logException(224, database.Version, ' ', g_version) - raise self._getException(224, database.Version, '\n', g_version) + msg = self._getExceptionMessage(227, g_jdbcext, database.Version, g_version) + raise IllegalIdentifierException(msg, self) else: return DataSource(self._ctx, self._logger, database) return None - def _logException(self, code, *args): - self._logger.logprb(SEVERE, 'ContentProvider', 'queryContent()', code, *args) - - def _getException(self, code, *args): - msg = self._logger.resolveString(code, *args) - return IllegalIdentifierException(msg, self) + def _getExceptionMessage(self, code, extension, *args): + title = self._logger.resolveString(code, extension) + message = self._logger.resolveString(code +1, *args) + self._logger.logp(SEVERE, 'ContentProvider', 'queryContent()', message) + msgbox = createMessageBox(getParentWindow(self._ctx), message, title, 'error', 1) + msgbox.execute() + msgbox.dispose() + return message diff --git a/uno/lib/uno/ucb/database.py b/uno/lib/uno/ucb/database.py index b576c5e9..d495a7c4 100644 --- a/uno/lib/uno/ucb/database.py +++ b/uno/lib/uno/ucb/database.py @@ -65,16 +65,17 @@ from .dbconfig import g_version from .configuration import g_admin +from .configuration import g_separator +import os import traceback class DataBase(): - def __init__(self, ctx, logger, url, sync=None, user='', pwd=''): + def __init__(self, ctx, logger, url, user='', pwd=''): self._ctx = ctx self._logger = logger self._url = url - self._sync = sync odb = url + '.odb' new = not getSimpleFile(ctx).exists(odb) connection = getDataSourceConnection(ctx, url, user, pwd, new) @@ -211,7 +212,7 @@ def getContentType(self): # Procedures called by the Replicator def getMetaData(self, user, item): itemid = item.get('Id') - metadata = self.getItem(user, itemid, False) + metadata = self.getItem(user.Id, user.RootId, itemid, False) atroot = metadata.get('ParentId') == user.RootId metadata['AtRoot'] = atroot return metadata @@ -227,30 +228,22 @@ def updateNewItemId(self, oldid, newid, created, modified): return newid # Procedures called by the Content - #TODO: Can't have a simple SELECT ResultSet with a Procedure, - def getItem(self, user, itemid, rewrite=True): + def getItem(self, userid, rootid, itemid, rewrite=True): item = None - isroot = itemid == user.RootId - print("Content.getItem() 1 isroot: '%s'" % isroot) - call = 'getRoot' if isroot else 'getItem' - select = self._getCall(call) - select.setString(1, user.Id if isroot else itemid) + isroot = itemid == rootid + query = 'getRoot' if isroot else 'getItem' + call = self._getCall(query) + call.setString(1, userid if isroot else itemid) if not isroot: - select.setBoolean(2, rewrite) - result = select.executeQuery() + call.setBoolean(2, rewrite) + result = call.executeQuery() if result.next(): - print("Content.getItem() 2 isroot: '%s'" % isroot) item = getDataFromResult(result) result.close() - select.close() - if item.get('IsFolder'): - infos = user.getCreatableContentsInfo(item.get('CanAddChild')) - else: - infos = () - item['CreatableContentsInfo'] = infos + call.close() return item - def getChildren(self, username, itemid, properties, mode, scheme): + def getChildren(self, itemid, properties, mode, scheme): #TODO: Can't have a ResultSet of type SCROLL_INSENSITIVE with a Procedure, #TODO: as a workaround we use a simple quey... select = self._getCall('getChildren', properties) @@ -259,7 +252,7 @@ def getChildren(self, username, itemid, properties, mode, scheme): # OpenOffice / LibreOffice Columns: # ['Title', 'Size', 'DateModified', 'DateCreated', 'IsFolder', 'TargetURL', 'IsHidden', # 'IsVolume', 'IsRemote', 'IsRemoveable', 'IsFloppy', 'IsCompactDisc'] - # "TargetURL" is done by: the database view Path + # "TargetURL" is done by: the given scheme + the database view Path + Uri Title i = 1 if 'TargetURL' in (property.Name for property in properties): select.setString(i, scheme) @@ -268,18 +261,17 @@ def getChildren(self, username, itemid, properties, mode, scheme): select.setString(i +1, itemid) return select - def updateConnectionMode(self, userid, itemid, value, default): + def updateConnectionMode(self, userid, itemid, value): update = self._getCall('updateConnectionMode') - update.setLong(1, value) + update.setShort(1, value) update.setString(2, itemid) update.executeUpdate() update.close() return value - def getIdentifier(self, user, url): - print("DataBase.getIdentifier() Url: '%s'" % url) - call = self._getCall('getIdentifier') - call.setString(1, user.Id) + def getItemId(self, userid, url): + call = self._getCall('getItemId') + call.setString(1, userid) call.setString(2, url) call.execute() itemid = call.getString(3) @@ -288,6 +280,17 @@ def getIdentifier(self, user, url): call.close() return itemid + def getPath(self, userid, itemid): + call = self._getCall('getPath') + call.setString(1, userid) + call.setString(2, itemid) + call.execute() + path = call.getString(3) + if call.wasNull(): + path = g_separator + call.close() + return path + def getNewIdentifier(self, userid): identifier = '' select = self._getCall('getNewIdentifier') @@ -308,7 +311,7 @@ def deleteNewIdentifier(self, userid, itemid): call.close() def updateContent(self, userid, itemid, property, value): - updated = False + updated = clear = False timestamp = currentDateTimeInTZ() if property == 'Title': update = self._getCall('updateTitle') @@ -317,6 +320,7 @@ def updateContent(self, userid, itemid, property, value): update.setString(3, itemid) updated = update.execute() == 0 update.close() + clear = True elif property == 'Size': update = self._getCall('updateSize') # FIXME: If we update the Size, we need to update the DateModified too... @@ -333,9 +337,7 @@ def updateContent(self, userid, itemid, property, value): update.setString(3, itemid) updated = update.execute() == 0 update.close() - if updated and self._sync: - # Start Replicator for pushing changes… - self._sync.set() + return updated, clear def getNewTitle(self, title, parentid, isfolder): call = self._getCall('getNewTitle') @@ -347,32 +349,30 @@ def getNewTitle(self, title, parentid, isfolder): call.close() return newtitle - def insertNewContent(self, userid, content, timestamp): + def insertNewContent(self, userid, item, timestamp): call = self._getCall('insertItem') call.setString(1, userid) call.setLong(2, 1) call.setObject(3, timestamp) - call.setString(4, content.get("Id")) - call.setString(5, content.get("Title")) - call.setTimestamp(6, content.get('DateCreated')) - call.setTimestamp(7, content.get('DateModified')) - call.setString(8, content.get('MediaType')) - call.setLong(9, content.get('Size')) - self._setStringValue(call, 10, content.get('Link')) - call.setBoolean(11, content.get('Trashed')) - call.setBoolean(12, content.get('CanAddChild')) - call.setBoolean(13, content.get('CanRename')) - call.setBoolean(14, content.get('IsReadOnly')) - call.setBoolean(15, content.get('IsVersionable')) - call.setString(16, content.get("ParentId")) + call.setString(4, item.get("Id")) + call.setString(5, item.get("Title")) + call.setTimestamp(6, item.get('DateCreated')) + call.setTimestamp(7, item.get('DateModified')) + call.setString(8, item.get('MediaType')) + call.setLong(9, item.get('Size')) + call.setString(10, item.get('Link')) + call.setBoolean(11, item.get('Trashed')) + call.setBoolean(12, item.get('CanAddChild')) + call.setBoolean(13, item.get('CanRename')) + call.setBoolean(14, item.get('IsReadOnly')) + call.setBoolean(15, item.get('IsVersionable')) + call.setString(16, item.get("ParentId")) status = call.execute() == 0 - content['BaseURI'] = call.getString(17) - content['Title'] = call.getString(18) - content['TitleOnServer'] = call.getString(19) + item['Title'] = call.getString(17) + item['TitleOnServer'] = call.getString(18) + path = call.getString(19) call.close() - if status and self._sync: - # Start Replicator for pushing changes… - self._sync.set() + return status def hasTitle(self, userid, parentid, title): has = True @@ -388,16 +388,16 @@ def hasTitle(self, userid, parentid, title): return has def getChildId(self, parentid, title): - id = None + itemid = None call = self._getCall('getChildId') call.setString(1, parentid) call.setString(2, title) result = call.executeQuery() if result.next(): - id = result.getString(1) + itemid = result.getString(1) result.close() call.close() - return id + return itemid # Procedures called by the Replicator # Synchronization pull token update procedure @@ -536,32 +536,35 @@ def updateItemId(self, newid, oldid): # Procedures called internally def _mergeItem(self, call1, call2, item, timestamp): - call1.setString(4, item[0]) + itemid = item[0] + call1.setString(4, itemid) call1.setString(5, item[1]) call1.setTimestamp(6, item[2]) call1.setTimestamp(7, item[3]) call1.setString(8, item[4]) - call1.setLong(9, item[5]) - self._setStringValue(call1, 10, item[6]) + size = item[5] + if os.name == 'nt': + mx = 2 ** 32 / 2 -1 + if size > mx: + size = min(size, mx) + self._logger.logprb(SEVERE, 'DataBase', '_mergeItem()', 402, size, item[5]) + call1.setLong(9, size) + call1.setString(10, item[6]) call1.setBoolean(11, item[7]) call1.setBoolean(12, item[8]) call1.setBoolean(13, item[9]) call1.setBoolean(14, item[10]) call1.setBoolean(15, item[11]) call1.addBatch() - self._mergeParent(call2, item, timestamp) + self._mergeParent(call2, item, itemid, timestamp) return 1 - def _mergeParent(self, call, item, timestamp): - call.setString(1, item[0]) - self._setStringValue(call, 2, item[-2]) - call.setArray(3, Array('VARCHAR', item[-1])) - call.setObject(4, timestamp) + def _mergeParent(self, call, item, itemid, timestamp): + call.setString(1, itemid) + call.setArray(2, Array('VARCHAR', item[12])) + call.setObject(3, timestamp) call.addBatch() - def _setStringValue(self, call, i, value): - call.setNull(i, VARCHAR) if value is None else call.setString(i, value) - def _getCall(self, name, format=None): return getDataSourceCall(self._ctx, self.Connection, name, format) diff --git a/uno/lib/uno/ucb/datasource.py b/uno/lib/uno/ucb/datasource.py index da64132c..08d2f609 100644 --- a/uno/lib/uno/ucb/datasource.py +++ b/uno/lib/uno/ucb/datasource.py @@ -40,7 +40,9 @@ from .oauth2 import getOAuth2UserName -from .unotool import createService +from .unotool import getUrlTransformer +from .unotool import getUriFactory +from .unotool import parseUrl from .ucp import User @@ -48,6 +50,8 @@ from .replicator import Replicator +from .configuration import g_separator + from threading import Event from threading import Lock import traceback @@ -63,7 +67,8 @@ def __init__(self, ctx, logger, database): self.Error = None self._sync = Event() self._lock = Lock() - self._factory = createService(ctx, 'com.sun.star.uri.UriReferenceFactory') + self._urifactory = getUriFactory(ctx) + self._transformer = getUrlTransformer(ctx) database.addCloseListener(self) folder, link = database.getContentType() self._provider = Provider(ctx, logger, folder, link) @@ -75,10 +80,23 @@ def __init__(self, ctx, logger, database): def getDefaultUser(self): return self._default + def parseIdentifier(self, identifier): + url = self._getPresentationUrl(identifier.getContentIdentifier()) + return self._urifactory.parse(url) + # FIXME: Get called from ParameterizedProvider.queryContent() - def queryContent(self, source, authority, identifier): - user, path = self._getUser(source, identifier.getContentIdentifier(), authority) - content = user.getContent(path, authority) + def queryContent(self, source, authority, url): + user, uri = self._getUser(source, authority, url) + itemid = user.getItemByUri(uri) + if itemid is None: + msg = self._logger.resolveString(311, url) + print(msg) + raise IllegalIdentifierException(msg, source) + content = user.getContent(authority, itemid) + if content is None: + msg = self._logger.resolveString(311, url) + print(msg) + raise IllegalIdentifierException(msg, source) return content # XCloseListener @@ -93,11 +111,13 @@ def queryClosing(self, source, ownership): self._logger.logprb(INFO, 'DataSource', 'queryClosing()', 341, self._provider.Scheme) def notifyClosing(self, source): pass + def disposing(self, source): + pass # Private methods - def _getUser(self, source, url, authority): + def _getUser(self, source, authority, url): default = False - uri = self._factory.parse(url) + uri = self._urifactory.parse(self._getPresentationUrl(url)) if uri is None: msg = self._logger.resolveString(321, url) raise IllegalIdentifierException(msg, source) @@ -121,13 +141,21 @@ def _getUser(self, source, url, authority): msg = self._logger.resolveString(323, name) raise IllegalIdentifierException(msg, source) else: - user = User(self._ctx, self._logger, source, self.DataBase, - self._provider, name, self._sync, self._lock) + user = User(self._ctx, source, self._logger, self.DataBase, + self._provider, self._sync, name) self._users[name] = user # FIXME: if the user has been instantiated then we can consider it as the default user if default: self._default = name - return user, uri.getPath() + return user, uri + + def _getPresentationUrl(self, url): + # FIXME: Sometimes the url can end with a dot or a slash, it must be deleted + url = url.rstrip('/.') + uri = parseUrl(self._transformer, url) + if uri is not None: + uri = self._transformer.getPresentation(uri, True) + return uri if uri else url def _getUserName(self, source, url): name = getOAuth2UserName(self._ctx, self, self._provider.Scheme) diff --git a/uno/lib/uno/ucb/dbinit.py b/uno/lib/uno/ucb/dbinit.py index 88b82d38..3d9f202c 100644 --- a/uno/lib/uno/ucb/dbinit.py +++ b/uno/lib/uno/ucb/dbinit.py @@ -178,7 +178,8 @@ def getQueries(): ('createChildrenView',{'Role': g_role}), ('createPathView',{'Role': g_role, 'Separator': g_separator}), - ('createGetIdentifier',{'Role': g_role, 'Separator': g_separator}), + ('createGetPath',{'Role': g_role}), + ('createGetItemId',{'Role': g_role, 'Separator': g_separator}), ('createGetRoot',{'Role': g_role}), ('createGetItem',{'Role': g_role}), ('createGetNewTitle',{'Role': g_role}), diff --git a/uno/lib/uno/ucb/dbqueries.py b/uno/lib/uno/ucb/dbqueries.py index 5ca107ee..db20cd64 100644 --- a/uno/lib/uno/ucb/dbqueries.py +++ b/uno/lib/uno/ucb/dbqueries.py @@ -154,74 +154,75 @@ def getSqlQuery(ctx, name, format=None): # Create Cached View Queries elif name == 'createChildView': query = '''\ -CREATE VIEW "Child" ("UserId", "ItemId", "ParentId", "Title") AS SELECT - I."UserId", I."ItemId", P."ItemId", I."Title" - FROM "Items" AS I - JOIN "Parents" AS P ON I."ItemId"=P."ChildId"; +CREATE VIEW "Child" ("UserId", "ItemId", "ParentId", "Title") AS SELECT + I."UserId", I."ItemId", P."ItemId", I."Title" + FROM "Items" AS I + JOIN "Parents" AS P ON I."ItemId"=P."ChildId" + WHERE I."Trashed" = FALSE; GRANT SELECT ON "Child" TO "%(Role)s";''' % format elif name == 'createTwinView': query = '''\ -CREATE VIEW "Twin" ("ParentId", "Title", "Idx") AS SELECT - P."ItemId", I."Title", ARRAY_AGG(I."ItemId" ORDER BY I."DateCreated", I."DateModified") - FROM "Items" AS I - JOIN "Parents" AS "P" ON "I"."ItemId"="P"."ChildId" - GROUP BY P."ItemId", I."Title" +CREATE VIEW "Twin" ("ParentId", "Title", "Idx") AS SELECT + P."ItemId", I."Title", ARRAY_AGG(I."ItemId" ORDER BY I."DateCreated", I."DateModified") + FROM "Items" AS I + JOIN "Parents" AS "P" ON "I"."ItemId"="P"."ChildId" + WHERE I."Trashed" = FALSE + GROUP BY P."ItemId", I."Title" HAVING COUNT(*) > 1; GRANT SELECT ON "Twin" TO "%(Role)s";''' % format elif name == 'createUriView': query = '''\ -CREATE VIEW "Uri" ("ItemId", "ParentId", "Title", "Length", "Position") AS SELECT - C."ItemId", T."ParentId", T."Title", CARDINALITY(T."Idx"), POSITION_ARRAY(C."ItemId" IN T."Idx") - FROM "Twin" AS T +CREATE VIEW "Uri" ("ItemId", "ParentId", "Title", "Length", "Position") AS SELECT + C."ItemId", T."ParentId", T."Title", CARDINALITY(T."Idx"), POSITION_ARRAY(C."ItemId" IN T."Idx") + FROM "Twin" AS T JOIN "Child" AS C ON T."Title"=C."Title" AND T."ParentId"=C."ParentId"; GRANT SELECT ON "Uri" TO "%(Role)s";''' % format elif name == 'createItemView': query = '''\ -CREATE VIEW "Item" ("ItemId", "ContentType", "IsFolder", "IsLink", "IsDocument") AS SELECT - I."ItemId", - CASE WHEN I."MediaType" IN (S."Value2",S."Value3") THEN I."MediaType" ELSE S."Value1" END, - I."MediaType"="S"."Value2", - I."MediaType"="S"."Value3", - I."MediaType"!="S"."Value2" AND I."MediaType"!="S"."Value3" - FROM "Settings" AS S, "Items" AS I +CREATE VIEW "Item" ("ItemId", "ContentType", "IsFolder", "IsLink", "IsDocument") AS SELECT + I."ItemId", + CASE WHEN I."MediaType" IN (S."Value2",S."Value3") THEN I."MediaType" ELSE S."Value1" END, + I."MediaType"="S"."Value2", + I."MediaType"="S"."Value3", + I."MediaType"!="S"."Value2" AND I."MediaType"!="S"."Value3" + FROM "Settings" AS S, "Items" AS I WHERE S."Name"='ContentType'; GRANT SELECT ON "Item" TO "%(Role)s";''' % format elif name == 'createTitleView': query = '''\ -CREATE VIEW "Title" ("ItemId", "Title", "Position") AS SELECT - U."ItemId", "GetUniqueName"(U."Title", I."IsFolder", U."Position"), U."Position" - FROM "Uri" AS U - INNER JOIN "Item" AS I ON U."ItemId"=I."ItemId" +CREATE VIEW "Title" ("ItemId", "Title", "Position") AS SELECT + U."ItemId", "GetUniqueName"(U."Title", I."IsFolder", U."Position"), U."Position" + FROM "Uri" AS U + INNER JOIN "Item" AS I ON U."ItemId"=I."ItemId" WHERE U."Position" > 1; GRANT SELECT ON "Title" TO "%(Role)s";''' % format elif name == 'createChildrenView': query = '''\ -CREATE VIEW "Children" ("UserId", "ItemId", "ParentId", "Title", "Uri", "DateCreated", "DateModified", "IsFolder", "Size", "ConnectionMode", "Trashed") AS SELECT +CREATE VIEW "Children" ("UserId", "ItemId", "ParentId", "Title", "Uri", "DateCreated", "DateModified", "IsFolder", "Size", "ConnectionMode") AS SELECT I."UserId", C."ItemId", C."ParentId", I."Title", COALESCE(T."Title",I."Title"), I."DateCreated", I."DateModified", - I2."IsFolder", I."Size", I."ConnectionMode", I."Trashed" - FROM "Items" AS I - INNER JOIN "Item" AS I2 ON I."ItemId"=I2."ItemId" - INNER JOIN "Child" AS C ON I2."ItemId"=C."ItemId" + I2."IsFolder", I."Size", I."ConnectionMode" + FROM "Items" AS I + INNER JOIN "Item" AS I2 ON I."ItemId"=I2."ItemId" + INNER JOIN "Child" AS C ON I2."ItemId"=C."ItemId" LEFT JOIN "Title" AS T ON C."ItemId"=T."ItemId"; GRANT SELECT ON "Children" TO "%(Role)s";''' % format elif name == 'createPathView': query = '''\ -CREATE VIEW "Path" AS WITH RECURSIVE TREE ("UserId", "ParentId", "ItemId", "Path") AS ( - SELECT "UserId", CAST(NULL AS VARCHAR(100)), "RootId", '' - FROM "Users" +CREATE VIEW "Path" AS WITH RECURSIVE TREE ("UserId", "ParentId", "ItemId", "Path", "Uri") AS ( + SELECT "UserId", CAST(NULL AS VARCHAR(100)), "RootId", '', '' FROM "Users" UNION ALL - SELECT I."UserId", C."ParentId", C."ItemId", "Path" || '%(Separator)s' || C."Uri" + SELECT I."UserId", C."ParentId", C."ItemId", TRIM(T."Path") || T."Uri" || '%(Separator)s', C."Uri" FROM "Items" AS I - INNER JOIN "Children" AS C ON I."ItemId"=C."ItemId" + INNER JOIN "Children" AS C ON I."ItemId" = C."ItemId" INNER JOIN TREE AS T ON T."ItemId" = C."ParentId" ) - SELECT "UserId", "ParentId", "ItemId", "Path" + SELECT "UserId", "ParentId", "ItemId", "Path", "Uri" FROM TREE; GRANT SELECT ON "Path" TO "%(Role)s";''' % format @@ -288,25 +289,25 @@ def getSqlQuery(ctx, name, format=None): WHERE U."UserName" = ?;''' elif name == 'getChildren': - target = '? || P."Path" AS "TargetURL"' - properties = {'Title': 'C."Title"', - 'Size': 'C."Size"', - 'DateModified': 'C."DateModified"', - 'DateCreated': 'C."DateCreated"', - 'IsFolder': 'C."IsFolder"', - 'TargetURL': target, - 'IsHidden': 'FALSE "IsHidden"', - 'IsVolume': 'FALSE "IsVolume"', - 'IsRemote': 'FALSE "IsRemote"', - 'IsRemoveable': 'FALSE "IsRemoveable"', - 'IsFloppy': 'FALSE "IsFloppy"', - 'IsCompactDisc': 'FALSE "IsCompactDisc"'} - columns = (properties[property.Name] for property in format if property.Name in properties) + properties = {'Title': 'C."Uri"', + 'Size': 'C."Size"', + 'DateModified': 'C."DateModified"', + 'DateCreated': 'C."DateCreated"', + 'IsFolder': 'C."IsFolder"', + 'TargetURL': '? || P."Path" || P."Uri"', + 'IsHidden': 'FALSE', + 'IsVolume': 'FALSE', + 'IsRemote': 'FALSE', + 'IsRemoveable': 'FALSE', + 'IsFloppy': 'FALSE', + 'IsCompactDisc': 'FALSE'} + columns = ('%s AS "%s"' % (properties[p.Name], p.Name) for p in format if p.Name in properties) query = '''\ SELECT %s FROM "Children" AS C -INNER JOIN "Path" AS P ON C."ItemId"=P."ItemId" -WHERE (C."IsFolder" = TRUE OR C."ConnectionMode" >= ?) AND C."Trashed" = FALSE AND C."ParentId" = ?;''' % ', '.join(columns) +INNER JOIN "Path" AS P ON C."ItemId" = P."ItemId" +WHERE (C."IsFolder" = TRUE OR C."ConnectionMode" >= ?) AND C."ParentId" = ?; +''' % ', '.join(columns) elif name == 'getChildId': query = '''\ @@ -355,20 +356,37 @@ def getSqlQuery(ctx, name, format=None): query = 'DELETE FROM "Identifiers" WHERE "UserId"=? AND "ItemId"=?;' # Create Procedure Query - elif name == 'createGetIdentifier': + elif name == 'createGetItemId': query = '''\ -CREATE PROCEDURE "GetIdentifier"(IN USERID VARCHAR(100), - IN URI VARCHAR(500), - OUT ITEMID VARCHAR(100)) - SPECIFIC "GetIdentifier_1" +CREATE PROCEDURE "GetItemId"(IN USERID VARCHAR(100), + IN URL VARCHAR(500), + OUT ITEMID VARCHAR(100)) + SPECIFIC "GetItemId_1" READS SQL DATA BEGIN ATOMIC DECLARE ITEM VARCHAR(100); - SELECT "ItemId" INTO ITEM FROM "Path" WHERE "UserId" = USERID AND - (URI = "Path" OR URI = ("Path" || '%(Separator)s')); + SELECT "ItemId" INTO ITEM FROM "Path" + WHERE "UserId" = USERID AND URL = "Path" || "Uri"; SET ITEMID = ITEM; END; -GRANT EXECUTE ON SPECIFIC ROUTINE "GetIdentifier_1" TO "%(Role)s";''' % format +GRANT EXECUTE ON SPECIFIC ROUTINE "GetItemId_1" TO "%(Role)s";''' % format + + + elif name == 'createGetPath': + query = '''\ +CREATE PROCEDURE "GetPath"(IN USERID VARCHAR(100), + IN ITEMID VARCHAR(100), + OUT PATH VARCHAR(500)) + SPECIFIC "GetPath_1" + READS SQL DATA + BEGIN ATOMIC + DECLARE TMP VARCHAR(500); + SELECT CONCAT("Path", "Uri") INTO TMP FROM "Path" + WHERE "UserId" = USERID AND "ItemId" = ITEMID; + SET PATH = TMP; + END; +GRANT EXECUTE ON SPECIFIC ROUTINE "GetPath_1" TO "%(Role)s";''' % format + elif name == 'createUpdateNewItemId': query = '''\ @@ -391,14 +409,14 @@ def getSqlQuery(ctx, name, format=None): DYNAMIC RESULT SETS 1 BEGIN ATOMIC DECLARE "Result" CURSOR WITH RETURN FOR - SELECT I."ItemId" AS "Id", '' AS "Path", - '' AS "ParentId", I."ItemId" AS "ObjectId", I."Title", - I."Title" AS "TitleOnServer", I."DateCreated", I."DateModified", + SELECT I."ItemId" AS "Id", '' AS "Path", '' AS "ParentId", + I."Title", I."Title" AS "TitleOnServer", I."DateCreated", I."DateModified", I2."ContentType", I."MediaType", I."Size", I."Link", I."Trashed", TRUE AS "IsRoot", I2."IsFolder", I2."IsLink", I2."IsDocument", C."CanAddChild", C."CanRename", C."IsReadOnly", C."IsVersionable", I."ConnectionMode", - '' AS "CasePreservingURL", FALSE AS "IsHidden", FALSE AS "IsVolume", FALSE AS "IsRemote", - FALSE AS "IsRemoveable", FALSE AS "IsFloppy", FALSE AS "IsCompactDisc" + FALSE AS "IsHidden", FALSE AS "IsVolume", FALSE AS "IsRemote", + FALSE AS "IsRemoveable", FALSE AS "IsFloppy", FALSE AS "IsCompactDisc", + I."ItemId" AS "ObjectId" FROM "Users" AS U INNER JOIN "Items" AS I ON U."RootId"=I."ItemId" INNER JOIN "Item" AS I2 ON I."ItemId"=I2."ItemId" @@ -417,20 +435,20 @@ def getSqlQuery(ctx, name, format=None): DYNAMIC RESULT SETS 1 BEGIN ATOMIC DECLARE "Result" CURSOR WITH RETURN FOR - SELECT I."ItemId" AS "Id", P2."Path", - P."ItemId" AS "ParentId", I."ItemId" AS "ObjectId", - "GetTitle"(I."Title",T."Title",SWAP) AS "Title", - I."Title" AS "TitleOnServer", I."DateCreated", I."DateModified", - I2."ContentType", I."MediaType", I."Size", I."Link", I."Trashed", + SELECT I."ItemId" AS "Id", P2."Path", P."ItemId" AS "ParentId", + "GetTitle"(I."Title", T."Title", SWAP) AS "Title", + I."Title" AS "TitleOnServer", I."DateCreated", I."DateModified", + I2."ContentType", I."MediaType", I."Size", I."Link", I."Trashed", FALSE AS "IsRoot", I2."IsFolder", I2."IsLink", I2."IsDocument", C."CanAddChild", C."CanRename", C."IsReadOnly", C."IsVersionable", I."ConnectionMode", - '' AS "CasePreservingURL", FALSE AS "IsHidden", FALSE AS "IsVolume", FALSE AS "IsRemote", - FALSE AS "IsRemoveable", FALSE AS "IsFloppy", FALSE AS "IsCompactDisc" + FALSE AS "IsHidden", FALSE AS "IsVolume", FALSE AS "IsRemote", + FALSE AS "IsRemoveable", FALSE AS "IsFloppy", FALSE AS "IsCompactDisc", + I."ItemId" AS "ObjectId" FROM "Items" AS I INNER JOIN "Item" AS I2 ON I."ItemId"=I2."ItemId" INNER JOIN "Capabilities" AS C ON I."ItemId"=C."ItemId" INNER JOIN "Parents" AS P ON I."ItemId"=P."ChildId" - INNER JOIN "Path" AS P2 ON P."ItemId"=P2."ItemId" + INNER JOIN "Path" AS P2 ON I."ItemId"=P2."ItemId" LEFT JOIN "Title" AS T ON I."ItemId"=T."ItemId" WHERE I."ItemId" = ITEMID FOR READ ONLY; OPEN "Result"; @@ -729,28 +747,21 @@ def getSqlQuery(ctx, name, format=None): elif name == 'createMergeParent': query = '''\ -CREATE PROCEDURE "MergeParent"(IN ItemId VARCHAR(100), - IN Path VARCHAR(100), - IN Parents VARCHAR(100) ARRAY, - IN DateTime TIMESTAMP(6) WITH TIME ZONE) +CREATE PROCEDURE "MergeParent"(IN ITEMID VARCHAR(100), + IN PARENTS VARCHAR(100) ARRAY, + IN DATETIME TIMESTAMP(6) WITH TIME ZONE) SPECIFIC "MergeParent_1" MODIFIES SQL DATA BEGIN ATOMIC - DECLARE Index INTEGER DEFAULT 1; - DECLARE TmpParents VARCHAR(100) ARRAY; - IF Path IS NULL THEN - SET TmpParents = Parents; - ELSE - SELECT ARRAY_AGG("ItemId") INTO TmpParents FROM "Path" WHERE "Path" = Path; - END IF; - DELETE FROM "Parents" WHERE "ChildId"=ItemId AND "ItemId" NOT IN (UNNEST(TmpParents)); - WHILE Index <= CARDINALITY(TmpParents) DO - MERGE INTO "Parents" USING (VALUES(ItemId, TmpParents[Index], DateTime)) + DECLARE INDEX INTEGER DEFAULT 1; + DELETE FROM "Parents" WHERE "ChildId" = ITEMID; + WHILE INDEX <= CARDINALITY(PARENTS) DO + MERGE INTO "Parents" USING (VALUES(ITEMID, PARENTS[INDEX], DATETIME)) AS vals(x,y,z) ON "Parents"."ChildId"=vals.x AND "Parents"."ItemId"=vals.y WHEN NOT MATCHED THEN INSERT ("ChildId","ItemId","TimeStamp") VALUES vals.x, vals.y, vals.z; - SET Index = Index + 1; + SET INDEX = INDEX + 1; END WHILE; END; GRANT EXECUTE ON SPECIFIC ROUTINE "MergeParent_1" TO "%(Role)s";''' % format @@ -773,15 +784,15 @@ def getSqlQuery(ctx, name, format=None): IN READONLY BOOLEAN, IN ISVERSIONABLE BOOLEAN, IN PARENT VARCHAR(100), - OUT URI VARCHAR(500), OUT NEWTITLE VARCHAR(100), - OUT NEWNAME VARCHAR(100)) + OUT NEWNAME VARCHAR(100), + OUT URI VARCHAR(500)) SPECIFIC "InsertItem_1" MODIFIES SQL DATA BEGIN ATOMIC - DECLARE PATH VARCHAR(500); DECLARE TMP1 VARCHAR(100); DECLARE TMP2 VARCHAR(100); + DECLARE PATH VARCHAR(500); INSERT INTO "Items" ("UserId","ItemId","Title","DateCreated","DateModified","MediaType", "Size","Link","Trashed","ConnectionMode","SyncMode","TimeStamp") VALUES (USERID,ITEMID,TITLE,CREATED,MODIFIED, MEDIATYPE,SIZE,LINK,TRASHED,CONNECTIONMODE,1,DATETIME); @@ -790,20 +801,22 @@ def getSqlQuery(ctx, name, format=None): ISVERSIONABLE,DATETIME); INSERT INTO "Parents" ("ChildId","ItemId","TimeStamp","SyncMode") VALUES (ITEMID, PARENT,DATETIME,1); - SELECT P."Path", COALESCE(T."Title", I."Title"), I."Title" "Title" INTO PATH, TMP1, TMP2 + SELECT COALESCE(T."Title", I."Title"), I."Title", P."Path" INTO TMP1, TMP2, PATH FROM "Items" AS I INNER JOIN "Path" AS P ON I."ItemId"=P."ItemId" LEFT JOIN "Title" AS T ON I."ItemId"=T."ItemId" WHERE I."ItemId"=ITEMID; - SET URI = PATH; SET NEWTITLE = TMP1; SET NEWNAME = TMP2; + SET URI = PATH; END; GRANT EXECUTE ON SPECIFIC ROUTINE "InsertItem_1" TO "%(Role)s";''' % format # Get Procedure Query - elif name == 'getIdentifier': - query = 'CALL "GetIdentifier"(?,?,?)' + elif name == 'getPath': + query = 'CALL "GetPath"(?,?,?)' + elif name == 'getItemId': + query = 'CALL "GetItemId"(?,?,?)' elif name == 'getRoot': query = 'CALL "GetRoot"(?)' elif name == 'getItem': @@ -825,7 +838,7 @@ def getSqlQuery(ctx, name, format=None): elif name == 'mergeItem': query = 'CALL "MergeItem"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)' elif name == 'mergeParent': - query = 'CALL "MergeParent"(?,?,?,?)' + query = 'CALL "MergeParent"(?,?,?)' elif name == 'pullChanges': query = 'CALL "PullChanges"(?,?,?,?,?,?)' elif name == 'insertItem': diff --git a/uno/lib/uno/ucb/replicator.py b/uno/lib/uno/ucb/replicator.py index 047baa6b..4071b3db 100644 --- a/uno/lib/uno/ucb/replicator.py +++ b/uno/lib/uno/ucb/replicator.py @@ -67,22 +67,26 @@ import time -class Replicator(unohelper.Base, - Thread): +class Replicator(Thread): def __init__(self, ctx, url, provider, users, sync, lock): - Thread.__init__(self) - self._ctx = ctx - self._users = users - self._sync = sync - self._lock = lock - self._canceled = False - self._fullPull = False - self._provider = provider - self._config = getConfiguration(ctx, g_identifier, False) - self._logger = getLogger(ctx, g_synclog, g_basename) - self.DataBase = DataBase(ctx, self._logger, url) - sync.clear() - self.start() + try: + Thread.__init__(self) + self._ctx = ctx + self._users = users + self._sync = sync + self._lock = lock + self._canceled = False + self._fullPull = False + self._provider = provider + self._config = getConfiguration(ctx, g_identifier, False) + self._logger = getLogger(ctx, g_synclog, g_basename) + self.DataBase = DataBase(ctx, self._logger, url) + sync.clear() + self.start() + except Exception as e: + self._logger.logprb(INFO, 'Replicator', '__init__()', 102, e, traceback.format_exc()) + else: + self._logger.logprb(INFO, 'Replicator', '__init__()', 101) def fullPull(self): return self._fullPull @@ -94,26 +98,23 @@ def cancel(self): def run(self): try: - msg = "Replicator for Scheme: %s loading ... " % self._provider.Scheme - print("Replicator.run() 1 *************************************************************") - print("Replicator run() 2") + self._logger.logprb(INFO, 'Replicator', 'run()', 111, self._provider.Scheme) while not self._canceled: - self._sync.wait(self._getReplicateTimeout()) + timeout = self._getReplicateTimeout() + self._logger.logprb(INFO, 'Replicator', 'run()', 112, round(timeout /60)) + self._sync.wait(timeout) self._synchronize() self._sync.clear() - print("replicator.run() 3") - print("replicator.run() 4 *************************************************************") except Exception as e: - msg = "Replicator run(): Error: %s - %s" % (e, traceback.print_exc()) - print(msg) + self._logger.logprb(SEVERE, 'Replicator', 'run()', 113, e, traceback.format_exc()) def _synchronize(self): policy = self._getPolicy() if policy == self._getSynchronizePolicy('NONE_IS_MASTER'): return - self._logger.logprb(INFO, 'Replicator', '_synchronize()', 101, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_synchronize()', 121) if self._provider.isOffLine(): - self._logger.logprb(INFO, 'Replicator', '_synchronize()', 102) + self._logger.logprb(INFO, 'Replicator', '_synchronize()', 122) elif policy == self._getSynchronizePolicy('SERVER_IS_MASTER'): if not self._canceled: self._pullUsers() @@ -124,14 +125,14 @@ def _synchronize(self): self._pushUsers() if not self._canceled: self._pullUsers() - self._logger.logprb(INFO, 'Replicator', '_synchronize()', 103, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_synchronize()', 123) def _pullUsers(self): try: for user in self._users.values(): if self._canceled: break - self._logger.logprb(INFO, 'Replicator', '_pullUsers()', 111, user.Name, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_pullUsers()', 131, user.Name) # In order to make the creation of files or directories possible quickly, # it is necessary to run the verification of the identifiers first. self._checkNewIdentifier(user) @@ -140,18 +141,19 @@ def _pullUsers(self): self._initUser(user) else: self._pullUser(user) - self._logger.logprb(INFO, 'Replicator', '_pullUsers()', 112, user.Name, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_pullUsers()', 132, user.Name) except Exception as e: - print("Replicator._pullUsers() ERROR: %s - %s" % (e, traceback.print_exc())) + self._logger.logprb(SEVERE, 'Replicator', '_pullUsers()', 133, e, traceback.format_exc()) def _initUser(self, user): # This procedure is launched only once for each new user # This procedure corresponds to the initial pull for a new User (ie: without Token) + self._logger.logprb(INFO, 'Replicator', '_initUser()', 141, user.Name) pages, count, token = self._provider.firstPull(user) - print("Replicator._initUser() 1 Count: %s - Pages %s - Token: %s" % (count, pages, token)) self._provider.initUser(self.DataBase, user, token) user.SyncMode = 1 self._fullPull = True + self._logger.logprb(INFO, 'Replicator', '_initUser()', 142, user.Name) def _pullUser(self, user): # This procedure is launched each time the synchronization is started @@ -169,27 +171,25 @@ def _pushUsers(self): try: end = currentDateTimeInTZ() for user in self._users.values(): - self._logger.logprb(INFO, 'Replicator', '_pushUsers()', 131, user.Name, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_pushUsers()', 151, user.Name) if self._isNewUser(user): self._initUser(user) items = [] start = user.TimeStamp for item in self.DataBase.getPushItems(user.Id, start, end): - print("Replicator._pushUsers() 1 Start: %s - End: %s" % (getDateTimeInTZToString(start), getDateTimeInTZToString(end))) - print("Replicator._pushUsers() 2 Item: UserName: %s - ItemId: %s - ChangeAction: %s - TimeStamp: %s" % (user.Name, item.get('Id'),item.get('ChangeAction'),getDateTimeInTZToString(item.get('TimeStamp')))) metadata = self.DataBase.getMetaData(user, item) newid = self._pushItem(user, item, metadata, start, end) if newid is not None: items.append(newid) else: modified = getDateTimeToString(metadata.get('DateModified')) - self._logger.logprb(SEVERE, 'Replicator', '_pushUsers()', 132, metadata.get('Title'), modified, metadata.get('Id')) + self._logger.logprb(SEVERE, 'Replicator', '_pushUsers()', 152, metadata.get('Title'), modified, metadata.get('Id')) break if items: self.DataBase.updatePushItems(user, items) - self._logger.logprb(INFO, 'Replicator', '_pushUsers()', 133, user.Name, getDateTimeInTZToString(currentDateTimeInTZ())) + self._logger.logprb(INFO, 'Replicator', '_pushUsers()', 153, user.Name) except Exception as e: - print("Replicator.synchronize() ERROR: %s - %s" % (e, traceback.print_exc())) + self._logger.logprb(SEVERE, 'Replicator', '_pushUsers()', 154, e, traceback.format_exc()) def _checkNewIdentifier(self, user): if not self._provider.GenerateIds: @@ -209,7 +209,6 @@ def _filterParents(self, call, provider, items, childs, roots, start): rows = [] while len(childs) and len(childs) != i: i = len(childs) - print("replicator._filterParents() %s" % len(childs)) for item in childs: itemid, parents = item if all(parent in roots for parent in parents): @@ -242,14 +241,13 @@ def _pushItem(self, user, item, metadata, start, end): print("Replicator._pushItem() INSERT 3") newid = self._provider.createFolder(user, itemid, metadata) print("Replicator._pushItem() INSERT 4") - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 141, metadata.get('Title'), created) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', 161, metadata.get('Title'), created) print("Replicator._pushItem() INSERT 5") elif self._provider.isLink(mediatype): pass elif self._provider.isDocument(mediatype): - newid = self._provider.uploadFile(user, itemid, metadata, chunk, retry, delay, True) - if newid: - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 142, metadata.get('Title'), created) + newid, args = self._provider.uploadFile(165, user, itemid, metadata, created, chunk, retry, delay, True) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', *args) # UPDATE procedures, only a few properties are synchronized: Title and content(ie: Size or DateModified) elif action & UPDATE: for property in self.DataBase.getPushProperties(user.Id, itemid, start, end): @@ -258,13 +256,13 @@ def _pushItem(self, user, item, metadata, start, end): modified = getDateTimeToString(metadata.get('DateModified')) if properties & TITLE: newid = self._provider.updateTitle(user.Request, itemid, metadata) - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 143, metadata.get('Title'), modified) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', 170, metadata.get('Title'), modified) elif properties & CONTENT: - newid = self._provider.uploadFile(user, itemid, metadata, chunk, retry, delay, False) - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 144, metadata.get('Title'), modified, metadata.get('Size')) + newid, args = self._provider.uploadFile(175, user, itemid, metadata, modified, chunk, retry, delay, False) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', *args) elif properties & TRASHED: newid = self._provider.updateTrashed(user.Request, itemid, metadata) - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 145, metadata.get('Title'), modified) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', 172, metadata.get('Title'), modified) # MOVE procedures to follow parent changes of a resource elif action & MOVE: print("Replicator._pushItem() MOVE") @@ -274,11 +272,10 @@ def _pushItem(self, user, item, metadata, start, end): elif action & DELETE: print("Replicator._pushItem() DELETE") newid = self._provider.updateTrashed(user.Request, itemid, metadata) - self._logger.logprb(INFO, 'Replicator', '_pushItem()', 145, metadata.get('Title'), timestamp) + self._logger.logprb(INFO, 'Replicator', '_pushItem()', 172, metadata.get('Title'), timestamp) return newid except Exception as e: - msg = "ERROR: %s - %s" % (e, traceback.print_exc()) - self._logger.logp(SEVERE, 'Replicator', '_pushItem()', msg) + self._logger.logprb(SEVERE, 'Replicator', '_pushItem()', 179, e, traceback.format_exc()) def _isNewUser(self, user): return user.SyncMode == 0 diff --git a/uno/lib/uno/ucb/ucp/content.py b/uno/lib/uno/ucb/ucp/content.py index c193cf88..988d171d 100644 --- a/uno/lib/uno/ucb/ucp/content.py +++ b/uno/lib/uno/ucb/ucp/content.py @@ -36,6 +36,8 @@ from com.sun.star.ucb.ConnectionMode import OFFLINE from com.sun.star.ucb.ConnectionMode import ONLINE +from com.sun.star.ucb.NameClash import OVERWRITE + from com.sun.star.beans.PropertyAttribute import BOUND from com.sun.star.beans.PropertyAttribute import CONSTRAINED from com.sun.star.beans.PropertyAttribute import READONLY @@ -50,6 +52,7 @@ from com.sun.star.ucb import CommandAbortedException from com.sun.star.ucb import IllegalIdentifierException from com.sun.star.ucb import InteractiveBadTransferURLException +from com.sun.star.ucb import UnsupportedCommandException from com.sun.star.ucb import XCommandProcessor2 from com.sun.star.ucb import XContent from com.sun.star.ucb import XContentCreator @@ -83,11 +86,7 @@ from .contenthelper import getInteractiveAugmentedIOException from .contenthelper import getMimeType -from ..logger import getLogger - -from ..configuration import g_defaultlog -from ..configuration import g_scheme -from ..configuration import g_separator +from .identifier import Identifier import traceback @@ -99,16 +98,18 @@ class Content(unohelper.Base, XContentCreator, XChild, XPropertiesChangeNotifier): - def __init__(self, ctx, user, authority=True, url='', data=None): + def __init__(self, ctx, user, authority, data, new=False): self._ctx = ctx self._user = user self._authority = authority - self._new = data is not None + self.MetaData = data + self._new = new + self._url = None + self._listeners = [] self._contentListeners = [] self._propertiesListener = {} - self._listeners = [] + self._commandid = {} self._logger = user._logger - self.MetaData = data if self._new else self._getMetaData(url) self._commandInfo = self._getCommandInfo() self._propertySetInfo = self._getPropertySetInfo() self._logger.logprb(INFO, 'Content', '__init__()', 601) @@ -128,11 +129,13 @@ def IsRoot(self): @property def CanAddChild(self): return self.MetaData.get('CanAddChild') - @property def Id(self): return self.MetaData.get('Id') @property + def ObjectId(self): + return self.MetaData.get('ObjectId') + @property def ParentId(self): return self.MetaData.get('ParentId') @property @@ -145,6 +148,9 @@ def Size(self): def Link(self): return self.MetaData.get('Link') @property + def Url(self): + return self.MetaData.get('CasePreservingURL') + @property def Title(self): return self.MetaData.get('Title') @property @@ -160,8 +166,9 @@ def setConnectionMode(self, mode): def User(self): return self._user - def setAuthority(self, authority): - self._authority = authority + @property + def _identifier(self): + return self._user.getContentIdentifier(self._authority, self.Id, self.Path, self.Title) # XComponent def dispose(self): @@ -179,9 +186,13 @@ def removeEventListener(self, listener): # XChild def getParent(self): - if self.IsRoot: - return None - return self._user.getContent(self.Path, self._authority) + content = None + try: + if not self.IsRoot: + content = self._user.getContent(self._authority, self.ParentId) + except Exception as e: + self._logger.logprb(SEVERE, 'Content', 'getParent()', 651, e, traceback.format_exc()) + return content def setParent(self, parent): raise NoSupportException('Parent can not be set', self) @@ -191,25 +202,31 @@ def addPropertiesChangeListener(self, names, listener): for name in names: if name not in self._propertiesListener: self._propertiesListener[name] = [] - if listener not in self._propertiesListener[name]: - self._propertiesListener[name].append(listener) + listeners = self._propertiesListener[name] + if listener not in listeners: + listeners.append(listener) def removePropertiesChangeListener(self, names, listener): for name in names: if name in self._propertiesListener: - if listener in self._propertiesListener[name]: - self._propertiesListener[name].remove(listener) + listeners = self._propertiesListener[name] + if listener in listeners: + listeners.remove(listener) # XContentCreator def queryCreatableContentsInfo(self): - return self.MetaData.get('CreatableContentsInfo') + return self._getCreatableContentsInfo() def createNewContent(self, info): - path = self._user.getContentPath(self.Path, self.Title, self.IsRoot) - return self._user.createNewContent(self.Id, self.Link, path, self._authority, info.Type) + self._logger.logprb(INFO, 'Content', 'createNewContent()', 661, self._identifier) + return self._user.createNewContent(self._authority, self.Id, self.Path, self.Title, info.Type) # XContent def getIdentifier(self): - identifier = self._user.getContentIdentifier(self._authority, self.Path, self.Title, self.IsRoot) - return identifier + try: + identifier = self._identifier + self._logger.logprb(INFO, 'Content', 'getIdentifier()', 641, identifier) + return Identifier(identifier) + except Exception as e: + self._logger.logprb(SEVERE, 'Content', 'getIdentifier()', 642, e, traceback.format_exc()) def getContentType(self): return self.MetaData.get('ContentType') def addContentEventListener(self, listener): @@ -222,18 +239,15 @@ def removeContentEventListener(self, listener): def createCommandIdentifier(self): print("Content.createCommandIdentifier() 1") return 1 - def execute(self, command, id, environment): - print("Content.execute() 1 Commande Name: %s ****************************************************************" % command.Name) - uri = self._user.getContentPath(self.Path, self.Title, self.IsRoot) - print("Content.execute() %s - %s - %s - IsFolder: %s" % (command.Name, uri, self.Id, self.IsFolder)) - msg = "command.Name: %s" % command.Name - self._logger.logp(INFO, 'Content', 'execute()', msg) - + def execute(self, command, cmdid, environment): + self._logger.logprb(INFO, 'Content', 'execute()', 636, command.Name, self._identifier) + print("Content.execute() commande: %s - url: %s - commandid: %s" % (command.Name, self._identifier, cmdid)) if command.Name == 'getCommandInfo': + self._logger.logprb(INFO, 'Content', 'execute()', 631, 'getCommandInfo', self.IsFolder) return CommandInfo(self._getCommandInfo()) elif command.Name == 'getPropertySetInfo': - return PropertySetInfo(self._propertySetInfo) + return PropertySetInfo(self._propertySetInfo, self._logger) elif command.Name == 'getPropertyValues': values = self._getPropertiesValues(command.Argument) @@ -244,19 +258,22 @@ def execute(self, command, id, environment): elif command.Name == 'delete': self.MetaData['Trashed'] = True - self._user.DataBase.updateContent(self._user.Id, self.Id, 'Trashed', True) + self._user.updateContent(self.Id, 'Trashed', True) elif command.Name == 'open': + print("Content.execute() open") + for property in command.Argument.Properties: + print("Content.execute() open Property: %s" % property.Name) try: + self._logger.logprb(INFO, 'Content', 'execute()', 631, 'open', self.IsFolder) print("Content.execute() open Mode: %s" % command.Argument.Mode) if self.IsFolder: print("Content.execute() open 1") select = self._getFolderContent(command.Argument.Properties) print("Content.execute() open 2") - msg += " IsFolder: %s" % self.IsFolder - self._logger.logp(INFO, 'Content', 'execute()', msg) + msg = " IsFolder: %s" % self.IsFolder print("Content.execute() open 3") - return DynamicResultSet(self._user, uri, self._authority, select) + return DynamicResultSet(self._user, self._authority, select) elif self.IsDocument: print("Content.execute() open 4") sf = getSimpleFile(self._ctx) @@ -278,32 +295,24 @@ def execute(self, command, id, environment): raise e elif command.Name == 'createNewContent' and self.IsFolder: + print("Content.execute() createNewContent") return self.createNewContent(command.Argument) elif command.Name == 'insert': + print("Content.execute() insert") # The Insert command is only used to create a new folder or a new document # (ie: File Save As). # It saves the content created by 'createNewContent' from the parent folder # right after the Title property is initialized + stream = command.Argument.Data + replace = command.Argument.ReplaceExisting + documentid = command.Argument.DocumentId + mimetype = command.Argument.MimeType + self._logger.logprb(INFO, 'Content', 'execute()', 635, replace, documentid, mimetype, self.IsFolder) print("Content.execute() insert 1 - %s - %s - %s" % (self.IsFolder, self.Id, self.MetaData.get('Title'))) - if self.IsFolder: - print("Content.execute() insert 2 ************** %s" % self.MetaData.get('MediaType')) - try: - if self._user.insertNewContent(self.MetaData): - print("Content.execute() insert 3") - # Need to consum the new Identifier if needed... - self._user.deleteNewIdentifier(self.Id) - print("Content.execute() insert 4") - except Exception as e: - msg = "Content.Insert() Error: %s" % traceback.print_exc() - print(msg) - raise e - - elif self.IsDocument: - stream = command.Argument.Data - replace = command.Argument.ReplaceExisting + if self.IsDocument: sf = getSimpleFile(self._ctx) target = self._user.getTargetUrl(self.Id) if sf.exists(target) and not replace: @@ -311,32 +320,42 @@ def execute(self, command, id, environment): if hasInterface(stream, 'com.sun.star.io.XInputStream'): sf.writeFile(target, stream) # For document type resources, the media type is always unknown... - mediatype = getMimeType(self._ctx, stream) - self.MetaData['MediaType'] = mediatype + mediatype = mimetype if mimetype else getMimeType(self._ctx, stream) stream.closeInput() - print("Content.execute() insert 2 ************** %s" % mediatype) - if self._user.insertNewContent(self.MetaData): - # Need to consum the new Identifier if needed... - self._user.deleteNewIdentifier(self.Id) - print("Content.execute() insert 3") + self.MetaData['MediaType'] = mediatype + print("Content.execute() insert 2 ************** mediatype: %s - mimetype: %s" % (mediatype, mimetype)) + + if self._user.insertNewContent(self._authority, self.MetaData): + print("Content.execute() insert 3 ") + # Need to consum the new Identifier if needed... + self._user.deleteNewIdentifier(self.Id) + print("Content.execute() insert 5") - elif command.Name == 'transfer' and self.IsFolder: + elif command.Name == 'transfer': + # see github/libreoffice/ucb/source/core/ucbcmds.cxx + self._logger.logprb(INFO, 'Content', 'execute()', 631, 'transfer', self.IsFolder) + title = command.Argument.NewTitle + source = command.Argument.SourceURL + move = command.Argument.MoveData + clash = command.Argument.NameClash + self._logger.logprb(INFO, 'Content', 'execute()', 633, title, source, move, clash) + if not self.IsFolder: + msg = "Couln't handle transfert, only Folder can handle transfert" + UnsupportedCommandException(msg, self) # Transfer command is used for document 'File Save' or 'File Save As' # NewTitle come from: # - Last segment path of 'XContent.getIdentifier().getContentIdentifier()' for OpenOffice # - Property 'Title' of 'XContent' for LibreOffice # If the content has been renamed, the last segment is the new Title of the content - title = command.Argument.NewTitle - source = command.Argument.SourceURL - move = command.Argument.MoveData - clash = command.Argument.NameClash print("Content.execute() transfert 1 %s - %s -%s - %s" % (title, source, move, clash)) # We check if 'NewTitle' is a child of this folder by recovering its ItemId itemid = self._user.DataBase.getChildId(self.Id, title) - if itemid is None: + if itemid is None or clash != OVERWRITE: print("Content.execute() transfert 2 %s" % itemid) # ItemId could not be found: 'NewTitle' does not exist in the folder... - # For new document (File Save As) we use commands: + # or NewTitle exist but we don't have the OVERWRITE flag set... + # When saving a new document with (File save) or when creating + # a new document with (File Save As) we use commands: # - createNewContent: for creating an empty new Content # - Insert at new Content for committing change # To execute these commands, we must throw an exception @@ -351,107 +370,40 @@ def execute(self, command, id, environment): sf.writeFile(target, inputstream) inputstream.closeInput() # We need to update the Size - self._user.DataBase.updateContent(self._user.Id, itemid, 'Size', sf.getSize(target)) + size = sf.getSize(target) + self._logger.logprb(INFO, 'Content', 'execute()', 634, self._identifier, size) + self._user.updateContent(itemid, 'Size', size) if move: - pass #must delete object + # TODO: must delete object + pass - elif command.Name == 'flush' and self.IsFolder: - pass + elif command.Name == 'update': + self._logger.logprb(INFO, 'Content', 'execute()', 631, 'update', self.IsFolder) + + elif command.Name == 'flush': + self._logger.logprb(INFO, 'Content', 'execute()', 631, 'flush', self.IsFolder) def abort(self, id): + print("Content.abort() 1") pass def releaseCommandIdentifier(self, id): + print("Content.releaseCommandIdentifier() 1") pass # Private methods - def _getMetaData(self, url): - if self._user.isRootPath(url): - itemid = self._user.RootId - else: - itemid = self._user.DataBase.getIdentifier(self._user, url) - if itemid is None: - msg = self._logger.resolveString(611, url) - raise IllegalIdentifierException(msg, self) - data = self._user.DataBase.getItem(self._user, itemid) - if data is None: - msg = self._logger.resolveString(612, itemid, url) - raise IllegalIdentifierException(msg, self) - return data + def _isNew(self): + return self._new - def _getCommandInfo(self): - commands = {} - t1 = uno.getTypeByName('com.sun.star.ucb.XCommandInfo') - commands['getCommandInfo'] = getCommandInfo('getCommandInfo', t1) - t2 = uno.getTypeByName('com.sun.star.beans.XPropertySetInfo') - commands['getPropertySetInfo'] = getCommandInfo('getPropertySetInfo', t2) - t3 = uno.getTypeByName('[]com.sun.star.beans.Property') - commands['getPropertyValues'] = getCommandInfo('getPropertyValues', t3) - t4 = uno.getTypeByName('[]com.sun.star.beans.PropertyValue') - commands['setPropertyValues'] = getCommandInfo('setPropertyValues', t4) - try: - t5 = uno.getTypeByName('com.sun.star.ucb.OpenCommandArgument3') - except RuntimeError as e: - t5 = uno.getTypeByName('com.sun.star.ucb.OpenCommandArgument2') - commands['open'] = getCommandInfo('open', t5) - try: - t6 = uno.getTypeByName('com.sun.star.ucb.InsertCommandArgument2') - except RuntimeError as e: - t6 = uno.getTypeByName('com.sun.star.ucb.InsertCommandArgument') - commands['insert'] = getCommandInfo('insert', t6) - if not self.IsRoot: - commands['delete'] = getCommandInfo('delete', uno.getTypeByName('boolean')) - try: - t7 = uno.getTypeByName('com.sun.star.ucb.TransferInfo2') - except RuntimeError as e: - t7 = uno.getTypeByName('com.sun.star.ucb.TransferInfo') - commands['transfer'] = getCommandInfo('transfer', t7) - commands['flush'] = getCommandInfo('flush') - print("Content._getCommandInfo() CanAddChild: %s **********************************************" % self.CanAddChild) - if self.CanAddChild: - t8 = uno.getTypeByName('com.sun.star.ucb.ContentInfo') - commands['createNewContent'] = getCommandInfo('createNewContent', t8) - return commands - - def _getPropertySetInfo(self): - RO = 0 if self._new else READONLY - properties = {} - properties['ContentType'] = getProperty('ContentType', 'string', BOUND | RO) - properties['MediaType'] = getProperty('MediaType', 'string', BOUND | READONLY) - properties['IsDocument'] = getProperty('IsDocument', 'boolean', BOUND | RO) - properties['IsFolder'] = getProperty('IsFolder', 'boolean', BOUND | RO) - properties['Title'] = getProperty('Title', 'string', BOUND | CONSTRAINED) - properties['Size'] = getProperty('Size', 'long', BOUND | RO) - created = getProperty('DateCreated', 'com.sun.star.util.DateTime', BOUND | READONLY) - properties['DateCreated'] = created - modified = getProperty('DateModified', 'com.sun.star.util.DateTime', BOUND | RO) - properties['DateModified'] = modified - properties['IsReadOnly'] = getProperty('IsReadOnly', 'boolean', BOUND | RO) - info = getProperty('CreatableContentsInfo','[]com.sun.star.ucb.ContentInfo', BOUND | RO) - properties['CreatableContentsInfo'] = info - properties['CasePreservingURL'] = getProperty('CasePreservingURL', 'string', BOUND | RO) - #properties['BaseURI'] = getProperty('BaseURI', 'string', BOUND | READONLY) - properties['TitleOnServer'] = getProperty('TitleOnServer', 'string', BOUND) - properties['IsHidden'] = getProperty('IsHidden', 'boolean', BOUND | RO) - properties['IsVolume'] = getProperty('IsVolume', 'boolean', BOUND | RO) - properties['IsRemote'] = getProperty('IsRemote', 'boolean', BOUND | RO) - properties['IsRemoveable'] = getProperty('IsRemoveable', 'boolean', BOUND | RO) - properties['IsFloppy'] = getProperty('IsFloppy', 'boolean', BOUND | RO) - properties['IsCompactDisc'] = getProperty('IsCompactDisc', 'boolean', BOUND | RO) - properties['IsVersionable'] = getProperty('IsVersionable', 'boolean', BOUND | RO) - properties['ConnectionMode'] = getProperty('ConnectionMode', 'short', BOUND | READONLY) - return properties + def _getCreatableContentsInfo(self): + return self._user.getCreatableContentsInfo(self.CanAddChild) if self.IsFolder else () def _getPropertiesValues(self, properties): values = [] for property in properties: value = None - if all((hasattr(property, 'Name'), - property.Name in self._propertySetInfo, - property.Name in self.MetaData)): - value = self.MetaData.get(property.Name) - msg = "Name: %s - Value: %s" % (property.Name, value) - level = INFO - print("content._getPropertiesValues(): %s: %s" % (property.Name, value)) + if (hasattr(property, 'Name') and + property.Name in self._propertySetInfo): + value, level, msg = self._getPropertyValue(property.Name) else: msg = "ERROR: Requested property: %s is not available" % property.Name level = SEVERE @@ -459,13 +411,30 @@ def _getPropertiesValues(self, properties): values.append(getNamedValue(property.Name, value)) return tuple(values) + def _getPropertyValue(self, name): + value = None + # Dynamic values + if name == 'CasePreservingURL': + if self._url is None: + value = self._identifier + else: + value = self._url + elif name == 'CreatableContentsInfo': + value = self._getCreatableContentsInfo() + else: + value = self.MetaData.get(name) + msg = "Name: %s - Value: %s" % (name, value) + print("content._getPropertiesValues(): %s: %s" % (name, value)) + return value, INFO, msg + + def _setPropertiesValues(self, environment, properties): try: results = [] for property in properties: - if all((hasattr(property, 'Name'), - hasattr(property, 'Value'), - property.Name in self._propertySetInfo)): + if (hasattr(property, 'Name') and + hasattr(property, 'Value') and + property.Name in self._propertySetInfo): result, level, msg = self._setPropertyValue(environment, property) else: msg = "ERROR: Requested property: %s is not available" % property.Name @@ -479,7 +448,6 @@ def _setPropertiesValues(self, environment, properties): msg = "Content._setPropertiesValues() Error: %s" % traceback.format_exc() print(msg) - def _setPropertyValue(self, environment, property): name, value = property.Name, property.Value print("Content._setPropertyValue() 1 %s - %s" % (name, value)) @@ -492,67 +460,71 @@ def _setPropertyValue(self, environment, property): result, level, msg = self._setProperty(environment, name, value) return result, level, msg - def _setProperty(self, environment, name, value): if name == 'Title': result, level, msg = self._setTitle(environment, value) + elif name == 'CasePreservingURL': + result, level, msg = self._setUrl(environment, value) else: self.MetaData[name] = value - msg = "Set property: %s value: %s" % (name, value) + msg = "Content: %s set property: %s value: %s" % (self._identifier, name, value) level = INFO result = None return result, level, msg def _setTitle(self, environment, title): - print("Identifier.setTitle() 2 Title: %s" % (title, )) - url = self.getIdentifier().getContentIdentifier() + print("Content.setTitle() 2 Title: %s" % (title, )) if u'~' in title: msg = "Can't set property: Title value: %s contains invalid character: '~'." % title level = SEVERE - data = getPropertyValueSet({'Uri': url,'ResourceName': title}) - error = getInteractiveAugmentedIOException(msg, environment, 'QUERY', 'INVALID_CHARACTER', data) + args = {'Uri': uno.Any('string', self._identifier), + 'ResourceName': uno.Any('string', title)} + error = getInteractiveAugmentedIOException(msg, environment, + 'QUERY', 'INVALID_CHARACTER', + getPropertyValueSet(args)) result = uno.Any('com.sun.star.ucb.InteractiveAugmentedIOException', error) elif not self._user.Provider.SupportDuplicate and self._user.DataBase.hasTitle(self._user.Id, self.ParentId, title): - print("Identifier.setTitle() 3 Title: %s" % (title, )) + print("Content.setTitle() 3 Title: %s" % (title, )) msg = "Can't set property: %s value: %s - Name Clash Error" % ('Title', title) level = SEVERE - data = getPropertyValueSet({'TargetFolderURL': url, + data = getPropertyValueSet({'TargetFolderURL': self._identifier, 'ClashingName': title, 'ProposedNewName': '%s(1)' % title}) - #data = getPropertyValueSet({'Uri': self.getIdentifier().getContentIdentifier(),'ResourceName': title}) + #data = getPropertyValueSet({'Uri': self._identifier,'ResourceName': title}) error = getInteractiveAugmentedIOException(msg, environment, 'QUERY', 'ALREADY_EXISTING', data) result = uno.Any('com.sun.star.ucb.InteractiveAugmentedIOException', error) else: - print("Identifier.setTitle() 4 Title: %s" % (title, )) + print("Content.setTitle() 4 Title: %s" % (title, )) # FIXME: When you change Title you must change also the Identifier.getContentIdentifier() - if not self._new: - # And as the uri changes we also have to clear this Identifier from the cache. - # New Identifier bypass the cache: they are created by the folder's Identifier - # (ie: createNewIdentifier()) and have same uri as this folder. - self._user.expireIdentifier(self.getIdentifier()) if self._user.Provider.SupportDuplicate: newtitle = self._user.DataBase.getNewTitle(title, self.ParentId, self.IsFolder) else: newtitle = title - print("Identifier.setTitle() 5 Title: %s - New Title: %s" % (title, newtitle)) + print("Content.setTitle() 5 Title: %s - New Title: %s" % (title, newtitle)) self.MetaData['Title'] = title self.MetaData['TitleOnServer'] = newtitle # If the identifier is new then the content is not yet in the database. # It will be inserted by the insert command of the XCommandProcessor2.execute() - if not self._new: - self._user.DataBase.updateContent(self._user.Id, self.Id, 'Title', title) - path = self._user.getContentPath(self.Path, newtitle, self.IsRoot) - print("Identifier.setTitle() 3 Path: %s - Url: %s" % (path, self.getIdentifier().getContentIdentifier())) + # But we must make this content accessible by an appropriate entry in the user paths cache + if not self._isNew(): + self._user.updateContent(self.Id, 'Title', title) + print("Content.setTitle() 7 Url: %s" % self._identifier) msg = "Set property: %s value: %s" % ('Title', title) level = INFO result = None return result, level, msg + def _setUrl(self, environment, url): + print("Content.setUrl() 2 Url: %s" % (url, )) + self._url = url + msg = "Set property: %s value: %s" % ('CasePreservingURL', url) + return None, INFO, msg + def _getFolderContent(self, properties): try: select, updated = self._updateFolderContent(properties) if updated: - loaded = self._user.DataBase.updateConnectionMode(self._user.Id, self.Id, OFFLINE, ONLINE) + loaded = self._user.updateConnectionMode(self.Id, OFFLINE) self.setConnectionMode(loaded) return select except Exception as e: @@ -564,22 +536,19 @@ def _updateFolderContent(self, properties): updated = False print("Content._updateFolderContent() 1 ConnectionMode: %s - SessionMode: %s" % (self.ConnectionMode,self._user.SessionMode)) if ONLINE == self.ConnectionMode == self._user.SessionMode: - url = self._user.getContentPath(self.Path, self.Title, self.IsRoot) - self._logger.logprb(INFO, 'Content', '_updateFolderContent()', 621, url) - print("Content._updateFolderContent() 2 Url: %s" % url) + self._logger.logprb(INFO, 'Content', '_updateFolderContent()', 621, self._identifier) + print("Content._updateFolderContent() 2 Url: %s" % self._identifier) updated = self._user.Provider.updateFolderContent(self) - mode = self._user.SessionMode - scheme = self._user.getContentScheme(self._authority) - select = self._user.DataBase.getChildren(self._user.Name, self.Id, properties, mode, scheme) + select = self._user.getChildren(self._authority, self.Id, properties) return select, updated def _getDocumentContent(self, sf): size = 0 - url = self._user.Provider.SourceURL + g_separator + self.Id + url = self._user.getTargetUrl(self.Id) if self.ConnectionMode == OFFLINE and sf.exists(url): return url, sf.getSize(url) if self._user.Provider.getDocumentContent(self, url): - loaded = self._user.DataBase.updateConnectionMode(self._user.Id, self.Id, OFFLINE, ONLINE) + loaded = self._user.updateConnectionMode(self.Id, OFFLINE) self.setConnectionMode(loaded) else: pass @@ -587,3 +556,51 @@ def _getDocumentContent(self, sf): return url, sf.getSize(url) + def _getCommandInfo(self): + commands = {} + if self.CanAddChild: + commands['createNewContent'] = getCommandInfo('createNewContent', 'com.sun.star.ucb.ContentInfo') + if not self.IsRoot: + commands['delete'] = getCommandInfo('delete', 'boolean') + commands['flush'] = getCommandInfo('flush') + commands['getCommandInfo'] = getCommandInfo('getCommandInfo', 'com.sun.star.ucb.XCommandInfo') + commands['getPropertySetInfo'] = getCommandInfo('getPropertySetInfo', 'com.sun.star.beans.XPropertySetInfo') + commands['getPropertyValues'] = getCommandInfo('getPropertyValues', '[]com.sun.star.beans.Property') + commands['insert'] = getCommandInfo('insert', 'com.sun.star.ucb.InsertCommandArgument2') + commands['open'] = getCommandInfo('open', 'com.sun.star.ucb.OpenCommandArgument3') + commands['setPropertyValues'] = getCommandInfo('setPropertyValues', '[]com.sun.star.beans.PropertyValue') + if self.IsFolder: + commands['transfer'] = getCommandInfo('transfer', 'com.sun.star.ucb.TransferInfo2') + commands['update'] = getCommandInfo('update', 'com.sun.star.ucb.OpenCommandArgument3') + return commands + + def _getPropertySetInfo(self): + RO = 0 if self._isNew() else READONLY + properties = {} + #properties['BaseURI'] = getProperty('BaseURI', 'string', BOUND | RO) + properties['CasePreservingURL'] = getProperty('CasePreservingURL', 'string', BOUND | RO) + properties['ConnectionMode'] = getProperty('ConnectionMode', 'short', BOUND | READONLY) + properties['ContentType'] = getProperty('ContentType', 'string', BOUND | RO) + properties['CreatableContentsInfo'] = getProperty('CreatableContentsInfo', '[]com.sun.star.ucb.ContentInfo', BOUND | RO) + #properties['CmisProperties'] = getProperty('CmisProperties', '[]com.sun.star.document.CmisProperty', BOUND | RO) + properties['DateCreated'] = getProperty('DateCreated', 'com.sun.star.util.DateTime', BOUND | READONLY) + properties['DateModified'] = getProperty('DateModified', 'com.sun.star.util.DateTime', BOUND | RO) + properties['IsCompactDisc'] = getProperty('IsCompactDisc', 'boolean', BOUND | RO) + properties['IsDocument'] = getProperty('IsDocument', 'boolean', BOUND | RO) + properties['IsFloppy'] = getProperty('IsFloppy', 'boolean', BOUND | RO) + properties['IsFolder'] = getProperty('IsFolder', 'boolean', BOUND | RO) + properties['IsHidden'] = getProperty('IsHidden', 'boolean', BOUND | RO) + properties['IsReadOnly'] = getProperty('IsReadOnly', 'boolean', BOUND | RO) + properties['IsRemote'] = getProperty('IsRemote', 'boolean', BOUND | RO) + properties['IsRemoveable'] = getProperty('IsRemoveable', 'boolean', BOUND | RO) + properties['IsVersionable'] = getProperty('IsVersionable', 'boolean', BOUND | RO) + properties['IsVolume'] = getProperty('IsVolume', 'boolean', BOUND | RO) + properties['MediaType'] = getProperty('MediaType', 'string', BOUND | READONLY) + properties['ObjectId'] = getProperty('ObjectId', 'string', BOUND | RO) + #properties['ParentId'] = getProperty('ParentId', 'string', BOUND | READONLY) + properties['Size'] = getProperty('Size', 'hyper', BOUND | RO) + #properties['TargetURL'] = getProperty('TargetURL', 'string', BOUND | RO) + properties['Title'] = getProperty('Title', 'string', BOUND | CONSTRAINED) + properties['TitleOnServer'] = getProperty('TitleOnServer', 'string', BOUND) + return properties + diff --git a/uno/lib/uno/ucb/ucp/contenthelper.py b/uno/lib/uno/ucb/ucp/contenthelper.py index a424f729..0ee474b7 100644 --- a/uno/lib/uno/ucb/ucp/contenthelper.py +++ b/uno/lib/uno/ucb/ucp/contenthelper.py @@ -111,11 +111,11 @@ def getCommand(name, argument, handle=-1): command.Argument = argument return command -def getCommandInfo(name, unotype=None, handle=-1): +def getCommandInfo(name, typename='', handle=-1): command = uno.createUnoStruct('com.sun.star.ucb.CommandInfo') command.Name = name - if unotype: - command.ArgType = unotype + if typename: + command.ArgType = uno.getTypeByName(typename) command.Handle = handle return command diff --git a/uno/lib/uno/ucb/ucp/contentlib.py b/uno/lib/uno/ucb/ucp/contentlib.py index 6a8aef40..a0812c2c 100644 --- a/uno/lib/uno/ucb/ucp/contentlib.py +++ b/uno/lib/uno/ucb/ucp/contentlib.py @@ -158,15 +158,14 @@ def _getValue(self, index): class DynamicResultSet(unohelper.Base, XDynamicResultSet): - def __init__(self, user, path, authority, select): + def __init__(self, user, authority, select): self._user = user - self._path = path self._authority = authority self._select = select # XDynamicResultSet def getStaticResultSet(self): - return ContentResultSet(self._user, self._path, self._authority, self._select) + return ContentResultSet(self._user, self._authority, self._select) def setListener(self, listener): pass def connectToCache(self, cache): @@ -181,10 +180,9 @@ class ContentResultSet(unohelper.Base, XRow, XResultSetMetaDataSupplier, XContentAccess): - def __init__(self, user, path, authority, select): + def __init__(self, user, authority, select): try: self._user = user - self._path = path self._authority = authority result = select.executeQuery() result.last() @@ -194,7 +192,7 @@ def __init__(self, user, path, authority, select): self._result = result print("ContentResultSet.__init__() %s" % self.RowCount) except Exception as e: - msg = "Error: %s" % traceback.print_exc() + msg = "Error: %s - %s" % (e, traceback.format_exc()) print(msg) # XResultSet @@ -287,14 +285,14 @@ def queryContentIdentifierString(self): def queryContentIdentifier(self): return Identifier(self.queryContentIdentifierString()) def queryContent(self): - title = self._result.getString(self._result.findColumn('Title')) - path = self._user.getContentPath(self._path, title) - return self._user.getContent(path, self._authority) + url = self.queryContentIdentifierString() + itemid = self._user.getItemByUrl(url) + return self._user.getContent(self._authority, itemid) def _getPropertySetInfo(self): properties = {} readonly = uno.getConstantByName('com.sun.star.beans.PropertyAttribute.READONLY') - properties['RowCount'] = getProperty('RowCount', 'long', readonly) + properties['RowCount'] = getProperty('RowCount', 'long', readonly) properties['IsRowCountFinal'] = getProperty('IsRowCountFinal', 'boolean', readonly) return properties diff --git a/uno/lib/uno/ucb/ucp/provider.py b/uno/lib/uno/ucb/ucp/provider.py index 4f937dbb..501689e2 100644 --- a/uno/lib/uno/ucb/ucp/provider.py +++ b/uno/lib/uno/ucb/ucp/provider.py @@ -294,18 +294,27 @@ def createFolder(self, user, itemid, item): response = user.Request.execute(parameter) return self.mergeNewFolder(user, itemid, response) - def uploadFile(self, user, item, data, chunk, retry, delay, new=False): + def uploadFile(self, code, user, item, data, created, chunk, retry, delay, new=False): method = 'getNewUploadLocation' if new else 'getUploadLocation' parameter = self.getRequestParameter(user.Request, method, data) response = user.Request.execute(parameter) + if not response.Ok: + msg = response.Text + response.close() + return None, (code +1, data.get('Title'), msg) location = self.parseUploadLocation(response) - if location: - parameter = self.getRequestParameter(user.Request, 'getUploadStream', location) - url = self.SourceURL + g_separator + item - response = user.Request.upload(parameter, url, chunk, retry, delay) - if response: - return self.updateItemId(user.DataBase, item, response) - return None + if location is None: + return None, (code +2, data.get('Title')) + parameter = self.getRequestParameter(user.Request, 'getUploadStream', location) + url = self.SourceURL + g_separator + item + response = user.Request.upload(parameter, url, chunk, retry, delay) + if not response.Ok: + msg = response.Text + response.close() + return None, (code +3, data.get('Title'), msg) + newid = self.updateItemId(user.DataBase, item, response) + return newid, (code, data.get('Title'), created, data.get('Size')) + def updateTitle(self, request, itemid, item): parameter = self.getRequestParameter(request, 'updateTitle', item) diff --git a/uno/lib/uno/ucb/ucp/user.py b/uno/lib/uno/ucb/ucp/user.py index e0dcf8f6..6143d751 100644 --- a/uno/lib/uno/ucb/ucp/user.py +++ b/uno/lib/uno/ucb/ucp/user.py @@ -57,6 +57,7 @@ from ..unotool import createService from ..unotool import getProperty +from ..unotool import getUriFactory from ..database import DataBase @@ -77,16 +78,16 @@ class User(): - def __init__(self, ctx, logger, source, database, provider, name, sync, lock, password=''): + def __init__(self, ctx, source, logger, database, provider, sync, name, password=''): self._ctx = ctx self._name = name self._sync = sync - self._lock = lock self._expired = None self.Provider = provider #self.CanAddChild = not self.Provider.GenerateIds self.CanAddChild = True self._logger = logger + self._factory = None metadata = database.selectUser(name) new = metadata is None if not new: @@ -121,11 +122,13 @@ def __init__(self, ctx, logger, source, database, provider, name, sync, lock, pa raise IllegalIdentifierException(msg, source) self.Request = request self.MetaData = metadata - self.DataBase = DataBase(ctx, logger, database.Url, sync, name, password) - self._identifiers = {} + self.DataBase = DataBase(ctx, logger, database.Url, name, password) + rootid = metadata.get('RootId') + self._ids = {'': rootid, '/': rootid} + self._paths = {} self._contents = {} - self._contents[self.RootId] = Content(ctx, self) if new: + # Start Replicator for pushing changes… self._sync.set() self._logger.logprb(INFO, 'User', '__init__()', 505) @@ -164,45 +167,54 @@ def TimeStamp(self, timestamp): def setToken(self, token): self.MetaData['Token'] = token - # method called from DataSource.queryContent(), Content.getParent() and ContentResultSet.queryContent() - def getContent(self, path, authority): - if self._expired is not None and path.startswith(self._expired): - self._removeIdentifiers() - if self.isRootPath(path): - itemid = self.RootId + # method called from ContentResultSet.queryContent() + def getItemByUrl(self, url): + uri = self._getUriFactory().parse(url) + return self.getItemByUri(uri) + + # method called from DataSource.queryContent() + def getItemByUri(self, uri): + path = uri.getPath() + if path in self._ids: + itemid = self._ids[path] else: - itemid = self._identifiers.get(path) - content = None if itemid is None else self._contents.get(itemid) - if content is None: - content = Content(self._ctx, self, authority, path) - self._identifiers[path] = content.Id - self._contents[content.Id] = content + itemid = self.DataBase.getItemId(self.Id, path) + if itemid is not None: + self._ids[path] = itemid + self._paths[itemid] = path + return itemid + + # method called from DataSource.queryContent(), Content.getParent() and ContentResultSet.queryContent() + def getContent(self, authority, itemid): + content = None + if itemid in self._contents: + data = self._contents[itemid] else: - content.setAuthority(authority) + data = self.DataBase.getItem(self.Id, self.RootId, itemid) + if data is not None: + self._contents[itemid] = data + if data is not None: + content = Content(self._ctx, self, authority, data) return content - def isRootPath(self, path): - return path in ('', g_separator) - - def getContentIdentifier(self, authority, path, title, isroot): - url = self.getContentScheme(authority) + self.getContentPath(path, title, isroot, g_separator) - return Identifier(url) + # method called from Content._identifier + def getContentIdentifier(self, authority, itemid, path, title): + identifier = self._getContentScheme(authority) + if itemid != self.RootId: + identifier += path + title + else: + identifier += g_separator + return identifier - def getContentPath(self, path, title, isroot=False, rootpath=''): - return rootpath if isroot else path + g_separator + title + def createNewContent(self, authority, parentid, path, title, contentype): + data = self._getNewContent(parentid, path, title, contentype) + content = Content(self._ctx, self, authority, data, True) + print("User.createNewContent()") + return content def getTargetUrl(self, itemid): return self.Provider.SourceURL + g_separator + itemid - def expireIdentifier(self, identifier): - # FIXME: We need to remove all the child of a resource (if it's a folder) - self._expired = identifier.getContentIdentifier() - - def createNewContent(self, id, link, path, authority, contentype): - data = self._getNewContent(id, link, path, contentype) - content = Content(self._ctx, self, authority, path, data) - return content - def getCreatableContentsInfo(self, canaddchild): content = [] if self.CanAddChild and canaddchild: @@ -216,7 +228,7 @@ def getCreatableContentsInfo(self, canaddchild): def getDocumentContent(self, sf, content, size): size = 0 itemid = content.getValue('Id') - url = self.Provider.SourceURL + g_separator + itemid + url = self.getTargetUrl() if content.getValue('ConnectionMode') == OFFLINE and sf.exists(url): size = sf.getSize(url) return url, size @@ -228,63 +240,84 @@ def getDocumentContent(self, sf, content, size): self._logger.logprb(SEVERE, 'User', 'getDocumentContent()', 511, e, traceback.format_exc()) else: size = sf.getSize(url) - loaded = self.DataBase.updateConnectionMode(self.Id, itemid, OFFLINE, ONLINE) + loaded = self.updateConnectionMode(itemid, OFFLINE) content.setConnectionMode(loaded) finally: stream.closeInput() return url, size - def insertNewContent(self, content): + def updateContent(self, itemid, property, value): + updated, clear = self.DataBase.updateContent(self.Id, itemid, property, value) + if updated: + # Start Replicator for pushing changes… + self._sync.set() + if clear: + # if Title as been changed then we need to clear identifier cache + self._ids = {'': self.RootId, '/': self.RootId} + self._paths = {} + + def insertNewContent(self, authority, content): timestamp = currentDateTimeInTZ() - self.DataBase.insertNewContent(self.Id, content, timestamp) - return True + status = self.DataBase.insertNewContent(self.Id, content, timestamp) + if status : + # Start Replicator for pushing changes… + self._sync.set() + return status def deleteNewIdentifier(self, itemid): if self.Provider.GenerateIds: self.DataBase.deleteNewIdentifier(self.Id, itemid) - def getContentScheme(self, authority): + def getChildren(self, authority, itemid, properties): + scheme = self._getContentScheme(authority) + return self.DataBase.getChildren(itemid, properties, self.SessionMode, scheme) + + def updateConnectionMode(self, itemid, mode): + return self.DataBase.updateConnectionMode(self.Id, itemid, mode) + + # Private methods + def _getContentScheme(self, authority): name = self.Name if authority else '' return '%s://%s' % (g_scheme, name) - def _getNewContent(self, parentid, link, path, contentype): + def _getUriFactory(self): + if self._factory is None: + self._factory = getUriFactory(self._ctx) + return self._factory + + def _getNewContent(self, parentid, path, title, contentype): timestamp = currentUnoDateTime() isfolder = self.Provider.isFolder(contentype) isdocument = self.Provider.isDocument(contentype) itemid = self._getNewIdentifier() - data = {} - data['Id'] = itemid - data['ParentId'] = parentid - data['Path'] = path - data['ObjectId'] = itemid - data['Title'] = '' - data['TitleOnServer'] = '' - data['DateCreated'] = timestamp - data['DateModified'] = timestamp - data['ContentType'] = contentype - mediatype = '' if isdocument else contentype - data['MediaType'] = mediatype - data['Link'] = link - data['Size'] = 0 - data['Trashed'] = False - data['IsRoot'] = False - data['IsFolder'] = isfolder - data['IsLink'] = False - data['IsDocument'] = isdocument - data['CanAddChild'] = isfolder - data['CanRename'] = True - data['IsReadOnly'] = False - data['IsVersionable'] = isdocument - data['ConnectionMode'] = True - data['BaseURI'] = path - data['CasePreservingURL'] = '' - data['IsHidden'] = False - data['IsVolume'] = False - data['IsRemote'] = False - data['IsRemoveable'] = False - data['IsFloppy'] = False - data['IsCompactDisc'] = False - data['CreatableContentsInfo'] = self.getCreatableContentsInfo(isfolder) + data = {'ConnectionMode': 1, + 'ContentType': contentype, + 'DateCreated': timestamp, + 'DateModified': timestamp, + 'IsCompactDisc': False, + 'IsDocument': isdocument, + 'IsFloppy': False, + 'IsFolder': isfolder, + 'IsHidden': False, + 'IsReadOnly': False, + 'IsRemote': False, + 'IsRemoveable': False, + 'IsVersionable': isdocument, + 'IsVolume': False, + 'MediaType': '' if isdocument else contentype, + 'ObjectId': itemid, + 'ParentId': parentid, + 'Size': 0, + 'Title': '', + 'TitleOnServer': '', + 'Id': itemid, + 'Path': self._getPath(parentid, path, title), + 'Link': '', + 'Trashed': False, + 'IsRoot': False, + 'IsLink': False, + 'CanAddChild': isfolder, + 'CanRename': True} return data def _getNewIdentifier(self): @@ -294,11 +327,10 @@ def _getNewIdentifier(self): identifier = binascii.hexlify(uno.generateUuid().value).decode('utf-8') return identifier - def _removeIdentifiers(self): - for url in tuple(self._identifiers.keys()): - if url.startswith(self._expired): - with self._lock: - if url in self._identifiers: - del self._identifiers[url] - self._expired = None + def _getPath(self, itemid, path, title): + if itemid != self.RootId: + path += title + g_separator + else: + path = g_separator + return path diff --git a/uno/lib/uno/unolib/unolib.py b/uno/lib/uno/unolib/unolib.py index b88d7a61..3b77b0f8 100644 --- a/uno/lib/uno/unolib/unolib.py +++ b/uno/lib/uno/unolib/unolib.py @@ -30,6 +30,9 @@ import uno import unohelper +from com.sun.star.logging.LogLevel import INFO +from com.sun.star.logging.LogLevel import SEVERE + from com.sun.star.beans import XPropertySet from com.sun.star.beans import XPropertySetInfo from com.sun.star.beans import XPropertiesChangeNotifier @@ -40,23 +43,26 @@ class PropertySetInfo(unohelper.Base, XPropertySetInfo): - def __init__(self, properties=None): + def __init__(self, properties=None, logger=None): if properties is None: - self.properties = {} - else: - self.properties = properties + properties = {} + self.properties = properties + self._logger = logger # XPropertySetInfo def getProperties(self): return tuple(self.properties.values()) def getPropertyByName(self, name): - print("PropertySetInfo.getPropertyByName() %s" % name) + if self._logger is not None: + self._logger.logprb(INFO, 'PropertySetInfo', 'getPropertyByName()', 711, name) if name in self.properties: return self.properties[name] raise UnknownPropertyException("UnknownPropertyException", None) def hasPropertyByName(self, name): - print("PropertySetInfo.hasPropertyByName() %s" % name) - return name in self.properties + has = name in self.properties + if self._logger is not None: + self._logger.logprb(INFO, 'PropertySetInfo', 'hasPropertyByName()', 721, name, has) + return has class PropertySet(XPropertySet): diff --git a/uno/resource/database/dbqueries_en_US.properties b/uno/resource/database/dbqueries_en_US.properties index 01322ce0..ab1fdc81 100644 --- a/uno/resource/database/dbqueries_en_US.properties +++ b/uno/resource/database/dbqueries_en_US.properties @@ -1,2 +1,2 @@ 100=getSqlQuery() -101=ERROR: Query '%s' not found!!! +101=ERROR: Query '{}' not found!!! diff --git a/uno/resource/database/dbqueries_fr_FR.properties b/uno/resource/database/dbqueries_fr_FR.properties index 721ebb63..a0ffb2b5 100644 --- a/uno/resource/database/dbqueries_fr_FR.properties +++ b/uno/resource/database/dbqueries_fr_FR.properties @@ -1,2 +1,2 @@ 100=getSqlQuery() -101=ERREUR: La requ\u00eate: '%s' est introuvable !!! +101=ERREUR: La requ\u00eate: '{}' est introuvable !!! diff --git a/uno/resource/database/dbtool_en_US.properties b/uno/resource/database/dbtool_en_US.properties index d6bed705..b2a05f45 100644 --- a/uno/resource/database/dbtool_en_US.properties +++ b/uno/resource/database/dbtool_en_US.properties @@ -1,3 +1,3 @@ 100=checkDataBase() 101=DataBase ERROR -102=Hsqldb database driver: %s is not the correct version!!!\nHsqldb requiered driver version: %s - loaded version: %s +102=Hsqldb database driver: {} is not the correct version!!!\nHsqldb requiered driver version: {} - loaded version: {} diff --git a/uno/resource/database/dbtool_fr_FR.properties b/uno/resource/database/dbtool_fr_FR.properties index e98707b0..94cbce2b 100644 --- a/uno/resource/database/dbtool_fr_FR.properties +++ b/uno/resource/database/dbtool_fr_FR.properties @@ -1,3 +1,3 @@ 100=checkDataBase() 101=ERREUR de base de donn\u00e9es -102=Le pilote Hsqldb: %s n'est pas de la bonne version!!!\nLe pilote Hsqldb n\u00e9cessite la version: %s - la version charg\u00e9e: %s +102=Le pilote Hsqldb: {} n'est pas de la bonne version!!!\nLe pilote Hsqldb n\u00e9cessite la version: {} - la version charg\u00e9e: {} diff --git a/uno/resource/logger/Logger_en_US.properties b/uno/resource/logger/Logger_en_US.properties index a7dcc969..0799d500 100644 --- a/uno/resource/logger/Logger_en_US.properties +++ b/uno/resource/logger/Logger_en_US.properties @@ -1,33 +1,14 @@ 110=Logger.logInfos() -111=Python version: %s -112=Python Path: %s - -120=The import of six module threw an exception: %s, producing a series of exceptions: %s -121=six module version: %s installed at location: %s -122=The import of ssl module threw an exception: %s, producing a series of exceptions: %s -123=ssl module version: %s installed at location: %s -124=The import of idna module threw an exception: %s, producing a series of exceptions: %s -125=idna module version: %s installed at location: %s -126=The import of charset_normalizer module threw an exception: %s, producing a series of exceptions: %s -127=charset_normalizer module version: %s installed at location: %s -128=The import of certifi module threw an exception: %s, producing a series of exceptions: %s -129=certifi module version: %s installed at location: %s -130=The import of urllib3 module threw an exception: %s, producing a series of exceptions: %s -131=urllib3 module version: %s installed at location: %s -132=The import of requests module threw an exception: %s, producing a series of exceptions: %s -133=requests module version: %s installed at location: %s -134=The import of lxml module threw an exception: %s, producing a series of exceptions: %s -135=lxml module version: %s installed at location: %s -136=The import of ijson module threw an exception: %s, producing a series of exceptions: %s -137=ijson module version: %s installed at location: %s -138=The import of selenium module threw an exception: %s, producing a series of exceptions: %s -139=selenium module version: %s installed at location: %s -140=The import of webdriver_manager module threw an exception: %s, producing a series of exceptions: %s -141=webdriver_manager module version: %s installed at location: %s - -150=LogWrapper._getResourceMessage() -151=ERROR: ResourceId: %s not found in file: %s/%s - -160=LogController.clearLogger() -161=Logger has been cleared... +111=Python version: {} +112=Python Path: {} +113=The import of {} module threw an exception: {}, producing a series of exceptions: {} +114={} module version {} is installed at location: {} +115={} module version {} installed at location: {} seem to be outdated minimum version is: {} +116={} module installed at location: {} has attributes: {} + +120=LogWrapper._getResourceMessage() +121=ERROR: ResourceId: {} not found in file: {}/{} + +130=LogController.clearLogger() +131=Logger has been cleared... diff --git a/uno/resource/logger/Logger_fr_FR.properties b/uno/resource/logger/Logger_fr_FR.properties index 410b2cea..830973eb 100644 --- a/uno/resource/logger/Logger_fr_FR.properties +++ b/uno/resource/logger/Logger_fr_FR.properties @@ -1,33 +1,14 @@ 110=Logger.logInfos() -111=Version de Python: %s -112=Python Path: %s - -120=L'importation du module six a gnr une exception: %s, produisant une srie d'exceptions: %s -121=Version du module six: %s install l'emplacement: %s -122=L'importation du module ssl a gnr une exception: %s, produisant une srie d'exceptions: %s -123=Version du module ssl: %s install l'emplacement: %s -124=L'importation du module idna a gnr une exception: %s, produisant une srie d'exceptions: %s -125=Version du module idna: %s install l'emplacement: %s -126=L'importation du module charset_normalizer a gnr une exception: %s, produisant une srie d'exceptions: %s -127=Version du module charset_normalizer: %s install l'emplacement: %s -128=L'importation du module certifi a gnr une exception: %s, produisant une srie d'exceptions: %s -129=Version du module certifi: %s install l'emplacement: %s -130=L'importation du module urllib3 a gnr une exception: %s, produisant une srie d'exceptions: %s -131=Version du module urllib3: %s install l'emplacement: %s -132=L'importation du module requests a gnr une exception: %s, produisant une srie d'exceptions: %s -133=Version du module requests: %s install l'emplacement: %s -134=L'importation du module lxml a gnr une exception: %s, produisant une srie d'exceptions: %s -135=Version du module lxml: %s install l'emplacement: %s -136=L'importation du module ijson a gnr une exception: %s, produisant une srie d'exceptions: %s -137=Version du module ijson: %s install l'emplacement: %s -138=L'importation du module selenium a gnr une exception: %s, produisant une srie d'exceptions: %s -139=Version du module selenium: %s install l'emplacement: %s -140=L'importation du module webdriver_manager a gnr une exception: %s, produisant une srie d'exceptions: %s -141=Version du module webdriver_manager: %s install l'emplacement: %s - -150=LogWrapper._getResourceMessage() -151=ERREUR: La ResourceId: %s est introuvable dans le fichier : %s/%s - -160=LogController.clearLogger() -161=La journalisation a t effac... +111=Version de Python: {} +112=Python Path: {} +113=L'importation du module {} a gnr une exception: {}, produisant une srie d'exceptions: {} +114=Le module {} version {} est install l'emplacement: {} +115=Le module {} version {} install l'emplacement: {} semble tre obsolte, la version minimale est: {} +116=Le module {} install l'emplacement: {} a les proprites suivantes: {} + +120=LogWrapper._getResourceMessage() +121=ERREUR: La ResourceId: {} est introuvable dans le fichier : {}/{} + +130=LogController.clearLogger() +131=La journalisation a t effac... diff --git a/uno/resource/ucb/ContentProvider_en_US.properties b/uno/resource/ucb/ContentProvider_en_US.properties index d2753fdf..7fde473e 100644 --- a/uno/resource/ucb/ContentProvider_en_US.properties +++ b/uno/resource/ucb/ContentProvider_en_US.properties @@ -1,71 +1,103 @@ 100=ContentProvider.__init__() -101=ContentProvider: %s Loading completed +101=ContentProvider: {} Loading completed 200=ContentProvider.__init__() -201=ParameterizedProvider%s Loading completed +201=ParameterizedProvider{} Loading completed 210=ContentProvider.createContentIdentifier() -211=Identifier: %s -> %s +211=Identifier: {} -> {} 220=ContentProvider._getDataSource() -221=The extension %s was not found.%sYou must install this extension to use %s. -222=Version %s of extension %s is obsolete.%sYou need to update this extension to version: %s. -223=Unable to connect to URL: %s%sAn SQLException was thrown with the message: %s -224=HsqlDB driver version %s is obsolete.%sYou need to update this driver to version %s or higher. +221={} - Installation error +222=The extension {} was not found. You must install this extension to use {}. +223={} - Configuration error +224=Version {} of extension {} is obsolete. You need to update this extension to version: {}. +225={} - Connection error +226=Unable to connect to URL: {}. An SQLException was thrown with the message: {} +227={} - Configuration error +228=HsqlDB driver version {} is obsolete.You need to update this driver to version {} or higher. 230=ContentProvider.queryContent() -231=Identitifer: %s ... Completed -232=IllegalIdentifierException: %s -233=Unexpected python exception with traceback: %s +231=Identitifer: {} ... Completed +232=IllegalIdentifierException: {} +233=Unexpected python exception with traceback: {} 240=ContentProvider.compareContentIds() -241=Identifiers: %s - %s ... seem to be the same -242=Identifiers: %s - %s ... doesn't seem to be the same +241=Identifiers: {} - {} ... seem to be the same +242=Identifiers: {} - {} ... doesn't seem to be the same 300=DataSource.__init__() 301=DataSource: Loading completed +310=DataSource.queryContent() +311=Error: Unable to load content with an incomplete Identifier: {} + 320=DataSource._getUser() -321=Error: Unable to load content with an invalid Identifier: %s -322=Error: Unable to retrieve User from Identifier: %s -323=Error: User: %s canceled OAuth2 Wizard! +321=Error: Unable to load content with an invalid Identifier: {} +322=Error: Unable to retrieve User from Identifier: {} +323=Error: User: {} canceled OAuth2 Wizard! 330=DataSource._getUserName() -331=Error: Unable to load content without User: %s +331=Error: Unable to load content without User: {} 340=DataSource.queryClosing() -341=The database: %s has been closed... +341=The database: {} has been closed... 400=DataBase.__init__() 401=DataBase: Loading completed +402=DataBase._mergeItem() size {} os name {} 410=DataBase.createDataBase() -411=Try to create the database with HsqlDB version: %s +411=Try to create the database with HsqlDB version: {} 412=Successful database creation -413=Unable to create database: installed HsqlDB version: %s is lower than minimum supported version: %s +413=Unable to create database: installed HsqlDB version: {} is lower than minimum supported version: {} 500=User.__init__() -501=Service: %s is not available... Please install the extension: OAuth2OOo!!! -502=Can't retrieve User: %s from provider: network is OffLine!!! -503=User: %s does not exist at this Provider -504=Can't insert User: %s in DataBase +501=Service: {} is not available... Please install the extension: OAuth2OOo!!! +502=Can't retrieve User: {} from provider: network is OffLine!!! +503=User: {} does not exist at this Provider +504=Can't insert User: {} in DataBase 505=User loading completed 510=User.getDocumentContent() -511=Error: %s - %s +511=Error: {} - {} 600=Content.__init__() 601=Content loading completed 610=Content._getMetaData() -611=Error: Unable to load content with an incomplete Identifier: %s -612=Error: Unable to retrieve metadata for ID: %s and Uri: % +611=Error: Unable to load content with an incomplete Identifier: {} +612=Error: Unable to retrieve metadata for ID: {} and Uri: {} 620=Content._updateFolderContent() -621=The content of the folder: %s is obtained with Request!!! +621=The content of the folder: {} is obtained with Request!!! + +630=Content.execute() +631=Content execute command: {} IsFolder: {} +632=The content execute command: update ************************* +633=Transfert content title: {} source: {} move: {} clash: {} +634=Save file: {} size: {} +635=Insert file replace: {} documentid {} mimetype: {} IsFolder {} +636=The content execute command: {} on identifier: {} + +640=Content.getIdentifier() +641=Content identifier: {} +642=Error: {} - {} + +650=Content.getParent() +651=Error: {} - {} + +660=Content.createNewContent() +661=Create new content from folder: {} + +710=PropertySetInfo.getPropertyByName() +711=The content gives the property: {} + +720=PropertySetInfo.hasPropertyByName() +721=The content has the property: {} - {} diff --git a/uno/resource/ucb/ContentProvider_fr_FR.properties b/uno/resource/ucb/ContentProvider_fr_FR.properties index 10952e1c..7a05ade5 100644 --- a/uno/resource/ucb/ContentProvider_fr_FR.properties +++ b/uno/resource/ucb/ContentProvider_fr_FR.properties @@ -1,71 +1,103 @@ 100=ContentProvider.__init__() -101=ContentProvider: %s Chargement termin\u00e9 +101=ContentProvider: {} Chargement termin\u00e9 200=ContentProvider.__init__() -201=ParameterizedProvider%s Chargement termin\u00e9 +201=ParameterizedProvider{} Chargement termin\u00e9 210=ContentProvider.createContentIdentifier() -211=Identifier: %s -> %s +211=Identifier: {} -> {} 220=ContentProvider._getDataSource() -221=L'extension %s est introuvable.%sVous devez installer cette extension pour utiliser %s. -222=La version %s de l'extension %s est obsolte.%sVous devez mettre jour cette extension vers la version: %s. -223=Impossible de se connecter sur l'URL: %s%sUne SQLException a t leve avec le message: %s -224=La version %s du pilote HsqlDB est obsolte.%sVous devez mettre jour ce pilote vers une version %s ou suprieure. +221={} - Erreur d'installation +222=L'extension {} est introuvable.Vous devez installer cette extension pour utiliser {}. +223={} - Erreur de configuration +224=La version {} de l'extension {} est obsolte.Vous devez mettre jour cette extension vers la version: {}. +225={} - Erreur de connection +226=Impossible de se connecter sur l'URL: {}. Une SQLException a t leve avec le message: {} +227={} - Erreur de configuration +228=La version {} du pilote HsqlDB est obsolte. Vous devez mettre jour ce pilote vers une version {} ou suprieure. 230=ContentProvider.queryContent() -231=Identitifer: %s ... Termin\u00e9 -232=IllegalIdentifierException: %s -233=Exception python inattendue avec le traceback: %s +231=Identitifer: {} ... Termin\u00e9 +232=IllegalIdentifierException: {} +233=Exception python inattendue avec le traceback: {} 240=ContentProvider.compareContentIds() -241=Identifiers: %s - %s ... semble \u00eatre le m\u00eame -242=Identifiers: %s - %s ... ne semble pas \u00eatre le m\u00eame +241=Identifiers: {} - {} ... semble \u00eatre le m\u00eame +242=Identifiers: {} - {} ... ne semble pas \u00eatre le m\u00eame 300=DataSource.__init__() 301=DataSource: Chargement termin\u00e9 +310=DataSource.queryContent() +311=Erreur: Impossible de charger le contenu avec un Identifier incomplet: {} + 320=DataSource._getUser() -321=Erreur: Impossible de charger de contenu avec un Identifier invalide: %s -322=Erreur: Impossible de r\u00e9cup\u00e9rer l'utilisateur partir de l'Identifier: %s -323=Erreur:L'utilisateur:%s a annul\u00e9 l'assistant OAuth2! +321=Erreur: Impossible de charger de contenu avec un Identifier invalide: {} +322=Erreur: Impossible de r\u00e9cup\u00e9rer l'utilisateur partir de l'Identifier: {} +323=Erreur:L'utilisateur:{} a annul\u00e9 l'assistant OAuth2! 330=DataSource._getUserName() -331=Erreur: Impossible de charger de contenu sans Utilisateur: %s +331=Erreur: Impossible de charger de contenu sans Utilisateur: {} 340=DataSource.queryClosing() -341=La base de donn\u00e9e: %s a \u00e9t\u00e9 ferm\u00e9e +341=La base de donn\u00e9e: {} a \u00e9t\u00e9 ferm\u00e9e 400=DataBase.__init__() 401=DataBase: Chargement termin\u00e9 +402=DataBase._mergeItem() size {} os name {} 410=DataBase.createDataBase() -411=Essaie de crer la base de donnes avec HsqlDB version: %s +411=Essaie de crer la base de donnes avec HsqlDB version: {} 412=Cration russie de la base de donnes -413=Impossible de crer la base de donnes : la version de HsqlDB installe: %s est infrieure la version minimale prise en charge: %s +413=Impossible de crer la base de donnes : la version de HsqlDB installe: {} est infrieure la version minimale prise en charge: {} 500=User.__init__() -501=Le Service: %s n'est pas disponible... Veuillez installer l'extension: OAuth2OOo!!! -502=Impossible de retrouver l'utilisateur: %s chez le fournisseur: le r\u00e9seau est hors ligne!!! -503=L'utilisateur: %s est inconnu chez ce fournisseur -504=Impossible d'inserer l'utilisateur: %s dans la base de donn\u00e9es +501=Le Service: {} n'est pas disponible... Veuillez installer l'extension: OAuth2OOo!!! +502=Impossible de retrouver l'utilisateur: {} chez le fournisseur: le r\u00e9seau est hors ligne!!! +503=L'utilisateur: {} est inconnu chez ce fournisseur +504=Impossible d'inserer l'utilisateur: {} dans la base de donn\u00e9es 505=User chargement termin\u00e9 510=User.getDocumentContent() -511=Erreur: %s - %s +511=Erreur: {} - {} 600=Content.__init__() 601=Content chargement termin\u00e9 610=Content._getMetaData() -611=Erreur: Impossible de charger le contenu avec un Identifier incomplet: %s -612=Erreur: Impossible de r\u00e9cup\u00e9rer les m\u00e9tadonn\u00e9es pour l'ID: %s et l'Uri: %s +611=Erreur: Impossible de charger le contenu avec un Identifier incomplet: {} +612=Erreur: Impossible de r\u00e9cup\u00e9rer les m\u00e9tadonn\u00e9es pour l'ID: {} et l'Uri: {} 620=Content._updateFolderContent() -621=Le contenu du dossier: %s est obtenu avec Request!!! +621=Le contenu du dossier: {} est obtenu avec Request!!! + +630=Content.execute() +631=Le contenu execute la commande: {} IsFolder: {} +632=Le contenu execute la commande: update ************************* +633=Transfert du contenu titre: {} soure: {} dplacer: {} conflit: {} +634=Sauvegarde du fichier: {} taille: {} +635=Insertion du fichier replace: {} documentid: {} mimetype: {} IsFolder {} +636=Le contenu execute la commande: {} sur l'identifieur: {} + +640=Content.getIdentifier() +641=Identificateur de contenu: {} +642=Erreur: {} - {} + +650=Content.getParent() +651=Erreur: {} - {} + +660=Content.createNewContent() +661=Creation d'un nouveau contenu dans le dossier: {} + +710=PropertySetInfo.getPropertyByName() +711=Le contenu donne la proprit: {} + +720=PropertySetInfo.hasPropertyByName() +721=Le contenu a la proprit: {} - {} diff --git a/uno/resource/ucb/Replicator_en_US.properties b/uno/resource/ucb/Replicator_en_US.properties index 220264e7..4acb05fb 100644 --- a/uno/resource/ucb/Replicator_en_US.properties +++ b/uno/resource/ucb/Replicator_en_US.properties @@ -1,35 +1,58 @@ -100=Replicator._synchronize() -101=Starting data synchronization at %s -102=Synchronization is not possible network is offline!!! -103=End of data synchronization at %s +100=Replicator.__init__() +101=Replicator has been initialized. +102=Replicator thread throw error: {}\n{} +103=Replicator {} -110=Replicator._pullUsers() -111=Starting data download for user: %s at %s -112=End of download for user: %s at %s +110=Replicator.run() +111=Replicator start thread with id {}. +112=Replicator thread has been paused for {} minutes. +113=Replicator thread throw error: {}\n{} -120=Replicator._initUser() -121=Import of Files/Directory by %s requests producing %s insertion/updates... -122=%s orphan File/Directory could not be imported!!! See the following details... -123=The File/Directory: %s identified with the ID: %s, seems orphan, its parents: %s could not be identified! +120=Replicator._synchronize() +121=Starting data synchronization. +122=Synchronization is not possible network is offline!!! +123=End of data synchronization. -130=Replicator._pushUsers() -131=Starting data replication for user: %s at %s -132=Has encountered an error while replicating the file/folder: %s of %s with Id: %s -133=End of replicating data for user: %s at %s +130=Replicator._pullUsers() +131=Starting data download for user: {}. +132=End of download for user: {}. +133=Replicator thread throw error: {}\n{} -140=Replicator._pushItem -141=Has replicated the creation of a folder: %s of %s -142=Has replicated the creation of a file: %s of %s -143=Has replicated the file/folder's title: %s update of %s -144=Has replicated the file: %s of %s size: %s -145=Has replicated the file/folder's trashed: %s of %s +140=Replicator._initUser() +141=Initialize user name: {}. +142=First data pull for user name {}, done... + +150=Replicator._pushUsers() +151=Starting data replication for user: {}. +152=Has encountered an error while replicating the file/folder: {} of {} with Id: {} +153=End of replicating data for user: {}. +154=Replicator thread throw error: {}\n{} + +160=Replicator._pushItem +161=Has replicated the creation of a folder: {} of {} + +165=Has replicated the creation of a file: {} of {} size: {} +166=Can't retrieve upload location for file: {} HTTP response: {} +167=Can't retrieve upload location for file: {} +168=Can't upload file: {} HTTP response: {} + +170=Has replicated the file/folder's title: {} update of {} +172=Has replicated the file/folder's trashed: {} of {} + +175=Has replicated the update of file: {} of {} size: {} +176=Can't retrieve upload location for file: {} HTTP response: {} +177=Can't retrieve upload location for file: {} +178=Can't upload file: {} HTTP response: {} + +179=Replicator thread throw error: {}\n{} 400=DataBase.__init__() 401=DataBase: Loading completed +402=DataBase._mergeItem() size {} os name {} 410=DataBase.createDataBase() -411=Try to create the database with HsqlDB version: %s +411=Try to create the database with HsqlDB version: {} 412=Successful database creation -413=Unable to create database: installed HsqlDB version: %s is lower than minimum supported version: %s +413=Unable to create database: installed HsqlDB version: {} is lower than minimum supported version: {} diff --git a/uno/resource/ucb/Replicator_fr_FR.properties b/uno/resource/ucb/Replicator_fr_FR.properties index a7e9f1ad..aa78098e 100644 --- a/uno/resource/ucb/Replicator_fr_FR.properties +++ b/uno/resource/ucb/Replicator_fr_FR.properties @@ -1,35 +1,58 @@ -100=Replicator._synchronize() -101=D\u00e9marrage de la synchronisation des donn\u00e9es \u00e0 %s -102=La synchronisation n'est pas possible le r\u00e9seau est hors ligne!!! -103=Fin de la synchronisation des donn\u00e9es \u00e0 %s +100=Replicator.__init__() +101=Le rplicateur a t initialis. +102=Le fil d'execution du rplicateur a lancer l'erreur: {}\n{} +103=Le rplicateur {} -110=Replicator._pullUsers() -111=D\u00e9marrage du t\u00e9l\u00e9chargement des donn\u00e9es pour l'utilisateur: %s \u00e0 %s -112=Fin du t\u00e9l\u00e9chargement pour l'utilisateur: %s \u00e0 %s +110=Replicator.run() +111=Le rplicateur dmarrer un fil d'execution avec l'id {}. +112=Le fil d'execution du rplicateur a t suspendu pour {} minutes. +113=Le fil d'execution du rplicateur a lancer l'erreur: {}\n{} -120=Replicator._initUser() -121=Importation des Fichiers/R\u00e9pertoires par %s requ\u00eates produisant %s insertion/mise \u00e0 jour... -122=%s Fichiers/R\u00e9pertoires orphelin n'ont pas pu \u00eatre import\u00e9!!! Voir les details suivants... -123=Le Fichier/R\u00e9pertoire: %s, avec l'ID: %s, semble orphelin, ses parents: %s n'ont pas pu \u00eatre identifi\u00e9! +120=Replicator._synchronize() +121=D\u00e9marrage de la synchronisation des donn\u00e9es. +122=La synchronisation n'est pas possible le r\u00e9seau est hors ligne!!! +123=Fin de la synchronisation des donn\u00e9es. -130=Replicator._pushUsers() -131=D\u00e9marrage de la r\u00e9plication des donn\u00e9es pour l'utilisateur: %s \u00e0 %s -132=A rencontr\u00e9 une erreur lors de la r\u00e9pliquation du fichier/r\u00e9p\u00e9rtoire: %s du %s portant l'Id: %s -133=Fin de la r\u00e9plication des donn\u00e9es pour l'utilisateur: %s \u00e0 %s +130=Replicator._pullUsers() +131=D\u00e9marrage du t\u00e9l\u00e9chargement des donn\u00e9es pour l'utilisateur: {}. +132=Fin du t\u00e9l\u00e9chargement pour l'utilisateur: {}. +133=Le fil d'execution du rplicateur a lancer l'erreur: {}\n{} -140=Replicator._pushItem -141=A repliqu\u00e9 la cr\u00e9ation du dossier: %s du %s -142=A repliqu\u00e9 la cr\u00e9ation du fichier: %s du %s -143=A repliqu\u00e9 la mise \u00e0 jour du titre du fichier/r\u00e9p\u00e9rtoire: %s du %s -144=A repliqu\u00e9 la mise \u00e0 jour du fichier: '%s' du %s d'une taille de: %s -145=A repliqu\u00e9 la mise \u00e0 jour de l'effacement du fichier/r\u00e9p\u00e9rtoire: %s du %s +140=Replicator._initUser() +141=Initialisation de l'utilisateur {}. +142=Premire rplication de donnes pour l'utilisateur {}, termine... + +150=Replicator._pushUsers() +151=D\u00e9marrage de la r\u00e9plication des donn\u00e9es pour l'utilisateur: {}. +152=A rencontr\u00e9 une erreur lors de la r\u00e9pliquation du fichier/r\u00e9p\u00e9rtoire: {} du {} portant l'Id: {} +153=Fin de la r\u00e9plication des donn\u00e9es pour l'utilisateur: {}. +154=Le fil d'execution du rplicateur a lancer l'erreur: {}\n{} + +160=Replicator._pushItem +161=A repliqu\u00e9 la cr\u00e9ation du dossier: {} du {} + +165=A repliqu\u00e9 la cr\u00e9ation du fichier: {} du {} d'une taille de: {} +166=Ne peut pas retrouver l'emplacement du tlchargement du fichier: {} la rponse HTTP est: {} +167=Ne peut pas retrouver l'emplacement du tlchargement du fichier: {} +168=Ne peut pas tlcharger le fichier: {} la rponse HTTP est: {} + +170=A repliqu\u00e9 la mise \u00e0 jour du titre du fichier/r\u00e9p\u00e9rtoire: {} du {} +172=A repliqu\u00e9 la mise \u00e0 jour de l'effacement du fichier/r\u00e9p\u00e9rtoire: {} du {} + +175=A repliqu\u00e9 la mise \u00e0 jour du fichier: {} du {} d'une taille de: {} +176=Ne peut pas retrouver l'emplacement de la mise \u00e0 jour du fichier: {} la rponse HTTP est: {} +177=Ne peut pas retrouver l'emplacement de la mise \u00e0 jour du fichier: {} +178=Ne peut pas mettre \u00e0 jour le fichier: {} la rponse HTTP est: {} + +179=Le fil d'execution du rplicateur a lancer l'erreur: {}\n{} 400=DataBase.__init__() 401=DataBase: Chargement termin\u00e9 +402=DataBase._mergeItem() size {} os name {} 410=DataBase.createDataBase() -411=Essaie de crer la base de donnes avec HsqlDB version: %s +411=Essaie de crer la base de donnes avec HsqlDB version: {} 412=Cration russie de la base de donnes -413=Impossible de crer la base de donnes : la version de HsqlDB installe: %s est infrieure la version minimale prise en charge: %s +413=Impossible de crer la base de donnes : la version de HsqlDB installe: {} est infrieure la version minimale prise en charge: {}