From d56b9bfdb0ae322ab0f120e5c7828fa24bfdf6cf Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 18 Jul 2022 14:42:29 +0900 Subject: [PATCH] Imported Upstream version 2.2.1 --- CHANGES | 2264 ----- HowToUsePyparsing.html | 1289 --- LICENSE | 18 - MANIFEST.in | 7 - PKG-INFO | 50 +- README => README.md | 80 +- docs/HowToUsePyparsing.html | 1289 --- ...06-AdventureEngineUsingPyparsing-notes.pdf | Bin 48227 -> 0 bytes docs/pycon06-IntroToPyparsing-notes.pdf | Bin 82733 -> 0 bytes docs/pyparsingClassDiagram.JPG | Bin 236402 -> 0 bytes docs/pyparsingClassDiagram.PNG | Bin 141354 -> 0 bytes examples/0README.html | 309 - examples/AcManForm.dfm | 885 -- examples/LAparser.py | 417 - examples/Setup.ini | 73 - examples/SimpleCalc.py | 118 - examples/SingleForm.dfm | 751 -- examples/TAP.py | 217 - examples/__init__.py | 0 examples/adventureEngine.py | 648 -- examples/antlr_grammar.py | 219 - examples/antlr_grammar_tests.py | 87 - examples/apicheck.py | 58 - examples/btpyparse.py | 129 - examples/builtin_parse_action_demo.py | 29 - examples/cLibHeader.py | 25 - examples/chemicalFormulas.py | 67 - examples/commasep.py | 26 - examples/configParse.py | 72 - examples/cpp_enum_parser.py | 52 - examples/datetimeParseActions.py | 68 - examples/deltaTime.py | 208 - examples/dfmparse.py | 179 - examples/dhcpd_leases_parser.py | 87 - examples/dictExample.py | 41 - examples/dictExample2.py | 59 - examples/ebnf.py | 151 - examples/ebnftest.py | 72 - examples/eval_arith.py | 227 - examples/excelExpr.py | 69 - examples/fourFn.py | 192 - examples/gen_ctypes.py | 174 - examples/getNTPservers.py | 30 - examples/getNTPserversNew.py | 35 - examples/greeting.py | 17 - examples/greetingInGreek.py | 20 - examples/greetingInKorean.py | 22 - examples/groupUsingListAllMatches.py | 17 - examples/holaMundo.py | 38 - examples/htmlStripper.py | 32 - examples/httpServerLogParser.py | 73 - examples/idlParse.py | 173 - examples/indentedGrammarExample.py | 54 - examples/invRegex.py | 257 - examples/jsonParser.py | 107 - examples/linenoExample.py | 49 - examples/list1.py | 56 - examples/listAllMatches.py | 52 - examples/lucene_grammar.py | 319 - examples/macroExpander.py | 60 - examples/makeHTMLTagExample.py | 21 - examples/matchPreviousDemo.py | 33 - examples/mozilla.ics | 50 - examples/mozillaCalendarParser.py | 81 - examples/nested.py | 30 - examples/numerics.py | 62 - examples/oc.py | 186 - examples/parseListString.py | 82 - examples/parsePythonValue.py | 70 - examples/parseResultsSumExample.py | 26 - examples/parseTabularData.py | 50 - examples/partial_gene_match.py | 88 - examples/pgn.py | 94 - examples/position.py | 55 - examples/protobuf_parser.py | 100 - examples/pymicko.py | 1387 --- examples/pythonGrammarParser.py | 220 - examples/rangeCheck.py | 62 - examples/readJson.py | 1917 ---- examples/removeLineBreaks.py | 45 - examples/romanNumerals.py | 74 - examples/scanExamples.py | 75 - examples/scanYahoo.py | 14 - examples/searchParserAppDemo.py | 34 - examples/searchparser.py | 292 - examples/select_parser.py | 126 - examples/sexpParser.py | 167 - examples/shapes.py | 64 - examples/simpleArith.py | 67 - examples/simpleBool.py | 102 - examples/simpleSQL.py | 88 - examples/simpleWiki.py | 32 - examples/sparser.py | 365 - examples/sql2dot.py | 96 - examples/stackish.py | 81 - examples/stateMachine2.py | 258 - examples/test_bibparse.py | 195 - examples/urlExtractor.py | 33 - examples/urlExtractorNew.py | 35 - examples/verilogParse.py | 720 -- examples/withAttribute.py | 24 - examples/wordsToNum.py | 106 - htmldoc/api-objects.txt | 2944 ------ htmldoc/class-tree.html | 339 - htmldoc/crarr.png | Bin 340 -> 0 bytes htmldoc/epydoc.css | 322 - htmldoc/epydoc.js | 293 - htmldoc/frames.html | 17 - htmldoc/help.html | 276 - htmldoc/identifier-index.html | 1406 --- htmldoc/index.html | 17 - htmldoc/module-tree.html | 114 - htmldoc/pyparsing-module.html | 2689 ------ htmldoc/pyparsing-pysrc.html | 7968 ----------------- htmldoc/pyparsing.And-class.html | 476 - htmldoc/pyparsing.CaselessKeyword-class.html | 374 - htmldoc/pyparsing.CaselessLiteral-class.html | 368 - htmldoc/pyparsing.CharsNotIn-class.html | 417 - htmldoc/pyparsing.CloseMatch-class.html | 395 - htmldoc/pyparsing.Combine-class.html | 437 - htmldoc/pyparsing.Dict-class.html | 402 - htmldoc/pyparsing.Each-class.html | 492 - htmldoc/pyparsing.Empty-class.html | 315 - htmldoc/pyparsing.FollowedBy-class.html | 373 - htmldoc/pyparsing.Forward-class.html | 598 -- htmldoc/pyparsing.GoToColumn-class.html | 398 - htmldoc/pyparsing.Group-class.html | 380 - htmldoc/pyparsing.Keyword-class.html | 509 -- htmldoc/pyparsing.LineEnd-class.html | 362 - htmldoc/pyparsing.LineStart-class.html | 371 - htmldoc/pyparsing.Literal-class.html | 381 - htmldoc/pyparsing.MatchFirst-class.html | 477 - htmldoc/pyparsing.NoMatch-class.html | 352 - htmldoc/pyparsing.NotAny-class.html | 413 - htmldoc/pyparsing.OneOrMore-class.html | 349 - htmldoc/pyparsing.OnlyOnce-class.html | 252 - htmldoc/pyparsing.Optional-class.html | 445 - htmldoc/pyparsing.Or-class.html | 469 - .../pyparsing.ParseBaseException-class.html | 410 - .../pyparsing.ParseElementEnhance-class.html | 616 -- htmldoc/pyparsing.ParseException-class.html | 213 - htmldoc/pyparsing.ParseExpression-class.html | 685 -- .../pyparsing.ParseFatalException-class.html | 195 - htmldoc/pyparsing.ParseResults-class.html | 1455 --- .../pyparsing.ParseSyntaxException-class.html | 193 - htmldoc/pyparsing.ParserElement-class.html | 2482 ----- htmldoc/pyparsing.QuotedString-class.html | 456 - htmldoc/pyparsing.Recipes-class.html | 249 - ...rsing.RecursiveGrammarException-class.html | 276 - htmldoc/pyparsing.Regex-class.html | 434 - .../pyparsing.Regex.compiledREtype-class.html | 480 - htmldoc/pyparsing.SkipTo-class.html | 428 - htmldoc/pyparsing.StringEnd-class.html | 354 - htmldoc/pyparsing.StringStart-class.html | 355 - htmldoc/pyparsing.Suppress-class.html | 385 - htmldoc/pyparsing.Token-class.html | 314 - htmldoc/pyparsing.TokenConverter-class.html | 322 - htmldoc/pyparsing.White-class.html | 419 - htmldoc/pyparsing.Word-class.html | 482 - htmldoc/pyparsing.WordEnd-class.html | 361 - htmldoc/pyparsing.WordStart-class.html | 361 - htmldoc/pyparsing.ZeroOrMore-class.html | 413 - htmldoc/pyparsing.pyparsing_common-class.html | 753 -- htmldoc/redirect.html | 38 - htmldoc/toc-everything.html | 135 - htmldoc/toc-pyparsing-module.html | 135 - htmldoc/toc.html | 31 - pyparsing.egg-info/PKG-INFO | 50 +- pyparsing.egg-info/SOURCES.txt | 170 +- pyparsing.py | 46 +- pyparsingClassDiagram.JPG | Bin 236402 -> 0 bytes pyparsingClassDiagram.PNG | Bin 141354 -> 0 bytes robots.txt | 2 - setup.cfg | 21 +- setup.py | 8 +- 175 files changed, 146 insertions(+), 59595 deletions(-) delete mode 100644 CHANGES delete mode 100644 HowToUsePyparsing.html delete mode 100644 LICENSE delete mode 100644 MANIFEST.in rename README => README.md (81%) delete mode 100644 docs/HowToUsePyparsing.html delete mode 100644 docs/pycon06-AdventureEngineUsingPyparsing-notes.pdf delete mode 100644 docs/pycon06-IntroToPyparsing-notes.pdf delete mode 100644 docs/pyparsingClassDiagram.JPG delete mode 100644 docs/pyparsingClassDiagram.PNG delete mode 100644 examples/0README.html delete mode 100644 examples/AcManForm.dfm delete mode 100644 examples/LAparser.py delete mode 100644 examples/Setup.ini delete mode 100644 examples/SimpleCalc.py delete mode 100644 examples/SingleForm.dfm delete mode 100644 examples/TAP.py delete mode 100644 examples/__init__.py delete mode 100644 examples/adventureEngine.py delete mode 100644 examples/antlr_grammar.py delete mode 100644 examples/antlr_grammar_tests.py delete mode 100644 examples/apicheck.py delete mode 100644 examples/btpyparse.py delete mode 100644 examples/builtin_parse_action_demo.py delete mode 100644 examples/cLibHeader.py delete mode 100644 examples/chemicalFormulas.py delete mode 100644 examples/commasep.py delete mode 100644 examples/configParse.py delete mode 100644 examples/cpp_enum_parser.py delete mode 100644 examples/datetimeParseActions.py delete mode 100644 examples/deltaTime.py delete mode 100644 examples/dfmparse.py delete mode 100644 examples/dhcpd_leases_parser.py delete mode 100644 examples/dictExample.py delete mode 100644 examples/dictExample2.py delete mode 100644 examples/ebnf.py delete mode 100644 examples/ebnftest.py delete mode 100644 examples/eval_arith.py delete mode 100644 examples/excelExpr.py delete mode 100644 examples/fourFn.py delete mode 100644 examples/gen_ctypes.py delete mode 100644 examples/getNTPservers.py delete mode 100644 examples/getNTPserversNew.py delete mode 100644 examples/greeting.py delete mode 100644 examples/greetingInGreek.py delete mode 100644 examples/greetingInKorean.py delete mode 100644 examples/groupUsingListAllMatches.py delete mode 100644 examples/holaMundo.py delete mode 100644 examples/htmlStripper.py delete mode 100644 examples/httpServerLogParser.py delete mode 100644 examples/idlParse.py delete mode 100644 examples/indentedGrammarExample.py delete mode 100644 examples/invRegex.py delete mode 100644 examples/jsonParser.py delete mode 100644 examples/linenoExample.py delete mode 100644 examples/list1.py delete mode 100644 examples/listAllMatches.py delete mode 100644 examples/lucene_grammar.py delete mode 100644 examples/macroExpander.py delete mode 100644 examples/makeHTMLTagExample.py delete mode 100644 examples/matchPreviousDemo.py delete mode 100644 examples/mozilla.ics delete mode 100644 examples/mozillaCalendarParser.py delete mode 100644 examples/nested.py delete mode 100644 examples/numerics.py delete mode 100644 examples/oc.py delete mode 100644 examples/parseListString.py delete mode 100644 examples/parsePythonValue.py delete mode 100644 examples/parseResultsSumExample.py delete mode 100644 examples/parseTabularData.py delete mode 100644 examples/partial_gene_match.py delete mode 100644 examples/pgn.py delete mode 100644 examples/position.py delete mode 100644 examples/protobuf_parser.py delete mode 100644 examples/pymicko.py delete mode 100644 examples/pythonGrammarParser.py delete mode 100644 examples/rangeCheck.py delete mode 100644 examples/readJson.py delete mode 100644 examples/removeLineBreaks.py delete mode 100644 examples/romanNumerals.py delete mode 100644 examples/scanExamples.py delete mode 100644 examples/scanYahoo.py delete mode 100644 examples/searchParserAppDemo.py delete mode 100644 examples/searchparser.py delete mode 100644 examples/select_parser.py delete mode 100644 examples/sexpParser.py delete mode 100644 examples/shapes.py delete mode 100644 examples/simpleArith.py delete mode 100644 examples/simpleBool.py delete mode 100644 examples/simpleSQL.py delete mode 100644 examples/simpleWiki.py delete mode 100644 examples/sparser.py delete mode 100644 examples/sql2dot.py delete mode 100644 examples/stackish.py delete mode 100644 examples/stateMachine2.py delete mode 100644 examples/test_bibparse.py delete mode 100644 examples/urlExtractor.py delete mode 100644 examples/urlExtractorNew.py delete mode 100644 examples/verilogParse.py delete mode 100644 examples/withAttribute.py delete mode 100644 examples/wordsToNum.py delete mode 100644 htmldoc/api-objects.txt delete mode 100644 htmldoc/class-tree.html delete mode 100644 htmldoc/crarr.png delete mode 100644 htmldoc/epydoc.css delete mode 100644 htmldoc/epydoc.js delete mode 100644 htmldoc/frames.html delete mode 100644 htmldoc/help.html delete mode 100644 htmldoc/identifier-index.html delete mode 100644 htmldoc/index.html delete mode 100644 htmldoc/module-tree.html delete mode 100644 htmldoc/pyparsing-module.html delete mode 100644 htmldoc/pyparsing-pysrc.html delete mode 100644 htmldoc/pyparsing.And-class.html delete mode 100644 htmldoc/pyparsing.CaselessKeyword-class.html delete mode 100644 htmldoc/pyparsing.CaselessLiteral-class.html delete mode 100644 htmldoc/pyparsing.CharsNotIn-class.html delete mode 100644 htmldoc/pyparsing.CloseMatch-class.html delete mode 100644 htmldoc/pyparsing.Combine-class.html delete mode 100644 htmldoc/pyparsing.Dict-class.html delete mode 100644 htmldoc/pyparsing.Each-class.html delete mode 100644 htmldoc/pyparsing.Empty-class.html delete mode 100644 htmldoc/pyparsing.FollowedBy-class.html delete mode 100644 htmldoc/pyparsing.Forward-class.html delete mode 100644 htmldoc/pyparsing.GoToColumn-class.html delete mode 100644 htmldoc/pyparsing.Group-class.html delete mode 100644 htmldoc/pyparsing.Keyword-class.html delete mode 100644 htmldoc/pyparsing.LineEnd-class.html delete mode 100644 htmldoc/pyparsing.LineStart-class.html delete mode 100644 htmldoc/pyparsing.Literal-class.html delete mode 100644 htmldoc/pyparsing.MatchFirst-class.html delete mode 100644 htmldoc/pyparsing.NoMatch-class.html delete mode 100644 htmldoc/pyparsing.NotAny-class.html delete mode 100644 htmldoc/pyparsing.OneOrMore-class.html delete mode 100644 htmldoc/pyparsing.OnlyOnce-class.html delete mode 100644 htmldoc/pyparsing.Optional-class.html delete mode 100644 htmldoc/pyparsing.Or-class.html delete mode 100644 htmldoc/pyparsing.ParseBaseException-class.html delete mode 100644 htmldoc/pyparsing.ParseElementEnhance-class.html delete mode 100644 htmldoc/pyparsing.ParseException-class.html delete mode 100644 htmldoc/pyparsing.ParseExpression-class.html delete mode 100644 htmldoc/pyparsing.ParseFatalException-class.html delete mode 100644 htmldoc/pyparsing.ParseResults-class.html delete mode 100644 htmldoc/pyparsing.ParseSyntaxException-class.html delete mode 100644 htmldoc/pyparsing.ParserElement-class.html delete mode 100644 htmldoc/pyparsing.QuotedString-class.html delete mode 100644 htmldoc/pyparsing.Recipes-class.html delete mode 100644 htmldoc/pyparsing.RecursiveGrammarException-class.html delete mode 100644 htmldoc/pyparsing.Regex-class.html delete mode 100644 htmldoc/pyparsing.Regex.compiledREtype-class.html delete mode 100644 htmldoc/pyparsing.SkipTo-class.html delete mode 100644 htmldoc/pyparsing.StringEnd-class.html delete mode 100644 htmldoc/pyparsing.StringStart-class.html delete mode 100644 htmldoc/pyparsing.Suppress-class.html delete mode 100644 htmldoc/pyparsing.Token-class.html delete mode 100644 htmldoc/pyparsing.TokenConverter-class.html delete mode 100644 htmldoc/pyparsing.White-class.html delete mode 100644 htmldoc/pyparsing.Word-class.html delete mode 100644 htmldoc/pyparsing.WordEnd-class.html delete mode 100644 htmldoc/pyparsing.WordStart-class.html delete mode 100644 htmldoc/pyparsing.ZeroOrMore-class.html delete mode 100644 htmldoc/pyparsing.pyparsing_common-class.html delete mode 100644 htmldoc/redirect.html delete mode 100644 htmldoc/toc-everything.html delete mode 100644 htmldoc/toc-pyparsing-module.html delete mode 100644 htmldoc/toc.html delete mode 100644 pyparsingClassDiagram.JPG delete mode 100644 pyparsingClassDiagram.PNG delete mode 100644 robots.txt diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 91eaf63..0000000 --- a/CHANGES +++ /dev/null @@ -1,2264 +0,0 @@ -========== -Change Log -========== - -Version 2.2.0 - March, 2017 ---------------------------- -- Bumped minor version number to reflect compatibility issues with - OneOrMore and ZeroOrMore bugfixes in 2.1.10. (2.1.10 fixed a bug - that was introduced in 2.1.4, but the fix could break code - written against 2.1.4 - 2.1.9.) - -- Updated setup.py to address recursive import problems now - that pyparsing is part of 'packaging' (used by setuptools). - Patch submitted by Joshua Root, much thanks! - -- Fixed KeyError issue reported by Yann Bizeul when using packrat - parsing in the Graphite time series database, thanks Yann! - -- Fixed incorrect usages of '\' in literals, as described in - https://docs.python.org/3/whatsnew/3.6.html#deprecated-python-behavior - Patch submitted by Ville Skyttä - thanks! - -- Minor internal change when using '-' operator, to be compatible - with ParserElement.streamline() method. - -- Expanded infixNotation to accept a list or tuple of parse actions - to attach to an operation. - -- New unit test added for dill support for storing pyparsing parsers. - Ordinary Python pickle can be used to pickle pyparsing parsers as - long as they do not use any parse actions. The 'dill' module is an - extension to pickle which *does* support pickling of attached - parse actions. - - -Version 2.1.10 - October, 2016 -------------------------------- -- Fixed bug in reporting named parse results for ZeroOrMore - expressions, thanks Ethan Nash for reporting this! - -- Fixed behavior of LineStart to be much more predictable. - LineStart can now be used to detect if the next parse position - is col 1, factoring in potential leading whitespace (which would - cause LineStart to fail). Also fixed a bug in col, which is - used in LineStart, where '\n's were erroneously considered to - be column 1. - -- Added support for multiline test strings in runTests. - -- Fixed bug in ParseResults.dump when keys were not strings. - Also changed display of string values to show them in quotes, - to help distinguish parsed numeric strings from parsed integers - that have been converted to Python ints. - - -Version 2.1.9 - September, 2016 -------------------------------- -- Added class CloseMatch, a variation on Literal which matches - "close" matches, that is, strings with at most 'n' mismatching - characters. - -- Fixed bug in Keyword.setDefaultKeywordChars(), reported by Kobayashi - Shinji - nice catch, thanks! - -- Minor API change in pyparsing_common. Renamed some of the common - expressions to PEP8 format (to be consistent with the other - pyparsing_common expressions): - . signedInteger -> signed_integer - . sciReal -> sci_real - - Also, in trying to stem the API bloat of pyparsing, I've copied - some of the global expressions and helper parse actions into - pyparsing_common, with the originals to be deprecated and removed - in a future release: - . commaSeparatedList -> pyparsing_common.comma_separated_list - . upcaseTokens -> pyparsing_common.upcaseTokens - . downcaseTokens -> pyparsing_common.downcaseTokens - - (I don't expect any other expressions, like the comment expressions, - quotedString, or the Word-helping strings like alphas, nums, etc. - to migrate to pyparsing_common - they are just too pervasive. As for - the PEP8 vs camelCase naming, all the expressions are PEP8, while - the parse actions in pyparsing_common are still camelCase. It's a - small step - when pyparsing 3.0 comes around, everything will change - to PEP8 snake case.) - -- Fixed Python3 compatibility bug when using dict keys() and values() - in ParseResults.getName(). - -- After some prodding, I've reworked the unitTests.py file for - pyparsing over the past few releases. It uses some variations on - unittest to handle my testing style. The test now: - . auto-discovers its test classes (while maintining their order - of definition) - . suppresses voluminous 'print' output for tests that pass - - -Version 2.1.8 - August, 2016 ----------------------------- -- Fixed issue in the optimization to _trim_arity, when the full - stacktrace is retrieved to determine if a TypeError is raised in - pyparsing or in the caller's parse action. Code was traversing - the full stacktrace, and potentially encountering UnicodeDecodeError. - -- Fixed bug in ParserElement.inlineLiteralsUsing, causing infinite - loop with Suppress. - -- Fixed bug in Each, when merging named results from multiple - expressions in a ZeroOrMore or OneOrMore. Also fixed bug when - ZeroOrMore expressions were erroneously treated as required - expressions in an Each expression. - -- Added a few more inline doc examples. - -- Improved use of runTests in several example scripts. - - -Version 2.1.7 - August, 2016 ----------------------------- -- Fixed regression reported by Andrea Censi (surfaced in PyContracts - tests) when using ParseSyntaxExceptions (raised when using operator '-') - with packrat parsing. - -- Minor fix to oneOf, to accept all iterables, not just space-delimited - strings and lists. (If you have a list or set of strings, it is - not necessary to concat them using ' '.join to pass them to oneOf, - oneOf will accept the list or set or generator directly.) - - -Version 2.1.6 - August, 2016 ----------------------------- -- *Major packrat upgrade*, inspired by patch provided by Tal Einat - - many, many, thanks to Tal for working on this! Tal's tests show - faster parsing performance (2X in some tests), *and* memory reduction - from 3GB down to ~100MB! Requires no changes to existing code using - packratting. (Uses OrderedDict, available in Python 2.7 and later. - For Python 2.6 users, will attempt to import from ordereddict - backport. If not present, will implement pure-Python Fifo dict.) - -- Minor API change - to better distinguish between the flexible - numeric types defined in pyparsing_common, I've changed "numeric" - (which parsed numbers of different types and returned int for ints, - float for floats, etc.) and "number" (which parsed numbers of int - or float type, and returned all floats) to "number" and "fnumber" - respectively. I hope the "f" prefix of "fnumber" will be a better - indicator of its internal conversion of parsed values to floats, - while the generic "number" is similar to the flexible number syntax - in other languages. Also fixed a bug in pyparsing_common.numeric - (now renamed to pyparsing_common.number), integers were parsed and - returned as floats instead of being retained as ints. - -- Fixed bug in upcaseTokens and downcaseTokens introduced in 2.1.5, - when the parse action was used in conjunction with results names. - Reported by Steven Arcangeli from the dql project, thanks for your - patience, Steven! - -- Major change to docs! After seeing some comments on reddit about - general issue with docs of Python modules, and thinking that I'm a - little overdue in doing some doc tuneup on pyparsing, I decided to - following the suggestions of the redditor and add more inline examples - to the pyparsing reference documentation. I hope this addition - will clarify some of the more common questions people have, especially - when first starting with pyparsing/Python. - -- Deprecated ParseResults.asXML. I've never been too happy with this - method, and it usually forces some unnatural code in the parsers in - order to get decent tag names. The amount of guesswork that asXML - has to do to try to match names with values should have been a red - flag from day one. If you are using asXML, you will need to implement - your own ParseResults->XML serialization. Or consider migrating to - a more current format such as JSON (which is very easy to do: - results_as_json = json.dumps(parse_result.asDict()) Hopefully, when - I remove this code in a future version, I'll also be able to simplify - some of the craziness in ParseResults, which IIRC was only there to try - to make asXML work. - -- Updated traceParseAction parse action decorator to show the repr - of the input and output tokens, instead of the str format, since - str has been simplified to just show the token list content. - - (The change to ParseResults.__str__ occurred in pyparsing 2.0.4, but - it seems that didn't make it into the release notes - sorry! Too - many users, especially beginners, were confused by the - "([token_list], {names_dict})" str format for ParseResults, thinking - they were getting a tuple containing a list and a dict. The full form - can be seen if using repr().) - - For tracing tokens in and out of parse actions, the more complete - repr form provides important information when debugging parse actions. - - -Verison 2.1.5 - June, 2016 ------------------------------- -- Added ParserElement.split() generator method, similar to re.split(). - Includes optional arguments maxsplit (to limit the number of splits), - and includeSeparators (to include the separating matched text in the - returned output, default=False). - -- Added a new parse action construction helper tokenMap, which will - apply a function and optional arguments to each element in a - ParseResults. So this parse action: - - def lowercase_all(tokens): - return [str(t).lower() for t in tokens] - OneOrMore(Word(alphas)).setParseAction(lowercase_all) - - can now be written: - - OneOrMore(Word(alphas)).setParseAction(tokenMap(str.lower)) - - Also simplifies writing conversion parse actions like: - - integer = Word(nums).setParseAction(lambda t: int(t[0])) - - to just: - - integer = Word(nums).setParseAction(tokenMap(int)) - - If additional arguments are necessary, they can be included in the - call to tokenMap, as in: - - hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16)) - -- Added more expressions to pyparsing_common: - . IPv4 and IPv6 addresses (including long, short, and mixed forms - of IPv6) - . MAC address - . ISO8601 date and date time strings (with named fields for year, month, etc.) - . UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) - . hex integer (returned as int) - . fraction (integer '/' integer, returned as float) - . mixed integer (integer '-' fraction, or just fraction, returned as float) - . stripHTMLTags (parse action to remove tags from HTML source) - . parse action helpers convertToDate and convertToDatetime to do custom parse - time conversions of parsed ISO8601 strings - -- runTests now returns a two-tuple: success if all tests succeed, - and an output list of each test and its output lines. - -- Added failureTests argument (default=False) to runTests, so that - tests can be run that are expected failures, and runTests' success - value will return True only if all tests *fail* as expected. Also, - parseAll now defaults to True. - -- New example numerics.py, shows samples of parsing integer and real - numbers using locale-dependent formats: - - 4.294.967.295,000 - 4 294 967 295,000 - 4,294,967,295.000 - - -Version 2.1.4 - May, 2016 ------------------------------- -- Split out the '==' behavior in ParserElement, now implemented - as the ParserElement.matches() method. Using '==' for string test - purposes will be removed in a future release. - -- Expanded capabilities of runTests(). Will now accept embedded - comments (default is Python style, leading '#' character, but - customizable). Comments will be emitted along with the tests and - test output. Useful during test development, to create a test string - consisting only of test case description comments separated by - blank lines, and then fill in the test cases. Will also highlight - ParseFatalExceptions with "(FATAL)". - -- Added a 'pyparsing_common' class containing common/helpful little - expressions such as integer, float, identifier, etc. I used this - class as a sort of embedded namespace, to contain these helpers - without further adding to pyparsing's namespace bloat. - -- Minor enhancement to traceParseAction decorator, to retain the - parse action's name for the trace output. - -- Added optional 'fatal' keyword arg to addCondition, to indicate that - a condition failure should halt parsing immediately. - - -Version 2.1.3 - May, 2016 ------------------------------- -- _trim_arity fix in 2.1.2 was very version-dependent on Py 3.5.0. - Now works for Python 2.x, 3.3, 3.4, 3.5.0, and 3.5.1 (and hopefully - beyond). - - -Version 2.1.2 - May, 2016 ------------------------------- -- Fixed bug in _trim_arity when pyparsing code is included in a - PyInstaller, reported by maluwa. - -- Fixed catastrophic regex backtracking in implementation of the - quoted string expressions (dblQuotedString, sglQuotedString, and - quotedString). Reported on the pyparsing wiki by webpentest, - good catch! (Also tuned up some other expressions susceptible to the - same backtracking problem, such as cStyleComment, cppStyleComment, - etc.) - - -Version 2.1.1 - March, 2016 ---------------------------- -- Added support for assigning to ParseResults using slices. - -- Fixed bug in ParseResults.toDict(), in which dict values were always - converted to dicts, even if they were just unkeyed lists of tokens. - Reported on SO by Gerald Thibault, thanks Gerald! - -- Fixed bug in SkipTo when using failOn, reported by robyschek, thanks! - -- Fixed bug in Each introduced in 2.1.0, reported by AND patch and - unit test submitted by robyschek, well done! - -- Removed use of functools.partial in replaceWith, as this creates - an ambiguous signature for the generated parse action, which fails in - PyPy. Reported by Evan Hubinger, thanks Evan! - -- Added default behavior to QuotedString to convert embedded '\t', '\n', - etc. characters to their whitespace counterparts. Found during Q&A - exchange on SO with Maxim. - - -Version 2.1.0 - February, 2016 ------------------------------- -- Modified the internal _trim_arity method to distinguish between - TypeError's raised while trying to determine parse action arity and - those raised within the parse action itself. This will clear up those - confusing "() takes exactly 1 argument (0 given)" error - messages when there is an actual TypeError in the body of the parse - action. Thanks to all who have raised this issue in the past, and - most recently to Michael Cohen, who sent in a proposed patch, and got - me to finally tackle this problem. - -- Added compatibility for pickle protocols 2-4 when pickling ParseResults. - In Python 2.x, protocol 0 was the default, and protocol 2 did not work. - In Python 3.x, protocol 3 is the default, so explicitly naming - protocol 0 or 1 was required to pickle ParseResults. With this release, - all protocols 0-4 are supported. Thanks for reporting this on StackOverflow, - Arne Wolframm, and for providing a nice simple test case! - -- Added optional 'stopOn' argument to ZeroOrMore and OneOrMore, to - simplify breaking on stop tokens that would match the repetition - expression. - - It is a common problem to fail to look ahead when matching repetitive - tokens if the sentinel at the end also matches the repetition - expression, as when parsing "BEGIN aaa bbb ccc END" with: - - "BEGIN" + OneOrMore(Word(alphas)) + "END" - - Since "END" matches the repetition expression "Word(alphas)", it will - never get parsed as the terminating sentinel. Up until now, this has - to be resolved by the user inserting their own negative lookahead: - - "BEGIN" + OneOrMore(~Literal("END") + Word(alphas)) + "END" - - Using stopOn, they can more easily write: - - "BEGIN" + OneOrMore(Word(alphas), stopOn="END") + "END" - - The stopOn argument can be a literal string or a pyparsing expression. - Inspired by a question by Lamakaha on StackOverflow (and many previous - questions with the same negative-lookahead resolution). - -- Added expression names for many internal and builtin expressions, to - reduce name and error message overhead during parsing. - -- Converted helper lambdas to functions to refactor and add docstring - support. - -- Fixed ParseResults.asDict() to correctly convert nested ParseResults - values to dicts. - -- Cleaned up some examples, fixed typo in fourFn.py identified by - aristotle2600 on reddit. - -- Removed keepOriginalText helper method, which was deprecated ages ago. - Superceded by originalTextFor. - -- Same for the Upcase class, which was long ago deprecated and replaced - with the upcaseTokens method. - - - -Version 2.0.7 - December, 2015 ------------------------------- -- Simplified string representation of Forward class, to avoid memory - and performance errors while building ParseException messages. Thanks, - Will McGugan, Andrea Censi, and Martijn Vermaat for the bug reports and - test code. - -- Cleaned up additional issues from enhancing the error messages for - Or and MatchFirst, handling Unicode values in expressions. Fixes Unicode - encoding issues in Python 2, thanks to Evan Hubinger for the bug report. - -- Fixed implementation of dir() for ParseResults - was leaving out all the - defined methods and just adding the custom results names. - -- Fixed bug in ignore() that was introduced in pyparsing 1.5.3, that would - not accept a string literal as the ignore expression. - -- Added new example parseTabularData.py to illustrate parsing of data - formatted in columns, with detection of empty cells. - -- Updated a number of examples to more current Python and pyparsing - forms. - - -Version 2.0.6 - November, 2015 ------------------------------- -- Fixed a bug in Each when multiple Optional elements are present. - Thanks for reporting this, whereswalden on SO. - -- Fixed another bug in Each, when Optional elements have results names - or parse actions, reported by Max Rothman - thank you, Max! - -- Added optional parseAll argument to runTests, whether tests should - require the entire input string to be parsed or not (similar to - parseAll argument to parseString). Plus a little neaten-up of the - output on Python 2 (no stray ()'s). - -- Modified exception messages from MatchFirst and Or expressions. These - were formerly misleading as they would only give the first or longest - exception mismatch error message. Now the error message includes all - the alternatives that were possible matches. Originally proposed by - a pyparsing user, but I've lost the email thread - finally figured out - a fairly clean way to do this. - -- Fixed a bug in Or, when a parse action on an alternative raises an - exception, other potentially matching alternatives were not always tried. - Reported by TheVeryOmni on the pyparsing wiki, thanks! - -- Fixed a bug to dump() introduced in 2.0.4, where list values were shown - in duplicate. - - -Version 2.0.5 - October, 2015 ------------------------------ -- (&$(@#&$(@!!!! Some "print" statements snuck into pyparsing v2.0.4, - breaking Python 3 compatibility! Fixed. Reported by jenshn, thanks! - - -Version 2.0.4 - October, 2015 ------------------------------ -- Added ParserElement.addCondition, to simplify adding parse actions - that act primarily as filters. If the given condition evaluates False, - pyparsing will raise a ParseException. The condition should be a method - with the same method signature as a parse action, but should return a - boolean. Suggested by Victor Porton, nice idea Victor, thanks! - -- Slight mod to srange to accept unicode literals for the input string, - such as "[а-яА-Я]" instead of "[\u0430-\u044f\u0410-\u042f]". Thanks - to Alexandr Suchkov for the patch! - -- Enhanced implementation of replaceWith. - -- Fixed enhanced ParseResults.dump() method when the results consists - only of an unnamed array of sub-structure results. Reported by Robin - Siebler, thanks for your patience and persistence, Robin! - -- Fixed bug in fourFn.py example code, where pi and e were defined using - CaselessLiteral instead of CaselessKeyword. This was not a problem until - adding a new function 'exp', and the leading 'e' of 'exp' was accidentally - parsed as the mathematical constant 'e'. Nice catch, Tom Grydeland - thanks! - -- Adopt new-fangled Python features, like decorators and ternary expressions, - per suggestions from Williamzjc - thanks William! (Oh yeah, I'm not - supporting Python 2.3 with this code any more...) Plus, some additional - code fixes/cleanup - thanks again! - -- Added ParserElement.runTests, a little test bench for quickly running - an expression against a list of sample input strings. Basically, I got - tired of writing the same test code over and over, and finally added it - as a test point method on ParserElement. - -- Added withClass helper method, a simplified version of withAttribute for - the common but annoying case when defining a filter on a div's class - - made difficult because 'class' is a Python reserved word. - - -Version 2.0.3 - October, 2014 ------------------------------ -- Fixed escaping behavior in QuotedString. Formerly, only quotation - marks (or characters designated as quotation marks in the QuotedString - constructor) would be escaped. Now all escaped characters will be - escaped, and the escaping backslashes will be removed. - -- Fixed regression in ParseResults.pop() - pop() was pretty much - broken after I added *improvements* in 2.0.2. Reported by Iain - Shelvington, thanks Iain! - -- Fixed bug in And class when initializing using a generator. - -- Enhanced ParseResults.dump() method to list out nested ParseResults that - are unnamed arrays of sub-structures. - -- Fixed UnboundLocalError under Python 3.4 in oneOf method, reported - on Sourceforge by aldanor, thanks! - -- Fixed bug in ParseResults __init__ method, when returning non-ParseResults - types from parse actions that implement __eq__. Raised during discussion - on the pyparsing wiki with cyrfer. - - -Version 2.0.2 - April, 2014 ---------------------------- -- Extended "expr(name)" shortcut (same as "expr.setResultsName(name)") - to accept "expr()" as a shortcut for "expr.copy()". - -- Added "locatedExpr(expr)" helper, to decorate any returned tokens - with their location within the input string. Adds the results names - locn_start and locn_end to the output parse results. - -- Added "pprint()" method to ParseResults, to simplify troubleshooting - and prettified output. Now instead of importing the pprint module - and then writing "pprint.pprint(result)", you can just write - "result.pprint()". This method also accepts addtional positional and - keyword arguments (such as indent, width, etc.), which get passed - through directly to the pprint method - (see http://docs.python.org/2/library/pprint.html#pprint.pprint). - -- Removed deprecation warnings when using '<<' for Forward expression - assignment. '<<=' is still preferred, but '<<' will be retained - for cases whre '<<=' operator is not suitable (such as in defining - lambda expressions). - -- Expanded argument compatibility for classes and functions that - take list arguments, to now accept generators as well. - -- Extended list-like behavior of ParseResults, adding support for - append and extend. NOTE: if you have existing applications using - these names as results names, you will have to access them using - dict-style syntax: res["append"] and res["extend"] - -- ParseResults emulates the change in list vs. iterator semantics for - methods like keys(), values(), and items(). Under Python 2.x, these - methods will return lists, under Python 3.x, these methods will - return iterators. - -- ParseResults now has a method haskeys() which returns True or False - depending on whether any results names have been defined. This simplifies - testing for the existence of results names under Python 3.x, which - returns keys() as an iterator, not a list. - -- ParseResults now supports both list and dict semantics for pop(). - If passed no argument or an integer argument, it will use list semantics - and pop tokens from the list of parsed tokens. If passed a non-integer - argument (most likely a string), it will use dict semantics and - pop the corresponding value from any defined results names. A - second default return value argument is supported, just as in - dict.pop(). - -- Fixed bug in markInputline, thanks for reporting this, Matt Grant! - -- Cleaned up my unit test environment, now runs with Python 2.6 and - 3.3. - - -Version 2.0.1 - July, 2013 --------------------------- -- Removed use of "nonlocal" that prevented using this version of - pyparsing with Python 2.6 and 2.7. This will make it easier to - install for packages that depend on pyparsing, under Python - versions 2.6 and later. Those using older versions of Python - will have to manually install pyparsing 1.5.7. - -- Fixed implementation of <<= operator to return self; reported by - Luc J. Bourhis, with patch fix by Mathias Mamsch - thanks, Luc - and Mathias! - - -Version 2.0.0 - November, 2012 ------------------------------- -- Rather than release another combined Python 2.x/3.x release - I've decided to start a new major version that is only - compatible with Python 3.x (and consequently Python 2.7 as - well due to backporting of key features). This version will - be the main development path from now on, with little follow-on - development on the 1.5.x path. - -- Operator '<<' is now deprecated, in favor of operator '<<=' for - attaching parsing expressions to Forward() expressions. This is - being done to address precedence of operations problems with '<<'. - Operator '<<' will be removed in a future version of pyparsing. - - -Version 1.5.7 - November, 2012 ------------------------------ -- NOTE: This is the last release of pyparsing that will try to - maintain compatibility with Python versions < 2.6. The next - release of pyparsing will be version 2.0.0, using new Python - syntax that will not be compatible for Python version 2.5 or - older. - -- An awesome new example is included in this release, submitted - by Luca DellOlio, for parsing ANTLR grammar definitions, nice - work Luca! - -- Fixed implementation of ParseResults.__str__ to use Pythonic - ''.join() instead of repeated string concatenation. This - purportedly has been a performance issue under PyPy. - -- Fixed bug in ParseResults.__dir__ under Python 3, reported by - Thomas Kluyver, thank you Thomas! - -- Added ParserElement.inlineLiteralsUsing static method, to - override pyparsing's default behavior of converting string - literals to Literal instances, to use other classes (such - as Suppress or CaselessLiteral). - -- Added new operator '<<=', which will eventually replace '<<' for - storing the contents of a Forward(). '<<=' does not have the same - operator precedence problems that '<<' does. - -- 'operatorPrecedence' is being renamed 'infixNotation' as a better - description of what this helper function creates. 'operatorPrecedence' - is deprecated, and will be dropped entirely in a future release. - -- Added optional arguments lpar and rpar to operatorPrecedence, so that - expressions that use it can override the default suppression of the - grouping characters. - -- Added support for using single argument builtin functions as parse - actions. Now you can write 'expr.setParseAction(len)' and get back - the length of the list of matched tokens. Supported builtins are: - sum, len, sorted, reversed, list, tuple, set, any, all, min, and max. - A script demonstrating this feature is included in the examples - directory. - -- Improved linking in generated docs, proposed on the pyparsing wiki - by techtonik, thanks! - -- Fixed a bug in the definition of 'alphas', which was based on the - string.uppercase and string.lowercase "constants", which in fact - *aren't* constant, but vary with locale settings. This could make - parsers locale-sensitive in a subtle way. Thanks to Kef Schecter for - his diligence in following through on reporting and monitoring - this bugfix! - -- Fixed a bug in the Py3 version of pyparsing, during exception - handling with packrat parsing enabled, reported by Catherine - Devlin - thanks Catherine! - -- Fixed typo in ParseBaseException.__dir__, reported anonymously on - the SourceForge bug tracker, thank you Pyparsing User With No Name. - -- Fixed bug in srange when using '\x###' hex character codes. - -- Addeed optional 'intExpr' argument to countedArray, so that you - can define your own expression that will evaluate to an integer, - to be used as the count for the following elements. Allows you - to define a countedArray with the count given in hex, for example, - by defining intExpr as "Word(hexnums).setParseAction(int(t[0],16))". - - -Version 1.5.6 - June, 2011 ----------------------------- -- Cleanup of parse action normalizing code, to be more version-tolerant, - and robust in the face of future Python versions - much thanks to - Raymond Hettinger for this rewrite! - -- Removal of exception cacheing, addressing a memory leak condition - in Python 3. Thanks to Michael Droettboom and the Cape Town PUG for - their analysis and work on this problem! - -- Fixed bug when using packrat parsing, where a previously parsed - expression would duplicate subsequent tokens - reported by Frankie - Ribery on stackoverflow, thanks! - -- Added 'ungroup' helper method, to address token grouping done - implicitly by And expressions, even if only one expression in the - And actually returns any text - also inspired by stackoverflow - discussion with Frankie Ribery! - -- Fixed bug in srange, which accepted escaped hex characters of the - form '\0x##', but should be '\x##'. Both forms will be supported - for backwards compatibility. - -- Enhancement to countedArray, accepting an optional expression to be - used for matching the leading integer count - proposed by Mathias on - the pyparsing mailing list, good idea! - -- Added the Verilog parser to the provided set of examples, under the - MIT license. While this frees up this parser for any use, if you find - yourself using it in a commercial purpose, please consider making a - charitable donation as described in the parser's header. - -- Added the excludeChars argument to the Word class, to simplify defining - a word composed of all characters in a large range except for one or - two. Suggested by JesterEE on the pyparsing wiki. - -- Added optional overlap parameter to scanString, to return overlapping - matches found in the source text. - -- Updated oneOf internal regular expression generation, with improved - parse time performance. - -- Slight performance improvement in transformString, removing empty - strings from the list of string fragments built while scanning the - source text, before calling ''.join. Especially useful when using - transformString to strip out selected text. - -- Enhanced form of using the "expr('name')" style of results naming, - in lieu of calling setResultsName. If name ends with an '*', then - this is equivalent to expr.setResultsName('name',listAllMatches=True). - -- Fixed up internal list flattener to use iteration instead of recursion, - to avoid stack overflow when transforming large files. - -- Added other new examples: - . protobuf parser - parses Google's protobuf language - . btpyparse - a BibTex parser contributed by Matthew Brett, - with test suite test_bibparse.py (thanks, Matthew!) - . groupUsingListAllMatches.py - demo using trailing '*' for results - names - - -Version 1.5.5 - August, 2010 ----------------------------- - -- Typo in Python3 version of pyparsing, "builtin" should be "builtins". - (sigh) - - -Version 1.5.4 - August, 2010 ----------------------------- - -- Fixed __builtins__ and file references in Python 3 code, thanks to - Greg Watson, saulspatz, sminos, and Mark Summerfield for reporting - their Python 3 experiences. - -- Added new example, apicheck.py, as a sample of scanning a Tcl-like - language for functions with incorrect number of arguments (difficult - to track down in Tcl languages). This example uses some interesting - methods for capturing exceptions while scanning through source - code. - -- Added new example deltaTime.py, that takes everyday time references - like "an hour from now", "2 days ago", "next Sunday at 2pm". - - -Version 1.5.3 - June, 2010 --------------------------- - -- ======= NOTE: API CHANGE!!!!!!! =============== - With this release, and henceforward, the pyparsing module is - imported as "pyparsing" on both Python 2.x and Python 3.x versions. - -- Fixed up setup.py to auto-detect Python version and install the - correct version of pyparsing - suggested by Alex Martelli, - thanks, Alex! (and my apologies to all those who struggled with - those spurious installation errors caused by my earlier - fumblings!) - -- Fixed bug on Python3 when using parseFile, getting bytes instead of - a str from the input file. - -- Fixed subtle bug in originalTextFor, if followed by - significant whitespace (like a newline) - discovered by - Francis Vidal, thanks! - -- Fixed very sneaky bug in Each, in which Optional elements were - not completely recognized as optional - found by Tal Weiss, thanks - for your patience. - -- Fixed off-by-1 bug in line() method when the first line of the - input text was an empty line. Thanks to John Krukoff for submitting - a patch! - -- Fixed bug in transformString if grammar contains Group expressions, - thanks to patch submitted by barnabas79, nice work! - -- Fixed bug in originalTextFor in which trailing comments or otherwised - ignored text got slurped in with the matched expression. Thanks to - michael_ramirez44 on the pyparsing wiki for reporting this just in - time to get into this release! - -- Added better support for summing ParseResults, see the new example, - parseResultsSumExample.py. - -- Added support for composing a Regex using a compiled RE object; - thanks to my new colleague, Mike Thornton! - -- In version 1.5.2, I changed the way exceptions are raised in order - to simplify the stacktraces reported during parsing. An anonymous - user posted a bug report on SF that this behavior makes it difficult - to debug some complex parsers, or parsers nested within parsers. In - this release I've added a class attribute ParserElement.verbose_stacktrace, - with a default value of False. If you set this to True, pyparsing will - report stacktraces using the pre-1.5.2 behavior. - -- New examples: - - . pymicko.py, a MicroC compiler submitted by Zarko Zivanov. - (Note: this example is separately licensed under the GPLv3, - and requires Python 2.6 or higher.) Thank you, Zarko! - - . oc.py, a subset C parser, using the BNF from the 1996 Obfuscated C - Contest. - - . stateMachine2.py, a modified version of stateMachine.py submitted - by Matt Anderson, that is compatible with Python versions 2.7 and - above - thanks so much, Matt! - - . select_parser.py, a parser for reading SQLite SELECT statements, - as specified at http://www.sqlite.org/lang_select.html; this goes - into much more detail than the simple SQL parser included in pyparsing's - source code - - . excelExpr.py, a *simplistic* first-cut at a parser for Excel - expressions, which I originally posted on comp.lang.python in January, - 2010; beware, this parser omits many common Excel cases (addition of - numbers represented as strings, references to named ranges) - - . cpp_enum_parser.py, a nice little parser posted my Mark Tolonen on - comp.lang.python in August, 2009 (redistributed here with Mark's - permission). Thanks a bunch, Mark! - - . partial_gene_match.py, a sample I posted to Stackoverflow.com, - implementing a special variation on Literal that does "close" matching, - up to a given number of allowed mismatches. The application was to - find matching gene sequences, with allowance for one or two mismatches. - - . tagCapture.py, a sample showing how to use a Forward placeholder to - enforce matching of text parsed in a previous expression. - - . matchPreviousDemo.py, simple demo showing how the matchPreviousLiteral - helper method is used to match a previously parsed token. - - -Version 1.5.2 - April, 2009 ------------------------------- -- Added pyparsing_py3.py module, so that Python 3 users can use - pyparsing by changing their pyparsing import statement to: - - import pyparsing_py3 - - Thanks for help from Patrick Laban and his friend Geremy - Condra on the pyparsing wiki. - -- Removed __slots__ declaration on ParseBaseException, for - compatibility with IronPython 2.0.1. Raised by David - Lawler on the pyparsing wiki, thanks David! - -- Fixed bug in SkipTo/failOn handling - caught by eagle eye - cpennington on the pyparsing wiki! - -- Fixed second bug in SkipTo when using the ignore constructor - argument, reported by Catherine Devlin, thanks! - -- Fixed obscure bug reported by Eike Welk when using a class - as a ParseAction with an errant __getitem__ method. - -- Simplified exception stack traces when reporting parse - exceptions back to caller of parseString or parseFile - thanks - to a tip from Peter Otten on comp.lang.python. - -- Changed behavior of scanString to avoid infinitely looping on - expressions that match zero-length strings. Prompted by a - question posted by ellisonbg on the wiki. - -- Enhanced classes that take a list of expressions (And, Or, - MatchFirst, and Each) to accept generator expressions also. - This can be useful when generating lists of alternative - expressions, as in this case, where the user wanted to match - any repetitions of '+', '*', '#', or '.', but not mixtures - of them (that is, match '+++', but not '+-+'): - - codes = "+*#." - format = MatchFirst(Word(c) for c in codes) - - Based on a problem posed by Denis Spir on the Python tutor - list. - -- Added new example eval_arith.py, which extends the example - simpleArith.py to actually evaluate the parsed expressions. - - -Version 1.5.1 - October, 2008 -------------------------------- -- Added new helper method originalTextFor, to replace the use of - the current keepOriginalText parse action. Now instead of - using the parse action, as in: - - fullName = Word(alphas) + Word(alphas) - fullName.setParseAction(keepOriginalText) - - (in this example, we used keepOriginalText to restore any white - space that may have been skipped between the first and last - names) - You can now write: - - fullName = originalTextFor(Word(alphas) + Word(alphas)) - - The implementation of originalTextFor is simpler and faster than - keepOriginalText, and does not depend on using the inspect or - imp modules. - -- Added optional parseAll argument to parseFile, to be consistent - with parseAll argument to parseString. Posted by pboucher on the - pyparsing wiki, thanks! - -- Added failOn argument to SkipTo, so that grammars can define - literal strings or pyparsing expressions which, if found in the - skipped text, will cause SkipTo to fail. Useful to prevent - SkipTo from reading past terminating expression. Instigated by - question posed by Aki Niimura on the pyparsing wiki. - -- Fixed bug in nestedExpr if multi-character expressions are given - for nesting delimiters. Patch provided by new pyparsing user, - Hans-Martin Gaudecker - thanks, H-M! - -- Removed dependency on xml.sax.saxutils.escape, and included - internal implementation instead - proposed by Mike Droettboom on - the pyparsing mailing list, thanks Mike! Also fixed erroneous - mapping in replaceHTMLEntity of " to ', now correctly maps - to ". (Also added support for mapping ' to '.) - -- Fixed typo in ParseResults.insert, found by Alejandro Dubrovsky, - good catch! - -- Added __dir__() methods to ParseBaseException and ParseResults, - to support new dir() behavior in Py2.6 and Py3.0. If dir() is - called on a ParseResults object, the returned list will include - the base set of attribute names, plus any results names that are - defined. - -- Fixed bug in ParseResults.asXML(), in which the first named - item within a ParseResults gets reported with an tag - instead of with the correct results name. - -- Fixed bug in '-' error stop, when '-' operator is used inside a - Combine expression. - -- Reverted generator expression to use list comprehension, for - better compatibility with old versions of Python. Reported by - jester/artixdesign on the SourceForge pyparsing discussion list. - -- Fixed bug in parseString(parseAll=True), when the input string - ends with a comment or whitespace. - -- Fixed bug in LineStart and LineEnd that did not recognize any - special whitespace chars defined using ParserElement.setDefault- - WhitespaceChars, found while debugging an issue for Marek Kubica, - thanks for the new test case, Marek! - -- Made Forward class more tolerant of subclassing. - - -Version 1.5.0 - June, 2008 --------------------------- -This version of pyparsing includes work on two long-standing -FAQ's: support for forcing parsing of the complete input string -(without having to explicitly append StringEnd() to the grammar), -and a method to improve the mechanism of detecting where syntax -errors occur in an input string with various optional and -alternative paths. This release also includes a helper method -to simplify definition of indentation-based grammars. With -these changes (and the past few minor updates), I thought it was -finally time to bump the minor rev number on pyparsing - so -1.5.0 is now available! Read on... - -- AT LAST!!! You can now call parseString and have it raise - an exception if the expression does not parse the entire - input string. This has been an FAQ for a LONG time. - - The parseString method now includes an optional parseAll - argument (default=False). If parseAll is set to True, then - the given parse expression must parse the entire input - string. (This is equivalent to adding StringEnd() to the - end of the expression.) The default value is False to - retain backward compatibility. - - Inspired by MANY requests over the years, most recently by - ecir-hana on the pyparsing wiki! - -- Added new operator '-' for composing grammar sequences. '-' - behaves just like '+' in creating And expressions, but '-' - is used to mark grammar structures that should stop parsing - immediately and report a syntax error, rather than just - backtracking to the last successful parse and trying another - alternative. For instance, running the following code: - - port_definition = Keyword("port") + '=' + Word(nums) - entity_definition = Keyword("entity") + "{" + - Optional(port_definition) + "}" - - entity_definition.parseString("entity { port 100 }") - - pyparsing fails to detect the missing '=' in the port definition. - But, since this expression is optional, pyparsing then proceeds - to try to match the closing '}' of the entity_definition. Not - finding it, pyparsing reports that there was no '}' after the '{' - character. Instead, we would like pyparsing to parse the 'port' - keyword, and if not followed by an equals sign and an integer, - to signal this as a syntax error. - - This can now be done simply by changing the port_definition to: - - port_definition = Keyword("port") - '=' + Word(nums) - - Now after successfully parsing 'port', pyparsing must also find - an equals sign and an integer, or it will raise a fatal syntax - exception. - - By judicious insertion of '-' operators, a pyparsing developer - can have their grammar report much more informative syntax error - messages. - - Patches and suggestions proposed by several contributors on - the pyparsing mailing list and wiki - special thanks to - Eike Welk and Thomas/Poldy on the pyparsing wiki! - -- Added indentedBlock helper method, to encapsulate the parse - actions and indentation stack management needed to keep track of - indentation levels. Use indentedBlock to define grammars for - indentation-based grouping grammars, like Python's. - - indentedBlock takes up to 3 parameters: - - blockStatementExpr - expression defining syntax of statement - that is repeated within the indented block - - indentStack - list created by caller to manage indentation - stack (multiple indentedBlock 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=True) - - A valid block must contain at least one indented statement. - -- Fixed bug in nestedExpr in which ignored expressions needed - to be set off with whitespace. Reported by Stefaan Himpe, - nice catch! - -- Expanded multiplication of an expression by a tuple, to - accept tuple values of None: - . expr*(n,None) or expr*(n,) is equivalent - to expr*n + ZeroOrMore(expr) - (read as "at least n instances of expr") - . expr*(None,n) is equivalent to expr*(0,n) - (read as "0 to n instances of expr") - . expr*(None,None) is equivalent to ZeroOrMore(expr) - . expr*(1,None) is equivalent to OneOrMore(expr) - - Note that expr*(None,n) does not raise an exception if - more than n exprs exist in the input stream; that is, - expr*(None,n) does not enforce a maximum number of expr - occurrences. If this behavior is desired, then write - expr*(None,n) + ~expr - -- Added None as a possible operator for operatorPrecedence. - None signifies "no operator", as in multiplying m times x - in "y=mx+b". - -- Fixed bug in Each, reported by Michael Ramirez, in which the - order of terms in the Each affected the parsing of the results. - Problem was due to premature grouping of the expressions in - the overall Each during grammar construction, before the - complete Each was defined. Thanks, Michael! - -- Also fixed bug in Each in which Optional's with default values - were not getting the defaults added to the results of the - overall Each expression. - -- Fixed a bug in Optional in which results names were not - assigned if a default value was supplied. - -- Cleaned up Py3K compatibility statements, including exception - construction statements, and better equivalence between _ustr - and basestring, and __nonzero__ and __bool__. - - -Version 1.4.11 - February, 2008 -------------------------------- -- With help from Robert A. Clark, this version of pyparsing - is compatible with Python 3.0a3. Thanks for the help, - Robert! - -- Added WordStart and WordEnd positional classes, to support - expressions that must occur at the start or end of a word. - Proposed by piranha on the pyparsing wiki, good idea! - -- Added matchOnlyAtCol helper parser action, to simplify - parsing log or data files that have optional fields that are - column dependent. Inspired by a discussion thread with - hubritic on comp.lang.python. - -- Added withAttribute.ANY_VALUE as a match-all value when using - withAttribute. Used to ensure that an attribute is present, - without having to match on the actual attribute value. - -- Added get() method to ParseResults, similar to dict.get(). - Suggested by new pyparsing user, Alejandro Dubrovksy, thanks! - -- Added '==' short-cut to see if a given string matches a - pyparsing expression. For instance, you can now write: - - integer = Word(nums) - if "123" == integer: - # do something - - print [ x for x in "123 234 asld".split() if x==integer ] - # prints ['123', '234'] - -- Simplified the use of nestedExpr when using an expression for - the opening or closing delimiters. Now the content expression - will not have to explicitly negate closing delimiters. Found - while working with dfinnie on GHOP Task #277, thanks! - -- Fixed bug when defining ignorable expressions that are - later enclosed in a wrapper expression (such as ZeroOrMore, - OneOrMore, etc.) - found while working with Prabhu - Gurumurthy, thanks Prahbu! - -- Fixed bug in withAttribute in which keys were automatically - converted to lowercase, making it impossible to match XML - attributes with uppercase characters in them. Using with- - Attribute requires that you reference attributes in all - lowercase if parsing HTML, and in correct case when parsing - XML. - -- Changed '<<' operator on Forward to return None, since this - is really used as a pseudo-assignment operator, not as a - left-shift operator. By returning None, it is easier to - catch faulty statements such as a << b | c, where precedence - of operations causes the '|' operation to be performed - *after* inserting b into a, so no alternation is actually - implemented. The correct form is a << (b | c). With this - change, an error will be reported instead of silently - clipping the alternative term. (Note: this may break some - existing code, but if it does, the code had a silent bug in - it anyway.) Proposed by wcbarksdale on the pyparsing wiki, - thanks! - -- Several unit tests were added to pyparsing's regression - suite, courtesy of the Google Highly-Open Participation - Contest. Thanks to all who administered and took part in - this event! - - -Version 1.4.10 - December 9, 2007 ---------------------------------- -- Fixed bug introduced in v1.4.8, parse actions were called for - intermediate operator levels, not just the deepest matching - operation level. Again, big thanks to Torsten Marek for - helping isolate this problem! - - -Version 1.4.9 - December 8, 2007 --------------------------------- -- Added '*' multiplication operator support when creating - grammars, accepting either an integer, or a two-integer - tuple multiplier, as in: - ipAddress = Word(nums) + ('.'+Word(nums))*3 - usPhoneNumber = Word(nums) + ('-'+Word(nums))*(1,2) - If multiplying by a tuple, the two integer values represent - min and max multiples. Suggested by Vincent of eToy.com, - great idea, Vincent! - -- Fixed bug in nestedExpr, original version was overly greedy! - Thanks to Michael Ramirez for raising this issue. - -- Fixed internal bug in ParseResults - when an item was deleted, - the key indices were not updated. Thanks to Tim Mitchell for - posting a bugfix patch to the SF bug tracking system! - -- Fixed internal bug in operatorPrecedence - when the results of - a right-associative term were sent to a parse action, the wrong - tokens were sent. Reported by Torsten Marek, nice job! - -- Added pop() method to ParseResults. If pop is called with an - integer or with no arguments, it will use list semantics and - update the ParseResults' list of tokens. If pop is called with - a non-integer (a string, for instance), then it will use dict - semantics and update the ParseResults' internal dict. - Suggested by Donn Ingle, thanks Donn! - -- Fixed quoted string built-ins to accept '\xHH' hex characters - within the string. - - -Version 1.4.8 - October, 2007 ------------------------------ -- Added new helper method nestedExpr to easily create expressions - that parse lists of data in nested parentheses, braces, brackets, - etc. - -- Added withAttribute parse action helper, to simplify creating - filtering parse actions to attach to expressions returned by - makeHTMLTags and makeXMLTags. Use withAttribute to qualify a - starting tag with one or more required attribute values, to avoid - false matches on common tags such as or
. - -- Added new examples nested.py and withAttribute.py to demonstrate - the new features. - -- Added performance speedup to grammars using operatorPrecedence, - instigated by Stefan Reichör - thanks for the feedback, Stefan! - -- Fixed bug/typo when deleting an element from a ParseResults by - using the element's results name. - -- Fixed whitespace-skipping bug in wrapper classes (such as Group, - Suppress, Combine, etc.) and when using setDebug(), reported by - new pyparsing user dazzawazza on SourceForge, nice job! - -- Added restriction to prevent defining Word or CharsNotIn expressions - with minimum length of 0 (should use Optional if this is desired), - and enhanced docstrings to reflect this limitation. Issue was - raised by Joey Tallieu, who submitted a patch with a slightly - different solution. Thanks for taking the initiative, Joey, and - please keep submitting your ideas! - -- Fixed bug in makeHTMLTags that did not detect HTML tag attributes - with no '= value' portion (such as ""), reported by - hamidh on the pyparsing wiki - thanks! - -- Fixed minor bug in makeHTMLTags and makeXMLTags, which did not - accept whitespace in closing tags. - - -Version 1.4.7 - July, 2007 --------------------------- -- NEW NOTATION SHORTCUT: ParserElement now accepts results names using - a notational shortcut, following the expression with the results name - in parentheses. So this: - - stats = "AVE:" + realNum.setResultsName("average") + \ - "MIN:" + realNum.setResultsName("min") + \ - "MAX:" + realNum.setResultsName("max") - - can now be written as this: - - stats = "AVE:" + realNum("average") + \ - "MIN:" + realNum("min") + \ - "MAX:" + realNum("max") - - The intent behind this change is to make it simpler to define results - names for significant fields within the expression, while keeping - the grammar syntax clean and uncluttered. - -- Fixed bug when packrat parsing is enabled, with cached ParseResults - being updated by subsequent parsing. Reported on the pyparsing - wiki by Kambiz, thanks! - -- Fixed bug in operatorPrecedence for unary operators with left - associativity, if multiple operators were given for the same term. - -- Fixed bug in example simpleBool.py, corrected precedence of "and" vs. - "or" operations. - -- Fixed bug in Dict class, in which keys were converted to strings - whether they needed to be or not. Have narrowed this logic to - convert keys to strings only if the keys are ints (which would - confuse __getitem__ behavior for list indexing vs. key lookup). - -- Added ParserElement method setBreak(), which will invoke the pdb - module's set_trace() function when this expression is about to be - parsed. - -- Fixed bug in StringEnd in which reading off the end of the input - string raises an exception - should match. Resolved while - answering a question for Shawn on the pyparsing wiki. - - -Version 1.4.6 - April, 2007 ---------------------------- -- Simplified constructor for ParseFatalException, to support common - exception construction idiom: - raise ParseFatalException, "unexpected text: 'Spanish Inquisition'" - -- Added method getTokensEndLoc(), to be called from within a parse action, - for those parse actions that need both the starting *and* ending - location of the parsed tokens within the input text. - -- Enhanced behavior of keepOriginalText so that named parse fields are - preserved, even though tokens are replaced with the original input - text matched by the current expression. Also, cleaned up the stack - traversal to be more robust. Suggested by Tim Arnold - thanks, Tim! - -- Fixed subtle bug in which countedArray (and similar dynamic - expressions configured in parse actions) failed to match within Or, - Each, FollowedBy, or NotAny. Reported by Ralf Vosseler, thanks for - your patience, Ralf! - -- Fixed Unicode bug in upcaseTokens and downcaseTokens parse actions, - scanString, and default debugging actions; reported (and patch submitted) - by Nikolai Zamkovoi, spasibo! - -- Fixed bug when saving a tuple as a named result. The returned - token list gave the proper tuple value, but accessing the result by - name only gave the first element of the tuple. Reported by - Poromenos, nice catch! - -- Fixed bug in makeHTMLTags/makeXMLTags, which failed to match tag - attributes with namespaces. - -- Fixed bug in SkipTo when setting include=True, to have the skipped-to - tokens correctly included in the returned data. Reported by gunars on - the pyparsing wiki, thanks! - -- Fixed typobug in OnceOnly.reset method, omitted self argument. - Submitted by eike welk, thanks for the lint-picking! - -- Added performance enhancement to Forward class, suggested by - akkartik on the pyparsing Wiki discussion, nice work! - -- Added optional asKeyword to Word constructor, to indicate that the - given word pattern should be matched only as a keyword, that is, it - should only match if it is within word boundaries. - -- Added S-expression parser to examples directory. - -- Added macro substitution example to examples directory. - -- Added holaMundo.py example, excerpted from Marco Alfonso's blog - - muchas gracias, Marco! - -- Modified internal cyclic references in ParseResults to use weakrefs; - this should help reduce the memory footprint of large parsing - programs, at some cost to performance (3-5%). Suggested by bca48150 on - the pyparsing wiki, thanks! - -- Enhanced the documentation describing the vagaries and idiosyncracies - of parsing strings with embedded tabs, and the impact on: - . parse actions - . scanString - . col and line helper functions - (Suggested by eike welk in response to some unexplained inconsistencies - between parsed location and offsets in the input string.) - -- Cleaned up internal decorators to preserve function names, - docstrings, etc. - - -Version 1.4.5 - December, 2006 ------------------------------- -- Removed debugging print statement from QuotedString class. Sorry - for not stripping this out before the 1.4.4 release! - -- A significant performance improvement, the first one in a while! - For my Verilog parser, this version of pyparsing is about double the - speed - YMMV. - -- Added support for pickling of ParseResults objects. (Reported by - Jeff Poole, thanks Jeff!) - -- Fixed minor bug in makeHTMLTags that did not recognize tag attributes - with embedded '-' or '_' characters. Also, added support for - passing expressions to makeHTMLTags and makeXMLTags, and used this - feature to define the globals anyOpenTag and anyCloseTag. - -- Fixed error in alphas8bit, I had omitted the y-with-umlaut character. - -- Added punc8bit string to complement alphas8bit - it contains all the - non-alphabetic, non-blank 8-bit characters. - -- Added commonHTMLEntity expression, to match common HTML "ampersand" - codes, such as "<", ">", "&", " ", and """. This - expression also defines a results name 'entity', which can be used - to extract the entity field (that is, "lt", "gt", etc.). Also added - built-in parse action replaceHTMLEntity, which can be attached to - commonHTMLEntity to translate "<", ">", "&", " ", and - """ to "<", ">", "&", " ", and "'". - -- Added example, htmlStripper.py, that strips HTML tags and scripts - from HTML pages. It also translates common HTML entities to their - respective characters. - - -Version 1.4.4 - October, 2006 -------------------------------- -- Fixed traceParseAction decorator to also trap and record exception - returns from parse actions, and to handle parse actions with 0, - 1, 2, or 3 arguments. - -- Enhanced parse action normalization to support using classes as - parse actions; that is, the class constructor is called at parse - time and the __init__ function is called with 0, 1, 2, or 3 - arguments. If passing a class as a parse action, the __init__ - method must use one of the valid parse action parameter list - formats. (This technique is useful when using pyparsing to compile - parsed text into a series of application objects - see the new - example simpleBool.py.) - -- Fixed bug in ParseResults when setting an item using an integer - index. (Reported by Christopher Lambacher, thanks!) - -- Fixed whitespace-skipping bug, patch submitted by Paolo Losi - - grazie, Paolo! - -- Fixed bug when a Combine contained an embedded Forward expression, - reported by cie on the pyparsing wiki - good catch! - -- Fixed listAllMatches bug, when a listAllMatches result was - nested within another result. (Reported by don pasquale on - comp.lang.python, well done!) - -- Fixed bug in ParseResults items() method, when returning an item - marked as listAllMatches=True - -- Fixed bug in definition of cppStyleComment (and javaStyleComment) - in which '//' line comments were not continued to the next line - if the line ends with a '\'. (Reported by eagle-eyed Ralph - Corderoy!) - -- Optimized re's for cppStyleComment and quotedString for better - re performance - also provided by Ralph Corderoy, thanks! - -- Added new example, indentedGrammarExample.py, showing how to - define a grammar using indentation to show grouping (as Python - does for defining statement nesting). Instigated by an e-mail - discussion with Andrew Dalke, thanks Andrew! - -- Added new helper operatorPrecedence (based on e-mail list discussion - with Ralph Corderoy and Paolo Losi), to facilitate definition of - grammars for expressions with unary and binary operators. For - instance, this grammar defines a 6-function arithmetic expression - grammar, with unary plus and minus, proper operator precedence,and - right- and left-associativity: - - expr = operatorPrecedence( operand, - [("!", 1, opAssoc.LEFT), - ("^", 2, opAssoc.RIGHT), - (oneOf("+ -"), 1, opAssoc.RIGHT), - (oneOf("* /"), 2, opAssoc.LEFT), - (oneOf("+ -"), 2, opAssoc.LEFT),] - ) - - Also added example simpleArith.py and simpleBool.py to provide - more detailed code samples using this new helper method. - -- Added new helpers matchPreviousLiteral and matchPreviousExpr, for - creating adaptive parsing expressions that match the same content - as was parsed in a previous parse expression. For instance: - - first = Word(nums) - matchExpr = first + ":" + matchPreviousLiteral(first) - - will match "1:1", but not "1:2". Since this matches at the literal - level, this will also match the leading "1:1" in "1:10". - - In contrast: - - first = Word(nums) - matchExpr = first + ":" + matchPreviousExpr(first) - - will *not* match the leading "1:1" in "1:10"; the expressions are - evaluated first, and then compared, so "1" is compared with "10". - -- Added keepOriginalText parse action. Sometimes pyparsing's - whitespace-skipping leaves out too much whitespace. Adding this - parse action will restore any internal whitespace for a parse - expression. This is especially useful when defining expressions - for scanString or transformString applications. - -- Added __add__ method for ParseResults class, to better support - using Python sum built-in for summing ParseResults objects returned - from scanString. - -- Added reset method for the new OnlyOnce class wrapper for parse - actions (to allow a grammar to be used multiple times). - -- Added optional maxMatches argument to scanString and searchString, - to short-circuit scanning after 'n' expression matches are found. - - -Version 1.4.3 - July, 2006 ------------------------------- -- Fixed implementation of multiple parse actions for an expression - (added in 1.4.2). - . setParseAction() reverts to its previous behavior, setting - one (or more) actions for an expression, overwriting any - action or actions previously defined - . new method addParseAction() appends one or more parse actions - to the list of parse actions attached to an expression - Now it is harder to accidentally append parse actions to an - expression, when what you wanted to do was overwrite whatever had - been defined before. (Thanks, Jean-Paul Calderone!) - -- Simplified interface to parse actions that do not require all 3 - parse action arguments. Very rarely do parse actions require more - than just the parsed tokens, yet parse actions still require all - 3 arguments including the string being parsed and the location - within the string where the parse expression was matched. With this - release, parse actions may now be defined to be called as: - . fn(string,locn,tokens) (the current form) - . fn(locn,tokens) - . fn(tokens) - . fn() - The setParseAction and addParseAction methods will internally decorate - the provided parse actions with compatible wrappers to conform to - the full (string,locn,tokens) argument sequence. - -- REMOVED SUPPORT FOR RETURNING PARSE LOCATION FROM A PARSE ACTION. - I announced this in March, 2004, and gave a final warning in the last - release. Now you can return a tuple from a parse action, and it will - be treated like any other return value (i.e., the tuple will be - substituted for the incoming tokens passed to the parse action, - which is useful when trying to parse strings into tuples). - -- Added setFailAction method, taking a callable function fn that - takes the arguments 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 values. It may throw ParseFatalException - if it is desired to stop parsing immediately. - (Suggested by peter21081944 on wikispaces.com) - -- Added class OnlyOnce as helper wrapper for parse actions. OnlyOnce - only permits a parse action to be called one time, after which - all subsequent calls throw a ParseException. - -- Added traceParseAction decorator to help debug parse actions. - Simply insert "@traceParseAction" ahead of the definition of your - parse action, and each invocation will be displayed, along with - incoming arguments, and returned value. - -- Fixed bug when copying ParserElements using copy() or - setResultsName(). (Reported by Dan Thill, great catch!) - -- Fixed bug in asXML() where token text contains <, >, and & - characters - generated XML now escapes these as <, > and - &. (Reported by Jacek Sieka, thanks!) - -- Fixed bug in SkipTo() when searching for a StringEnd(). (Reported - by Pete McEvoy, thanks Pete!) - -- Fixed "except Exception" statements, the most critical added as part - of the packrat parsing enhancement. (Thanks, Erick Tryzelaar!) - -- Fixed end-of-string infinite looping on LineEnd and StringEnd - expressions. (Thanks again to Erick Tryzelaar.) - -- Modified setWhitespaceChars to return self, to be consistent with - other ParserElement modifiers. (Suggested by Erick Tryzelaar.) - -- Fixed bug/typo in new ParseResults.dump() method. - -- Fixed bug in searchString() method, in which only the first token of - an expression was returned. searchString() now returns a - ParseResults collection of all search matches. - -- Added example program removeLineBreaks.py, a string transformer that - converts text files with hard line-breaks into one with line breaks - only between paragraphs. - -- Added example program listAllMatches.py, to illustrate using the - listAllMatches option when specifying results names (also shows new - support for passing lists to oneOf). - -- Added example program linenoExample.py, to illustrate using the - helper methods lineno, line, and col, and returning objects from a - parse action. - -- Added example program parseListString.py, to which can parse the - string representation of a Python list back into a true list. Taken - mostly from my PyCon presentation examples, but now with support - for tuple elements, too! - - - -Version 1.4.2 - April 1, 2006 (No foolin'!) -------------------------------------------- -- Significant speedup from memoizing nested expressions (a technique - known as "packrat parsing"), thanks to Chris Lesniewski-Laas! Your - mileage may vary, but my Verilog parser almost doubled in speed to - over 600 lines/sec! - - 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 ParserElement.enablePackrat(). If - your program uses psyco to "compile as you go", you must call - enablePackrat before calling psyco.full(). If you do not do this, - Python will crash. For best results, call enablePackrat() immediately - after importing pyparsing. - -- Added new helper method countedArray(expr), for defining patterns that - start with a leading integer to indicate the number of array elements, - followed by that many elements, matching the given expr parse - expression. For instance, this two-liner: - wordArray = countedArray(Word(alphas)) - print wordArray.parseString("3 Practicality beats purity")[0] - returns the parsed array of words: - ['Practicality', 'beats', 'purity'] - The leading token '3' is suppressed, although it is easily obtained - from the length of the returned array. - (Inspired by e-mail discussion with Ralf Vosseler.) - -- Added support for attaching multiple parse actions to a single - ParserElement. (Suggested by Dan "Dang" Griffith - nice idea, Dan!) - -- Added support for asymmetric quoting characters in the recently-added - QuotedString class. Now you can define your own quoted string syntax - like "<>". To define - this custom form of QuotedString, your code would define: - dblAngleQuotedString = QuotedString('<<',endQuoteChar='>>') - QuotedString also supports escaped quotes, escape character other - than '\', and multiline. - -- Changed the default value returned internally by Optional, so that - None can be used as a default value. (Suggested by Steven Bethard - - I finally saw the light!) - -- Added dump() method to ParseResults, to make it easier to list out - and diagnose values returned from calling parseString. - -- A new example, a search query string parser, submitted by Steven - Mooij and Rudolph Froger - a very interesting application, thanks! - -- Added an example that parses the BNF in Python's Grammar file, in - support of generating Python grammar documentation. (Suggested by - J H Stovall.) - -- A new example, submitted by Tim Cera, of a flexible parser module, - using a simple config variable to adjust parsing for input formats - that have slight variations - thanks, Tim! - -- Added an example for parsing Roman numerals, showing the capability - of parse actions to "compile" Roman numerals into their integer - values during parsing. - -- Added a new docs directory, for additional documentation or help. - Currently, this includes the text and examples from my recent - presentation at PyCon. - -- Fixed another typo in CaselessKeyword, thanks Stefan Behnel. - -- Expanded oneOf to also accept tuples, not just lists. This really - should be sufficient... - -- Added deprecation warnings when tuple is returned from a parse action. - Looking back, I see that I originally deprecated this feature in March, - 2004, so I'm guessing people really shouldn't have been using this - feature - I'll drop it altogether in the next release, which will - allow users to return a tuple from a parse action (which is really - handy when trying to reconstuct tuples from a tuple string - representation!). - - -Version 1.4.1 - February, 2006 ------------------------------- -- Converted generator expression in QuotedString class to list - comprehension, to retain compatibility with Python 2.3. (Thanks, Titus - Brown for the heads-up!) - -- Added searchString() method to ParserElement, as an alternative to - using "scanString(instring).next()[0][0]" to search through a string - looking for a substring matching a given parse expression. (Inspired by - e-mail conversation with Dave Feustel.) - -- Modified oneOf to accept lists of strings as well as a single string - of space-delimited literals. (Suggested by Jacek Sieka - thanks!) - -- Removed deprecated use of Upcase in pyparsing test code. (Also caught by - Titus Brown.) - -- Removed lstrip() call from Literal - too aggressive in stripping - whitespace which may be valid for some grammars. (Point raised by Jacek - Sieka). Also, made Literal more robust in the event of passing an empty - string. - -- Fixed bug in replaceWith when returning None. - -- Added cautionary documentation for Forward class when assigning a - MatchFirst expression, as in: - fwdExpr << a | b | c - Precedence of operators causes this to be evaluated as: - (fwdExpr << a) | b | c - thereby leaving b and c out as parseable alternatives. Users must - explicitly group the values inserted into the Forward: - fwdExpr << (a | b | c) - (Suggested by Scot Wilcoxon - thanks, Scot!) - - -Version 1.4 - January 18, 2006 ------------------------------- -- Added Regex class, to permit definition of complex embedded expressions - using regular expressions. (Enhancement provided by John Beisley, great - job!) - -- Converted implementations of Word, oneOf, quoted string, and comment - helpers to utilize regular expression matching. Performance improvements - in the 20-40% range. - -- Added QuotedString class, to support definition of non-standard quoted - strings (Suggested by Guillaume Proulx, thanks!) - -- Added CaselessKeyword class, to streamline grammars with, well, caseless - keywords (Proposed by Stefan Behnel, thanks!) - -- Fixed bug in SkipTo, when using an ignoreable expression. (Patch provided - by Anonymous, thanks, whoever-you-are!) - -- Fixed typo in NoMatch class. (Good catch, Stefan Behnel!) - -- Fixed minor bug in _makeTags(), using string.printables instead of - pyparsing.printables. - -- Cleaned up some of the expressions created by makeXXXTags helpers, to - suppress extraneous <> characters. - -- Added some grammar definition-time checking to verify that a grammar is - being built using proper ParserElements. - -- Added examples: - . LAparser.py - linear algebra C preprocessor (submitted by Mike Ellis, - thanks Mike!) - . wordsToNum.py - converts word description of a number back to - the original number (such as 'one hundred and twenty three' -> 123) - . updated fourFn.py to support unary minus, added BNF comments - - -Version 1.3.3 - September 12, 2005 ----------------------------------- -- Improved support for Unicode strings that would be returned using - srange. Added greetingInKorean.py example, for a Korean version of - "Hello, World!" using Unicode. (Thanks, June Kim!) - -- Added 'hexnums' string constant (nums+"ABCDEFabcdef") for defining - hexadecimal value expressions. - -- NOTE: ===THIS CHANGE MAY BREAK EXISTING CODE=== - Modified tag and results definitions returned by makeHTMLTags(), - to better support the looseness of HTML parsing. Tags to be - parsed are now caseless, and keys generated for tag attributes are - now converted to lower case. - - Formerly, makeXMLTags("XYZ") would return a tag with results - name of "startXYZ", this has been changed to "startXyz". If this - tag is matched against '', the - matched keys formerly would be "Abc", "DEF", and "ghi"; keys are - now converted to lower case, giving keys of "abc", "def", and - "ghi". These changes were made to try to address the lax - case sensitivity agreement between start and end tags in many - HTML pages. - - No changes were made to makeXMLTags(), which assumes more rigorous - parsing rules. - - Also, cleaned up case-sensitivity bugs in closing tags, and - switched to using Keyword instead of Literal class for tags. - (Thanks, Steve Young, for getting me to look at these in more - detail!) - -- Added two helper parse actions, upcaseTokens and downcaseTokens, - which will convert matched text to all uppercase or lowercase, - respectively. - -- Deprecated Upcase class, to be replaced by upcaseTokens parse - action. - -- Converted messages sent to stderr to use warnings module, such as - when constructing a Literal with an empty string, one should use - the Empty() class or the empty helper instead. - -- Added ' ' (space) as an escapable character within a quoted - string. - -- Added helper expressions for common comment types, in addition - to the existing cStyleComment (/*...*/) and htmlStyleComment - () - . dblSlashComment = // ... (to end of line) - . cppStyleComment = cStyleComment or dblSlashComment - . javaStyleComment = cppStyleComment - . pythonStyleComment = # ... (to end of line) - - - -Version 1.3.2 - July 24, 2005 ------------------------------ -- Added Each class as an enhanced version of And. 'Each' requires - that all given expressions be present, but may occur in any order. - Special handling is provided to group ZeroOrMore and OneOrMore - elements that occur out-of-order in the input string. You can also - construct 'Each' objects by joining expressions with the '&' - operator. When using the Each class, results names are strongly - recommended for accessing the matched tokens. (Suggested by Pradam - Amini - thanks, Pradam!) - -- Stricter interpretation of 'max' qualifier on Word elements. If the - 'max' attribute is specified, matching will fail if an input field - contains more than 'max' consecutive body characters. For example, - previously, Word(nums,max=3) would match the first three characters - of '0123456', returning '012' and continuing parsing at '3'. Now, - when constructed using the max attribute, Word will raise an - exception with this string. - -- Cleaner handling of nested dictionaries returned by Dict. No - longer necessary to dereference sub-dictionaries as element [0] of - their parents. - === NOTE: THIS CHANGE MAY BREAK SOME EXISTING CODE, BUT ONLY IF - PARSING NESTED DICTIONARIES USING THE LITTLE-USED DICT CLASS === - (Prompted by discussion thread on the Python Tutor list, with - contributions from Danny Yoo, Kent Johnson, and original post by - Liam Clarke - thanks all!) - - - -Version 1.3.1 - June, 2005 ----------------------------------- -- Added markInputline() method to ParseException, to display the input - text line location of the parsing exception. (Thanks, Stefan Behnel!) - -- Added setDefaultKeywordChars(), so that Keyword definitions using a - custom keyword character set do not all need to add the keywordChars - constructor argument (similar to setDefaultWhitespaceChars()). - (suggested by rzhanka on the SourceForge pyparsing forum.) - -- Simplified passing debug actions to setDebugAction(). You can now - pass 'None' for a debug action if you want to take the default - debug behavior. To suppress a particular debug action, you can pass - the pyparsing method nullDebugAction. - -- Refactored parse exception classes, moved all behavior to - ParseBaseException, and the former ParseException is now a subclass of - ParseBaseException. Added a second subclass, ParseFatalException, as - a subclass of ParseBaseException. User-defined parse actions can raise - ParseFatalException if a data inconsistency is detected (such as a - begin-tag/end-tag mismatch), and this will stop all parsing immediately. - (Inspired by e-mail thread with Michele Petrazzo - thanks, Michelle!) - -- Added helper methods makeXMLTags and makeHTMLTags, that simplify the - definition of XML or HTML tag parse expressions for a given tagname. - Both functions return a pair of parse expressions, one for the opening - tag (that is, '') and one for the closing tag (''). - The opening tagame also recognizes any attribute definitions that have - been included in the opening tag, as well as an empty tag (one with a - trailing '/', as in '' which is equivalent to ''). - makeXMLTags uses stricter XML syntax for attributes, requiring that they - be enclosed in double quote characters - makeHTMLTags is more lenient, - and accepts single-quoted strings or any contiguous string of characters - up to the next whitespace character or '>' character. Attributes can - be retrieved as dictionary or attribute values of the returned results - from the opening tag. - -- Added example minimath2.py, a refinement on fourFn.py that adds - an interactive session and support for variables. (Thanks, Steven Siew!) - -- Added performance improvement, up to 20% reduction! (Found while working - with Wolfgang Borgert on performance tuning of his TTCN3 parser.) - -- And another performance improvement, up to 25%, when using scanString! - (Found while working with Henrik Westlund on his C header file scanner.) - -- Updated UML diagrams to reflect latest class/method changes. - - -Version 1.3 - March, 2005 ----------------------------------- -- Added new Keyword class, as a special form of Literal. Keywords - must be followed by whitespace or other non-keyword characters, to - distinguish them from variables or other identifiers that just - happen to start with the same characters as a keyword. For instance, - the input string containing "ifOnlyIfOnly" will match a Literal("if") - at the beginning and in the middle, but will fail to match a - Keyword("if"). Keyword("if") will match only strings such as "if only" - or "if(only)". (Proposed by Wolfgang Borgert, and Berteun Damman - separately requested this on comp.lang.python - great idea!) - -- Added setWhitespaceChars() method to override the characters to be - skipped as whitespace before matching a particular ParseElement. Also - added the class-level method setDefaultWhitespaceChars(), to allow - users to override the default set of whitespace characters (space, - tab, newline, and return) for all subsequently defined ParseElements. - (Inspired by Klaas Hofstra's inquiry on the Sourceforge pyparsing - forum.) - -- Added helper parse actions to support some very common parse - action use cases: - . replaceWith(replStr) - replaces the matching tokens with the - provided replStr replacement string; especially useful with - transformString() - . removeQuotes - removes first and last character from string enclosed - in quotes (note - NOT the same as the string strip() method, as only - a single character is removed at each end) - -- Added copy() method to ParseElement, to make it easier to define - different parse actions for the same basic parse expression. (Note, copy - is implicitly called when using setResultsName().) - - - (The following changes were posted to CVS as Version 1.2.3 - - October-December, 2004) - -- Added support for Unicode strings in creating grammar definitions. - (Big thanks to Gavin Panella!) - -- Added constant alphas8bit to include the following 8-bit characters: - ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ - -- Added srange() function to simplify definition of Word elements, using - regexp-like '[A-Za-z0-9]' syntax. This also simplifies referencing - common 8-bit characters. - -- Fixed bug in Dict when a single element Dict was embedded within another - Dict. (Thanks Andy Yates for catching this one!) - -- Added 'formatted' argument to ParseResults.asXML(). If set to False, - suppresses insertion of whitespace for pretty-print formatting. Default - equals True for backward compatibility. - -- Added setDebugActions() function to ParserElement, to allow user-defined - debugging actions. - -- Added support for escaped quotes (either in \', \", or doubled quote - form) to the predefined expressions for quoted strings. (Thanks, Ero - Carrera!) - -- Minor performance improvement (~5%) converting "char in string" tests - to "char in dict". (Suggested by Gavin Panella, cool idea!) - - -Version 1.2.2 - September 27, 2004 ----------------------------------- -- Modified delimitedList to accept an expression as the delimiter, instead - of only accepting strings. - -- Modified ParseResults, to convert integer field keys to strings (to - avoid confusion with list access). - -- Modified Combine, to convert all embedded tokens to strings before - combining. - -- Fixed bug in MatchFirst in which parse actions would be called for - expressions that only partially match. (Thanks, John Hunter!) - -- Fixed bug in fourFn.py example that fixes right-associativity of ^ - operator. (Thanks, Andrea Griffini!) - -- Added class FollowedBy(expression), to look ahead in the input string - without consuming tokens. - -- Added class NoMatch that never matches any input. Can be useful in - debugging, and in very specialized grammars. - -- Added example pgn.py, for parsing chess game files stored in Portable - Game Notation. (Thanks, Alberto Santini!) - - -Version 1.2.1 - August 19, 2004 -------------------------------- -- Added SkipTo(expression) token type, simplifying grammars that only - want to specify delimiting expressions, and want to match any characters - between them. - -- Added helper method dictOf(key,value), making it easier to work with - the Dict class. (Inspired by Pavel Volkovitskiy, thanks!). - -- Added optional argument listAllMatches (default=False) to - setResultsName(). Setting listAllMatches to True overrides the default - modal setting of tokens to results names; instead, the results name - acts as an accumulator for all matching tokens within the local - repetition group. (Suggested by Amaury Le Leyzour - thanks!) - -- Fixed bug in ParseResults, throwing exception when trying to extract - slice, or make a copy using [:]. (Thanks, Wilson Fowlie!) - -- Fixed bug in transformString() when the input string contains 's - (Thanks, Rick Walia!). - -- Fixed bug in returning tokens from un-Grouped And's, Or's and - MatchFirst's, where too many tokens would be included in the results, - confounding parse actions and returned results. - -- Fixed bug in naming ParseResults returned by And's, Or's, and Match - First's. - -- Fixed bug in LineEnd() - matching this token now correctly consumes - and returns the end of line "\n". - -- Added a beautiful example for parsing Mozilla calendar files (Thanks, - Petri Savolainen!). - -- Added support for dynamically modifying Forward expressions during - parsing. - - -Version 1.2 - 20 June 2004 --------------------------- -- Added definition for htmlComment to help support HTML scanning and - parsing. - -- Fixed bug in generating XML for Dict classes, in which trailing item was - duplicated in the output XML. - -- Fixed release bug in which scanExamples.py was omitted from release - files. - -- Fixed bug in transformString() when parse actions are not defined on the - outermost parser element. - -- Added example urlExtractor.py, as another example of using scanString - and parse actions. - - -Version 1.2beta3 - 4 June 2004 ------------------------------- -- Added White() token type, analogous to Word, to match on whitespace - characters. Use White in parsers with significant whitespace (such as - configuration file parsers that use indentation to indicate grouping). - Construct White with a string containing the whitespace characters to be - matched. Similar to Word, White also takes optional min, max, and exact - parameters. - -- As part of supporting whitespace-signficant parsing, added parseWithTabs() - method to ParserElement, to override the default behavior in parseString - of automatically expanding tabs to spaces. To retain tabs during - parsing, call parseWithTabs() before calling parseString(), parseFile() or - scanString(). (Thanks, Jean-Guillaume Paradis for catching this, and for - your suggestions on whitespace-significant parsing.) - -- Added transformString() method to ParseElement, as a complement to - scanString(). To use transformString, define a grammar and attach a parse - action to the overall grammar that modifies the returned token list. - Invoking transformString() on a target string will then scan for matches, - and replace the matched text patterns according to the logic in the parse - action. transformString() returns the resulting transformed string. - (Note: transformString() does *not* automatically expand tabs to spaces.) - Also added scanExamples.py to the examples directory to show sample uses of - scanString() and transformString(). - -- Removed group() method that was introduced in beta2. This turns out NOT to - be equivalent to nesting within a Group() object, and I'd prefer not to sow - more seeds of confusion. - -- Fixed behavior of asXML() where tags for groups were incorrectly duplicated. - (Thanks, Brad Clements!) - -- Changed beta version message to display to stderr instead of stdout, to - make asXML() easier to use. (Thanks again, Brad.) - - -Version 1.2beta2 - 19 May 2004 ------------------------------- -- *** SIMPLIFIED API *** - Parse actions that do not modify the list of tokens - no longer need to return a value. This simplifies those parse actions that - use the list of tokens to update a counter or record or display some of the - token content; these parse actions can simply end without having to specify - 'return toks'. - -- *** POSSIBLE API INCOMPATIBILITY *** - Fixed CaselessLiteral bug, where the - returned token text was not the original string (as stated in the docs), - but the original string converted to upper case. (Thanks, Dang Griffith!) - **NOTE: this may break some code that relied on this erroneous behavior. - Users should scan their code for uses of CaselessLiteral.** - -- *** POSSIBLE CODE INCOMPATIBILITY *** - I have renamed the internal - attributes on ParseResults from 'dict' and 'list' to '__tokdict' and - '__toklist', to avoid collisions with user-defined data fields named 'dict' - and 'list'. Any client code that accesses these attributes directly will - need to be modified. Hopefully the implementation of methods such as keys(), - items(), len(), etc. on ParseResults will make such direct attribute - accessess unnecessary. - -- Added asXML() method to ParseResults. This greatly simplifies the process - of parsing an input data file and generating XML-structured data. - -- Added getName() method to ParseResults. This method is helpful when - a grammar specifies ZeroOrMore or OneOrMore of a MatchFirst or Or - expression, and the parsing code needs to know which expression matched. - (Thanks, Eric van der Vlist, for this idea!) - -- Added items() and values() methods to ParseResults, to better support using - ParseResults as a Dictionary. - -- Added parseFile() as a convenience function to parse the contents of an - entire text file. Accepts either a file name or a file object. (Thanks - again, Dang!) - -- Added group() method to And, Or, and MatchFirst, as a short-cut alternative - to enclosing a construct inside a Group object. - -- Extended fourFn.py to support exponentiation, and simple built-in functions. - -- Added EBNF parser to examples, including a demo where it parses its own - EBNF! (Thanks to Seo Sanghyeon!) - -- Added Delphi Form parser to examples, dfmparse.py, plus a couple of - sample Delphi forms as tests. (Well done, Dang!) - -- Another performance speedup, 5-10%, inspired by Dang! Plus about a 20% - speedup, by pre-constructing and cacheing exception objects instead of - constructing them on the fly. - -- Fixed minor bug when specifying oneOf() with 'caseless=True'. - -- Cleaned up and added a few more docstrings, to improve the generated docs. - - -Version 1.1.2 - 21 Mar 2004 ---------------------------- -- Fixed minor bug in scanString(), so that start location is at the start of - the matched tokens, not at the start of the whitespace before the matched - tokens. - -- Inclusion of HTML documentation, generated using Epydoc. Reformatted some - doc strings to better generate readable docs. (Beautiful work, Ed Loper, - thanks for Epydoc!) - -- Minor performance speedup, 5-15% - -- And on a process note, I've used the unittest module to define a series of - unit tests, to help avoid the embarrassment of the version 1.1 snafu. - - -Version 1.1.1 - 6 Mar 2004 --------------------------- -- Fixed critical bug introduced in 1.1, which broke MatchFirst(!) token - matching. - **THANK YOU, SEO SANGHYEON!!!** - -- Added "from future import __generators__" to permit running under - pre-Python 2.3. - -- Added example getNTPservers.py, showing how to use pyparsing to extract - a text pattern from the HTML of a web page. - - -Version 1.1 - 3 Mar 2004 -------------------------- -- ***Changed API*** - While testing out parse actions, I found that the value - of loc passed in was not the starting location of the matched tokens, but - the location of the next token in the list. With this version, the location - passed to the parse action is now the starting location of the tokens that - matched. - - A second part of this change is that the return value of parse actions no - longer needs to return a tuple containing both the location and the parsed - tokens (which may optionally be modified); parse actions only need to return - the list of tokens. Parse actions that return a tuple are deprecated; they - will still work properly for conversion/compatibility, but this behavior will - be removed in a future version. - -- Added validate() method, to help diagnose infinite recursion in a grammar tree. - validate() is not 100% fool-proof, but it can help track down nasty infinite - looping due to recursively referencing the same grammar construct without some - intervening characters. - -- Cleaned up default listing of some parse element types, to more closely match - ordinary BNF. Instead of the form :[contents-list], some changes - are: - . And(token1,token2,token3) is "{ token1 token2 token3 }" - . Or(token1,token2,token3) is "{ token1 ^ token2 ^ token3 }" - . MatchFirst(token1,token2,token3) is "{ token1 | token2 | token3 }" - . Optional(token) is "[ token ]" - . OneOrMore(token) is "{ token }..." - . ZeroOrMore(token) is "[ token ]..." - -- Fixed an infinite loop in oneOf if the input string contains a duplicated - option. (Thanks Brad Clements) - -- Fixed a bug when specifying a results name on an Optional token. (Thanks - again, Brad Clements) - -- Fixed a bug introduced in 1.0.6 when I converted quotedString to use - CharsNotIn; I accidentally permitted quoted strings to span newlines. I have - fixed this in this version to go back to the original behavior, in which - quoted strings do *not* span newlines. - -- Fixed minor bug in HTTP server log parser. (Thanks Jim Richardson) - - -Version 1.0.6 - 13 Feb 2004 ----------------------------- -- Added CharsNotIn class (Thanks, Lee SangYeong). This is the opposite of - Word, in that it is constructed with a set of characters *not* to be matched. - (This enhancement also allowed me to clean up and simplify some of the - definitions for quoted strings, cStyleComment, and restOfLine.) - -- **MINOR API CHANGE** - Added joinString argument to the __init__ method of - Combine (Thanks, Thomas Kalka). joinString defaults to "", but some - applications might choose some other string to use instead, such as a blank - or newline. joinString was inserted as the second argument to __init__, - so if you have code that specifies an adjacent value, without using - 'adjacent=', this code will break. - -- Modified LineStart to recognize the start of an empty line. - -- Added optional caseless flag to oneOf(), to create a list of CaselessLiteral - tokens instead of Literal tokens. - -- Added some enhancements to the SQL example: - . Oracle-style comments (Thanks to Harald Armin Massa) - . simple WHERE clause - -- Minor performance speedup - 5-15% - - -Version 1.0.5 - 19 Jan 2004 ----------------------------- -- Added scanString() generator method to ParseElement, to support regex-like - pattern-searching - -- Added items() list to ParseResults, to return named results as a - list of (key,value) pairs - -- Fixed memory overflow in asList() for deeply nested ParseResults (Thanks, - Sverrir Valgeirsson) - -- Minor performance speedup - 10-15% - - -Version 1.0.4 - 8 Jan 2004 ---------------------------- -- Added positional tokens StringStart, StringEnd, LineStart, and LineEnd - -- Added commaSeparatedList to pre-defined global token definitions; also added - commasep.py to the examples directory, to demonstrate the differences between - parsing comma-separated data and simple line-splitting at commas - -- Minor API change: delimitedList does not automatically enclose the - list elements in a Group, but makes this the responsibility of the caller; - also, if invoked using 'combine=True', the list delimiters are also included - in the returned text (good for scoped variables, such as a.b.c or a::b::c, or - for directory paths such as a/b/c) - -- Performance speed-up again, 30-40% - -- Added httpServerLogParser.py to examples directory, as this is - a common parsing task - - -Version 1.0.3 - 23 Dec 2003 ---------------------------- -- Performance speed-up again, 20-40% - -- Added Python distutils installation setup.py, etc. (thanks, Dave Kuhlman) - - -Version 1.0.2 - 18 Dec 2003 ---------------------------- -- **NOTE: Changed API again!!!** (for the last time, I hope) - - + Renamed module from parsing to pyparsing, to better reflect Python - linkage. - -- Also added dictExample.py to examples directory, to illustrate - usage of the Dict class. - - -Version 1.0.1 - 17 Dec 2003 ---------------------------- -- **NOTE: Changed API!** - - + Renamed 'len' argument on Word.__init__() to 'exact' - -- Performance speed-up, 10-30% - - -Version 1.0.0 - 15 Dec 2003 ---------------------------- -- Initial public release - -Version 0.1.1 thru 0.1.17 - October-November, 2003 --------------------------------------------------- -- initial development iterations: - - added Dict, Group - - added helper methods oneOf, delimitedList - - added helpers quotedString (and double and single), restOfLine, cStyleComment - - added MatchFirst as an alternative to the slower Or - - added UML class diagram - - fixed various logic bugs diff --git a/HowToUsePyparsing.html b/HowToUsePyparsing.html deleted file mode 100644 index 1bd180b..0000000 --- a/HowToUsePyparsing.html +++ /dev/null @@ -1,1289 +0,0 @@ - - - - - - -Using the pyparsing module - - - - - - -
-

Using the pyparsing module

- --- - - - - - - - - - - - -
Author:Paul McGuire
Address:
-ptmcg@users.sourceforge.net
-
-
Revision:2.0.1
Date:July, 2013
Copyright:Copyright © 2003-2013 Paul McGuire.
- --- - - - -
abstract:This document provides how-to instructions for the -pyparsing library, an easy-to-use Python module for constructing -and executing basic text parsers. The pyparsing module is useful -for evaluating user-definable -expressions, processing custom application language commands, or -extracting data from formatted reports.
- -
-

1   Steps to follow

-

To parse an incoming data string, the client code must follow these steps:

-
    -
  1. First define the tokens and patterns to be matched, and assign -this to a program variable. Optional results names or parsing -actions can also be defined at this time.
  2. -
  3. Call parseString() or scanString() on this variable, passing in -the string to -be parsed. During the matching process, whitespace between -tokens is skipped by default (although this can be changed). -When token matches occur, any defined parse action methods are -called.
  4. -
  5. Process the parsed results, returned as a list of strings. -Matching results may also be accessed as named attributes of -the returned results, if names are defined in the definition of -the token pattern, using setResultsName().
  6. -
-
-

1.1   Hello, World!

-

The following complete Python program will parse the greeting "Hello, World!", -or any other greeting of the form "<salutation>, <addressee>!":

-
-from pyparsing import Word, alphas
-
-greet = Word( alphas ) + "," + Word( alphas ) + "!"
-greeting = greet.parseString( "Hello, World!" )
-print greeting
-
-

The parsed tokens are returned in the following form:

-
-['Hello', ',', 'World', '!']
-
-
-
-

1.2   Usage notes

-
    -
  • The pyparsing module can be used to interpret simple command -strings or algebraic expressions, or can be used to extract data -from text reports with complicated format and structure ("screen -or report scraping"). However, it is possible that your defined -matching patterns may accept invalid inputs. Use pyparsing to -extract data from strings assumed to be well-formatted.

    -
  • -
  • To keep up the readability of your code, use operators such as +, |, -^, and ~ to combine expressions. You can also combine -string literals with ParseExpressions - they will be -automatically converted to Literal objects. For example:

    -
    -integer  = Word( nums )            # simple unsigned integer
    -variable = Word( alphas, max=1 )   # single letter variable, such as x, z, m, etc.
    -arithOp  = Word( "+-*/", max=1 )   # arithmetic operators
    -equation = variable + "=" + integer + arithOp + integer    # will match "x=2+2", etc.
    -
    -

    In the definition of equation, the string "=" will get added as -a Literal("="), but in a more readable way.

    -
  • -
  • The pyparsing module's default behavior is to ignore whitespace. This is the -case for 99% of all parsers ever written. This allows you to write simple, clean, -grammars, such as the above equation, without having to clutter it up with -extraneous ws markers. The equation grammar will successfully parse all of the -following statements:

    -
    -x=2+2
    -x = 2+2
    -a = 10   *   4
    -r= 1234/ 100000
    -
    -

    Of course, it is quite simple to extend this example to support more elaborate expressions, with -nesting with parentheses, floating point numbers, scientific notation, and named constants -(such as e or pi). See fourFn.py, included in the examples directory.

    -
  • -
  • To modify pyparsing's default whitespace skipping, you can use one or -more of the following methods:

    -
      -
    • use the static method ParserElement.setDefaultWhitespaceChars -to override the normal set of whitespace chars (' tn'). For instance -when defining a grammar in which newlines are significant, you should -call ParserElement.setDefaultWhitespaceChars(' \t') to remove -newline from the set of skippable whitespace characters. Calling -this method will affect all pyparsing expressions defined afterward.

      -
    • -
    • call leaveWhitespace() on individual expressions, to suppress the -skipping of whitespace before trying to match the expression

      -
    • -
    • use Combine to require that successive expressions must be -adjacent in the input string. For instance, this expression:

      -
      -real = Word(nums) + '.' + Word(nums)
      -
      -

      will match "3.14159", but will also match "3 . 12". It will also -return the matched results as ['3', '.', '14159']. By changing this -expression to:

      -
      -real = Combine( Word(nums) + '.' + Word(nums) )
      -
      -

      it will not match numbers with embedded spaces, and it will return a -single concatenated string '3.14159' as the parsed token.

      -
    • -
    -
  • -
  • Repetition of expressions can be indicated using the '*' operator. An -expression may be multiplied by an integer value (to indicate an exact -repetition count), or by a tuple containing -two integers, or None and an integer, representing min and max repetitions -(with None representing no min or no max, depending whether it is the first or -second tuple element). See the following examples, where n is used to -indicate an integer value:

    -
      -
    • expr*3 is equivalent to expr + expr + expr
    • -
    • expr*(2,3) is equivalent to expr + expr + Optional(expr)
    • -
    • expr*(n,None) or expr*(n,) is equivalent -to expr*n + ZeroOrMore(expr) (read as "at least n instances of expr")
    • -
    • expr*(None,n) is equivalent to expr*(0,n) -(read as "0 to n instances of expr")
    • -
    • expr*(None,None) is equivalent to ZeroOrMore(expr)
    • -
    • expr*(1,None) is equivalent to OneOrMore(expr)
    • -
    -

    Note that expr*(None,n) does not raise an exception if -more than n exprs exist in the input stream; that is, -expr*(None,n) does not enforce a maximum number of expr -occurrences. If this behavior is desired, then write -expr*(None,n) + ~expr.

    -
  • -
  • MatchFirst expressions are matched left-to-right, and the first -match found will skip all later expressions within, so be sure -to define less-specific patterns after more-specific patterns. -If you are not sure which expressions are most specific, use Or -expressions (defined using the ^ operator) - they will always -match the longest expression, although they are more -compute-intensive.

    -
  • -
  • Or expressions will evaluate all of the specified subexpressions -to determine which is the "best" match, that is, which matches -the longest string in the input data. In case of a tie, the -left-most expression in the Or list will win.

    -
  • -
  • If parsing the contents of an entire file, pass it to the -parseFile method using:

    -
    -expr.parseFile( sourceFile )
    -
    -
  • -
  • ParseExceptions will report the location where an expected token -or expression failed to match. For example, if we tried to use our -"Hello, World!" parser to parse "Hello World!" (leaving out the separating -comma), we would get an exception, with the message:

    -
    -pyparsing.ParseException: Expected "," (6), (1,7)
    -
    -

    In the case of complex -expressions, the reported location may not be exactly where you -would expect. See more information under ParseException .

    -
  • -
  • Use the Group class to enclose logical groups of tokens within a -sublist. This will help organize your results into more -hierarchical form (the default behavior is to return matching -tokens as a flat list of matching input strings).

    -
  • -
  • Punctuation may be significant for matching, but is rarely of -much interest in the parsed results. Use the suppress() method -to keep these tokens from cluttering up your returned lists of -tokens. For example, delimitedList() matches a succession of -one or more expressions, separated by delimiters (commas by -default), but only returns a list of the actual expressions - -the delimiters are used for parsing, but are suppressed from the -returned output.

    -
  • -
  • Parse actions can be used to convert values from strings to -other data types (ints, floats, booleans, etc.).

    -
  • -
  • Results names are recommended for retrieving tokens from complex -expressions. It is much easier to access a token using its field -name than using a positional index, especially if the expression -contains optional elements. You can also shortcut -the setResultsName call:

    -
    -stats = "AVE:" + realNum.setResultsName("average") + \
    -        "MIN:" + realNum.setResultsName("min") + \
    -        "MAX:" + realNum.setResultsName("max")
    -
    -

    can now be written as this:

    -
    -stats = "AVE:" + realNum("average") + \
    -        "MIN:" + realNum("min") + \
    -        "MAX:" + realNum("max")
    -
    -
  • -
  • Be careful when defining parse actions that modify global variables or -data structures (as in fourFn.py), especially for low level tokens -or expressions that may occur within an And expression; an early element -of an And may match, but the overall expression may fail.

    -
  • -
  • Performance of pyparsing may be slow for complex grammars and/or large -input strings. The psyco package can be used to improve the speed of the -pyparsing module with no changes to grammar or program logic - observed -improvments have been in the 20-50% range.

    -
  • -
-
-
-
-

2   Classes

-
-

2.1   Classes in the pyparsing module

-

ParserElement - abstract base class for all pyparsing classes; -methods for code to use are:

-
    -
  • parseString( sourceString, parseAll=False ) - only called once, on the overall -matching pattern; returns a ParseResults object that makes the -matched tokens available as a list, and optionally as a dictionary, -or as an object with named attributes; if parseAll is set to True, then -parseString will raise a ParseException if the grammar does not process -the complete input string.

    -
  • -
  • parseFile( sourceFile ) - a convenience function, that accepts an -input file object or filename. The file contents are passed as a -string to parseString(). parseFile also supports the parseAll argument.

    -
  • -
  • scanString( sourceString ) - generator function, used to find and -extract matching text in the given source string; for each matched text, -returns a tuple of:

    -
      -
    • matched tokens (packaged as a ParseResults object)
    • -
    • start location of the matched text in the given source string
    • -
    • end location in the given source string
    • -
    -

    scanString allows you to scan through the input source string for -random matches, instead of exhaustively defining the grammar for the entire -source text (as would be required with parseString).

    -
  • -
  • transformString( sourceString ) - convenience wrapper function for -scanString, to process the input source string, and replace matching -text with the tokens returned from parse actions defined in the grammar -(see setParseAction).

    -
  • -
  • searchString( sourceString ) - another convenience wrapper function for -scanString, returns a list of the matching tokens returned from each -call to scanString.

    -
  • -
  • setName( name ) - associate a short descriptive name for this -element, useful in displaying exceptions and trace information

    -
  • -
  • setResultsName( string, listAllMatches=False ) - name to be given -to tokens matching -the element; if multiple tokens within -a repetition group (such as ZeroOrMore or delimitedList) the -default is to return only the last matching token - if listAllMatches -is set to True, then a list of all the matching tokens is returned. -(New in 1.5.6 - a results name with a trailing '*' character will be -interpreted as setting listAllMatches to True.) -Note: -setResultsName returns a copy of the element so that a single -basic element can be referenced multiple times and given -different names within a complex grammar.

    -
  • -
-
    -
  • setParseAction( *fn ) - specify one or more functions to call after successful -matching of the element; each function is defined as fn( s, -loc, toks ), where:

    -
      -
    • s is the original parse string
    • -
    • loc is the location in the string where matching started
    • -
    • toks is the list of the matched tokens, packaged as a ParseResults object
    • -
    -

    Multiple functions can be attached to a ParserElement by specifying multiple -arguments to setParseAction, or by calling setParseAction multiple times.

    -

    Each parse action function can return a modified toks list, to perform conversion, or -string modifications. For brevity, fn may also be a -lambda - here is an example of using a parse action to convert matched -integer tokens from strings to integers:

    -
    -intNumber = Word(nums).setParseAction( lambda s,l,t: [ int(t[0]) ] )
    -
    -

    If fn does not modify the toks list, it does not need to return -anything at all.

    -
  • -
  • setBreak( breakFlag=True ) - if breakFlag is True, calls pdb.set_break() -as this expression is about to be parsed

    -
  • -
  • copy() - returns a copy of a ParserElement; can be used to use the same -parse expression in different places in a grammar, with different parse actions -attached to each

    -
  • -
  • leaveWhitespace() - change default behavior of skipping -whitespace before starting matching (mostly used internally to the -pyparsing module, rarely used by client code)

    -
  • -
  • setWhitespaceChars( chars ) - define the set of chars to be ignored -as whitespace before trying to match a specific ParserElement, in place of the -default set of whitespace (space, tab, newline, and return)

    -
  • -
  • setDefaultWhitespaceChars( chars ) - class-level method to override -the default set of whitespace chars for all subsequently created ParserElements -(including copies); useful when defining grammars that treat one or more of the -default whitespace characters as significant (such as a line-sensitive grammar, to -omit newline from the list of ignorable whitespace)

    -
  • -
  • suppress() - convenience function to suppress the output of the -given element, instead of wrapping it with a Suppress object.

    -
  • -
  • ignore( expr ) - function to specify parse expression to be -ignored while matching defined patterns; can be called -repeatedly to specify multiple expressions; useful to specify -patterns of comment syntax, for example

    -
  • -
  • setDebug( dbgFlag=True ) - function to enable/disable tracing output -when trying to match this element

    -
  • -
  • validate() - function to verify that the defined grammar does not -contain infinitely recursive constructs

    -
  • -
-
    -
  • parseWithTabs() - function to override default behavior of converting -tabs to spaces before parsing the input string; rarely used, except when -specifying whitespace-significant grammars using the White class.
  • -
  • enablePackrat() - a class-level static method to enable a memoizing -performance enhancement, known as "packrat parsing". packrat parsing is -disabled by default, since it may conflict with some user programs that use -parse actions. To activate the packrat feature, your -program must call the class method ParserElement.enablePackrat(). If -your program uses psyco to "compile as you go", you must call -enablePackrat before calling psyco.full(). If you do not do this, -Python will crash. For best results, call enablePackrat() immediately -after importing pyparsing.
  • -
-
-
-

2.2   Basic ParserElement subclasses

-
    -
  • Literal - construct with a string to be matched exactly
  • -
  • CaselessLiteral - construct with a string to be matched, but -without case checking; results are always returned as the -defining literal, NOT as they are found in the input string
  • -
  • Keyword - similar to Literal, but must be immediately followed by -whitespace, punctuation, or other non-keyword characters; prevents -accidental matching of a non-keyword that happens to begin with a -defined keyword
  • -
  • CaselessKeyword - similar to Keyword, but with caseless matching -behavior
  • -
-
    -
  • Word - one or more contiguous characters; construct with a -string containing the set of allowed initial characters, and an -optional second string of allowed body characters; for instance, -a common Word construct is to match a code identifier - in C, a -valid identifier must start with an alphabetic character or an -underscore ('_'), followed by a body that can also include numeric -digits. That is, a, i, MAX_LENGTH, _a1, b_109_, and -plan9FromOuterSpace -are all valid identifiers; 9b7z, $a, .section, and 0debug -are not. To -define an identifier using a Word, use either of the following:

    -
    -- Word( alphas+"_", alphanums+"_" )
    -- Word( srange("[a-zA-Z_]"), srange("[a-zA-Z0-9_]") )
    -
    -

    If only one -string given, it specifies that the same character set defined -for the initial character is used for the word body; for instance, to -define an identifier that can only be composed of capital letters and -underscores, use:

    -
    -- Word( "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" )
    -- Word( srange("[A-Z_]") )
    -
    -

    A Word may -also be constructed with any of the following optional parameters:

    -
      -
    • min - indicating a minimum length of matching characters
    • -
    • max - indicating a maximum length of matching characters
    • -
    • exact - indicating an exact length of matching characters
    • -
    -

    If exact is specified, it will override any values for min or max.

    -

    New in 1.5.6 - Sometimes you want to define a word using all -characters in a range except for one or two of them; you can do this -with the new excludeChars argument. This is helpful if you want to define -a word with all printables except for a single delimiter character, such -as '.'. Previously, you would have to create a custom string to pass to Word. -With this change, you can just create Word(printables, excludeChars='.').

    -
  • -
  • CharsNotIn - similar to Word, but matches characters not -in the given constructor string (accepts only one string for both -initial and body characters); also supports min, max, and exact -optional parameters.

    -
  • -
  • Regex - a powerful construct, that accepts a regular expression -to be matched at the current parse position; accepts an optional -flags parameter, corresponding to the flags parameter in the re.compile -method; if the expression includes named sub-fields, they will be -represented in the returned ParseResults

    -
  • -
  • QuotedString - supports the definition of custom quoted string -formats, in addition to pyparsing's built-in dblQuotedString and -sglQuotedString. QuotedString allows you to specify the following -parameters:

    -
      -
    • quoteChar - string of one or more characters defining the quote delimiting string
    • -
    • escChar - character to escape quotes, typically backslash (default=None)
    • -
    • escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
    • -
    • multiline - boolean indicating whether quotes can span multiple lines (default=False)
    • -
    • unquoteResults - boolean indicating whether the matched text should be unquoted (default=True)
    • -
    • endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar)
    • -
    -
  • -
  • SkipTo - skips ahead in the input string, accepting any -characters up to the specified pattern; may be constructed with -the following optional parameters:

    -
      -
    • include - if set to true, also consumes the match expression -(default is False)
    • -
    • ignore - allows the user to specify patterns to not be matched, -to prevent false matches
    • -
    • failOn - if a literal string or expression is given for this argument, it defines an expression that -should cause the SkipTo expression to fail, and not skip over that expression
    • -
    -
  • -
-
    -
  • White - also similar to Word, but matches whitespace -characters. Not usually needed, as whitespace is implicitly -ignored by pyparsing. However, some grammars are whitespace-sensitive, -such as those that use leading tabs or spaces to indicating grouping -or hierarchy. (If matching on tab characters, be sure to call -parseWithTabs on the top-level parse element.)
  • -
  • Empty - a null expression, requiring no characters - will always -match; useful for debugging and for specialized grammars
  • -
  • NoMatch - opposite of Empty, will never match; useful for debugging -and for specialized grammars
  • -
-
-
-

2.3   Expression subclasses

-
    -
  • And - construct with a list of ParserElements, all of which must -match for And to match; can also be created using the '+' -operator; multiple expressions can be Anded together using the '*' -operator as in:

    -
    -ipAddress = Word(nums) + ('.'+Word(nums))*3
    -
    -

    A tuple can be used as the multiplier, indicating a min/max:

    -
    -usPhoneNumber = Word(nums) + ('-'+Word(nums))*(1,2)
    -
    -

    A special form of And is created if the '-' operator is used -instead of the '+' operator. In the ipAddress example above, if -no trailing '.' and Word(nums) are found after matching the initial -Word(nums), then pyparsing will back up in the grammar and try other -alternatives to ipAddress. However, if ipAddress is defined as:

    -
    -strictIpAddress = Word(nums) - ('.'+Word(nums))*3
    -
    -

    then no backing up is done. If the first Word(nums) of strictIpAddress -is matched, then any mismatch after that will raise a ParseSyntaxException, -which will halt the parsing process immediately. By careful use of the -'-' operator, grammars can provide meaningful error messages close to -the location where the incoming text does not match the specified -grammar.

    -
  • -
  • Or - construct with a list of ParserElements, any of which must -match for Or to match; if more than one expression matches, the -expression that makes the longest match will be used; can also -be created using the '^' operator

    -
  • -
  • MatchFirst - construct with a list of ParserElements, any of -which must match for MatchFirst to match; matching is done -left-to-right, taking the first expression that matches; can -also be created using the '|' operator

    -
  • -
  • Each - similar to And, in that all of the provided expressions -must match; however, Each permits matching to be done in any order; -can also be created using the '&' operator

    -
  • -
  • Optional - construct with a ParserElement, but this element is -not required to match; can be constructed with an optional default argument, -containing a default string or object to be supplied if the given optional -parse element is not found in the input string; parse action will only -be called if a match is found, or if a default is specified

    -
  • -
  • ZeroOrMore - similar to Optional, but can be repeated

    -
  • -
  • OneOrMore - similar to ZeroOrMore, but at least one match must -be present

    -
  • -
  • FollowedBy - a lookahead expression, requires matching of the given -expressions, but does not advance the parsing position within the input string

    -
  • -
  • NotAny - a negative lookahead expression, prevents matching of named -expressions, does not advance the parsing position within the input string; -can also be created using the unary '~' operator

    -
  • -
-
-
-

2.4   Expression operators

-
    -
  • ~ - creates NotAny using the expression after the operator
  • -
  • + - creates And using the expressions before and after the operator
  • -
  • | - creates MatchFirst (first left-to-right match) using the expressions before and after the operator
  • -
  • ^ - creates Or (longest match) using the expressions before and after the operator
  • -
  • & - creates Each using the expressions before and after the operator
  • -
  • * - creates And by multiplying the expression by the integer operand; if -expression is multiplied by a 2-tuple, creates an And of (min,max) -expressions (similar to "{min,max}" form in regular expressions); if -min is None, intepret as (0,max); if max is None, interpret as -expr*min + ZeroOrMore(expr)
  • -
  • - - like + but with no backup and retry of alternatives
  • -
  • * - repetition of expression
  • -
  • == - matching expression to string; returns True if the string matches the given expression
  • -
  • <<= - inserts the expression following the operator as the body of the -Forward expression before the operator (formerly <<, which is now deprecated)
  • -
-
-
-

2.5   Positional subclasses

-
    -
  • StringStart - matches beginning of the text
  • -
  • StringEnd - matches the end of the text
  • -
  • LineStart - matches beginning of a line (lines delimited by \n characters)
  • -
  • LineEnd - matches the end of a line
  • -
  • WordStart - matches a leading word boundary
  • -
  • WordEnd - matches a trailing word boundary
  • -
-
-
-

2.6   Converter subclasses

-
    -
  • Upcase - converts matched tokens to uppercase (deprecated - -use upcaseTokens parse action instead)
  • -
  • Combine - joins all matched tokens into a single string, using -specified joinString (default joinString=""); expects -all matching tokens to be adjacent, with no intervening -whitespace (can be overridden by specifying adjacent=False in constructor)
  • -
  • Suppress - clears matched tokens; useful to keep returned -results from being cluttered with required but uninteresting -tokens (such as list delimiters)
  • -
-
-
-

2.7   Special subclasses

-
    -
  • Group - causes the matched tokens to be enclosed in a list; -useful in repeated elements like ZeroOrMore and OneOrMore to -break up matched tokens into groups for each repeated pattern
  • -
  • Dict - like Group, but also constructs a dictionary, using the -[0]'th elements of all enclosed token lists as the keys, and -each token list as the value
  • -
  • SkipTo - catch-all matching expression that accepts all characters -up until the given pattern is found to match; useful for specifying -incomplete grammars
  • -
  • Forward - placeholder token used to define recursive token -patterns; when defining the actual expression later in the -program, insert it into the Forward object using the <<= -operator (see fourFn.py for an example).
  • -
-
-
-

2.8   Other classes

-
    -
  • ParseResults - class used to contain and manage the lists of tokens -created from parsing the input using the user-defined parse -expression. ParseResults can be accessed in a number of ways:

    -
      -
    • as a list
        -
      • total list of elements can be found using len()
      • -
      • individual elements can be found using [0], [1], [-1], etc.
      • -
      • elements can be deleted using del
      • -
      • the -1th element can be extracted and removed in a single operation -using pop(), or any element can be extracted and removed -using pop(n)
      • -
      -
    • -
    • as a dictionary
        -
      • if setResultsName() is used to name elements within the -overall parse expression, then these fields can be referenced -as dictionary elements or as attributes
      • -
      • the Dict class generates dictionary entries using the data of the -input text - in addition to ParseResults listed as [ [ a1, b1, c1, ...], [ a2, b2, c2, ...]  ] -it also acts as a dictionary with entries defined as { a1 : [ b1, c1, ... ] }, { a2 : [ b2, c2, ... ] }; -this is especially useful when processing tabular data where the first column contains a key -value for that line of data
      • -
      • list elements that are deleted using del will still be accessible by their -dictionary keys
      • -
      • supports get(), items() and keys() methods, similar to a dictionary
      • -
      • a keyed item can be extracted and removed using pop(key). Here -key must be non-numeric (such as a string), in order to use dict -extraction instead of list extraction.
      • -
      • new named elements can be added (in a parse action, for instance), using the same -syntax as adding an item to a dict (parseResults["X"]="new item"); named elements can be removed using del parseResults["X"]
      • -
      -
    • -
    • as a nested list
        -
      • results returned from the Group class are encapsulated within their -own list structure, so that the tokens can be handled as a hierarchical -tree
      • -
      -
    • -
    -

    ParseResults can also be converted to an ordinary list of strings -by calling asList(). Note that this will strip the results of any -field names that have been defined for any embedded parse elements. -(The pprint module is especially good at printing out the nested contents -given by asList().)

    -

    Finally, ParseResults can be converted to an XML string by calling asXML(). Where -possible, results will be tagged using the results names defined for the respective -ParseExpressions. asXML() takes two optional arguments:

    -
      -
    • doctagname - for ParseResults that do not have a defined name, this argument -will wrap the resulting XML in a set of opening and closing tags <doctagname> -and </doctagname>.
    • -
    • namedItemsOnly (default=False) - flag to indicate if the generated XML should -skip items that do not have defined names. If a nested group item is named, then all -embedded items will be included, whether they have names or not.
    • -
    -
  • -
-
-
-

2.9   Exception classes and Troubleshooting

-
    -
  • ParseException - exception returned when a grammar parse fails; -ParseExceptions have attributes loc, msg, line, lineno, and column; to view the -text line and location where the reported ParseException occurs, use:

    -
    -except ParseException, err:
    -    print err.line
    -    print " "*(err.column-1) + "^"
    -    print err
    -
    -
  • -
  • RecursiveGrammarException - exception returned by validate() if -the grammar contains a recursive infinite loop, such as:

    -
    -badGrammar = Forward()
    -goodToken = Literal("A")
    -badGrammar <<= Optional(goodToken) + badGrammar
    -
    -
  • -
  • ParseFatalException - exception that parse actions can raise to stop parsing -immediately. Should be used when a semantic error is found in the input text, such -as a mismatched XML tag.

    -
  • -
  • ParseSyntaxException - subclass of ParseFatalException raised when a -syntax error is found, based on the use of the '-' operator when defining -a sequence of expressions in an And expression.

    -
  • -
-

You can also get some insights into the parsing logic using diagnostic parse actions, -and setDebug(), or test the matching of expression fragments by testing them using -scanString().

-
-
-
-

3   Miscellaneous attributes and methods

-
-

3.1   Helper methods

-
    -
  • delimitedList( expr, delim=',') - convenience function for -matching one or more occurrences of expr, separated by delim. -By default, the delimiters are suppressed, so the returned results contain -only the separate list elements. Can optionally specify combine=True, -indicating that the expressions and delimiters should be returned as one -combined value (useful for scoped variables, such as "a.b.c", or -"a::b::c", or paths such as "a/b/c").

    -
  • -
  • countedArray( expr ) - convenience function for a pattern where an list of -instances of the given expression are preceded by an integer giving the count of -elements in the list. Returns an expression that parses the leading integer, -reads exactly that many expressions, and returns the array of expressions in the -parse results - the leading integer is suppressed from the results (although it -is easily reconstructed by using len on the returned array).

    -
  • -
  • oneOf( string, caseless=False ) - convenience function for quickly declaring an -alternative set of Literal tokens, by splitting the given string on -whitespace boundaries. The tokens are sorted so that longer -matches are attempted first; this ensures that a short token does -not mask a longer one that starts with the same characters. If caseless=True, -will create an alternative set of CaselessLiteral tokens.

    -
  • -
  • dictOf( key, value ) - convenience function for quickly declaring a -dictionary pattern of Dict( ZeroOrMore( Group( key + value ) ) ).

    -
  • -
  • makeHTMLTags( tagName ) and makeXMLTags( tagName ) - convenience -functions to create definitions of opening and closing tag expressions. Returns -a pair of expressions, for the corresponding <tag> and </tag> strings. Includes -support for attributes in the opening tag, such as <tag attr1="abc"> - attributes -are returned as keyed tokens in the returned ParseResults. makeHTMLTags is less -restrictive than makeXMLTags, especially with respect to case sensitivity.

    -
  • -
  • infixNotation(baseOperand, operatorList) - (formerly named operatorPrecedence) convenience function to define a -grammar for parsing infix notation -expressions with a hierarchical precedence of operators. To use the infixNotation -helper:

    -
      -
    1. Define the base "atom" operand term of the grammar. -For this simple grammar, the smallest operand is either -and integer or a variable. This will be the first argument -to the infixNotation method.
    2. -
    3. Define a list of tuples for each level of operator -precendence. 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 -None, indicates an empty operator, such as the implied -multiplication operation between 'm' and 'x' in "y = mx + b". -If numTerms parameter is 3, this must be a 2-tuple containing the 2 delimiting operators.
      • -
      • 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 opAssoc.RIGHT and opAssoc.LEFT.
      • -
      • parseAction is the parse action to be associated with -expressions matching this operator expression (the -parse action tuple member may be omitted)
      • -
      -
    4. -
    5. Call infixNotation passing the operand expression and -the operator precedence list, and save the returned value -as the generated pyparsing expression. You can then use -this expression to parse input strings, or incorporate it -into a larger, more complex grammar.
    6. -
    -
  • -
  • matchPreviousLiteral and matchPreviousExpr - function to define and -expression that matches the same content -as was parsed in a previous parse expression. For instance:

    -
    -first = Word(nums)
    -matchExpr = first + ":" + matchPreviousLiteral(first)
    -
    -

    will match "1:1", but not "1:2". Since this matches at the literal -level, this will also match the leading "1:1" in "1:10".

    -

    In contrast:

    -
    -first = Word(nums)
    -matchExpr = first + ":" + matchPreviousExpr(first)
    -
    -

    will not match the leading "1:1" in "1:10"; the expressions are -evaluated first, and then compared, so "1" is compared with "10".

    -
  • -
  • nestedExpr(opener, closer, content=None, ignoreExpr=quotedString) - method for defining nested -lists enclosed in opening and closing delimiters.

    -
      -
    • opener - opening character for a nested list (default="("); can also be a pyparsing expression
    • -
    • closer - closing character for a nested list (default=")"); can also be a pyparsing expression
    • -
    • content - expression for items within the nested lists (default=None)
    • -
    • ignoreExpr - expression for ignoring opening and closing delimiters (default=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 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 Or or MatchFirst. -The default is quotedString, but if no expressions are to be ignored, -then pass None for this argument.

    -
  • -
  • indentedBlock( statementExpr, indentationStackVar, indent=True) - -function to define an indented block of statements, similar to -indentation-based blocking in Python source code:

    -
      -
    • statementExpr - the expression defining a statement that -will be found in the indented block; a valid indentedBlock -must contain at least 1 matching statementExpr
    • -
    • indentationStackVar - a Python list variable; this variable -should be common to all indentedBlock expressions defined -within the same grammar, and should be reinitialized to [1] -each time the grammar is to be used
    • -
    • indent - a boolean flag indicating whether the expressions -within the block must be indented from the current parse -location; if using indentedBlock to define the left-most -statements (all starting in column 1), set indent to False
    • -
    -
  • -
-
    -
  • originalTextFor( expr ) - helper function to preserve the originally parsed text, regardless of any -token processing or conversion done by the contained expression. For instance, the following expression:

    -
    -fullName = Word(alphas) + Word(alphas)
    -
    -

    will return the parse of "John Smith" as ['John', 'Smith']. In some applications, the actual name as it -was given in the input string is what is desired. To do this, use originalTextFor:

    -
    -fullName = originalTextFor(Word(alphas) + Word(alphas))
    -
    -
  • -
  • ungroup( expr ) - function to "ungroup" returned tokens; useful -to undo the default behavior of And to always group the returned tokens, even -if there is only one in the list. (New in 1.5.6)

    -
  • -
  • lineno( loc, string ) - function to give the line number of the -location within the string; the first line is line 1, newlines -start new rows

    -
  • -
  • col( loc, string ) - function to give the column number of the -location within the string; the first column is column 1, -newlines reset the column number to 1

    -
  • -
  • line( loc, string ) - function to retrieve the line of text -representing lineno( loc, string ); useful when printing out diagnostic -messages for exceptions

    -
  • -
  • srange( rangeSpec ) - function to define a string of characters, -given a string of the form used by regexp string ranges, such as "[0-9]" for -all numeric digits, "[A-Z_]" for uppercase characters plus underscore, and -so on (note that rangeSpec does not include support for generic regular -expressions, just string range specs)

    -
  • -
  • getTokensEndLoc() - function to call from within a parse action to get -the ending location for the matched tokens

    -
  • -
  • traceParseAction(fn) - decorator function to debug parse actions. Lists -each call, called arguments, and return value or exception

    -
  • -
-
-
-

3.2   Helper parse actions

-
    -
  • removeQuotes - removes the first and last characters of a quoted string; -useful to remove the delimiting quotes from quoted strings

    -
  • -
  • replaceWith(replString) - returns a parse action that simply returns the -replString; useful when using transformString, or converting HTML entities, as in:

    -
    -nbsp = Literal("&nbsp;").setParseAction( replaceWith("<BLANK>") )
    -
    -
  • -
  • keepOriginalText- (deprecated, use originalTextFor instead) restores any internal whitespace or suppressed -text within the tokens for a matched parse -expression. This is especially useful when defining expressions -for scanString or transformString applications.

    -
  • -
  • withAttribute( *args, **kwargs ) - helper to create a validating parse action to be used with start tags created -with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag -with a required attribute value, to avoid false matches on common tags such as -<TD> or <DIV>.

    -

    withAttribute can be called with:

    -
      -
    • keyword arguments, as in (class="Customer",align="right"), or
    • -
    • a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
    • -
    -

    An attribute can be specified to have the special value -withAttribute.ANY_VALUE, which will match any value - use this to -ensure that an attribute is present but any attribute value is -acceptable.

    -
  • -
  • downcaseTokens - converts all matched tokens to lowercase

    -
  • -
  • upcaseTokens - converts all matched tokens to uppercase

    -
  • -
  • matchOnlyAtCol( columnNumber ) - a parse action that verifies that -an expression was matched at a particular column, raising a -ParseException if matching at a different column number; useful when parsing -tabular data

    -
  • -
-
-
-

3.3   Common string and token constants

-
    -
  • alphas - same as string.letters

    -
  • -
  • nums - same as string.digits

    -
  • -
  • alphanums - a string containing alphas + nums

    -
  • -
  • alphas8bit - a string containing alphabetic 8-bit characters:

    -
    -ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ
    -
    -
  • -
  • printables - same as string.printable, minus the space (' ') character

    -
  • -
  • empty - a global Empty(); will always match

    -
  • -
  • sglQuotedString - a string of characters enclosed in 's; may -include whitespace, but not newlines

    -
  • -
  • dblQuotedString - a string of characters enclosed in "s; may -include whitespace, but not newlines

    -
  • -
  • quotedString - sglQuotedString | dblQuotedString

    -
  • -
  • cStyleComment - a comment block delimited by '/*' and '*/' sequences; can span -multiple lines, but does not support nesting of comments

    -
  • -
  • htmlComment - a comment block delimited by '<!--' and '-->' sequences; can span -multiple lines, but does not support nesting of comments

    -
  • -
  • commaSeparatedList - similar to delimitedList, except that the -list expressions can be any text value, or a quoted string; quoted strings can -safely include commas without incorrectly breaking the string into two tokens

    -
  • -
  • restOfLine - all remaining printable characters up to but not including the next -newline

    -
  • -
-
-
-
- - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index bbc959e..0000000 --- a/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -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. diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 5f2b98b..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include pyparsing.py -include HowToUsePyparsing.html pyparsingClassDiagram.* -include README CHANGES LICENSE -include examples/*.py examples/Setup.ini examples/*.dfm examples/*.ics examples/*.html -include htmldoc/*.* -include docs/*.* -include robots.txt diff --git a/PKG-INFO b/PKG-INFO index 437c191..2deb689 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,23 +1,27 @@ -Metadata-Version: 1.1 -Name: pyparsing -Version: 2.2.0 -Summary: Python parsing module -Home-page: http://pyparsing.wikispaces.com/ -Author: Paul McGuire -Author-email: ptmcg@users.sourceforge.net -License: MIT License -Download-URL: http://sourceforge.net/project/showfiles.php?group_id=97203 -Description: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Information Technology -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 +Metadata-Version: 1.2 +Name: pyparsing +Version: 2.2.1 +Summary: Python parsing module +Home-page: https://github.com/pyparsing/pyparsing/ +Author: Paul McGuire +Author-email: ptmcg@users.sourceforge.net +License: MIT License +Download-URL: https://pypi.org/project/pyparsing/ +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.* diff --git a/README b/README.md similarity index 81% rename from README rename to README.md index dc959ec..8921d62 100644 --- a/README +++ b/README.md @@ -1,9 +1,9 @@ -==================================== -PyParsing -- A Python Parsing Module -==================================== - -Introduction -============ +PyParsing -- A Python Parsing Module +==================================== +[![Build Status](https://travis-ci.org/pyparsing/pyparsing.svg?branch=master)](https://travis-ci.org/pyparsing/pyparsing) + +Introduction +============ The pyparsing module is an alternative approach to creating and executing simple grammars, vs. the traditional lex/yacc approach, or the use of @@ -11,12 +11,14 @@ regular expressions. The pyparsing module provides a library of classes that client code uses to construct the grammar directly in Python code. Here is a program to parse "Hello, World!" (or any greeting of the form -", !"): +"salutation, addressee!"): - from pyparsing import Word, alphas - greet = Word( alphas ) + "," + Word( alphas ) + "!" - hello = "Hello, World!" - print hello, "->", greet.parseString( hello ) +```python +from pyparsing import Word, alphas +greet = Word( alphas ) + "," + Word( alphas ) + "!" +hello = "Hello, World!" +print hello, "->", greet.parseString( hello ) +``` The program outputs the following: @@ -39,18 +41,18 @@ vexing when writing text parsers: The .zip file includes examples of a simple SQL parser, simple CORBA IDL parser, a config file parser, a chemical formula parser, and a four- function algebraic notation parser. It also includes a simple how-to -document, and a UML class diagram of the library's classes. - - - -Installation -============ - -Do the usual: - +document, and a UML class diagram of the library's classes. + + + +Installation +============ + +Do the usual: + python setup.py install -(pyparsing requires Python 2.6 or later.) +(pyparsing requires Python 2.6 or later.) Or corresponding commands using pip, easy_install, or wheel: @@ -59,22 +61,22 @@ Or corresponding commands using pip, easy_install, or wheel: easy_install pyparsing wheel install pyparsing - - -Documentation -============= - -See: - - HowToUsePyparsing.html - - -License -======= - - MIT License. See header of pyparsing.py - -History -======= - + + +Documentation +============= + +See: + + HowToUsePyparsing.html + + +License +======= + + MIT License. See header of pyparsing.py + +History +======= + See CHANGES file. diff --git a/docs/HowToUsePyparsing.html b/docs/HowToUsePyparsing.html deleted file mode 100644 index 1bd180b..0000000 --- a/docs/HowToUsePyparsing.html +++ /dev/null @@ -1,1289 +0,0 @@ - - - - - - -Using the pyparsing module - - - - - - -
-

Using the pyparsing module

- --- - - - - - - - - - - - -
Author:Paul McGuire
Address:
-ptmcg@users.sourceforge.net
-
-
Revision:2.0.1
Date:July, 2013
Copyright:Copyright © 2003-2013 Paul McGuire.
- --- - - - -
abstract:This document provides how-to instructions for the -pyparsing library, an easy-to-use Python module for constructing -and executing basic text parsers. The pyparsing module is useful -for evaluating user-definable -expressions, processing custom application language commands, or -extracting data from formatted reports.
- -
-

1   Steps to follow

-

To parse an incoming data string, the client code must follow these steps:

-
    -
  1. First define the tokens and patterns to be matched, and assign -this to a program variable. Optional results names or parsing -actions can also be defined at this time.
  2. -
  3. Call parseString() or scanString() on this variable, passing in -the string to -be parsed. During the matching process, whitespace between -tokens is skipped by default (although this can be changed). -When token matches occur, any defined parse action methods are -called.
  4. -
  5. Process the parsed results, returned as a list of strings. -Matching results may also be accessed as named attributes of -the returned results, if names are defined in the definition of -the token pattern, using setResultsName().
  6. -
-
-

1.1   Hello, World!

-

The following complete Python program will parse the greeting "Hello, World!", -or any other greeting of the form "<salutation>, <addressee>!":

-
-from pyparsing import Word, alphas
-
-greet = Word( alphas ) + "," + Word( alphas ) + "!"
-greeting = greet.parseString( "Hello, World!" )
-print greeting
-
-

The parsed tokens are returned in the following form:

-
-['Hello', ',', 'World', '!']
-
-
-
-

1.2   Usage notes

-
    -
  • The pyparsing module can be used to interpret simple command -strings or algebraic expressions, or can be used to extract data -from text reports with complicated format and structure ("screen -or report scraping"). However, it is possible that your defined -matching patterns may accept invalid inputs. Use pyparsing to -extract data from strings assumed to be well-formatted.

    -
  • -
  • To keep up the readability of your code, use operators such as +, |, -^, and ~ to combine expressions. You can also combine -string literals with ParseExpressions - they will be -automatically converted to Literal objects. For example:

    -
    -integer  = Word( nums )            # simple unsigned integer
    -variable = Word( alphas, max=1 )   # single letter variable, such as x, z, m, etc.
    -arithOp  = Word( "+-*/", max=1 )   # arithmetic operators
    -equation = variable + "=" + integer + arithOp + integer    # will match "x=2+2", etc.
    -
    -

    In the definition of equation, the string "=" will get added as -a Literal("="), but in a more readable way.

    -
  • -
  • The pyparsing module's default behavior is to ignore whitespace. This is the -case for 99% of all parsers ever written. This allows you to write simple, clean, -grammars, such as the above equation, without having to clutter it up with -extraneous ws markers. The equation grammar will successfully parse all of the -following statements:

    -
    -x=2+2
    -x = 2+2
    -a = 10   *   4
    -r= 1234/ 100000
    -
    -

    Of course, it is quite simple to extend this example to support more elaborate expressions, with -nesting with parentheses, floating point numbers, scientific notation, and named constants -(such as e or pi). See fourFn.py, included in the examples directory.

    -
  • -
  • To modify pyparsing's default whitespace skipping, you can use one or -more of the following methods:

    -
      -
    • use the static method ParserElement.setDefaultWhitespaceChars -to override the normal set of whitespace chars (' tn'). For instance -when defining a grammar in which newlines are significant, you should -call ParserElement.setDefaultWhitespaceChars(' \t') to remove -newline from the set of skippable whitespace characters. Calling -this method will affect all pyparsing expressions defined afterward.

      -
    • -
    • call leaveWhitespace() on individual expressions, to suppress the -skipping of whitespace before trying to match the expression

      -
    • -
    • use Combine to require that successive expressions must be -adjacent in the input string. For instance, this expression:

      -
      -real = Word(nums) + '.' + Word(nums)
      -
      -

      will match "3.14159", but will also match "3 . 12". It will also -return the matched results as ['3', '.', '14159']. By changing this -expression to:

      -
      -real = Combine( Word(nums) + '.' + Word(nums) )
      -
      -

      it will not match numbers with embedded spaces, and it will return a -single concatenated string '3.14159' as the parsed token.

      -
    • -
    -
  • -
  • Repetition of expressions can be indicated using the '*' operator. An -expression may be multiplied by an integer value (to indicate an exact -repetition count), or by a tuple containing -two integers, or None and an integer, representing min and max repetitions -(with None representing no min or no max, depending whether it is the first or -second tuple element). See the following examples, where n is used to -indicate an integer value:

    -
      -
    • expr*3 is equivalent to expr + expr + expr
    • -
    • expr*(2,3) is equivalent to expr + expr + Optional(expr)
    • -
    • expr*(n,None) or expr*(n,) is equivalent -to expr*n + ZeroOrMore(expr) (read as "at least n instances of expr")
    • -
    • expr*(None,n) is equivalent to expr*(0,n) -(read as "0 to n instances of expr")
    • -
    • expr*(None,None) is equivalent to ZeroOrMore(expr)
    • -
    • expr*(1,None) is equivalent to OneOrMore(expr)
    • -
    -

    Note that expr*(None,n) does not raise an exception if -more than n exprs exist in the input stream; that is, -expr*(None,n) does not enforce a maximum number of expr -occurrences. If this behavior is desired, then write -expr*(None,n) + ~expr.

    -
  • -
  • MatchFirst expressions are matched left-to-right, and the first -match found will skip all later expressions within, so be sure -to define less-specific patterns after more-specific patterns. -If you are not sure which expressions are most specific, use Or -expressions (defined using the ^ operator) - they will always -match the longest expression, although they are more -compute-intensive.

    -
  • -
  • Or expressions will evaluate all of the specified subexpressions -to determine which is the "best" match, that is, which matches -the longest string in the input data. In case of a tie, the -left-most expression in the Or list will win.

    -
  • -
  • If parsing the contents of an entire file, pass it to the -parseFile method using:

    -
    -expr.parseFile( sourceFile )
    -
    -
  • -
  • ParseExceptions will report the location where an expected token -or expression failed to match. For example, if we tried to use our -"Hello, World!" parser to parse "Hello World!" (leaving out the separating -comma), we would get an exception, with the message:

    -
    -pyparsing.ParseException: Expected "," (6), (1,7)
    -
    -

    In the case of complex -expressions, the reported location may not be exactly where you -would expect. See more information under ParseException .

    -
  • -
  • Use the Group class to enclose logical groups of tokens within a -sublist. This will help organize your results into more -hierarchical form (the default behavior is to return matching -tokens as a flat list of matching input strings).

    -
  • -
  • Punctuation may be significant for matching, but is rarely of -much interest in the parsed results. Use the suppress() method -to keep these tokens from cluttering up your returned lists of -tokens. For example, delimitedList() matches a succession of -one or more expressions, separated by delimiters (commas by -default), but only returns a list of the actual expressions - -the delimiters are used for parsing, but are suppressed from the -returned output.

    -
  • -
  • Parse actions can be used to convert values from strings to -other data types (ints, floats, booleans, etc.).

    -
  • -
  • Results names are recommended for retrieving tokens from complex -expressions. It is much easier to access a token using its field -name than using a positional index, especially if the expression -contains optional elements. You can also shortcut -the setResultsName call:

    -
    -stats = "AVE:" + realNum.setResultsName("average") + \
    -        "MIN:" + realNum.setResultsName("min") + \
    -        "MAX:" + realNum.setResultsName("max")
    -
    -

    can now be written as this:

    -
    -stats = "AVE:" + realNum("average") + \
    -        "MIN:" + realNum("min") + \
    -        "MAX:" + realNum("max")
    -
    -
  • -
  • Be careful when defining parse actions that modify global variables or -data structures (as in fourFn.py), especially for low level tokens -or expressions that may occur within an And expression; an early element -of an And may match, but the overall expression may fail.

    -
  • -
  • Performance of pyparsing may be slow for complex grammars and/or large -input strings. The psyco package can be used to improve the speed of the -pyparsing module with no changes to grammar or program logic - observed -improvments have been in the 20-50% range.

    -
  • -
-
-
-
-

2   Classes

-
-

2.1   Classes in the pyparsing module

-

ParserElement - abstract base class for all pyparsing classes; -methods for code to use are:

-
    -
  • parseString( sourceString, parseAll=False ) - only called once, on the overall -matching pattern; returns a ParseResults object that makes the -matched tokens available as a list, and optionally as a dictionary, -or as an object with named attributes; if parseAll is set to True, then -parseString will raise a ParseException if the grammar does not process -the complete input string.

    -
  • -
  • parseFile( sourceFile ) - a convenience function, that accepts an -input file object or filename. The file contents are passed as a -string to parseString(). parseFile also supports the parseAll argument.

    -
  • -
  • scanString( sourceString ) - generator function, used to find and -extract matching text in the given source string; for each matched text, -returns a tuple of:

    -
      -
    • matched tokens (packaged as a ParseResults object)
    • -
    • start location of the matched text in the given source string
    • -
    • end location in the given source string
    • -
    -

    scanString allows you to scan through the input source string for -random matches, instead of exhaustively defining the grammar for the entire -source text (as would be required with parseString).

    -
  • -
  • transformString( sourceString ) - convenience wrapper function for -scanString, to process the input source string, and replace matching -text with the tokens returned from parse actions defined in the grammar -(see setParseAction).

    -
  • -
  • searchString( sourceString ) - another convenience wrapper function for -scanString, returns a list of the matching tokens returned from each -call to scanString.

    -
  • -
  • setName( name ) - associate a short descriptive name for this -element, useful in displaying exceptions and trace information

    -
  • -
  • setResultsName( string, listAllMatches=False ) - name to be given -to tokens matching -the element; if multiple tokens within -a repetition group (such as ZeroOrMore or delimitedList) the -default is to return only the last matching token - if listAllMatches -is set to True, then a list of all the matching tokens is returned. -(New in 1.5.6 - a results name with a trailing '*' character will be -interpreted as setting listAllMatches to True.) -Note: -setResultsName returns a copy of the element so that a single -basic element can be referenced multiple times and given -different names within a complex grammar.

    -
  • -
-
    -
  • setParseAction( *fn ) - specify one or more functions to call after successful -matching of the element; each function is defined as fn( s, -loc, toks ), where:

    -
      -
    • s is the original parse string
    • -
    • loc is the location in the string where matching started
    • -
    • toks is the list of the matched tokens, packaged as a ParseResults object
    • -
    -

    Multiple functions can be attached to a ParserElement by specifying multiple -arguments to setParseAction, or by calling setParseAction multiple times.

    -

    Each parse action function can return a modified toks list, to perform conversion, or -string modifications. For brevity, fn may also be a -lambda - here is an example of using a parse action to convert matched -integer tokens from strings to integers:

    -
    -intNumber = Word(nums).setParseAction( lambda s,l,t: [ int(t[0]) ] )
    -
    -

    If fn does not modify the toks list, it does not need to return -anything at all.

    -
  • -
  • setBreak( breakFlag=True ) - if breakFlag is True, calls pdb.set_break() -as this expression is about to be parsed

    -
  • -
  • copy() - returns a copy of a ParserElement; can be used to use the same -parse expression in different places in a grammar, with different parse actions -attached to each

    -
  • -
  • leaveWhitespace() - change default behavior of skipping -whitespace before starting matching (mostly used internally to the -pyparsing module, rarely used by client code)

    -
  • -
  • setWhitespaceChars( chars ) - define the set of chars to be ignored -as whitespace before trying to match a specific ParserElement, in place of the -default set of whitespace (space, tab, newline, and return)

    -
  • -
  • setDefaultWhitespaceChars( chars ) - class-level method to override -the default set of whitespace chars for all subsequently created ParserElements -(including copies); useful when defining grammars that treat one or more of the -default whitespace characters as significant (such as a line-sensitive grammar, to -omit newline from the list of ignorable whitespace)

    -
  • -
  • suppress() - convenience function to suppress the output of the -given element, instead of wrapping it with a Suppress object.

    -
  • -
  • ignore( expr ) - function to specify parse expression to be -ignored while matching defined patterns; can be called -repeatedly to specify multiple expressions; useful to specify -patterns of comment syntax, for example

    -
  • -
  • setDebug( dbgFlag=True ) - function to enable/disable tracing output -when trying to match this element

    -
  • -
  • validate() - function to verify that the defined grammar does not -contain infinitely recursive constructs

    -
  • -
-
    -
  • parseWithTabs() - function to override default behavior of converting -tabs to spaces before parsing the input string; rarely used, except when -specifying whitespace-significant grammars using the White class.
  • -
  • enablePackrat() - a class-level static method to enable a memoizing -performance enhancement, known as "packrat parsing". packrat parsing is -disabled by default, since it may conflict with some user programs that use -parse actions. To activate the packrat feature, your -program must call the class method ParserElement.enablePackrat(). If -your program uses psyco to "compile as you go", you must call -enablePackrat before calling psyco.full(). If you do not do this, -Python will crash. For best results, call enablePackrat() immediately -after importing pyparsing.
  • -
-
-
-

2.2   Basic ParserElement subclasses

-
    -
  • Literal - construct with a string to be matched exactly
  • -
  • CaselessLiteral - construct with a string to be matched, but -without case checking; results are always returned as the -defining literal, NOT as they are found in the input string
  • -
  • Keyword - similar to Literal, but must be immediately followed by -whitespace, punctuation, or other non-keyword characters; prevents -accidental matching of a non-keyword that happens to begin with a -defined keyword
  • -
  • CaselessKeyword - similar to Keyword, but with caseless matching -behavior
  • -
-
    -
  • Word - one or more contiguous characters; construct with a -string containing the set of allowed initial characters, and an -optional second string of allowed body characters; for instance, -a common Word construct is to match a code identifier - in C, a -valid identifier must start with an alphabetic character or an -underscore ('_'), followed by a body that can also include numeric -digits. That is, a, i, MAX_LENGTH, _a1, b_109_, and -plan9FromOuterSpace -are all valid identifiers; 9b7z, $a, .section, and 0debug -are not. To -define an identifier using a Word, use either of the following:

    -
    -- Word( alphas+"_", alphanums+"_" )
    -- Word( srange("[a-zA-Z_]"), srange("[a-zA-Z0-9_]") )
    -
    -

    If only one -string given, it specifies that the same character set defined -for the initial character is used for the word body; for instance, to -define an identifier that can only be composed of capital letters and -underscores, use:

    -
    -- Word( "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" )
    -- Word( srange("[A-Z_]") )
    -
    -

    A Word may -also be constructed with any of the following optional parameters:

    -
      -
    • min - indicating a minimum length of matching characters
    • -
    • max - indicating a maximum length of matching characters
    • -
    • exact - indicating an exact length of matching characters
    • -
    -

    If exact is specified, it will override any values for min or max.

    -

    New in 1.5.6 - Sometimes you want to define a word using all -characters in a range except for one or two of them; you can do this -with the new excludeChars argument. This is helpful if you want to define -a word with all printables except for a single delimiter character, such -as '.'. Previously, you would have to create a custom string to pass to Word. -With this change, you can just create Word(printables, excludeChars='.').

    -
  • -
  • CharsNotIn - similar to Word, but matches characters not -in the given constructor string (accepts only one string for both -initial and body characters); also supports min, max, and exact -optional parameters.

    -
  • -
  • Regex - a powerful construct, that accepts a regular expression -to be matched at the current parse position; accepts an optional -flags parameter, corresponding to the flags parameter in the re.compile -method; if the expression includes named sub-fields, they will be -represented in the returned ParseResults

    -
  • -
  • QuotedString - supports the definition of custom quoted string -formats, in addition to pyparsing's built-in dblQuotedString and -sglQuotedString. QuotedString allows you to specify the following -parameters:

    -
      -
    • quoteChar - string of one or more characters defining the quote delimiting string
    • -
    • escChar - character to escape quotes, typically backslash (default=None)
    • -
    • escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
    • -
    • multiline - boolean indicating whether quotes can span multiple lines (default=False)
    • -
    • unquoteResults - boolean indicating whether the matched text should be unquoted (default=True)
    • -
    • endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar)
    • -
    -
  • -
  • SkipTo - skips ahead in the input string, accepting any -characters up to the specified pattern; may be constructed with -the following optional parameters:

    -
      -
    • include - if set to true, also consumes the match expression -(default is False)
    • -
    • ignore - allows the user to specify patterns to not be matched, -to prevent false matches
    • -
    • failOn - if a literal string or expression is given for this argument, it defines an expression that -should cause the SkipTo expression to fail, and not skip over that expression
    • -
    -
  • -
-
    -
  • White - also similar to Word, but matches whitespace -characters. Not usually needed, as whitespace is implicitly -ignored by pyparsing. However, some grammars are whitespace-sensitive, -such as those that use leading tabs or spaces to indicating grouping -or hierarchy. (If matching on tab characters, be sure to call -parseWithTabs on the top-level parse element.)
  • -
  • Empty - a null expression, requiring no characters - will always -match; useful for debugging and for specialized grammars
  • -
  • NoMatch - opposite of Empty, will never match; useful for debugging -and for specialized grammars
  • -
-
-
-

2.3   Expression subclasses

-
    -
  • And - construct with a list of ParserElements, all of which must -match for And to match; can also be created using the '+' -operator; multiple expressions can be Anded together using the '*' -operator as in:

    -
    -ipAddress = Word(nums) + ('.'+Word(nums))*3
    -
    -

    A tuple can be used as the multiplier, indicating a min/max:

    -
    -usPhoneNumber = Word(nums) + ('-'+Word(nums))*(1,2)
    -
    -

    A special form of And is created if the '-' operator is used -instead of the '+' operator. In the ipAddress example above, if -no trailing '.' and Word(nums) are found after matching the initial -Word(nums), then pyparsing will back up in the grammar and try other -alternatives to ipAddress. However, if ipAddress is defined as:

    -
    -strictIpAddress = Word(nums) - ('.'+Word(nums))*3
    -
    -

    then no backing up is done. If the first Word(nums) of strictIpAddress -is matched, then any mismatch after that will raise a ParseSyntaxException, -which will halt the parsing process immediately. By careful use of the -'-' operator, grammars can provide meaningful error messages close to -the location where the incoming text does not match the specified -grammar.

    -
  • -
  • Or - construct with a list of ParserElements, any of which must -match for Or to match; if more than one expression matches, the -expression that makes the longest match will be used; can also -be created using the '^' operator

    -
  • -
  • MatchFirst - construct with a list of ParserElements, any of -which must match for MatchFirst to match; matching is done -left-to-right, taking the first expression that matches; can -also be created using the '|' operator

    -
  • -
  • Each - similar to And, in that all of the provided expressions -must match; however, Each permits matching to be done in any order; -can also be created using the '&' operator

    -
  • -
  • Optional - construct with a ParserElement, but this element is -not required to match; can be constructed with an optional default argument, -containing a default string or object to be supplied if the given optional -parse element is not found in the input string; parse action will only -be called if a match is found, or if a default is specified

    -
  • -
  • ZeroOrMore - similar to Optional, but can be repeated

    -
  • -
  • OneOrMore - similar to ZeroOrMore, but at least one match must -be present

    -
  • -
  • FollowedBy - a lookahead expression, requires matching of the given -expressions, but does not advance the parsing position within the input string

    -
  • -
  • NotAny - a negative lookahead expression, prevents matching of named -expressions, does not advance the parsing position within the input string; -can also be created using the unary '~' operator

    -
  • -
-
-
-

2.4   Expression operators

-
    -
  • ~ - creates NotAny using the expression after the operator
  • -
  • + - creates And using the expressions before and after the operator
  • -
  • | - creates MatchFirst (first left-to-right match) using the expressions before and after the operator
  • -
  • ^ - creates Or (longest match) using the expressions before and after the operator
  • -
  • & - creates Each using the expressions before and after the operator
  • -
  • * - creates And by multiplying the expression by the integer operand; if -expression is multiplied by a 2-tuple, creates an And of (min,max) -expressions (similar to "{min,max}" form in regular expressions); if -min is None, intepret as (0,max); if max is None, interpret as -expr*min + ZeroOrMore(expr)
  • -
  • - - like + but with no backup and retry of alternatives
  • -
  • * - repetition of expression
  • -
  • == - matching expression to string; returns True if the string matches the given expression
  • -
  • <<= - inserts the expression following the operator as the body of the -Forward expression before the operator (formerly <<, which is now deprecated)
  • -
-
-
-

2.5   Positional subclasses

-
    -
  • StringStart - matches beginning of the text
  • -
  • StringEnd - matches the end of the text
  • -
  • LineStart - matches beginning of a line (lines delimited by \n characters)
  • -
  • LineEnd - matches the end of a line
  • -
  • WordStart - matches a leading word boundary
  • -
  • WordEnd - matches a trailing word boundary
  • -
-
-
-

2.6   Converter subclasses

-
    -
  • Upcase - converts matched tokens to uppercase (deprecated - -use upcaseTokens parse action instead)
  • -
  • Combine - joins all matched tokens into a single string, using -specified joinString (default joinString=""); expects -all matching tokens to be adjacent, with no intervening -whitespace (can be overridden by specifying adjacent=False in constructor)
  • -
  • Suppress - clears matched tokens; useful to keep returned -results from being cluttered with required but uninteresting -tokens (such as list delimiters)
  • -
-
-
-

2.7   Special subclasses

-
    -
  • Group - causes the matched tokens to be enclosed in a list; -useful in repeated elements like ZeroOrMore and OneOrMore to -break up matched tokens into groups for each repeated pattern
  • -
  • Dict - like Group, but also constructs a dictionary, using the -[0]'th elements of all enclosed token lists as the keys, and -each token list as the value
  • -
  • SkipTo - catch-all matching expression that accepts all characters -up until the given pattern is found to match; useful for specifying -incomplete grammars
  • -
  • Forward - placeholder token used to define recursive token -patterns; when defining the actual expression later in the -program, insert it into the Forward object using the <<= -operator (see fourFn.py for an example).
  • -
-
-
-

2.8   Other classes

-
    -
  • ParseResults - class used to contain and manage the lists of tokens -created from parsing the input using the user-defined parse -expression. ParseResults can be accessed in a number of ways:

    -
      -
    • as a list
        -
      • total list of elements can be found using len()
      • -
      • individual elements can be found using [0], [1], [-1], etc.
      • -
      • elements can be deleted using del
      • -
      • the -1th element can be extracted and removed in a single operation -using pop(), or any element can be extracted and removed -using pop(n)
      • -
      -
    • -
    • as a dictionary
        -
      • if setResultsName() is used to name elements within the -overall parse expression, then these fields can be referenced -as dictionary elements or as attributes
      • -
      • the Dict class generates dictionary entries using the data of the -input text - in addition to ParseResults listed as [ [ a1, b1, c1, ...], [ a2, b2, c2, ...]  ] -it also acts as a dictionary with entries defined as { a1 : [ b1, c1, ... ] }, { a2 : [ b2, c2, ... ] }; -this is especially useful when processing tabular data where the first column contains a key -value for that line of data
      • -
      • list elements that are deleted using del will still be accessible by their -dictionary keys
      • -
      • supports get(), items() and keys() methods, similar to a dictionary
      • -
      • a keyed item can be extracted and removed using pop(key). Here -key must be non-numeric (such as a string), in order to use dict -extraction instead of list extraction.
      • -
      • new named elements can be added (in a parse action, for instance), using the same -syntax as adding an item to a dict (parseResults["X"]="new item"); named elements can be removed using del parseResults["X"]
      • -
      -
    • -
    • as a nested list
        -
      • results returned from the Group class are encapsulated within their -own list structure, so that the tokens can be handled as a hierarchical -tree
      • -
      -
    • -
    -

    ParseResults can also be converted to an ordinary list of strings -by calling asList(). Note that this will strip the results of any -field names that have been defined for any embedded parse elements. -(The pprint module is especially good at printing out the nested contents -given by asList().)

    -

    Finally, ParseResults can be converted to an XML string by calling asXML(). Where -possible, results will be tagged using the results names defined for the respective -ParseExpressions. asXML() takes two optional arguments:

    -
      -
    • doctagname - for ParseResults that do not have a defined name, this argument -will wrap the resulting XML in a set of opening and closing tags <doctagname> -and </doctagname>.
    • -
    • namedItemsOnly (default=False) - flag to indicate if the generated XML should -skip items that do not have defined names. If a nested group item is named, then all -embedded items will be included, whether they have names or not.
    • -
    -
  • -
-
-
-

2.9   Exception classes and Troubleshooting

-
    -
  • ParseException - exception returned when a grammar parse fails; -ParseExceptions have attributes loc, msg, line, lineno, and column; to view the -text line and location where the reported ParseException occurs, use:

    -
    -except ParseException, err:
    -    print err.line
    -    print " "*(err.column-1) + "^"
    -    print err
    -
    -
  • -
  • RecursiveGrammarException - exception returned by validate() if -the grammar contains a recursive infinite loop, such as:

    -
    -badGrammar = Forward()
    -goodToken = Literal("A")
    -badGrammar <<= Optional(goodToken) + badGrammar
    -
    -
  • -
  • ParseFatalException - exception that parse actions can raise to stop parsing -immediately. Should be used when a semantic error is found in the input text, such -as a mismatched XML tag.

    -
  • -
  • ParseSyntaxException - subclass of ParseFatalException raised when a -syntax error is found, based on the use of the '-' operator when defining -a sequence of expressions in an And expression.

    -
  • -
-

You can also get some insights into the parsing logic using diagnostic parse actions, -and setDebug(), or test the matching of expression fragments by testing them using -scanString().

-
-
-
-

3   Miscellaneous attributes and methods

-
-

3.1   Helper methods

-
    -
  • delimitedList( expr, delim=',') - convenience function for -matching one or more occurrences of expr, separated by delim. -By default, the delimiters are suppressed, so the returned results contain -only the separate list elements. Can optionally specify combine=True, -indicating that the expressions and delimiters should be returned as one -combined value (useful for scoped variables, such as "a.b.c", or -"a::b::c", or paths such as "a/b/c").

    -
  • -
  • countedArray( expr ) - convenience function for a pattern where an list of -instances of the given expression are preceded by an integer giving the count of -elements in the list. Returns an expression that parses the leading integer, -reads exactly that many expressions, and returns the array of expressions in the -parse results - the leading integer is suppressed from the results (although it -is easily reconstructed by using len on the returned array).

    -
  • -
  • oneOf( string, caseless=False ) - convenience function for quickly declaring an -alternative set of Literal tokens, by splitting the given string on -whitespace boundaries. The tokens are sorted so that longer -matches are attempted first; this ensures that a short token does -not mask a longer one that starts with the same characters. If caseless=True, -will create an alternative set of CaselessLiteral tokens.

    -
  • -
  • dictOf( key, value ) - convenience function for quickly declaring a -dictionary pattern of Dict( ZeroOrMore( Group( key + value ) ) ).

    -
  • -
  • makeHTMLTags( tagName ) and makeXMLTags( tagName ) - convenience -functions to create definitions of opening and closing tag expressions. Returns -a pair of expressions, for the corresponding <tag> and </tag> strings. Includes -support for attributes in the opening tag, such as <tag attr1="abc"> - attributes -are returned as keyed tokens in the returned ParseResults. makeHTMLTags is less -restrictive than makeXMLTags, especially with respect to case sensitivity.

    -
  • -
  • infixNotation(baseOperand, operatorList) - (formerly named operatorPrecedence) convenience function to define a -grammar for parsing infix notation -expressions with a hierarchical precedence of operators. To use the infixNotation -helper:

    -
      -
    1. Define the base "atom" operand term of the grammar. -For this simple grammar, the smallest operand is either -and integer or a variable. This will be the first argument -to the infixNotation method.
    2. -
    3. Define a list of tuples for each level of operator -precendence. 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 -None, indicates an empty operator, such as the implied -multiplication operation between 'm' and 'x' in "y = mx + b". -If numTerms parameter is 3, this must be a 2-tuple containing the 2 delimiting operators.
      • -
      • 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 opAssoc.RIGHT and opAssoc.LEFT.
      • -
      • parseAction is the parse action to be associated with -expressions matching this operator expression (the -parse action tuple member may be omitted)
      • -
      -
    4. -
    5. Call infixNotation passing the operand expression and -the operator precedence list, and save the returned value -as the generated pyparsing expression. You can then use -this expression to parse input strings, or incorporate it -into a larger, more complex grammar.
    6. -
    -
  • -
  • matchPreviousLiteral and matchPreviousExpr - function to define and -expression that matches the same content -as was parsed in a previous parse expression. For instance:

    -
    -first = Word(nums)
    -matchExpr = first + ":" + matchPreviousLiteral(first)
    -
    -

    will match "1:1", but not "1:2". Since this matches at the literal -level, this will also match the leading "1:1" in "1:10".

    -

    In contrast:

    -
    -first = Word(nums)
    -matchExpr = first + ":" + matchPreviousExpr(first)
    -
    -

    will not match the leading "1:1" in "1:10"; the expressions are -evaluated first, and then compared, so "1" is compared with "10".

    -
  • -
  • nestedExpr(opener, closer, content=None, ignoreExpr=quotedString) - method for defining nested -lists enclosed in opening and closing delimiters.

    -
      -
    • opener - opening character for a nested list (default="("); can also be a pyparsing expression
    • -
    • closer - closing character for a nested list (default=")"); can also be a pyparsing expression
    • -
    • content - expression for items within the nested lists (default=None)
    • -
    • ignoreExpr - expression for ignoring opening and closing delimiters (default=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 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 Or or MatchFirst. -The default is quotedString, but if no expressions are to be ignored, -then pass None for this argument.

    -
  • -
  • indentedBlock( statementExpr, indentationStackVar, indent=True) - -function to define an indented block of statements, similar to -indentation-based blocking in Python source code:

    -
      -
    • statementExpr - the expression defining a statement that -will be found in the indented block; a valid indentedBlock -must contain at least 1 matching statementExpr
    • -
    • indentationStackVar - a Python list variable; this variable -should be common to all indentedBlock expressions defined -within the same grammar, and should be reinitialized to [1] -each time the grammar is to be used
    • -
    • indent - a boolean flag indicating whether the expressions -within the block must be indented from the current parse -location; if using indentedBlock to define the left-most -statements (all starting in column 1), set indent to False
    • -
    -
  • -
-
    -
  • originalTextFor( expr ) - helper function to preserve the originally parsed text, regardless of any -token processing or conversion done by the contained expression. For instance, the following expression:

    -
    -fullName = Word(alphas) + Word(alphas)
    -
    -

    will return the parse of "John Smith" as ['John', 'Smith']. In some applications, the actual name as it -was given in the input string is what is desired. To do this, use originalTextFor:

    -
    -fullName = originalTextFor(Word(alphas) + Word(alphas))
    -
    -
  • -
  • ungroup( expr ) - function to "ungroup" returned tokens; useful -to undo the default behavior of And to always group the returned tokens, even -if there is only one in the list. (New in 1.5.6)

    -
  • -
  • lineno( loc, string ) - function to give the line number of the -location within the string; the first line is line 1, newlines -start new rows

    -
  • -
  • col( loc, string ) - function to give the column number of the -location within the string; the first column is column 1, -newlines reset the column number to 1

    -
  • -
  • line( loc, string ) - function to retrieve the line of text -representing lineno( loc, string ); useful when printing out diagnostic -messages for exceptions

    -
  • -
  • srange( rangeSpec ) - function to define a string of characters, -given a string of the form used by regexp string ranges, such as "[0-9]" for -all numeric digits, "[A-Z_]" for uppercase characters plus underscore, and -so on (note that rangeSpec does not include support for generic regular -expressions, just string range specs)

    -
  • -
  • getTokensEndLoc() - function to call from within a parse action to get -the ending location for the matched tokens

    -
  • -
  • traceParseAction(fn) - decorator function to debug parse actions. Lists -each call, called arguments, and return value or exception

    -
  • -
-
-
-

3.2   Helper parse actions

-
    -
  • removeQuotes - removes the first and last characters of a quoted string; -useful to remove the delimiting quotes from quoted strings

    -
  • -
  • replaceWith(replString) - returns a parse action that simply returns the -replString; useful when using transformString, or converting HTML entities, as in:

    -
    -nbsp = Literal("&nbsp;").setParseAction( replaceWith("<BLANK>") )
    -
    -
  • -
  • keepOriginalText- (deprecated, use originalTextFor instead) restores any internal whitespace or suppressed -text within the tokens for a matched parse -expression. This is especially useful when defining expressions -for scanString or transformString applications.

    -
  • -
  • withAttribute( *args, **kwargs ) - helper to create a validating parse action to be used with start tags created -with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag -with a required attribute value, to avoid false matches on common tags such as -<TD> or <DIV>.

    -

    withAttribute can be called with:

    -
      -
    • keyword arguments, as in (class="Customer",align="right"), or
    • -
    • a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
    • -
    -

    An attribute can be specified to have the special value -withAttribute.ANY_VALUE, which will match any value - use this to -ensure that an attribute is present but any attribute value is -acceptable.

    -
  • -
  • downcaseTokens - converts all matched tokens to lowercase

    -
  • -
  • upcaseTokens - converts all matched tokens to uppercase

    -
  • -
  • matchOnlyAtCol( columnNumber ) - a parse action that verifies that -an expression was matched at a particular column, raising a -ParseException if matching at a different column number; useful when parsing -tabular data

    -
  • -
-
-
-

3.3   Common string and token constants

-
    -
  • alphas - same as string.letters

    -
  • -
  • nums - same as string.digits

    -
  • -
  • alphanums - a string containing alphas + nums

    -
  • -
  • alphas8bit - a string containing alphabetic 8-bit characters:

    -
    -ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ
    -
    -
  • -
  • printables - same as string.printable, minus the space (' ') character

    -
  • -
  • empty - a global Empty(); will always match

    -
  • -
  • sglQuotedString - a string of characters enclosed in 's; may -include whitespace, but not newlines

    -
  • -
  • dblQuotedString - a string of characters enclosed in "s; may -include whitespace, but not newlines

    -
  • -
  • quotedString - sglQuotedString | dblQuotedString

    -
  • -
  • cStyleComment - a comment block delimited by '/*' and '*/' sequences; can span -multiple lines, but does not support nesting of comments

    -
  • -
  • htmlComment - a comment block delimited by '<!--' and '-->' sequences; can span -multiple lines, but does not support nesting of comments

    -
  • -
  • commaSeparatedList - similar to delimitedList, except that the -list expressions can be any text value, or a quoted string; quoted strings can -safely include commas without incorrectly breaking the string into two tokens

    -
  • -
  • restOfLine - all remaining printable characters up to but not including the next -newline

    -
  • -
-
-
-
- - diff --git a/docs/pycon06-AdventureEngineUsingPyparsing-notes.pdf b/docs/pycon06-AdventureEngineUsingPyparsing-notes.pdf deleted file mode 100644 index 6e5753afc1e2e541fb1ed91e2856e244c13c6384..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48227 zcma&sQ;;TIo2cPJmu=g&ZQHhObfL?(ZQFL2ZTl_TuG-%}d(WJF2YZfk#fo*58JTg# zoe!C!s5l)HJqtA1=w)0XG#eo!p@XqCG%qiMteL%qt0f`(KRe0{;#Rh$4yI=O{Ln70&Spk-(4N`L+I9{&9LOV2MSfs?sB2ehHi=!6N9bXDiR^IBJ?K`2 z&-|nwg4W}WpjIVg>MEdLcN{FFX-(*Mldbf(Z1vm+_eU8VGndi)&{~vqq~9=q@0?v9 zJCPn9kl>r%g z*lgOsdnd$Q6sp-RJ3q=~=L_neiOnXsQZyW%IQ3XGW6*=hT|d%Z1DLXu-;ThGyZgmb znj>9CSAGJcV57}X;Df)SMO8`{l7H1+|K5I8$f_dGe(qL{dd3NirHAITTCWPX2US%8w= zRQ6EhwQ>Mv6;hCM)Ak6Jtvs|Ak7YVcXlN4;<;Bn-b5J@ObdXXeJ97+ zJ@d)ldxv^ij@UzMuxcOg!y+q~S|C=dFw-Y~>V5{!5NG#Fy2_{POUk?N_hNguni2N4 zBZ)R&_SbK|uxaP8@SLpw))skhHiTQvc}DJiIi7&;x$)9{(Ajw1Ai;&*^UxI!-NbpV zd0u6NcG`3sSOL%cm4x#?YzMM)($CTF;6Qj0vWWv0jSw!pQwZwm;#Z%xYdwL%8Rjjkq-os{+p$Ec zQvh|u0zM?|iM{a0wVXjVFKH7e0Z35;%xY+A+pvPMB#(X9vHC|KPbH{iAwRfsz22K9 z0djF99n#j3a)yzb68FX$?^cZ%fr%~0ML$x~XGW%=3?>kpm++*zte~+!(eD>%N@S0> zSmQQNwO{vdkJvS@9 z2M>oZ&m5iuzM!5295aQtTE*t?W?X1ZcIHGc-L)(8kr}4+iKg1jddiV;9DW4JpMB86 zc^ot*`{Z_7WeMGE13MkmQdN2UMd}1Lk!>F44GO(?^fHk?Ej--3*RLZT&hg@nP#zKS zQ`tL52)$_peNEpCV_o_KR&w=*6UcJMYbW{?cC^}CilWNM&K(oWbed=8ZAn3V$=iYQ z+iON*C(=>%)wLBTuk@KMsmr16A6C-JzPqTEY}88oesV50^Aj`Dn&u5eT>{E^<)_@!Ut2de#;D!y;t=6e#eELbm;+8@6ZFM0JW6 z^w+L2!C%);S2U~(;)8@X2>JCveKIS$si+!)`HFq1l>;0a6sY|~qX;(#@#9%EEiw%0 z{fF+J#Nw$Y{N!7n`c5L7_ju{g3uzqbzR?Esvqqk=6%SB8g|?6h_HJy8ZP&xKgOV5| zIummBqj$C@J@;}p)JaQ6#=jzL=$gN}eAX8x+nB|UO73j%xigmgAsWIu;#l`Xr){XP z!d@L%;`CM4)m2NugQXY7%-Ol$pfRf}TaiX2p{6uqm}B)lvD4^2aV24e+)P>3&-hz2u>s!4=HpMf9;EDF0X1@(KdxCJ+)ae%ls0x&f%h!~%U zcq8F%s$)A#@IHWnw+uWJa1m-zdM;V$1!|FY01de%e-?ZD`S=Xs`CWKOH3T%{nKPM zRPxA96L}!r{_6E;fEe9LZf0-#|A6(+>OUy^55@j-WoF@Gg8qMdOkDpG8#CkohHO_j zHV%g)NMDr(4JQYL%uH7F9X?>E5GV6p=xO@SPDa0aQS0Tj+~rFFVYQ6$1iKmQ6csI` zGM�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 diff --git a/docs/pycon06-IntroToPyparsing-notes.pdf b/docs/pycon06-IntroToPyparsing-notes.pdf deleted file mode 100644 index c9db90ed11877961b33102a55f7d31d01166b1f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82733 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

pyparsing Examples

-

-This directory contains a number of Python scripts that can get you started in learning to use pyparsing. - -

    -
  • greeting.py
    -Parse "Hello, World!". -
  • -

    - -

  • greetingInKorean.py ~ submission by June Kim
    -Unicode example to parse "Hello, World!" in Korean. -
  • -

    - -

  • greetingInGreek.py ~ submission by ???
    -Unicode example to parse "Hello, World!" in Greek. -
  • -

    - -

  • holaMundo.py ~ submission by Marco Alfonso
    -"Hello, World!" example translated to Spanish, from Marco Alfonso's blog. -
  • -

    - -

  • chemicalFormulas.py
    -Simple example to demonstrate the use of ParseResults returned from parseString(). -Parses a chemical formula (such as "H2O" or "C6H5OH"), and walks the returned list of tokens to calculate the molecular weight. -
  • -

    - -

  • wordsToNum.py
    -A sample program that reads a number in words (such as "fifteen hundred and sixty four"), and returns the actual number (1564). -Also demonstrates some processing of ParseExceptions, including marking where the parse failure was found. -
  • -

    - -

  • pythonGrammarparser.py ~ suggested by JH Stovall
    -A sample program that parses the EBNF used in the Python source code to define the Python grammar. From this parser, -one can generate Python grammar documentation tools, such as railroad track diagrams. Also demonstrates use of -Dict class. -
  • -

    - -

  • commasep.py
    -Demonstration of the use of the commaSeparatedList helper. Shows examples of -proper handling of commas within quotes, trimming of whitespace around delimited entries, and handling of consecutive commas (null arguments). Includes comparison with simple string.split(','). -
  • -

    - -

  • dictExample.py
    -A demonstration of using the Dict class, to parse a table of ASCII tabulated data. -
  • -

    - -

  • dictExample2.py ~ submission by Mike Kelly
    -An extended version of dictExample.py, in which Mike Kelly also parses the column headers, and generates a transposed version of the original table! -
  • -

    - -

  • scanExamples.py
    -Some examples of using scanString and transformString, as alternative parsing methods to parseString, to do macro substitution, and selection and/or removal of matching strings within a source file. -
  • -

    - -

  • urlExtractor.py
    -Another example using scanString, this time to extract all HREF references found on Yahoo!'s home page, and return them as a dictionary. -
  • -

    - -

  • makeHTMLTagExample.py
    -A sample program showing sample definitions and applications of HTML tag expressions -created using makeHTMLTags helper function. Very useful for scraping data from HTML pages. -
  • -

    - -

  • urlExtractorNew.py
    -Another updated version of urlExtractor.py, using the new makeHTMLTags() method. -
  • -

    - -

  • fourFn.py
    -A simple algebraic expression parser, that performs +,-,*,/, and ^ arithmetic operations. (With suggestions and bug-fixes graciously offered by Andrea Griffini.) -
  • -

    - -

  • SimpleCalc.py ~ submission by Steven Siew
    -An interactive version of fourFn.py, with support for variables. -
  • -

    - -

  • LAParser.py ~ submission by Mike Ellis
    -An interactive Linear Algebra Parser, an extension of SimpleCalc.py. Supports linear algebra (LA) notation for vectors, matrices, and scalars, -including matrix operations such as inversion and determinants. Converts LA expressions to C code - uses a separate C library for runtime -evaluation of results. -
  • -

    - -

  • configParse.py
    -A simple alternative to Python's ConfigParse module, demonstrating the use of the Dict class to return nested dictionary access to configuration values. -
  • -

    - -

  • getNTPservers.py
    -Yet another scanString example, to read/extract the list of NTP servers from NIST's web site. -
  • -

    - -

  • getNTPserversNew.py
    -An updated version of getNTPservers.py, using the new makeHTMLTags() method. -
  • -

    - -

  • httpServerLogParser.py
    -Parser for Apache server log files. -
  • -

    - -

  • idlParse.py
    -Parser for CORBA IDL files. -
  • -

    - -

  • mozillaCalendarParser.py -~ submission by Petri Savolainen
    -Parser for Mozilla calendar (*.ics) files. -
  • -

    - -

  • pgn.py ~ submission by Alberto Santini
    -Parser for PGN (Portable Game Notation) files, the standard form for documenting the moves in chess games. -
  • -

    - -

  • simpleSQL.py
    -A simple parser that will extract table and column names from SQL SELECT statements.. -
  • -

    - -

  • dfmparse.py ~ submission by Dan Griffith
    -Parser for Delphi forms. -
  • -

    - -

  • ebnf.py / ebnftest.py ~ submission by Seo Sanghyeon
    -An EBNF-compiler that reads EBNF and generates a pyparsing grammar! Including a test that compiles... EBNF itself! -
  • -

    - -

  • searchparser.py ~ submission by Steven Mooij and Rudolph Froger
    -An expression parser that parses search strings, with special keyword and expression operations using (), not, and, or, and quoted strings. -
  • -

    - -

  • sparser.py ~ submission by Tim Cera
    -A configurable parser module that can be configured with a list of tuples, giving a high-level definition for parsing common sets -of water table data files. Tim had to contend with several different styles of data file formats, each with slight variations of its own. -Tim created a configurable parser (or "SPECIFIED parser" - hence the name "sparser"), that simply works from a config variable listing -the field names and data types, and implicitly, their order in the source data file. -

    -See mayport_florida_8720220_data_def.txt for an -example configuration file. -

  • -

    - -

  • romanNumerals.py
    -A Roman numeral generator and parser example, showing the power of parse actions -to compile Roman numerals into their integer values. -
  • -

    - -

  • removeLineBreaks.py
    -A string transformer that converts text files with hard line-breaks into one with line breaks -only between paragraphs. Useful when converting downloads from -Project Gutenberg to import to word processing apps -that can reformat paragraphs once hard line-breaks are removed, or for loading into your Palm Pilot for portable perusal. -

    -See Successful Methods of Public Speaking.txt and -Successful Methods of Public Speaking(2).txt for a sample -before and after (text file courtesy of Project Gutenberg). -

  • -

    - -

  • listAllMatches.py
    -An example program showing the utility of the listAllMatches option when specifying results naming. -
  • -

    - -

  • linenoExample.py
    -An example program showing how to use the string location to extract line and column numbers, or the -source line of text. -
  • -

    - -

  • parseListString.py
    -An example program showing a progression of steps, how to parse a string representation of a Python -list back into a true list. -
  • -

    - -

  • parsePythonValue.py
    -An extension of parseListString.py to parse tuples and dicts, including nested values, -returning a Python value of the original type. -
  • -

    - -

  • indentedGrammarExample.py
    -An example program showing how to parse a grammar using indentation for grouping, -such as is done in Python. -
  • -

    - -

  • simpleArith.py
    -An example program showing how to use the new operatorPrecedence helper method to define a 6-function -(+, -, *, /, ^, and !) arithmetic expression parser, with unary plus and minus signs. -
  • -

    - -

  • simpleBool.py
    -An example program showing how to use the new operatorPrecedence helper method to define a -boolean expression parser, with parse actions associated with each operator to "compile" the expression -into a data structure that will evaluate the expression's boolean value. -
  • -

    - -

  • simpleWiki.py
    -An example program showing how to use transformString to implement a simple Wiki markup parser. -
  • -

    - -

  • sql2dot.py~ submission by EnErGy [CSDX]
    -A nice graphing program that generates schema diagrams from SQL table definition statements. -
  • -

    - -

  • htmlStripper.py
    -An example implementation of a common application, removing HTML markup tags from an HTML page, -leaving just the text content. -
  • -

    - -

  • macroExpansion.py
    -An example implementation of a simple preprocessor, that will read embedded macro definitions -and replace macro references with the defined substitution string. -
  • -

    - -

  • sexpParser.py
    -A parser that uses a recursive grammar to parse S-expressions. -
  • -

    - -

  • nested.py
    -An example using nestedExpr, a helper method to simplify definitions of expressions of nested lists. -
  • -

    - -

  • withAttribute.py
    -An example using withAttribute, a helper method to define parse actions to validate matched HTML tags -using additional attributes. Especially helpful for matching common tags such as <DIV> and <TD>. -
  • -

    - -

  • stackish.py
    -A parser for the data representation format, Stackish. -
  • -

    - -

  • builtin_parse_action_demo.py
    -New in version 1.5.7
    -Demonstration of using builtins (min, max, sum, len, etc.) as parse actions. -
  • -

    - -

  • antlr_grammar.py~ submission by Luca DellOlio
    -New in version 1.5.7
    -Pyparsing example parsing ANTLR .a files and generating a working pyparsing parser. -
  • -

    - -

  • shapes.py
    -New in version 1.5.7
    -Parse actions example simple shape definition syntax, and returning the matched tokens as -domain objects instead of just strings. -
  • -

    - -

  • datetimeParseActions.py
    -New in version 1.5.7
    -Parse actions example showing a parse action returning a datetime object instead of -string tokens, and doing validation of the tokens, raising a ParseException if the -given YYYY/MM/DD string does not represent a valid date. -
  • -

    - -

  • position.py
    -New in version 1.5.7
    -Demonstration of a couple of different ways to capture the location a particular -expression was found within the overall input string. -
  • -

    - - -

- - diff --git a/examples/AcManForm.dfm b/examples/AcManForm.dfm deleted file mode 100644 index db80f6a..0000000 --- a/examples/AcManForm.dfm +++ /dev/null @@ -1,885 +0,0 @@ -object Form1: TForm1 - Left = 193 - Top = 105 - Width = 696 - Height = 480 - Caption = 'AcManTest' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - OldCreateOrder = False - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object RichEdit1: TRichEdit - Left = 0 - Top = 107 - Width = 688 - Height = 346 - Align = alClient - Lines.Strings = ( - 'RichEdit1') - TabOrder = 0 - end - object ActionToolBar1: TActionToolBar - Left = 0 - Top = 25 - Width = 688 - Height = 28 - ActionManager = ActionManager1 - Caption = 'ActionToolBar1' - ColorMap.HighlightColor = 14410210 - ColorMap.BtnSelectedColor = clBtnFace - ColorMap.UnusedColor = 14410210 - EdgeBorders = [ebTop, ebBottom] - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - Spacing = 0 - end - object ActionMainMenuBar1: TActionMainMenuBar - Left = 0 - Top = 0 - Width = 688 - Height = 25 - UseSystemFont = False - ActionManager = ActionManager1 - AnimationStyle = asSlide - Caption = 'ActionMainMenuBar1' - ColorMap.HighlightColor = 14410210 - ColorMap.BtnSelectedColor = clBtnFace - ColorMap.UnusedColor = 14410210 - EdgeBorders = [ebTop, ebBottom] - EdgeOuter = esNone - Font.Charset = ANSI_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentShowHint = False - ShowHint = True - Spacing = 0 - end - object ActionToolBar2: TActionToolBar - Left = 0 - Top = 53 - Width = 688 - Height = 28 - ActionManager = ActionManager1 - Caption = 'ActionToolBar2' - ColorMap.HighlightColor = 14410210 - ColorMap.BtnSelectedColor = clBtnFace - ColorMap.UnusedColor = 14410210 - EdgeBorders = [ebTop, ebBottom] - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - ParentFont = False - ParentShowHint = False - ShowHint = True - Spacing = 0 - end - object ActionToolBar3: TActionToolBar - Left = 0 - Top = 81 - Width = 688 - Height = 26 - ActionManager = ActionManager1 - Caption = 'ActionToolBar3' - ColorMap.HighlightColor = 14410210 - ColorMap.BtnSelectedColor = clBtnFace - ColorMap.UnusedColor = 14410210 - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - ParentFont = False - Spacing = 0 - end - object ActionManager1: TActionManager - FileName = 'settings' - ActionBars.SessionCount = 4 - ActionBars = < - item - Items = < - item - Action = EditUndo1 - ImageIndex = 3 - ShortCut = 16474 - end - item - Action = EditCut1 - ImageIndex = 0 - ShortCut = 16472 - end - item - Action = EditCopy1 - ImageIndex = 1 - ShortCut = 16451 - end - item - Action = EditPaste1 - ImageIndex = 2 - ShortCut = 16470 - end - item - Action = SearchFind1 - ImageIndex = 15 - ShortCut = 16454 - end - item - Action = SearchReplace1 - ImageIndex = 17 - end> - ActionBar = ActionToolBar1 - AutoSize = False - end - item - Items = < - item - Items = < - item - Action = FileOpen1 - ImageIndex = 12 - ShortCut = 16463 - end - item - Action = FileSaveAs1 - ImageIndex = 13 - end - item - Action = FilePrintSetup1 - end - item - Action = FileRun1 - end - item - Action = FileExit1 - ImageIndex = 14 - LastSession = -1 - UsageCount = -1 - end> - Caption = '&File' - end - item - Items = < - item - Action = EditCut1 - ImageIndex = 0 - ShortCut = 16472 - end - item - Action = EditCopy1 - ImageIndex = 1 - ShortCut = 16451 - end - item - Action = EditPaste1 - ImageIndex = 2 - ShortCut = 16470 - end - item - Action = EditSelectAll1 - ShortCut = 16449 - end - item - Action = EditUndo1 - ImageIndex = 3 - ShortCut = 16474 - end - item - Action = EditDelete1 - ImageIndex = 4 - ShortCut = 46 - end> - Caption = '&Edit' - end - item - Items = < - item - Action = RichEditBold1 - ImageIndex = 5 - ShortCut = 16450 - end - item - Action = RichEditItalic1 - ImageIndex = 6 - ShortCut = 16457 - end - item - Action = RichEditUnderline1 - ImageIndex = 7 - ShortCut = 16469 - end - item - Action = RichEditStrikeOut1 - end - item - Action = RichEditBullets1 - ImageIndex = 8 - end - item - Action = RichEditAlignLeft1 - ImageIndex = 9 - end - item - Action = RichEditAlignRight1 - ImageIndex = 10 - end - item - Action = RichEditAlignCenter1 - ImageIndex = 11 - end> - Caption = 'F&ormat' - end - item - Items = < - item - Action = SearchFind1 - ImageIndex = 15 - ShortCut = 16454 - end - item - Action = SearchFindNext1 - ImageIndex = 16 - ShortCut = 114 - end - item - Action = SearchReplace1 - ImageIndex = 17 - end - item - Action = SearchFindFirst1 - end> - Caption = '&Search' - end - item - Items = < - item - Action = CustomizeActionBars1 - end> - Caption = '&Tools' - end - item - Items = < - item - Action = HelpContents1 - ImageIndex = 18 - end> - Caption = '&Help' - end> - ActionBar = ActionMainMenuBar1 - AutoSize = False - end - item - Items = < - item - Action = RichEditBold1 - ImageIndex = 5 - ShortCut = 16450 - end - item - Action = RichEditItalic1 - ImageIndex = 6 - ShortCut = 16457 - end - item - Action = RichEditUnderline1 - ImageIndex = 7 - ShortCut = 16469 - end - item - Action = RichEditBullets1 - Caption = 'Bull&ets' - ImageIndex = 8 - end - item - Action = RichEditAlignLeft1 - ImageIndex = 9 - end - item - Action = RichEditAlignRight1 - ImageIndex = 10 - end - item - Action = RichEditAlignCenter1 - ImageIndex = 11 - end> - ActionBar = ActionToolBar2 - AutoSize = False - end - item - AutoSize = False - end - item - AutoSize = False - end - item - Items = < - item - Action = FileSaveAs1 - ImageIndex = 13 - LastSession = 2 - end - item - Action = CustomizeActionBars1 - end - item - Action = FileExit1 - ImageIndex = 14 - end - item - Action = HelpContents1 - Caption = 'C&ontents' - ImageIndex = 18 - end - item - Action = ActionShowStatus - Caption = '&ShowStatus' - end> - ActionBar = ActionToolBar3 - AutoSize = False - end> - Images = ImageList1 - Left = 88 - Top = 136 - StyleName = 'XP Style' - object EditCut1: TEditCut - Category = 'Edit' - Caption = 'Cu&t' - Hint = 'Cut|Cuts the selection and puts it on the Clipboard' - ImageIndex = 0 - ShortCut = 16472 - end - object EditCopy1: TEditCopy - Category = 'Edit' - Caption = '&Copy' - Hint = 'Copy|Copies the selection and puts it on the Clipboard' - ImageIndex = 1 - ShortCut = 16451 - end - object EditPaste1: TEditPaste - Category = 'Edit' - Caption = '&Paste' - Hint = 'Paste|Inserts Clipboard contents' - ImageIndex = 2 - ShortCut = 16470 - end - object EditSelectAll1: TEditSelectAll - Category = 'Edit' - Caption = 'Select &All' - Hint = 'Select All|Selects the entire document' - ShortCut = 16449 - end - object EditUndo1: TEditUndo - Category = 'Edit' - Caption = '&Undo' - Hint = 'Undo|Reverts the last action' - ImageIndex = 3 - ShortCut = 16474 - end - object EditDelete1: TEditDelete - Category = 'Edit' - Caption = '&Delete' - Hint = 'Delete|Erases the selection' - ImageIndex = 4 - ShortCut = 46 - end - object RichEditBold1: TRichEditBold - Category = 'Format' - AutoCheck = True - Caption = '&Bold' - Hint = 'Bold' - ImageIndex = 5 - ShortCut = 16450 - end - object RichEditItalic1: TRichEditItalic - Category = 'Format' - AutoCheck = True - Caption = '&Italic' - Hint = 'Italic' - ImageIndex = 6 - ShortCut = 16457 - end - object RichEditUnderline1: TRichEditUnderline - Category = 'Format' - AutoCheck = True - Caption = '&Underline' - Hint = 'Underline' - ImageIndex = 7 - ShortCut = 16469 - end - object RichEditStrikeOut1: TRichEditStrikeOut - Category = 'Format' - AutoCheck = True - Caption = '&Strikeout' - Hint = 'Strikeout' - end - object RichEditBullets1: TRichEditBullets - Category = 'Format' - AutoCheck = True - Caption = '&Bullets' - Hint = 'Bullets|Inserts a bullet on the current line' - ImageIndex = 8 - end - object RichEditAlignLeft1: TRichEditAlignLeft - Category = 'Format' - AutoCheck = True - Caption = 'Align &Left' - Hint = 'Align Left|Aligns text at the left indent' - ImageIndex = 9 - end - object RichEditAlignRight1: TRichEditAlignRight - Category = 'Format' - AutoCheck = True - Caption = 'Align &Right' - Hint = 'Align Right|Aligns text at the right indent' - ImageIndex = 10 - end - object RichEditAlignCenter1: TRichEditAlignCenter - Category = 'Format' - AutoCheck = True - Caption = '&Center' - Hint = 'Center|Centers text between margins' - ImageIndex = 11 - end - object FileOpen1: TFileOpen - Category = 'File' - Caption = '&Open...' - Hint = 'Open|Opens an existing file' - ImageIndex = 12 - ShortCut = 16463 - end - object FileSaveAs1: TFileSaveAs - Category = 'File' - Caption = 'Save &As...' - Hint = 'Save As|Saves the active file with a new name' - ImageIndex = 13 - end - object FilePrintSetup1: TFilePrintSetup - Category = 'File' - Caption = 'Print Set&up...' - Hint = 'Print Setup' - end - object FileRun1: TFileRun - Category = 'File' - Browse = False - BrowseDlg.Title = 'Run' - Caption = '&Run...' - Hint = 'Run|Runs an application' - Operation = 'open' - ShowCmd = scShowNormal - end - object FileExit1: TFileExit - Category = 'File' - Caption = 'E&xit' - Hint = 'Exit|Quits the application' - ImageIndex = 14 - end - object SearchFind1: TSearchFind - Category = 'Search' - Caption = '&Find...' - Hint = 'Find|Finds the specified text' - ImageIndex = 15 - ShortCut = 16454 - end - object SearchFindNext1: TSearchFindNext - Category = 'Search' - Caption = 'Find &Next' - Enabled = False - Hint = 'Find Next|Repeats the last find' - ImageIndex = 16 - ShortCut = 114 - end - object SearchReplace1: TSearchReplace - Category = 'Search' - Caption = '&Replace' - Hint = 'Replace|Replaces specific text with different text' - ImageIndex = 17 - end - object SearchFindFirst1: TSearchFindFirst - Category = 'Search' - Caption = 'F&ind First' - Hint = 'Find First|Finds the first occurance of specified text' - end - object CustomizeActionBars1: TCustomizeActionBars - Category = 'Tools' - Caption = '&Customize' - CustomizeDlg.StayOnTop = False - end - object HelpContents1: THelpContents - Category = 'Help' - Caption = '&Contents' - Enabled = False - Hint = 'Help Contents' - ImageIndex = 18 - end - object ActionShowStatus: TAction - Category = 'Tools' - Caption = 'ShowStatus' - OnExecute = ActionShowStatusExecute - end - end - object ImageList1: TImageList - Left = 168 - Top = 136 - Bitmap = { - 494C010113001400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000005000000001001000000000000028 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 1040104010420000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010401040 - FF7FFF7F18631042000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000010401040FF7FFF7F - 0000000018631863104200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000104210401040FF7FFF7F00000000 - 1040104000001863186310420000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000001863000000000000 - 0000000000000000186300000000000000000000000000000000000000000000 - 00000000000000000000000000000000000010421040FF7F0000000010401040 - 1040104010400000186318631042000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010420000 - 0000000010420000000000000000000000000000000000001863000000000000 - 0000000000000000186300000000000000001042000000001040104010400042 - E07F104010401040000018631863104200000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010420000 - 0000000010420000000000000000000000001042104010401040104010401040 - 0042104010401040104000001863000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000001863000000000000 - 0000186300000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000001040FF7F1040104010401040 - 1040E07FE07F1040104010400000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000001863000000000000 - 0000186300000000000000000000000000000000000000001863000000000000 - 000018630000000000000000000000000000000000001040FF7F104010401040 - 104010400042E07FE07F10401040000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000001863000000000000 - 0000186300000000000000000000000000000000000000001040FF7F10401040 - 104000421040E07FE07F10401040104000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 1042000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000001040FF7F1040 - 1040E07FE07FE07F104010401040000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 104200000000000000000000000000000000000000000000000000001040FF7F - 1040104010401040104000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001040 - FF7F104010400000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 1040104000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001042104210421042104210421042 - 104210421042FF7F186310421863FF7F18630000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001042104210421042104210421042 - 1042104210421042FF7F1042FF7F104210420000000000000000000000000000 - 0000000000000000000000000000000000000000000000420042000000000000 - 0000000000000000000000000042000000000000000000000000000000000000 - 0000000000000000000000000000000000001000100010001000000000001042 - 10421042FF7FFF7FFF7F10001000100010000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420042000000000000 - 0000000000000000000000000042000000000000000000000000004200420000 - 00000000000018630000004200000000000000000000000010001F0010000000 - 00001042FF7FFF7FFF7F10000000000000000000FF7F00000000000000000000 - 0000000000000000FF7F00000000000000000000000000420042000000000000 - 0000000000000000000000000042000000000000000000000000004200420000 - 000000000000186300000042000000000000000000000000100010001F001000 - 0000FF7FFF7FFF7FFF7F10000000000000000000FF7F00000000000000000000 - 0000000000000000FF7F00000000000000000000000000420042000000000000 - 0000000000000000000000000042000000000000000000000000004200420000 - 00000000000000000000004200000000000000000000000010001F0010001F00 - 0000FF7FFF7FFF7FFF7F10000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420042004200420042 - 0042004200420042004200420042000000000000000000000000004200420042 - 004200420042004200420042000000000000000000000000100010001F001000 - 0000FF7FFF03FF7FFF03100000000000000000000000FF7F0000000000000000 - 00000000FF7F0000000000000000000000000000000000420042000000000000 - 0000000000000000000000420042000000000000000000000000004200420000 - 00000000000000000042004200000000000000000000000010001F0010001F00 - 0000FF03FF7FFF03FF7F100000000000000000000000FF7F0000000000001863 - 00000000FF7F0000000000000000000000000000000000420000000000000000 - 0000000000000000000000000042000000000000000000000000004200001863 - 186318631863186300000042000000000000000000000000100010001F001000 - 0000FF7FFF03FF7FFF03100000000000000000000000FF7F0000000000001863 - 00000000FF7F0000000000000000000000000000000000420000000000000000 - 0000000000000000000000000042000000000000000000000000004200001863 - 18631863186318630000004200000000000000000000000010001F0010001F00 - 0000FF03FF7FFF03FF7F10000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 0000000000000000000000000042000000000000000000000000004200001863 - 1863186318631863000000000000000000000000000000001000100010001000 - 100010001000100010001000000000000000000000000000FF7F000000000000 - 00000000FF7F0000000000000000000000000000000000420000000000000000 - 0000000000000000000000000042000000000000000000000000004200001863 - 1863186318631863000018630000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000420000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000002 - 0002000200020000000000000000000000000000000000000000FF7F00000000 - 000000000000FF7F000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000100010001000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010001000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001000 - 1000100010001000100010001000100010000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000100000000000 - 1000000000001000100000000000000000000000000000000000000000000000 - 1000100010001000100010001000100010000000000000000000000000001000 - FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F10000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000100000000000 - 1000000010000000000010000000000000000000000000000000000000000000 - 1000FF7FFF7FFF7FFF7FFF7FFF7FFF7F10000000104200421042004210421000 - FF7F000000000000000000000000FF7F10000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000100000000000 - 1000000010000000000010000000000000000000000000000000000000000000 - 1000FF7F00000000000000000000FF7F10000000004210420042104200421000 - FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F10000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000010001000 - 1000000010000000000010000000000000000000000000000000000000000000 - 1000FF7FFF7FFF7FFF7FFF7FFF7FFF7F10000000104200421042004210421000 - FF7F000000000000FF7F10001000100010000000000000000000000000000000 - 0000000000000000000010000000000000000000000000000000000000000000 - 10000000100010001000000000000000000000000000FF7FFF7FFF7FFF7FFF7F - 1000FF7F00000000000000000000FF7F10000000004210420042104200421000 - FF7FFF7FFF7FFF7FFF7F1000FF7F100000000000000010001000100010001000 - 0000000000000000000010000000000000000000000000000000000000000000 - 10000000100000000000000000000000000000000000FF7F0000000000000000 - 1000FF7FFF7FFF7FFF7FFF7FFF7FFF7F10000000104200421042004210421000 - FF7FFF7FFF7FFF7FFF7F10001000000000000000000010001000100010000000 - 0000000000000000000000001000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7FFF7F - 1000FF7F00000000FF7F10001000100010000000004210420042104200421000 - 1000100010001000100010000000000000000000000010001000100000000000 - 0000000000000000000000001000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7F0000000000000000 - 1000FF7FFF7FFF7FFF7F1000FF7F100000000000104200421042004210420042 - 1042004210420042104200420000000000000000000010001000000010000000 - 0000000000000000000000001000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7FFF7F - 1000FF7FFF7FFF7FFF7F10001000000000000000004210420000000000000000 - 0000000000000000104210420000000000000000000010000000000000001000 - 1000000000000000000010000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7F00000000FF7F0000 - 1000100010001000100010000000000000000000104210420000000000000000 - 0000000000000000104200420000000000000000000000000000000000000000 - 0000100010001000100000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7F0000 - FF7F0000000000000000000000000000000000000042104200420000E07F0000 - 0000E07F00001042004210420000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7F0000 - 000000000000000000000000000000000000000000000000000000000000E07F - E07F000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000424D3E000000000000003E000000 - 2800000040000000500000000100010000000000800200000000000000000000 - 000000000000000000000000FFFFFF00FFFFB6E7FFFF0000FE49B76BFE3F0000 - FE498427F81F0000FFFFB76BE00F0000FFFFCEE780070000C7C7FFFF00030000 - C7C7C7C700010000C387C7C700000000C007C38700010000C007C00780010000 - C007C007C0010000C007C007E0000000C007C007F0000000F39FC007F8030000 - F39FF39FFC0F0000F39FF39FFE3F0000FFFFFF7E0000FFFFC001BFFF0000FFFF - 8031F003000007C18031E003E00707C18031E003E00707C18001E003E0070101 - 8001E003E007000180012003E00700018FF1E002E00700018FF1E003E0078003 - 8FF1E003E007C1078FF1E003FFFFC1078FF1E003F81FE38F8FF5FFFFF81FE38F - 8001BF7DF81FE38FFFFF7F7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - 8FFFFFFFFFFFFFFF8C03C007C007C0078FFFFFFFFFFFFFFFFFFFC03FF807F83F - FFFFFFFFFFFFFFFF8FFFC007C007C0078C03FFFFFFFFFFFF8FFFC03FF807F01F - FFFFFFFFFFFFFFFFFFFFC007C007C0078FFFFFFFFFFFFFFF8C03C03FF807F83F - 8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - EFFDFFFFFFFFE00FC7FFFFFFFFFFFFFFC3FBF00F81FFF83FE3F7F8C7E3FFF39F - F1E7F8C7F1FFF39FF8CFF8C7F8FFF39FFC1FF80FFC7FF39FFE3FF8C7FE3FF39F - FC1FF8C7FF1FF39FF8CFF8C7FF8FF39FE1E7F00FFF03E10FC3F3FFFFFFFFFFFF - C7FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFFFFFFC00FFFF - F6CFFE008000FFFFF6B7FE000000FFFFF6B7FE000000FFFFF8B780000000FFF7 - FE8F80000001C1F7FE3F80000003C3FBFF7F80000003C7FBFE3F80010003CBFB - FEBF80030003DCF7FC9F80070FC3FF0FFDDF807F0003FFFFFDDF80FF8007FFFF - FDDF81FFF87FFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 - 000000000000} - end -end diff --git a/examples/LAparser.py b/examples/LAparser.py deleted file mode 100644 index ec75d6c..0000000 --- a/examples/LAparser.py +++ /dev/null @@ -1,417 +0,0 @@ -""" -Purpose: Linear Algebra Parser -Based on: SimpleCalc.py example (author Paul McGuire) in pyparsing-1.3.3 -Author: Mike Ellis -Copyright: Ellis & Grant, Inc. 2005 -License: You may freely use, modify, and distribute this software. -Warranty: THIS SOFTWARE HAS NO WARRANTY WHATSOEVER. USE AT YOUR OWN RISK. -Notes: Parses infix linear algebra (LA) notation for vectors, matrices, and scalars. - Output is C code function calls. The parser can be run as an interactive - interpreter or included as module to use for in-place substitution into C files - containing LA equations. - - Supported operations are: - OPERATION: INPUT OUTPUT - Scalar addition: "a = b+c" "a=(b+c)" - Scalar subtraction: "a = b-c" "a=(b-c)" - Scalar multiplication: "a = b*c" "a=b*c" - Scalar division: "a = b/c" "a=b/c" - Scalar exponentiation: "a = b^c" "a=pow(b,c)" - Vector scaling: "V3_a = V3_b * c" "vCopy(a,vScale(b,c))" - Vector addition: "V3_a = V3_b + V3_c" "vCopy(a,vAdd(b,c))" - Vector subtraction: "V3_a = V3_b - V3_c" "vCopy(a,vSubtract(b,c))" - Vector dot product: "a = V3_b * V3_c" "a=vDot(b,c)" - Vector outer product: "M3_a = V3_b @ V3_c" "a=vOuterProduct(b,c)" - Vector magn. squared: "a = V3_b^Mag2" "a=vMagnitude2(b)" - Vector magnitude: "a = V3_b^Mag" "a=sqrt(vMagnitude2(b))" - Matrix scaling: "M3_a = M3_b * c" "mCopy(a,mScale(b,c))" - Matrix addition: "M3_a = M3_b + M3_c" "mCopy(a,mAdd(b,c))" - Matrix subtraction: "M3_a = M3_b - M3_c" "mCopy(a,mSubtract(b,c))" - Matrix multiplication: "M3_a = M3_b * M3_c" "mCopy(a,mMultiply(b,c))" - Matrix by vector mult.: "V3_a = M3_b * V3_c" "vCopy(a,mvMultiply(b,c))" - Matrix inversion: "M3_a = M3_b^-1" "mCopy(a,mInverse(b))" - Matrix transpose: "M3_a = M3_b^T" "mCopy(a,mTranspose(b))" - Matrix determinant: "a = M3_b^Det" "a=mDeterminant(b)" - - The parser requires the expression to be an equation. Each non-scalar variable - must be prefixed with a type tag, 'M3_' for 3x3 matrices and 'V3_' for 3-vectors. - For proper compilation of the C code, the variables need to be declared without - the prefix as float[3] for vectors and float[3][3] for matrices. The operations do - not modify any variables on the right-hand side of the equation. - - Equations may include nested expressions within parentheses. The allowed binary - operators are '+-*/^' for scalars, and '+-*^@' for vectors and matrices with the - meanings defined in the table above. - - Specifying an improper combination of operands, e.g. adding a vector to a matrix, - is detected by the parser and results in a Python TypeError Exception. The usual cause - of this is omitting one or more tag prefixes. The parser knows nothing about a - a variable's C declaration and relies entirely on the type tags. Errors in C - declarations are not caught until compile time. - -Usage: To process LA equations embedded in source files, import this module and - pass input and output file objects to the fprocess() function. You can - can also invoke the parser from the command line, e.g. 'python LAparser.py', - to run a small test suite and enter an interactive loop where you can enter - LA equations and see the resulting C code. - -""" - -import re,os,sys -from pyparsing import Word, alphas, ParseException, Literal, CaselessLiteral \ -, Combine, Optional, nums, Or, Forward, OneOrMore, ZeroOrMore, \ - FollowedBy, StringStart, StringEnd, alphanums -import math - -# Debugging flag can be set to either "debug_flag=True" or "debug_flag=False" -debug_flag=False - -#---------------------------------------------------------------------------- -# Variables that hold intermediate parsing results and a couple of -# helper functions. -exprStack = [] # Holds operators and operands parsed from input. -targetvar = None # Holds variable name to left of '=' sign in LA equation. - - -def _pushFirst( str, loc, toks ): - if debug_flag: print("pushing ", toks[0], "str is ", str) - exprStack.append( toks[0] ) - -def _assignVar( str, loc, toks ): - global targetvar - targetvar = toks[0] - -#----------------------------------------------------------------------------- -# The following statements define the grammar for the parser. - -point = Literal('.') -e = CaselessLiteral('E') -plusorminus = Literal('+') | Literal('-') -number = Word(nums) -integer = Combine( Optional(plusorminus) + number ) -floatnumber = Combine( integer + - Optional( point + Optional(number) ) + - Optional( e + integer ) - ) - -lbracket = Literal("[") -rbracket = Literal("]") -ident = Forward() -## The definition below treats array accesses as identifiers. This means your expressions -## can include references to array elements, rows and columns, e.g., a = b[i] + 5. -## Expressions within []'s are not presently supported, so a = b[i+1] will raise -## a ParseException. -ident = Combine(Word(alphas + '-',alphanums + '_') + \ - ZeroOrMore(lbracket + (Word(alphas + '-',alphanums + '_')|integer) + rbracket) \ - ) - -plus = Literal( "+" ) -minus = Literal( "-" ) -mult = Literal( "*" ) -div = Literal( "/" ) -outer = Literal( "@" ) -lpar = Literal( "(" ).suppress() -rpar = Literal( ")" ).suppress() -addop = plus | minus -multop = mult | div | outer -expop = Literal( "^" ) -assignop = Literal( "=" ) - -expr = Forward() -atom = ( ( e | floatnumber | integer | ident ).setParseAction(_pushFirst) | - ( lpar + expr.suppress() + rpar ) - ) -factor = Forward() -factor << atom + ZeroOrMore( ( expop + factor ).setParseAction( _pushFirst ) ) - -term = factor + ZeroOrMore( ( multop + factor ).setParseAction( _pushFirst ) ) -expr << term + ZeroOrMore( ( addop + term ).setParseAction( _pushFirst ) ) -equation = (ident + assignop).setParseAction(_assignVar) + expr + StringEnd() - -# End of grammar definition -#----------------------------------------------------------------------------- -## The following are helper variables and functions used by the Binary Infix Operator -## Functions described below. - -vprefix = 'V3_' -vplen = len(vprefix) -mprefix = 'M3_' -mplen = len(mprefix) - -## We don't support unary negation for vectors and matrices -class UnaryUnsupportedError(Exception): pass - -def _isvec(ident): - if ident[0] == '-' and ident[1:vplen+1] == vprefix: - raise UnaryUnsupportedError - else: return ident[0:vplen] == vprefix - -def _ismat(ident): - if ident[0] == '-' and ident[1:mplen+1] == mprefix: - raise UnaryUnsupportedError - else: return ident[0:mplen] == mprefix - -def _isscalar(ident): return not (_isvec(ident) or _ismat(ident)) - -## Binary infix operator (BIO) functions. These are called when the stack evaluator -## pops a binary operator like '+' or '*". The stack evaluator pops the two operand, a and b, -## and calls the function that is mapped to the operator with a and b as arguments. Thus, -## 'x + y' yields a call to addfunc(x,y). Each of the BIO functions checks the prefixes of its -## arguments to determine whether the operand is scalar, vector, or matrix. This information -## is used to generate appropriate C code. For scalars, this is essentially the input string, e.g. -## 'a + b*5' as input yields 'a + b*5' as output. For vectors and matrices, the input is translated to -## nested function calls, e.g. "V3_a + V3_b*5" yields "V3_vAdd(a,vScale(b,5)". Note that prefixes are -## stripped from operands and function names within the argument list to the outer function and -## the appropriate prefix is placed on the outer function for removal later as the stack evaluation -## recurses toward the final assignment statement. - -def _addfunc(a,b): - if _isscalar(a) and _isscalar(b): return "(%s+%s)"%(a,b) - if _isvec(a) and _isvec(b): return "%svAdd(%s,%s)"%(vprefix,a[vplen:],b[vplen:]) - if _ismat(a) and _ismat(b): return "%smAdd(%s,%s)"%(mprefix,a[mplen:],b[mplen:]) - else: raise TypeError - -def _subfunc(a,b): - if _isscalar(a) and _isscalar(b): return "(%s-%s)"%(a,b) - if _isvec(a) and _isvec(b): return "%svSubtract(%s,%s)"%(vprefix,a[vplen:],b[vplen:]) - if _ismat(a) and _ismat(b): return "%smSubtract(%s,%s)"%(mprefix,a[mplen:],b[mplen:]) - else: raise TypeError - -def _mulfunc(a,b): - if _isscalar(a) and _isscalar(b): return "%s*%s"%(a,b) - if _isvec(a) and _isvec(b): return "vDot(%s,%s)"%(a[vplen:],b[vplen:]) - if _ismat(a) and _ismat(b): return "%smMultiply(%s,%s)"%(mprefix,a[mplen:],b[mplen:]) - if _ismat(a) and _isvec(b): return "%smvMultiply(%s,%s)"%(vprefix,a[mplen:],b[vplen:]) - if _ismat(a) and _isscalar(b): return "%smScale(%s,%s)"%(mprefix,a[mplen:],b) - if _isvec(a) and _isscalar(b): return "%svScale(%s,%s)"%(vprefix,a[mplen:],b) - else: raise TypeError - -def _outermulfunc(a,b): - ## The '@' operator is used for the vector outer product. - if _isvec(a) and _isvec(b): - return "%svOuterProduct(%s,%s)"%(mprefix,a[vplen:],b[vplen:]) - else: raise TypeError - -def _divfunc(a,b): - ## The '/' operator is used only for scalar division - if _isscalar(a) and _isscalar(b): return "%s/%s"%(a,b) - else: raise TypeError - -def _expfunc(a,b): - ## The '^' operator is used for exponentiation on scalars and - ## as a marker for unary operations on vectors and matrices. - if _isscalar(a) and _isscalar(b): return "pow(%s,%s)"%(str(a),str(b)) - if _ismat(a) and b=='-1': return "%smInverse(%s)"%(mprefix,a[mplen:]) - if _ismat(a) and b=='T': return "%smTranspose(%s)"%(mprefix,a[mplen:]) - if _ismat(a) and b=='Det': return "mDeterminant(%s)"%(a[mplen:]) - if _isvec(a) and b=='Mag': return "sqrt(vMagnitude2(%s))"%(a[vplen:]) - if _isvec(a) and b=='Mag2': return "vMagnitude2(%s)"%(a[vplen:]) - else: raise TypeError - -def _assignfunc(a,b): - ## The '=' operator is used for assignment - if _isscalar(a) and _isscalar(b): return "%s=%s"%(a,b) - if _isvec(a) and _isvec(b): return "vCopy(%s,%s)"%(a[vplen:],b[vplen:]) - if _ismat(a) and _ismat(b): return "mCopy(%s,%s)"%(a[mplen:],b[mplen:]) - else: raise TypeError - -## End of BIO func definitions -##---------------------------------------------------------------------------- - -# Map operator symbols to corresponding BIO funcs -opn = { "+" : ( _addfunc ), - "-" : ( _subfunc ), - "*" : ( _mulfunc ), - "@" : ( _outermulfunc ), - "/" : ( _divfunc), - "^" : ( _expfunc ), } - - -##---------------------------------------------------------------------------- -# Recursive function that evaluates the expression stack -def _evaluateStack( s ): - op = s.pop() - if op in "+-*/@^": - op2 = _evaluateStack( s ) - op1 = _evaluateStack( s ) - result = opn[op]( op1, op2 ) - if debug_flag: print(result) - return result - else: - return op - -##---------------------------------------------------------------------------- -# The parse function that invokes all of the above. -def parse(input_string): - """ - Accepts an input string containing an LA equation, e.g., - "M3_mymatrix = M3_anothermatrix^-1" returns C code function - calls that implement the expression. - """ - - global exprStack - global targetvar - - # Start with a blank exprStack and a blank targetvar - exprStack = [] - targetvar=None - - if input_string != '': - # try parsing the input string - try: - L=equation.parseString( input_string ) - except ParseException as err: - print('Parse Failure', file=sys.stderr) - print(err.line, file=sys.stderr) - print(" "*(err.column-1) + "^", file=sys.stderr) - print(err, file=sys.stderr) - raise - - # show result of parsing the input string - if debug_flag: - print(input_string, "->", L) - print("exprStack=", exprStack) - - # Evaluate the stack of parsed operands, emitting C code. - try: - result=_evaluateStack(exprStack) - except TypeError: - print("Unsupported operation on right side of '%s'.\nCheck for missing or incorrect tags on non-scalar operands."%input_string, file=sys.stderr) - raise - except UnaryUnsupportedError: - print("Unary negation is not supported for vectors and matrices: '%s'"%input_string, file=sys.stderr) - raise - - # Create final assignment and print it. - if debug_flag: print("var=",targetvar) - if targetvar != None: - try: - result = _assignfunc(targetvar,result) - except TypeError: - print("Left side tag does not match right side of '%s'"%input_string, file=sys.stderr) - raise - except UnaryUnsupportedError: - print("Unary negation is not supported for vectors and matrices: '%s'"%input_string, file=sys.stderr) - raise - - return result - else: - print("Empty left side in '%s'"%input_string, file=sys.stderr) - raise TypeError - -##----------------------------------------------------------------------------------- -def fprocess(infilep,outfilep): - """ - Scans an input file for LA equations between double square brackets, - e.g. [[ M3_mymatrix = M3_anothermatrix^-1 ]], and replaces the expression - with a comment containing the equation followed by nested function calls - that implement the equation as C code. A trailing semi-colon is appended. - The equation within [[ ]] should NOT end with a semicolon as that will raise - a ParseException. However, it is ok to have a semicolon after the right brackets. - - Other text in the file is unaltered. - - The arguments are file objects (NOT file names) opened for reading and - writing, respectively. - """ - pattern = r'\[\[\s*(.*?)\s*\]\]' - eqn = re.compile(pattern,re.DOTALL) - s = infilep.read() - def parser(mo): - ccode = parse(mo.group(1)) - return "/* %s */\n%s;\nLAParserBufferReset();\n"%(mo.group(1),ccode) - - content = eqn.sub(parser,s) - outfilep.write(content) - -##----------------------------------------------------------------------------------- -def test(): - """ - Tests the parsing of various supported expressions. Raises - an AssertError if the output is not what is expected. Prints the - input, expected output, and actual output for all tests. - """ - print("Testing LAParser") - testcases = [ - ("Scalar addition","a = b+c","a=(b+c)"), - ("Vector addition","V3_a = V3_b + V3_c","vCopy(a,vAdd(b,c))"), - ("Vector addition","V3_a=V3_b+V3_c","vCopy(a,vAdd(b,c))"), - ("Matrix addition","M3_a = M3_b + M3_c","mCopy(a,mAdd(b,c))"), - ("Matrix addition","M3_a=M3_b+M3_c","mCopy(a,mAdd(b,c))"), - ("Scalar subtraction","a = b-c","a=(b-c)"), - ("Vector subtraction","V3_a = V3_b - V3_c","vCopy(a,vSubtract(b,c))"), - ("Matrix subtraction","M3_a = M3_b - M3_c","mCopy(a,mSubtract(b,c))"), - ("Scalar multiplication","a = b*c","a=b*c"), - ("Scalar division","a = b/c","a=b/c"), - ("Vector multiplication (dot product)","a = V3_b * V3_c","a=vDot(b,c)"), - ("Vector multiplication (outer product)","M3_a = V3_b @ V3_c","mCopy(a,vOuterProduct(b,c))"), - ("Matrix multiplication","M3_a = M3_b * M3_c","mCopy(a,mMultiply(b,c))"), - ("Vector scaling","V3_a = V3_b * c","vCopy(a,vScale(b,c))"), - ("Matrix scaling","M3_a = M3_b * c","mCopy(a,mScale(b,c))"), - ("Matrix by vector multiplication","V3_a = M3_b * V3_c","vCopy(a,mvMultiply(b,c))"), - ("Scalar exponentiation","a = b^c","a=pow(b,c)"), - ("Matrix inversion","M3_a = M3_b^-1","mCopy(a,mInverse(b))"), - ("Matrix transpose","M3_a = M3_b^T","mCopy(a,mTranspose(b))"), - ("Matrix determinant","a = M3_b^Det","a=mDeterminant(b)"), - ("Vector magnitude squared","a = V3_b^Mag2","a=vMagnitude2(b)"), - ("Vector magnitude","a = V3_b^Mag","a=sqrt(vMagnitude2(b))"), - ("Complicated expression", "myscalar = (M3_amatrix * V3_bvector)^Mag + 5*(-xyz[i] + 2.03^2)","myscalar=(sqrt(vMagnitude2(mvMultiply(amatrix,bvector)))+5*(-xyz[i]+pow(2.03,2)))"), - ("Complicated Multiline", "myscalar = \n(M3_amatrix * V3_bvector)^Mag +\n 5*(xyz + 2.03^2)","myscalar=(sqrt(vMagnitude2(mvMultiply(amatrix,bvector)))+5*(xyz+pow(2.03,2)))") - - ] - - for t in testcases: - name,input,expected = t - print(name) - print(" %s input"%input) - print(" %s expected"%expected) - result = parse(input) - print(" %s received"%result) - print("") - assert expected == result - - ##TODO: Write testcases with invalid expressions and test that the expected - ## exceptions are raised. - - print("Tests completed!") -##---------------------------------------------------------------------------- -## The following is executed only when this module is executed as -## command line script. It runs a small test suite (see above) -## and then enters an interactive loop where you -## can enter expressions and see the resulting C code as output. - -if __name__ == '__main__': - # run testcases - test() - - # input_string - input_string='' - - # Display instructions on how to use the program interactively - interactiveusage = """ - Entering interactive mode: - Type in an equation to be parsed or 'quit' to exit the program. - Type 'debug on' to print parsing details as each string is processed. - Type 'debug off' to stop printing parsing details - """ - print(interactiveusage) - input_string = input("> ") - - while input_string != 'quit': - if input_string == "debug on": - debug_flag = True - elif input_string == "debug off": - debug_flag = False - else: - try: - print(parse(input_string)) - except: - pass - - # obtain new input string - input_string = input("> ") - - # if user types 'quit' then say goodbye - print("Good bye!") - - diff --git a/examples/Setup.ini b/examples/Setup.ini deleted file mode 100644 index 4574b1c..0000000 --- a/examples/Setup.ini +++ /dev/null @@ -1,73 +0,0 @@ -[Startup] -AppName=M3i.comm -stname = Utility -modemid=125D&DEV_1999 -audioid=125D&DEV_1998 -win98path= -winmepath= -win2kpath= -winxppath= -win95path= -winnt4path= - -stupgrade =Install/Upgrade Drivers -stuninstall =Uninstall Drivers -stchoose =Choose One Function to Process -stchoosez3 =Choose Devices to Process - -copycompl =Copying files completed - -RemString1=Set up has finished remove ESS device driver and cleaned your system. Click Finish to exit. -RemString2=ESS devices is removed completely.No need to reboot. If you want to reinstall, run the setup again with driver package. -stshowmsg1=Setup will clean the installed files and update registry. -stshowmsg2=Setup is updating system's registry .... -stshowmsg3=Setup is starting - -sysdriver=es56cvmp.sys -mdmzn=mdmm3com.inf -mdmznp=esmdm_98.inf -mdmzna=mdmessa.inf -spkname=essspk.exe -remvess=remvess.exe -slmcat=allem3m.cat -audiocat=allem3.cat -audioinf=M3i -sysaudio=es198xdl.sys -audiovxd=es198x.vxd - -[Languages] -Default=0x0009 -count=30 -key0=0x002d -key1=0x0003 -key2=0x0804 -key3=0x0404 -key4=0x001a -key5=0x0005 -key6=0x0006 -key7=0x0013 -key8=0x0009 -key9=0x000b -key10=0x0c0c -key11=0x040c -key12=0x0007 -key13=0x0008 -key14=0x000e -key15=0x0021 -key16=0x0010 -key17=0x0011 -key18=0x0012 -key19=0x0014 -key20=0x0015 -key21=0x0416 -key22=0x0816 -key23=0x0019 -key24=0x001b -key25=0x0024 -key26=0x000a -key27=0x001d -key28=0x001e -key29=0x001f - -[test] -foo=bar diff --git a/examples/SimpleCalc.py b/examples/SimpleCalc.py deleted file mode 100644 index 46a5dff..0000000 --- a/examples/SimpleCalc.py +++ /dev/null @@ -1,118 +0,0 @@ -# SimpleCalc.py -# -# Demonstration of the parsing module, -# Sample usage -# -# $ python SimpleCalc.py -# Type in the string to be parse or 'quit' to exit the program -# > g=67.89 + 7/5 -# 69.29 -# > g -# 69.29 -# > h=(6*g+8.8)-g -# 355.25 -# > h + 1 -# 356.25 -# > 87.89 + 7/5 -# 89.29 -# > ans+10 -# 99.29 -# > quit -# Good bye! -# -# - - - -# Uncomment the line below for readline support on interactive terminal -# import readline -from pyparsing import ParseException, Word, alphas, alphanums -import math - -# Debugging flag can be set to either "debug_flag=True" or "debug_flag=False" -debug_flag=False - -variables = {} - -from fourFn import BNF, exprStack, fn, opn -def evaluateStack( s ): - op = s.pop() - if op == 'unary -': - return -evaluateStack( s ) - if op in "+-*/^": - op2 = evaluateStack( s ) - op1 = evaluateStack( s ) - return opn[op]( op1, op2 ) - elif op == "PI": - return math.pi # 3.1415926535 - elif op == "E": - return math.e # 2.718281828 - elif op in fn: - return fn[op]( evaluateStack( s ) ) - elif op[0].isalpha(): - if op in variables: - return variables[op] - raise Exception("invalid identifier '%s'" % op) - else: - return float( op ) - -arithExpr = BNF() -ident = Word(alphas, alphanums).setName("identifier") -assignment = ident("varname") + '=' + arithExpr -pattern = assignment | arithExpr - -if __name__ == '__main__': - # input_string - input_string='' - - # Display instructions on how to quit the program - print("Type in the string to be parsed or 'quit' to exit the program") - input_string = input("> ") - - while input_string != 'quit': - if input_string.lower() == 'debug': - debug_flag=True - input_string = input("> ") - continue - - # Reset to an empty exprStack - del exprStack[:] - - if input_string != '': - # try parsing the input string - try: - L=pattern.parseString( input_string, parseAll=True ) - except ParseException as err: - L=['Parse Failure',input_string] - - # show result of parsing the input string - if debug_flag: print(input_string, "->", L) - if len(L)==0 or L[0] != 'Parse Failure': - if debug_flag: print("exprStack=", exprStack) - - # calculate result , store a copy in ans , display the result to user - try: - result=evaluateStack(exprStack) - except Exception as e: - print(str(e)) - else: - variables['ans']=result - print(result) - - # Assign result to a variable if required - if L.varname: - variables[L.varname] = result - if debug_flag: print("variables=",variables) - else: - print('Parse Failure') - print(err.line) - print(" "*(err.column-1) + "^") - print(err) - - # obtain new input string - input_string = input("> ") - - # if user type 'quit' then say goodbye - print("Good bye!") - - diff --git a/examples/SingleForm.dfm b/examples/SingleForm.dfm deleted file mode 100644 index 7a52734..0000000 --- a/examples/SingleForm.dfm +++ /dev/null @@ -1,751 +0,0 @@ -object Form1: TForm1 - Left = 161 - Top = 149 - Width = 696 - Height = 342 - Caption = 'DbxSingle' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - OldCreateOrder = False - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object ActionToolBar2: TActionToolBar - Left = 0 - Top = 0 - Width = 688 - Height = 26 - ActionManager = ActionManager1 - AllowHiding = False - Caption = 'ActionToolBar2' - ColorMap.HighlightColor = 14410210 - ColorMap.BtnSelectedColor = clBtnFace - ColorMap.UnusedColor = 14410210 - Spacing = 0 - end - object PageControl1: TPageControl - Left = 0 - Top = 26 - Width = 688 - Height = 289 - ActivePage = TabSheet1 - Align = alClient - TabOrder = 1 - object TabSheet1: TTabSheet - Caption = 'Data' - object DBGrid1: TDBGrid - Left = 0 - Top = 0 - Width = 680 - Height = 261 - Align = alClient - DataSource = DataSource1 - TabOrder = 0 - TitleFont.Charset = DEFAULT_CHARSET - TitleFont.Color = clWindowText - TitleFont.Height = -11 - TitleFont.Name = 'MS Sans Serif' - TitleFont.Style = [] - end - end - object TabSheet2: TTabSheet - Caption = 'Log' - ImageIndex = 1 - object Memo1: TMemo - Left = 0 - Top = 0 - Width = 680 - Height = 399 - Align = alClient - TabOrder = 0 - end - end - end - object SimpleDataSet1: TSimpleDataSet - Aggregates = <> - Connection.ConnectionName = 'IBLocal' - Connection.DriverName = 'Interbase' - Connection.GetDriverFunc = 'getSQLDriverINTERBASE' - Connection.LibraryName = 'dbexpint.dll' - Connection.LoginPrompt = False - Connection.Params.Strings = ( - 'BlobSize=-1' - 'CommitRetain=False' - - 'Database=C:\Program Files\Common Files\Borland Shared\Data\emplo' + - 'yee.gdb' - 'DriverName=Interbase' - 'Password=masterkey' - 'RoleName=RoleName' - 'ServerCharSet=ASCII' - 'SQLDialect=1' - 'Interbase TransIsolation=ReadCommited' - 'User_Name=sysdba' - 'WaitOnLocks=True') - Connection.VendorLib = 'GDS32.DLL' - DataSet.CommandText = 'EMPLOYEE' - DataSet.CommandType = ctTable - DataSet.MaxBlobSize = -1 - DataSet.Params = <> - Params = <> - AfterPost = DoUpdate - BeforeDelete = DoUpdate - Left = 104 - Top = 56 - end - object ActionManager1: TActionManager - ActionBars = < - item - Items.CaptionOptions = coAll - Items = < - item - Action = DataSetFirst1 - ImageIndex = 0 - end - item - Action = DataSetPrior1 - ImageIndex = 1 - end - item - Action = DataSetNext1 - ImageIndex = 2 - end - item - Action = DataSetLast1 - ImageIndex = 3 - end - item - Action = DataSetInsert1 - ImageIndex = 4 - end - item - Action = DataSetDelete1 - ImageIndex = 5 - end - item - Action = DataSetEdit1 - ImageIndex = 6 - end - item - Action = DataSetPost1 - ImageIndex = 7 - end - item - Action = DataSetCancel1 - ImageIndex = 8 - end - item - Action = DataSetRefresh1 - ImageIndex = 9 - end> - ActionBar = ActionToolBar2 - end> - Images = ImageList1 - Left = 112 - Top = 184 - StyleName = 'XP Style' - object DataSetFirst1: TDataSetFirst - Category = 'Dataset' - Caption = 'First' - ImageIndex = 0 - end - object DataSetPrior1: TDataSetPrior - Category = 'Dataset' - Caption = 'Prior' - ImageIndex = 1 - end - object DataSetNext1: TDataSetNext - Category = 'Dataset' - Caption = 'Next' - ImageIndex = 2 - end - object DataSetLast1: TDataSetLast - Category = 'Dataset' - Caption = 'Last' - ImageIndex = 3 - end - object DataSetInsert1: TDataSetInsert - Category = 'Dataset' - Caption = 'Insert' - ImageIndex = 4 - end - object DataSetDelete1: TDataSetDelete - Category = 'Dataset' - Caption = 'Delete' - ImageIndex = 5 - end - object DataSetEdit1: TDataSetEdit - Category = 'Dataset' - Caption = 'Edit' - ImageIndex = 6 - end - object DataSetPost1: TDataSetPost - Category = 'Dataset' - Caption = 'Post' - ImageIndex = 7 - end - object DataSetCancel1: TDataSetCancel - Category = 'Dataset' - Caption = 'Cancel' - ImageIndex = 8 - end - object DataSetRefresh1: TDataSetRefresh - Category = 'Dataset' - Caption = 'Refresh' - ImageIndex = 9 - end - end - object ImageList1: TImageList - Left = 112 - Top = 120 - Bitmap = { - 494C01010C000F00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000004000000001002000000000000040 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400848484008484840084848400848484008484 - 8400848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 00000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 00000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 00000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 00000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008484 - 8400000000008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400008484000084840000848400008484000084840000848400008484000084 - 8400008484000084840000000000000000000000000000000000000000000000 - 00000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000 - 0000848484000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000084 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000008484000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000008484840000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008484 - 8400000000000000000084848400000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000084840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000008484840000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000848484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000848484008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000008484840000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000848484000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000848484000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000008484840000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000084848400000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000084848400000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000848484000000000000000000000000000000000000000000000000008484 - 8400000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000424D3E000000000000003E000000 - 2800000040000000400000000100010000000000000200000000000000000000 - 000000000000000000000000FFFFFF0000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000FFFFFFFFFFFFFC07FFFFFFFFC001F807 - FFFFFFFF8031F807FFFFFC7F8031F807F3E7F0FF8031F807F1C7F1FF8001F807 - F88FE3FF8001F807FC1FE7FF8001F80FFE3FE7078FF1FF7FFC1FE3878FF1FE3F - F88FE1078FF1FC1FF1C7F0078FF1FFFFF3E7F8378FF1FEFFFFFFFFFF8FF5FFFF - FFFFFFFF8001FDFFFFFFFFFFFFFF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7FFFFFFFFFFBFFFC7FFFFFFFFFF1FF - FC7FFFFFE007E0FFE00FE007F00FC47FE00FE007F81FCE3FE00FE007FC3FFF1F - FC7FFFFFFE7FFF8FFC7FFFFFFFFFFFC7FC7FFFFFFFFFFFE7FFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7FF9FF9FFE7E7 - E787FE1FF87FE1E7E607F81FF81FE067E007F01FF80FE007E607F81FF81FE067 - E787FE1FF87FE1E7E7E7FF9FF9FFE7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 - 000000000000} - end - object DataSource1: TDataSource - DataSet = SimpleDataSet1 - Left = 108 - Top = 250 - end - object SQLMonitor1: TSQLMonitor - OnTrace = SQLMonitor1Trace - Left = 228 - Top = 122 - end -end diff --git a/examples/TAP.py b/examples/TAP.py deleted file mode 100644 index 139e47c..0000000 --- a/examples/TAP.py +++ /dev/null @@ -1,217 +0,0 @@ -# -# TAP.py - TAP parser -# -# A pyparsing parser to process the output of the Perl -# "Test Anything Protocol" -# (http://search.cpan.org/~petdance/TAP-1.00/TAP.pm) -# -# TAP output lines are preceded or followed by a test number range: -# 1..n -# with 'n' TAP output lines. -# -# The general format of a TAP output line is: -# ok/not ok (required) -# Test number (recommended) -# Description (recommended) -# Directive (only when necessary) -# -# A TAP output line may also indicate abort of the test suit with the line: -# Bail out! -# optionally followed by a reason for bailing -# -# Copyright 2008, by Paul McGuire -# - -from pyparsing import ParserElement,LineEnd,Optional,Word,nums,Regex,\ - Literal,CaselessLiteral,Group,OneOrMore,Suppress,restOfLine,\ - FollowedBy,empty - -__all__ = ['tapOutputParser', 'TAPTest', 'TAPSummary'] - -# newlines are significant whitespace, so set default skippable -# whitespace to just spaces and tabs -ParserElement.setDefaultWhitespaceChars(" \t") -NL = LineEnd().suppress() - -integer = Word(nums) -plan = '1..' + integer("ubound") - -OK,NOT_OK = map(Literal,['ok','not ok']) -testStatus = (OK | NOT_OK) - -description = Regex("[^#\n]+") -description.setParseAction(lambda t:t[0].lstrip('- ')) - -TODO,SKIP = map(CaselessLiteral,'TODO SKIP'.split()) -directive = Group(Suppress('#') + (TODO + restOfLine | - FollowedBy(SKIP) + - restOfLine.copy().setParseAction(lambda t:['SKIP',t[0]]) )) - -commentLine = Suppress("#") + empty + restOfLine - -testLine = Group( - Optional(OneOrMore(commentLine + NL))("comments") + - testStatus("passed") + - Optional(integer)("testNumber") + - Optional(description)("description") + - Optional(directive)("directive") - ) -bailLine = Group(Literal("Bail out!")("BAIL") + - empty + Optional(restOfLine)("reason")) - -tapOutputParser = Optional(Group(plan)("plan") + NL) & \ - Group(OneOrMore((testLine|bailLine) + NL))("tests") - -class TAPTest(object): - def __init__(self,results): - self.num = results.testNumber - self.passed = (results.passed=="ok") - self.skipped = self.todo = False - if results.directive: - self.skipped = (results.directive[0][0]=='SKIP') - self.todo = (results.directive[0][0]=='TODO') - @classmethod - def bailedTest(cls,num): - ret = TAPTest(empty.parseString("")) - ret.num = num - ret.skipped = True - return ret - -class TAPSummary(object): - def __init__(self,results): - self.passedTests = [] - self.failedTests = [] - self.skippedTests = [] - self.todoTests = [] - self.bonusTests = [] - self.bail = False - if results.plan: - expected = list(range(1, int(results.plan.ubound)+1)) - else: - expected = list(range(1,len(results.tests)+1)) - - for i,res in enumerate(results.tests): - # test for bail out - if res.BAIL: - #~ print "Test suite aborted: " + res.reason - #~ self.failedTests += expected[i:] - self.bail = True - self.skippedTests += [ TAPTest.bailedTest(ii) for ii in expected[i:] ] - self.bailReason = res.reason - break - - #~ print res.dump() - testnum = i+1 - if res.testNumber != "": - if testnum != int(res.testNumber): - print("ERROR! test %(testNumber)s out of sequence" % res) - testnum = int(res.testNumber) - res["testNumber"] = testnum - - test = TAPTest(res) - if test.passed: - self.passedTests.append(test) - else: - self.failedTests.append(test) - if test.skipped: self.skippedTests.append(test) - if test.todo: self.todoTests.append(test) - if test.todo and test.passed: self.bonusTests.append(test) - - self.passedSuite = not self.bail and (set(self.failedTests)-set(self.todoTests) == set()) - - def summary(self, showPassed=False, showAll=False): - testListStr = lambda tl : "[" + ",".join(str(t.num) for t in tl) + "]" - summaryText = [] - if showPassed or showAll: - summaryText.append( "PASSED: %s" % testListStr(self.passedTests) ) - if self.failedTests or showAll: - summaryText.append( "FAILED: %s" % testListStr(self.failedTests) ) - if self.skippedTests or showAll: - summaryText.append( "SKIPPED: %s" % testListStr(self.skippedTests) ) - if self.todoTests or showAll: - summaryText.append( "TODO: %s" % testListStr(self.todoTests) ) - if self.bonusTests or showAll: - summaryText.append( "BONUS: %s" % testListStr(self.bonusTests) ) - if self.passedSuite: - summaryText.append( "PASSED" ) - else: - summaryText.append( "FAILED" ) - return "\n".join(summaryText) - -# create TAPSummary objects from tapOutput parsed results, by setting -# class as parse action -tapOutputParser.setParseAction(TAPSummary) - - -if __name__ == "__main__": - test1 = """\ - 1..4 - ok 1 - Input file opened - not ok 2 - First line of the input valid - ok 3 - Read the rest of the file - not ok 4 - Summarized correctly # TODO Not written yet - """ - test2 = """\ - ok 1 - not ok 2 some description # TODO with a directive - ok 3 a description only, no directive - ok 4 # TODO directive only - ok a description only, no directive - ok # Skipped only a directive, no description - ok - """ - test3 = """\ - ok - created Board - ok - ok - not ok - ok - ok - ok - ok - # +------+------+------+------+ - # | |16G | |05C | - # | |G N C | |C C G | - # | | G | | C +| - # +------+------+------+------+ - # |10C |01G | |03C | - # |R N G |G A G | |C C C | - # | R | G | | C +| - # +------+------+------+------+ - # | |01G |17C |00C | - # | |G A G |G N R |R N R | - # | | G | R | G | - # +------+------+------+------+ - ok - board has 7 tiles + starter tile - 1..9 - """ - test4 = """\ - 1..4 - ok 1 - Creating test program - ok 2 - Test program runs, no error - not ok 3 - infinite loop # TODO halting problem unsolved - not ok 4 - infinite loop 2 # TODO halting problem unsolved - """ - test5 = """\ - 1..20 - ok - database handle - not ok - failed database login - Bail out! Couldn't connect to database. - """ - test6 = """\ - ok 1 - retrieving servers from the database - # need to ping 6 servers - ok 2 - pinged diamond - ok 3 - pinged ruby - not ok 4 - pinged sapphire - ok 5 - pinged onyx - not ok 6 - pinged quartz - ok 7 - pinged gold - 1..7 - """ - - for test in (test1,test2,test3,test4,test5,test6): - print(test) - tapResult = tapOutputParser.parseString(test)[0] - print(tapResult.summary(showAll=True)) - print() diff --git a/examples/__init__.py b/examples/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/examples/adventureEngine.py b/examples/adventureEngine.py deleted file mode 100644 index be09770..0000000 --- a/examples/adventureEngine.py +++ /dev/null @@ -1,648 +0,0 @@ -# adventureEngine.py -# Copyright 2005-2006, Paul McGuire -# -# Updated 2012 - latest pyparsing API -# - -from pyparsing import * -import random -import string - -def aOrAn( item ): - if item.desc[0] in "aeiou": - return "an " + item.desc - else: - return "a " + item.desc - -def enumerateItems(l): - if len(l) == 0: return "nothing" - out = [] - if len(l) > 1: - out.append(', '.join(aOrAn(item) for item in l[:-1])) - out.append('and') - out.append(aOrAn(l[-1])) - return " ".join(out) - -def enumerateDoors(l): - if len(l) == 0: return "" - out = [] - if len(l) > 1: - out.append(', '.join(l[:-1])) - out.append("and") - out.append(l[-1]) - return " ".join(out) - -class Room(object): - def __init__(self, desc): - self.desc = desc - self.inv = [] - self.gameOver = False - self.doors = [None,None,None,None] - - def __getattr__(self,attr): - return \ - { - "n":self.doors[0], - "s":self.doors[1], - "e":self.doors[2], - "w":self.doors[3], - }[attr] - - def enter(self,player): - if self.gameOver: - player.gameOver = True - - def addItem(self, it): - self.inv.append(it) - - def removeItem(self,it): - self.inv.remove(it) - - def describe(self): - print(self.desc) - visibleItems = [ it for it in self.inv if it.isVisible ] - if random.random() > 0.5: - if len(visibleItems) > 1: - is_form = "are" - else: - is_form = "is" - print("There %s %s here." % (is_form, enumerateItems(visibleItems))) - else: - print("You see %s." % (enumerateItems(visibleItems))) - - -class Exit(Room): - def __init__(self): - super(Exit,self).__init__("") - - def enter(self,player): - player.gameOver = True - - - -class Item(object): - items = {} - def __init__(self, desc): - self.desc = desc - self.isDeadly = False - self.isFragile = False - self.isBroken = False - self.isTakeable = True - self.isVisible = True - self.isOpenable = False - self.useAction = None - self.usableConditionTest = None - self.cantTakeMessage = "You can't take that!" - Item.items[desc] = self - - def __str__(self): - return self.desc - - def breakItem(self): - if not self.isBroken: - print("") - self.desc = "broken " + self.desc - self.isBroken = True - - def isUsable(self, player, target): - if self.usableConditionTest: - return self.usableConditionTest( player, target ) - else: - return False - - def useItem(self, player, target): - if self.useAction: - self.useAction(player, self, target) - -class OpenableItem(Item): - def __init__(self, desc, contents=None): - super(OpenableItem,self).__init__(desc) - self.isOpenable = True - self.isOpened = False - if contents is not None: - if isinstance(contents, Item): - self.contents = [contents,] - else: - self.contents = contents - else: - self.contents = [] - - def openItem(self, player): - if not self.isOpened: - self.isOpened = not self.isOpened - if self.contents is not None: - for item in self.contents: - player.room.addItem( item ) - self.contents = [] - self.desc = "open " + self.desc - - def closeItem(self, player): - if self.isOpened: - self.isOpened = not self.isOpened - if self.desc.startswith("open "): - self.desc = self.desc[5:] - - -class Command(object): - "Base class for commands" - def __init__(self, verb, verbProg): - self.verb = verb - self.verbProg = verbProg - - @staticmethod - def helpDescription(): - return "" - - def _doCommand(self, player): - pass - - def __call__(self, player ): - print(self.verbProg.capitalize()+"...") - self._doCommand(player) - - -class MoveCommand(Command): - def __init__(self, quals): - super(MoveCommand,self).__init__("MOVE", "moving") - self.direction = quals.direction[0] - - @staticmethod - def helpDescription(): - return """MOVE or GO - go NORTH, SOUTH, EAST, or WEST - (can abbreviate as 'GO N' and 'GO W', or even just 'E' and 'S')""" - - def _doCommand(self, player): - rm = player.room - nextRoom = rm.doors[ - { - "N":0, - "S":1, - "E":2, - "W":3, - }[self.direction] - ] - if nextRoom: - player.moveTo( nextRoom ) - else: - print("Can't go that way.") - - -class TakeCommand(Command): - def __init__(self, quals): - super(TakeCommand,self).__init__("TAKE", "taking") - self.subject = quals.item - - @staticmethod - def helpDescription(): - return "TAKE or PICKUP or PICK UP - pick up an object (but some are deadly)" - - def _doCommand(self, player): - rm = player.room - subj = Item.items[self.subject] - if subj in rm.inv and subj.isVisible: - if subj.isTakeable: - rm.removeItem(subj) - player.take(subj) - else: - print(subj.cantTakeMessage) - else: - print("There is no %s here." % subj) - - -class DropCommand(Command): - def __init__(self, quals): - super(DropCommand,self).__init__("DROP", "dropping") - self.subject = quals.item - - @staticmethod - def helpDescription(): - return "DROP or LEAVE - drop an object (but fragile items may break)" - - def _doCommand(self, player): - rm = player.room - subj = Item.items[self.subject] - if subj in player.inv: - rm.addItem(subj) - player.drop(subj) - else: - print("You don't have %s." % (aOrAn(subj))) - -class InventoryCommand(Command): - def __init__(self, quals): - super(InventoryCommand,self).__init__("INV", "taking inventory") - - @staticmethod - def helpDescription(): - return "INVENTORY or INV or I - lists what items you have" - - def _doCommand(self, player): - print("You have %s." % enumerateItems( player.inv )) - -class LookCommand(Command): - def __init__(self, quals): - super(LookCommand,self).__init__("LOOK", "looking") - - @staticmethod - def helpDescription(): - return "LOOK or L - describes the current room and any objects in it" - - def _doCommand(self, player): - player.room.describe() - -class DoorsCommand(Command): - def __init__(self, quals): - super(DoorsCommand,self).__init__("DOORS", "looking for doors") - - @staticmethod - def helpDescription(): - return "DOORS - display what doors are visible from this room" - - def _doCommand(self, player): - rm = player.room - numDoors = sum([1 for r in rm.doors if r is not None]) - if numDoors == 0: - reply = "There are no doors in any direction." - else: - if numDoors == 1: - reply = "There is a door to the " - else: - reply = "There are doors to the " - doorNames = [ {0:"north", 1:"south", 2:"east", 3:"west"}[i] - for i,d in enumerate(rm.doors) if d is not None ] - #~ print doorNames - reply += enumerateDoors( doorNames ) - reply += "." - print(reply) - -class UseCommand(Command): - def __init__(self, quals): - super(UseCommand,self).__init__("USE", "using") - self.subject = Item.items[quals.usedObj] - if quals.targetObj: - self.target = Item.items[quals.targetObj] - else: - self.target = None - - @staticmethod - def helpDescription(): - return "USE or U - use an object, optionally IN or ON another object" - - def _doCommand(self, player): - rm = player.room - availItems = rm.inv + player.inv - if self.subject in availItems: - if self.subject.isUsable( player, self.target ): - self.subject.useItem( player, self.target ) - else: - print("You can't use that here.") - else: - print("There is no %s here to use." % self.subject) - -class OpenCommand(Command): - def __init__(self, quals): - super(OpenCommand,self).__init__("OPEN", "opening") - self.subject = Item.items[quals.item] - - @staticmethod - def helpDescription(): - return "OPEN or O - open an object" - - def _doCommand(self, player): - rm = player.room - availItems = rm.inv+player.inv - if self.subject in availItems: - if self.subject.isOpenable: - if not self.subject.isOpened: - self.subject.openItem( player ) - else: - print("It's already open.") - else: - print("You can't open that.") - else: - print("There is no %s here to open." % self.subject) - -class CloseCommand(Command): - def __init__(self, quals): - super(CloseCommand,self).__init__("CLOSE", "closing") - self.subject = Item.items[quals.item] - - @staticmethod - def helpDescription(): - return "CLOSE or CL - close an object" - - def _doCommand(self, player): - rm = player.room - availItems = rm.inv+player.inv - if self.subject in availItems: - if self.subject.isOpenable: - if self.subject.isOpened: - self.subject.closeItem( player ) - else: - print("You can't close that, it's not open.") - else: - print("You can't close that.") - else: - print("There is no %s here to close." % self.subject) - -class QuitCommand(Command): - def __init__(self, quals): - super(QuitCommand,self).__init__("QUIT", "quitting") - - @staticmethod - def helpDescription(): - return "QUIT or Q - ends the game" - - def _doCommand(self, player): - print("Ok....") - player.gameOver = True - -class HelpCommand(Command): - def __init__(self, quals): - super(HelpCommand,self).__init__("HELP", "helping") - - @staticmethod - def helpDescription(): - return "HELP or H or ? - displays this help message" - - def _doCommand(self, player): - print("Enter any of the following commands (not case sensitive):") - for cmd in [ - InventoryCommand, - DropCommand, - TakeCommand, - UseCommand, - OpenCommand, - CloseCommand, - MoveCommand, - LookCommand, - DoorsCommand, - QuitCommand, - HelpCommand, - ]: - print(" - %s" % cmd.helpDescription()) - print() - -class AppParseException(ParseException): - pass - -class Parser(object): - def __init__(self): - self.bnf = self.makeBNF() - - def makeBNF(self): - invVerb = oneOf("INV INVENTORY I", caseless=True) - dropVerb = oneOf("DROP LEAVE", caseless=True) - takeVerb = oneOf("TAKE PICKUP", caseless=True) | \ - (CaselessLiteral("PICK") + CaselessLiteral("UP") ) - moveVerb = oneOf("MOVE GO", caseless=True) | empty - useVerb = oneOf("USE U", caseless=True) - openVerb = oneOf("OPEN O", caseless=True) - closeVerb = oneOf("CLOSE CL", caseless=True) - quitVerb = oneOf("QUIT Q", caseless=True) - lookVerb = oneOf("LOOK L", caseless=True) - doorsVerb = CaselessLiteral("DOORS") - helpVerb = oneOf("H HELP ?",caseless=True) - - itemRef = OneOrMore(Word(alphas)).setParseAction( self.validateItemName ) - nDir = oneOf("N NORTH",caseless=True).setParseAction(replaceWith("N")) - sDir = oneOf("S SOUTH",caseless=True).setParseAction(replaceWith("S")) - eDir = oneOf("E EAST",caseless=True).setParseAction(replaceWith("E")) - wDir = oneOf("W WEST",caseless=True).setParseAction(replaceWith("W")) - moveDirection = nDir | sDir | eDir | wDir - - invCommand = invVerb - dropCommand = dropVerb + itemRef("item") - takeCommand = takeVerb + itemRef("item") - useCommand = useVerb + itemRef("usedObj") + \ - Optional(oneOf("IN ON",caseless=True)) + \ - Optional(itemRef,default=None)("targetObj") - openCommand = openVerb + itemRef("item") - closeCommand = closeVerb + itemRef("item") - moveCommand = moveVerb + moveDirection("direction") - quitCommand = quitVerb - lookCommand = lookVerb - doorsCommand = doorsVerb - helpCommand = helpVerb - - # attach command classes to expressions - invCommand.setParseAction(InventoryCommand) - dropCommand.setParseAction(DropCommand) - takeCommand.setParseAction(TakeCommand) - useCommand.setParseAction(UseCommand) - openCommand.setParseAction(OpenCommand) - closeCommand.setParseAction(CloseCommand) - moveCommand.setParseAction(MoveCommand) - quitCommand.setParseAction(QuitCommand) - lookCommand.setParseAction(LookCommand) - doorsCommand.setParseAction(DoorsCommand) - helpCommand.setParseAction(HelpCommand) - - # define parser using all command expressions - return ( invCommand | - useCommand | - openCommand | - closeCommand | - dropCommand | - takeCommand | - moveCommand | - lookCommand | - doorsCommand | - helpCommand | - quitCommand )("command") + LineEnd() - - def validateItemName(self,s,l,t): - iname = " ".join(t) - if iname not in Item.items: - raise AppParseException(s,l,"No such item '%s'." % iname) - return iname - - def parseCmd(self, cmdstr): - try: - ret = self.bnf.parseString(cmdstr) - return ret - except AppParseException as pe: - print(pe.msg) - except ParseException as pe: - print(random.choice([ "Sorry, I don't understand that.", - "Huh?", - "Excuse me?", - "???", - "What?" ] )) - -class Player(object): - def __init__(self, name): - self.name = name - self.gameOver = False - self.inv = [] - - def moveTo(self, rm): - self.room = rm - rm.enter(self) - if self.gameOver: - if rm.desc: - rm.describe() - print("Game over!") - else: - rm.describe() - - def take(self,it): - if it.isDeadly: - print("Aaaagh!...., the %s killed me!" % it) - self.gameOver = True - else: - self.inv.append(it) - - def drop(self,it): - self.inv.remove(it) - if it.isFragile: - it.breakItem() - - -def createRooms( rm ): - """ - create rooms, using multiline string showing map layout - string contains symbols for the following: - A-Z, a-z indicate rooms, and rooms will be stored in a dictionary by - reference letter - -, | symbols indicate connection between rooms - <, >, ^, . symbols indicate one-way connection between rooms - """ - # start with empty dictionary of rooms - ret = {} - - # look for room symbols, and initialize dictionary - # - exit room is always marked 'Z' - for c in rm: - if c in string.ascii_letters: - if c != "Z": - ret[c] = Room(c) - else: - ret[c] = Exit() - - # scan through input string looking for connections between rooms - rows = rm.split("\n") - for row,line in enumerate(rows): - for col,c in enumerate(line): - if c in string.ascii_letters: - room = ret[c] - n = None - s = None - e = None - w = None - - # look in neighboring cells for connection symbols (must take - # care to guard that neighboring cells exist before testing - # contents) - if col > 0 and line[col-1] in "<-": - other = line[col-2] - w = ret[other] - if col < len(line)-1 and line[col+1] in "->": - other = line[col+2] - e = ret[other] - if row > 1 and col < len(rows[row-1]) and rows[row-1][col] in '|^': - other = rows[row-2][col] - n = ret[other] - if row < len(rows)-1 and col < len(rows[row+1]) and rows[row+1][col] in '|.': - other = rows[row+2][col] - s = ret[other] - - # set connections to neighboring rooms - room.doors=[n,s,e,w] - - return ret - -# put items in rooms -def putItemInRoom(i,r): - if isinstance(r,str): - r = rooms[r] - r.addItem( Item.items[i] ) - -def playGame(p,startRoom): - # create parser - parser = Parser() - p.moveTo( startRoom ) - while not p.gameOver: - cmdstr = input(">> ") - cmd = parser.parseCmd(cmdstr) - if cmd is not None: - cmd.command( p ) - print() - print("You ended the game with:") - for i in p.inv: - print(" -", aOrAn(i)) - - -#==================== -# start game definition -roomMap = """ - d-Z - | - f-c-e - . | - q'+"'")) | ('u' + Word(hexnums, exact=4)) | Word(printables, exact=1)) -LITERAL_CHAR = ESC | ~(Literal("'") | Literal('\\')) + Word(printables, exact=1) -CHAR_LITERAL = Suppress("'") + LITERAL_CHAR + Suppress("'") -STRING_LITERAL = Suppress("'") + Combine(OneOrMore(LITERAL_CHAR)) + Suppress("'") -DOUBLE_QUOTE_STRING_LITERAL = '"' + ZeroOrMore(LITERAL_CHAR) + '"' -DOUBLE_ANGLE_STRING_LITERAL = '<<' + ZeroOrMore(Word(printables, exact=1)) + '>>' -TOKEN_REF = Word(alphas.upper(), alphanums+'_') -RULE_REF = Word(alphas.lower(), alphanums+'_') -ACTION_ESC = (Suppress("\\") + Suppress("'")) | Suppress('\\"') | Suppress('\\') + (~(Literal("'") | Literal('"')) + Word(printables, exact=1)) -ACTION_CHAR_LITERAL = Suppress("'") + (ACTION_ESC | ~(Literal('\\') | Literal("'")) + Word(printables, exact=1)) + Suppress("'") -ACTION_STRING_LITERAL = Suppress('"') + ZeroOrMore(ACTION_ESC | ~(Literal('\\') | Literal('"')) + Word(printables, exact=1)) + Suppress('"') -SRC = Suppress('src') + ACTION_STRING_LITERAL("file") + INT("line") -id = TOKEN_REF | RULE_REF -SL_COMMENT = Suppress('//') + Suppress('$ANTLR') + SRC | ZeroOrMore(~EOL + Word(printables)) + EOL -ML_COMMENT = cStyleComment -WS = OneOrMore(Suppress(' ') | Suppress('\t') | (Optional(Suppress('\r')) + Literal('\n'))) -WS_LOOP = ZeroOrMore(SL_COMMENT | ML_COMMENT) -NESTED_ARG_ACTION = Forward() -NESTED_ARG_ACTION << Suppress('[') + ZeroOrMore(NESTED_ARG_ACTION | ACTION_STRING_LITERAL | ACTION_CHAR_LITERAL) + Suppress(']') -ARG_ACTION = NESTED_ARG_ACTION -NESTED_ACTION = Forward() -NESTED_ACTION << Suppress('{') + ZeroOrMore(NESTED_ACTION | SL_COMMENT | ML_COMMENT | ACTION_STRING_LITERAL | ACTION_CHAR_LITERAL) + Suppress('}') -ACTION = NESTED_ACTION + Optional('?') -SCOPE = Suppress('scope') -OPTIONS = Suppress('options') + Suppress('{') # + WS_LOOP + Suppress('{') -TOKENS = Suppress('tokens') + Suppress('{') # + WS_LOOP + Suppress('{') -FRAGMENT = 'fragment'; -TREE_BEGIN = Suppress('^(') -ROOT = Suppress('^') -BANG = Suppress('!') -RANGE = Suppress('..') -REWRITE = Suppress('->') - -# General Parser Definitions - -# Grammar heading -optionValue = id | STRING_LITERAL | CHAR_LITERAL | INT | Literal('*').setName("s") - -option = Group(id("id") + Suppress('=') + optionValue("value"))("option") -optionsSpec = OPTIONS + Group(OneOrMore(option + Suppress(';')))("options") + Suppress('}') -tokenSpec = Group(TOKEN_REF("token_ref") + (Suppress('=') + (STRING_LITERAL | CHAR_LITERAL)("lit")))("token") + Suppress(';') -tokensSpec = TOKENS + Group(OneOrMore(tokenSpec))("tokens") + Suppress('}') -attrScope = Suppress('scope') + id + ACTION -grammarType = Keyword('lexer') + Keyword('parser') + Keyword('tree') -actionScopeName = id | Keyword('lexer')("l") | Keyword('parser')("p") -action = Suppress('@') + Optional(actionScopeName + Suppress('::')) + id + ACTION - -grammarHeading = Optional(ML_COMMENT("ML_COMMENT")) + Optional(grammarType) + Suppress('grammar') + id("grammarName") + Suppress(';') + Optional(optionsSpec) + Optional(tokensSpec) + ZeroOrMore(attrScope) + ZeroOrMore(action) - -modifier = Keyword('protected') | Keyword('public') | Keyword('private') | Keyword('fragment') -ruleAction = Suppress('@') + id + ACTION -throwsSpec = Suppress('throws') + delimitedList(id) -ruleScopeSpec = (Suppress('scope') + ACTION) | (Suppress('scope') + delimitedList(id) + Suppress(';')) | (Suppress('scope') + ACTION + Suppress('scope') + delimitedList(id) + Suppress(';')) -unary_op = oneOf("^ !") -notTerminal = CHAR_LITERAL | TOKEN_REF | STRING_LITERAL -terminal = (CHAR_LITERAL | TOKEN_REF + Optional(ARG_ACTION) | STRING_LITERAL | '.') + Optional(unary_op) -block = Forward() -notSet = Suppress('~') + (notTerminal | block) -rangeNotPython = CHAR_LITERAL("c1") + RANGE + CHAR_LITERAL("c2") -atom = Group(rangeNotPython + Optional(unary_op)("op")) | terminal | (notSet + Optional(unary_op)("op")) | (RULE_REF + Optional(ARG_ACTION("arg")) + Optional(unary_op)("op")) -element = Forward() -treeSpec = Suppress('^(') + element*(2,) + Suppress(')') -ebnfSuffix = oneOf("? * +") -ebnf = block + Optional(ebnfSuffix("op") | '=>') -elementNoOptionSpec = (id("result_name") + oneOf('= +=')("labelOp") + atom("atom") + Optional(ebnfSuffix)) | (id("result_name") + oneOf('= +=')("labelOp") + block + Optional(ebnfSuffix)) | atom("atom") + Optional(ebnfSuffix) | ebnf | ACTION | (treeSpec + Optional(ebnfSuffix)) # | SEMPRED ( '=>' -> GATED_SEMPRED | -> SEMPRED ) -element << Group(elementNoOptionSpec)("element") -alternative = Group(Group(OneOrMore(element))("elements")) # Do not ask me why group is needed twice... seems like the xml that you see is not always the real structure? -rewrite = Optional(Literal('TODO REWRITE RULES TODO')) -block << Suppress('(') + Optional(Optional(optionsSpec("opts")) + Suppress(':')) + Group(alternative('a1') + rewrite + Group(ZeroOrMore(Suppress('|') + alternative('a2') + rewrite))("alternatives"))("block") + Suppress(')') -altList = alternative('a1') + rewrite + Group(ZeroOrMore(Suppress('|') + alternative('a2') + rewrite))("alternatives") -exceptionHandler = Suppress('catch') + ARG_ACTION + ACTION -finallyClause = Suppress('finally') + ACTION -exceptionGroup = (OneOrMore(exceptionHandler) + Optional(finallyClause)) | finallyClause - -ruleHeading = Optional(ML_COMMENT)("ruleComment") + Optional(modifier)("modifier") + id("ruleName") + Optional("!") + Optional(ARG_ACTION("arg")) + Optional(Suppress('returns') + ARG_ACTION("rt")) + Optional(throwsSpec) + Optional(optionsSpec) + Optional(ruleScopeSpec) + ZeroOrMore(ruleAction) -rule = Group(ruleHeading + Suppress(':') + altList + Suppress(';') + Optional(exceptionGroup))("rule") - -grammarDef = grammarHeading + Group(OneOrMore(rule))("rules") - -def grammar(): - return grammarDef - -def __antlrAlternativesConverter(pyparsingRules, antlrBlock): - rule = None - if hasattr(antlrBlock, 'alternatives') and antlrBlock.alternatives != '' and len(antlrBlock.alternatives) > 0: - alternatives = [] - alternatives.append(__antlrAlternativeConverter(pyparsingRules, antlrBlock.a1)) - for alternative in antlrBlock.alternatives: - alternatives.append(__antlrAlternativeConverter(pyparsingRules, alternative)) - rule = MatchFirst(alternatives)("anonymous_or") - elif hasattr(antlrBlock, 'a1') and antlrBlock.a1 != '': - rule = __antlrAlternativeConverter(pyparsingRules, antlrBlock.a1) - else: - raise Exception('Not yet implemented') - assert rule != None - return rule - -def __antlrAlternativeConverter(pyparsingRules, antlrAlternative): - elementList = [] - for element in antlrAlternative.elements: - rule = None - if hasattr(element.atom, 'c1') and element.atom.c1 != '': - regex = r'['+str(element.atom.c1[0])+'-'+str(element.atom.c2[0]+']') - rule = Regex(regex)("anonymous_regex") - elif hasattr(element, 'block') and element.block != '': - rule = __antlrAlternativesConverter(pyparsingRules, element.block) - else: - ruleRef = element.atom - assert ruleRef in pyparsingRules - rule = pyparsingRules[element.atom](element.atom) - if hasattr(element, 'op') and element.op != '': - if element.op == '+': - rule = Group(OneOrMore(rule))("anonymous_one_or_more") - elif element.op == '*': - rule = Group(ZeroOrMore(rule))("anonymous_zero_or_more") - elif element.op == '?': - rule = Optional(rule) - else: - raise Exception('rule operator not yet implemented : ' + element.op) - rule = rule - elementList.append(rule) - if len(elementList) > 1: - rule = Group(And(elementList))("anonymous_and") - else: - rule = elementList[0] - assert rule != None - return rule - -def __antlrRuleConverter(pyparsingRules, antlrRule): - rule = None - rule = __antlrAlternativesConverter(pyparsingRules, antlrRule) - assert rule != None - rule(antlrRule.ruleName) - return rule - -def antlrConverter(antlrGrammarTree): - pyparsingRules = {} - antlrTokens = {} - for antlrToken in antlrGrammarTree.tokens: - antlrTokens[antlrToken.token_ref] = antlrToken.lit - for antlrTokenName, antlrToken in list(antlrTokens.items()): - pyparsingRules[antlrTokenName] = Literal(antlrToken) - antlrRules = {} - for antlrRule in antlrGrammarTree.rules: - antlrRules[antlrRule.ruleName] = antlrRule - pyparsingRules[antlrRule.ruleName] = Forward() # antlr is a top down grammar - for antlrRuleName, antlrRule in list(antlrRules.items()): - pyparsingRule = __antlrRuleConverter(pyparsingRules, antlrRule) - assert pyparsingRule != None - pyparsingRules[antlrRuleName] << pyparsingRule - return pyparsingRules - -if __name__ == "__main__": - - text = """grammar SimpleCalc; - -options { - language = Python; -} - -tokens { - PLUS = '+' ; - MINUS = '-' ; - MULT = '*' ; - DIV = '/' ; -} - -/*------------------------------------------------------------------ - * PARSER RULES - *------------------------------------------------------------------*/ - -expr : term ( ( PLUS | MINUS ) term )* ; - -term : factor ( ( MULT | DIV ) factor )* ; - -factor : NUMBER ; - - -/*------------------------------------------------------------------ - * LEXER RULES - *------------------------------------------------------------------*/ - -NUMBER : (DIGIT)+ ; - -/* WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ; */ - -fragment DIGIT : '0'..'9' ; - -""" - - grammar().validate() - antlrGrammarTree = grammar().parseString(text) - print(antlrGrammarTree.asXML("antlrGrammarTree")) - pyparsingRules = antlrConverter(antlrGrammarTree) - pyparsingRule = pyparsingRules["expr"] - pyparsingTree = pyparsingRule.parseString("2 - 5 * 42 + 7 / 25") - print(pyparsingTree.asXML("pyparsingTree")) diff --git a/examples/antlr_grammar_tests.py b/examples/antlr_grammar_tests.py deleted file mode 100644 index c2c3d8d..0000000 --- a/examples/antlr_grammar_tests.py +++ /dev/null @@ -1,87 +0,0 @@ -''' -Created on 4 sept. 2010 - -@author: luca - -Submitted by Luca DallOlio, September, 2010 -''' -import unittest -import antlr_grammar - -class Test(unittest.TestCase): - - - def testOptionsSpec(self): - text = """options { - language = Python; - }""" - antlr_grammar.optionsSpec.parseString(text) #@UndefinedVariable - - def testTokensSpec(self): - text = """tokens { - PLUS = '+' ; - MINUS = '-' ; - MULT = '*' ; - DIV = '/' ; - }""" - antlr_grammar.tokensSpec.parseString(text) #@UndefinedVariable - - def testBlock(self): - text = """( PLUS | MINUS )""" - antlr_grammar.block.parseString(text) #@UndefinedVariable - - def testRule(self): - text = """expr : term ( ( PLUS | MINUS ) term )* ;""" - antlr_grammar.rule.parseString(text) #@UndefinedVariable - - def testLexerRule(self): - text = """fragment DIGIT : '0'..'9' ;""" - antlr_grammar.rule.parseString(text) #@UndefinedVariable - - def testLexerRule2(self): - text = """WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;""" - #antlr_grammar.rule.parseString(text) #@UndefinedVariable - - def testGrammar(self): - text = """grammar SimpleCalc; - -options { - language = Python; -} - -tokens { - PLUS = '+' ; - MINUS = '-' ; - MULT = '*' ; - DIV = '/' ; -} - -/*------------------------------------------------------------------ - * PARSER RULES - *------------------------------------------------------------------*/ - -expr : term ( ( PLUS | MINUS ) term )* ; - -term : factor ( ( MULT | DIV ) factor )* ; - -factor : NUMBER ; - - -/*------------------------------------------------------------------ - * LEXER RULES - *------------------------------------------------------------------*/ - -NUMBER : (DIGIT)+ ; - -/* WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ; */ - -fragment DIGIT : '0'..'9' ;""" - antlrGrammarTree = antlr_grammar.grammarDef.parseString(text) #@UndefinedVariable - pyparsingRules = antlr_grammar.antlrConverter(antlrGrammarTree) - pyparsingRule = pyparsingRules["expr"] - pyparsingTree = pyparsingRule.parseString("2 - 5 * 42 + 7 / 25") - self.assertNotEqual(None, pyparsingTree) - -if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testOptionsSpec'] - unittest.main() \ No newline at end of file diff --git a/examples/apicheck.py b/examples/apicheck.py deleted file mode 100644 index 7bca41a..0000000 --- a/examples/apicheck.py +++ /dev/null @@ -1,58 +0,0 @@ -# apicheck.py -# A simple source code scanner for finding patterns of the form -# [ procname1 $arg1 $arg2 ] -# and verifying the number of arguments -# -# Copyright (c) 2004-2016, Paul McGuire -# - -from pyparsing import * - -# define punctuation and simple tokens for locating API calls -LBRACK,RBRACK,LBRACE,RBRACE = map(Suppress,"[]{}") -ident = Word(alphas,alphanums+"_") | QuotedString("{",endQuoteChar="}") -arg = "$" + ident - -# define an API call with a specific number of arguments - using '-' -# will ensure that after matching procname, an incorrect number of args will -# raise a ParseSyntaxException, which will interrupt the scanString -def apiProc(name, numargs): - return LBRACK + Keyword(name)("procname") - arg*numargs + RBRACK - -# create an apiReference, listing all API functions to be scanned for, and -# their respective number of arguments. Beginning the overall expression -# with FollowedBy allows us to quickly rule out non-api calls while scanning, -# since all of the api calls begin with a "[" -apiRef = FollowedBy("[") + MatchFirst([ - apiProc("procname1", 2), - apiProc("procname2", 1), - apiProc("procname3", 2), - ]) - -test = """[ procname1 $par1 $par2 ] - other code here - [ procname1 $par1 $par2 $par3 ] - more code here - [ procname1 $par1 ] - [ procname3 ${arg with spaces} $par2 ]""" - - -# now explicitly iterate through the scanner using next(), so that -# we can trap ParseSyntaxException's that would be raised due to -# an incorrect number of arguments. If an exception does occur, -# then see how we reset the input text and scanner to advance to the -# next line of source code -api_scanner = apiRef.scanString(test) -while 1: - try: - t,s,e = next(api_scanner) - print("found %s on line %d" % (t.procname, lineno(s,test))) - except ParseSyntaxException as pe: - print("invalid arg count on line", pe.lineno) - print(pe.lineno,':',pe.line) - # reset api scanner to start after this exception location - test = "\n"*(pe.lineno-1)+test[pe.loc+1:] - api_scanner = apiRef.scanString(test) - except StopIteration: - break - diff --git a/examples/btpyparse.py b/examples/btpyparse.py deleted file mode 100644 index 4fbbac8..0000000 --- a/examples/btpyparse.py +++ /dev/null @@ -1,129 +0,0 @@ -""" Pyparsing parser for BibTeX files - -A standalone parser using pyparsing. - -pyparsing has a simple and expressive syntax so the grammar is easy to read and -write. - -Submitted by Matthew Brett, 2010 - -Simplified BSD license -""" - -from pyparsing import (Regex, Suppress, ZeroOrMore, Group, Optional, Forward, - SkipTo, CaselessLiteral, Dict) - - -class Macro(object): - """ Class to encapsulate undefined macro references """ - def __init__(self, name): - self.name = name - def __repr__(self): - return 'Macro("%s")' % self.name - def __eq__(self, other): - return self.name == other.name - def __ne__(self, other): - return self.name != other.name - - -# Character literals -LCURLY,RCURLY,LPAREN,RPAREN,QUOTE,COMMA,AT,EQUALS,HASH = map(Suppress,'{}()",@=#') - - -def bracketed(expr): - """ Return matcher for `expr` between curly brackets or parentheses """ - return (LPAREN + expr + RPAREN) | (LCURLY + expr + RCURLY) - - -# Define parser components for strings (the hard bit) -chars_no_curly = Regex(r"[^{}]+") -chars_no_curly.leaveWhitespace() -chars_no_quotecurly = Regex(r'[^"{}]+') -chars_no_quotecurly.leaveWhitespace() -# Curly string is some stuff without curlies, or nested curly sequences -curly_string = Forward() -curly_item = Group(curly_string) | chars_no_curly -curly_string << LCURLY + ZeroOrMore(curly_item) + RCURLY -# quoted string is either just stuff within quotes, or stuff within quotes, within -# which there is nested curliness -quoted_item = Group(curly_string) | chars_no_quotecurly -quoted_string = QUOTE + ZeroOrMore(quoted_item) + QUOTE - -# Numbers can just be numbers. Only integers though. -number = Regex('[0-9]+') - -# Basis characters (by exclusion) for variable / field names. The following -# list of characters is from the btparse documentation -any_name = Regex('[^\\s"#%\'(),={}]+') - -# btparse says, and the test bibs show by experiment, that macro and field names -# cannot start with a digit. In fact entry type names cannot start with a digit -# either (see tests/bibs). Cite keys can start with a digit -not_digname = Regex('[^\\d\\s"#%\'(),={}][^\\s"#%\'(),={}]*') - -# Comment comments out to end of line -comment = (AT + CaselessLiteral('comment') + - Regex(r"[\s{(].*").leaveWhitespace()) - -# The name types with their digiteyness -not_dig_lower = not_digname.copy().setParseAction(lambda t: t[0].lower()) -macro_def = not_dig_lower.copy() -macro_ref = not_dig_lower.copy().setParseAction(lambda t : Macro(t[0].lower())) -field_name = not_dig_lower.copy() -# Spaces in names mean they cannot clash with field names -entry_type = not_dig_lower('entry_type') -cite_key = any_name('cite_key') -# Number has to be before macro name -string = (number | macro_ref | quoted_string | curly_string) - -# There can be hash concatenation -field_value = string + ZeroOrMore(HASH + string) -field_def = Group(field_name + EQUALS + field_value) -entry_contents = Dict(ZeroOrMore(field_def + COMMA) + Optional(field_def)) - -# Entry is surrounded either by parentheses or curlies -entry = (AT + entry_type + bracketed(cite_key + COMMA + entry_contents)) - -# Preamble is a macro-like thing with no name -preamble = AT + CaselessLiteral('preamble') + bracketed(field_value) - -# Macros (aka strings) -macro_contents = macro_def + EQUALS + field_value -macro = AT + CaselessLiteral('string') + bracketed(macro_contents) - -# Implicit comments -icomment = SkipTo('@').setParseAction(lambda t : t.insert(0, 'icomment')) - -# entries are last in the list (other than the fallback) because they have -# arbitrary start patterns that would match comments, preamble or macro -definitions = Group(comment | - preamble | - macro | - entry | - icomment) - -# Start symbol -bibfile = ZeroOrMore(definitions) - - -def parse_str(str): - return bibfile.parseString(str) - - -if __name__ == '__main__': - # Run basic test - txt = """ -Some introductory text -(implicit comment) - -@ARTICLE{Authors2011, - author = {First Author and Second Author and Third Author}, - title = {An article about {S}omething}, - journal = "Journal of Articles", - year = {2011}, - volume = {16}, - pages = {1140--1141}, - number = {2} -} -""" - print('\n\n'.join(defn.dump() for defn in parse_str(txt))) diff --git a/examples/builtin_parse_action_demo.py b/examples/builtin_parse_action_demo.py deleted file mode 100644 index 3ec6af8..0000000 --- a/examples/builtin_parse_action_demo.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# builtin_parse_action_demo.py -# Copyright, 2012 - Paul McGuire -# -# Simple example of using builtin functions as parse actions. -# - -from pyparsing import * - -integer = Word(nums).setParseAction(lambda t : int(t[0])) - -# make an expression that will match a list of ints (which -# will be converted to actual ints by the parse action attached -# to integer) -nums = OneOrMore(integer) - - -test = "2 54 34 2 211 66 43 2 0" -print(test) - -# try each of these builtins as parse actions -for fn in (sum, max, min, len, sorted, reversed, list, tuple, set, any, all): - fn_name = fn.__name__ - if fn is reversed: - # reversed returns an iterator, we really want to show the list of items - fn = lambda x : list(reversed(x)) - - # show how each builtin works as a free-standing parse action - print(fn_name, nums.setParseAction(fn).parseString(test)) diff --git a/examples/cLibHeader.py b/examples/cLibHeader.py deleted file mode 100644 index bb98521..0000000 --- a/examples/cLibHeader.py +++ /dev/null @@ -1,25 +0,0 @@ -# -# cLibHeader.py -# -# A simple parser to extract API doc info from a C header file -# -# Copyright, 2012 - Paul McGuire -# - -from pyparsing import Word, alphas, alphanums, Combine, oneOf, Optional, delimitedList, Group, Keyword - -testdata = """ - int func1(float *vec, int len, double arg1); - int func2(float **arr, float *vec, int len, double arg1, double arg2); - """ - -ident = Word(alphas, alphanums + "_") -vartype = Combine( oneOf("float double int char") + Optional(Word("*")), adjacent = False) -arglist = delimitedList(Group(vartype("type") + ident("name"))) - -functionCall = Keyword("int") + ident("name") + "(" + arglist("args") + ")" + ";" - -for fn,s,e in functionCall.scanString(testdata): - print(fn.name) - for a in fn.args: - print(" - %(name)s (%(type)s)" % a) diff --git a/examples/chemicalFormulas.py b/examples/chemicalFormulas.py deleted file mode 100644 index ce66afd..0000000 --- a/examples/chemicalFormulas.py +++ /dev/null @@ -1,67 +0,0 @@ -# chemicalFormulas.py -# -# Copyright (c) 2003, Paul McGuire -# - -from pyparsing import Word, Optional, OneOrMore, Group, ParseException, Regex -from pyparsing import alphas - -atomicWeight = { - "O" : 15.9994, - "H" : 1.00794, - "Na" : 22.9897, - "Cl" : 35.4527, - "C" : 12.0107 - } - -def test( bnf, strg, fn=None ): - try: - print(strg,"->", bnf.parseString( strg ), end=' ') - except ParseException as pe: - print(pe) - else: - if fn != None: - print(fn( bnf.parseString( strg ) )) - else: - print() - -digits = "0123456789" - -# Version 1 -element = Regex("A[cglmrstu]|B[aehikr]?|C[adeflmorsu]?|D[bsy]|" - "E[rsu]|F[emr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airu]|" - "M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|" - "S[bcegimnr]?|T[abcehilm]|U(u[bhopqst])?|V|W|Xe|Yb?|Z[nr]") - -element = Word( alphas.upper(), alphas.lower(), max=2) -elementRef = Group( element + Optional( Word( digits ), default="1" ) ) -formula = OneOrMore( elementRef ) - -fn = lambda elemList : sum(atomicWeight[elem]*int(qty) for elem,qty in elemList) -test( formula, "H2O", fn ) -test( formula, "C6H5OH", fn ) -test( formula, "NaCl", fn ) -print() - -# Version 2 - access parsed items by field name -elementRef = Group( element("symbol") + Optional( Word( digits ), default="1" )("qty") ) -formula = OneOrMore( elementRef ) - -fn = lambda elemList : sum(atomicWeight[elem.symbol]*int(elem.qty) for elem in elemList) -test( formula, "H2O", fn ) -test( formula, "C6H5OH", fn ) -test( formula, "NaCl", fn ) -print() - -# Version 3 - convert integers during parsing process -integer = Word( digits ).setParseAction(lambda t:int(t[0])) -elementRef = Group( element("symbol") + Optional( integer, default=1 )("qty") ) -formula = OneOrMore( elementRef ) - -fn = lambda elemList : sum(atomicWeight[elem.symbol]*elem.qty for elem in elemList) -test( formula, "H2O", fn ) -test( formula, "C6H5OH", fn ) -test( formula, "NaCl", fn ) - - - diff --git a/examples/commasep.py b/examples/commasep.py deleted file mode 100644 index 3ce8546..0000000 --- a/examples/commasep.py +++ /dev/null @@ -1,26 +0,0 @@ -# commasep.py -# -# comma-separated list example, to illustrate the advantages of using -# the pyparsing commaSeparatedList as opposed to string.split(","): -# - leading and trailing whitespace is implicitly trimmed from list elements -# - list elements can be quoted strings, which can safely contain commas without breaking -# into separate elements -# -# Copyright (c) 2004-2016, Paul McGuire -# - -from pyparsing import commaSeparatedList - -testData = [ - "a,b,c,100.2,,3", - "d, e, j k , m ", - "'Hello, World', f, g , , 5.1,x", - "John Doe, 123 Main St., Cleveland, Ohio", - "Jane Doe, 456 St. James St., Los Angeles , California ", - "", - ] - -for line in testData: - print(commaSeparatedList.parseString(line)) - print(line.split(",")) - print() diff --git a/examples/configParse.py b/examples/configParse.py deleted file mode 100644 index 769249c..0000000 --- a/examples/configParse.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# configparse.py -# -# an example of using the parsing module to be able to process a .INI configuration file -# -# Copyright (c) 2003, Paul McGuire -# - -from pyparsing import \ - Literal, Word, ZeroOrMore, Group, Dict, Optional, \ - printables, ParseException, restOfLine, empty -import pprint - - -inibnf = None -def inifile_BNF(): - global inibnf - - if not inibnf: - - # punctuation - lbrack = Literal("[").suppress() - rbrack = Literal("]").suppress() - equals = Literal("=").suppress() - semi = Literal(";") - - comment = semi + Optional( restOfLine ) - - nonrbrack = "".join( [ c for c in printables if c != "]" ] ) + " \t" - nonequals = "".join( [ c for c in printables if c != "=" ] ) + " \t" - - sectionDef = lbrack + Word( nonrbrack ) + rbrack - keyDef = ~lbrack + Word( nonequals ) + equals + empty + restOfLine - # strip any leading or trailing blanks from key - def stripKey(tokens): - tokens[0] = tokens[0].strip() - keyDef.setParseAction(stripKey) - - # using Dict will allow retrieval of named data fields as attributes of the parsed results - inibnf = Dict( ZeroOrMore( Group( sectionDef + Dict( ZeroOrMore( Group( keyDef ) ) ) ) ) ) - - inibnf.ignore( comment ) - - return inibnf - - -pp = pprint.PrettyPrinter(2) - -def test( strng ): - print(strng) - try: - iniFile = open(strng) - iniData = "".join( iniFile.readlines() ) - bnf = inifile_BNF() - tokens = bnf.parseString( iniData ) - pp.pprint( tokens.asList() ) - - except ParseException as err: - print(err.line) - print(" "*(err.column-1) + "^") - print(err) - - iniFile.close() - print() - return tokens - -if __name__ == "__main__": - ini = test("setup.ini") - print("ini['Startup']['modemid'] =", ini['Startup']['modemid']) - print("ini.Startup =", ini.Startup) - print("ini.Startup.modemid =", ini.Startup.modemid) - diff --git a/examples/cpp_enum_parser.py b/examples/cpp_enum_parser.py deleted file mode 100644 index cd8f525..0000000 --- a/examples/cpp_enum_parser.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# cpp_enum_parser.py -# -# Posted by Mark Tolonen on comp.lang.python in August, 2009, -# Used with permission. -# -# Parser that scans through C or C++ code for enum definitions, and -# generates corresponding Python constant definitions. -# -# - -from pyparsing import * -# sample string with enums and other stuff -sample = ''' - stuff before - enum hello { - Zero, - One, - Two, - Three, - Five=5, - Six, - Ten=10 - }; - in the middle - enum blah - { - alpha, - beta, - gamma = 10 , - zeta = 50 - }; - at the end - ''' - -# syntax we don't want to see in the final parse tree -LBRACE,RBRACE,EQ,COMMA = map(Suppress,"{}=,") -_enum = Suppress('enum') -identifier = Word(alphas,alphanums+'_') -integer = Word(nums) -enumValue = Group(identifier('name') + Optional(EQ + integer('value'))) -enumList = Group(enumValue + ZeroOrMore(COMMA + enumValue)) -enum = _enum + identifier('enum') + LBRACE + enumList('names') + RBRACE - -# find instances of enums ignoring other syntax -for item,start,stop in enum.scanString(sample): - id = 0 - for entry in item.names: - if entry.value != '': - id = int(entry.value) - print('%s_%s = %d' % (item.enum.upper(),entry.name.upper(),id)) - id += 1 diff --git a/examples/datetimeParseActions.py b/examples/datetimeParseActions.py deleted file mode 100644 index e42d2c6..0000000 --- a/examples/datetimeParseActions.py +++ /dev/null @@ -1,68 +0,0 @@ -# parseActions.py -# -# A sample program a parser to match a date string of the form "YYYY/MM/DD", -# and return it as a datetime, or raise an exception if not a valid date. -# -# Copyright 2012, Paul T. McGuire -# -from datetime import datetime -from pyparsing import * - -# define an integer string, and a parse action to convert it -# to an integer at parse time -integer = Word(nums).setName("integer") -def convertToInt(tokens): - # no need to test for validity - we can't get here - # unless tokens[0] contains all numeric digits - return int(tokens[0]) -integer.setParseAction(convertToInt) -# or can be written as one line as -#integer = Word(nums).setParseAction(lambda t: int(t[0])) - -# define a pattern for a year/month/day date -date_expr = integer('year') + '/' + integer('month') + '/' + integer('day') -date_expr.ignore(pythonStyleComment) - -def convertToDatetime(s,loc,tokens): - try: - # note that the year, month, and day fields were already - # converted to ints from strings by the parse action defined - # on the integer expression above - return datetime(tokens.year, tokens.month, tokens.day).date() - except Exception as ve: - errmsg = "'%s/%s/%s' is not a valid date, %s" % \ - (tokens.year, tokens.month, tokens.day, ve) - raise ParseException(s, loc, errmsg) -date_expr.setParseAction(convertToDatetime) - - -date_expr.runTests("""\ - 2000/1/1 - - # invalid month - 2000/13/1 - - # 1900 was not a leap year - 1900/2/29 - - # but 2000 was - 2000/2/29 - """) - - -# if dates conform to ISO8601, use definitions in pyparsing_common -date_expr = pyparsing_common.iso8601_date.setParseAction(pyparsing_common.convertToDate()) -date_expr.ignore(pythonStyleComment) - -date_expr.runTests("""\ - 2000-01-01 - - # invalid month - 2000-13-01 - - # 1900 was not a leap year - 1900-02-29 - - # but 2000 was - 2000-02-29 - """) \ No newline at end of file diff --git a/examples/deltaTime.py b/examples/deltaTime.py deleted file mode 100644 index e38da00..0000000 --- a/examples/deltaTime.py +++ /dev/null @@ -1,208 +0,0 @@ -# deltaTime.py -# -# Parser to convert a conversational time reference such as "in a minute" or -# "noon tomorrow" and convert it to a Python datetime. The returned -# ParseResults object contains the results name "timeOffset" containing -# the timedelta, and "calculatedTime" containing the computed time relative -# to datetime.now(). -# -# Copyright 2010, by Paul McGuire -# - -from datetime import datetime, timedelta -from pyparsing import * -import calendar - -__all__ = ["nlTimeExpression"] - -# string conversion parse actions -def convertToTimedelta(toks): - unit = toks.timeunit.lower().rstrip("s") - td = { - 'week' : timedelta(7), - 'day' : timedelta(1), - 'hour' : timedelta(0,0,0,0,0,1), - 'minute' : timedelta(0,0,0,0,1), - 'second' : timedelta(0,1), - }[unit] - if toks.qty: - td *= int(toks.qty) - if toks.dir: - td *= toks.dir - toks["timeOffset"] = td - -def convertToDay(toks): - now = datetime.now() - if "wkdayRef" in toks: - todaynum = now.weekday() - daynames = [n.lower() for n in calendar.day_name] - nameddaynum = daynames.index(toks.wkdayRef.day.lower()) - if toks.wkdayRef.dir > 0: - daydiff = (nameddaynum + 7 - todaynum) % 7 - else: - daydiff = -((todaynum + 7 - nameddaynum) % 7) - toks["absTime"] = datetime(now.year, now.month, now.day)+timedelta(daydiff) - else: - name = toks.name.lower() - toks["absTime"] = { - "now" : now, - "today" : datetime(now.year, now.month, now.day), - "yesterday" : datetime(now.year, now.month, now.day)+timedelta(-1), - "tomorrow" : datetime(now.year, now.month, now.day)+timedelta(+1), - }[name] - -def convertToAbsTime(toks): - now = datetime.now() - if "dayRef" in toks: - day = toks.dayRef.absTime - day = datetime(day.year, day.month, day.day) - else: - day = datetime(now.year, now.month, now.day) - if "timeOfDay" in toks: - if isinstance(toks.timeOfDay,str): - timeOfDay = { - "now" : timedelta(0, (now.hour*60+now.minute)*60+now.second, now.microsecond), - "noon" : timedelta(0,0,0,0,0,12), - "midnight" : timedelta(), - }[toks.timeOfDay] - else: - hhmmss = toks.timeparts - if hhmmss.miltime: - hh,mm = hhmmss.miltime - ss = 0 - else: - hh,mm,ss = (hhmmss.HH % 12), hhmmss.MM, hhmmss.SS - if not mm: mm = 0 - if not ss: ss = 0 - if toks.timeOfDay.ampm == 'pm': - hh += 12 - timeOfDay = timedelta(0, (hh*60+mm)*60+ss, 0) - else: - timeOfDay = timedelta(0, (now.hour*60+now.minute)*60+now.second, now.microsecond) - toks["absTime"] = day + timeOfDay - -def calculateTime(toks): - if toks.absTime: - absTime = toks.absTime - else: - absTime = datetime.now() - if toks.timeOffset: - absTime += toks.timeOffset - toks["calculatedTime"] = absTime - -# grammar definitions -CL = CaselessLiteral -today, tomorrow, yesterday, noon, midnight, now = map( CL, - "today tomorrow yesterday noon midnight now".split()) -plural = lambda s : Combine(CL(s) + Optional(CL("s"))) -week, day, hour, minute, second = map( plural, - "week day hour minute second".split()) -am = CL("am") -pm = CL("pm") -COLON = Suppress(':') - -# are these actually operators? -in_ = CL("in").setParseAction(replaceWith(1)) -from_ = CL("from").setParseAction(replaceWith(1)) -before = CL("before").setParseAction(replaceWith(-1)) -after = CL("after").setParseAction(replaceWith(1)) -ago = CL("ago").setParseAction(replaceWith(-1)) -next_ = CL("next").setParseAction(replaceWith(1)) -last_ = CL("last").setParseAction(replaceWith(-1)) -at_ = CL("at") -on_ = CL("on") - -couple = (Optional(CL("a")) + CL("couple") + Optional(CL("of"))).setParseAction(replaceWith(2)) -a_qty = CL("a").setParseAction(replaceWith(1)) -integer = Word(nums).setParseAction(lambda t:int(t[0])) -int4 = Group(Word(nums,exact=4).setParseAction(lambda t: [int(t[0][:2]),int(t[0][2:])] )) -def fill_timefields(t): - t[0]['HH'] = t[0][0] - t[0]['MM'] = t[0][1] - t[0]['ampm'] = ('am','pm')[t[0].HH >= 12] -int4.addParseAction(fill_timefields) -qty = integer | couple | a_qty -dayName = oneOf( list(calendar.day_name) ) - -dayOffset = (qty("qty") + (week | day)("timeunit")) -dayFwdBack = (from_ + now.suppress() | ago)("dir") -weekdayRef = (Optional(next_ | last_,1)("dir") + dayName("day")) -dayRef = Optional( (dayOffset + (before | after | from_)("dir") ).setParseAction(convertToTimedelta) ) + \ - ((yesterday | today | tomorrow)("name")| - weekdayRef("wkdayRef")).setParseAction(convertToDay) -todayRef = (dayOffset + dayFwdBack).setParseAction(convertToTimedelta) | \ - (in_("dir") + qty("qty") + day("timeunit")).setParseAction(convertToTimedelta) - -dayTimeSpec = dayRef | todayRef -dayTimeSpec.setParseAction(calculateTime) - -relativeTimeUnit = (week | day | hour | minute | second) - -timespec = Group(ungroup(int4) | - integer("HH") + - ungroup(Optional(COLON + integer,[0]))("MM") + - ungroup(Optional(COLON + integer,[0]))("SS") + - (am | pm)("ampm") - ) - -absTimeSpec = ((noon | midnight | now | timespec("timeparts"))("timeOfDay") + - Optional(on_) + Optional(dayRef)("dayRef") | - dayRef("dayRef") + at_ + - (noon | midnight | now | timespec("timeparts"))("timeOfDay")) -absTimeSpec.setParseAction(convertToAbsTime,calculateTime) - -relTimeSpec = qty("qty") + relativeTimeUnit("timeunit") + \ - (from_ | before | after)("dir") + \ - Optional(at_) + \ - absTimeSpec("absTime") | \ - qty("qty") + relativeTimeUnit("timeunit") + ago("dir") | \ - in_ + qty("qty") + relativeTimeUnit("timeunit") -relTimeSpec.setParseAction(convertToTimedelta,calculateTime) - -nlTimeExpression = (absTimeSpec + Optional(dayTimeSpec) | - dayTimeSpec + Optional(Optional(at_) + absTimeSpec) | - relTimeSpec + Optional(absTimeSpec)) - -if __name__ == "__main__": - # test grammar - tests = """\ - today - tomorrow - yesterday - in a couple of days - a couple of days from now - a couple of days from today - in a day - 3 days ago - 3 days from now - a day ago - in 2 weeks - in 3 days at 5pm - now - 10 minutes ago - 10 minutes from now - in 10 minutes - in a minute - in a couple of minutes - 20 seconds ago - in 30 seconds - 20 seconds before noon - 20 seconds before noon tomorrow - noon - midnight - noon tomorrow - 6am tomorrow - 0800 yesterday - 12:15 AM today - 3pm 2 days from today - a week from today - a week from now - 3 weeks ago - noon next Sunday - noon Sunday - noon last Sunday - 2pm next Sunday - next Sunday at 2pm""" - - print("(relative to %s)" % datetime.now()) - nlTimeExpression.runTests(tests) diff --git a/examples/dfmparse.py b/examples/dfmparse.py deleted file mode 100644 index cf83814..0000000 --- a/examples/dfmparse.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -This module can parse a Delphi Form (dfm) file. - -The main is used in experimenting (to find which files fail -to parse, and where), but isn't useful for anything else. -""" -__version__ = "1.0" -__author__ = "Daniel 'Dang' Griffith " - - -from pyparsing import Literal, CaselessLiteral, Word, delimitedList \ - , Optional, Combine, Group, alphas, nums, alphanums, Forward \ - , oneOf, sglQuotedString, OneOrMore, ZeroOrMore, CharsNotIn - - -# This converts DFM character constants into Python string (unicode) values. -def to_chr(x): - """chr(x) if 0 < x < 128 ; unicode(x) if x > 127.""" - return 0 < x < 128 and chr(x) or eval("u'\\u%d'" % x ) - -################# -# BEGIN GRAMMAR -################# - -COLON = Literal(":").suppress() -CONCAT = Literal("+").suppress() -EQUALS = Literal("=").suppress() -LANGLE = Literal("<").suppress() -LBRACE = Literal("[").suppress() -LPAREN = Literal("(").suppress() -PERIOD = Literal(".").suppress() -RANGLE = Literal(">").suppress() -RBRACE = Literal("]").suppress() -RPAREN = Literal(")").suppress() - -CATEGORIES = CaselessLiteral("categories").suppress() -END = CaselessLiteral("end").suppress() -FONT = CaselessLiteral("font").suppress() -HINT = CaselessLiteral("hint").suppress() -ITEM = CaselessLiteral("item").suppress() -OBJECT = CaselessLiteral("object").suppress() - -attribute_value_pair = Forward() # this is recursed in item_list_entry - -simple_identifier = Word(alphas, alphanums + "_") -identifier = Combine( simple_identifier + ZeroOrMore( Literal(".") + simple_identifier )) -object_name = identifier -object_type = identifier - -# Integer and floating point values are converted to Python longs and floats, respectively. -int_value = Combine(Optional("-") + Word(nums)).setParseAction(lambda s,l,t: [ int(t[0]) ] ) -float_value = Combine(Optional("-") + Optional(Word(nums)) + "." + Word(nums)).setParseAction(lambda s,l,t: [ float(t[0]) ] ) -number_value = float_value | int_value - -# Base16 constants are left in string form, including the surrounding braces. -base16_value = Combine(Literal("{") + OneOrMore(Word("0123456789ABCDEFabcdef")) + Literal("}"), adjacent=False) - -# This is the first part of a hack to convert the various delphi partial sglQuotedStrings -# into a single sglQuotedString equivalent. The gist of it is to combine -# all sglQuotedStrings (with their surrounding quotes removed (suppressed)) -# with sequences of #xyz character constants, with "strings" concatenated -# with a '+' sign. -unquoted_sglQuotedString = Combine( Literal("'").suppress() + ZeroOrMore( CharsNotIn("'\n\r") ) + Literal("'").suppress() ) - -# The parse action on this production converts repetitions of constants into a single string. -pound_char = Combine( - OneOrMore((Literal("#").suppress()+Word(nums) - ).setParseAction( lambda s, l, t: to_chr(int(t[0]) )))) - -# This is the second part of the hack. It combines the various "unquoted" -# partial strings into a single one. Then, the parse action puts -# a single matched pair of quotes around it. -delphi_string = Combine( - OneOrMore(CONCAT | pound_char | unquoted_sglQuotedString) - , adjacent=False - ).setParseAction(lambda s, l, t: "'%s'" % t[0]) - -string_value = delphi_string | base16_value - -list_value = LBRACE + Optional(Group(delimitedList(identifier | number_value | string_value))) + RBRACE -paren_list_value = LPAREN + ZeroOrMore(identifier | number_value | string_value) + RPAREN - -item_list_entry = ITEM + ZeroOrMore(attribute_value_pair) + END -item_list = LANGLE + ZeroOrMore(item_list_entry) + RANGLE - -generic_value = identifier -value = item_list | number_value | string_value | list_value | paren_list_value | generic_value - -category_attribute = CATEGORIES + PERIOD + oneOf("strings itemsvisibles visibles", True) -event_attribute = oneOf("onactivate onclosequery onclose oncreate ondeactivate onhide onshow", True) -font_attribute = FONT + PERIOD + oneOf("charset color height name style", True) -hint_attribute = HINT -layout_attribute = oneOf("left top width height", True) -generic_attribute = identifier -attribute = (category_attribute | event_attribute | font_attribute | hint_attribute | layout_attribute | generic_attribute) - -category_attribute_value_pair = category_attribute + EQUALS + paren_list_value -event_attribute_value_pair = event_attribute + EQUALS + value -font_attribute_value_pair = font_attribute + EQUALS + value -hint_attribute_value_pair = hint_attribute + EQUALS + value -layout_attribute_value_pair = layout_attribute + EQUALS + value -generic_attribute_value_pair = attribute + EQUALS + value -attribute_value_pair << Group( - category_attribute_value_pair - | event_attribute_value_pair - | font_attribute_value_pair - | hint_attribute_value_pair - | layout_attribute_value_pair - | generic_attribute_value_pair - ) - -object_declaration = Group((OBJECT + object_name + COLON + object_type)) -object_attributes = Group(ZeroOrMore(attribute_value_pair)) - -nested_object = Forward() -object_definition = object_declaration + object_attributes + ZeroOrMore(nested_object) + END -nested_object << Group(object_definition) - -################# -# END GRAMMAR -################# - -def printer(s, loc, tok): - print(tok, end=' ') - return tok - -def get_filename_list(tf): - import sys, glob - if tf == None: - if len(sys.argv) > 1: - tf = sys.argv[1:] - else: - tf = glob.glob("*.dfm") - elif type(tf) == str: - tf = [tf] - testfiles = [] - for arg in tf: - testfiles.extend(glob.glob(arg)) - return testfiles - -def main(testfiles=None, action=printer): - """testfiles can be None, in which case the command line arguments are used as filenames. - testfiles can be a string, in which case that file is parsed. - testfiles can be a list. - In all cases, the filenames will be globbed. - If more than one file is parsed successfully, a dictionary of ParseResults is returned. - Otherwise, a simple ParseResults is returned. - """ - testfiles = get_filename_list(testfiles) - print(testfiles) - - if action: - for i in (simple_identifier, value, item_list): - i.setParseAction(action) - - success = 0 - failures = [] - - retval = {} - for f in testfiles: - try: - retval[f] = object_definition.parseFile(f) - success += 1 - except: - failures.append(f) - - if failures: - print('\nfailed while processing %s' % ', '.join(failures)) - print('\nsucceeded on %d of %d files' %(success, len(testfiles))) - - if len(retval) == 1 and len(testfiles) == 1: - # if only one file is parsed, return the parseResults directly - return retval[list(retval.keys())[0]] - - # else, return a dictionary of parseResults - return retval - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/examples/dhcpd_leases_parser.py b/examples/dhcpd_leases_parser.py deleted file mode 100644 index 145e6ea..0000000 --- a/examples/dhcpd_leases_parser.py +++ /dev/null @@ -1,87 +0,0 @@ -# -# dhcpd_leases_parser.py -# -# Copyright 2008, Paul McGuire -# -# Sample parser to parse a dhcpd.leases file to extract leases -# and lease attributes -# -# format ref: http://www.linuxmanpages.com/man5/dhcpd.leases.5.php -# - -sample = r"""\ -# All times in this file are in UTC (GMT), not your local timezone. This is -# not a bug, so please don't ask about it. There is no portable way to -# store leases in the local timezone, so please don't request this as a -# feature. If this is inconvenient or confusing to you, we sincerely -# apologize. Seriously, though - don't ask. -# The format of this file is documented in the dhcpd.leases(5) manual page. -# This lease file was written by isc-dhcp-V3.0.4 - -lease 192.168.0.250 { - starts 3 2008/01/23 17:16:41; - ends 6 2008/02/02 17:16:41; - tstp 6 2008/02/02 17:16:41; - binding state free; - hardware ethernet 00:17:f2:9b:d8:19; - uid "\001\000\027\362\233\330\031"; -} -lease 192.168.0.198 { - starts 1 2008/02/04 13:46:55; - ends never; - tstp 1 2008/02/04 17:04:14; - binding state free; - hardware ethernet 00:13:72:d3:3b:98; - uid "\001\000\023r\323;\230"; -} -lease 192.168.0.239 { - starts 3 2008/02/06 12:12:03; - ends 4 2008/02/07 12:12:03; - tstp 4 2008/02/07 12:12:03; - binding state free; - hardware ethernet 00:1d:09:65:93:26; -} -""" - -from pyparsing import * -import datetime,time - -LBRACE,RBRACE,SEMI,QUOTE = map(Suppress,'{};"') -ipAddress = Combine(Word(nums) + ('.' + Word(nums))*3) -hexint = Word(hexnums,exact=2) -macAddress = Combine(hexint + (':'+hexint)*5) -hdwType = Word(alphanums) - -yyyymmdd = Combine((Word(nums,exact=4)|Word(nums,exact=2))+ - ('/'+Word(nums,exact=2))*2) -hhmmss = Combine(Word(nums,exact=2)+(':'+Word(nums,exact=2))*2) -dateRef = oneOf(list("0123456"))("weekday") + yyyymmdd("date") + \ - hhmmss("time") - -def utcToLocalTime(tokens): - utctime = datetime.datetime.strptime("%(date)s %(time)s" % tokens, - "%Y/%m/%d %H:%M:%S") - localtime = utctime-datetime.timedelta(0,time.timezone,0) - tokens["utcdate"],tokens["utctime"] = tokens["date"],tokens["time"] - tokens["localdate"],tokens["localtime"] = str(localtime).split() - del tokens["date"] - del tokens["time"] -dateRef.setParseAction(utcToLocalTime) - -startsStmt = "starts" + dateRef + SEMI -endsStmt = "ends" + (dateRef | "never") + SEMI -tstpStmt = "tstp" + dateRef + SEMI -tsfpStmt = "tsfp" + dateRef + SEMI -hdwStmt = "hardware" + hdwType("type") + macAddress("mac") + SEMI -uidStmt = "uid" + QuotedString('"')("uid") + SEMI -bindingStmt = "binding" + Word(alphanums) + Word(alphanums) + SEMI - -leaseStatement = startsStmt | endsStmt | tstpStmt | tsfpStmt | hdwStmt | \ - uidStmt | bindingStmt -leaseDef = "lease" + ipAddress("ipaddress") + LBRACE + \ - Dict(ZeroOrMore(Group(leaseStatement))) + RBRACE - -for lease in leaseDef.searchString(sample): - print(lease.dump()) - print(lease.ipaddress,'->',lease.hardware.mac) - print() diff --git a/examples/dictExample.py b/examples/dictExample.py deleted file mode 100644 index 5085aed..0000000 --- a/examples/dictExample.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# dictExample.py -# -# Illustration of using pyparsing's Dict class to process tabular data -# -# Copyright (c) 2003, Paul McGuire -# -from pyparsing import Literal, Word, Group, Dict, ZeroOrMore, alphas, nums, delimitedList -import pprint - -testData = """ -+-------+------+------+------+------+------+------+------+------+ -| | A1 | B1 | C1 | D1 | A2 | B2 | C2 | D2 | -+=======+======+======+======+======+======+======+======+======+ -| min | 7 | 43 | 7 | 15 | 82 | 98 | 1 | 37 | -| max | 11 | 52 | 10 | 17 | 85 | 112 | 4 | 39 | -| ave | 9 | 47 | 8 | 16 | 84 | 106 | 3 | 38 | -| sdev | 1 | 3 | 1 | 1 | 1 | 3 | 1 | 1 | -+-------+------+------+------+------+------+------+------+------+ -""" - -# define grammar for datatable -heading = (Literal( -"+-------+------+------+------+------+------+------+------+------+") + -"| | A1 | B1 | C1 | D1 | A2 | B2 | C2 | D2 |" + -"+=======+======+======+======+======+======+======+======+======+").suppress() -vert = Literal("|").suppress() -number = Word(nums) -rowData = Group( vert + Word(alphas) + vert + delimitedList(number,"|") + vert ) -trailing = Literal( -"+-------+------+------+------+------+------+------+------+------+").suppress() - -datatable = heading + Dict( ZeroOrMore(rowData) ) + trailing - -# now parse data and print results -data = datatable.parseString(testData) -print(data) -pprint.pprint(data.asList()) -print("data keys=", list(data.keys())) -print("data['min']=", data['min']) -print("data.max", data.max) diff --git a/examples/dictExample2.py b/examples/dictExample2.py deleted file mode 100644 index cae463b..0000000 --- a/examples/dictExample2.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# dictExample2.py -# -# Illustration of using pyparsing's Dict class to process tabular data -# Enhanced Dict example, courtesy of Mike Kelly -# -# Copyright (c) 2004, Paul McGuire -# -from pyparsing import Literal, Word, Group, Dict, ZeroOrMore, alphas, nums, delimitedList, pyparsing_common -import pprint - -testData = """ -+-------+------+------+------+------+------+------+------+------+ -| | A1 | B1 | C1 | D1 | A2 | B2 | C2 | D2 | -+=======+======+======+======+======+======+======+======+======+ -| min | 7 | 43 | 7 | 15 | 82 | 98 | 1 | 37 | -| max | 11 | 52 | 10 | 17 | 85 | 112 | 4 | 39 | -| ave | 9 | 47 | 8 | 16 | 84 | 106 | 3 | 38 | -| sdev | 1 | 3 | 1 | 1 | 1 | 3 | 1 | 1 | -+-------+------+------+------+------+------+------+------+------+ -""" - -# define grammar for datatable -underline = Word("-=") -number = pyparsing_common.integer - -vert = Literal("|").suppress() - -rowDelim = ("+" + ZeroOrMore( underline + "+" ) ).suppress() -columnHeader = Group(vert + vert + delimitedList(Word(alphas + nums), "|") + vert) - -heading = rowDelim + columnHeader("columns") + rowDelim -rowData = Group( vert + Word(alphas) + vert + delimitedList(number,"|") + vert ) -trailing = rowDelim - -datatable = heading + Dict( ZeroOrMore(rowData) ) + trailing - -# now parse data and print results -data = datatable.parseString(testData) -print(data.dump()) -print("data keys=", list(data.keys())) -print("data['min']=", data['min']) -print("sum(data['min']) =", sum(data['min'])) -print("data.max =", data.max) -print("sum(data.max) =", sum(data.max)) - -# now print transpose of data table, using column labels read from table header and -# values from data lists -print() -print(" " * 5, end=' ') -for i in range(1,len(data)): - print("|%5s" % data[i][0], end=' ') -print() -print(("-" * 6) + ("+------" * (len(data)-1))) -for i in range(len(data.columns)): - print("%5s" % data.columns[i], end=' ') - for j in range(len(data) - 1): - print('|%5s' % data[j + 1][i + 1], end=' ') - print() diff --git a/examples/ebnf.py b/examples/ebnf.py deleted file mode 100644 index 242aed4..0000000 --- a/examples/ebnf.py +++ /dev/null @@ -1,151 +0,0 @@ -# This module tries to implement ISO 14977 standard with pyparsing. -# pyparsing version 1.1 or greater is required. - -# ISO 14977 standardize The Extended Backus-Naur Form(EBNF) syntax. -# You can read a final draft version here: -# http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html -# -# Submitted 2004 by Seo Sanghyeon -# - -from pyparsing import * - - -all_names = ''' -integer -meta_identifier -terminal_string -optional_sequence -repeated_sequence -grouped_sequence -syntactic_primary -syntactic_factor -syntactic_term -single_definition -definitions_list -syntax_rule -syntax -'''.split() - - -integer = Word(nums) -meta_identifier = Word(alphas, alphanums + '_') -terminal_string = Suppress("'") + CharsNotIn("'") + Suppress("'") ^ \ - Suppress('"') + CharsNotIn('"') + Suppress('"') -definitions_list = Forward() -optional_sequence = Suppress('[') + definitions_list + Suppress(']') -repeated_sequence = Suppress('{') + definitions_list + Suppress('}') -grouped_sequence = Suppress('(') + definitions_list + Suppress(')') -syntactic_primary = optional_sequence ^ repeated_sequence ^ \ - grouped_sequence ^ meta_identifier ^ terminal_string -syntactic_factor = Optional(integer + Suppress('*')) + syntactic_primary -syntactic_term = syntactic_factor + Optional(Suppress('-') + syntactic_factor) -single_definition = delimitedList(syntactic_term, ',') -definitions_list << delimitedList(single_definition, '|') -syntax_rule = meta_identifier + Suppress('=') + definitions_list + \ - Suppress(';') - -ebnfComment = ( "(*" + - ZeroOrMore( CharsNotIn("*") | ( "*" + ~Literal(")") ) ) + - "*)" ).streamline().setName("ebnfComment") - -syntax = OneOrMore(syntax_rule) -syntax.ignore(ebnfComment) - - -def do_integer(str, loc, toks): - return int(toks[0]) - -def do_meta_identifier(str, loc, toks): - if toks[0] in symbol_table: - return symbol_table[toks[0]] - else: - forward_count.value += 1 - symbol_table[toks[0]] = Forward() - return symbol_table[toks[0]] - -def do_terminal_string(str, loc, toks): - return Literal(toks[0]) - -def do_optional_sequence(str, loc, toks): - return Optional(toks[0]) - -def do_repeated_sequence(str, loc, toks): - return ZeroOrMore(toks[0]) - -def do_grouped_sequence(str, loc, toks): - return Group(toks[0]) - -def do_syntactic_primary(str, loc, toks): - return toks[0] - -def do_syntactic_factor(str, loc, toks): - if len(toks) == 2: - # integer * syntactic_primary - return And([toks[1]] * toks[0]) - else: - # syntactic_primary - return [ toks[0] ] - -def do_syntactic_term(str, loc, toks): - if len(toks) == 2: - # syntactic_factor - syntactic_factor - return NotAny(toks[1]) + toks[0] - else: - # syntactic_factor - return [ toks[0] ] - -def do_single_definition(str, loc, toks): - toks = toks.asList() - if len(toks) > 1: - # syntactic_term , syntactic_term , ... - return And(toks) - else: - # syntactic_term - return [ toks[0] ] - -def do_definitions_list(str, loc, toks): - toks = toks.asList() - if len(toks) > 1: - # single_definition | single_definition | ... - return Or(toks) - else: - # single_definition - return [ toks[0] ] - -def do_syntax_rule(str, loc, toks): - # meta_identifier = definitions_list ; - assert toks[0].expr is None, "Duplicate definition" - forward_count.value -= 1 - toks[0] << toks[1] - return [ toks[0] ] - -def do_syntax(str, loc, toks): - # syntax_rule syntax_rule ... - return symbol_table - - - -symbol_table = {} -class forward_count: - pass -forward_count.value = 0 -for name in all_names: - expr = vars()[name] - action = vars()['do_' + name] - expr.setName(name) - expr.setParseAction(action) - #~ expr.setDebug() - - -def parse(ebnf, given_table={}): - symbol_table.clear() - symbol_table.update(given_table) - forward_count.value = 0 - table = syntax.parseString(ebnf)[0] - assert forward_count.value == 0, "Missing definition" - for name in table: - expr = table[name] - expr.setName(name) - #~ expr.setDebug() - return table diff --git a/examples/ebnftest.py b/examples/ebnftest.py deleted file mode 100644 index 253404f..0000000 --- a/examples/ebnftest.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# ebnftest.py -# -# Test script for ebnf.py -# -# Submitted 2004 by Seo Sanghyeon -# -print('Importing pyparsing...') -from pyparsing import * - -print('Constructing EBNF parser with pyparsing...') -import ebnf - - -grammar = ''' -syntax = (syntax_rule), {(syntax_rule)}; -syntax_rule = meta_identifier, '=', definitions_list, ';'; -definitions_list = single_definition, {'|', single_definition}; -single_definition = syntactic_term, {',', syntactic_term}; -syntactic_term = syntactic_factor,['-', syntactic_factor]; -syntactic_factor = [integer, '*'], syntactic_primary; -syntactic_primary = optional_sequence | repeated_sequence | - grouped_sequence | meta_identifier | terminal_string; -optional_sequence = '[', definitions_list, ']'; -repeated_sequence = '{', definitions_list, '}'; -grouped_sequence = '(', definitions_list, ')'; -(* -terminal_string = "'", character - "'", {character - "'"}, "'" | - '"', character - '"', {character - '"'}, '"'; - meta_identifier = letter, {letter | digit}; -integer = digit, {digit}; -*) -''' - -table = {} -#~ table['character'] = Word(printables, exact=1) -#~ table['letter'] = Word(alphas + '_', exact=1) -#~ table['digit'] = Word(nums, exact=1) -table['terminal_string'] = sglQuotedString -table['meta_identifier'] = Word(alphas+"_", alphas+"_"+nums) -table['integer'] = Word(nums) - -print('Parsing EBNF grammar with EBNF parser...') -parsers = ebnf.parse(grammar, table) -ebnf_parser = parsers['syntax'] - -commentcharcount = 0 -commentlocs = set() -def tallyCommentChars(s,l,t): - global commentcharcount,commentlocs - # only count this comment if we haven't seen it before - if l not in commentlocs: - charCount = ( len(t[0]) - len(list(filter(str.isspace, t[0]))) ) - commentcharcount += charCount - commentlocs.add(l) - return l,t - -#ordinarily, these lines wouldn't be necessary, but we are doing extra stuff with the comment expression -ebnf.ebnfComment.setParseAction( tallyCommentChars ) -ebnf_parser.ignore( ebnf.ebnfComment ) - -print('Parsing EBNF grammar with generated EBNF parser...\n') -parsed_chars = ebnf_parser.parseString(grammar) -parsed_char_len = len(parsed_chars) - -print("],\n".join(str( parsed_chars.asList() ).split("],"))) - -#~ grammar_length = len(grammar) - len(filter(str.isspace, grammar))-commentcharcount - -#~ assert parsed_char_len == grammar_length - -print('Ok!') diff --git a/examples/eval_arith.py b/examples/eval_arith.py deleted file mode 100644 index 9562253..0000000 --- a/examples/eval_arith.py +++ /dev/null @@ -1,227 +0,0 @@ -# eval_arith.py -# -# Copyright 2009, 2011 Paul McGuire -# -# Expansion on the pyparsing example simpleArith.py, to include evaluation -# of the parsed tokens. -# -# Added support for exponentiation, using right-to-left evaluation of -# operands -# -from pyparsing import Word, nums, alphas, Combine, oneOf, \ - opAssoc, infixNotation, Literal - -class EvalConstant(object): - "Class to evaluate a parsed constant or variable" - vars_ = {} - def __init__(self, tokens): - self.value = tokens[0] - def eval(self): - if self.value in EvalConstant.vars_: - return EvalConstant.vars_[self.value] - else: - return float(self.value) - -class EvalSignOp(object): - "Class to evaluate expressions with a leading + or - sign" - def __init__(self, tokens): - self.sign, self.value = tokens[0] - def eval(self): - mult = {'+':1, '-':-1}[self.sign] - return mult * self.value.eval() - -def operatorOperands(tokenlist): - "generator to extract operators and operands in pairs" - it = iter(tokenlist) - while 1: - try: - yield (next(it), next(it)) - except StopIteration: - break - -class EvalPowerOp(object): - "Class to evaluate multiplication and division expressions" - def __init__(self, tokens): - self.value = tokens[0] - def eval(self): - res = self.value[-1].eval() - for val in self.value[-3::-2]: - res = val.eval()**res - return res - -class EvalMultOp(object): - "Class to evaluate multiplication and division expressions" - def __init__(self, tokens): - self.value = tokens[0] - def eval(self): - prod = self.value[0].eval() - for op,val in operatorOperands(self.value[1:]): - if op == '*': - prod *= val.eval() - if op == '/': - prod /= val.eval() - return prod - -class EvalAddOp(object): - "Class to evaluate addition and subtraction expressions" - def __init__(self, tokens): - self.value = tokens[0] - def eval(self): - sum = self.value[0].eval() - for op,val in operatorOperands(self.value[1:]): - if op == '+': - sum += val.eval() - if op == '-': - sum -= val.eval() - return sum - -class EvalComparisonOp(object): - "Class to evaluate comparison expressions" - opMap = { - "<" : lambda a,b : a < b, - "<=" : lambda a,b : a <= b, - ">" : lambda a,b : a > b, - ">=" : lambda a,b : a >= b, - "!=" : lambda a,b : a != b, - "=" : lambda a,b : a == b, - "LT" : lambda a,b : a < b, - "LE" : lambda a,b : a <= b, - "GT" : lambda a,b : a > b, - "GE" : lambda a,b : a >= b, - "NE" : lambda a,b : a != b, - "EQ" : lambda a,b : a == b, - "<>" : lambda a,b : a != b, - } - def __init__(self, tokens): - self.value = tokens[0] - def eval(self): - val1 = self.value[0].eval() - for op,val in operatorOperands(self.value[1:]): - fn = EvalComparisonOp.opMap[op] - val2 = val.eval() - if not fn(val1,val2): - break - val1 = val2 - else: - return True - return False - - -# define the parser -integer = Word(nums) -real = Combine(Word(nums) + "." + Word(nums)) -variable = Word(alphas,exact=1) -operand = real | integer | variable - -signop = oneOf('+ -') -multop = oneOf('* /') -plusop = oneOf('+ -') -expop = Literal('**') - -# use parse actions to attach EvalXXX constructors to sub-expressions -operand.setParseAction(EvalConstant) -arith_expr = infixNotation(operand, - [ - (signop, 1, opAssoc.RIGHT, EvalSignOp), - (expop, 2, opAssoc.LEFT, EvalPowerOp), - (multop, 2, opAssoc.LEFT, EvalMultOp), - (plusop, 2, opAssoc.LEFT, EvalAddOp), - ]) - -comparisonop = oneOf("< <= > >= != = <> LT GT LE GE EQ NE") -comp_expr = infixNotation(arith_expr, - [ - (comparisonop, 2, opAssoc.LEFT, EvalComparisonOp), - ]) - -def main(): - # sample expressions posted on comp.lang.python, asking for advice - # in safely evaluating them - rules=[ - '( A - B ) = 0', - '(A + B + C + D + E + F + G + H + I) = J', - '(A + B + C + D + E + F + G + H) = I', - '(A + B + C + D + E + F) = G', - '(A + B + C + D + E) = (F + G + H + I + J)', - '(A + B + C + D + E) = (F + G + H + I)', - '(A + B + C + D + E) = F', - '(A + B + C + D) = (E + F + G + H)', - '(A + B + C) = (D + E + F)', - '(A + B) = (C + D + E + F)', - '(A + B) = (C + D)', - '(A + B) = (C - D + E - F - G + H + I + J)', - '(A + B) = C', - '(A + B) = 0', - '(A+B+C+D+E) = (F+G+H+I+J)', - '(A+B+C+D) = (E+F+G+H)', - '(A+B+C+D)=(E+F+G+H)', - '(A+B+C)=(D+E+F)', - '(A+B)=(C+D)', - '(A+B)=C', - '(A-B)=C', - '(A/(B+C))', - '(B/(C+D))', - '(G + H) = I', - '-0.99 LE ((A+B+C)-(D+E+F+G)) LE 0.99', - '-0.99 LE (A-(B+C)) LE 0.99', - '-1000.00 LE A LE 0.00', - '-5000.00 LE A LE 0.00', - 'A < B', - 'A < 7000', - 'A = -(B)', - 'A = C', - 'A = 0', - 'A GT 0', - 'A GT 0.00', - 'A GT 7.00', - 'A LE B', - 'A LT -1000.00', - 'A LT -5000', - 'A LT 0', - 'A=(B+C+D)', - 'A=B', - 'I = (G + H)', - '0.00 LE A LE 4.00', - '4.00 LT A LE 7.00', - '0.00 LE A LE 4.00 LE E > D', - '2**2**(A+3)', - ] - vars_={'A': 0, 'B': 1.1, 'C': 2.2, 'D': 3.3, 'E': 4.4, 'F': 5.5, 'G': - 6.6, 'H':7.7, 'I':8.8, 'J':9.9} - - # define tests from given rules - tests = [] - for t in rules: - t_orig = t - t = t.replace("=","==") - t = t.replace("EQ","==") - t = t.replace("LE","<=") - t = t.replace("GT",">") - t = t.replace("LT","<") - t = t.replace("GE",">=") - t = t.replace("LE","<=") - t = t.replace("NE","!=") - t = t.replace("<>","!=") - tests.append( (t_orig,eval(t,vars_)) ) - - # copy vars_ to EvalConstant lookup dict - EvalConstant.vars_ = vars_ - failed = 0 - for test,expected in tests: - ret = comp_expr.parseString(test)[0] - parsedvalue = ret.eval() - print(test, expected, parsedvalue) - if parsedvalue != expected: - print("<<< FAIL") - failed += 1 - else: - print('') - - print('') - if failed: - print(failed, "tests FAILED") - else: - print("all tests PASSED") - -if __name__=='__main__': - main() diff --git a/examples/excelExpr.py b/examples/excelExpr.py deleted file mode 100644 index 7ce8db2..0000000 --- a/examples/excelExpr.py +++ /dev/null @@ -1,69 +0,0 @@ -# excelExpr.py -# -# Copyright 2010, Paul McGuire -# -# A partial implementation of a parser of Excel formula expressions. -# -from pyparsing import (CaselessKeyword, Suppress, Word, alphas, - alphanums, nums, Optional, Group, oneOf, Forward, Regex, - infixNotation, opAssoc, dblQuotedString, delimitedList, - Combine, Literal, QuotedString, ParserElement, pyparsing_common) -ParserElement.enablePackrat() - -EQ,LPAR,RPAR,COLON,COMMA = map(Suppress, '=():,') -EXCL, DOLLAR = map(Literal,"!$") -sheetRef = Word(alphas, alphanums) | QuotedString("'",escQuote="''") -colRef = Optional(DOLLAR) + Word(alphas,max=2) -rowRef = Optional(DOLLAR) + Word(nums) -cellRef = Combine(Group(Optional(sheetRef + EXCL)("sheet") + colRef("col") + - rowRef("row"))) - -cellRange = (Group(cellRef("start") + COLON + cellRef("end"))("range") - | cellRef | Word(alphas,alphanums)) - -expr = Forward() - -COMPARISON_OP = oneOf("< = > >= <= != <>") -condExpr = expr + COMPARISON_OP + expr - -ifFunc = (CaselessKeyword("if") - - LPAR + - Group(condExpr)("condition") + - COMMA + Group(expr)("if_true") + - COMMA + Group(expr)("if_false") + RPAR) - -statFunc = lambda name : Group(CaselessKeyword(name) + Group(LPAR + delimitedList(expr) + RPAR)) -sumFunc = statFunc("sum") -minFunc = statFunc("min") -maxFunc = statFunc("max") -aveFunc = statFunc("ave") -funcCall = ifFunc | sumFunc | minFunc | maxFunc | aveFunc - -multOp = oneOf("* /") -addOp = oneOf("+ -") -numericLiteral = pyparsing_common.number -operand = numericLiteral | funcCall | cellRange | cellRef -arithExpr = infixNotation(operand, - [ - (multOp, 2, opAssoc.LEFT), - (addOp, 2, opAssoc.LEFT), - ]) - -textOperand = dblQuotedString | cellRef -textExpr = infixNotation(textOperand, - [ - ('&', 2, opAssoc.LEFT), - ]) - -expr << (arithExpr | textExpr) - - -(EQ + expr).runTests("""\ - =3*A7+5 - =3*Sheet1!$A$7+5 - =3*'Sheet 1'!$A$7+5" - =3*'O''Reilly''s sheet'!$A$7+5 - =if(Sum(A1:A25)>42,Min(B1:B25),if(Sum(C1:C25)>3.14, (Min(C1:C25)+3)*18,Max(B1:B25))) - =sum(a1:a25,10,min(b1,c2,d3)) - =if("T"&a2="TTime", "Ready", "Not ready") -""") \ No newline at end of file diff --git a/examples/fourFn.py b/examples/fourFn.py deleted file mode 100644 index 75f3909..0000000 --- a/examples/fourFn.py +++ /dev/null @@ -1,192 +0,0 @@ -# fourFn.py -# -# Demonstration of the pyparsing module, implementing a simple 4-function expression parser, -# with support for scientific notation, and symbols for e and pi. -# Extended to add exponentiation and simple built-in functions. -# Extended test cases, simplified pushFirst method. -# Removed unnecessary expr.suppress() call (thanks Nathaniel Peterson!), and added Group -# Changed fnumber to use a Regex, which is now the preferred method -# -# Copyright 2003-2009 by Paul McGuire -# -from pyparsing import Literal,CaselessLiteral,Word,Group,Optional,\ - ZeroOrMore,Forward,nums,alphas,alphanums,Regex,ParseException,\ - CaselessKeyword, Suppress -import math -import operator - -exprStack = [] - -def pushFirst( strg, loc, toks ): - exprStack.append( toks[0] ) -def pushUMinus( strg, loc, toks ): - for t in toks: - if t == '-': - exprStack.append( 'unary -' ) - #~ exprStack.append( '-1' ) - #~ exprStack.append( '*' ) - else: - break - -bnf = None -def BNF(): - """ - expop :: '^' - multop :: '*' | '/' - addop :: '+' | '-' - integer :: ['+' | '-'] '0'..'9'+ - atom :: PI | E | real | fn '(' expr ')' | '(' expr ')' - factor :: atom [ expop factor ]* - term :: factor [ multop factor ]* - expr :: term [ addop term ]* - """ - global bnf - if not bnf: - point = Literal( "." ) - # use CaselessKeyword for e and pi, to avoid accidentally matching - # functions that start with 'e' or 'pi' (such as 'exp'); Keyword - # and CaselessKeyword only match whole words - e = CaselessKeyword( "E" ) - pi = CaselessKeyword( "PI" ) - #~ fnumber = Combine( Word( "+-"+nums, nums ) + - #~ Optional( point + Optional( Word( nums ) ) ) + - #~ Optional( e + Word( "+-"+nums, nums ) ) ) - fnumber = Regex(r"[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?") - ident = Word(alphas, alphanums+"_$") - - plus, minus, mult, div = map(Literal, "+-*/") - lpar, rpar = map(Suppress, "()") - addop = plus | minus - multop = mult | div - expop = Literal( "^" ) - - expr = Forward() - atom = ((0,None)*minus + ( pi | e | fnumber | ident + lpar + expr + rpar | ident ).setParseAction( pushFirst ) | - Group( lpar + expr + rpar )).setParseAction(pushUMinus) - - # by defining exponentiation as "atom [ ^ factor ]..." instead of "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-righ - # that is, 2^3^2 = 2^(3^2), not (2^3)^2. - factor = Forward() - factor << atom + ZeroOrMore( ( expop + factor ).setParseAction( pushFirst ) ) - - term = factor + ZeroOrMore( ( multop + factor ).setParseAction( pushFirst ) ) - expr << term + ZeroOrMore( ( addop + term ).setParseAction( pushFirst ) ) - bnf = expr - return bnf - -# map operator symbols to corresponding arithmetic operations -epsilon = 1e-12 -opn = { "+" : operator.add, - "-" : operator.sub, - "*" : operator.mul, - "/" : operator.truediv, - "^" : operator.pow } -fn = { "sin" : math.sin, - "cos" : math.cos, - "tan" : math.tan, - "exp" : math.exp, - "abs" : abs, - "trunc" : lambda a: int(a), - "round" : round, - "sgn" : lambda a: (a > epsilon) - (a < -epsilon) } -def evaluateStack( s ): - op = s.pop() - if op == 'unary -': - return -evaluateStack( s ) - if op in "+-*/^": - op2 = evaluateStack( s ) - op1 = evaluateStack( s ) - return opn[op]( op1, op2 ) - elif op == "PI": - return math.pi # 3.1415926535 - elif op == "E": - return math.e # 2.718281828 - elif op in fn: - return fn[op]( evaluateStack( s ) ) - elif op[0].isalpha(): - raise Exception("invalid identifier '%s'" % op) - else: - return float( op ) - -if __name__ == "__main__": - - def test( s, expVal ): - global exprStack - exprStack[:] = [] - try: - results = BNF().parseString( s, parseAll=True ) - val = evaluateStack( exprStack[:] ) - except ParseException as e: - print(s, "failed parse:", str(pe)) - except Exception as e: - print(s, "failed eval:", str(e)) - else: - if val == expVal: - print(s, "=", val, results, "=>", exprStack) - else: - print(s+"!!!", val, "!=", expVal, results, "=>", exprStack) - - test( "9", 9 ) - test( "-9", -9 ) - test( "--9", 9 ) - test( "-E", -math.e ) - test( "9 + 3 + 6", 9 + 3 + 6 ) - test( "9 + 3 / 11", 9 + 3.0 / 11 ) - test( "(9 + 3)", (9 + 3) ) - test( "(9+3) / 11", (9+3.0) / 11 ) - test( "9 - 12 - 6", 9 - 12 - 6 ) - test( "9 - (12 - 6)", 9 - (12 - 6) ) - test( "2*3.14159", 2*3.14159 ) - test( "3.1415926535*3.1415926535 / 10", 3.1415926535*3.1415926535 / 10 ) - test( "PI * PI / 10", math.pi * math.pi / 10 ) - test( "PI*PI/10", math.pi*math.pi/10 ) - test( "PI^2", math.pi**2 ) - test( "round(PI^2)", round(math.pi**2) ) - test( "6.02E23 * 8.048", 6.02E23 * 8.048 ) - test( "e / 3", math.e / 3 ) - test( "sin(PI/2)", math.sin(math.pi/2) ) - test( "trunc(E)", int(math.e) ) - test( "trunc(-E)", int(-math.e) ) - test( "round(E)", round(math.e) ) - test( "round(-E)", round(-math.e) ) - test( "E^PI", math.e**math.pi ) - test( "exp(0)", 1 ) - test( "exp(1)", math.e ) - test( "2^3^2", 2**3**2 ) - test( "2^3+2", 2**3+2 ) - test( "2^3+5", 2**3+5 ) - test( "2^9", 2**9 ) - test( "sgn(-2)", -1 ) - test( "sgn(0)", 0 ) - test( "foo(0.1)", None ) - test( "sgn(0.1)", 1 ) - - -""" -Test output: ->pythonw -u fourFn.py -9 = 9.0 ['9'] => ['9'] -9 + 3 + 6 = 18.0 ['9', '+', '3', '+', '6'] => ['9', '3', '+', '6', '+'] -9 + 3 / 11 = 9.27272727273 ['9', '+', '3', '/', '11'] => ['9', '3', '11', '/', '+'] -(9 + 3) = 12.0 [] => ['9', '3', '+'] -(9+3) / 11 = 1.09090909091 ['/', '11'] => ['9', '3', '+', '11', '/'] -9 - 12 - 6 = -9.0 ['9', '-', '12', '-', '6'] => ['9', '12', '-', '6', '-'] -9 - (12 - 6) = 3.0 ['9', '-'] => ['9', '12', '6', '-', '-'] -2*3.14159 = 6.28318 ['2', '*', '3.14159'] => ['2', '3.14159', '*'] -3.1415926535*3.1415926535 / 10 = 0.986960440053 ['3.1415926535', '*', '3.1415926535', '/', '10'] => ['3.1415926535', '3.1415926535', '*', '10', '/'] -PI * PI / 10 = 0.986960440109 ['PI', '*', 'PI', '/', '10'] => ['PI', 'PI', '*', '10', '/'] -PI*PI/10 = 0.986960440109 ['PI', '*', 'PI', '/', '10'] => ['PI', 'PI', '*', '10', '/'] -PI^2 = 9.86960440109 ['PI', '^', '2'] => ['PI', '2', '^'] -6.02E23 * 8.048 = 4.844896e+024 ['6.02E23', '*', '8.048'] => ['6.02E23', '8.048', '*'] -e / 3 = 0.90609394282 ['E', '/', '3'] => ['E', '3', '/'] -sin(PI/2) = 1.0 ['sin', 'PI', '/', '2'] => ['PI', '2', '/', 'sin'] -trunc(E) = 2 ['trunc', 'E'] => ['E', 'trunc'] -E^PI = 23.1406926328 ['E', '^', 'PI'] => ['E', 'PI', '^'] -2^3^2 = 512.0 ['2', '^', '3', '^', '2'] => ['2', '3', '2', '^', '^'] -2^3+2 = 10.0 ['2', '^', '3', '+', '2'] => ['2', '3', '^', '2', '+'] -2^9 = 512.0 ['2', '^', '9'] => ['2', '9', '^'] -sgn(-2) = -1 ['sgn', '-2'] => ['-2', 'sgn'] -sgn(0) = 0 ['sgn', '0'] => ['0', 'sgn'] -sgn(0.1) = 1 ['sgn', '0.1'] => ['0.1', 'sgn'] ->Exit code: 0 -""" diff --git a/examples/gen_ctypes.py b/examples/gen_ctypes.py deleted file mode 100644 index 9e74819..0000000 --- a/examples/gen_ctypes.py +++ /dev/null @@ -1,174 +0,0 @@ -# -# gen_ctypes.py -# -# Parse a .h header file to generate ctypes argtype and return type definitions -# -# Copyright 2004-2016, by Paul McGuire -# -from pyparsing import * - -typemap = { - "byte" : "c_byte", - "char" : "c_char", - "char *" : "c_char_p", - "double" : "c_double", - "float" : "c_float", - "int" : "c_int", - "int16" : "c_int16", - "int32" : "c_int32", - "int64" : "c_int64", - "int8" : "c_int8", - "long" : "c_long", - "longlong" : "c_longlong", - "short" : "c_short", - "size_t" : "c_size_t", - "ubyte" : "c_ubyte", - "uchar" : "c_ubyte", - "u_char" : "c_ubyte", - "uint" : "c_uint", - "u_int" : "c_uint", - "uint16" : "c_uint16", - "uint32" : "c_uint32", - "uint64" : "c_uint64", - "uint8" : "c_uint8", - "u_long" : "c_ulong", - "ulong" : "c_ulong", - "ulonglong" : "c_ulonglong", - "ushort" : "c_ushort", - "u_short" : "c_ushort", - "void *" : "c_void_p", - "voidp" : "c_voidp", - "wchar" : "c_wchar", - "wchar *" : "c_wchar_p", - "Bool" : "c_bool", - "void" : "None", - } - -LPAR,RPAR,LBRACE,RBRACE,COMMA,SEMI = map(Suppress,"(){},;") -ident = Word(alphas, alphanums + "_") -integer = Regex(r"[+-]?\d+") -hexinteger = Regex(r"0x[0-9a-fA-F]+") - -const = Suppress("const") -primitiveType = oneOf(t for t in typemap if not t.endswith("*")) -structType = Suppress("struct") + ident -vartype = (Optional(const) + - (primitiveType | structType | ident) + - Optional(Word("*")("ptr"))) -def normalizetype(t): - if isinstance(t, ParseResults): - return ' '.join(t) - #~ ret = ParseResults([' '.join(t)]) - #~ return ret - -vartype.setParseAction(normalizetype) - -arg = Group(vartype("argtype") + Optional(ident("argname"))) -func_def = (vartype("fn_type") + ident("fn_name") + - LPAR + Optional(delimitedList(arg|"..."))("fn_args") + RPAR + SEMI) -def derivefields(t): - if t.fn_args and t.fn_args[-1] == "...": - t["varargs"]=True -func_def.setParseAction(derivefields) - -fn_typedef = "typedef" + func_def -var_typedef = "typedef" + primitiveType("primType") + ident("name") + SEMI - -enum_def = (Keyword("enum") + LBRACE + - delimitedList(Group(ident("name") + '=' + (hexinteger|integer)("value")))("evalues") - + Optional(COMMA) - + RBRACE) - -c_header = open("snmp_api.h").read() - - -module = "pynetsnmp" - -user_defined_types = set() -typedefs = [] -fn_typedefs = [] -functions = [] -enum_constants = [] - -# add structures commonly included from std lib headers -def addStdType(t,namespace=""): - fullname = namespace+'_'+t if namespace else t - typemap[t] = fullname - user_defined_types.add(t) -addStdType("fd_set", "sys_select") -addStdType("timeval", "sys_time") - -def getUDType(typestr): - key = typestr.rstrip(" *") - if key not in typemap: - user_defined_types.add(key) - typemap[key] = "%s_%s" % (module, key) - -def typeAsCtypes(typestr): - if typestr in typemap: - return typemap[typestr] - if typestr.endswith("*"): - return "POINTER(%s)" % typeAsCtypes(typestr.rstrip(" *")) - return typestr - -# scan input header text for primitive typedefs -for td,_,_ in var_typedef.scanString(c_header): - typedefs.append( (td.name, td.primType) ) - # add typedef type to typemap to map to itself - typemap[td.name] = td.name - -# scan input header text for function typedefs -fn_typedefs = fn_typedef.searchString(c_header) -# add each function typedef to typemap to map to itself -for fntd in fn_typedefs: - typemap[fntd.fn_name] = fntd.fn_name - -# scan input header text, and keep running list of user-defined types -for fn,_,_ in (cStyleComment.suppress() | fn_typedef.suppress() | func_def).scanString(c_header): - if not fn: continue - getUDType(fn.fn_type) - for arg in fn.fn_args: - if arg != "...": - if arg.argtype not in typemap: - getUDType(arg.argtype) - functions.append(fn) - -# scan input header text for enums -enum_def.ignore(cppStyleComment) -for en_,_,_ in enum_def.scanString(c_header): - for ev in en_.evalues: - enum_constants.append( (ev.name, ev.value) ) - -print("from ctypes import *") -print("%s = CDLL('%s.dll')" % (module, module)) -print() -print("# user defined types") -for tdname,tdtyp in typedefs: - print("%s = %s" % (tdname, typemap[tdtyp])) -for fntd in fn_typedefs: - print("%s = CFUNCTYPE(%s)" % (fntd.fn_name, - ',\n '.join(typeAsCtypes(a.argtype) for a in fntd.fn_args))) -for udtype in user_defined_types: - print("class %s(Structure): pass" % typemap[udtype]) - -print() -print("# constant definitions") -for en,ev in enum_constants: - print("%s = %s" % (en,ev)) - -print() -print("# functions") -for fn in functions: - prefix = "%s.%s" % (module, fn.fn_name) - - print("%s.restype = %s" % (prefix, typeAsCtypes(fn.fn_type))) - if fn.varargs: - print("# warning - %s takes variable argument list" % prefix) - del fn.fn_args[-1] - - if fn.fn_args.asList() != [['void']]: - print("%s.argtypes = (%s,)" % (prefix, ','.join(typeAsCtypes(a.argtype) for a in fn.fn_args))) - else: - print("%s.argtypes = ()" % (prefix)) - - diff --git a/examples/getNTPservers.py b/examples/getNTPservers.py deleted file mode 100644 index bbf1d60..0000000 --- a/examples/getNTPservers.py +++ /dev/null @@ -1,30 +0,0 @@ -# getNTPservers.py -# -# Demonstration of the parsing module, implementing a HTML page scanner, -# to extract a list of NTP time servers from the NIST web site. -# -# Copyright 2004, by Paul McGuire -# -from pyparsing import Word, Combine, Suppress, CharsNotIn, nums -import urllib.request, urllib.parse, urllib.error - -integer = Word(nums) -ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer ) -tdStart = Suppress("") -tdEnd = Suppress("") -timeServerPattern = tdStart + ipAddress.setResultsName("ipAddr") + tdEnd + \ - tdStart + CharsNotIn("<").setResultsName("loc") + tdEnd - -# get list of time servers -nistTimeServerURL = "http://www.boulder.nist.gov/timefreq/service/time-servers.html" -serverListPage = urllib.request.urlopen( nistTimeServerURL ) -serverListHTML = serverListPage.read() -serverListPage.close() - -addrs = {} -for srvr,startloc,endloc in timeServerPattern.scanString( serverListHTML ): - print(srvr.ipAddr, "-", srvr.loc) - addrs[srvr.ipAddr] = srvr.loc - # or do this: - #~ addr,loc = srvr - #~ print addr, "-", loc diff --git a/examples/getNTPserversNew.py b/examples/getNTPserversNew.py deleted file mode 100644 index 14e710c..0000000 --- a/examples/getNTPserversNew.py +++ /dev/null @@ -1,35 +0,0 @@ -# getNTPserversNew.py -# -# Demonstration of the parsing module, implementing a HTML page scanner, -# to extract a list of NTP time servers from the NIST web site. -# -# Copyright 2004-2010, by Paul McGuire -# September, 2010 - updated to more current use of setResultsName, new NIST URL -# -from pyparsing import (Word, Combine, Suppress, SkipTo, nums, makeHTMLTags, - delimitedList, alphas, alphanums) -try: - import urllib.request - urlopen = urllib.request.urlopen -except ImportError: - import urllib - urlopen = urllib.urlopen - -integer = Word(nums) -ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer ) -hostname = delimitedList(Word(alphas,alphanums+"-_"),".",combine=True) -tdStart,tdEnd = makeHTMLTags("td") -timeServerPattern = (tdStart + hostname("hostname") + tdEnd + - tdStart + ipAddress("ipAddr") + tdEnd + - tdStart + SkipTo(tdEnd)("loc") + tdEnd) - -# get list of time servers -nistTimeServerURL = "http://tf.nist.gov/tf-cgi/servers.cgi#" -serverListPage = urlopen( nistTimeServerURL ) -serverListHTML = serverListPage.read().decode("UTF-8") -serverListPage.close() - -addrs = {} -for srvr,startloc,endloc in timeServerPattern.scanString( serverListHTML ): - print("%s (%s) - %s" % (srvr.ipAddr, srvr.hostname.strip(), srvr.loc.strip())) - addrs[srvr.ipAddr] = srvr.loc diff --git a/examples/greeting.py b/examples/greeting.py deleted file mode 100644 index 2e6b241..0000000 --- a/examples/greeting.py +++ /dev/null @@ -1,17 +0,0 @@ -# greeting.py -# -# Demonstration of the pyparsing module, on the prototypical "Hello, World!" -# example -# -# Copyright 2003, by Paul McGuire -# -from pyparsing import Word, alphas - -# define grammar -greet = Word( alphas ) + "," + Word( alphas ) + "!" - -# input string -hello = "Hello, World!" - -# parse input string -print(hello, "->", greet.parseString( hello )) diff --git a/examples/greetingInGreek.py b/examples/greetingInGreek.py deleted file mode 100644 index c4d002f..0000000 --- a/examples/greetingInGreek.py +++ /dev/null @@ -1,20 +0,0 @@ -# vim:fileencoding=utf-8 -# -# greetingInGreek.py -# -# Demonstration of the parsing module, on the prototypical "Hello, World!" example -# -# Copyright 2004-2016, by Paul McGuire -# -from pyparsing import Word - -# define grammar -alphas = ''.join(chr(x) for x in range(0x386, 0x3ce)) -greet = Word(alphas) + ',' + Word(alphas) + '!' - -# input string -hello = "Καλημέρα, κόσμε!".decode('utf-8') - -# parse input string -print(greet.parseString( hello )) - diff --git a/examples/greetingInKorean.py b/examples/greetingInKorean.py deleted file mode 100644 index e48cc8b..0000000 --- a/examples/greetingInKorean.py +++ /dev/null @@ -1,22 +0,0 @@ -# vim:fileencoding=utf-8 -# -# greetingInKorean.py -# -# Demonstration of the parsing module, on the prototypical "Hello, World!" example -# -# Copyright 2004-2016, by Paul McGuire -# -from pyparsing import Word, srange - -koreanChars = srange(r"[\0xac00-\0xd7a3]") -koreanWord = Word(koreanChars,min=2) - -# define grammar -greet = koreanWord + "," + koreanWord + "!" - -# input string -hello = '\uc548\ub155, \uc5ec\ub7ec\ubd84!' #"Hello, World!" in Korean - -# parse input string -print(greet.parseString( hello )) - diff --git a/examples/groupUsingListAllMatches.py b/examples/groupUsingListAllMatches.py deleted file mode 100644 index 28cdfd6..0000000 --- a/examples/groupUsingListAllMatches.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# A simple example showing the use of the implied listAllMatches=True for -# results names with a trailing '*' character. -# -# This example performs work similar to itertools.groupby, but without -# having to sort the input first. -# -# Copyright 2004-2016, by Paul McGuire -# -from pyparsing import Word, ZeroOrMore, nums - -aExpr = Word("A", nums) -bExpr = Word("B", nums) -cExpr = Word("C", nums) -grammar = ZeroOrMore(aExpr("A*") | bExpr("B*") | cExpr("C*")) - -grammar.runTests("A1 B1 A2 C1 B2 A3") diff --git a/examples/holaMundo.py b/examples/holaMundo.py deleted file mode 100644 index 6ae2cc5..0000000 --- a/examples/holaMundo.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: UTF-8 -*- - -# escrito por Marco Alfonso, 2004 Noviembre - -# importamos el modulo -from pyparsing import * -saludo= Word(alphas) + ',' + Word(alphas) + '!' - -# Aqui decimos que la gramatica "saludo" DEBE contener -# una palabra compuesta de caracteres alfanumericos -# (Word(alphas)) mas una ',' mas otra palabra alfanumerica, -# mas '!' y esos seian nuestros tokens -tokens = saludo.parseString("Hola, Mundo !") - -# Ahora parseamos una cadena, "Hola, Mundo!", -# el metodo parseString, nos devuelve una lista con los tokens -# encontrados, en caso de no haber errores... -for i in range(len(tokens)): - print ("Token %d -> %s" % (i,tokens[i])) - -#imprimimos cada uno de los tokens Y listooo!!, he aquí a salida -# Token 0 -> Hola -# Token 1 -> , -# Token 2-> Mundo -# Token 3 -> ! - -# Por supuesto, se pueden "reutilizar" gramáticas, por ejemplo: -numimag = Word(nums) + 'i' -numreal = Word(nums) -numcomplex = numreal + '+' + numimag -print (numcomplex.parseString("3+5i")) - -# Cambiar a complejo numero durante parsear: -numcomplex.setParseAction(lambda t: complex(''.join(t).replace('i','j'))) -print (numcomplex.parseString("3+5i")) - -# Excelente!!, bueno, los dejo, me voy a seguir tirando código... - diff --git a/examples/htmlStripper.py b/examples/htmlStripper.py deleted file mode 100644 index 1d7a0f0..0000000 --- a/examples/htmlStripper.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# htmlStripper.py -# -# Sample code for stripping HTML markup tags and scripts from -# HTML source files. -# -# Copyright (c) 2006, 2016, Paul McGuire -# -from contextlib import closing -import urllib.request, urllib.parse, urllib.error -from pyparsing import (makeHTMLTags, SkipTo, commonHTMLEntity, replaceHTMLEntity, - htmlComment, anyOpenTag, anyCloseTag, LineEnd, OneOrMore, replaceWith) - -scriptOpen,scriptClose = makeHTMLTags("script") -scriptBody = scriptOpen + SkipTo(scriptClose) + scriptClose -commonHTMLEntity.setParseAction(replaceHTMLEntity) - -# get some HTML -targetURL = "http://wiki.python.org/moin/PythonDecoratorLibrary" -with closing(urllib.request.urlopen( targetURL )) as targetPage: - targetHTML = targetPage.read().decode("UTF-8") - -# first pass, strip out tags and translate entities -firstPass = (htmlComment | scriptBody | commonHTMLEntity | - anyOpenTag | anyCloseTag ).suppress().transformString(targetHTML) - -# first pass leaves many blank lines, collapse these down -repeatedNewlines = LineEnd() + OneOrMore(LineEnd()) -repeatedNewlines.setParseAction(replaceWith("\n\n")) -secondPass = repeatedNewlines.transformString(firstPass) - -print(secondPass) \ No newline at end of file diff --git a/examples/httpServerLogParser.py b/examples/httpServerLogParser.py deleted file mode 100644 index a147a05..0000000 --- a/examples/httpServerLogParser.py +++ /dev/null @@ -1,73 +0,0 @@ -# httpServerLogParser.py -# -# Copyright (c) 2016, Paul McGuire -# -""" -Parser for HTTP server log output, of the form: - -195.146.134.15 - - [20/Jan/2003:08:55:36 -0800] -"GET /path/to/page.html HTTP/1.0" 200 4649 "http://www.somedomain.com/020602/page.html" -"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" -127.0.0.1 - u.surname@domain.com [12/Sep/2006:14:13:53 +0300] -"GET /skins/monobook/external.png HTTP/1.0" 304 - "http://wiki.mysite.com/skins/monobook/main.css" -"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6" - -You can then break it up as follows: -IP ADDRESS - - -Server Date / Time [SPACE] -"GET /path/to/page -HTTP/Type Request" -Success Code -Bytes Sent To Client -Referer -Client Software -""" - -from pyparsing import alphas,nums, dblQuotedString, Combine, Word, Group, delimitedList, Suppress, removeQuotes -import string - -def getCmdFields( s, l, t ): - t["method"],t["requestURI"],t["protocolVersion"] = t[0].strip('"').split() - -logLineBNF = None -def getLogLineBNF(): - global logLineBNF - - if logLineBNF is None: - integer = Word( nums ) - ipAddress = delimitedList( integer, ".", combine=True ) - - timeZoneOffset = Word("+-",nums) - month = Word(string.uppercase, string.lowercase, exact=3) - serverDateTime = Group( Suppress("[") + - Combine( integer + "/" + month + "/" + integer + - ":" + integer + ":" + integer + ":" + integer ) + - timeZoneOffset + - Suppress("]") ) - - logLineBNF = ( ipAddress.setResultsName("ipAddr") + - Suppress("-") + - ("-" | Word( alphas+nums+"@._" )).setResultsName("auth") + - serverDateTime.setResultsName("timestamp") + - dblQuotedString.setResultsName("cmd").setParseAction(getCmdFields) + - (integer | "-").setResultsName("statusCode") + - (integer | "-").setResultsName("numBytesSent") + - dblQuotedString.setResultsName("referrer").setParseAction(removeQuotes) + - dblQuotedString.setResultsName("clientSfw").setParseAction(removeQuotes) ) - return logLineBNF - -testdata = """ -195.146.134.15 - - [20/Jan/2003:08:55:36 -0800] "GET /path/to/page.html HTTP/1.0" 200 4649 "http://www.somedomain.com/020602/page.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" -111.111.111.11 - - [16/Feb/2004:04:09:49 -0800] "GET /ads/redirectads/336x280redirect.htm HTTP/1.1" 304 - "http://www.foobarp.org/theme_detail.php?type=vs&cat=0&mid=27512" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" -11.111.11.111 - - [16/Feb/2004:10:35:12 -0800] "GET /ads/redirectads/468x60redirect.htm HTTP/1.1" 200 541 "http://11.11.111.11/adframe.php?n=ad1f311a&what=zone:56" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.20 [ru\"]" -127.0.0.1 - u.surname@domain.com [12/Sep/2006:14:13:53 +0300] "GET /skins/monobook/external.png HTTP/1.0" 304 - "http://wiki.mysite.com/skins/monobook/main.css" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6" -""" -for line in testdata.split("\n"): - if not line: continue - fields = getLogLineBNF().parseString(line) - print(fields.dump()) - #~ print repr(fields) - #~ for k in fields.keys(): - #~ print "fields." + k + " =", fields[k] - print(fields.asXML("LOG")) - print() diff --git a/examples/idlParse.py b/examples/idlParse.py deleted file mode 100644 index b94bac4..0000000 --- a/examples/idlParse.py +++ /dev/null @@ -1,173 +0,0 @@ -# -# idlparse.py -# -# an example of using the parsing module to be able to process a subset of the CORBA IDL grammar -# -# Copyright (c) 2003, Paul McGuire -# - -from pyparsing import Literal, CaselessLiteral, Word, OneOrMore, ZeroOrMore, \ - Forward, NotAny, delimitedList, oneOf, Group, Optional, Combine, alphas, nums, restOfLine, cStyleComment, \ - alphanums, printables, empty, quotedString, ParseException, ParseResults, Keyword, Regex -import pprint -#~ import tree2image - -bnf = None -def CORBA_IDL_BNF(): - global bnf - - if not bnf: - - # punctuation - (colon,lbrace,rbrace,lbrack,rbrack,lparen,rparen, - equals,comma,dot,slash,bslash,star,semi,langle,rangle) = map(Literal, r":{}[]()=,./\*;<>") - - # keywords - (any_, attribute_, boolean_, case_, char_, const_, context_, default_, double_, enum_, exception_, - FALSE_, fixed_, float_, inout_, interface_, in_, long_, module_, Object_, octet_, oneway_, out_, raises_, - readonly_, sequence_, short_, string_, struct_, switch_, TRUE_, typedef_, unsigned_, union_, void_, - wchar_, wstring_) = map(Keyword, """any attribute boolean case char const context - default double enum exception FALSE fixed float inout interface in long module - Object octet oneway out raises readonly sequence short string struct switch - TRUE typedef unsigned union void wchar wstring""".split()) - - identifier = Word( alphas, alphanums + "_" ).setName("identifier") - - real = Regex(r"[+-]?\d+\.\d*([Ee][+-]?\d+)?").setName("real") - integer = Regex(r"0x[0-9a-fA-F]+|[+-]?\d+").setName("int") - - udTypeName = delimitedList( identifier, "::", combine=True ).setName("udType") - typeName = ( any_ | boolean_ | char_ | double_ | fixed_ | - float_ | long_ | octet_ | short_ | string_ | - wchar_ | wstring_ | udTypeName ).setName("type") - sequenceDef = Forward().setName("seq") - sequenceDef << Group( sequence_ + langle + ( sequenceDef | typeName ) + rangle ) - typeDef = sequenceDef | ( typeName + Optional( lbrack + integer + rbrack ) ) - typedefDef = Group( typedef_ + typeDef + identifier + semi ).setName("typedef") - - moduleDef = Forward() - constDef = Group( const_ + typeDef + identifier + equals + ( real | integer | quotedString ) + semi ) #| quotedString ) - exceptionItem = Group( typeDef + identifier + semi ) - exceptionDef = ( exception_ + identifier + lbrace + ZeroOrMore( exceptionItem ) + rbrace + semi ) - attributeDef = Optional( readonly_ ) + attribute_ + typeDef + identifier + semi - paramlist = delimitedList( Group( ( inout_ | in_ | out_ ) + typeName + identifier ) ).setName( "paramlist" ) - operationDef = ( ( void_ ^ typeDef ) + identifier + lparen + Optional( paramlist ) + rparen + \ - Optional( raises_ + lparen + Group( delimitedList( typeName ) ) + rparen ) + semi ) - interfaceItem = ( constDef | exceptionDef | attributeDef | operationDef ) - interfaceDef = Group( interface_ + identifier + Optional( colon + delimitedList( typeName ) ) + lbrace + \ - ZeroOrMore( interfaceItem ) + rbrace + semi ).setName("opnDef") - moduleItem = ( interfaceDef | exceptionDef | constDef | typedefDef | moduleDef ) - moduleDef << module_ + identifier + lbrace + ZeroOrMore( moduleItem ) + rbrace + semi - - bnf = ( moduleDef | OneOrMore( moduleItem ) ) - - singleLineComment = "//" + restOfLine - bnf.ignore( singleLineComment ) - bnf.ignore( cStyleComment ) - - return bnf - -testnum = 1 -def test( strng ): - global testnum - print(strng) - try: - bnf = CORBA_IDL_BNF() - tokens = bnf.parseString( strng ) - print("tokens = ") - pprint.pprint( tokens.asList() ) - imgname = "idlParse%02d.bmp" % testnum - testnum += 1 - #~ tree2image.str2image( str(tokens.asList()), imgname ) - except ParseException as err: - print(err.line) - print(" "*(err.column-1) + "^") - print(err) - print() - -if __name__ == "__main__": - test( - """ - /* - * a block comment * - */ - typedef string[10] tenStrings; - typedef sequence stringSeq; - typedef sequence< sequence > stringSeqSeq; - - interface QoSAdmin { - stringSeq method1( in string arg1, inout long arg2 ); - stringSeqSeq method2( in string arg1, inout long arg2, inout long arg3); - string method3(); - }; - """ - ) - test( - """ - /* - * a block comment * - */ - typedef string[10] tenStrings; - typedef - /** ** *** **** * - * a block comment * - */ - sequence /*comment inside an And */ stringSeq; - /* */ /**/ /***/ /****/ - typedef sequence< sequence > stringSeqSeq; - - interface QoSAdmin { - stringSeq method1( in string arg1, inout long arg2 ); - stringSeqSeq method2( in string arg1, inout long arg2, inout long arg3); - string method3(); - }; - """ - ) - test( - r""" - const string test="Test String\n"; - const long a = 0; - const long b = -100; - const float c = 3.14159; - const long d = 0x007f7f7f; - exception TestException - { - string msg; - sequence dataStrings; - }; - - interface TestInterface - { - void method1( in string arg1, inout long arg2 ); - }; - """ - ) - test( - """ - module Test1 - { - exception TestException - { - string msg; - ]; - - interface TestInterface - { - void method1( in string arg1, inout long arg2 ) - raises ( TestException ); - }; - }; - """ - ) - test( - """ - module Test1 - { - exception TestException - { - string msg; - }; - - }; - """ - ) diff --git a/examples/indentedGrammarExample.py b/examples/indentedGrammarExample.py deleted file mode 100644 index 442e6a4..0000000 --- a/examples/indentedGrammarExample.py +++ /dev/null @@ -1,54 +0,0 @@ -# indentedGrammarExample.py -# -# Copyright (c) 2006,2016 Paul McGuire -# -# A sample of a pyparsing grammar using indentation for -# grouping (like Python does). -# -# Updated to use indentedBlock helper method. -# - -from pyparsing import * - -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() -suite = indentedBlock(stmt, indentStack) - -identifier = Word(alphas, alphanums) -funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") -funcDef = Group( funcDecl + suite ) - -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) - -print(data) -parseTree = module_body.parseString(data) -parseTree.pprint() - diff --git a/examples/invRegex.py b/examples/invRegex.py deleted file mode 100644 index aea3b55..0000000 --- a/examples/invRegex.py +++ /dev/null @@ -1,257 +0,0 @@ -# -# invRegex.py -# -# Copyright 2008, Paul McGuire -# -# pyparsing script to expand a regular expression into all possible matching strings -# Supports: -# - {n} and {m,n} repetition, but not unbounded + or * repetition -# - ? optional elements -# - [] character ranges -# - () grouping -# - | alternation -# -__all__ = ["count","invert"] - -from pyparsing import (Literal, oneOf, printables, ParserElement, Combine, - SkipTo, infixNotation, ParseFatalException, Word, nums, opAssoc, - Suppress, ParseResults, srange) - -class CharacterRangeEmitter(object): - def __init__(self,chars): - # remove duplicate chars in character range, but preserve original order - seen = set() - self.charset = "".join( seen.add(c) or c for c in chars if c not in seen ) - def __str__(self): - return '['+self.charset+']' - def __repr__(self): - return '['+self.charset+']' - def makeGenerator(self): - def genChars(): - for s in self.charset: - yield s - return genChars - -class OptionalEmitter(object): - def __init__(self,expr): - self.expr = expr - def makeGenerator(self): - def optionalGen(): - yield "" - for s in self.expr.makeGenerator()(): - yield s - return optionalGen - -class DotEmitter(object): - def makeGenerator(self): - def dotGen(): - for c in printables: - yield c - return dotGen - -class GroupEmitter(object): - def __init__(self,exprs): - self.exprs = ParseResults(exprs) - def makeGenerator(self): - def groupGen(): - def recurseList(elist): - if len(elist)==1: - for s in elist[0].makeGenerator()(): - yield s - else: - for s in elist[0].makeGenerator()(): - for s2 in recurseList(elist[1:]): - yield s + s2 - if self.exprs: - for s in recurseList(self.exprs): - yield s - return groupGen - -class AlternativeEmitter(object): - def __init__(self,exprs): - self.exprs = exprs - def makeGenerator(self): - def altGen(): - for e in self.exprs: - for s in e.makeGenerator()(): - yield s - return altGen - -class LiteralEmitter(object): - def __init__(self,lit): - self.lit = lit - def __str__(self): - return "Lit:"+self.lit - def __repr__(self): - return "Lit:"+self.lit - def makeGenerator(self): - def litGen(): - yield self.lit - return litGen - -def handleRange(toks): - return CharacterRangeEmitter(srange(toks[0])) - -def handleRepetition(toks): - toks=toks[0] - if toks[1] in "*+": - raise ParseFatalException("",0,"unbounded repetition operators not supported") - if toks[1] == "?": - return OptionalEmitter(toks[0]) - if "count" in toks: - return GroupEmitter([toks[0]] * int(toks.count)) - if "minCount" in toks: - mincount = int(toks.minCount) - maxcount = int(toks.maxCount) - optcount = maxcount - mincount - if optcount: - opt = OptionalEmitter(toks[0]) - for i in range(1,optcount): - opt = OptionalEmitter(GroupEmitter([toks[0],opt])) - return GroupEmitter([toks[0]] * mincount + [opt]) - else: - return [toks[0]] * mincount - -def handleLiteral(toks): - lit = "" - for t in toks: - if t[0] == "\\": - if t[1] == "t": - lit += '\t' - else: - lit += t[1] - else: - lit += t - return LiteralEmitter(lit) - -def handleMacro(toks): - macroChar = toks[0][1] - if macroChar == "d": - return CharacterRangeEmitter("0123456789") - elif macroChar == "w": - return CharacterRangeEmitter(srange("[A-Za-z0-9_]")) - elif macroChar == "s": - return LiteralEmitter(" ") - else: - raise ParseFatalException("",0,"unsupported macro character (" + macroChar + ")") - -def handleSequence(toks): - return GroupEmitter(toks[0]) - -def handleDot(): - return CharacterRangeEmitter(printables) - -def handleAlternative(toks): - return AlternativeEmitter(toks[0]) - - -_parser = None -def parser(): - global _parser - if _parser is None: - ParserElement.setDefaultWhitespaceChars("") - lbrack,rbrack,lbrace,rbrace,lparen,rparen,colon,qmark = map(Literal,"[]{}():?") - - reMacro = Combine("\\" + oneOf(list("dws"))) - escapedChar = ~reMacro + Combine("\\" + oneOf(list(printables))) - reLiteralChar = "".join(c for c in printables if c not in r"\[]{}().*?+|") + " \t" - - reRange = Combine(lbrack + SkipTo(rbrack,ignore=escapedChar) + rbrack) - reLiteral = ( escapedChar | oneOf(list(reLiteralChar)) ) - reNonCaptureGroup = Suppress("?:") - reDot = Literal(".") - repetition = ( - ( lbrace + Word(nums)("count") + rbrace ) | - ( lbrace + Word(nums)("minCount")+","+ Word(nums)("maxCount") + rbrace ) | - oneOf(list("*+?")) - ) - - reRange.setParseAction(handleRange) - reLiteral.setParseAction(handleLiteral) - reMacro.setParseAction(handleMacro) - reDot.setParseAction(handleDot) - - reTerm = ( reLiteral | reRange | reMacro | reDot | reNonCaptureGroup) - reExpr = infixNotation( reTerm, - [ - (repetition, 1, opAssoc.LEFT, handleRepetition), - (None, 2, opAssoc.LEFT, handleSequence), - (Suppress('|'), 2, opAssoc.LEFT, handleAlternative), - ] - ) - _parser = reExpr - - return _parser - -def count(gen): - """Simple function to count the number of elements returned by a generator.""" - return sum(1 for _ in gen) - -def invert(regex): - r"""Call this routine as a generator to return all the strings that - match the input regular expression. - for s in invert(r"[A-Z]{3}\d{3}"): - print s - """ - invReGenerator = GroupEmitter(parser().parseString(regex)).makeGenerator() - return invReGenerator() - -def main(): - tests = r""" - [A-EA] - [A-D]* - [A-D]{3} - X[A-C]{3}Y - X[A-C]{3}\( - X\d - foobar\d\d - foobar{2} - foobar{2,9} - fooba[rz]{2} - (foobar){2} - ([01]\d)|(2[0-5]) - (?:[01]\d)|(2[0-5]) - ([01]\d\d)|(2[0-4]\d)|(25[0-5]) - [A-C]{1,2} - [A-C]{0,3} - [A-C]\s[A-C]\s[A-C] - [A-C]\s?[A-C][A-C] - [A-C]\s([A-C][A-C]) - [A-C]\s([A-C][A-C])? - [A-C]{2}\d{2} - @|TH[12] - @(@|TH[12])? - @(@|TH[12]|AL[12]|SP[123]|TB(1[0-9]?|20?|[3-9]))? - @(@|TH[12]|AL[12]|SP[123]|TB(1[0-9]?|20?|[3-9])|OH(1[0-9]?|2[0-9]?|30?|[4-9]))? - (([ECMP]|HA|AK)[SD]|HS)T - [A-CV]{2} - A[cglmrstu]|B[aehikr]?|C[adeflmorsu]?|D[bsy]|E[rsu]|F[emr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airu]|M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|S[bcegimnr]?|T[abcehilm]|Uu[bhopqst]|U|V|W|Xe|Yb?|Z[nr] - (a|b)|(x|y) - (a|b) (x|y) - [ABCDEFG](?:#|##|b|bb)?(?:maj|min|m|sus|aug|dim)?[0-9]?(?:/[ABCDEFG](?:#|##|b|bb)?)? - (Fri|Mon|S(atur|un)|T(hur|ue)s|Wednes)day - A(pril|ugust)|((Dec|Nov|Sept)em|Octo)ber|(Febr|Jan)uary|Ju(ly|ne)|Ma(rch|y) - """.split('\n') - - for t in tests: - t = t.strip() - if not t: continue - print('-'*50) - print(t) - try: - num = count(invert(t)) - print(num) - maxprint = 30 - for s in invert(t): - print(s) - maxprint -= 1 - if not maxprint: - break - except ParseFatalException as pfe: - print(pfe.msg) - print('') - continue - print('') - -if __name__ == "__main__": - main() diff --git a/examples/jsonParser.py b/examples/jsonParser.py deleted file mode 100644 index f080c6c..0000000 --- a/examples/jsonParser.py +++ /dev/null @@ -1,107 +0,0 @@ -# jsonParser.py -# -# Implementation of a simple JSON parser, returning a hierarchical -# ParseResults object support both list- and dict-style data access. -# -# Copyright 2006, by Paul McGuire -# -# Updated 8 Jan 2007 - fixed dict grouping bug, and made elements and -# members optional in array and object collections -# -# Updated 9 Aug 2016 - use more current pyparsing constructs/idioms -# -json_bnf = """ -object - { members } - {} -members - string : value - members , string : value -array - [ elements ] - [] -elements - value - elements , value -value - string - number - object - array - true - false - null -""" - -from pyparsing import * - -def make_keyword(kwd_str, kwd_value): - return Keyword(kwd_str).setParseAction(replaceWith(kwd_value)) -TRUE = make_keyword("true", True) -FALSE = make_keyword("false", False) -NULL = make_keyword("null", None) - -LBRACK, RBRACK, LBRACE, RBRACE, COLON = map(Suppress, "[]{}:") - -jsonString = dblQuotedString().setParseAction(removeQuotes) -jsonNumber = pyparsing_common.number() - -jsonObject = Forward() -jsonValue = Forward() -jsonElements = delimitedList( jsonValue ) -jsonArray = Group(LBRACK + Optional(jsonElements, []) + RBRACK) -jsonValue << (jsonString | jsonNumber | Group(jsonObject) | jsonArray | TRUE | FALSE | NULL) -memberDef = Group(jsonString + COLON + jsonValue) -jsonMembers = delimitedList(memberDef) -jsonObject << Dict(LBRACE + Optional(jsonMembers) + RBRACE) - -jsonComment = cppStyleComment -jsonObject.ignore(jsonComment) - - -if __name__ == "__main__": - testdata = """ - { - "glossary": { - "title": "example glossary", - "GlossDiv": { - "title": "S", - "GlossList": - { - "ID": "SGML", - "SortAs": "SGML", - "GlossTerm": "Standard Generalized Markup Language", - "TrueValue": true, - "FalseValue": false, - "Gravity": -9.8, - "LargestPrimeLessThan100": 97, - "AvogadroNumber": 6.02E23, - "EvenPrimesGreaterThan2": null, - "PrimesLessThan10" : [2,3,5,7], - "Acronym": "SGML", - "Abbrev": "ISO 8879:1986", - "GlossDef": "A meta-markup language, used to create markup languages such as DocBook.", - "GlossSeeAlso": ["GML", "XML", "markup"], - "EmptyDict" : {}, - "EmptyList" : [] - } - } - } - } - """ - - import pprint - results = jsonObject.parseString(testdata) - pprint.pprint( results.asList() ) - print() - def testPrint(x): - print(type(x),repr(x)) - print(list(results.glossary.GlossDiv.GlossList.keys())) - testPrint( results.glossary.title ) - testPrint( results.glossary.GlossDiv.GlossList.ID ) - testPrint( results.glossary.GlossDiv.GlossList.FalseValue ) - testPrint( results.glossary.GlossDiv.GlossList.Acronym ) - testPrint( results.glossary.GlossDiv.GlossList.EvenPrimesGreaterThan2 ) - testPrint( results.glossary.GlossDiv.GlossList.PrimesLessThan10 ) - - diff --git a/examples/linenoExample.py b/examples/linenoExample.py deleted file mode 100644 index 1186f48..0000000 --- a/examples/linenoExample.py +++ /dev/null @@ -1,49 +0,0 @@ -# -# linenoExample.py -# -# an example of using the location value returned by pyparsing to -# extract the line and column number of the location of the matched text, -# or to extract the entire line of text. -# -# Copyright (c) 2006, Paul McGuire -# -from pyparsing import * - -data = """Now is the time -for all good men -to come to the aid -of their country.""" - -# demonstrate use of lineno, line, and col in a parse action -def reportLongWords(st,locn,toks): - word = toks[0] - if len(word) > 3: - print("Found '%s' on line %d at column %d" % (word, lineno(locn,st), col(locn,st))) - print("The full line of text was:") - print("'%s'" % line(locn,st)) - print((" "*col(locn,st))+" ^") - print() - -wd = Word(alphas).setParseAction( reportLongWords ) -OneOrMore(wd).parseString(data) - - -# demonstrate returning an object from a parse action, containing more information -# than just the matching token text -class Token(object): - def __init__(self, st, locn, tokString): - self.tokenString = tokString - self.locn = locn - self.sourceLine = line(locn,st) - self.lineNo = lineno(locn,st) - self.col = col(locn,st) - def __str__(self): - return "%(tokenString)s (line: %(lineNo)d, col: %(col)d)" % self.__dict__ - -def createTokenObject(st,locn,toks): - return Token(st,locn, toks[0]) - -wd = Word(alphas).setParseAction( createTokenObject ) - -for tokenObj in OneOrMore(wd).parseString(data): - print(tokenObj) diff --git a/examples/list1.py b/examples/list1.py deleted file mode 100644 index 49a0bff..0000000 --- a/examples/list1.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# list1.py -# -# an example of using parse actions to convert type of parsed data. -# -# Copyright (c) 2006-2016, Paul McGuire -# -from pyparsing import * - -# first pass -lbrack = Literal("[") -rbrack = Literal("]") -integer = Word(nums).setName("integer") -real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." + - Optional(Word(nums))).setName("real") - -listItem = real | integer | quotedString - -listStr = lbrack + delimitedList(listItem) + rbrack - -test = "['a', 100, 3.14]" - -print(listStr.parseString(test)) - - -# second pass, cleanup and add converters -lbrack = Literal("[").suppress() -rbrack = Literal("]").suppress() -cvtInt = lambda s,l,toks: int(toks[0]) -cvtReal = lambda s,l,toks: float(toks[0]) -integer = Word(nums).setName("integer").setParseAction( cvtInt ) -real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." + - Optional(Word(nums))).setName("real").setParseAction( cvtReal ) -listItem = real | integer | quotedString.setParseAction( removeQuotes ) - -listStr = lbrack + delimitedList(listItem) + rbrack - -test = "['a', 100, 3.14]" - -print(listStr.parseString(test)) - -# third pass, add nested list support -lbrack, rbrack = map(Suppress, "[]") - -cvtInt = tokenMap(int) -cvtReal = tokenMap(float) - -integer = Word(nums).setName("integer").setParseAction( cvtInt ) -real = Regex(r"[+-]?\d+\.\d*").setName("real").setParseAction( cvtReal ) - -listStr = Forward() -listItem = real | integer | quotedString.setParseAction(removeQuotes) | Group(listStr) -listStr << lbrack + delimitedList(listItem) + rbrack - -test = "['a', 100, 3.14, [ +2.718, 'xyzzy', -1.414] ]" -print(listStr.parseString(test)) \ No newline at end of file diff --git a/examples/listAllMatches.py b/examples/listAllMatches.py deleted file mode 100644 index 1b1bdd4..0000000 --- a/examples/listAllMatches.py +++ /dev/null @@ -1,52 +0,0 @@ -# listAllMatches.py -# -# Sample program showing how/when to use listAllMatches to get all matching tokens in a results name. -# -# copyright 2006, Paul McGuire -# - -from pyparsing import oneOf, OneOrMore, printables, StringEnd - -test = "The quick brown fox named 'Aloysius' lives at 123 Main Street (and jumps over lazy dogs in his spare time)." -nonAlphas = [ c for c in printables if not c.isalpha() ] - -print("Extract vowels, consonants, and special characters from this test string:") -print("'" + test + "'") -print('') - -print("Define grammar using normal results names") -print("(only last matching symbol is saved)") -vowels = oneOf(list("aeiouy"), caseless=True)("vowels") -cons = oneOf(list("bcdfghjklmnpqrstvwxz"), caseless=True)("cons") -other = oneOf(nonAlphas)("others") -letters = OneOrMore(cons | vowels | other) + StringEnd() - -results = letters.parseString(test) -print(results) -print(results.vowels) -print(results.cons) -print(results.others) -print('') - - -print("Define grammar using results names, with listAllMatches=True") -print("(all matching symbols are saved)") -vowels = oneOf(list("aeiouy"), caseless=True)("vowels*") -cons = oneOf(list("bcdfghjklmnpqrstvwxz"), caseless=True)("cons*") -other = oneOf(nonAlphas)("others*") - -letters = OneOrMore(cons | vowels | other) - -results = letters.parseString(test, parseAll=True) -print(results) -print(sorted(set(results))) -print('') -print(results.vowels) -print(sorted(set(results.vowels))) -print('') -print(results.cons) -print(sorted(set(results.cons))) -print('') -print(results.others) -print(sorted(set(results.others))) - diff --git a/examples/lucene_grammar.py b/examples/lucene_grammar.py deleted file mode 100644 index 6e404d8..0000000 --- a/examples/lucene_grammar.py +++ /dev/null @@ -1,319 +0,0 @@ -# -# lucene_grammar.py -# -# Copyright 2011, Paul McGuire -# -# implementation of Lucene grammar, as decribed -# at http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/docs/queryparsersyntax.html -# - -from pyparsing import (Literal, CaselessKeyword, Forward, Regex, QuotedString, Suppress, - Optional, Group, FollowedBy, infixNotation, opAssoc, ParseException, ParserElement, - pyparsing_common) -ParserElement.enablePackrat() - -COLON,LBRACK,RBRACK,LBRACE,RBRACE,TILDE,CARAT = map(Literal,":[]{}~^") -LPAR,RPAR = map(Suppress,"()") -and_, or_, not_, to_ = map(CaselessKeyword, "AND OR NOT TO".split()) -keyword = and_ | or_ | not_ | to_ - -expression = Forward() - -valid_word = Regex(r'([a-zA-Z0-9*_+.-]|\\[!(){}\[\]^"~*?\\:])+').setName("word") -valid_word.setParseAction( - lambda t : t[0].replace('\\\\',chr(127)).replace('\\','').replace(chr(127),'\\') - ) - -string = QuotedString('"') - -required_modifier = Literal("+")("required") -prohibit_modifier = Literal("-")("prohibit") -integer = Regex(r"\d+").setParseAction(lambda t:int(t[0])) -proximity_modifier = Group(TILDE + integer("proximity")) -number = pyparsing_common.fnumber() -fuzzy_modifier = TILDE + Optional(number, default=0.5)("fuzzy") - -term = Forward() -field_name = valid_word().setName("fieldname") -incl_range_search = Group(LBRACK + term("lower") + to_ + term("upper") + RBRACK) -excl_range_search = Group(LBRACE + term("lower") + to_ + term("upper") + RBRACE) -range_search = incl_range_search("incl_range") | excl_range_search("excl_range") -boost = (CARAT + number("boost")) - -string_expr = Group(string + proximity_modifier) | string -word_expr = Group(valid_word + fuzzy_modifier) | valid_word -term << (Optional(field_name("field") + COLON) + - (word_expr | string_expr | range_search | Group(LPAR + expression + RPAR)) + - Optional(boost)) -term.setParseAction(lambda t:[t] if 'field' in t or 'boost' in t else None) - -expression << infixNotation(term, - [ - (required_modifier | prohibit_modifier, 1, opAssoc.RIGHT), - ((not_ | '!').setParseAction(lambda: "NOT"), 1, opAssoc.RIGHT), - ((and_ | '&&').setParseAction(lambda: "AND"), 2, opAssoc.LEFT), - (Optional(or_ | '||').setParseAction(lambda: "OR"), 2, opAssoc.LEFT), - ]) - -# test strings taken from grammar description doc, and TestQueryParser.java -tests = r""" - a and b - a and not b - a and !b - a && !b - a&&!b - name:a - name:a and not title:b - (a^100 c d f) and !z - name:"blah de blah" - title:(+return +"pink panther") - title:"The Right Way" AND text:go - title:"Do it right" AND right - title:Do it right - roam~ - roam~0.8 - "jakarta apache"~10 - mod_date:[20020101 TO 20030101] - title:{Aida TO Carmen} - jakarta apache - jakarta^4 apache - "jakarta apache"^4 "Apache Lucene" - "jakarta apache" jakarta - "jakarta apache" OR jakarta - "jakarta apache" AND "Apache Lucene" - +jakarta lucene - "jakarta apache" NOT "Apache Lucene" - "jakarta apache" -"Apache Lucene" - (jakarta OR apache) AND website - \(1+1\)\:2 - c\:\\windows - (fieldX:xxxxx OR fieldy:xxxxxxxx)^2 AND (fieldx:the OR fieldy:foo) - (fieldX:xxxxx fieldy:xxxxxxxx)^2 AND (fieldx:the fieldy:foo) - (fieldX:xxxxx~0.5 fieldy:xxxxxxxx)^2 AND (fieldx:the fieldy:foo) - +term -term term - foo:term AND field:anotherTerm - germ term^2.0 - (term)^2.0 - (foo OR bar) AND (baz OR boo) - +(apple \"steve jobs\") -(foo bar baz) - +title:(dog OR cat) -author:\"bob dole\" - a AND b - +a +b - (a AND b) - c OR (a AND b) - c (+a +b) - a AND NOT b - +a -b - a AND -b - a AND !b - a && b - a && ! b - a OR b - a b - a || b - a OR !b - a -b - a OR ! b - a OR -b - a - b - a + b - a ! b - +foo:term +anotherterm - hello - term^2.0 - (germ term)^2.0 - term^2 - +(foo bar) +(baz boo) - ((a OR b) AND NOT c) OR d - (+(a b) -c) d - field - a&&b - .NET - term - germ - 3 - term 1.0 1 2 - term term1 term2 - term term term - term* - term*^2 - term*^2.0 - term~ - term~2.0 - term~0.7 - term~^3 - term~2.0^3.0 - term*germ - term*germ^3 - term*germ^3.0 - term~1.1 - [A TO C] - t*erm* - *term* - term term^3.0 term - term stop^3.0 term - term +stop term - term -stop term - drop AND (stop) AND roll - +drop +roll - term +(stop) term - term -(stop) term - drop AND stop AND roll - term phrase term - term (phrase1 phrase2) term - term AND NOT phrase term - +term -(phrase1 phrase2) term - stop^3 - stop - (stop)^3 - ((stop))^3 - (stop^3) - ((stop)^3) - (stop) - ((stop)) - term +stop - [ a TO z] - [a TO z] - [ a TO z ] - { a TO z} - {a TO z} - { a TO z } - { a TO z }^2.0 - {a TO z}^2.0 - [ a TO z] OR bar - [a TO z] bar - [ a TO z] AND bar - +[a TO z] +bar - ( bar blar { a TO z}) - bar blar {a TO z} - gack ( bar blar { a TO z}) - gack (bar blar {a TO z}) - [* TO Z] - [* TO z] - [A TO *] - [a TO *] - [* TO *] - [\* TO \*] - \!blah - \:blah - blah - \~blah - \*blah - a - a-b:c - a+b:c - a\:b:c - a\\b:c - a:b-c - a:b+c - a:b\:c - a:b\\c - a:b-c* - a:b+c* - a:b\:c* - a:b\\c* - a:b-c~2.0 - a:b+c~2.0 - a:b\:c~ - a:b\\c~ - [a- TO a+] - [ a\\ TO a\* ] - c\:\\temp\\\~foo.txt - abc - XYZ - (item:\\ item:ABCD\\) - \* - * - \\ - a\:b\:c - a\\b\:c - a\:b\\c - a\:b\:c\* - a\:b\\\\c\* - a:b-c~ - a:b+c~ - a\:b\:c\~ - a\:b\\c\~ - +weltbank +worlbank - +term +term +term - term +term term - term term +term - term +term +term - -term term term - -term +term +term - on - on^1.0 - hello^2.0 - the^3 - the - some phrase - xunit~ - one two three - A AND B OR C AND D - +A +B +C +D - foo:zoo* - foo:zoo*^2 - zoo - foo:* - foo:*^2 - *:foo - a:the OR a:foo - a:woo OR a:the - *:* - (*:*) - +*:* -*:* - the wizard of ozzy - """ - -failtests = r""" - field:term:with:colon some more terms - (sub query)^5.0^2.0 plus more - a:b:c - a:b:c~ - a:b:c* - a:b:c~2.0 - \+blah - \-blah - foo \|| bar - foo \AND bar - \a - a\-b:c - a\+b:c - a\b:c - a:b\-c - a:b\+c - a\-b\:c - a\+b\:c - a:b\c* - a:b\-c~ - a:b\+c~ - a:b\c - a:b\-c* - a:b\+c* - [ a\- TO a\+ ] - [a\ TO a*] - a\\\+b - a\+b - c:\temp\~foo.txt - XY\ - a\u0062c - a:b\c~2.0 - XY\u005a - XY\u005A - item:\ item:ABCD\ - \ - a\ or b - a\:b\-c - a\:b\+c - a\:b\-c\* - a\:b\+c\* - a\:b\-c\~ - a\:b\+c\~ - a:b\c~ - [ a\ TO a* ] - """ - -success1, _ = expression.runTests(tests) -success2, _ = expression.runTests(failtests, failureTests=True) - -print(("FAIL", "OK")[success1 and success2]) diff --git a/examples/macroExpander.py b/examples/macroExpander.py deleted file mode 100644 index 327976c..0000000 --- a/examples/macroExpander.py +++ /dev/null @@ -1,60 +0,0 @@ -# macroExpander.py -# -# Example pyparsing program for performing macro expansion, similar to -# the C pre-processor. This program is not as fully-featured, simply -# processing macros of the form: -# #def xxx yyyyy -# and replacing xxx with yyyyy in the rest of the input string. Macros -# can also be composed using other macros, such as -# #def zzz xxx+1 -# Since xxx was previously defined as yyyyy, then zzz will be replaced -# with yyyyy+1. -# -# Copyright 2007 by Paul McGuire -# -from pyparsing import * - -# define the structure of a macro definition (the empty term is used -# to advance to the next non-whitespace character) -identifier = Word(alphas+"_",alphanums+"_") -macroDef = "#def" + identifier("macro") + empty + restOfLine("value") - -# define a placeholder for defined macros - initially nothing -macroExpr = Forward() -macroExpr << NoMatch() - -# global dictionary for macro definitions -macros = {} - -# parse action for macro definitions -def processMacroDefn(s,l,t): - macroVal = macroExpander.transformString(t.value) - macros[t.macro] = macroVal - macroExpr << MatchFirst(map(Keyword, macros.keys())) - return "#def " + t.macro + " " + macroVal - -# parse action to replace macro references with their respective definition -def processMacroRef(s,l,t): - return macros[t[0]] - -# attach parse actions to expressions -macroExpr.setParseAction(processMacroRef) -macroDef.setParseAction(processMacroDefn) - -# define pattern for scanning through the input string -macroExpander = macroExpr | macroDef - - - -# test macro substitution using transformString -testString = """ - #def A 100 - #def ALEN A+1 - - char Astring[ALEN]; - char AA[A]; - typedef char[ALEN] Acharbuf; - """ - -print(macroExpander.transformString(testString)) -print(macros) diff --git a/examples/makeHTMLTagExample.py b/examples/makeHTMLTagExample.py deleted file mode 100644 index 3b771c7..0000000 --- a/examples/makeHTMLTagExample.py +++ /dev/null @@ -1,21 +0,0 @@ -import urllib.request, urllib.parse, urllib.error - -from pyparsing import makeHTMLTags, SkipTo - -# read HTML from a web page -serverListPage = urllib.request.urlopen( "http://www.yahoo.com" ) -htmlText = serverListPage.read() -serverListPage.close() - -# using makeHTMLTags to define opening and closing tags -anchorStart,anchorEnd = makeHTMLTags("a") - -# compose an expression for an anchored reference -anchor = anchorStart + SkipTo(anchorEnd)("body") + anchorEnd - -# use scanString to scan through the HTML source, extracting -# just the anchor tags and their associated body text -# (note the href attribute of the opening A tag is available -# as an attribute in the returned parse results) -for tokens,start,end in anchor.scanString(htmlText): - print(tokens.body,'->',tokens.href) diff --git a/examples/matchPreviousDemo.py b/examples/matchPreviousDemo.py deleted file mode 100644 index f0812e9..0000000 --- a/examples/matchPreviousDemo.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# matchPreviousDemo.py -# - -from pyparsing import * - -src = """ -class a -... -end a; - -class b -... -end b; - -class c -... -end d;""" - - -identifier = Word(alphas) - -classIdent = identifier("classname") # note that this also makes a copy of identifier -classHead = "class" + classIdent -classBody = "..." -classEnd = "end" + matchPreviousLiteral(classIdent) + ';' -classDefn = classHead + classBody + classEnd - -# use this form to catch syntax error -# classDefn = classHead + classBody - classEnd - -for tokens in classDefn.searchString(src): - print(tokens.classname) \ No newline at end of file diff --git a/examples/mozilla.ics b/examples/mozilla.ics deleted file mode 100644 index e6dd3dc..0000000 --- a/examples/mozilla.ics +++ /dev/null @@ -1,50 +0,0 @@ -BEGIN:VCALENDAR -VERSION - :2.0 -PRODID - :-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN -METHOD - :PUBLISH -BEGIN:VEVENT -UID - :153ed0e0-1dd2-11b2-9d71-96da104537a4 -SUMMARY - :Test event -DESCRIPTION - :Some notes -LOCATION - :Somewhere over the rainbow -CATEGORIES - :Personal -URL - :http://personal.amec.fi -STATUS - :CONFIRMED -CLASS - :PRIVATE -X - ;MEMBER=AlarmEmailAddress - :petri.savolainen@iki.fi -X-MOZILLA-RECUR-DEFAULT-UNITS - :months -RRULE - :FREQ=MONTHLY;UNTIL=20040914;INTERVAL=1 -EXDATE - :20040714T000000 -DTSTART - ;VALUE=DATE - :20040714 -DTEND - ;VALUE=DATE - :20040815 -DTSTAMP - :20040714T141219Z -LAST-MODIFIED - :20040714T141457Z -BEGIN:VALARM -TRIGGER - ;VALUE=DURATION - :PT15M -END:VALARM -END:VEVENT -END:VCALENDAR diff --git a/examples/mozillaCalendarParser.py b/examples/mozillaCalendarParser.py deleted file mode 100644 index 210f284..0000000 --- a/examples/mozillaCalendarParser.py +++ /dev/null @@ -1,81 +0,0 @@ -from pyparsing import Optional, oneOf, Dict, Literal, Word, printables, Group, OneOrMore, ZeroOrMore - -""" -A simple parser for calendar (*.ics) files, -as exported by the Mozilla calendar. - -Any suggestions and comments welcome. - -Version: 0.1 -Copyright: Petri Savolainen -License: Free for any use -""" - - -# TERMINALS - -BEGIN = Literal("BEGIN:").suppress() -END = Literal("END:").suppress() -valstr = printables + "\xe4\xf6\xe5\xd6\xc4\xc5 " - -EQ = Literal("=").suppress() -SEMI = Literal(";").suppress() -COLON = Literal(":").suppress() - -EVENT = Literal("VEVENT").suppress() -CALENDAR = Literal("VCALENDAR").suppress() -ALARM = Literal("VALARM").suppress() - -# TOKENS - -CALPROP = oneOf("VERSION PRODID METHOD") -ALMPROP = oneOf("TRIGGER") -EVTPROP = oneOf("X-MOZILLA-RECUR-DEFAULT-INTERVAL \ - X-MOZILLA-RECUR-DEFAULT-UNITS \ - UID DTSTAMP LAST-MODIFIED X RRULE EXDATE") - -propval = Word(valstr) -typeval = Word(valstr) -typename = oneOf("VALUE MEMBER FREQ UNTIL INTERVAL") - -proptype = Group(SEMI + typename + EQ + typeval).suppress() - -calprop = Group(CALPROP + ZeroOrMore(proptype) + COLON + propval) -almprop = Group(ALMPROP + ZeroOrMore(proptype) + COLON + propval) -evtprop = Group(EVTPROP + ZeroOrMore(proptype) + COLON + propval).suppress() \ - | "CATEGORIES" + COLON + propval.setResultsName("categories") \ - | "CLASS" + COLON + propval.setResultsName("class") \ - | "DESCRIPTION" + COLON + propval.setResultsName("description") \ - | "DTSTART" + proptype + COLON + propval.setResultsName("begin") \ - | "DTEND" + proptype + COLON + propval.setResultsName("end") \ - | "LOCATION" + COLON + propval.setResultsName("location") \ - | "PRIORITY" + COLON + propval.setResultsName("priority") \ - | "STATUS" + COLON + propval.setResultsName("status") \ - | "SUMMARY" + COLON + propval.setResultsName("summary") \ - | "URL" + COLON + propval.setResultsName("url") \ - -calprops = Group(OneOrMore(calprop)).suppress() -evtprops = Group(OneOrMore(evtprop)) -almprops = Group(OneOrMore(almprop)).suppress() - -alarm = BEGIN + ALARM + almprops + END + ALARM -event = BEGIN + EVENT + evtprops + Optional(alarm) + END + EVENT -events = Group(OneOrMore(event)) -calendar = BEGIN + CALENDAR + calprops + ZeroOrMore(event) + END + CALENDAR -calendars = OneOrMore(calendar) - - -# PARSE ACTIONS - -def gotEvent(s,loc,toks): - for event in toks: - print(event.dump()) - -event.setParseAction(gotEvent) - - -# MAIN PROGRAM - -if __name__=="__main__": - - calendars.parseFile("mozilla.ics") diff --git a/examples/nested.py b/examples/nested.py deleted file mode 100644 index 24cf2f4..0000000 --- a/examples/nested.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# nested.py -# Copyright, 2007 - Paul McGuire -# -# Simple example of using nestedExpr to define expressions using -# paired delimiters for grouping lists and sublists -# - -from pyparsing import * -import pprint - -data = """ -{ - { item1 "item with } in it" } - { - {item2a item2b } - {item3} - } - -} -""" - -# use {}'s for nested lists -nestedItems = nestedExpr("{", "}") -print(( (nestedItems+stringEnd).parseString(data).asList() )) - -# use default delimiters of ()'s -mathExpr = nestedExpr() -print(( mathExpr.parseString( "((( ax + by)*C) *(Z | (E^F) & D))") )) - diff --git a/examples/numerics.py b/examples/numerics.py deleted file mode 100644 index 5ab99dd..0000000 --- a/examples/numerics.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# numerics.py -# -# Examples of parsing real and integers using various grouping and -# decimal point characters, varying by locale. -# -# Copyright 2016, Paul McGuire -# -# Format samples from https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html -# -tests = """\ -# Canadian (English and French) -4 294 967 295,000 - -# Danish -4 294 967 295,000 - -# Finnish -4 294 967 295,000 - -# French -4 294 967 295,000 - -# German -4 294 967 295,000 - -# Italian -4.294.967.295,000 - -# Norwegian -4.294.967.295,000 - -# Spanish -4.294.967.295,000 - -# Swedish -4 294 967 295,000 - -# GB-English -4,294,967,295.000 - -# US-English -4,294,967,295.000 - -# Thai -4,294,967,295.000 -""" - -from pyparsing import Regex - -comma_decimal = Regex(r'\d{1,2}(([ .])\d\d\d(\2\d\d\d)*)?,\d*') -comma_decimal.setParseAction(lambda t: float(t[0].replace(' ','').replace('.','').replace(',','.'))) - -dot_decimal = Regex(r'\d{1,2}(([ ,])\d\d\d(\2\d\d\d)*)?\.\d*') -dot_decimal.setParseAction(lambda t: float(t[0].replace(' ','').replace(',',''))) - -decimal = comma_decimal ^ dot_decimal -decimal.runTests(tests, parseAll=True) - -grouped_integer = Regex(r'\d{1,2}(([ .,])\d\d\d(\2\d\d\d)*)?') -grouped_integer.setParseAction(lambda t: int(t[0].replace(' ','').replace(',','').replace('.',''))) -grouped_integer.runTests(tests, parseAll=False) diff --git a/examples/oc.py b/examples/oc.py deleted file mode 100644 index 42b9d48..0000000 --- a/examples/oc.py +++ /dev/null @@ -1,186 +0,0 @@ -# oc.py -# -# A subset-C parser, (BNF taken from 1996 International Obfuscated C Code Contest) -# -# Copyright, 2010, Paul McGuire -# -""" -http://www.ioccc.org/1996/august.hint - -The following is a description of the OC grammar: - - OC grammar - ========== - Terminals are in quotes, () is used for bracketing. - - program: decl* - - decl: vardecl - fundecl - - vardecl: type NAME ; - type NAME "[" INT "]" ; - - fundecl: type NAME "(" args ")" "{" body "}" - - args: /*empty*/ - ( arg "," )* arg - - arg: type NAME - - body: vardecl* stmt* - - stmt: ifstmt - whilestmt - dowhilestmt - "return" expr ";" - expr ";" - "{" stmt* "}" - ";" - - ifstmt: "if" "(" expr ")" stmt - "if" "(" expr ")" stmt "else" stmt - - whilestmt: "while" "(" expr ")" stmt - - dowhilestmt: "do" stmt "while" "(" expr ")" ";" - - expr: expr binop expr - unop expr - expr "[" expr "]" - "(" expr ")" - expr "(" exprs ")" - NAME - INT - CHAR - STRING - - exprs: /*empty*/ - (expr ",")* expr - - binop: "+" | "-" | "*" | "/" | "%" | - "=" | - "<" | "==" | "!=" - - unop: "!" | "-" | "*" - - type: "int" stars - "char" stars - - stars: "*"* -""" - -from pyparsing import * - -LPAR,RPAR,LBRACK,RBRACK,LBRACE,RBRACE,SEMI,COMMA = map(Suppress, "()[]{};,") -INT, CHAR, WHILE, DO, IF, ELSE, RETURN = map(Keyword, - "int char while do if else return".split()) - -NAME = Word(alphas+"_", alphanums+"_") -integer = Regex(r"[+-]?\d+") -char = Regex(r"'.'") -string_ = dblQuotedString - -TYPE = Group((INT | CHAR) + ZeroOrMore("*")) - -expr = Forward() -operand = NAME | integer | char | string_ -expr << (infixNotation(operand, - [ - (oneOf('! - *'), 1, opAssoc.RIGHT), - (oneOf('++ --'), 1, opAssoc.RIGHT), - (oneOf('++ --'), 1, opAssoc.LEFT), - (oneOf('* / %'), 2, opAssoc.LEFT), - (oneOf('+ -'), 2, opAssoc.LEFT), - (oneOf('< == > <= >= !='), 2, opAssoc.LEFT), - (Regex(r'=[^=]'), 2, opAssoc.LEFT), - ]) + - Optional( LBRACK + expr + RBRACK | - LPAR + Group(Optional(delimitedList(expr))) + RPAR ) - ) - -stmt = Forward() - -ifstmt = IF - LPAR + expr + RPAR + stmt + Optional(ELSE + stmt) -whilestmt = WHILE - LPAR + expr + RPAR + stmt -dowhilestmt = DO - stmt + WHILE + LPAR + expr + RPAR + SEMI -returnstmt = RETURN - expr + SEMI - -stmt << Group( ifstmt | - whilestmt | - dowhilestmt | - returnstmt | - expr + SEMI | - LBRACE + ZeroOrMore(stmt) + RBRACE | - SEMI) - -vardecl = Group(TYPE + NAME + Optional(LBRACK + integer + RBRACK)) + SEMI - -arg = Group(TYPE + NAME) -body = ZeroOrMore(vardecl) + ZeroOrMore(stmt) -fundecl = Group(TYPE + NAME + LPAR + Optional(Group(delimitedList(arg))) + RPAR + - LBRACE + Group(body) + RBRACE) -decl = fundecl | vardecl -program = ZeroOrMore(decl) - -program.ignore(cStyleComment) - -# set parser element names -for vname in ("ifstmt whilestmt dowhilestmt returnstmt TYPE " - "NAME fundecl vardecl program arg body stmt".split()): - v = vars()[vname] - v.setName(vname) - -#~ for vname in "fundecl stmt".split(): - #~ v = vars()[vname] - #~ v.setDebug() - -test = r""" -/* A factorial program */ -int -putstr(char *s) -{ - while(*s) - putchar(*s++); -} - -int -fac(int n) -{ - if (n == 0) - return 1; - else - return n*fac(n-1); -} - -int -putn(int n) -{ - if (9 < n) - putn(n / 10); - putchar((n%10) + '0'); -} - -int -facpr(int n) -{ - putstr("factorial "); - putn(n); - putstr(" = "); - putn(fac(n)); - putstr("\n"); -} - -int -main() -{ - int i; - i = 0; - while(i < 10) - facpr(i++); - return 0; -} -""" - -ast = program.parseString(test, parseAll=True) -ast.pprint() diff --git a/examples/parseListString.py b/examples/parseListString.py deleted file mode 100644 index d74f3af..0000000 --- a/examples/parseListString.py +++ /dev/null @@ -1,82 +0,0 @@ -# parseListString.py -# -# Copyright, 2006, by Paul McGuire -# - -from pyparsing import * - -# first pass -lbrack = Literal("[") -rbrack = Literal("]") -integer = Word(nums).setName("integer") -real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." + - Optional(Word(nums))).setName("real") - -listItem = real | integer | quotedString - -listStr = lbrack + delimitedList(listItem) + rbrack - -test = "['a', 100, 3.14]" - -print(listStr.parseString(test)) - - -# second pass, cleanup and add converters -lbrack = Literal("[").suppress() -rbrack = Literal("]").suppress() -cvtInt = lambda s,l,toks: int(toks[0]) -integer = Word(nums).setName("integer").setParseAction( cvtInt ) -cvtReal = lambda s,l,toks: float(toks[0]) -real = Regex(r'[+-]?\d+\.\d*').setName("floating-point number").setParseAction( cvtReal ) -listItem = real | integer | quotedString.setParseAction( removeQuotes ) - -listStr = lbrack + delimitedList(listItem) + rbrack - -test = "['a', 100, 3.14]" - -print(listStr.parseString(test)) - -# third pass, add nested list support, and tuples, too! -cvtInt = lambda s,l,toks: int(toks[0]) -cvtReal = lambda s,l,toks: float(toks[0]) - -lbrack = Literal("[").suppress() -rbrack = Literal("]").suppress() -integer = Word(nums).setName("integer").setParseAction( cvtInt ) -real = Regex(r'[+-]?\d+\.\d*').setName("floating-point number").setParseAction( cvtReal ) -tupleStr = Forward() -listStr = Forward() -listItem = real | integer | quotedString.setParseAction(removeQuotes) | Group(listStr) | tupleStr -tupleStr << ( Suppress("(") + delimitedList(listItem) + Optional(Suppress(",")) + Suppress(")") ) -tupleStr.setParseAction( lambda t:tuple(t.asList()) ) -listStr << lbrack + delimitedList(listItem) + Optional(Suppress(",")) + rbrack - -test = "['a', 100, ('A', [101,102]), 3.14, [ +2.718, 'xyzzy', -1.414] ]" -print(listStr.parseString(test)) - -# fourth pass, add parsing of dicts -cvtInt = lambda s,l,toks: int(toks[0]) -cvtReal = lambda s,l,toks: float(toks[0]) -cvtDict = lambda s,l,toks: dict(toks[0]) - -lbrack = Literal("[").suppress() -rbrack = Literal("]").suppress() -lbrace = Literal("{").suppress() -rbrace = Literal("}").suppress() -colon = Literal(":").suppress() -integer = Word(nums).setName("integer").setParseAction( cvtInt ) -real = Regex(r'[+-]?\d+\.\d*').setName("real").setParseAction( cvtReal ) - -tupleStr = Forward() -listStr = Forward() -dictStr = Forward() -listItem = real | integer | quotedString.setParseAction(removeQuotes) | Group(listStr) | tupleStr | dictStr -tupleStr <<= ( Suppress("(") + delimitedList(listItem) + Optional(Suppress(",")) + Suppress(")") ) -tupleStr.setParseAction( lambda t:tuple(t.asList()) ) -listStr <<= (lbrack + Optional(delimitedList(listItem)) + Optional(Suppress(",")) + rbrack) -dictKeyStr = real | integer | quotedString.setParseAction(removeQuotes) -dictStr <<= lbrace + Optional(delimitedList( Group( dictKeyStr + colon + listItem ))) + Optional(Suppress(",")) + rbrace -dictStr.setParseAction(lambda t: dict((k_v[0],(k_v[1].asList() if isinstance(k_v[1],ParseResults) else k_v[1])) for k_v in t)) - -test = '[{0: [2], 1: []}, {0: [], 1: [], 2: [,]}, {0: [1, 2,],}]' -print(listStr.parseString(test)) diff --git a/examples/parsePythonValue.py b/examples/parsePythonValue.py deleted file mode 100644 index 53c61fc..0000000 --- a/examples/parsePythonValue.py +++ /dev/null @@ -1,70 +0,0 @@ -# parsePythonValue.py -# -# Copyright, 2006, by Paul McGuire -# -from __future__ import print_function -from pyparsing import * - - -cvtBool = lambda t:t[0]=='True' -cvtInt = lambda toks: int(toks[0]) -cvtReal = lambda toks: float(toks[0]) -cvtTuple = lambda toks : tuple(toks.asList()) -cvtDict = lambda toks: dict(toks.asList()) -cvtList = lambda toks: [toks.asList()] - -# define punctuation as suppressed literals -lparen,rparen,lbrack,rbrack,lbrace,rbrace,colon = \ - map(Suppress,"()[]{}:") - -integer = Regex(r"[+-]?\d+")\ - .setName("integer")\ - .setParseAction( cvtInt ) -real = Regex(r"[+-]?\d+\.\d*([Ee][+-]?\d+)?")\ - .setName("real")\ - .setParseAction( cvtReal ) -tupleStr = Forward() -listStr = Forward() -dictStr = Forward() - -unicodeString.setParseAction(lambda t:t[0][2:-1].decode('unicode-escape')) -quotedString.setParseAction(lambda t:t[0][1:-1].decode('string-escape')) -boolLiteral = oneOf("True False").setParseAction(cvtBool) -noneLiteral = Literal("None").setParseAction(replaceWith(None)) - -listItem = real|integer|quotedString|unicodeString|boolLiteral|noneLiteral| \ - Group(listStr) | tupleStr | dictStr - -tupleStr << ( Suppress("(") + Optional(delimitedList(listItem)) + - Optional(Suppress(",")) + Suppress(")") ) -tupleStr.setParseAction( cvtTuple ) - -listStr << (lbrack + Optional(delimitedList(listItem) + - Optional(Suppress(","))) + rbrack) -listStr.setParseAction(cvtList, lambda t: t[0]) - -dictEntry = Group( listItem + colon + listItem ) -dictStr << (lbrace + Optional(delimitedList(dictEntry) + \ - Optional(Suppress(","))) + rbrace) -dictStr.setParseAction( cvtDict ) - -tests = """['a', 100, ('A', [101,102]), 3.14, [ +2.718, 'xyzzy', -1.414] ] - [{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}] - { 'A':1, 'B':2, 'C': {'a': 1.2, 'b': 3.4} } - 3.14159 - 42 - 6.02E23 - 6.02e+023 - 1.0e-7 - 'a quoted string'""".split("\n") - -for test in tests: - print("Test:", test.strip()) - result = listItem.parseString(test)[0] - print("Result:", result) - try: - for dd in result: - if isinstance(dd,dict): print(list(dd.items())) - except TypeError as te: - pass - print() diff --git a/examples/parseResultsSumExample.py b/examples/parseResultsSumExample.py deleted file mode 100644 index 1fb694a..0000000 --- a/examples/parseResultsSumExample.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# parseResultsSumExample.py -# -# Sample script showing the value in merging ParseResults retrieved by searchString, -# using Python's builtin sum() method -# -samplestr1 = "garbage;DOB 10-10-2010;more garbage\nID PARI12345678;more garbage" -samplestr2 = "garbage;ID PARI12345678;more garbage\nDOB 10-10-2010;more garbage" -samplestr3 = "garbage;DOB 10-10-2010" -samplestr4 = "garbage;ID PARI12345678;more garbage- I am cool" - -from pyparsing import * -dob_ref = "DOB" + Regex(r"\d{2}-\d{2}-\d{4}")("dob") -id_ref = "ID" + Word(alphanums,exact=12)("id") -info_ref = "-" + restOfLine("info") - -person_data = dob_ref | id_ref | info_ref - -for test in (samplestr1,samplestr2,samplestr3,samplestr4,): - person = sum(person_data.searchString(test)) - print(person.id) - print(person.dump()) - print() - - - \ No newline at end of file diff --git a/examples/parseTabularData.py b/examples/parseTabularData.py deleted file mode 100644 index 3846310..0000000 --- a/examples/parseTabularData.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# parseTabularData.py -# -# Example of parsing data that is formatted in a tabular listing, with -# potential for missing values. Uses new addCondition method on -# ParserElements. -# -# Copyright 2015, Paul McGuire -# -from pyparsing import col,Word,Optional,alphas,nums,ParseException - -table = """\ - 1 2 -12345678901234567890 -COLOR S M L -RED 10 2 2 -BLUE 5 10 -GREEN 3 5 -PURPLE 8""" - -# function to create column-specific parse conditions -def mustMatchCols(startloc,endloc): - return lambda s,l,t: startloc <= col(l,s) <= endloc - -# helper to define values in a space-delimited table -# (change empty_cell_is_zero to True if a value of 0 is desired for empty cells) -def tableValue(expr, colstart, colend): - empty_cell_is_zero = False - if empty_cell_is_zero: - return Optional(expr.copy().addCondition(mustMatchCols(colstart,colend), - message="text not in expected columns"), - default=0) - else: - return Optional(expr.copy().addCondition(mustMatchCols(colstart,colend), - message="text not in expected columns")) - - -# define the grammar for this simple table -colorname = Word(alphas) -integer = Word(nums).setParseAction(lambda t: int(t[0])).setName("integer") -row = (colorname("name") + - tableValue(integer, 11, 12)("S") + - tableValue(integer, 15, 16)("M") + - tableValue(integer, 19, 20)("L")) - -# parse the sample text - skip over the header and counter lines -for line in table.splitlines()[3:]: - print(line) - print(row.parseString(line).dump()) - print('') diff --git a/examples/partial_gene_match.py b/examples/partial_gene_match.py deleted file mode 100644 index 8bf5f7c..0000000 --- a/examples/partial_gene_match.py +++ /dev/null @@ -1,88 +0,0 @@ -# parital_gene_match.py -# -# Example showing how to create a customized pyparsing Token, in this case, -# one that is very much like Literal, but which tolerates up to 'n' character -# mismatches -from pyparsing import * - -import urllib.request, urllib.parse, urllib.error - -# read in a bunch of genomic data -datafile = urllib.request.urlopen("http://toxodb.org/common/downloads/release-6.0/Tgondii/TgondiiApicoplastORFsNAs_ToxoDB-6.0.fasta") -fastasrc = datafile.read() -datafile.close() - -""" -Sample header: ->NC_001799-6-2978-2778 | organism=Toxoplasma_gondii_RH | location=NC_001799:2778-2978(-) | length=201 -""" -integer = Word(nums).setParseAction(lambda t:int(t[0])) -genebit = Group(">" + Word(alphanums.upper()+"-_") + "|" + - Word(printables)("id") + SkipTo("length=", include=True) + - integer("genelen") + LineEnd() + - Combine(OneOrMore(Word("ACGTN")),adjacent=False)("gene")) - -# read gene data from .fasta file - takes just a few seconds -genedata = OneOrMore(genebit).parseString(fastasrc) - - -class CloseMatch(Token): - """A special subclass of Token that does *close* matches. For each - close match of the given string, a tuple is returned giving the - found close match, and a list of mismatch positions.""" - def __init__(self, seq, maxMismatches=1): - super(CloseMatch,self).__init__() - self.name = seq - self.sequence = seq - self.maxMismatches = maxMismatches - self.errmsg = "Expected " + self.sequence - self.mayIndexError = False - self.mayReturnEmpty = False - - def parseImpl( self, instring, loc, doActions=True ): - start = loc - instrlen = len(instring) - maxloc = start + len(self.sequence) - - if maxloc <= instrlen: - seq = self.sequence - seqloc = 0 - mismatches = [] - throwException = False - done = False - while loc < maxloc and not done: - if instring[loc] != seq[seqloc]: - mismatches.append(seqloc) - if len(mismatches) > self.maxMismatches: - throwException = True - done = True - loc += 1 - seqloc += 1 - else: - throwException = True - - if throwException: - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - return loc, (instring[start:loc],mismatches) - -# using the genedata extracted above, look for close matches of a gene sequence -searchseq = CloseMatch("TTAAATCTAGAAGAT", 3) -for g in genedata: - print("%s (%d)" % (g.id, g.genelen)) - print("-"*24) - for t,startLoc,endLoc in searchseq.scanString(g.gene, overlap=True): - matched, mismatches = t[0] - print("MATCH:", searchseq.sequence) - print("FOUND:", matched) - if mismatches: - print(" ", ''.join(' ' if i not in mismatches else '*' - for i,c in enumerate(searchseq.sequence))) - else: - print("") - print("at location", startLoc) - print() - print() \ No newline at end of file diff --git a/examples/pgn.py b/examples/pgn.py deleted file mode 100644 index d13f83e..0000000 --- a/examples/pgn.py +++ /dev/null @@ -1,94 +0,0 @@ -# pgn.py rel. 1.1 17-sep-2004 -# -# Demonstration of the parsing module, implementing a pgn parser. -# -# The aim of this parser is not to support database application, -# but to create automagically a pgn annotated reading the log console file -# of a lecture of ICC (Internet Chess Club), saved by Blitzin. -# Of course you can modify the Abstract Syntax Tree to your purpose. -# -# Copyright 2004, by Alberto Santini http://www.albertosantini.it/chess/ -# -from pyparsing import alphanums, nums, quotedString -from pyparsing import Combine, Forward, Group, Literal, oneOf, OneOrMore, Optional, Suppress, ZeroOrMore, White, Word -from pyparsing import ParseException - -# -# define pgn grammar -# - -tag = Suppress("[") + Word(alphanums) + Combine(quotedString) + Suppress("]") -comment = Suppress("{") + Word(alphanums + " ") + Suppress("}") - -dot = Literal(".") -piece = oneOf("K Q B N R") -file_coord = oneOf("a b c d e f g h") -rank_coord = oneOf("1 2 3 4 5 6 7 8") -capture = oneOf("x :") -promote = Literal("=") -castle_queenside = oneOf("O-O-O 0-0-0 o-o-o") -castle_kingside = oneOf("O-O 0-0 o-o") - -move_number = Optional(comment) + Word(nums) + dot -m1 = file_coord + rank_coord # pawn move e.g. d4 -m2 = file_coord + capture + file_coord + rank_coord # pawn capture move e.g. dxe5 -m3 = file_coord + "8" + promote + piece # pawn promotion e.g. e8=Q -m4 = piece + file_coord + rank_coord # piece move e.g. Be6 -m5 = piece + file_coord + file_coord + rank_coord # piece move e.g. Nbd2 -m6 = piece + rank_coord + file_coord + rank_coord # piece move e.g. R4a7 -m7 = piece + capture + file_coord + rank_coord # piece capture move e.g. Bxh7 -m8 = castle_queenside | castle_kingside # castling e.g. o-o - -check = oneOf("+ ++") -mate = Literal("#") -annotation = Word("!?", max=2) -nag = " $" + Word(nums) -decoration = check | mate | annotation | nag - -variant = Forward() -half_move = Combine((m3 | m1 | m2 | m4 | m5 | m6 | m7 | m8) + Optional(decoration)) \ - + Optional(comment) +Optional(variant) -move = Suppress(move_number) + half_move + Optional(half_move) -variant << "(" + OneOrMore(move) + ")" -# grouping the plies (half-moves) for each move: useful to group annotations, variants... -# suggested by Paul McGuire :) -move = Group(Suppress(move_number) + half_move + Optional(half_move)) -variant << Group("(" + OneOrMore(move) + ")") -game_terminator = oneOf("1-0 0-1 1/2-1/2 *") - -pgnGrammar = Suppress(ZeroOrMore(tag)) + ZeroOrMore(move) + Optional(Suppress(game_terminator)) - -def parsePGN( pgn, bnf=pgnGrammar, fn=None ): - try: - return bnf.parseString( pgn ) - except ParseException as err: - print(err.line) - print(" "*(err.column-1) + "^") - print(err) - -if __name__ == "__main__": - # input string - pgn = """ -[Event "ICC 5 0 u"] -[Site "Internet Chess Club"] -[Date "2004.01.25"] -[Round "-"] -[White "guest920"] -[Black "IceBox"] -[Result "0-1"] -[ICCResult "White checkmated"] -[BlackElo "1498"] -[Opening "French defense"] -[ECO "C00"] -[NIC "FR.01"] -[Time "04:44:56"] -[TimeControl "300+0"] - -1. e4 e6 2. Nf3 d5 $2 3. exd5 (3. e5 g6 4. h4) exd5 4. Qe2+ Qe7 5. Qxe7+ Bxe7 6. d3 Nf6 7. Be3 -Bg4 8. Nbd2 c5 9. h3 Be6 10. O-O-O Nc6 11. g4 Bd6 12. g5 Nd7 13. Rg1 d4 14. -g6 fxg6 15. Bg5 Rf8 16. a3 Bd5 17. Re1+ Nde5 18. Nxe5 Nxe5 19. Bf4 Rf5 20. -Bxe5 Rxe5 21. Rg5 Rxe1# {Black wins} 0-1 -""" - # parse input string - tokens = parsePGN(pgn, pgnGrammar) - print(tokens.dump()) diff --git a/examples/position.py b/examples/position.py deleted file mode 100644 index 984c018..0000000 --- a/examples/position.py +++ /dev/null @@ -1,55 +0,0 @@ -from pyparsing import * - -text = """Lorem ipsum dolor sit amet, consectetur adipisicing -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""" - -# find all words beginning with a vowel -vowels = "aeiouAEIOU" -initialVowelWord = Word(vowels,alphas) - -# Unfortunately, searchString will advance character by character through -# the input text, so it will detect that the initial "Lorem" is not an -# initialVowelWord, but then it will test "orem" and think that it is. So -# we need to add a do-nothing term that will match the words that start with -# consonants, but we will just throw them away when we match them. The key is -# that, in having been matched, the parser will skip over them entirely when -# looking for initialVowelWords. -consonants = ''.join(c for c in alphas if c not in vowels) -initialConsWord = Word(consonants, alphas).suppress() - -# using scanString to locate where tokens are matched -for t,start,end in (initialConsWord|initialVowelWord).scanString(text): - if t: - print(start,':', t[0]) - -# add parse action to annotate the parsed tokens with their location in the -# input string -def addLocnToTokens(s,l,t): - t['locn'] = l - t['word'] = t[0] -initialVowelWord.setParseAction(addLocnToTokens) - -for ivowelInfo in (initialConsWord | initialVowelWord).searchString(text): - if not ivowelInfo: - continue - print(ivowelInfo.locn, ':', ivowelInfo.word) - - -# alternative - add an Empty that will save the current location -def location(name): - return Empty().setParseAction(lambda s,l,t: t.__setitem__(name,l)) -locateInitialVowels = location("locn") + initialVowelWord("word") - -# search through the input text -for ivowelInfo in (initialConsWord | locateInitialVowels).searchString(text): - if not ivowelInfo: - continue - print(ivowelInfo.locn, ':', ivowelInfo.word) - - diff --git a/examples/protobuf_parser.py b/examples/protobuf_parser.py deleted file mode 100644 index 04ce0d8..0000000 --- a/examples/protobuf_parser.py +++ /dev/null @@ -1,100 +0,0 @@ -# protobuf_parser.py -# -# simple parser for parsing protobuf .proto files -# -# Copyright 2010, Paul McGuire -# - -from pyparsing import (Word, alphas, alphanums, Regex, Suppress, Forward, - Group, oneOf, ZeroOrMore, Optional, delimitedList, Keyword, - restOfLine, quotedString, Dict) - -ident = Word(alphas+"_",alphanums+"_").setName("identifier") -integer = Regex(r"[+-]?\d+") - -LBRACE,RBRACE,LBRACK,RBRACK,LPAR,RPAR,EQ,SEMI = map(Suppress,"{}[]()=;") - -kwds = """message required optional repeated enum extensions extends extend - to package service rpc returns true false option import""" -for kw in kwds.split(): - exec("%s_ = Keyword('%s')" % (kw.upper(), kw)) - -messageBody = Forward() - -messageDefn = MESSAGE_ - ident("messageId") + LBRACE + messageBody("body") + RBRACE - -typespec = oneOf("""double float int32 int64 uint32 uint64 sint32 sint64 - fixed32 fixed64 sfixed32 sfixed64 bool string bytes""") | ident -rvalue = integer | TRUE_ | FALSE_ | ident -fieldDirective = LBRACK + Group(ident + EQ + rvalue) + RBRACK -fieldDefn = (( REQUIRED_ | OPTIONAL_ | REPEATED_ )("fieldQualifier") - - typespec("typespec") + ident("ident") + EQ + integer("fieldint") + ZeroOrMore(fieldDirective) + SEMI) - -# enumDefn ::= 'enum' ident '{' { ident '=' integer ';' }* '}' -enumDefn = ENUM_("typespec") - ident('name') + LBRACE + Dict( ZeroOrMore( Group(ident + EQ + integer + SEMI) ))('values') + RBRACE - -# extensionsDefn ::= 'extensions' integer 'to' integer ';' -extensionsDefn = EXTENSIONS_ - integer + TO_ + integer + SEMI - -# messageExtension ::= 'extend' ident '{' messageBody '}' -messageExtension = EXTEND_ - ident + LBRACE + messageBody + RBRACE - -# messageBody ::= { fieldDefn | enumDefn | messageDefn | extensionsDefn | messageExtension }* -messageBody << Group(ZeroOrMore( Group(fieldDefn | enumDefn | messageDefn | extensionsDefn | messageExtension) )) - -# methodDefn ::= 'rpc' ident '(' [ ident ] ')' 'returns' '(' [ ident ] ')' ';' -methodDefn = (RPC_ - ident("methodName") + - LPAR + Optional(ident("methodParam")) + RPAR + - RETURNS_ + LPAR + Optional(ident("methodReturn")) + RPAR) - -# serviceDefn ::= 'service' ident '{' methodDefn* '}' -serviceDefn = SERVICE_ - ident("serviceName") + LBRACE + ZeroOrMore(Group(methodDefn)) + RBRACE - -# packageDirective ::= 'package' ident [ '.' ident]* ';' -packageDirective = Group(PACKAGE_ - delimitedList(ident, '.', combine=True) + SEMI) - -comment = '//' + restOfLine - -importDirective = IMPORT_ - quotedString("importFileSpec") + SEMI - -optionDirective = OPTION_ - ident("optionName") + EQ + quotedString("optionValue") + SEMI - -topLevelStatement = Group(messageDefn | messageExtension | enumDefn | serviceDefn | importDirective | optionDirective) - -parser = Optional(packageDirective) + ZeroOrMore(topLevelStatement) - -parser.ignore(comment) - - -test1 = """message Person { - required int32 id = 1; - required string name = 2; - optional string email = 3; -}""" - -test2 = """package tutorial; - -message Person { - required string name = 1; - required int32 id = 2; - optional string email = 3; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; - } - - message PhoneNumber { - required string number = 1; - optional PhoneType type = 2 [default = HOME]; - } - - repeated PhoneNumber phone = 4; -} - -message AddressBook { - repeated Person person = 1; -}""" - -parser.runTests([test1, test2]) diff --git a/examples/pymicko.py b/examples/pymicko.py deleted file mode 100644 index b136689..0000000 --- a/examples/pymicko.py +++ /dev/null @@ -1,1387 +0,0 @@ -#!/usr/bin/python - -# Python/pyparsing educational microC compiler v1.0 -# Copyright (C) 2009 Zarko Zivanov -# (largely based on flex/bison microC compiler by Zorica Suvajdzin, used with her permission; -# current version can be found at http://www.acs.uns.ac.rs, under "Programski Prevodioci" [Serbian site]) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# A copy of the GNU General Public License can be found at . - -from pyparsing import * -from sys import stdin, stdout, stderr, argv, exit - -#defines debug level -# 0 - no debug -# 1 - print parsing results -# 2 - print parsing results and symbol table -# 3 - print parsing results only, without executing parse actions (grammar-only testing) -DEBUG = 0 - -########################################################################################## -########################################################################################## - -# About microC language and microC compiler - -# microC language and microC compiler are educational tools, and their goal is to show some basic principles -# of writing a C language compiler. Compiler represents one (relatively simple) solution, not necessarily the best one. -# This Python/pyparsing version is made using Python 2.6.4 and pyparsing 1.5.2 (and it may contain errors :) ) - -########################################################################################## -########################################################################################## - -# Model of the used hypothetical processor - -# The reason behind using a hypothetical processor is to simplify code generation and to concentrate on the compiler itself. -# This compiler can relatively easily be ported to x86, but one must know all the little details about which register -# can be used for what, which registers are default for various operations, etc. - -# The hypothetical processor has 16 registers, called %0 to %15. Register %13 is used for the function return value (x86's eax), -# %14 is the stack frame pointer (x86's ebp) and %15 is the stack pointer (x86's esp). All data-handling instructions can be -# unsigned (suffix U), or signed (suffix S). These are ADD, SUB, MUL and DIV. These are three-address instructions, -# the first two operands are input, the third one is output. Whether these operands are registers, memory or constant -# is not relevant, all combinations are possible (except that output cannot be a constant). Constants are writen with a $ prefix (10-base only). -# Conditional jumps are handled by JXXY instructions, where XX is LT, GT, LE, GE, EQ, NE (less than, greater than, less than or equal, etc.) -# and Y is U or S (unsigned or signed, except for JEQ i JNE). Unconditional jump is JMP. The move instruction is MOV. -# Function handling is done using CALL, RET, PUSH and POP (C style function calls). Static data is defined using the WORD directive -# (example: variable: WORD 1), whose only argument defines the number of locations that are reserved. - -########################################################################################## -########################################################################################## - -# Grammar of The microC Programming Language -# (small subset of C made for compiler course at Faculty of Technical Sciences, Chair for Applied Computer Sciences, Novi Sad, Serbia) - -# Patterns: - -# letter -# -> "_" | "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" | "E" | "f" -# | "F" | "g" | "G" | "h" | "H" | "i" | "I" | "j" | "J" | "k" | "K" | "l" -# | "L" | "m" | "M" | "n" | "N" | "o" | "O" | "p" | "P" | "q" | "Q" | "r" -# | "R" | "s" | "S" | "t" | "T" | "u" | "U" | "v" | "V" | "w" | "W" | "x" -# | "X" | "y" | "Y" | "z" | "Z" - -# digit -# -> "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" - -# identifier -# -> letter ( letter | digit )* - -# int_constant -# -> digit + - -# unsigned_constant -# -> digit + ( "u" | "U" ) - -# Productions: - -# program -# -> variable_list function_list -# -> function_list - -# variable_list -# -> variable ";" -# -> variable_list variable ";" - -# variable -# -> type identifier - -# type -# -> "int" -# -> "unsigned" - -# function_list -# -> function -# -> function_list function - -# function -# -> type identifier "(" parameters ")" body - -# parameters -# -> -# -> parameter_list - -# parameter_list -# -> variable -# -> parameter_list "," variable - -# body -# -> "{" variable_list statement_list "}" -# -> "{" statement_list "}" - -# statement_list -# -> -# -> statement_list statement - -# statement -# -> assignement_statement -# -> function_call_statement -# -> if_statement -# -> while_statement -# -> return_statement -# -> compound_statement - -# assignement_statement -# -> identifier "=" num_exp ";" - -# num_exp -# -> mul_exp -# -> num_exp "+" mul_exp -# -> num_exp "-" mul_exp - -# mul_exp -# -> exp -# -> mul_exp "*" exp -# -> mul_exp "/" exp - -# exp -# -> constant -# -> identifier -# -> function_call -# -> "(" num_exp ")" -# -> "+" exp -# -> "-" exp - -# constant -# -> int_constant -# -> unsigned_constant - -# function_call -# -> identifier "(" arguments ")" - -# arguments -# -> -# -> argument_list - -# argument_list -# -> num_exp -# -> argument_list "," num_exp - -# function_call_statement -# -> function_call ";" - -# if_statement -# -> "if" "(" log_exp ")" statement -# -> "if" "(" log_exp ")" statement "else" statement -# -> -> -> -> -> -> -> -> 2 - -# log_exp -# -> and_exp -# -> log_exp "||" and_exp - -# and_exp -# -> rel_exp -# -> and_exp "&&" rel_exp - -# rel_exp -# -> num_exp "<" num_exp -# -> num_exp ">" num_exp -# -> num_exp "<=" num_exp -# -> num_exp ">=" num_exp -# -> num_exp "==" num_exp -# -> num_exp "!=" num_exp - -# while_statement -# -> "while" "(" log_exp ")" statement - -# return_statement -# -> "return" num_exp ";" - -# compound_statement -# -> "{" statement_list "}" - -# Comment: /* a comment */ - -########################################################################################## -########################################################################################## - -class Enumerate(dict): - """C enum emulation (original by Scott David Daniels)""" - def __init__(self, names): - for number, name in enumerate(names.split()): - setattr(self, name, number) - self[number] = name - -class SharedData(object): - """Data used in all three main classes""" - - #Possible kinds of symbol table entries - KINDS = Enumerate("NO_KIND WORKING_REGISTER GLOBAL_VAR FUNCTION PARAMETER LOCAL_VAR CONSTANT") - #Supported types of functions and variables - TYPES = Enumerate("NO_TYPE INT UNSIGNED") - - #bit size of variables - TYPE_BIT_SIZE = 16 - #min/max values of constants - MIN_INT = -2 ** (TYPE_BIT_SIZE - 1) - MAX_INT = 2 ** (TYPE_BIT_SIZE - 1) - 1 - MAX_UNSIGNED = 2 ** TYPE_BIT_SIZE - 1 - #available working registers (the last one is the register for function's return value!) - REGISTERS = "%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13".split() - #register for function's return value - FUNCTION_REGISTER = len(REGISTERS) - 1 - #the index of last working register - LAST_WORKING_REGISTER = len(REGISTERS) - 2 - #list of relational operators - RELATIONAL_OPERATORS = "< > <= >= == !=".split() - - def __init__(self): - #index of the currently parsed function - self.functon_index = 0 - #name of the currently parsed function - self.functon_name = 0 - #number of parameters of the currently parsed function - self.function_params = 0 - #number of local variables of the currently parsed function - self.function_vars = 0 - -########################################################################################## -########################################################################################## - -class ExceptionSharedData(object): - """Class for exception handling data""" - - def __init__(self): - #position in currently parsed text - self.location = 0 - #currently parsed text - self.text = "" - - def setpos(self, location, text): - """Helper function for setting curently parsed text and position""" - self.location = location - self.text = text - -exshared = ExceptionSharedData() - -class SemanticException(Exception): - """Exception for semantic errors found during parsing, similar to ParseException. - Introduced because ParseException is used internally in pyparsing and custom - messages got lost and replaced by pyparsing's generic errors. - """ - - def __init__(self, message, print_location=True): - super(SemanticException,self).__init__() - self._message = message - self.location = exshared.location - self.print_location = print_location - if exshared.location != None: - self.line = lineno(exshared.location, exshared.text) - self.col = col(exshared.location, exshared.text) - self.text = line(exshared.location, exshared.text) - else: - self.line = self.col = self.text = None - - def _get_message(self): - return self._message - def _set_message(self, message): - self._message = message - message = property(_get_message, _set_message) - - def __str__(self): - """String representation of the semantic error""" - msg = "Error" - if self.print_location and (self.line != None): - msg += " at line %d, col %d" % (self.line, self.col) - msg += ": %s" % self.message - if self.print_location and (self.line != None): - msg += "\n%s" % self.text - return msg - -########################################################################################## -########################################################################################## - -class SymbolTableEntry(object): - """Class which represents one symbol table entry.""" - - def __init__(self, sname = "", skind = 0, stype = 0, sattr = None, sattr_name = "None"): - """Initialization of symbol table entry. - sname - symbol name - skind - symbol kind - stype - symbol type - sattr - symbol attribute - sattr_name - symbol attribute name (used only for table display) - """ - self.name = sname - self.kind = skind - self.type = stype - self.attribute = sattr - self.attribute_name = sattr_name - self.param_types = [] - - def set_attribute(self, name, value): - """Sets attribute's name and value""" - self.attribute_name = name - self.attribute = value - - def attribute_str(self): - """Returns attribute string (used only for table display)""" - return "{0}={1}".format(self.attribute_name, self.attribute) if self.attribute != None else "None" - -class SymbolTable(object): - """Class for symbol table of microC program""" - - def __init__(self, shared): - """Initialization of the symbol table""" - self.table = [] - self.lable_len = 0 - #put working registers in the symbol table - for reg in range(SharedData.FUNCTION_REGISTER+1): - self.insert_symbol(SharedData.REGISTERS[reg], SharedData.KINDS.WORKING_REGISTER, SharedData.TYPES.NO_TYPE) - #shared data - self.shared = shared - - def error(self, text=""): - """Symbol table error exception. It should happen only if index is out of range while accessing symbol table. - This exeption is not handled by the compiler, so as to allow traceback printing - """ - if text == "": - raise Exception("Symbol table index out of range") - else: - raise Exception("Symbol table error: %s" % text) - - def display(self): - """Displays the symbol table content""" - #Finding the maximum length for each column - sym_name = "Symbol name" - sym_len = max(max(len(i.name) for i in self.table),len(sym_name)) - kind_name = "Kind" - kind_len = max(max(len(SharedData.KINDS[i.kind]) for i in self.table),len(kind_name)) - type_name = "Type" - type_len = max(max(len(SharedData.TYPES[i.type]) for i in self.table),len(type_name)) - attr_name = "Attribute" - attr_len = max(max(len(i.attribute_str()) for i in self.table),len(attr_name)) - #print table header - print("{0:3s} | {1:^{2}s} | {3:^{4}s} | {5:^{6}s} | {7:^{8}} | {9:s}".format(" No", sym_name, sym_len, kind_name, kind_len, type_name, type_len, attr_name, attr_len, "Parameters")) - print("-----------------------------" + "-" * (sym_len + kind_len + type_len + attr_len)) - #print symbol table - for i,sym in enumerate(self.table): - parameters = "" - for p in sym.param_types: - if parameters == "": - parameters = "{0}".format(SharedData.TYPES[p]) - else: - parameters += ", {0}".format(SharedData.TYPES[p]) - print("{0:3d} | {1:^{2}s} | {3:^{4}s} | {5:^{6}s} | {7:^{8}} | ({9})".format(i, sym.name, sym_len, SharedData.KINDS[sym.kind], kind_len, SharedData.TYPES[sym.type], type_len, sym.attribute_str(), attr_len, parameters)) - - def insert_symbol(self, sname, skind, stype): - """Inserts new symbol at the end of the symbol table. - Returns symbol index - sname - symbol name - skind - symbol kind - stype - symbol type - """ - self.table.append(SymbolTableEntry(sname, skind, stype)) - self.table_len = len(self.table) - return self.table_len-1 - - def clear_symbols(self, index): - """Clears all symbols begining with the index to the end of table""" - try: - del self.table[index:] - except Exception: - self.error() - self.table_len = len(self.table) - - def lookup_symbol(self, sname, skind=list(SharedData.KINDS.keys()), stype=list(SharedData.TYPES.keys())): - """Searches for symbol, from the end to the begining. - Returns symbol index or None - sname - symbol name - skind - symbol kind (one kind, list of kinds, or None) deafult: any kind - stype - symbol type (or None) default: any type - """ - skind = skind if isinstance(skind, list) else [skind] - stype = stype if isinstance(stype, list) else [stype] - for i, sym in [[x, self.table[x]] for x in range(len(self.table) - 1, SharedData.LAST_WORKING_REGISTER, -1)]: - if (sym.name == sname) and (sym.kind in skind) and (sym.type in stype): - return i - return None - - def insert_id(self, sname, skind, skinds, stype): - """Inserts a new identifier at the end of the symbol table, if possible. - Returns symbol index, or raises an exception if the symbol alredy exists - sname - symbol name - skind - symbol kind - skinds - symbol kinds to check for - stype - symbol type - """ - index = self.lookup_symbol(sname, skinds) - if index == None: - index = self.insert_symbol(sname, skind, stype) - return index - else: - raise SemanticException("Redefinition of '%s'" % sname) - - def insert_global_var(self, vname, vtype): - "Inserts a new global variable" - return self.insert_id(vname, SharedData.KINDS.GLOBAL_VAR, [SharedData.KINDS.GLOBAL_VAR, SharedData.KINDS.FUNCTION], vtype) - - def insert_local_var(self, vname, vtype, position): - "Inserts a new local variable" - index = self.insert_id(vname, SharedData.KINDS.LOCAL_VAR, [SharedData.KINDS.LOCAL_VAR, SharedData.KINDS.PARAMETER], vtype) - self.table[index].attribute = position - - def insert_parameter(self, pname, ptype): - "Inserts a new parameter" - index = self.insert_id(pname, SharedData.KINDS.PARAMETER, SharedData.KINDS.PARAMETER, ptype) - #set parameter's attribute to it's ordinal number - self.table[index].set_attribute("Index", self.shared.function_params) - #set parameter's type in param_types list of a function - self.table[self.shared.function_index].param_types.append(ptype) - return index - - def insert_function(self, fname, ftype): - "Inserts a new function" - index = self.insert_id(fname, SharedData.KINDS.FUNCTION, [SharedData.KINDS.GLOBAL_VAR, SharedData.KINDS.FUNCTION], ftype) - self.table[index].set_attribute("Params",0) - return index - - def insert_constant(self, cname, ctype): - """Inserts a constant (or returns index if the constant already exists) - Additionally, checks for range. - """ - index = self.lookup_symbol(cname, stype=ctype) - if index == None: - num = int(cname) - if ctype == SharedData.TYPES.INT: - if (num < SharedData.MIN_INT) or (num > SharedData.MAX_INT): - raise SemanticException("Integer constant '%s' out of range" % cname) - elif ctype == SharedData.TYPES.UNSIGNED: - if (num < 0) or (num > SharedData.MAX_UNSIGNED): - raise SemanticException("Unsigned constant '%s' out of range" % cname) - index = self.insert_symbol(cname, SharedData.KINDS.CONSTANT, ctype) - return index - - def same_types(self, index1, index2): - """Returns True if both symbol table elements are of the same type""" - try: - same = self.table[index1].type == self.table[index2].type != SharedData.TYPES.NO_TYPE - except Exception: - self.error() - return same - - def same_type_as_argument(self, index, function_index, argument_number): - """Returns True if index and function's argument are of the same type - index - index in symbol table - function_index - function's index in symbol table - argument_number - # of function's argument - """ - try: - same = self.table[function_index].param_types[argument_number] == self.table[index].type - except Exception: - self.error() - return same - - def get_attribute(self, index): - try: - return self.table[index].attribute - except Exception: - self.error() - - def set_attribute(self, index, value): - try: - self.table[index].attribute = value - except Exception: - self.error() - - def get_name(self, index): - try: - return self.table[index].name - except Exception: - self.error() - - def get_kind(self, index): - try: - return self.table[index].kind - except Exception: - self.error() - - def get_type(self, index): - try: - return self.table[index].type - except Exception: - self.error() - - def set_type(self, index, stype): - try: - self.table[index].type = stype - except Exception: - self.error() - -########################################################################################## -########################################################################################## - -class CodeGenerator(object): - """Class for code generation methods.""" - - #dictionary of relational operators - RELATIONAL_DICT = dict([op,i] for i, op in enumerate(SharedData.RELATIONAL_OPERATORS)) - #conditional jumps for relational operators - CONDITIONAL_JUMPS = ["JLTS", "JGTS", "JLES", "JGES", "JEQ ", "JNE ", - "JLTU", "JGTU", "JLEU", "JGEU", "JEQ ", "JNE "] - #opposite conditional jumps for relational operators - OPPOSITE_JUMPS = ["JGES", "JLES", "JGTS", "JLTS", "JNE ", "JEQ ", - "JGEU", "JLEU", "JGTU", "JLTU", "JNE ", "JEQ "] - #supported operations - OPERATIONS = {"+" : "ADD", "-" : "SUB", "*" : "MUL", "/" : "DIV"} - #suffixes for signed and unsigned operations (if no type is specified, unsigned will be assumed) - OPSIGNS = {SharedData.TYPES.NO_TYPE : "U", SharedData.TYPES.INT : "S", SharedData.TYPES.UNSIGNED : "U"} - #text at start of data segment - DATA_START_TEXT = "#DATA" - #text at start of code segment - CODE_START_TEXT = "#CODE" - - def __init__(self, shared, symtab): - #generated code - self.code = "" - #prefix for internal labels - self.internal = "@" - #suffix for label definition - self.definition = ":" - #list of free working registers - self.free_registers = list(range(SharedData.FUNCTION_REGISTER, -1, -1)) - #list of used working registers - self.used_registers = [] - #list of used registers needed when function call is inside of a function call - self.used_registers_stack = [] - #shared data - self.shared = shared - #symbol table - self.symtab = symtab - - def error(self, text): - """Compiler error exception. It should happen only if something is wrong with compiler. - This exeption is not handled by the compiler, so as to allow traceback printing - """ - raise Exception("Compiler error: %s" % text) - - def take_register(self, rtype = SharedData.TYPES.NO_TYPE): - """Reserves one working register and sets its type""" - if len(self.free_registers) == 0: - self.error("no more free registers") - reg = self.free_registers.pop() - self.used_registers.append(reg) - self.symtab.set_type(reg, rtype) - return reg - - def take_function_register(self, rtype = SharedData.TYPES.NO_TYPE): - """Reserves register for function return value and sets its type""" - reg = SharedData.FUNCTION_REGISTER - if reg not in self.free_registers: - self.error("function register already taken") - self.free_registers.remove(reg) - self.used_registers.append(reg) - self.symtab.set_type(reg, rtype) - return reg - - def free_register(self, reg): - """Releases working register""" - if reg not in self.used_registers: - self.error("register %s is not taken" % self.REGISTERS[reg]) - self.used_registers.remove(reg) - self.free_registers.append(reg) - self.free_registers.sort(reverse = True) - - def free_if_register(self, index): - """If index is a working register, free it, otherwise just return (helper function)""" - if (index < 0) or (index > SharedData.FUNCTION_REGISTER): - return - else: - self.free_register(index) - - def label(self, name, internal=False, definition=False): - """Generates label name (helper function) - name - label name - internal - boolean value, adds "@" prefix to label - definition - boolean value, adds ":" suffix to label - """ - return "{0}{1}{2}".format(self.internal if internal else "", name, self.definition if definition else "") - - def symbol(self, index): - """Generates symbol name from index""" - #if index is actually a string, just return it - if isinstance(index, str): - return index - elif (index < 0) or (index >= self.symtab.table_len): - self.error("symbol table index out of range") - sym = self.symtab.table[index] - #local variables are located at negative offset from frame pointer register - if sym.kind == SharedData.KINDS.LOCAL_VAR: - return "-{0}(%14)".format(sym.attribute * 4 + 4) - #parameters are located at positive offset from frame pointer register - elif sym.kind == SharedData.KINDS.PARAMETER: - return "{0}(%14)".format(8 + sym.attribute * 4) - elif sym.kind == SharedData.KINDS.CONSTANT: - return "${0}".format(sym.name) - else: - return "{0}".format(sym.name) - - def save_used_registers(self): - """Pushes all used working registers before function call""" - used = self.used_registers[:] - del self.used_registers[:] - self.used_registers_stack.append(used[:]) - used.sort() - for reg in used: - self.newline_text("PUSH\t%s" % SharedData.REGISTERS[reg], True) - self.free_registers.extend(used) - self.free_registers.sort(reverse = True) - - def restore_used_registers(self): - """Pops all used working registers after function call""" - used = self.used_registers_stack.pop() - self.used_registers = used[:] - used.sort(reverse = True) - for reg in used: - self.newline_text("POP \t%s" % SharedData.REGISTERS[reg], True) - self.free_registers.remove(reg) - - def text(self, text): - """Inserts text into generated code""" - self.code += text - - def prepare_data_segment(self): - """Inserts text at the start of data segment""" - self.text(self.DATA_START_TEXT) - - def prepare_code_segment(self): - """Inserts text at the start of code segment""" - self.newline_text(self.CODE_START_TEXT) - - def newline(self, indent=False): - """Inserts a newline, optionally with indentation.""" - self.text("\n") - if indent: - self.text("\t\t\t") - - def newline_text(self, text, indent = False): - """Inserts a newline and text, optionally with indentation (helper function)""" - self.newline(indent) - self.text(text) - - def newline_label(self, name, internal=False, definition=False): - """Inserts a newline and a label (helper function) - name - label name - internal - boolean value, adds "@" prefix to label - definition - boolean value, adds ":" suffix to label - """ - self.newline_text(self.label("{0}{1}{2}".format("@" if internal else "", name, ":" if definition else ""))) - - def global_var(self, name): - """Inserts a new static (global) variable definition""" - self.newline_label(name, False, True) - self.newline_text("WORD\t1", True) - - def arithmetic_mnemonic(self, op_name, op_type): - """Generates an arithmetic instruction mnemonic""" - return self.OPERATIONS[op_name] + self.OPSIGNS[op_type] - - def arithmetic(self, operation, operand1, operand2, operand3 = None): - """Generates an arithmetic instruction - operation - one of supporetd operations - operandX - index in symbol table or text representation of operand - First two operands are input, third one is output - """ - if isinstance(operand1, int): - output_type = self.symtab.get_type(operand1) - self.free_if_register(operand1) - else: - output_type = None - if isinstance(operand2, int): - output_type = self.symtab.get_type(operand2) if output_type == None else output_type - self.free_if_register(operand2) - else: - output_type = SharedData.TYPES.NO_TYPE if output_type == None else output_type - #if operand3 is not defined, reserve one free register for it - output = self.take_register(output_type) if operand3 == None else operand3 - mnemonic = self.arithmetic_mnemonic(operation, output_type) - self.newline_text("{0}\t{1},{2},{3}".format(mnemonic, self.symbol(operand1), self.symbol(operand2), self.symbol(output)), True) - return output - - def relop_code(self, relop, operands_type): - """Returns code for relational operator - relop - relational operator - operands_type - int or unsigned - """ - code = self.RELATIONAL_DICT[relop] - offset = 0 if operands_type == SharedData.TYPES.INT else len(SharedData.RELATIONAL_OPERATORS) - return code + offset - - def jump(self, relcode, opposite, label): - """Generates a jump instruction - relcode - relational operator code - opposite - generate normal or opposite jump - label - jump label - """ - jump = self.OPPOSITE_JUMPS[relcode] if opposite else self.CONDITIONAL_JUMPS[relcode] - self.newline_text("{0}\t{1}".format(jump, label), True) - - def unconditional_jump(self, label): - """Generates an unconditional jump instruction - label - jump label - """ - self.newline_text("JMP \t{0}".format(label), True) - - def move(self,operand1, operand2): - """Generates a move instruction - If the output operand (opernad2) is a working register, sets it's type - operandX - index in symbol table or text representation of operand - """ - if isinstance(operand1, int): - output_type = self.symtab.get_type(operand1) - self.free_if_register(operand1) - else: - output_type = SharedData.TYPES.NO_TYPE - self.newline_text("MOV \t{0},{1}".format(self.symbol(operand1), self.symbol(operand2)), True) - if isinstance(operand2, int): - if self.symtab.get_kind(operand2) == SharedData.KINDS.WORKING_REGISTER: - self.symtab.set_type(operand2, output_type) - - def push(self, operand): - """Generates a push operation""" - self.newline_text("PUSH\t%s" % self.symbol(operand), True) - - def pop(self, operand): - """Generates a pop instruction""" - self.newline_text("POP \t%s" % self.symbol(operand), True) - - def compare(self, operand1, operand2): - """Generates a compare instruction - operandX - index in symbol table - """ - typ = self.symtab.get_type(operand1) - self.free_if_register(operand1) - self.free_if_register(operand2) - self.newline_text("CMP{0}\t{1},{2}".format(self.OPSIGNS[typ], self.symbol(operand1), self.symbol(operand2)), True) - - def function_begin(self): - """Inserts function name label and function frame initialization""" - self.newline_label(self.shared.function_name, False, True) - self.push("%14") - self.move("%15", "%14") - - def function_body(self): - """Inserts a local variable initialization and body label""" - if self.shared.function_vars > 0: - const = self.symtab.insert_constant("{0}".format(self.shared.function_vars * 4), SharedData.TYPES.UNSIGNED) - self.arithmetic("-", "%15", const, "%15") - self.newline_label(self.shared.function_name + "_body", True, True) - - def function_end(self): - """Inserts an exit label and function return instructions""" - self.newline_label(self.shared.function_name + "_exit", True, True) - self.move("%14", "%15") - self.pop("%14") - self.newline_text("RET", True) - - def function_call(self, function, arguments): - """Generates code for a function call - function - function index in symbol table - arguments - list of arguments (indexes in symbol table) - """ - #push each argument to stack - for arg in arguments: - self.push(self.symbol(arg)) - self.free_if_register(arg) - self.newline_text("CALL\t"+self.symtab.get_name(function), True) - args = self.symtab.get_attribute(function) - #generates stack cleanup if function has arguments - if args > 0: - args_space = self.symtab.insert_constant("{0}".format(args * 4), SharedData.TYPES.UNSIGNED) - self.arithmetic("+", "%15", args_space, "%15") - -########################################################################################## -########################################################################################## - -class MicroC(object): - """Class for microC parser/compiler""" - - def __init__(self): - #Definitions of terminal symbols for microC programming language - self.tId = Word(alphas+"_",alphanums+"_") - self.tInteger = Word(nums).setParseAction(lambda x : [x[0], SharedData.TYPES.INT]) - self.tUnsigned = Regex(r"[0-9]+[uU]").setParseAction(lambda x : [x[0][:-1], SharedData.TYPES.UNSIGNED]) - self.tConstant = (self.tUnsigned | self.tInteger).setParseAction(self.constant_action) - self.tType = Keyword("int").setParseAction(lambda x : SharedData.TYPES.INT) | \ - Keyword("unsigned").setParseAction(lambda x : SharedData.TYPES.UNSIGNED) - self.tRelOp = oneOf(SharedData.RELATIONAL_OPERATORS) - self.tMulOp = oneOf("* /") - self.tAddOp = oneOf("+ -") - - #Definitions of rules for global variables - self.rGlobalVariable = (self.tType("type") + self.tId("name") + - FollowedBy(";")).setParseAction(self.global_variable_action) - self.rGlobalVariableList = ZeroOrMore(self.rGlobalVariable + Suppress(";")) - - #Definitions of rules for numeric expressions - self.rExp = Forward() - self.rMulExp = Forward() - self.rNumExp = Forward() - self.rArguments = delimitedList(self.rNumExp("exp").setParseAction(self.argument_action)) - self.rFunctionCall = ((self.tId("name") + FollowedBy("(")).setParseAction(self.function_call_prepare_action) + - Suppress("(") + Optional(self.rArguments)("args") + Suppress(")")).setParseAction(self.function_call_action) - self.rExp << (self.rFunctionCall | - self.tConstant | - self.tId("name").setParseAction(self.lookup_id_action) | - Group(Suppress("(") + self.rNumExp + Suppress(")")) | - Group("+" + self.rExp) | - Group("-" + self.rExp)).setParseAction(lambda x : x[0]) - self.rMulExp << ((self.rExp + ZeroOrMore(self.tMulOp + self.rExp))).setParseAction(self.mulexp_action) - self.rNumExp << (self.rMulExp + ZeroOrMore(self.tAddOp + self.rMulExp)).setParseAction(self.numexp_action) - - #Definitions of rules for logical expressions (these are without parenthesis support) - self.rAndExp = Forward() - self.rLogExp = Forward() - self.rRelExp = (self.rNumExp + self.tRelOp + self.rNumExp).setParseAction(self.relexp_action) - self.rAndExp << (self.rRelExp("exp") + ZeroOrMore(Literal("&&").setParseAction(self.andexp_action) + - self.rRelExp("exp")).setParseAction(lambda x : self.relexp_code)) - self.rLogExp << (self.rAndExp("exp") + ZeroOrMore(Literal("||").setParseAction(self.logexp_action) + - self.rAndExp("exp")).setParseAction(lambda x : self.andexp_code)) - - #Definitions of rules for statements - self.rStatement = Forward() - self.rStatementList = Forward() - self.rReturnStatement = (Keyword("return") + self.rNumExp("exp") + - Suppress(";")).setParseAction(self.return_action) - self.rAssignmentStatement = (self.tId("var") + Suppress("=") + self.rNumExp("exp") + - Suppress(";")).setParseAction(self.assignment_action) - self.rFunctionCallStatement = self.rFunctionCall + Suppress(";") - self.rIfStatement = ( (Keyword("if") + FollowedBy("(")).setParseAction(self.if_begin_action) + - (Suppress("(") + self.rLogExp + Suppress(")")).setParseAction(self.if_body_action) + - (self.rStatement + Empty()).setParseAction(self.if_else_action) + - Optional(Keyword("else") + self.rStatement)).setParseAction(self.if_end_action) - self.rWhileStatement = ( (Keyword("while") + FollowedBy("(")).setParseAction(self.while_begin_action) + - (Suppress("(") + self.rLogExp + Suppress(")")).setParseAction(self.while_body_action) + - self.rStatement).setParseAction(self.while_end_action) - self.rCompoundStatement = Group(Suppress("{") + self.rStatementList + Suppress("}")) - self.rStatement << (self.rReturnStatement | self.rIfStatement | self.rWhileStatement | - self.rFunctionCallStatement | self.rAssignmentStatement | self.rCompoundStatement) - self.rStatementList << ZeroOrMore(self.rStatement) - - self.rLocalVariable = (self.tType("type") + self.tId("name") + FollowedBy(";")).setParseAction(self.local_variable_action) - self.rLocalVariableList = ZeroOrMore(self.rLocalVariable + Suppress(";")) - self.rFunctionBody = Suppress("{") + Optional(self.rLocalVariableList).setParseAction(self.function_body_action) + \ - self.rStatementList + Suppress("}") - self.rParameter = (self.tType("type") + self.tId("name")).setParseAction(self.parameter_action) - self.rParameterList = delimitedList(self.rParameter) - self.rFunction = ( (self.tType("type") + self.tId("name")).setParseAction(self.function_begin_action) + - Group(Suppress("(") + Optional(self.rParameterList)("params") + Suppress(")") + - self.rFunctionBody)).setParseAction(self.function_end_action) - - self.rFunctionList = OneOrMore(self.rFunction) - self.rProgram = (Empty().setParseAction(self.data_begin_action) + self.rGlobalVariableList + - Empty().setParseAction(self.code_begin_action) + self.rFunctionList).setParseAction(self.program_end_action) - - #shared data - self.shared = SharedData() - #symbol table - self.symtab = SymbolTable(self.shared) - #code generator - self.codegen = CodeGenerator(self.shared, self.symtab) - - #index of the current function call - self.function_call_index = -1 - #stack for the nested function calls - self.function_call_stack = [] - #arguments of the current function call - self.function_arguments = [] - #stack for arguments of the nested function calls - self.function_arguments_stack = [] - #number of arguments for the curent function call - self.function_arguments_number = -1 - #stack for the number of arguments for the nested function calls - self.function_arguments_number_stack = [] - - #last relational expression - self.relexp_code = None - #last and expression - self.andexp_code = None - #label number for "false" internal labels - self.false_label_number = -1 - #label number for all other internal labels - self.label_number = None - #label stack for nested statements - self.label_stack = [] - - def warning(self, message, print_location=True): - """Displays warning message. Uses exshared for current location of parsing""" - msg = "Warning" - if print_location and (exshared.location != None): - wline = lineno(exshared.location, exshared.text) - wcol = col(exshared.location, exshared.text) - wtext = line(exshared.location, exshared.text) - msg += " at line %d, col %d" % (wline, wcol) - msg += ": %s" % message - if print_location and (exshared.location != None): - msg += "\n%s" % wtext - print(msg) - - - def data_begin_action(self): - """Inserts text at start of data segment""" - self.codegen.prepare_data_segment() - - def code_begin_action(self): - """Inserts text at start of code segment""" - self.codegen.prepare_code_segment() - - def global_variable_action(self, text, loc, var): - """Code executed after recognising a global variable""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("GLOBAL_VAR:",var) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - index = self.symtab.insert_global_var(var.name, var.type) - self.codegen.global_var(var.name) - return index - - def local_variable_action(self, text, loc, var): - """Code executed after recognising a local variable""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("LOCAL_VAR:",var, var.name, var.type) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - index = self.symtab.insert_local_var(var.name, var.type, self.shared.function_vars) - self.shared.function_vars += 1 - return index - - def parameter_action(self, text, loc, par): - """Code executed after recognising a parameter""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("PARAM:",par) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - index = self.symtab.insert_parameter(par.name, par.type) - self.shared.function_params += 1 - return index - - def constant_action(self, text, loc, const): - """Code executed after recognising a constant""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("CONST:",const) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - return self.symtab.insert_constant(const[0], const[1]) - - def function_begin_action(self, text, loc, fun): - """Code executed after recognising a function definition (type and function name)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("FUN_BEGIN:",fun) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - self.shared.function_index = self.symtab.insert_function(fun.name, fun.type) - self.shared.function_name = fun.name - self.shared.function_params = 0 - self.shared.function_vars = 0 - self.codegen.function_begin(); - - def function_body_action(self, text, loc, fun): - """Code executed after recognising the beginning of function's body""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("FUN_BODY:",fun) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - self.codegen.function_body() - - def function_end_action(self, text, loc, fun): - """Code executed at the end of function definition""" - if DEBUG > 0: - print("FUN_END:",fun) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #set function's attribute to number of function parameters - self.symtab.set_attribute(self.shared.function_index, self.shared.function_params) - #clear local function symbols (but leave function name) - self.symtab.clear_symbols(self.shared.function_index + 1) - self.codegen.function_end() - - def return_action(self, text, loc, ret): - """Code executed after recognising a return statement""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("RETURN:",ret) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - if not self.symtab.same_types(self.shared.function_index, ret.exp[0]): - raise SemanticException("Incompatible type in return") - #set register for function's return value to expression value - reg = self.codegen.take_function_register() - self.codegen.move(ret.exp[0], reg) - #after return statement, register for function's return value is available again - self.codegen.free_register(reg) - #jump to function's exit - self.codegen.unconditional_jump(self.codegen.label(self.shared.function_name+"_exit", True)) - - def lookup_id_action(self, text, loc, var): - """Code executed after recognising an identificator in expression""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("EXP_VAR:",var) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - var_index = self.symtab.lookup_symbol(var.name, [SharedData.KINDS.GLOBAL_VAR, SharedData.KINDS.PARAMETER, SharedData.KINDS.LOCAL_VAR]) - if var_index == None: - raise SemanticException("'%s' undefined" % var.name) - return var_index - - def assignment_action(self, text, loc, assign): - """Code executed after recognising an assignment statement""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("ASSIGN:",assign) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - var_index = self.symtab.lookup_symbol(assign.var, [SharedData.KINDS.GLOBAL_VAR, SharedData.KINDS.PARAMETER, SharedData.KINDS.LOCAL_VAR]) - if var_index == None: - raise SemanticException("Undefined lvalue '%s' in assignment" % assign.var) - if not self.symtab.same_types(var_index, assign.exp[0]): - raise SemanticException("Incompatible types in assignment") - self.codegen.move(assign.exp[0], var_index) - - def mulexp_action(self, text, loc, mul): - """Code executed after recognising a mulexp expression (something *|/ something)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("MUL_EXP:",mul) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #iterate through all multiplications/divisions - m = list(mul) - while len(m) > 1: - if not self.symtab.same_types(m[0], m[2]): - raise SemanticException("Invalid opernads to binary '%s'" % m[1]) - reg = self.codegen.arithmetic(m[1], m[0], m[2]) - #replace first calculation with it's result - m[0:3] = [reg] - return m[0] - - def numexp_action(self, text, loc, num): - """Code executed after recognising a numexp expression (something +|- something)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("NUM_EXP:",num) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #iterate through all additions/substractions - n = list(num) - while len(n) > 1: - if not self.symtab.same_types(n[0], n[2]): - raise SemanticException("Invalid opernads to binary '%s'" % n[1]) - reg = self.codegen.arithmetic(n[1], n[0], n[2]) - #replace first calculation with it's result - n[0:3] = [reg] - return n[0] - - def function_call_prepare_action(self, text, loc, fun): - """Code executed after recognising a function call (type and function name)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("FUN_PREP:",fun) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - index = self.symtab.lookup_symbol(fun.name, SharedData.KINDS.FUNCTION) - if index == None: - raise SemanticException("'%s' is not a function" % fun.name) - #save any previous function call data (for nested function calls) - self.function_call_stack.append(self.function_call_index) - self.function_call_index = index - self.function_arguments_stack.append(self.function_arguments[:]) - del self.function_arguments[:] - self.codegen.save_used_registers() - - def argument_action(self, text, loc, arg): - """Code executed after recognising each of function's arguments""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("ARGUMENT:",arg.exp) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - arg_ordinal = len(self.function_arguments) - #check argument's type - if not self.symtab.same_type_as_argument(arg.exp, self.function_call_index, arg_ordinal): - raise SemanticException("Incompatible type for argument %d in '%s'" % (arg_ordinal + 1, self.symtab.get_name(self.function_call_index))) - self.function_arguments.append(arg.exp) - - def function_call_action(self, text, loc, fun): - """Code executed after recognising the whole function call""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("FUN_CALL:",fun) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #check number of arguments - if len(self.function_arguments) != self.symtab.get_attribute(self.function_call_index): - raise SemanticException("Wrong number of arguments for function '%s'" % fun.name) - #arguments should be pushed to stack in reverse order - self.function_arguments.reverse() - self.codegen.function_call(self.function_call_index, self.function_arguments) - self.codegen.restore_used_registers() - return_type = self.symtab.get_type(self.function_call_index) - #restore previous function call data - self.function_call_index = self.function_call_stack.pop() - self.function_arguments = self.function_arguments_stack.pop() - register = self.codegen.take_register(return_type) - #move result to a new free register, to allow the next function call - self.codegen.move(self.codegen.take_function_register(return_type), register) - return register - - def relexp_action(self, text, loc, arg): - """Code executed after recognising a relexp expression (something relop something)""" - if DEBUG > 0: - print("REL_EXP:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - exshared.setpos(loc, text) - if not self.symtab.same_types(arg[0], arg[2]): - raise SemanticException("Invalid operands for operator '{0}'".format(arg[1])) - self.codegen.compare(arg[0], arg[2]) - #return relational operator's code - self.relexp_code = self.codegen.relop_code(arg[1], self.symtab.get_type(arg[0])) - return self.relexp_code - - def andexp_action(self, text, loc, arg): - """Code executed after recognising a andexp expression (something and something)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("AND+EXP:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - label = self.codegen.label("false{0}".format(self.false_label_number), True, False) - self.codegen.jump(self.relexp_code, True, label) - self.andexp_code = self.relexp_code - return self.andexp_code - - def logexp_action(self, text, loc, arg): - """Code executed after recognising logexp expression (something or something)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("LOG_EXP:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - label = self.codegen.label("true{0}".format(self.label_number), True, False) - self.codegen.jump(self.relexp_code, False, label) - self.codegen.newline_label("false{0}".format(self.false_label_number), True, True) - self.false_label_number += 1 - - def if_begin_action(self, text, loc, arg): - """Code executed after recognising an if statement (if keyword)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("IF_BEGIN:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - self.false_label_number += 1 - self.label_number = self.false_label_number - self.codegen.newline_label("if{0}".format(self.label_number), True, True) - - def if_body_action(self, text, loc, arg): - """Code executed after recognising if statement's body""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("IF_BODY:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #generate conditional jump (based on last compare) - label = self.codegen.label("false{0}".format(self.false_label_number), True, False) - self.codegen.jump(self.relexp_code, True, label) - #generate 'true' label (executes if condition is satisfied) - self.codegen.newline_label("true{0}".format(self.label_number), True, True) - #save label numbers (needed for nested if/while statements) - self.label_stack.append(self.false_label_number) - self.label_stack.append(self.label_number) - - def if_else_action(self, text, loc, arg): - """Code executed after recognising if statement's else body""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("IF_ELSE:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #jump to exit after all statements for true condition are executed - self.label_number = self.label_stack.pop() - label = self.codegen.label("exit{0}".format(self.label_number), True, False) - self.codegen.unconditional_jump(label) - #generate final 'false' label (executes if condition isn't satisfied) - self.codegen.newline_label("false{0}".format(self.label_stack.pop()), True, True) - self.label_stack.append(self.label_number) - - def if_end_action(self, text, loc, arg): - """Code executed after recognising a whole if statement""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("IF_END:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - self.codegen.newline_label("exit{0}".format(self.label_stack.pop()), True, True) - - def while_begin_action(self, text, loc, arg): - """Code executed after recognising a while statement (while keyword)""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("WHILE_BEGIN:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - self.false_label_number += 1 - self.label_number = self.false_label_number - self.codegen.newline_label("while{0}".format(self.label_number), True, True) - - def while_body_action(self, text, loc, arg): - """Code executed after recognising while statement's body""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("WHILE_BODY:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #generate conditional jump (based on last compare) - label = self.codegen.label("false{0}".format(self.false_label_number), True, False) - self.codegen.jump(self.relexp_code, True, label) - #generate 'true' label (executes if condition is satisfied) - self.codegen.newline_label("true{0}".format(self.label_number), True, True) - self.label_stack.append(self.false_label_number) - self.label_stack.append(self.label_number) - - def while_end_action(self, text, loc, arg): - """Code executed after recognising a whole while statement""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("WHILE_END:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - #jump to condition checking after while statement body - self.label_number = self.label_stack.pop() - label = self.codegen.label("while{0}".format(self.label_number), True, False) - self.codegen.unconditional_jump(label) - #generate final 'false' label and exit label - self.codegen.newline_label("false{0}".format(self.label_stack.pop()), True, True) - self.codegen.newline_label("exit{0}".format(self.label_number), True, True) - - def program_end_action(self, text, loc, arg): - """Checks if there is a 'main' function and the type of 'main' function""" - exshared.setpos(loc, text) - if DEBUG > 0: - print("PROGRAM_END:",arg) - if DEBUG == 2: self.symtab.display() - if DEBUG > 2: return - index = self.symtab.lookup_symbol("main",SharedData.KINDS.FUNCTION) - if index == None: - raise SemanticException("Undefined reference to 'main'", False) - elif self.symtab.get_type(index) != SharedData.TYPES.INT: - self.warning("Return type of 'main' is not int", False) - - def parse_text(self,text): - """Parse string (helper function)""" - try: - return self.rProgram.ignore(cStyleComment).parseString(text, parseAll=True) - except SemanticException as err: - print(err) - exit(3) - except ParseException as err: - print(err) - exit(3) - - def parse_file(self,filename): - """Parse file (helper function)""" - try: - return self.rProgram.ignore(cStyleComment).parseFile(filename, parseAll=True) - except SemanticException as err: - print(err) - exit(3) - except ParseException as err: - print(err) - exit(3) - -########################################################################################## -########################################################################################## -if 0: - #main program - mc = MicroC() - output_file = "output.asm" - - if len(argv) == 1: - input_file = stdin - elif len(argv) == 2: - input_file = argv[1] - elif len(argv) == 3: - input_file = argv[1] - output_file = argv[2] - else: - usage = """Usage: {0} [input_file [output_file]] - If output file is omitted, output.asm is used - If input file is omitted, stdin is used""".format(argv[0]) - print(usage) - exit(1) - try: - parse = stdin if input_file == stdin else open(input_file,'r') - except Exception: - print("Input file '%s' open error" % input_file) - exit(2) - mc.parse_file(parse) - #if you want to see the final symbol table, uncomment next line - #mc.symtab.display() - try: - out = open(output_file, 'w') - out.write(mc.codegen.code) - out.close - except Exception: - print("Output file '%s' open error" % output_file) - exit(2) - -########################################################################################## -########################################################################################## - -if __name__ == "__main__": - - test_program_example = """ - int a; - int b; - int c; - unsigned d; - - int fun1(int x, unsigned y) { - return 123; - } - - int fun2(int a) { - return 1 + a * fun1(a, 456u); - } - - int main(int x, int y) { - int w; - unsigned z; - if (9 > 8 && 2 < 3 || 6 != 5 && a <= b && c < x || w >= y) { - a = b + 1; - if (x == y) - while (d < 4u) - x = x * w; - else - while (a + b < c - y && x > 3 || y < 2) - if (z > d) - a = a - 4; - else - b = a * b * c * x / y; - } - else - c = 4; - a = fun1(x,d) + fun2(fun1(fun2(w + 3 * 2) + 2 * c, 2u)); - return 2; - } - """ - - mc = MicroC() - mc.parse_text(test_program_example) - print(mc.codegen.code) \ No newline at end of file diff --git a/examples/pythonGrammarParser.py b/examples/pythonGrammarParser.py deleted file mode 100644 index f199917..0000000 --- a/examples/pythonGrammarParser.py +++ /dev/null @@ -1,220 +0,0 @@ -# pythonGrammarParser.py -# -# Copyright, 2006, by Paul McGuire -# - -from pyparsing import * - -# should probably read this from the Grammar file provided with the Python source, but -# this just skips that step and inlines the bnf text directly - this grammar was taken from -# Python 2.4.1 -# -grammar = r""" -# Grammar for Python - -# Note: Changing the grammar specified in this file will most likely -# require corresponding changes in the parser module -# (../Modules/parsermodule.c). If you can't make the changes to -# that module yourself, please co-ordinate the required changes -# with someone who can; ask around on python-dev for help. Fred -# Drake will probably be listening there. - -# Commands for Kees Blom's railroad program -#diagram:token NAME -#diagram:token NUMBER -#diagram:token STRING -#diagram:token NEWLINE -#diagram:token ENDMARKER -#diagram:token INDENT -#diagram:output\input python.bla -#diagram:token DEDENT -#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm -#diagram:rules - -# Start symbols for the grammar: -# single_input is a single interactive statement; -# file_input is a module or sequence of commands read from an input file; -# eval_input is the input for the eval() and input() functions. -# NB: compound_stmt in single_input is followed by extra NEWLINE! -single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE -file_input: (NEWLINE | stmt)* ENDMARKER -eval_input: testlist NEWLINE* ENDMARKER - -decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE -decorators: decorator+ -funcdef: [decorators] 'def' NAME parameters ':' suite -parameters: '(' [varargslist] ')' -varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [','] -fpdef: NAME | '(' fplist ')' -fplist: fpdef (',' fpdef)* [','] - -stmt: simple_stmt | compound_stmt -simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE -small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt -expr_stmt: testlist (augassign testlist | ('=' testlist)*) -augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' -# For normal assignments, additional restrictions enforced by the interpreter -print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] ) -del_stmt: 'del' exprlist -pass_stmt: 'pass' -flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt -break_stmt: 'break' -continue_stmt: 'continue' -return_stmt: 'return' [testlist] -yield_stmt: 'yield' testlist -raise_stmt: 'raise' [test [',' test [',' test]]] -import_stmt: import_name | import_from -import_name: 'import' dotted_as_names -import_from: 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) -import_as_name: NAME [NAME NAME] -dotted_as_name: dotted_name [NAME NAME] -import_as_names: import_as_name (',' import_as_name)* [','] -dotted_as_names: dotted_as_name (',' dotted_as_name)* -dotted_name: NAME ('.' NAME)* -global_stmt: 'global' NAME (',' NAME)* -exec_stmt: 'exec' expr ['in' test [',' test]] -assert_stmt: 'assert' test [',' test] -#35 -compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef -if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] -while_stmt: 'while' test ':' suite ['else' ':' suite] -for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] -try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break - ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) -# NB compile.c makes sure that the default except clause is last -except_clause: 'except' [test [',' test]] -suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT - -test: and_test ('or' and_test)* | lambdef -and_test: not_test ('and' not_test)* -not_test: 'not' not_test | comparison -comparison: expr (comp_op expr)* -comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' -expr: xor_expr ('|' xor_expr)* -xor_expr: and_expr ('^' and_expr)* -and_expr: shift_expr ('&' shift_expr)* -shift_expr: arith_expr (('<<'|'>>') arith_expr)* -arith_expr: term (('+'|'-') term)* -term: factor (('*'|'/'|'%'|'//') factor)* -factor: ('+'|'-'|'~') factor | power -power: atom trailer* ['**' factor] -atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ -listmaker: test ( list_for | (',' test)* [','] ) -testlist_gexp: test ( gen_for | (',' test)* [','] ) -lambdef: 'lambda' [varargslist] ':' test -trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME -subscriptlist: subscript (',' subscript)* [','] -subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] -sliceop: ':' [test] -exprlist: expr (',' expr)* [','] -testlist: test (',' test)* [','] -testlist_safe: test [(',' test)+ [',']] -dictmaker: test ':' test (',' test ':' test)* [','] - -classdef: 'class' NAME ['(' testlist ')'] ':' suite - -arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test) -argument: [test '='] test [gen_for] # Really [keyword '='] test - -list_iter: list_for | list_if -list_for: 'for' exprlist 'in' testlist_safe [list_iter] -list_if: 'if' test [list_iter] - -gen_iter: gen_for | gen_if -gen_for: 'for' exprlist 'in' test [gen_iter] -gen_if: 'if' test [gen_iter] - -testlist1: test (',' test)* - -# not used in grammar, but may appear in "node" passed from Parser to Compiler -encoding_decl: NAME -""" - -class SemanticGroup(object): - def __init__(self,contents): - self.contents = contents - while self.contents[-1].__class__ == self.__class__: - self.contents = self.contents[:-1] + self.contents[-1].contents - - def __str__(self): - return "%s(%s)" % (self.label, - " ".join([isinstance(c,str) and c or str(c) for c in self.contents]) ) - -class OrList(SemanticGroup): - label = "OR" - pass - -class AndList(SemanticGroup): - label = "AND" - pass - -class OptionalGroup(SemanticGroup): - label = "OPT" - pass - -class Atom(SemanticGroup): - def __init__(self,contents): - if len(contents) > 1: - self.rep = contents[1] - else: - self.rep = "" - if isinstance(contents,str): - self.contents = contents - else: - self.contents = contents[0] - - def __str__(self): - return "%s%s" % (self.rep, self.contents) - -def makeGroupObject(cls): - def groupAction(s,l,t): - try: - return cls(t[0].asList()) - except: - return cls(t) - return groupAction - - -# bnf punctuation -LPAREN = Suppress("(") -RPAREN = Suppress(")") -LBRACK = Suppress("[") -RBRACK = Suppress("]") -COLON = Suppress(":") -ALT_OP = Suppress("|") - -# bnf grammar -ident = Word(alphanums+"_") -bnfToken = Word(alphanums+"_") + ~FollowedBy(":") -repSymbol = oneOf("* +") -bnfExpr = Forward() -optionalTerm = Group(LBRACK + bnfExpr + RBRACK).setParseAction(makeGroupObject(OptionalGroup)) -bnfTerm = ( (bnfToken | quotedString | optionalTerm | ( LPAREN + bnfExpr + RPAREN )) + Optional(repSymbol) ).setParseAction(makeGroupObject(Atom)) -andList = Group(bnfTerm + OneOrMore(bnfTerm)).setParseAction(makeGroupObject(AndList)) -bnfFactor = andList | bnfTerm -orList = Group( bnfFactor + OneOrMore( ALT_OP + bnfFactor ) ).setParseAction(makeGroupObject(OrList)) -bnfExpr << ( orList | bnfFactor ) -bnfLine = ident + COLON + bnfExpr - -bnfComment = "#" + restOfLine - -# build return tokens as a dictionary -bnf = Dict(OneOrMore(Group(bnfLine))) -bnf.ignore(bnfComment) - -# bnf is defined, parse the grammar text -bnfDefs = bnf.parseString(grammar) - -# correct answer is 78 -expected = 78 -assert len(bnfDefs) == expected, \ - "Error, found %d BNF defns, expected %d" % (len(bnfDefs), expected) - -# list out defns in order they were parsed (to verify accuracy of parsing) -for k,v in bnfDefs: - print(k,"=",v) -print() - -# list out parsed grammar defns (demonstrates dictionary access to parsed tokens) -for k in list(bnfDefs.keys()): - print(k,"=",bnfDefs[k]) diff --git a/examples/rangeCheck.py b/examples/rangeCheck.py deleted file mode 100644 index 67cf267..0000000 --- a/examples/rangeCheck.py +++ /dev/null @@ -1,62 +0,0 @@ -# rangeCheck.py -# -# A sample program showing how parse actions can convert parsed -# strings into a data type or object, and to validate the parsed value. -# -# Updated to use new addCondition method and expr() copy. -# -# Copyright 2011,2015 Paul T. McGuire -# - -from pyparsing import Word, nums, Suppress, ParseException, empty, Optional -from datetime import datetime - -def ranged_value(expr, minval=None, maxval=None): - # have to specify at least one range boundary - if minval is None and maxval is None: - raise ValueError("minval or maxval must be specified") - - # set range testing function and error message depending on - # whether either or both min and max values are given - inRangeCondition = { - (True, False) : lambda s,l,t : t[0] <= maxval, - (False, True) : lambda s,l,t : minval <= t[0], - (False, False) : lambda s,l,t : minval <= t[0] <= maxval, - }[minval is None, maxval is None] - outOfRangeMessage = { - (True, False) : "value is greater than %s" % maxval, - (False, True) : "value is less than %s" % minval, - (False, False) : "value is not in the range (%s to %s)" % (minval,maxval), - }[minval is None, maxval is None] - - return expr().addCondition(inRangeCondition, message=outOfRangeMessage) - -# define the expressions for a date of the form YYYY/MM/DD or YYYY/MM (assumes YYYY/MM/01) -integer = Word(nums).setName("integer") -integer.setParseAction(lambda t:int(t[0])) - -month = ranged_value(integer, 1, 12) -day = ranged_value(integer, 1, 31) -year = ranged_value(integer, 2000, None) - -SLASH = Suppress('/') -dateExpr = year("year") + SLASH + month("month") + Optional(SLASH + day("day")) -dateExpr.setName("date") - -# convert date fields to datetime (also validates dates as truly valid dates) -dateExpr.setParseAction(lambda t: datetime(t.year, t.month, t.day or 1).date()) - -# add range checking on dates -mindate = datetime(2002,1,1).date() -maxdate = datetime.now().date() -dateExpr = ranged_value(dateExpr, mindate, maxdate) - - -dateExpr.runTests(""" - 2011/5/8 - 2001/1/1 - 2004/2/29 - 2004/2 - 1999/12/31""") - - diff --git a/examples/readJson.py b/examples/readJson.py deleted file mode 100644 index deca53b..0000000 --- a/examples/readJson.py +++ /dev/null @@ -1,1917 +0,0 @@ - -#~ url = "http://cmsdoc.cern.ch/cms/test/aprom/phedex/dev/gowri/datasvc/tbedi/requestDetails" -#~ params = {'format':'json'} -#~ import urllib -#~ eparams = urllib.urlencode(params) -#~ import urllib2 -#~ request = urllib2.Request(url,eparams) -#~ response = urllib2.urlopen(request) -#~ s = response.read() -#~ response.close() - -#~ print s - -s = """ -{"phedex":{"request":[{"last_update":"1188037561", "numofapproved":"1", -"id":"7425"}, {"last_update":"1188751826", "numofapproved":"1", -"id":"8041"}, {"last_update":"1190116795", "numofapproved":"1", -"id":"9281"}, {"last_update":"1190248781", "numofapproved":"1", -"id":"9521"}, {"last_update":"1192615612", "numofapproved":"1", -"id":"12821"}, {"last_update":"1192729887", "numofapproved":"1", -"id":"13121"}, {"last_update":"1193152971", "numofapproved":"1", -"id":"13501"}, {"last_update":"1194022054", "numofapproved":"1", -"id":"14782"}, {"last_update":"1194429365", "numofapproved":"1", -"id":"15081"}, {"last_update":"1195069848", "numofapproved":"1", -"id":"16661"}, {"last_update":"1178403225", "numofapproved":"1", -"id":"1281"}, {"last_update":"1179239056", "numofapproved":"1", -"id":"1387"}, {"last_update":"1179842205", "numofapproved":"1", -"id":"1665"}, {"last_update":"1179842040", "numofapproved":"1", -"id":"1661"}, {"last_update":"1179935333", "numofapproved":"1", -"id":"1741"}, {"last_update":"1183151195", "numofapproved":"1", -"id":"3841"}, {"last_update":"1187031531", "numofapproved":"1", -"id":"6601"}, {"last_update":"1188820478", "numofapproved":"1", -"id":"8121"}, {"last_update":"1190652719", "numofapproved":"1", -"id":"9983"}, {"last_update":"1192628950", "numofapproved":"1", -"id":"12841"}, {"last_update":"1193075426", "numofapproved":"1", -"id":"13341"}, {"last_update":"1194214609", "numofapproved":"1", -"id":"14882"}, {"last_update":"1194387864", "numofapproved":"1", -"id":"15062"}, {"last_update":"1195134504", "numofapproved":"1", -"id":"16741"}, {"last_update":"1182431453", "numofapproved":"1", -"id":"3421"}, {"last_update":"1183448188", "numofapproved":"1", -"id":"4061"}, {"last_update":"1184588081", "numofapproved":"1", -"id":"4908"}, {"last_update":"1184681258", "numofapproved":"1", -"id":"4913"}, {"last_update":"1188039048", "numofapproved":"1", -"id":"7426"}, {"last_update":"1192699041", "numofapproved":"1", -"id":"12982"}, {"last_update":"1193219685", "numofapproved":"1", -"id":"13529"}, {"last_update":"1193401408", "numofapproved":"1", -"id":"14081"}, {"last_update":"1194454724", "numofapproved":"1", -"id":"15201"}, {"last_update":"1194937690", "numofapproved":"1", -"id":"16044"}, {"last_update":"1194947125", "numofapproved":"1", -"id":"16103"}, {"last_update":"1195134890", "numofapproved":"1", -"id":"16761"}, {"last_update":"1195486898", "numofapproved":"1", -"id":"17301"}, {"last_update":"1195497774", "numofapproved":"1", -"id":"17341"}, {"last_update":"1184744080", "numofapproved":"1", -"id":"4941"}, {"last_update":"1186558911", "numofapproved":"1", -"id":"6321"}, {"last_update":"1189524520", "numofapproved":"1", -"id":"8802"}, {"last_update":"1192683178", "numofapproved":"1", -"id":"12921"}, {"last_update":"1193260655", "numofapproved":"1", -"id":"13530"}, {"last_update":"1194280038", "numofapproved":"1", -"id":"15002"}, {"last_update":"1182077478", "numofapproved":"1", -"id":"3162"}, {"last_update":"1183386650", "numofapproved":"1", -"id":"3961"}, {"last_update":"1192063369", "numofapproved":"1", -"id":"12182"}, {"last_update":"1181931262", "numofapproved":"1", -"id":"3101"}, {"last_update":"1178648271", "numofapproved":"1", -"id":"1308"}, {"last_update":"1179239923", "numofapproved":"1", -"id":"1405"}, {"last_update":"1184370745", "numofapproved":"1", -"id":"4861"}, {"last_update":"1185280568", "numofapproved":"1", -"id":"5302"}, {"last_update":"1187875115", "numofapproved":"1", -"id":"7344"}, {"last_update":"1189140441", "numofapproved":"1", -"id":"8541"}, {"last_update":"1189180903", "numofapproved":"1", -"id":"8661"}, {"last_update":"1189767643", "numofapproved":"1", -"id":"9001"}, {"last_update":"1190726167", "numofapproved":"1", -"id":"10101"}, {"last_update":"1190972990", "numofapproved":"1", -"id":"10661"}, {"last_update":"1190990720", "numofapproved":"1", -"id":"10712"}, {"last_update":"1192004838", "numofapproved":"1", -"id":"12021"}, {"last_update":"1192612211", "numofapproved":"1", -"id":"12803"}, {"last_update":"1194441407", "numofapproved":"1", -"id":"15103"}, {"last_update":"1194792356", "numofapproved":"1", -"id":"15681"}, {"last_update":"1194860650", "numofapproved":"1", -"id":"15801"}, {"last_update":"1194877395", "numofapproved":"1", -"id":"15881"}, {"last_update":"1194950552", "numofapproved":"1", -"id":"16124"}, {"last_update":"1194992714", "numofapproved":"1", -"id":"16421"}, {"last_update":"1195054500", "numofapproved":"1", -"id":"16581"}, {"last_update":"1195228524", "numofapproved":"1", -"id":"17001"}, {"last_update":"1195469382", "numofapproved":"1", -"id":"17161"}, {"last_update":"1178035947", "numofapproved":"1", -"id":"1202"}, {"last_update":"1178869668", "numofapproved":"1", -"id":"1356"}, {"last_update":"1183563268", "numofapproved":"1", -"id":"4201"}, {"last_update":"1185314677", "numofapproved":"1", -"id":"5361"}, {"last_update":"1188467567", "numofapproved":"1", -"id":"7781"}, {"last_update":"1190011821", "numofapproved":"1", -"id":"9202"}, {"last_update":"1190206214", "numofapproved":"1", -"id":"9481"}, {"last_update":"1190973037", "numofapproved":"1", -"id":"10663"}, {"last_update":"1190819127", "numofapproved":"1", -"id":"10342"}, {"last_update":"1192154959", "numofapproved":"1", -"id":"12381"}, {"last_update":"1192634509", "numofapproved":"1", -"id":"12862"}, {"last_update":"1194004677", "numofapproved":"1", -"id":"14722"}, {"last_update":"1195548191", "numofapproved":"1", -"id":"17501"}, {"last_update":"1195548953", "numofapproved":"1", -"id":"17502"}, {"last_update":"1195559809", "numofapproved":"1", -"id":"17541"}, {"last_update":"1177589103", "numofapproved":"1", -"id":"1044"}, {"last_update":"1183416879", "numofapproved":"1", -"id":"4041"}, {"last_update":"1186646977", "numofapproved":"1", -"id":"6342"}, {"last_update":"1189656586", "numofapproved":"1", -"id":"8902"}, {"last_update":"1190150645", "numofapproved":"1", -"id":"9421"}, {"last_update":"1190409040", "numofapproved":"1", -"id":"9741"}, {"last_update":"1190973011", "numofapproved":"1", -"id":"10662"}, {"last_update":"1190993896", "numofapproved":"1", -"id":"10761"}, {"last_update":"1193973610", "numofapproved":"1", -"id":"14661"}, {"last_update":"1193973848", "numofapproved":"1", -"id":"14664"}, {"last_update":"1194539978", "numofapproved":"1", -"id":"15381"}, {"last_update":"1194947356", "numofapproved":"1", -"id":"16105"}, {"last_update":"1195399589", "numofapproved":"1", -"id":"17101"}, {"last_update":"1195464953", "numofapproved":"1", -"id":"17141"}, {"last_update":"1171962221", "numofapproved":"1", -"id":"109"}, {"last_update":"1173113812", "numofapproved":"1", -"id":"247"}, {"last_update":"1173975435", "numofapproved":"1", -"id":"343"}, {"last_update":"1174050971", "numofapproved":"1", -"id":"353"}, {"last_update":"1174301484", "numofapproved":"1", -"id":"393"}, {"last_update":"1172565853", "numofapproved":"1", -"id":"208"}, {"last_update":"1172593328", "numofapproved":"1", -"id":"215"}, {"last_update":"1175267391", "numofapproved":"1", -"id":"565"}, {"last_update":"1171379845", "numofapproved":"1", -"id":"25"}, {"last_update":"1171477466", "numofapproved":"1", -"id":"53"}, {"last_update":"1171799296", "numofapproved":"1", -"id":"77"}, {"last_update":"1172671474", "numofapproved":"1", -"id":"223"}, {"last_update":"1174301354", "numofapproved":"1", -"id":"388"}, {"last_update":"1174899552", "numofapproved":"1", -"id":"511"}, {"last_update":"1174899458", "numofapproved":"1", -"id":"505"}, {"last_update":"1175502936", "numofapproved":"1", -"id":"604"}, {"last_update":"1175613825", "numofapproved":"1", -"id":"665"}, {"last_update":"1175776232", "numofapproved":"1", -"id":"673"}, {"last_update":"1171621302", "numofapproved":"1", -"id":"68"}, {"last_update":"1171904738", "numofapproved":"1", -"id":"98"}, {"last_update":"1171968012", "numofapproved":"1", -"id":"115"}, {"last_update":"1172145037", "numofapproved":"1", -"id":"168"}, {"last_update":"1172246599", "numofapproved":"1", -"id":"185"}, {"last_update":"1173886280", "numofapproved":"1", -"id":"318"}, {"last_update":"1174562010", "numofapproved":"1", -"id":"423"}, {"last_update":"1176308974", "numofapproved":"1", -"id":"884"}, {"last_update":"1176482150", "numofapproved":"1", -"id":"943"}, {"last_update":"1176702424", "numofapproved":"1", -"id":"1001"}, {"last_update":"1176748776", "numofapproved":"1", -"id":"984"}, {"last_update":"1172669745", "numofapproved":"1", -"id":"222"}, {"last_update":"1174899538", "numofapproved":"1", -"id":"510"}, {"last_update":"1174899143", "numofapproved":"1", -"id":"493"}, {"last_update":"1174899043", "numofapproved":"1", -"id":"488"}, {"last_update":"1175711780", "numofapproved":"1", -"id":"667"}, {"last_update":"1175712851", "numofapproved":"1", -"id":"705"}, {"last_update":"1176296548", "numofapproved":"1", -"id":"841"}, {"last_update":"1175862269", "numofapproved":"1", -"id":"781"}, {"last_update":"1171483107", "numofapproved":"1", -"id":"54"}, {"last_update":"1171645737", "numofapproved":"1", -"id":"71"}, {"last_update":"1172253423", "numofapproved":"1", -"id":"188"}, {"last_update":"1173888726", "numofapproved":"1", -"id":"321"}, {"last_update":"1173975649", "numofapproved":"1", -"id":"346"}, {"last_update":"1174299379", "numofapproved":"1", -"id":"363"}, {"last_update":"1174301359", "numofapproved":"1", -"id":"389"}, {"last_update":"1174301073", "numofapproved":"1", -"id":"379"}, {"last_update":"1174300650", "numofapproved":"1", -"id":"371"}, {"last_update":"1171485069", "numofapproved":"1", -"id":"55"}, {"last_update":"1171799178", "numofapproved":"1", -"id":"73"}, {"last_update":"1171896809", "numofapproved":"1", -"id":"95"}, {"last_update":"1172672959", "numofapproved":"1", -"id":"224"}, {"last_update":"1172693619", "numofapproved":"1", -"id":"230"}, {"last_update":"1173207656", "numofapproved":"1", -"id":"253"}, {"last_update":"1174059533", "numofapproved":"1", -"id":"356"}, {"last_update":"1174300538", "numofapproved":"1", -"id":"368"}, {"last_update":"1176137457", "numofapproved":"1", -"id":"807"}, {"last_update":"1173728124", "numofapproved":"1", -"id":"305"}, {"last_update":"1172507633", "numofapproved":"1", -"id":"198"}, {"last_update":"1174301173", "numofapproved":"1", -"id":"383"}, {"last_update":"1174899102", "numofapproved":"1", -"id":"491"}, {"last_update":"1174301362", "numofapproved":"1", -"id":"390"}, {"last_update":"1175254095", "numofapproved":"1", -"id":"561"}, {"last_update":"1174037250", "numofapproved":"1", -"id":"348"}, {"last_update":"1175865081", "numofapproved":"1", -"id":"782"}, {"last_update":"1177591942", "numofapproved":"1", -"id":"1046"}, {"last_update":"1177989191", "numofapproved":"1", -"id":"1201"}, {"last_update":"1178743279", "numofapproved":"1", -"id":"1323"}, {"last_update":"1178876587", "numofapproved":"1", -"id":"1357"}, {"last_update":"1179239620", "numofapproved":"1", -"id":"1401"}, {"last_update":"1180725458", "numofapproved":"1", -"id":"2141"}, {"last_update":"1181205209", "numofapproved":"1", -"id":"2421"}, {"last_update":"1181575615", "numofapproved":"1", -"id":"2761"}, {"last_update":"1182184775", "numofapproved":"1", -"id":"3201"}, {"last_update":"1182963728", "numofapproved":"1", -"id":"3661"}, {"last_update":"1178727735", "numofapproved":"1", -"id":"1349"}, {"last_update":"1182497720", "numofapproved":"1", -"id":"3441"}, {"last_update":"1184381847", "numofapproved":"1", -"id":"4881"}, {"last_update":"1184568423", "numofapproved":"1", -"id":"4904"}, {"last_update":"1185364813", "numofapproved":"1", -"id":"5421"}, {"last_update":"1188043594", "numofapproved":"1", -"id":"7441"}, {"last_update":"1188675287", "numofapproved":"1", -"id":"7981"}, {"last_update":"1188741594", "numofapproved":"1", -"id":"8021"}, {"last_update":"1189144234", "numofapproved":"1", -"id":"8561"}, {"last_update":"1189170150", "numofapproved":"1", -"id":"8641"}, {"last_update":"1189501508", "numofapproved":"1", -"id":"8761"}, {"last_update":"1189811918", "numofapproved":"1", -"id":"9041"}, {"last_update":"1189812095", "numofapproved":"1", -"id":"9042"}, {"last_update":"1177591716", "numofapproved":"1", -"id":"1045"}, {"last_update":"1178040595", "numofapproved":"1", -"id":"1203"}, {"last_update":"1182437936", "numofapproved":"1", -"id":"3423"}, {"last_update":"1190480042", "numofapproved":"1", -"id":"9781"}, {"last_update":"1190821494", "numofapproved":"1", -"id":"10361"}, {"last_update":"1190959672", "numofapproved":"1", -"id":"10602"}, {"last_update":"1190964023", "numofapproved":"1", -"id":"10621"}, {"last_update":"1190991147", "numofapproved":"1", -"id":"10721"}, {"last_update":"1190992132", "numofapproved":"1", -"id":"10741"}, {"last_update":"1190990410", "numofapproved":"1", -"id":"10706"}, {"last_update":"1181667132", "numofapproved":"1", -"id":"2861"}, {"last_update":"1183746653", "numofapproved":"1", -"id":"4321"}, {"last_update":"1191184539", "numofapproved":"1", -"id":"10861"}, {"last_update":"1191490599", "numofapproved":"1", -"id":"11261"}, {"last_update":"1191834884", "numofapproved":"1", -"id":"11801"}, {"last_update":"1191834899", "numofapproved":"1", -"id":"11802"}, {"last_update":"1191940759", "numofapproved":"1", -"id":"11961"}, {"last_update":"1179971250", "numofapproved":"1", -"id":"1643"}, {"last_update":"1181663618", "numofapproved":"1", -"id":"2841"}, {"last_update":"1181932994", "numofapproved":"1", -"id":"3102"}, {"last_update":"1182420732", "numofapproved":"1", -"id":"3382"}, {"last_update":"1192118127", "numofapproved":"1", -"id":"12281"}, {"last_update":"1192222036", "numofapproved":"1", -"id":"12481"}, {"last_update":"1192155814", "numofapproved":"1", -"id":"12364"}, {"last_update":"1192563924", "numofapproved":"1", -"id":"12761"}, {"last_update":"1193124530", "numofapproved":"1", -"id":"13441"}, {"last_update":"1193345545", "numofapproved":"1", -"id":"13921"}, {"last_update":"1193396927", "numofapproved":"1", -"id":"14041"}, {"last_update":"1180015411", "numofapproved":"1", -"id":"1651"}, {"last_update":"1180107815", "numofapproved":"1", -"id":"1658"}, {"last_update":"1186050394", "numofapproved":"1", -"id":"6021"}, {"last_update":"1188519417", "numofapproved":"1", -"id":"7841"}, {"last_update":"1193222002", "numofapproved":"1", -"id":"13541"}, {"last_update":"1193965081", "numofapproved":"1", -"id":"14641"}, {"last_update":"1193660582", "numofapproved":"1", -"id":"14381"}, {"last_update":"1194088240", "numofapproved":"1", -"id":"14821"}, {"last_update":"1194110475", "numofapproved":"1", -"id":"14841"}, {"last_update":"1194246367", "numofapproved":"1", -"id":"14902"}, {"last_update":"1194464283", "numofapproved":"1", -"id":"15221"}, {"last_update":"1194622250", "numofapproved":"1", -"id":"15461"}, {"last_update":"1194635632", "numofapproved":"1", -"id":"15601"}, {"last_update":"1179147506", "numofapproved":"1", -"id":"1382"}, {"last_update":"1179240025", "numofapproved":"1", -"id":"1388"}, {"last_update":"1179748089", "numofapproved":"1", -"id":"1561"}, {"last_update":"1179868997", "numofapproved":"1", -"id":"1681"}, {"last_update":"1183019667", "numofapproved":"1", -"id":"3702"}, {"last_update":"1184531598", "numofapproved":"1", -"id":"4902"}, {"last_update":"1187294472", "numofapproved":"1", -"id":"6841"}, {"last_update":"1189521494", "numofapproved":"1", -"id":"8801"}, {"last_update":"1192726867", "numofapproved":"1", -"id":"13081"}, {"last_update":"1193049178", "numofapproved":"1", -"id":"13301"}, {"last_update":"1193387050", "numofapproved":"1", -"id":"13947"}, {"last_update":"1194277280", "numofapproved":"1", -"id":"14981"}, {"last_update":"1179150720", "numofapproved":"1", -"id":"1383"}, {"last_update":"1179842104", "numofapproved":"1", -"id":"1663"}, {"last_update":"1183766887", "numofapproved":"1", -"id":"4341"}, {"last_update":"1185542132", "numofapproved":"1", -"id":"5682"}, {"last_update":"1186737114", "numofapproved":"1", -"id":"6382"}, {"last_update":"1187015679", "numofapproved":"1", -"id":"6521"}, {"last_update":"1190326980", "numofapproved":"1", -"id":"9641"}, {"last_update":"1191595711", "numofapproved":"1", -"id":"11622"}, {"last_update":"1192106288", "numofapproved":"1", -"id":"12221"}, {"last_update":"1192454432", "numofapproved":"1", -"id":"12622"}, {"last_update":"1194339640", "numofapproved":"1", -"id":"15021"}, {"last_update":"1177758209", "numofapproved":"1", -"id":"1181"}, {"last_update":"1179842392", "numofapproved":"1", -"id":"1669"}, {"last_update":"1179872870", "numofapproved":"1", -"id":"1682"}, {"last_update":"1181233887", "numofapproved":"1", -"id":"2541"}, {"last_update":"1182349297", "numofapproved":"1", -"id":"3342"}, {"last_update":"1182375421", "numofapproved":"1", -"id":"3350"}, {"last_update":"1183485259", "numofapproved":"1", -"id":"4081"}, {"last_update":"1184319308", "numofapproved":"1", -"id":"4821"}, {"last_update":"1187626648", "numofapproved":"1", -"id":"6981"}, {"last_update":"1193153090", "numofapproved":"1", -"id":"13502"}, {"last_update":"1194366368", "numofapproved":"1", -"id":"15041"}, {"last_update":"1194617018", "numofapproved":"1", -"id":"15421"}, {"last_update":"1195230640", "numofapproved":"1", -"id":"17021"}, {"last_update":"1179908379", "numofapproved":"1", -"id":"1701"}, {"last_update":"1188049228", "numofapproved":"1", -"id":"7427"}, {"last_update":"1177581166", "numofapproved":"1", -"id":"1061"}, {"last_update":"1187160654", "numofapproved":"1", -"id":"6661"}, {"last_update":"1192983992", "numofapproved":"1", -"id":"13222"}, {"last_update":"1193388978", "numofapproved":"1", -"id":"13954"}, {"last_update":"1194617112", "numofapproved":"1", -"id":"15422"}, {"last_update":"1195398876", "numofapproved":"1", -"id":"17081"}, {"last_update":"1184262511", "numofapproved":"1", -"id":"4801"}, {"last_update":"1192112284", "numofapproved":"1", -"id":"12241"}, {"last_update":"1193082767", "numofapproved":"1", -"id":"13401"}, {"last_update":"1193179243", "numofapproved":"1", -"id":"13526"}, {"last_update":"1178142915", "numofapproved":"1", -"id":"1206"}, {"last_update":"1178648333", "numofapproved":"1", -"id":"1310"}, {"last_update":"1179279626", "numofapproved":"1", -"id":"1391"}, {"last_update":"1182882268", "numofapproved":"1", -"id":"3584"}, {"last_update":"1183128448", "numofapproved":"1", -"id":"3823"}, {"last_update":"1183377394", "numofapproved":"1", -"id":"3941"}, {"last_update":"1188582729", "numofapproved":"1", -"id":"7902"}, {"last_update":"1189695063", "numofapproved":"1", -"id":"8962"}, {"last_update":"1192001165", "numofapproved":"1", -"id":"12001"}, {"last_update":"1192155647", "numofapproved":"1", -"id":"12363"}, {"last_update":"1193418304", "numofapproved":"1", -"id":"14202"}, {"last_update":"1193632105", "numofapproved":"1", -"id":"14341"}, {"last_update":"1194011106", "numofapproved":"1", -"id":"14741"}, {"last_update":"1194818628", "numofapproved":"1", -"id":"15701"}, {"last_update":"1194875153", "numofapproved":"1", -"id":"15861"}, {"last_update":"1194727029", "numofapproved":"1", -"id":"15665"}, {"last_update":"1194950210", "numofapproved":"1", -"id":"16122"}, {"last_update":"1194976681", "numofapproved":"1", -"id":"16241"}, {"last_update":"1194979189", "numofapproved":"1", -"id":"16281"}, {"last_update":"1194962224", "numofapproved":"1", -"id":"16201"}, {"last_update":"1195046085", "numofapproved":"1", -"id":"16481"}, {"last_update":"1195399919", "numofapproved":"1", -"id":"17102"}, {"last_update":"1183113736", "numofapproved":"1", -"id":"3782"}, {"last_update":"1183114202", "numofapproved":"1", -"id":"3783"}, {"last_update":"1189017904", "numofapproved":"1", -"id":"8441"}, {"last_update":"1189694944", "numofapproved":"1", -"id":"8961"}, {"last_update":"1190766842", "numofapproved":"1", -"id":"10181"}, {"last_update":"1190973066", "numofapproved":"1", -"id":"10665"}, {"last_update":"1190990264", "numofapproved":"1", -"id":"10702"}, {"last_update":"1193043204", "numofapproved":"1", -"id":"13281"}, {"last_update":"1194627082", "numofapproved":"1", -"id":"15561"}, {"last_update":"1194894589", "numofapproved":"1", -"id":"15941"}, {"last_update":"1195485915", "numofapproved":"1", -"id":"17281"}, {"last_update":"1195485806", "numofapproved":"1", -"id":"17261"}, {"last_update":"1195498836", "numofapproved":"1", -"id":"17361"}, {"last_update":"1195514951", "numofapproved":"1", -"id":"17421"}, {"last_update":"1183722351", "numofapproved":"1", -"id":"4261"}, {"last_update":"1184218083", "numofapproved":"1", -"id":"4682"}, {"last_update":"1186848968", "numofapproved":"1", -"id":"6441"}, {"last_update":"1187023846", "numofapproved":"1", -"id":"6561"}, {"last_update":"1187870812", "numofapproved":"1", -"id":"7342"}, {"last_update":"1188657717", "numofapproved":"1", -"id":"7961"}, {"last_update":"1190541897", "numofapproved":"1", -"id":"9841"}, {"last_update":"1190629135", "numofapproved":"1", -"id":"9922"}, {"last_update":"1191226530", "numofapproved":"1", -"id":"10922"}, {"last_update":"1191505214", "numofapproved":"1", -"id":"11321"}, {"last_update":"1192304524", "numofapproved":"1", -"id":"12541"}, {"last_update":"1193948730", "numofapproved":"1", -"id":"14601"}, {"last_update":"1194073812", "numofapproved":"1", -"id":"14801"}, {"last_update":"1194387224", "numofapproved":"1", -"id":"14892"}, {"last_update":"1194464384", "numofapproved":"1", -"id":"15223"}, {"last_update":"1194726799", "numofapproved":"1", -"id":"15663"}, {"last_update":"1171969969", "numofapproved":"1", -"id":"119"}, {"last_update":"1174444717", "numofapproved":"1", -"id":"405"}, {"last_update":"1174899431", "numofapproved":"1", -"id":"504"}, {"last_update":"1174899204", "numofapproved":"1", -"id":"496"}, {"last_update":"1174925591", "numofapproved":"1", -"id":"530"}, {"last_update":"1176902523", "numofapproved":"1", -"id":"1008"}, {"last_update":"1172765523", "numofapproved":"1", -"id":"232"}, {"last_update":"1173315950", "numofapproved":"1", -"id":"260"}, {"last_update":"1174899524", "numofapproved":"1", -"id":"509"}, {"last_update":"1174300691", "numofapproved":"1", -"id":"373"}, {"last_update":"1175502917", "numofapproved":"1", -"id":"625"}, {"last_update":"1175601578", "numofapproved":"1", -"id":"662"}, {"last_update":"1175608600", "numofapproved":"1", -"id":"684"}, {"last_update":"1176755309", "numofapproved":"1", -"id":"985"}, {"last_update":"1171386411", "numofapproved":"1", -"id":"45"}, {"last_update":"1171800366", "numofapproved":"1", -"id":"81"}, {"last_update":"1172847417", "numofapproved":"1", -"id":"241"}, {"last_update":"1174734904", "numofapproved":"1", -"id":"462"}, {"last_update":"1174735234", "numofapproved":"1", -"id":"469"}, {"last_update":"1174735074", "numofapproved":"1", -"id":"465"}, {"last_update":"1175267646", "numofapproved":"1", -"id":"566"}, {"last_update":"1176331857", "numofapproved":"1", -"id":"888"}, {"last_update":"1176387926", "numofapproved":"1", -"id":"890"}, {"last_update":"1176458401", "numofapproved":"1", -"id":"904"}, {"last_update":"1173088626", "numofapproved":"1", -"id":"244"}, {"last_update":"1173109009", "numofapproved":"1", -"id":"246"}, {"last_update":"1173671557", "numofapproved":"1", -"id":"284"}, {"last_update":"1174927658", "numofapproved":"1", -"id":"532"}, {"last_update":"1175592399", "numofapproved":"1", -"id":"661"}, {"last_update":"1176480402", "numofapproved":"1", -"id":"941"}, {"last_update":"1176561564", "numofapproved":"1", -"id":"945"}, {"last_update":"1172218707", "numofapproved":"1", -"id":"180"}, {"last_update":"1172771475", "numofapproved":"1", -"id":"233"}, {"last_update":"1173267863", "numofapproved":"1", -"id":"257"}, {"last_update":"1176493803", "numofapproved":"1", -"id":"963"}, {"last_update":"1171449646", "numofapproved":"1", -"id":"49"}, {"last_update":"1171471549", "numofapproved":"1", -"id":"51"}, {"last_update":"1171800487", "numofapproved":"1", -"id":"88"}, {"last_update":"1171800431", "numofapproved":"1", -"id":"85"}, {"last_update":"1175502995", "numofapproved":"1", -"id":"627"}, {"last_update":"1175712797", "numofapproved":"1", -"id":"704"}, {"last_update":"1171122384", "numofapproved":"1", -"id":"3"}, {"last_update":"1171380774", "numofapproved":"1", "id":"26"}, -{"last_update":"1171904757", "numofapproved":"1", "id":"99"}, -{"last_update":"1174300705", "numofapproved":"1", "id":"374"}, -{"last_update":"1174924802", "numofapproved":"1", "id":"526"}, -{"last_update":"1175935441", "numofapproved":"1", "id":"801"}, -{"last_update":"1175610915", "numofapproved":"1", "id":"686"}, -{"last_update":"1171977081", "numofapproved":"1", "id":"125"}, -{"last_update":"1173165324", "numofapproved":"1", "id":"249"}, -{"last_update":"1173888337", "numofapproved":"1", "id":"319"}, -{"last_update":"1173889473", "numofapproved":"1", "id":"331"}, -{"last_update":"1172180902", "numofapproved":"1", "id":"175"}, -{"last_update":"1174058063", "numofapproved":"1", "id":"354"}, -{"last_update":"1174300674", "numofapproved":"1", "id":"372"}, -{"last_update":"1171886332", "numofapproved":"1", "id":"93"}, -{"last_update":"1176731068", "numofapproved":"1", "id":"1003"}, -{"last_update":"1178645848", "numofapproved":"1", "id":"1306"}, -{"last_update":"1178706683", "numofapproved":"1", "id":"1321"}, -{"last_update":"1179240076", "numofapproved":"1", "id":"1406"}, -{"last_update":"1180380411", "numofapproved":"1", "id":"1862"}, -{"last_update":"1180683561", "numofapproved":"1", "id":"2041"}, -{"last_update":"1181229731", "numofapproved":"1", "id":"2521"}, -{"last_update":"1182210982", "numofapproved":"1", "id":"3203"}, -{"last_update":"1182421105", "numofapproved":"1", "id":"3401"}, -{"last_update":"1182199404", "numofapproved":"1", "id":"3202"}, -{"last_update":"1182258596", "numofapproved":"1", "id":"3241"}, -{"last_update":"1183556842", "numofapproved":"1", "id":"4161"}, -{"last_update":"1184146825", "numofapproved":"1", "id":"4601"}, -{"last_update":"1184771229", "numofapproved":"1", "id":"4981"}, -{"last_update":"1185355415", "numofapproved":"1", "id":"5401"}, -{"last_update":"1185377130", "numofapproved":"1", "id":"5481"}, -{"last_update":"1185483994", "numofapproved":"1", "id":"5621"}, -{"last_update":"1186496707", "numofapproved":"1", "id":"6261"}, -{"last_update":"1187704347", "numofapproved":"1", "id":"7001"}, -{"last_update":"1187758331", "numofapproved":"1", "id":"7101"}, -{"last_update":"1187765716", "numofapproved":"1", "id":"7161"}, -{"last_update":"1188284185", "numofapproved":"1", "id":"7581"}, -{"last_update":"1188463286", "numofapproved":"1", "id":"7761"}, -{"last_update":"1189012058", "numofapproved":"1", "id":"8421"}, -{"last_update":"1189814265", "numofapproved":"1", "id":"9061"}, -{"last_update":"1180880867", "numofapproved":"1", "id":"2161"}, -{"last_update":"1181218244", "numofapproved":"1", "id":"2463"}, -{"last_update":"1183515137", "numofapproved":"1", "id":"4141"}, -{"last_update":"1183515248", "numofapproved":"1", "id":"4142"}, -{"last_update":"1188311100", "numofapproved":"1", "id":"7641"}, -{"last_update":"1190011501", "numofapproved":"1", "id":"9201"}, -{"last_update":"1190012299", "numofapproved":"1", "id":"9221"}, -{"last_update":"1190149196", "numofapproved":"1", "id":"9382"}, -{"last_update":"1190202046", "numofapproved":"1", "id":"9461"}, -{"last_update":"1190626607", "numofapproved":"1", "id":"9881"}, -{"last_update":"1190632230", "numofapproved":"1", "id":"9941"}, -{"last_update":"1190660429", "numofapproved":"1", "id":"10002"}, -{"last_update":"1190819102", "numofapproved":"1", "id":"10341"}, -{"last_update":"1190824319", "numofapproved":"1", "id":"10382"}, -{"last_update":"1190825791", "numofapproved":"1", "id":"10402"}, -{"last_update":"1190847397", "numofapproved":"1", "id":"10421"}, -{"last_update":"1190876679", "numofapproved":"1", "id":"10441"}, -{"last_update":"1190918894", "numofapproved":"1", "id":"10541"}, -{"last_update":"1190924961", "numofapproved":"1", "id":"10582"}, -{"last_update":"1190991179", "numofapproved":"1", "id":"10723"}, -{"last_update":"1190663960", "numofapproved":"1", "id":"10042"}, -{"last_update":"1191222270", "numofapproved":"1", "id":"10881"}, -{"last_update":"1178869580", "numofapproved":"1", "id":"1355"}, -{"last_update":"1180054057", "numofapproved":"1", "id":"1655"}, -{"last_update":"1180428815", "numofapproved":"1", "id":"1881"}, -{"last_update":"1183369278", "numofapproved":"1", "id":"3901"}, -{"last_update":"1185018445", "numofapproved":"1", "id":"5163"}, -{"last_update":"1185201628", "numofapproved":"1", "id":"5221"}, -{"last_update":"1189345395", "numofapproved":"1", "id":"8741"}, -{"last_update":"1191406141", "numofapproved":"1", "id":"11041"}, -{"last_update":"1191410914", "numofapproved":"1", "id":"11067"}, -{"last_update":"1191558362", "numofapproved":"1", "id":"11461"}, -{"last_update":"1191584539", "numofapproved":"1", "id":"11541"}, -{"last_update":"1191584660", "numofapproved":"1", "id":"11542"}, -{"last_update":"1191599491", "numofapproved":"1", "id":"11661"}, -{"last_update":"1191813292", "numofapproved":"1", "id":"11781"}, -{"last_update":"1191856553", "numofapproved":"1", "id":"11842"}, -{"last_update":"1191861142", "numofapproved":"1", "id":"11862"}, -{"last_update":"1177509523", "numofapproved":"1", "id":"1041"}, -{"last_update":"1190627650", "numofapproved":"1", "id":"9901"}, -{"last_update":"1192034749", "numofapproved":"1", "id":"12141"}, -{"last_update":"1192165574", "numofapproved":"1", "id":"12401"}, -{"last_update":"1192431750", "numofapproved":"1", "id":"12581"}, -{"last_update":"1192536591", "numofapproved":"1", "id":"12721"}, -{"last_update":"1193035428", "numofapproved":"1", "id":"13261"}, -{"last_update":"1193239266", "numofapproved":"1", "id":"13581"}, -{"last_update":"1193314455", "numofapproved":"1", "id":"13841"}, -{"last_update":"1193333733", "numofapproved":"1", "id":"13901"}, -{"last_update":"1193389116", "numofapproved":"1", "id":"14001"}, -{"last_update":"1184970339", "numofapproved":"1", "id":"5121"}, -{"last_update":"1190892760", "numofapproved":"1", "id":"10481"}, -{"last_update":"1192823398", "numofapproved":"1", "id":"13182"}, -{"last_update":"1193911671", "numofapproved":"1", "id":"14541"}, -{"last_update":"1193916761", "numofapproved":"1", "id":"14543"}, -{"last_update":"1194212665", "numofapproved":"1", "id":"14881"}, -{"last_update":"1194248205", "numofapproved":"1", "id":"14921"}, -{"last_update":"1194513600", "numofapproved":"1", "id":"15110"}, -{"last_update":"1194539704", "numofapproved":"1", "id":"15361"}, -{"last_update":"1194569643", "numofapproved":"1", "id":"15112"}, -{"last_update":"1194619794", "numofapproved":"1", "id":"15441"}, -{"last_update":"1194623621", "numofapproved":"1", "id":"15501"}, -{"last_update":"1194624477", "numofapproved":"1", "id":"15521"}, -{"last_update":"1194635685", "numofapproved":"1", "id":"15602"}, -{"last_update":"1179311539", "numofapproved":"1", "id":"1393"}, -{"last_update":"1179672561", "numofapproved":"1", "id":"1521"}, -{"last_update":"1180712413", "numofapproved":"1", "id":"2101"}, -{"last_update":"1181646264", "numofapproved":"1", "id":"2821"}, -{"last_update":"1181807696", "numofapproved":"1", "id":"2921"}, -{"last_update":"1181824523", "numofapproved":"1", "id":"2942"}, -{"last_update":"1181835089", "numofapproved":"1", "id":"2981"}, -{"last_update":"1182000147", "numofapproved":"1", "id":"3141"}, -{"last_update":"1182952133", "numofapproved":"1", "id":"3641"}, -{"last_update":"1188811518", "numofapproved":"1", "id":"8101"}, -{"last_update":"1188975549", "numofapproved":"1", "id":"8321"}, -{"last_update":"1190122760", "numofapproved":"1", "id":"9301"}, -{"last_update":"1190124712", "numofapproved":"1", "id":"9321"}, -{"last_update":"1194526560", "numofapproved":"1", "id":"15281"}, -{"last_update":"1195149112", "numofapproved":"1", "id":"16821"}, -{"last_update":"1179823256", "numofapproved":"1", "id":"1602"}, -{"last_update":"1186332011", "numofapproved":"1", "id":"6165"}, -{"last_update":"1187263451", "numofapproved":"1", "id":"6781"}, -{"last_update":"1190312346", "numofapproved":"1", "id":"9621"}, -{"last_update":"1193178728", "numofapproved":"1", "id":"13525"}, -{"last_update":"1193908534", "numofapproved":"1", "id":"14524"}, -{"last_update":"1194279992", "numofapproved":"1", "id":"15001"}, -{"last_update":"1194947169", "numofapproved":"1", "id":"16104"}, -{"last_update":"1195139978", "numofapproved":"1", "id":"16801"}, -{"last_update":"1195152323", "numofapproved":"1", "id":"16841"}, -{"last_update":"1188086146", "numofapproved":"1", "id":"7428"}, -{"last_update":"1192143475", "numofapproved":"1", "id":"12341"}, -{"last_update":"1192529949", "numofapproved":"1", "id":"12664"}, -{"last_update":"1192721072", "numofapproved":"1", "id":"13041"}, -{"last_update":"1193844156", "numofapproved":"1", "id":"14501"}, -{"last_update":"1177597683", "numofapproved":"1", "id":"1063"}, -{"last_update":"1180975406", "numofapproved":"1", "id":"2184"}, -{"last_update":"1184681435", "numofapproved":"1", "id":"4914"}, -{"last_update":"1187596457", "numofapproved":"1", "id":"6922"}, -{"last_update":"1190661113", "numofapproved":"1", "id":"10003"}, -{"last_update":"1192721357", "numofapproved":"1", "id":"13042"}, -{"last_update":"1193130120", "numofapproved":"1", "id":"13461"}, -{"last_update":"1193388868", "numofapproved":"1", "id":"13953"}, -{"last_update":"1194861534", "numofapproved":"1", "id":"15821"}, -{"last_update":"1182357592", "numofapproved":"1", "id":"3345"}, -{"last_update":"1183722862", "numofapproved":"1", "id":"4262"}, -{"last_update":"1186066354", "numofapproved":"1", "id":"6041"}, -{"last_update":"1192698982", "numofapproved":"1", "id":"12981"}, -{"last_update":"1181237191", "numofapproved":"1", "id":"2561"}, -{"last_update":"1184569090", "numofapproved":"1", "id":"4906"}, -{"last_update":"1185397555", "numofapproved":"1", "id":"5501"}, -{"last_update":"1185541935", "numofapproved":"1", "id":"5681"}, -{"last_update":"1193385832", "numofapproved":"1", "id":"13941"}, -{"last_update":"1185482424", "numofapproved":"1", "id":"5581"}, -{"last_update":"1195508796", "numofapproved":"1", "id":"17401"}, -{"last_update":"1178718386", "numofapproved":"1", "id":"1347"}, -{"last_update":"1178788813", "numofapproved":"1", "id":"1351"}, -{"last_update":"1178877332", "numofapproved":"1", "id":"1358"}, -{"last_update":"1183208679", "numofapproved":"1", "id":"3861"}, -{"last_update":"1187885439", "numofapproved":"1", "id":"7347"}, -{"last_update":"1188985190", "numofapproved":"1", "id":"8341"}, -{"last_update":"1189687132", "numofapproved":"1", "id":"8941"}, -{"last_update":"1189864330", "numofapproved":"1", "id":"9121"}, -{"last_update":"1190990605", "numofapproved":"1", "id":"10709"}, -{"last_update":"1192634449", "numofapproved":"1", "id":"12861"}, -{"last_update":"1194723756", "numofapproved":"1", "id":"15641"}, -{"last_update":"1194792428", "numofapproved":"1", "id":"15682"}, -{"last_update":"1194725734", "numofapproved":"1", "id":"15661"}, -{"last_update":"1194945618", "numofapproved":"1", "id":"16061"}, -{"last_update":"1194946006", "numofapproved":"1", "id":"16081"}, -{"last_update":"1194949774", "numofapproved":"1", "id":"16121"}, -{"last_update":"1194950925", "numofapproved":"1", "id":"16126"}, -{"last_update":"1194979238", "numofapproved":"1", "id":"16282"}, -{"last_update":"1195051013", "numofapproved":"1", "id":"16543"}, -{"last_update":"1195050956", "numofapproved":"1", "id":"16542"}, -{"last_update":"1195047036", "numofapproved":"1", "id":"16501"}, -{"last_update":"1195221919", "numofapproved":"1", "id":"16942"}, -{"last_update":"1178035892", "numofapproved":"1", "id":"1221"}, -{"last_update":"1178570265", "numofapproved":"1", "id":"1302"}, -{"last_update":"1178811921", "numofapproved":"1", "id":"1354"}, -{"last_update":"1182344326", "numofapproved":"1", "id":"3321"}, -{"last_update":"1184999048", "numofapproved":"1", "id":"5141"}, -{"last_update":"1188994511", "numofapproved":"1", "id":"8361"}, -{"last_update":"1189161726", "numofapproved":"1", "id":"8601"}, -{"last_update":"1190500875", "numofapproved":"1", "id":"9803"}, -{"last_update":"1190817424", "numofapproved":"1", "id":"10321"}, -{"last_update":"1191327796", "numofapproved":"1", "id":"11001"}, -{"last_update":"1191410544", "numofapproved":"1", "id":"11062"}, -{"last_update":"1192009739", "numofapproved":"1", "id":"12062"}, -{"last_update":"1193973669", "numofapproved":"1", "id":"14662"}, -{"last_update":"1194035149", "numofapproved":"1", "id":"14783"}, -{"last_update":"1194465519", "numofapproved":"1", "id":"15106"}, -{"last_update":"1194464336", "numofapproved":"1", "id":"15222"}, -{"last_update":"1194861398", "numofapproved":"1", "id":"15802"}, -{"last_update":"1194950791", "numofapproved":"1", "id":"16125"}, -{"last_update":"1195501394", "numofapproved":"1", "id":"17381"}, -{"last_update":"1195546583", "numofapproved":"1", "id":"17461"}, -{"last_update":"1177607652", "numofapproved":"1", "id":"1048"}, -{"last_update":"1182349136", "numofapproved":"1", "id":"3322"}, -{"last_update":"1184217665", "numofapproved":"1", "id":"4681"}, -{"last_update":"1185510733", "numofapproved":"1", "id":"5641"}, -{"last_update":"1187875988", "numofapproved":"1", "id":"7345"}, -{"last_update":"1188384227", "numofapproved":"1", "id":"7701"}, -{"last_update":"1188935650", "numofapproved":"1", "id":"8261"}, -{"last_update":"1188951982", "numofapproved":"1", "id":"8301"}, -{"last_update":"1190391010", "numofapproved":"1", "id":"9701"}, -{"last_update":"1191169581", "numofapproved":"1", "id":"10841"}, -{"last_update":"1194435269", "numofapproved":"1", "id":"15101"}, -{"last_update":"1171800457", "numofapproved":"1", "id":"86"}, -{"last_update":"1171968036", "numofapproved":"1", "id":"116"}, -{"last_update":"1171984640", "numofapproved":"1", "id":"129"}, -{"last_update":"1171987101", "numofapproved":"1", "id":"130"}, -{"last_update":"1172588327", "numofapproved":"1", "id":"213"}, -{"last_update":"1173736730", "numofapproved":"1", "id":"306"}, -{"last_update":"1174735009", "numofapproved":"1", "id":"463"}, -{"last_update":"1172314484", "numofapproved":"1", "id":"192"}, -{"last_update":"1172580739", "numofapproved":"1", "id":"212"}, -{"last_update":"1173889335", "numofapproved":"1", "id":"328"}, -{"last_update":"1171799339", "numofapproved":"1", "id":"79"}, -{"last_update":"1171882669", "numofapproved":"1", "id":"91"}, -{"last_update":"1172561300", "numofapproved":"1", "id":"207"}, -{"last_update":"1172565919", "numofapproved":"1", "id":"209"}, -{"last_update":"1172600401", "numofapproved":"1", "id":"217"}, -{"last_update":"1174040553", "numofapproved":"1", "id":"350"}, -{"last_update":"1174300376", "numofapproved":"1", "id":"365"}, -{"last_update":"1171800419", "numofapproved":"1", "id":"84"}, -{"last_update":"1171800471", "numofapproved":"1", "id":"87"}, -{"last_update":"1171904826", "numofapproved":"1", "id":"102"}, -{"last_update":"1171962248", "numofapproved":"1", "id":"110"}, -{"last_update":"1171968056", "numofapproved":"1", "id":"117"}, -{"last_update":"1172180757", "numofapproved":"1", "id":"174"}, -{"last_update":"1172249286", "numofapproved":"1", "id":"186"}, -{"last_update":"1172331355", "numofapproved":"1", "id":"194"}, -{"last_update":"1172838799", "numofapproved":"1", "id":"235"}, -{"last_update":"1173839361", "numofapproved":"1", "id":"316"}, -{"last_update":"1176141087", "numofapproved":"1", "id":"809"}, -{"last_update":"1176293168", "numofapproved":"1", "id":"827"}, -{"last_update":"1176314927", "numofapproved":"1", "id":"887"}, -{"last_update":"1172147490", "numofapproved":"1", "id":"169"}, -{"last_update":"1172673371", "numofapproved":"1", "id":"225"}, -{"last_update":"1175021309", "numofapproved":"1", "id":"539"}, -{"last_update":"1175719394", "numofapproved":"1", "id":"708"}, -{"last_update":"1175797177", "numofapproved":"1", "id":"741"}, -{"last_update":"1175797204", "numofapproved":"1", "id":"761"}, -{"last_update":"1173888948", "numofapproved":"1", "id":"323"}, -{"last_update":"1171050355", "numofapproved":"1", "id":"1"}, -{"last_update":"1171904868", "numofapproved":"1", "id":"104"}, -{"last_update":"1174301476", "numofapproved":"1", "id":"392"}, -{"last_update":"1174396679", "numofapproved":"1", "id":"401"}, -{"last_update":"1174735025", "numofapproved":"1", "id":"464"}, -{"last_update":"1171894147", "numofapproved":"1", "id":"94"}, -{"last_update":"1172226240", "numofapproved":"1", "id":"181"}, -{"last_update":"1172442130", "numofapproved":"1", "id":"195"}, -{"last_update":"1174300588", "numofapproved":"1", "id":"370"}, -{"last_update":"1174899082", "numofapproved":"1", "id":"490"}, -{"last_update":"1174899309", "numofapproved":"1", "id":"501"}, -{"last_update":"1173724444", "numofapproved":"1", "id":"304"}, -{"last_update":"1176314883", "numofapproved":"1", "id":"886"}, -{"last_update":"1173284377", "numofapproved":"1", "id":"259"}, -{"last_update":"1172244974", "numofapproved":"1", "id":"184"}, -{"last_update":"1173825356", "numofapproved":"1", "id":"315"}, -{"last_update":"1174898980", "numofapproved":"1", "id":"485"}, -{"last_update":"1175713133", "numofapproved":"1", "id":"706"}, -{"last_update":"1175872869", "numofapproved":"1", "id":"784"}, -{"last_update":"1174301161", "numofapproved":"1", "id":"380"}, -{"last_update":"1176710519", "numofapproved":"1", "id":"1002"}, -{"last_update":"1176776871", "numofapproved":"1", "id":"1006"}, -{"last_update":"1176383102", "numofapproved":"1", "id":"901"}, -{"last_update":"1176391153", "numofapproved":"1", "id":"902"}, -{"last_update":"1176562039", "numofapproved":"1", "id":"946"}, -{"last_update":"1175713172", "numofapproved":"1", "id":"668"}, -{"last_update":"1178045208", "numofapproved":"1", "id":"1204"}, -{"last_update":"1178648231", "numofapproved":"1", "id":"1307"}, -{"last_update":"1178876638", "numofapproved":"1", "id":"1362"}, -{"last_update":"1181120419", "numofapproved":"1", "id":"2341"}, -{"last_update":"1181217997", "numofapproved":"1", "id":"2462"}, -{"last_update":"1181292688", "numofapproved":"1", "id":"2622"}, -{"last_update":"1182246090", "numofapproved":"1", "id":"3205"}, -{"last_update":"1182982710", "numofapproved":"1", "id":"3681"}, -{"last_update":"1177496084", "numofapproved":"1", "id":"1021"}, -{"last_update":"1177496190", "numofapproved":"1", "id":"1022"}, -{"last_update":"1178310654", "numofapproved":"1", "id":"1261"}, -{"last_update":"1182861963", "numofapproved":"1", "id":"3582"}, -{"last_update":"1183392466", "numofapproved":"1", "id":"3981"}, -{"last_update":"1183971409", "numofapproved":"1", "id":"4404"}, -{"last_update":"1183984082", "numofapproved":"1", "id":"4421"}, -{"last_update":"1184101764", "numofapproved":"1", "id":"4581"}, -{"last_update":"1185805036", "numofapproved":"1", "id":"5821"}, -{"last_update":"1186071563", "numofapproved":"1", "id":"6061"}, -{"last_update":"1186331614", "numofapproved":"1", "id":"6221"}, -{"last_update":"1187103429", "numofapproved":"1", "id":"6623"}, -{"last_update":"1187359405", "numofapproved":"1", "id":"6901"}, -{"last_update":"1187764462", "numofapproved":"1", "id":"7121"}, -{"last_update":"1187765742", "numofapproved":"1", "id":"7181"}, -{"last_update":"1187821663", "numofapproved":"1", "id":"7281"}, -{"last_update":"1187851593", "numofapproved":"1", "id":"7301"}, -{"last_update":"1188829369", "numofapproved":"1", "id":"8141"}, -{"last_update":"1189006834", "numofapproved":"1", "id":"8401"}, -{"last_update":"1189656411", "numofapproved":"1", "id":"8901"}, -{"last_update":"1181824325", "numofapproved":"1", "id":"2961"}, -{"last_update":"1184699326", "numofapproved":"1", "id":"4922"}, -{"last_update":"1185981618", "numofapproved":"1", "id":"5981"}, -{"last_update":"1186476979", "numofapproved":"1", "id":"6169"}, -{"last_update":"1186501212", "numofapproved":"1", "id":"6301"}, -{"last_update":"1187111728", "numofapproved":"1", "id":"6624"}, -{"last_update":"1187275194", "numofapproved":"1", "id":"6821"}, -{"last_update":"1190232587", "numofapproved":"1", "id":"9501"}, -{"last_update":"1190379779", "numofapproved":"1", "id":"9661"}, -{"last_update":"1190500551", "numofapproved":"1", "id":"9801"}, -{"last_update":"1190555711", "numofapproved":"1", "id":"9861"}, -{"last_update":"1190664200", "numofapproved":"1", "id":"10061"}, -{"last_update":"1190662067", "numofapproved":"1", "id":"10021"}, -{"last_update":"1190887692", "numofapproved":"1", "id":"10461"}, -{"last_update":"1190887880", "numofapproved":"1", "id":"10462"}, -{"last_update":"1190924576", "numofapproved":"1", "id":"10581"}, -{"last_update":"1190990748", "numofapproved":"1", "id":"10713"}, -{"last_update":"1190990297", "numofapproved":"1", "id":"10703"}, -{"last_update":"1182792178", "numofapproved":"1", "id":"3541"}, -{"last_update":"1189505682", "numofapproved":"1", "id":"8781"}, -{"last_update":"1191410630", "numofapproved":"1", "id":"11081"}, -{"last_update":"1191431148", "numofapproved":"1", "id":"11141"}, -{"last_update":"1191446393", "numofapproved":"1", "id":"11181"}, -{"last_update":"1191559326", "numofapproved":"1", "id":"11481"}, -{"last_update":"1191860159", "numofapproved":"1", "id":"11861"}, -{"last_update":"1191933842", "numofapproved":"1", "id":"11901"}, -{"last_update":"1181765760", "numofapproved":"1", "id":"2901"}, -{"last_update":"1187098770", "numofapproved":"1", "id":"6622"}, -{"last_update":"1192155125", "numofapproved":"1", "id":"12382"}, -{"last_update":"1192449036", "numofapproved":"1", "id":"12601"}, -{"last_update":"1192604489", "numofapproved":"1", "id":"12781"}, -{"last_update":"1193265229", "numofapproved":"1", "id":"13681"}, -{"last_update":"1193304550", "numofapproved":"1", "id":"13781"}, -{"last_update":"1193401945", "numofapproved":"1", "id":"14101"}, -{"last_update":"1193305327", "numofapproved":"1", "id":"13801"}, -{"last_update":"1179912412", "numofapproved":"1", "id":"1722"}, -{"last_update":"1188295203", "numofapproved":"1", "id":"7621"}, -{"last_update":"1188580008", "numofapproved":"1", "id":"7881"}, -{"last_update":"1189115708", "numofapproved":"1", "id":"8521"}, -{"last_update":"1193864375", "numofapproved":"1", "id":"14522"}, -{"last_update":"1193973963", "numofapproved":"1", "id":"14666"}, -{"last_update":"1194003054", "numofapproved":"1", "id":"14701"}, -{"last_update":"1194262755", "numofapproved":"1", "id":"14885"}, -{"last_update":"1194262860", "numofapproved":"1", "id":"14886"}, -{"last_update":"1194366475", "numofapproved":"1", "id":"15042"}, -{"last_update":"1194505568", "numofapproved":"1", "id":"15108"}, -{"last_update":"1194507434", "numofapproved":"1", "id":"15109"}, -{"last_update":"1194625505", "numofapproved":"1", "id":"15542"}, -{"last_update":"1194635569", "numofapproved":"1", "id":"15583"}, -{"last_update":"1179319405", "numofapproved":"1", "id":"1394"}, -{"last_update":"1179409867", "numofapproved":"1", "id":"1441"}, -{"last_update":"1179431647", "numofapproved":"1", "id":"1481"}, -{"last_update":"1179842302", "numofapproved":"1", "id":"1667"}, -{"last_update":"1180710254", "numofapproved":"1", "id":"2081"}, -{"last_update":"1181855583", "numofapproved":"1", "id":"3041"}, -{"last_update":"1182100211", "numofapproved":"1", "id":"3182"}, -{"last_update":"1183377220", "numofapproved":"1", "id":"3921"}, -{"last_update":"1184677615", "numofapproved":"1", "id":"4910"}, -{"last_update":"1184679060", "numofapproved":"1", "id":"4911"}, -{"last_update":"1184679348", "numofapproved":"1", "id":"4912"}, -{"last_update":"1184749371", "numofapproved":"1", "id":"4943"}, -{"last_update":"1186734180", "numofapproved":"1", "id":"6381"}, -{"last_update":"1187012463", "numofapproved":"1", "id":"6501"}, -{"last_update":"1187209404", "numofapproved":"1", "id":"6741"}, -{"last_update":"1192687257", "numofapproved":"1", "id":"12941"}, -{"last_update":"1193385868", "numofapproved":"1", "id":"13942"}, -{"last_update":"1193386346", "numofapproved":"1", "id":"13943"}, -{"last_update":"1194937571", "numofapproved":"1", "id":"16042"}, -{"last_update":"1194855975", "numofapproved":"1", "id":"15761"}, -{"last_update":"1194960221", "numofapproved":"1", "id":"16161"}, -{"last_update":"1184058679", "numofapproved":"1", "id":"4541"}, -{"last_update":"1185865315", "numofapproved":"1", "id":"5842"}, -{"last_update":"1187178780", "numofapproved":"1", "id":"6681"}, -{"last_update":"1194884625", "numofapproved":"1", "id":"15921"}, -{"last_update":"1195134032", "numofapproved":"1", "id":"16721"}, -{"last_update":"1195164570", "numofapproved":"1", "id":"16901"}, -{"last_update":"1182336429", "numofapproved":"1", "id":"3301"}, -{"last_update":"1182415670", "numofapproved":"1", "id":"3353"}, -{"last_update":"1184575801", "numofapproved":"1", "id":"4907"}, -{"last_update":"1185483718", "numofapproved":"1", "id":"5601"}, -{"last_update":"1186402874", "numofapproved":"1", "id":"6166"}, -{"last_update":"1186750969", "numofapproved":"1", "id":"6383"}, -{"last_update":"1192725360", "numofapproved":"1", "id":"13061"}, -{"last_update":"1193314911", "numofapproved":"1", "id":"13822"}, -{"last_update":"1183448275", "numofapproved":"1", "id":"4062"}, -{"last_update":"1187321039", "numofapproved":"1", "id":"6861"}, -{"last_update":"1188287578", "numofapproved":"1", "id":"7601"}, -{"last_update":"1194464420", "numofapproved":"1", "id":"15224"}, -{"last_update":"1195139641", "numofapproved":"1", "id":"16781"}, -{"last_update":"1186147124", "numofapproved":"1", "id":"6107"}, -{"last_update":"1188821750", "numofapproved":"1", "id":"8122"}, -{"last_update":"1192531864", "numofapproved":"1", "id":"12665"}, -{"last_update":"1192984220", "numofapproved":"1", "id":"13223"}, -{"last_update":"1195225246", "numofapproved":"1", "id":"16982"}, -{"last_update":"1182410787", "numofapproved":"1", "id":"3351"}, -{"last_update":"1184531419", "numofapproved":"1", "id":"4901"}, -{"last_update":"1188801472", "numofapproved":"1", "id":"8081"}, -{"last_update":"1192524288", "numofapproved":"1", "id":"12661"}, -{"last_update":"1180950691", "numofapproved":"1", "id":"2181"}, -{"last_update":"1184016732", "numofapproved":"1", "id":"4501"}, -{"last_update":"1186074085", "numofapproved":"1", "id":"6081"}, -{"last_update":"1194937650", "numofapproved":"1", "id":"16043"}, -{"last_update":"1182937178", "numofapproved":"1", "id":"3623"}, -{"last_update":"1191419601", "numofapproved":"1", "id":"11101"}, -{"last_update":"1191856562", "numofapproved":"1", "id":"11843"}, -{"last_update":"1192525042", "numofapproved":"1", "id":"12681"}, -{"last_update":"1194625494", "numofapproved":"1", "id":"15541"}, -{"last_update":"1194982850", "numofapproved":"1", "id":"16361"}, -{"last_update":"1194989219", "numofapproved":"1", "id":"16401"}, -{"last_update":"1195066723", "numofapproved":"1", "id":"16641"}, -{"last_update":"1183971226", "numofapproved":"1", "id":"4403"}, -{"last_update":"1185526866", "numofapproved":"1", "id":"5661"}, -{"last_update":"1185741495", "numofapproved":"1", "id":"5741"}, -{"last_update":"1185905429", "numofapproved":"1", "id":"5881"}, -{"last_update":"1186137969", "numofapproved":"1", "id":"6104"}, -{"last_update":"1189267536", "numofapproved":"1", "id":"8701"}, -{"last_update":"1190115042", "numofapproved":"1", "id":"9261"}, -{"last_update":"1190664258", "numofapproved":"1", "id":"10062"}, -{"last_update":"1190774949", "numofapproved":"1", "id":"10201"}, -{"last_update":"1190965042", "numofapproved":"1", "id":"10641"}, -{"last_update":"1191493379", "numofapproved":"1", "id":"11301"}, -{"last_update":"1191578051", "numofapproved":"1", "id":"11501"}, -{"last_update":"1192188840", "numofapproved":"1", "id":"12421"}, -{"last_update":"1194000252", "numofapproved":"1", "id":"14682"}, -{"last_update":"1194622556", "numofapproved":"1", "id":"15462"}, -{"last_update":"1194981068", "numofapproved":"1", "id":"16341"}, -{"last_update":"1185795733", "numofapproved":"1", "id":"5782"}, -{"last_update":"1186646854", "numofapproved":"1", "id":"6341"}, -{"last_update":"1187087291", "numofapproved":"1", "id":"6621"}, -{"last_update":"1187951800", "numofapproved":"1", "id":"7401"}, -{"last_update":"1189170373", "numofapproved":"1", "id":"8642"}, -{"last_update":"1191007934", "numofapproved":"1", "id":"10781"}, -{"last_update":"1190985695", "numofapproved":"1", "id":"10681"}, -{"last_update":"1192009758", "numofapproved":"1", "id":"12063"}, -{"last_update":"1193062543", "numofapproved":"1", "id":"13321"}, -{"last_update":"1194950304", "numofapproved":"1", "id":"16123"}, -{"last_update":"1171882085", "numofapproved":"1", "id":"90"}, -{"last_update":"1171962264", "numofapproved":"1", "id":"111"}, -{"last_update":"1172646556", "numofapproved":"1", "id":"219"}, -{"last_update":"1174040139", "numofapproved":"1", "id":"349"}, -{"last_update":"1174059263", "numofapproved":"1", "id":"355"}, -{"last_update":"1174899063", "numofapproved":"1", "id":"489"}, -{"last_update":"1173797557", "numofapproved":"1", "id":"310"}, -{"last_update":"1174735191", "numofapproved":"1", "id":"468"}, -{"last_update":"1174899259", "numofapproved":"1", "id":"499"}, -{"last_update":"1174899354", "numofapproved":"1", "id":"502"}, -{"last_update":"1175254120", "numofapproved":"1", "id":"562"}, -{"last_update":"1171126391", "numofapproved":"1", "id":"4"}, -{"last_update":"1171800381", "numofapproved":"1", "id":"82"}, -{"last_update":"1171799224", "numofapproved":"1", "id":"75"}, -{"last_update":"1171972550", "numofapproved":"1", "id":"123"}, -{"last_update":"1174301165", "numofapproved":"1", "id":"381"}, -{"last_update":"1171904847", "numofapproved":"1", "id":"103"}, -{"last_update":"1172260956", "numofapproved":"1", "id":"190"}, -{"last_update":"1172803368", "numofapproved":"1", "id":"234"}, -{"last_update":"1173199576", "numofapproved":"1", "id":"250"}, -{"last_update":"1173206201", "numofapproved":"1", "id":"252"}, -{"last_update":"1175258941", "numofapproved":"1", "id":"563"}, -{"last_update":"1176232231", "numofapproved":"1", "id":"825"}, -{"last_update":"1176475088", "numofapproved":"1", "id":"921"}, -{"last_update":"1172082181", "numofapproved":"1", "id":"166"}, -{"last_update":"1172595205", "numofapproved":"1", "id":"216"}, -{"last_update":"1174898892", "numofapproved":"1", "id":"481"}, -{"last_update":"1174899696", "numofapproved":"1", "id":"518"}, -{"last_update":"1174924777", "numofapproved":"1", "id":"525"}, -{"last_update":"1175598588", "numofapproved":"1", "id":"682"}, -{"last_update":"1175602572", "numofapproved":"1", "id":"683"}, -{"last_update":"1175707879", "numofapproved":"1", "id":"666"}, -{"last_update":"1175710528", "numofapproved":"1", "id":"703"}, -{"last_update":"1175715728", "numofapproved":"1", "id":"707"}, -{"last_update":"1176137267", "numofapproved":"1", "id":"806"}, -{"last_update":"1176306491", "numofapproved":"1", "id":"883"}, -{"last_update":"1172069972", "numofapproved":"1", "id":"134"}, -{"last_update":"1173889144", "numofapproved":"1", "id":"324"}, -{"last_update":"1175502804", "numofapproved":"1", "id":"623"}, -{"last_update":"1175772530", "numofapproved":"1", "id":"711"}, -{"last_update":"1176297526", "numofapproved":"1", "id":"861"}, -{"last_update":"1171445818", "numofapproved":"1", "id":"47"}, -{"last_update":"1171884505", "numofapproved":"1", "id":"92"}, -{"last_update":"1172250708", "numofapproved":"1", "id":"187"}, -{"last_update":"1173749631", "numofapproved":"1", "id":"307"}, -{"last_update":"1173889164", "numofapproved":"1", "id":"325"}, -{"last_update":"1174301168", "numofapproved":"1", "id":"382"}, -{"last_update":"1171904807", "numofapproved":"1", "id":"101"}, -{"last_update":"1171970405", "numofapproved":"1", "id":"120"}, -{"last_update":"1172218677", "numofapproved":"1", "id":"179"}, -{"last_update":"1173125028", "numofapproved":"1", "id":"248"}, -{"last_update":"1171978122", "numofapproved":"1", "id":"126"}, -{"last_update":"1172676736", "numofapproved":"1", "id":"226"}, -{"last_update":"1173975473", "numofapproved":"1", "id":"344"}, -{"last_update":"1172072582", "numofapproved":"1", "id":"165"}, -{"last_update":"1173888774", "numofapproved":"1", "id":"322"}, -{"last_update":"1174560347", "numofapproved":"1", "id":"422"}, -{"last_update":"1174899242", "numofapproved":"1", "id":"498"}, -{"last_update":"1174735110", "numofapproved":"1", "id":"466"}, -{"last_update":"1176735630", "numofapproved":"1", "id":"1004"}, -{"last_update":"1175725931", "numofapproved":"1", "id":"670"}, -{"last_update":"1176498072", "numofapproved":"1", "id":"944"}, -{"last_update":"1178264233", "numofapproved":"1", "id":"1241"}, -{"last_update":"1178746727", "numofapproved":"1", "id":"1350"}, -{"last_update":"1178798992", "numofapproved":"1", "id":"1352"}, -{"last_update":"1180011647", "numofapproved":"1", "id":"1649"}, -{"last_update":"1180430823", "numofapproved":"1", "id":"1901"}, -{"last_update":"1180649952", "numofapproved":"1", "id":"2021"}, -{"last_update":"1180966506", "numofapproved":"1", "id":"2183"}, -{"last_update":"1180987142", "numofapproved":"1", "id":"2241"}, -{"last_update":"1181127788", "numofapproved":"1", "id":"2322"}, -{"last_update":"1181217668", "numofapproved":"1", "id":"2461"}, -{"last_update":"1182789542", "numofapproved":"1", "id":"3522"}, -{"last_update":"1182851714", "numofapproved":"1", "id":"3581"}, -{"last_update":"1179268837", "numofapproved":"1", "id":"1407"}, -{"last_update":"1179999486", "numofapproved":"1", "id":"1645"}, -{"last_update":"1180019568", "numofapproved":"1", "id":"1653"}, -{"last_update":"1180082061", "numofapproved":"1", "id":"1821"}, -{"last_update":"1184181871", "numofapproved":"1", "id":"4642"}, -{"last_update":"1184251955", "numofapproved":"1", "id":"4741"}, -{"last_update":"1184346893", "numofapproved":"1", "id":"4841"}, -{"last_update":"1184773981", "numofapproved":"1", "id":"5001"}, -{"last_update":"1185272905", "numofapproved":"1", "id":"5281"}, -{"last_update":"1185484083", "numofapproved":"1", "id":"5622"}, -{"last_update":"1185897961", "numofapproved":"1", "id":"5861"}, -{"last_update":"1186951708", "numofapproved":"1", "id":"6462"}, -{"last_update":"1187596311", "numofapproved":"1", "id":"6941"}, -{"last_update":"1187766852", "numofapproved":"1", "id":"7201"}, -{"last_update":"1188158133", "numofapproved":"1", "id":"7481"}, -{"last_update":"1188233835", "numofapproved":"1", "id":"7501"}, -{"last_update":"1188269273", "numofapproved":"1", "id":"7561"}, -{"last_update":"1177672684", "numofapproved":"1", "id":"1141"}, -{"last_update":"1178042016", "numofapproved":"1", "id":"1222"}, -{"last_update":"1181646022", "numofapproved":"1", "id":"2801"}, -{"last_update":"1181853920", "numofapproved":"1", "id":"3021"}, -{"last_update":"1183715836", "numofapproved":"1", "id":"4241"}, -{"last_update":"1183726859", "numofapproved":"1", "id":"4281"}, -{"last_update":"1189860355", "numofapproved":"1", "id":"9101"}, -{"last_update":"1189871747", "numofapproved":"1", "id":"9141"}, -{"last_update":"1190380660", "numofapproved":"1", "id":"9681"}, -{"last_update":"1190510808", "numofapproved":"1", "id":"9821"}, -{"last_update":"1190542013", "numofapproved":"1", "id":"9843"}, -{"last_update":"1190665412", "numofapproved":"1", "id":"10081"}, -{"last_update":"1190299519", "numofapproved":"1", "id":"9601"}, -{"last_update":"1191410594", "numofapproved":"1", "id":"11063"}, -{"last_update":"1191505786", "numofapproved":"1", "id":"11341"}, -{"last_update":"1191583652", "numofapproved":"1", "id":"11522"}, -{"last_update":"1191599712", "numofapproved":"1", "id":"11681"}, -{"last_update":"1191602931", "numofapproved":"1", "id":"11721"}, -{"last_update":"1191762572", "numofapproved":"1", "id":"11761"}, -{"last_update":"1191856256", "numofapproved":"1", "id":"11841"}, -{"last_update":"1191937041", "numofapproved":"1", "id":"11921"}, -{"last_update":"1179325639", "numofapproved":"1", "id":"1409"}, -{"last_update":"1179912165", "numofapproved":"1", "id":"1721"}, -{"last_update":"1181119430", "numofapproved":"1", "id":"2321"}, -{"last_update":"1184696743", "numofapproved":"1", "id":"4921"}, -{"last_update":"1192154847", "numofapproved":"1", "id":"12361"}, -{"last_update":"1192237071", "numofapproved":"1", "id":"12501"}, -{"last_update":"1178637394", "numofapproved":"1", "id":"1304"}, -{"last_update":"1178716778", "numofapproved":"1", "id":"1344"}, -{"last_update":"1182937057", "numofapproved":"1", "id":"3622"}, -{"last_update":"1183113642", "numofapproved":"1", "id":"3781"}, -{"last_update":"1183995467", "numofapproved":"1", "id":"4461"}, -{"last_update":"1184223331", "numofapproved":"1", "id":"4721"}, -{"last_update":"1190990692", "numofapproved":"1", "id":"10711"}, -{"last_update":"1193269310", "numofapproved":"1", "id":"13761"}, -{"last_update":"1193735756", "numofapproved":"1", "id":"14441"}, -{"last_update":"1194635738", "numofapproved":"1", "id":"15603"}, -{"last_update":"1194901721", "numofapproved":"1", "id":"15961"}, -{"last_update":"1194949951", "numofapproved":"1", "id":"16141"}, -{"last_update":"1194960695", "numofapproved":"1", "id":"16182"}, -{"last_update":"1194973974", "numofapproved":"1", "id":"16221"}, -{"last_update":"1194946810", "numofapproved":"1", "id":"16102"}, -{"last_update":"1194977452", "numofapproved":"1", "id":"16261"}, -{"last_update":"1195040385", "numofapproved":"1", "id":"16461"}, -{"last_update":"1195053483", "numofapproved":"1", "id":"16561"}, -{"last_update":"1195053518", "numofapproved":"1", "id":"16562"}, -{"last_update":"1195218698", "numofapproved":"1", "id":"16921"}, -{"last_update":"1195225049", "numofapproved":"1", "id":"16961"}, -{"last_update":"1195164270", "numofapproved":"1", "id":"16881"}, -{"last_update":"1195080947", "numofapproved":"1", "id":"16681"}, -{"last_update":"1195469884", "numofapproved":"1", "id":"17181"}, -{"last_update":"1185314804", "numofapproved":"1", "id":"5381"}, -{"last_update":"1188401767", "numofapproved":"1", "id":"7721"}, -{"last_update":"1190286841", "numofapproved":"1", "id":"9582"}, -{"last_update":"1190733096", "numofapproved":"1", "id":"10141"}, -{"last_update":"1190847451", "numofapproved":"1", "id":"10422"}, -{"last_update":"1190990526", "numofapproved":"1", "id":"10707"}, -{"last_update":"1192009711", "numofapproved":"1", "id":"12061"}, -{"last_update":"1192155478", "numofapproved":"1", "id":"12362"}, -{"last_update":"1192468382", "numofapproved":"1", "id":"12641"}, -{"last_update":"1193332032", "numofapproved":"1", "id":"13881"}, -{"last_update":"1195497290", "numofapproved":"1", "id":"17321"}, -{"last_update":"1195519935", "numofapproved":"1", "id":"17441"}, -{"last_update":"1195549826", "numofapproved":"1", "id":"17521"}, -{"last_update":"1177668131", "numofapproved":"1", "id":"1101"}, -{"last_update":"1186835348", "numofapproved":"1", "id":"6421"}, -{"last_update":"1191057903", "numofapproved":"1", "id":"10802"}, -{"last_update":"1193973906", "numofapproved":"1", "id":"14665"}, -{"last_update":"1171904780", "numofapproved":"1", "id":"100"}, -{"last_update":"1172677750", "numofapproved":"1", "id":"227"}, -{"last_update":"1172686704", "numofapproved":"1", "id":"229"}, -{"last_update":"1173101684", "numofapproved":"1", "id":"245"}, -{"last_update":"1173466151", "numofapproved":"1", "id":"282"}, -{"last_update":"1174301263", "numofapproved":"1", "id":"386"}, -{"last_update":"1174302366", "numofapproved":"1", "id":"399"}, -{"last_update":"1174501294", "numofapproved":"1", "id":"421"}, -{"last_update":"1174899635", "numofapproved":"1", "id":"515"}, -{"last_update":"1174924556", "numofapproved":"1", "id":"523"}, -{"last_update":"1175141200", "numofapproved":"1", "id":"541"}, -{"last_update":"1171799271", "numofapproved":"1", "id":"76"}, -{"last_update":"1171900163", "numofapproved":"1", "id":"97"}, -{"last_update":"1174301267", "numofapproved":"1", "id":"387"}, -{"last_update":"1174735156", "numofapproved":"1", "id":"467"}, -{"last_update":"1174899569", "numofapproved":"1", "id":"512"}, -{"last_update":"1174926970", "numofapproved":"1", "id":"531"}, -{"last_update":"1175502757", "numofapproved":"1", "id":"602"}, -{"last_update":"1175603425", "numofapproved":"1", "id":"663"}, -{"last_update":"1176194967", "numofapproved":"1", "id":"822"}, -{"last_update":"1171800398", "numofapproved":"1", "id":"83"}, -{"last_update":"1171968376", "numofapproved":"1", "id":"118"}, -{"last_update":"1172070063", "numofapproved":"1", "id":"135"}, -{"last_update":"1173821159", "numofapproved":"1", "id":"314"}, -{"last_update":"1176559052", "numofapproved":"1", "id":"964"}, -{"last_update":"1171299245", "numofapproved":"1", "id":"23"}, -{"last_update":"1171535160", "numofapproved":"1", "id":"57"}, -{"last_update":"1171564542", "numofapproved":"1", "id":"65"}, -{"last_update":"1172646592", "numofapproved":"1", "id":"220"}, -{"last_update":"1174899489", "numofapproved":"1", "id":"507"}, -{"last_update":"1174924890", "numofapproved":"1", "id":"528"}, -{"last_update":"1175687005", "numofapproved":"1", "id":"701"}, -{"last_update":"1176132888", "numofapproved":"1", "id":"805"}, -{"last_update":"1171286610", "numofapproved":"1", "id":"21"}, -{"last_update":"1172184441", "numofapproved":"1", "id":"176"}, -{"last_update":"1172187221", "numofapproved":"1", "id":"178"}, -{"last_update":"1173386668", "numofapproved":"1", "id":"261"}, -{"last_update":"1173809115", "numofapproved":"1", "id":"312"}, -{"last_update":"1175609126", "numofapproved":"1", "id":"685"}, -{"last_update":"1175791369", "numofapproved":"1", "id":"712"}, -{"last_update":"1176480434", "numofapproved":"1", "id":"942"}, -{"last_update":"1171503567", "numofapproved":"1", "id":"56"}, -{"last_update":"1171799204", "numofapproved":"1", "id":"74"}, -{"last_update":"1172236765", "numofapproved":"1", "id":"183"}, -{"last_update":"1175598013", "numofapproved":"1", "id":"681"}, -{"last_update":"1175610956", "numofapproved":"1", "id":"687"}, -{"last_update":"1175725436", "numofapproved":"1", "id":"710"}, -{"last_update":"1171905052", "numofapproved":"1", "id":"105"}, -{"last_update":"1172268920", "numofapproved":"1", "id":"191"}, -{"last_update":"1173264110", "numofapproved":"1", "id":"256"}, -{"last_update":"1173889179", "numofapproved":"1", "id":"326"}, -{"last_update":"1174301066", "numofapproved":"1", "id":"378"}, -{"last_update":"1174300399", "numofapproved":"1", "id":"366"}, -{"last_update":"1174387980", "numofapproved":"1", "id":"400"}, -{"last_update":"1176823766", "numofapproved":"1", "id":"1007"}, -{"last_update":"1171970585", "numofapproved":"1", "id":"122"}, -{"last_update":"1172071500", "numofapproved":"1", "id":"145"}, -{"last_update":"1172580279", "numofapproved":"1", "id":"211"}, -{"last_update":"1172658493", "numofapproved":"1", "id":"221"}, -{"last_update":"1174301611", "numofapproved":"1", "id":"397"}, -{"last_update":"1176900132", "numofapproved":"1", "id":"989"}, -{"last_update":"1171965754", "numofapproved":"1", "id":"114"}, -{"last_update":"1173797482", "numofapproved":"1", "id":"309"}, -{"last_update":"1174300513", "numofapproved":"1", "id":"367"}, -{"last_update":"1174301493", "numofapproved":"1", "id":"395"}, -{"last_update":"1174899124", "numofapproved":"1", "id":"492"}, -{"last_update":"1174899677", "numofapproved":"1", "id":"517"}, -{"last_update":"1174924235", "numofapproved":"1", "id":"522"}, -{"last_update":"1174925568", "numofapproved":"1", "id":"529"}, -{"last_update":"1174933088", "numofapproved":"1", "id":"533"}, -{"last_update":"1174933338", "numofapproved":"1", "id":"538"}, -{"last_update":"1174044629", "numofapproved":"1", "id":"352"}, -{"last_update":"1175713207", "numofapproved":"1", "id":"669"}, -{"last_update":"1178339569", "numofapproved":"1", "id":"1262"}, -{"last_update":"1178611427", "numofapproved":"1", "id":"1303"}, -{"last_update":"1178707269", "numofapproved":"1", "id":"1341"}, -{"last_update":"1179411388", "numofapproved":"1", "id":"1461"}, -{"last_update":"1180000879", "numofapproved":"1", "id":"1648"}, -{"last_update":"1180097993", "numofapproved":"1", "id":"1657"}, -{"last_update":"1180107947", "numofapproved":"1", "id":"1659"}, -{"last_update":"1180515935", "numofapproved":"1", "id":"1922"}, -{"last_update":"1180712418", "numofapproved":"1", "id":"2102"}, -{"last_update":"1180731895", "numofapproved":"1", "id":"2063"}, -{"last_update":"1180731763", "numofapproved":"1", "id":"2143"}, -{"last_update":"1180951519", "numofapproved":"1", "id":"2201"}, -{"last_update":"1180954763", "numofapproved":"1", "id":"2182"}, -{"last_update":"1181134185", "numofapproved":"1", "id":"2361"}, -{"last_update":"1181206368", "numofapproved":"1", "id":"2441"}, -{"last_update":"1181207556", "numofapproved":"1", "id":"2442"}, -{"last_update":"1183065868", "numofapproved":"1", "id":"3741"}, -{"last_update":"1183124436", "numofapproved":"1", "id":"3822"}, -{"last_update":"1183118631", "numofapproved":"1", "id":"3802"}, -{"last_update":"1183515629", "numofapproved":"1", "id":"4144"}, -{"last_update":"1184169495", "numofapproved":"1", "id":"4621"}, -{"last_update":"1184777700", "numofapproved":"1", "id":"5021"}, -{"last_update":"1185371099", "numofapproved":"1", "id":"5441"}, -{"last_update":"1185460060", "numofapproved":"1", "id":"5521"}, -{"last_update":"1185462514", "numofapproved":"1", "id":"5541"}, -{"last_update":"1185573050", "numofapproved":"1", "id":"5721"}, -{"last_update":"1185795586", "numofapproved":"1", "id":"5781"}, -{"last_update":"1185962181", "numofapproved":"1", "id":"5901"}, -{"last_update":"1185987024", "numofapproved":"1", "id":"6001"}, -{"last_update":"1186138150", "numofapproved":"1", "id":"6105"}, -{"last_update":"1186500528", "numofapproved":"1", "id":"6281"}, -{"last_update":"1187765075", "numofapproved":"1", "id":"7141"}, -{"last_update":"1188158263", "numofapproved":"1", "id":"7482"}, -{"last_update":"1189094579", "numofapproved":"1", "id":"8461"}, -{"last_update":"1189327635", "numofapproved":"1", "id":"8721"}, -{"last_update":"1182356521", "numofapproved":"1", "id":"3344"}, -{"last_update":"1185017921", "numofapproved":"1", "id":"5161"}, -{"last_update":"1185271167", "numofapproved":"1", "id":"5261"}, -{"last_update":"1190663796", "numofapproved":"1", "id":"10041"}, -{"last_update":"1190726728", "numofapproved":"1", "id":"10121"}, -{"last_update":"1190801144", "numofapproved":"1", "id":"10241"}, -{"last_update":"1190894441", "numofapproved":"1", "id":"10502"}, -{"last_update":"1190973098", "numofapproved":"1", "id":"10667"}, -{"last_update":"1190925124", "numofapproved":"1", "id":"10584"}, -{"last_update":"1191249884", "numofapproved":"1", "id":"10961"}, -{"last_update":"1187732431", "numofapproved":"1", "id":"7081"}, -{"last_update":"1189259179", "numofapproved":"1", "id":"8681"}, -{"last_update":"1191446517", "numofapproved":"1", "id":"11183"}, -{"last_update":"1191510643", "numofapproved":"1", "id":"11381"}, -{"last_update":"1191529640", "numofapproved":"1", "id":"11421"}, -{"last_update":"1191588726", "numofapproved":"1", "id":"11602"}, -{"last_update":"1191903050", "numofapproved":"1", "id":"11881"}, -{"last_update":"1181218459", "numofapproved":"1", "id":"2464"}, -{"last_update":"1187024536", "numofapproved":"1", "id":"6581"}, -{"last_update":"1192009094", "numofapproved":"1", "id":"12041"}, -{"last_update":"1192064048", "numofapproved":"1", "id":"12183"}, -{"last_update":"1192061973", "numofapproved":"1", "id":"12181"}, -{"last_update":"1193026780", "numofapproved":"1", "id":"13241"}, -{"last_update":"1193416409", "numofapproved":"1", "id":"14161"}, -{"last_update":"1186992495", "numofapproved":"1", "id":"6481"}, -{"last_update":"1191410811", "numofapproved":"1", "id":"11066"}, -{"last_update":"1193440748", "numofapproved":"1", "id":"14241"}, -{"last_update":"1194252005", "numofapproved":"1", "id":"14884"}, -{"last_update":"1194362364", "numofapproved":"1", "id":"14889"}, -{"last_update":"1179240103", "numofapproved":"1", "id":"1389"}, -{"last_update":"1181812262", "numofapproved":"1", "id":"2922"}, -{"last_update":"1182093916", "numofapproved":"1", "id":"3181"}, -{"last_update":"1182767688", "numofapproved":"1", "id":"3501"}, -{"last_update":"1184181747", "numofapproved":"1", "id":"4661"}, -{"last_update":"1186505570", "numofapproved":"1", "id":"6170"}, -{"last_update":"1186751068", "numofapproved":"1", "id":"6384"}, -{"last_update":"1187558925", "numofapproved":"1", "id":"6921"}, -{"last_update":"1188037477", "numofapproved":"1", "id":"7424"}, -{"last_update":"1194937530", "numofapproved":"1", "id":"16041"}, -{"last_update":"1179754250", "numofapproved":"1", "id":"1562"}, -{"last_update":"1183416194", "numofapproved":"1", "id":"4021"}, -{"last_update":"1185835616", "numofapproved":"1", "id":"5841"}, -{"last_update":"1192731190", "numofapproved":"1", "id":"13141"}, -{"last_update":"1193178120", "numofapproved":"1", "id":"13523"}, -{"last_update":"1193844805", "numofapproved":"1", "id":"14503"}, -{"last_update":"1193909242", "numofapproved":"1", "id":"14525"}, -{"last_update":"1195474767", "numofapproved":"1", "id":"17221"}, -{"last_update":"1177690781", "numofapproved":"1", "id":"1142"}, -{"last_update":"1185373614", "numofapproved":"1", "id":"5461"}, -{"last_update":"1192520088", "numofapproved":"1", "id":"12624"}, -{"last_update":"1193194444", "numofapproved":"1", "id":"13527"}, -{"last_update":"1193387684", "numofapproved":"1", "id":"13950"}, -{"last_update":"1193388786", "numofapproved":"1", "id":"13952"}, -{"last_update":"1194616895", "numofapproved":"1", "id":"15401"}, -{"last_update":"1195034817", "numofapproved":"1", "id":"16441"}, -{"last_update":"1183107374", "numofapproved":"1", "id":"3761"}, -{"last_update":"1183515040", "numofapproved":"1", "id":"4121"}, -{"last_update":"1184744160", "numofapproved":"1", "id":"4942"}, -{"last_update":"1192094830", "numofapproved":"1", "id":"12201"}, -{"last_update":"1193314411", "numofapproved":"1", "id":"13821"}, -{"last_update":"1193391901", "numofapproved":"1", "id":"13957"}, -{"last_update":"1193399824", "numofapproved":"1", "id":"14043"}, -{"last_update":"1194450353", "numofapproved":"1", "id":"15181"}, -{"last_update":"1194474719", "numofapproved":"1", "id":"15241"}, -{"last_update":"1194622799", "numofapproved":"1", "id":"15481"}, -{"last_update":"1194880827", "numofapproved":"1", "id":"15901"}, -{"last_update":"1182363929", "numofapproved":"1", "id":"3347"}, -{"last_update":"1182952243", "numofapproved":"1", "id":"3642"}, -{"last_update":"1183386876", "numofapproved":"1", "id":"3962"}, -{"last_update":"1193178314", "numofapproved":"1", "id":"13524"}, -{"last_update":"1195376577", "numofapproved":"1", "id":"17061"}, -{"last_update":"1179832847", "numofapproved":"1", "id":"1621"}, -{"last_update":"1184053269", "numofapproved":"1", "id":"4521"}, -{"last_update":"1185024744", "numofapproved":"1", "id":"5181"}, -{"last_update":"1186130324", "numofapproved":"1", "id":"6101"}, -{"last_update":"1192529640", "numofapproved":"1", "id":"12662"}, -{"last_update":"1193158482", "numofapproved":"1", "id":"13521"}, -{"last_update":"1194247788", "numofapproved":"1", "id":"14883"}, -{"last_update":"1182363717", "numofapproved":"1", "id":"3346"}, -{"last_update":"1193386824", "numofapproved":"1", "id":"13944"}, -{"last_update":"1193844655", "numofapproved":"1", "id":"14502"}, -{"last_update":"1180732326", "numofapproved":"1", "id":"2064"}, -{"last_update":"1182247493", "numofapproved":"1", "id":"3222"}, -{"last_update":"1183515318", "numofapproved":"1", "id":"4143"}, -{"last_update":"1184840285", "numofapproved":"1", "id":"5061"}, -{"last_update":"1188458821", "numofapproved":"1", "id":"7741"}, -{"last_update":"1188919582", "numofapproved":"1", "id":"8241"}, -{"last_update":"1190990231", "numofapproved":"1", "id":"10701"}, -{"last_update":"1190990557", "numofapproved":"1", "id":"10708"}, -{"last_update":"1191583611", "numofapproved":"1", "id":"11521"}, -{"last_update":"1192031263", "numofapproved":"1", "id":"12102"}, -{"last_update":"1192431349", "numofapproved":"1", "id":"12563"}, -{"last_update":"1192608972", "numofapproved":"1", "id":"12801"}, -{"last_update":"1193244196", "numofapproved":"1", "id":"13641"}, -{"last_update":"1193733530", "numofapproved":"1", "id":"14422"}, -{"last_update":"1194988770", "numofapproved":"1", "id":"16381"}, -{"last_update":"1195050890", "numofapproved":"1", "id":"16541"}, -{"last_update":"1195047262", "numofapproved":"1", "id":"16502"}, -{"last_update":"1195221672", "numofapproved":"1", "id":"16941"}, -{"last_update":"1195400016", "numofapproved":"1", "id":"17103"}, -{"last_update":"1178716622", "numofapproved":"1", "id":"1343"}, -{"last_update":"1183563126", "numofapproved":"1", "id":"4181"}, -{"last_update":"1183970953", "numofapproved":"1", "id":"4402"}, -{"last_update":"1190149151", "numofapproved":"1", "id":"9381"}, -{"last_update":"1190628937", "numofapproved":"1", "id":"9921"}, -{"last_update":"1190908511", "numofapproved":"1", "id":"10521"}, -{"last_update":"1191365468", "numofapproved":"1", "id":"11021"}, -{"last_update":"1192431054", "numofapproved":"1", "id":"12561"}, -{"last_update":"1188938163", "numofapproved":"1", "id":"8281"}, -{"last_update":"1192155298", "numofapproved":"1", "id":"12383"}, -{"last_update":"1193223714", "numofapproved":"1", "id":"13561"}, -{"last_update":"1171799359", "numofapproved":"1", "id":"80"}, -{"last_update":"1171962550", "numofapproved":"1", "id":"112"}, -{"last_update":"1171965210", "numofapproved":"1", "id":"113"}, -{"last_update":"1171980888", "numofapproved":"1", "id":"128"}, -{"last_update":"1174299174", "numofapproved":"1", "id":"361"}, -{"last_update":"1174301053", "numofapproved":"1", "id":"376"}, -{"last_update":"1174899661", "numofapproved":"1", "id":"516"}, -{"last_update":"1172646493", "numofapproved":"1", "id":"218"}, -{"last_update":"1174899018", "numofapproved":"1", "id":"487"}, -{"last_update":"1175091201", "numofapproved":"1", "id":"540"}, -{"last_update":"1175267243", "numofapproved":"1", "id":"564"}, -{"last_update":"1176293117", "numofapproved":"1", "id":"826"}, -{"last_update":"1171602873", "numofapproved":"1", "id":"67"}, -{"last_update":"1172568714", "numofapproved":"1", "id":"210"}, -{"last_update":"1174300556", "numofapproved":"1", "id":"369"}, -{"last_update":"1174301614", "numofapproved":"1", "id":"398"}, -{"last_update":"1174429050", "numofapproved":"1", "id":"404"}, -{"last_update":"1175547821", "numofapproved":"1", "id":"641"}, -{"last_update":"1175696551", "numofapproved":"1", "id":"702"}, -{"last_update":"1176223342", "numofapproved":"1", "id":"823"}, -{"last_update":"1176459077", "numofapproved":"1", "id":"905"}, -{"last_update":"1172169117", "numofapproved":"1", "id":"172"}, -{"last_update":"1172259821", "numofapproved":"1", "id":"189"}, -{"last_update":"1172847347", "numofapproved":"1", "id":"237"}, -{"last_update":"1176485274", "numofapproved":"1", "id":"961"}, -{"last_update":"1176739199", "numofapproved":"1", "id":"983"}, -{"last_update":"1171710108", "numofapproved":"1", "id":"72"}, -{"last_update":"1172147854", "numofapproved":"1", "id":"170"}, -{"last_update":"1172178657", "numofapproved":"1", "id":"173"}, -{"last_update":"1174933210", "numofapproved":"1", "id":"535"}, -{"last_update":"1175502973", "numofapproved":"1", "id":"626"}, -{"last_update":"1172071610", "numofapproved":"1", "id":"146"}, -{"last_update":"1172847402", "numofapproved":"1", "id":"240"}, -{"last_update":"1173282970", "numofapproved":"1", "id":"258"}, -{"last_update":"1175502729", "numofapproved":"1", "id":"621"}, -{"last_update":"1173889203", "numofapproved":"1", "id":"327"}, -{"last_update":"1174301604", "numofapproved":"1", "id":"396"}, -{"last_update":"1176738556", "numofapproved":"1", "id":"1005"}, -{"last_update":"1171287066", "numofapproved":"1", "id":"22"}, -{"last_update":"1171388951", "numofapproved":"1", "id":"46"}, -{"last_update":"1171645099", "numofapproved":"1", "id":"70"}, -{"last_update":"1174301489", "numofapproved":"1", "id":"394"}, -{"last_update":"1176109438", "numofapproved":"1", "id":"804"}, -{"last_update":"1173203622", "numofapproved":"1", "id":"251"}, -{"last_update":"1174300337", "numofapproved":"1", "id":"364"}, -{"last_update":"1174898999", "numofapproved":"1", "id":"486"}, -{"last_update":"1174899221", "numofapproved":"1", "id":"497"}, -{"last_update":"1174899505", "numofapproved":"1", "id":"508"}, -{"last_update":"1171905996", "numofapproved":"1", "id":"106"}, -{"last_update":"1172003938", "numofapproved":"1", "id":"131"}, -{"last_update":"1172134183", "numofapproved":"1", "id":"167"}, -{"last_update":"1178550080", "numofapproved":"1", "id":"1301"}, -{"last_update":"1178718229", "numofapproved":"1", "id":"1346"}, -{"last_update":"1178725187", "numofapproved":"1", "id":"1322"}, -{"last_update":"1179302219", "numofapproved":"1", "id":"1392"}, -{"last_update":"1180015260", "numofapproved":"1", "id":"1650"}, -{"last_update":"1180088452", "numofapproved":"1", "id":"1656"}, -{"last_update":"1180719498", "numofapproved":"1", "id":"2121"}, -{"last_update":"1180731930", "numofapproved":"1", "id":"2145"}, -{"last_update":"1180731601", "numofapproved":"1", "id":"2142"}, -{"last_update":"1181034337", "numofapproved":"1", "id":"2281"}, -{"last_update":"1181222113", "numofapproved":"1", "id":"2501"}, -{"last_update":"1181254636", "numofapproved":"1", "id":"2601"}, -{"last_update":"1181578682", "numofapproved":"1", "id":"2762"}, -{"last_update":"1181731051", "numofapproved":"1", "id":"2881"}, -{"last_update":"1177673345", "numofapproved":"1", "id":"1162"}, -{"last_update":"1183741680", "numofapproved":"1", "id":"4301"}, -{"last_update":"1183988623", "numofapproved":"1", "id":"4441"}, -{"last_update":"1184217947", "numofapproved":"1", "id":"4701"}, -{"last_update":"1186260146", "numofapproved":"1", "id":"6181"}, -{"last_update":"1186289860", "numofapproved":"1", "id":"6163"}, -{"last_update":"1186235477", "numofapproved":"1", "id":"6161"}, -{"last_update":"1186508996", "numofapproved":"1", "id":"6171"}, -{"last_update":"1187626570", "numofapproved":"1", "id":"6961"}, -{"last_update":"1187713755", "numofapproved":"1", "id":"7041"}, -{"last_update":"1187769208", "numofapproved":"1", "id":"7222"}, -{"last_update":"1187856827", "numofapproved":"1", "id":"7341"}, -{"last_update":"1188053850", "numofapproved":"1", "id":"7461"}, -{"last_update":"1188264856", "numofapproved":"1", "id":"7541"}, -{"last_update":"1188319841", "numofapproved":"1", "id":"7681"}, -{"last_update":"1188582632", "numofapproved":"1", "id":"7901"}, -{"last_update":"1188734330", "numofapproved":"1", "id":"8001"}, -{"last_update":"1189003562", "numofapproved":"1", "id":"8381"}, -{"last_update":"1179787121", "numofapproved":"1", "id":"1581"}, -{"last_update":"1181998896", "numofapproved":"1", "id":"3121"}, -{"last_update":"1182274782", "numofapproved":"1", "id":"3261"}, -{"last_update":"1186350397", "numofapproved":"1", "id":"6241"}, -{"last_update":"1187354512", "numofapproved":"1", "id":"6881"}, -{"last_update":"1188918086", "numofapproved":"1", "id":"8221"}, -{"last_update":"1190392989", "numofapproved":"1", "id":"9721"}, -{"last_update":"1190925022", "numofapproved":"1", "id":"10583"}, -{"last_update":"1190959571", "numofapproved":"1", "id":"10601"}, -{"last_update":"1190990357", "numofapproved":"1", "id":"10705"}, -{"last_update":"1190990656", "numofapproved":"1", "id":"10710"}, -{"last_update":"1191226364", "numofapproved":"1", "id":"10921"}, -{"last_update":"1180011741", "numofapproved":"1", "id":"1761"}, -{"last_update":"1180533694", "numofapproved":"1", "id":"1961"}, -{"last_update":"1180731839", "numofapproved":"1", "id":"2144"}, -{"last_update":"1181461876", "numofapproved":"1", "id":"2681"}, -{"last_update":"1181855690", "numofapproved":"1", "id":"3061"}, -{"last_update":"1189537687", "numofapproved":"1", "id":"8821"}, -{"last_update":"1189937430", "numofapproved":"1", "id":"9161"}, -{"last_update":"1190803903", "numofapproved":"1", "id":"10261"}, -{"last_update":"1190973051", "numofapproved":"1", "id":"10664"}, -{"last_update":"1191410739", "numofapproved":"1", "id":"11064"}, -{"last_update":"1191426697", "numofapproved":"1", "id":"11121"}, -{"last_update":"1191446459", "numofapproved":"1", "id":"11182"}, -{"last_update":"1191450891", "numofapproved":"1", "id":"11201"}, -{"last_update":"1191550000", "numofapproved":"1", "id":"11441"}, -{"last_update":"1191588714", "numofapproved":"1", "id":"11601"}, -{"last_update":"1191596815", "numofapproved":"1", "id":"11641"}, -{"last_update":"1191647971", "numofapproved":"1", "id":"11741"}, -{"last_update":"1191949660", "numofapproved":"1", "id":"11981"}, -{"last_update":"1180641844", "numofapproved":"1", "id":"2001"}, -{"last_update":"1188319710", "numofapproved":"1", "id":"7661"}, -{"last_update":"1189169640", "numofapproved":"1", "id":"8621"}, -{"last_update":"1192028009", "numofapproved":"1", "id":"12081"}, -{"last_update":"1192116783", "numofapproved":"1", "id":"12261"}, -{"last_update":"1192558715", "numofapproved":"1", "id":"12741"}, -{"last_update":"1192727702", "numofapproved":"1", "id":"13101"}, -{"last_update":"1193035517", "numofapproved":"1", "id":"13262"}, -{"last_update":"1193080239", "numofapproved":"1", "id":"13381"}, -{"last_update":"1193268912", "numofapproved":"1", "id":"13722"}, -{"last_update":"1193386894", "numofapproved":"1", "id":"13946"}, -{"last_update":"1193388087", "numofapproved":"1", "id":"13982"}, -{"last_update":"1179841973", "numofapproved":"1", "id":"1642"}, -{"last_update":"1179842066", "numofapproved":"1", "id":"1662"}, -{"last_update":"1185971695", "numofapproved":"1", "id":"5941"}, -{"last_update":"1186137440", "numofapproved":"1", "id":"6103"}, -{"last_update":"1192823224", "numofapproved":"1", "id":"13181"}, -{"last_update":"1193921116", "numofapproved":"1", "id":"14581"}, -{"last_update":"1193918035", "numofapproved":"1", "id":"14544"}, -{"last_update":"1193973759", "numofapproved":"1", "id":"14663"}, -{"last_update":"1194004166", "numofapproved":"1", "id":"14721"}, -{"last_update":"1194020795", "numofapproved":"1", "id":"14761"}, -{"last_update":"1194021069", "numofapproved":"1", "id":"14781"}, -{"last_update":"1194283444", "numofapproved":"1", "id":"14887"}, -{"last_update":"1194436909", "numofapproved":"1", "id":"15141"}, -{"last_update":"1194538247", "numofapproved":"1", "id":"15341"}, -{"last_update":"1180031440", "numofapproved":"1", "id":"1801"}, -{"last_update":"1181823965", "numofapproved":"1", "id":"2941"}, -{"last_update":"1182846565", "numofapproved":"1", "id":"3561"}, -{"last_update":"1185872587", "numofapproved":"1", "id":"5843"}, -{"last_update":"1186472951", "numofapproved":"1", "id":"6168"}, -{"last_update":"1189937606", "numofapproved":"1", "id":"9181"}, -{"last_update":"1193389026", "numofapproved":"1", "id":"13955"}, -{"last_update":"1192130592", "numofapproved":"1", "id":"12321"}, -{"last_update":"1194387386", "numofapproved":"1", "id":"15061"}, -{"last_update":"1179336536", "numofapproved":"1", "id":"1396"}, -{"last_update":"1182280246", "numofapproved":"1", "id":"3281"}, -{"last_update":"1183394591", "numofapproved":"1", "id":"4001"}, -{"last_update":"1184677502", "numofapproved":"1", "id":"4909"}, -{"last_update":"1186144184", "numofapproved":"1", "id":"6106"}, -{"last_update":"1187191683", "numofapproved":"1", "id":"6701"}, -{"last_update":"1193909594", "numofapproved":"1", "id":"14527"}, -{"last_update":"1194435747", "numofapproved":"1", "id":"15121"}, -{"last_update":"1184252278", "numofapproved":"1", "id":"4761"}, -{"last_update":"1194854996", "numofapproved":"1", "id":"15721"}, -{"last_update":"1194937730", "numofapproved":"1", "id":"16045"}, -{"last_update":"1193076864", "numofapproved":"1", "id":"13361"}, -{"last_update":"1194904087", "numofapproved":"1", "id":"15981"}, -{"last_update":"1181853751", "numofapproved":"1", "id":"3001"}, -{"last_update":"1182075529", "numofapproved":"1", "id":"3161"}, -{"last_update":"1184883226", "numofapproved":"1", "id":"5081"}, -{"last_update":"1186136013", "numofapproved":"1", "id":"6102"}, -{"last_update":"1193147983", "numofapproved":"1", "id":"13481"}, -{"last_update":"1194532658", "numofapproved":"1", "id":"15301"}, -{"last_update":"1194937763", "numofapproved":"1", "id":"16046"}, -{"last_update":"1195225183", "numofapproved":"1", "id":"16981"}, -{"last_update":"1180616624", "numofapproved":"1", "id":"1981"}, -{"last_update":"1183019269", "numofapproved":"1", "id":"3701"}, -{"last_update":"1188656338", "numofapproved":"1", "id":"7941"}, -{"last_update":"1178799062", "numofapproved":"1", "id":"1353"}, -{"last_update":"1178905809", "numofapproved":"1", "id":"1360"}, -{"last_update":"1179311575", "numofapproved":"1", "id":"1408"}, -{"last_update":"1182507595", "numofapproved":"1", "id":"3461"}, -{"last_update":"1184254004", "numofapproved":"1", "id":"4781"}, -{"last_update":"1187938257", "numofapproved":"1", "id":"7381"}, -{"last_update":"1188473327", "numofapproved":"1", "id":"7801"}, -{"last_update":"1189102174", "numofapproved":"1", "id":"8481"}, -{"last_update":"1191419747", "numofapproved":"1", "id":"11102"}, -{"last_update":"1193389169", "numofapproved":"1", "id":"14002"}, -{"last_update":"1194440930", "numofapproved":"1", "id":"15102"}, -{"last_update":"1194855848", "numofapproved":"1", "id":"15741"}, -{"last_update":"1194862162", "numofapproved":"1", "id":"15841"}, -{"last_update":"1194923605", "numofapproved":"1", "id":"16021"}, -{"last_update":"1194950051", "numofapproved":"1", "id":"16142"}, -{"last_update":"1194960554", "numofapproved":"1", "id":"16181"}, -{"last_update":"1194988868", "numofapproved":"1", "id":"16382"}, -{"last_update":"1195058276", "numofapproved":"1", "id":"16601"}, -{"last_update":"1195469960", "numofapproved":"1", "id":"17201"}, -{"last_update":"1178648361", "numofapproved":"1", "id":"1311"}, -{"last_update":"1183970840", "numofapproved":"1", "id":"4401"}, -{"last_update":"1184838534", "numofapproved":"1", "id":"5041"}, -{"last_update":"1190745858", "numofapproved":"1", "id":"10161"}, -{"last_update":"1191587968", "numofapproved":"1", "id":"11581"}, -{"last_update":"1189773687", "numofapproved":"1", "id":"9021"}, -{"last_update":"1192612866", "numofapproved":"1", "id":"12804"}, -{"last_update":"1193746024", "numofapproved":"1", "id":"14461"}, -{"last_update":"1193918117", "numofapproved":"1", "id":"14561"}, -{"last_update":"1194981013", "numofapproved":"1", "id":"16321"}, -{"last_update":"1195546695", "numofapproved":"1", "id":"17481"}, -{"last_update":"1177592107", "numofapproved":"1", "id":"1047"}, -{"last_update":"1183569612", "numofapproved":"1", "id":"4221"}, -{"last_update":"1186770649", "numofapproved":"1", "id":"6401"}, -{"last_update":"1187707518", "numofapproved":"1", "id":"7021"}, -{"last_update":"1187769297", "numofapproved":"1", "id":"7223"}, -{"last_update":"1187798945", "numofapproved":"1", "id":"7241"}, -{"last_update":"1187820883", "numofapproved":"1", "id":"7261"}, -{"last_update":"1190286816", "numofapproved":"1", "id":"9581"}, -{"last_update":"1190541964", "numofapproved":"1", "id":"9842"}, -{"last_update":"1190500569", "numofapproved":"1", "id":"9802"}, -{"last_update":"1190800190", "numofapproved":"1", "id":"10222"}, -{"last_update":"1190965460", "numofapproved":"1", "id":"10642"}, -{"last_update":"1192120899", "numofapproved":"1", "id":"12301"}, -{"last_update":"1193265675", "numofapproved":"1", "id":"13701"}, -{"last_update":"1194508196", "numofapproved":"1", "id":"15261"}, -{"last_update":"1172503197", "numofapproved":"1", "id":"196"}, -{"last_update":"1172847366", "numofapproved":"1", "id":"238"}, -{"last_update":"1173975764", "numofapproved":"1", "id":"347"}, -{"last_update":"1174301010", "numofapproved":"1", "id":"375"}, -{"last_update":"1174899614", "numofapproved":"1", "id":"514"}, -{"last_update":"1174924853", "numofapproved":"1", "id":"527"}, -{"last_update":"1175270318", "numofapproved":"1", "id":"567"}, -{"last_update":"1174933246", "numofapproved":"1", "id":"536"}, -{"last_update":"1176369900", "numofapproved":"1", "id":"889"}, -{"last_update":"1171102836", "numofapproved":"1", "id":"2"}, -{"last_update":"1171970451", "numofapproved":"1", "id":"121"}, -{"last_update":"1174898953", "numofapproved":"1", "id":"484"}, -{"last_update":"1175610845", "numofapproved":"1", "id":"664"}, -{"last_update":"1176313569", "numofapproved":"1", "id":"885"}, -{"last_update":"1171878648", "numofapproved":"1", "id":"89"}, -{"last_update":"1171897268", "numofapproved":"1", "id":"96"}, -{"last_update":"1172326187", "numofapproved":"1", "id":"193"}, -{"last_update":"1176106905", "numofapproved":"1", "id":"802"}, -{"last_update":"1176389540", "numofapproved":"1", "id":"891"}, -{"last_update":"1171318806", "numofapproved":"1", "id":"24"}, -{"last_update":"1171601548", "numofapproved":"1", "id":"66"}, -{"last_update":"1172148331", "numofapproved":"1", "id":"171"}, -{"last_update":"1172686680", "numofapproved":"1", "id":"228"}, -{"last_update":"1173793572", "numofapproved":"1", "id":"308"}, -{"last_update":"1174899594", "numofapproved":"1", "id":"513"}, -{"last_update":"1174898936", "numofapproved":"1", "id":"483"}, -{"last_update":"1175502773", "numofapproved":"1", "id":"622"}, -{"last_update":"1175722537", "numofapproved":"1", "id":"709"}, -{"last_update":"1175764633", "numofapproved":"1", "id":"672"}, -{"last_update":"1175797156", "numofapproved":"1", "id":"721"}, -{"last_update":"1175899070", "numofapproved":"1", "id":"785"}, -{"last_update":"1176106959", "numofapproved":"1", "id":"803"}, -{"last_update":"1176228460", "numofapproved":"1", "id":"824"}, -{"last_update":"1176488163", "numofapproved":"1", "id":"962"}, -{"last_update":"1172068869", "numofapproved":"1", "id":"133"}, -{"last_update":"1172847381", "numofapproved":"1", "id":"239"}, -{"last_update":"1173888657", "numofapproved":"1", "id":"320"}, -{"last_update":"1171449446", "numofapproved":"1", "id":"48"}, -{"last_update":"1175287424", "numofapproved":"1", "id":"581"}, -{"last_update":"1175502897", "numofapproved":"1", "id":"624"}, -{"last_update":"1175503020", "numofapproved":"1", "id":"605"}, -{"last_update":"1172848367", "numofapproved":"1", "id":"243"}, -{"last_update":"1174301060", "numofapproved":"1", "id":"377"}, -{"last_update":"1176824481", "numofapproved":"1", "id":"986"}, -{"last_update":"1171275893", "numofapproved":"1", "id":"6"}, -{"last_update":"1172546216", "numofapproved":"1", "id":"206"}, -{"last_update":"1175502705", "numofapproved":"1", "id":"601"}, -{"last_update":"1173962671", "numofapproved":"1", "id":"341"}, -{"last_update":"1173975403", "numofapproved":"1", "id":"342"}, -{"last_update":"1173816295", "numofapproved":"1", "id":"313"}, -{"last_update":"1174301256", "numofapproved":"1", "id":"384"}, -{"last_update":"1174933293", "numofapproved":"1", "id":"537"}, -{"last_update":"1176899419", "numofapproved":"1", "id":"988"}, -{"last_update":"1173975599", "numofapproved":"1", "id":"345"}, -{"last_update":"1174041960", "numofapproved":"1", "id":"351"}, -{"last_update":"1175759476", "numofapproved":"1", "id":"671"}, -{"last_update":"1178195644", "numofapproved":"1", "id":"1207"}, -{"last_update":"1178725318", "numofapproved":"1", "id":"1348"}, -{"last_update":"1179333492", "numofapproved":"1", "id":"1421"}, -{"last_update":"1179999737", "numofapproved":"1", "id":"1646"}, -{"last_update":"1180710770", "numofapproved":"1", "id":"2062"}, -{"last_update":"1182868347", "numofapproved":"1", "id":"3601"}, -{"last_update":"1182932927", "numofapproved":"1", "id":"3621"}, -{"last_update":"1183115054", "numofapproved":"1", "id":"3784"}, -{"last_update":"1180000741", "numofapproved":"1", "id":"1647"}, -{"last_update":"1181292582", "numofapproved":"1", "id":"2621"}, -{"last_update":"1184181581", "numofapproved":"1", "id":"4641"}, -{"last_update":"1185280501", "numofapproved":"1", "id":"5301"}, -{"last_update":"1185471699", "numofapproved":"1", "id":"5561"}, -{"last_update":"1185542771", "numofapproved":"1", "id":"5701"}, -{"last_update":"1186650650", "numofapproved":"1", "id":"6361"}, -{"last_update":"1186951065", "numofapproved":"1", "id":"6461"}, -{"last_update":"1187769080", "numofapproved":"1", "id":"7221"}, -{"last_update":"1187887905", "numofapproved":"1", "id":"7348"}, -{"last_update":"1188001607", "numofapproved":"1", "id":"7423"}, -{"last_update":"1188463414", "numofapproved":"1", "id":"7762"}, -{"last_update":"1188555813", "numofapproved":"1", "id":"7861"}, -{"last_update":"1188634622", "numofapproved":"1", "id":"7921"}, -{"last_update":"1189543954", "numofapproved":"1", "id":"8841"}, -{"last_update":"1177511009", "numofapproved":"1", "id":"1043"}, -{"last_update":"1181898808", "numofapproved":"1", "id":"3081"}, -{"last_update":"1182247483", "numofapproved":"1", "id":"3221"}, -{"last_update":"1187024005", "numofapproved":"1", "id":"6562"}, -{"last_update":"1189839471", "numofapproved":"1", "id":"9081"}, -{"last_update":"1190018380", "numofapproved":"1", "id":"9241"}, -{"last_update":"1190149586", "numofapproved":"1", "id":"9401"}, -{"last_update":"1190652684", "numofapproved":"1", "id":"9981"}, -{"last_update":"1190662296", "numofapproved":"1", "id":"10022"}, -{"last_update":"1190813509", "numofapproved":"1", "id":"10281"}, -{"last_update":"1190826005", "numofapproved":"1", "id":"10403"}, -{"last_update":"1190991166", "numofapproved":"1", "id":"10722"}, -{"last_update":"1191057700", "numofapproved":"1", "id":"10801"}, -{"last_update":"1191161241", "numofapproved":"1", "id":"10821"}, -{"last_update":"1191227885", "numofapproved":"1", "id":"10941"}, -{"last_update":"1182537005", "numofapproved":"1", "id":"3481"}, -{"last_update":"1185018401", "numofapproved":"1", "id":"5162"}, -{"last_update":"1186752963", "numofapproved":"1", "id":"6386"}, -{"last_update":"1190660077", "numofapproved":"1", "id":"10001"}, -{"last_update":"1191319062", "numofapproved":"1", "id":"10981"}, -{"last_update":"1191446097", "numofapproved":"1", "id":"11161"}, -{"last_update":"1191446587", "numofapproved":"1", "id":"11184"}, -{"last_update":"1191470824", "numofapproved":"1", "id":"11221"}, -{"last_update":"1191526821", "numofapproved":"1", "id":"11401"}, -{"last_update":"1191585471", "numofapproved":"1", "id":"11561"}, -{"last_update":"1191602213", "numofapproved":"1", "id":"11701"}, -{"last_update":"1191845720", "numofapproved":"1", "id":"11821"}, -{"last_update":"1191933874", "numofapproved":"1", "id":"11902"}, -{"last_update":"1191933897", "numofapproved":"1", "id":"11903"}, -{"last_update":"1177673238", "numofapproved":"1", "id":"1161"}, -{"last_update":"1181601542", "numofapproved":"1", "id":"2781"}, -{"last_update":"1182869532", "numofapproved":"1", "id":"3583"}, -{"last_update":"1183315879", "numofapproved":"1", "id":"3881"}, -{"last_update":"1187097870", "numofapproved":"1", "id":"6641"}, -{"last_update":"1190148660", "numofapproved":"1", "id":"9361"}, -{"last_update":"1192248648", "numofapproved":"1", "id":"12521"}, -{"last_update":"1192702958", "numofapproved":"1", "id":"13001"}, -{"last_update":"1193387721", "numofapproved":"1", "id":"13981"}, -{"last_update":"1193391276", "numofapproved":"1", "id":"14021"}, -{"last_update":"1193397051", "numofapproved":"1", "id":"14061"}, -{"last_update":"1193592081", "numofapproved":"1", "id":"14321"}, -{"last_update":"1188474438", "numofapproved":"1", "id":"7821"}, -{"last_update":"1190158372", "numofapproved":"1", "id":"9441"}, -{"last_update":"1193648459", "numofapproved":"1", "id":"14361"}, -{"last_update":"1193999834", "numofapproved":"1", "id":"14681"}, -{"last_update":"1194200119", "numofapproved":"1", "id":"14861"}, -{"last_update":"1194528747", "numofapproved":"1", "id":"15111"}, -{"last_update":"1179150787", "numofapproved":"1", "id":"1384"}, -{"last_update":"1179266496", "numofapproved":"1", "id":"1390"}, -{"last_update":"1179508139", "numofapproved":"1", "id":"1501"}, -{"last_update":"1179842157", "numofapproved":"1", "id":"1664"}, -{"last_update":"1179842347", "numofapproved":"1", "id":"1668"}, -{"last_update":"1181245388", "numofapproved":"1", "id":"2562"}, -{"last_update":"1181311044", "numofapproved":"1", "id":"2661"}, -{"last_update":"1181545818", "numofapproved":"1", "id":"2701"}, -{"last_update":"1181934881", "numofapproved":"1", "id":"3103"}, -{"last_update":"1187020798", "numofapproved":"1", "id":"6541"}, -{"last_update":"1187271377", "numofapproved":"1", "id":"6801"}, -{"last_update":"1196086904", "numofapproved":"1", "id":"17545"}, -{"last_update":"1196266437", "numofapproved":"2", "id":"17662"}, -{"last_update":"1196266638", "numofapproved":"2", "id":"17663"}, -{"last_update":"1197533251", "numofapproved":"1", "id":"17901"}, -{"last_update":"1197533384", "numofapproved":"1", "id":"17923"}, -{"last_update":"1197556776", "numofapproved":"2", "id":"17941"}, -{"last_update":"1200059354", "numofapproved":"1", "id":"17981"}, -{"last_update":"1200576144", "numofapproved":"1", "id":"18001"}, -{"last_update":"1200576230", "numofapproved":"1", "id":"18002"}, -{"last_update":"1200657266", "numofapproved":"1", "id":"18041"}, -{"last_update":"1201510556", "numofapproved":"1", "id":"18061"}, -{"last_update":"1196087136", "numofapproved":"1", "id":"17546"}, -{"last_update":"1196087269", "numofapproved":"1", "id":"17547"}, -{"last_update":"1196087335", "numofapproved":"1", "id":"17548"}, -{"last_update":"1196087379", "numofapproved":"1", "id":"17549"}, -{"last_update":"1196087427", "numofapproved":"1", "id":"17550"}, -{"last_update":"1196096347", "numofapproved":"1", "id":"17581"}, -{"last_update":"1196265997", "numofapproved":"2", "id":"17661"}, -{"last_update":"1196266785", "numofapproved":"1", "id":"17664"}, -{"last_update":"1196270058", "numofapproved":"1", "id":"17701"}, -{"last_update":"1196431875", "numofapproved":"1", "id":"17804"}, -{"last_update":"1197635044", "numofapproved":"1", "id":"17961"}, -{"last_update":"1202720206", "numofapproved":"2", "id":"18084"}, -{"last_update":"1196267153", "numofapproved":"1", "id":"17681"}, -{"last_update":"1196090749", "numofapproved":"1", "id":"17569"}, -{"last_update":"1196162163", "numofapproved":"2", "id":"17641"}, -{"last_update":"1196345846", "numofapproved":"1", "id":"17721"}, -{"last_update":"1196088254", "numofapproved":"1", "id":"17552"}, -{"last_update":"1196088437", "numofapproved":"1", "id":"17564"}, -{"last_update":"1196088477", "numofapproved":"1", "id":"17565"}, -{"last_update":"1196088537", "numofapproved":"1", "id":"17566"}, -{"last_update":"1196088894", "numofapproved":"1", "id":"17567"}, -{"last_update":"1196090414", "numofapproved":"1", "id":"17554"}, -{"last_update":"1196097621", "numofapproved":"1", "id":"17601"}, -{"last_update":"1196097710", "numofapproved":"1", "id":"17602"}, -{"last_update":"1196098047", "numofapproved":"1", "id":"17603"}, -{"last_update":"1196358376", "numofapproved":"2", "id":"17761"}, -{"last_update":"1196358647", "numofapproved":"1", "id":"17762"}, -{"last_update":"1196427604", "numofapproved":"1", "id":"17781"}, -{"last_update":"1196429856", "numofapproved":"1", "id":"17782"}, -{"last_update":"1196431068", "numofapproved":"2", "id":"17783"}, -{"last_update":"1196435953", "numofapproved":"2", "id":"17821"}, -{"last_update":"1204027277", "numofapproved":"1", "id":"18104"}, -{"last_update":"1196090201", "numofapproved":"1", "id":"17553"}, -{"last_update":"1196097095", "numofapproved":"1", "id":"17582"}, -{"last_update":"1196097215", "numofapproved":"1", "id":"17583"}, -{"last_update":"1196430140", "numofapproved":"2", "id":"17803"}, -{"last_update":"1196436411", "numofapproved":"2", "id":"17841"}, -{"last_update":"1196692298", "numofapproved":"1", "id":"17861"}, -{"last_update":"1196692342", "numofapproved":"2", "id":"17862"}, -{"last_update":"1196695231", "numofapproved":"2", "id":"17865"}, -{"last_update":"1197533316", "numofapproved":"1", "id":"17921"}, -{"last_update":"1201512744", "numofapproved":"1", "id":"18082"}, -{"last_update":"1201513438", "numofapproved":"2", "id":"18083"}, -{"last_update":"1196087540", "numofapproved":"1", "id":"17551"}, -{"last_update":"1196156416", "numofapproved":"2", "id":"17621"}, -{"last_update":"1196356717", "numofapproved":"1", "id":"17741"}, -{"last_update":"1196428544", "numofapproved":"2", "id":"17801"}, -{"last_update":"1196429000", "numofapproved":"2", "id":"17802"}, -{"last_update":"1196692578", "numofapproved":"1", "id":"17863"}, -{"last_update":"1196693445", "numofapproved":"2", "id":"17881"}, -{"last_update":"1196693804", "numofapproved":"2", "id":"17864"}, -{"last_update":"1197533347", "numofapproved":"1", "id":"17922"}, -{"last_update":"1200591782", "numofapproved":"1", "id":"18021"}, -{"last_update":"1201510930", "numofapproved":"1", "id":"18081"}, -{"last_update":"1192432005", "numofapproved":"1", "id":"12582"}, -{"last_update":"1192614291", "numofapproved":"1", "id":"12805"}, -{"last_update":"1192624421", "numofapproved":"1", "id":"12806"}, -{"last_update":"1192983623", "numofapproved":"1", "id":"13221"}, -{"last_update":"1193043248", "numofapproved":"1", "id":"13282"}, -{"last_update":"1193223892", "numofapproved":"1", "id":"13562"}, -{"last_update":"1193239943", "numofapproved":"1", "id":"13601"}, -{"last_update":"1193385960", "numofapproved":"1", "id":"13961"}, -{"last_update":"1193386863", "numofapproved":"1", "id":"13945"}, -{"last_update":"1193399770", "numofapproved":"1", "id":"14042"}, -{"last_update":"1193417684", "numofapproved":"1", "id":"14181"}, -{"last_update":"1193458402", "numofapproved":"1", "id":"14261"}, -{"last_update":"1193555071", "numofapproved":"1", "id":"14301"}, -{"last_update":"1185285506", "numofapproved":"1", "id":"5321"}, -{"last_update":"1188250869", "numofapproved":"1", "id":"7521"}, -{"last_update":"1191410480", "numofapproved":"1", "id":"11061"}, -{"last_update":"1193763056", "numofapproved":"1", "id":"14482"}, -{"last_update":"1193913886", "numofapproved":"1", "id":"14542"}, -{"last_update":"1194366001", "numofapproved":"1", "id":"14890"}, -{"last_update":"1194454607", "numofapproved":"1", "id":"15105"}, -{"last_update":"1194255904", "numofapproved":"1", "id":"14941"}, -{"last_update":"1179328986", "numofapproved":"1", "id":"1395"}, -{"last_update":"1180377628", "numofapproved":"1", "id":"1861"}, -{"last_update":"1181250011", "numofapproved":"1", "id":"2563"}, -{"last_update":"1181572386", "numofapproved":"1", "id":"2741"}, -{"last_update":"1183967114", "numofapproved":"1", "id":"4381"}, -{"last_update":"1192512712", "numofapproved":"1", "id":"12623"}, -{"last_update":"1193172621", "numofapproved":"1", "id":"13522"}, -{"last_update":"1193868932", "numofapproved":"1", "id":"14523"}, -{"last_update":"1194980345", "numofapproved":"1", "id":"16301"}, -{"last_update":"1182280312", "numofapproved":"1", "id":"3282"}, -{"last_update":"1184058726", "numofapproved":"1", "id":"4542"}, -{"last_update":"1188829875", "numofapproved":"1", "id":"8161"}, -{"last_update":"1190129857", "numofapproved":"1", "id":"9341"}, -{"last_update":"1190652687", "numofapproved":"1", "id":"9982"}, -{"last_update":"1193389082", "numofapproved":"1", "id":"13956"}, -{"last_update":"1195400591", "numofapproved":"1", "id":"17121"}, -{"last_update":"1184420846", "numofapproved":"1", "id":"4882"}, -{"last_update":"1184532219", "numofapproved":"1", "id":"4903"}, -{"last_update":"1192030476", "numofapproved":"1", "id":"12101"}, -{"last_update":"1192202239", "numofapproved":"1", "id":"12461"}, -{"last_update":"1192688302", "numofapproved":"1", "id":"12961"}, -{"last_update":"1192703266", "numofapproved":"1", "id":"13021"}, -{"last_update":"1193387096", "numofapproved":"1", "id":"13948"}, -{"last_update":"1193387200", "numofapproved":"1", "id":"13949"}, -{"last_update":"1193909837", "numofapproved":"1", "id":"14528"}, -{"last_update":"1181062093", "numofapproved":"1", "id":"2301"}, -{"last_update":"1182364431", "numofapproved":"1", "id":"3348"}, -{"last_update":"1182364589", "numofapproved":"1", "id":"3349"}, -{"last_update":"1184942429", "numofapproved":"1", "id":"5101"}, -{"last_update":"1192682522", "numofapproved":"1", "id":"12901"}, -{"last_update":"1184756287", "numofapproved":"1", "id":"4944"}, -{"last_update":"1190274411", "numofapproved":"1", "id":"9541"}, -{"last_update":"1193324229", "numofapproved":"1", "id":"13861"}, -{"last_update":"1195163999", "numofapproved":"1", "id":"16861"}, -{"last_update":"1181553321", "numofapproved":"1", "id":"2721"}, -{"last_update":"1178869453", "numofapproved":"1", "id":"1361"}, -{"last_update":"1181219788", "numofapproved":"1", "id":"2481"}, -{"last_update":"1178140002", "numofapproved":"1", "id":"1205"}, -{"last_update":"1178716891", "numofapproved":"1", "id":"1345"}, -{"last_update":"1180691957", "numofapproved":"1", "id":"2061"}, -{"last_update":"1182246242", "numofapproved":"1", "id":"3206"}, -{"last_update":"1182882314", "numofapproved":"1", "id":"3585"}, -{"last_update":"1183124192", "numofapproved":"1", "id":"3821"}, -{"last_update":"1183905634", "numofapproved":"1", "id":"4361"}, -{"last_update":"1191225755", "numofapproved":"1", "id":"10901"}, -{"last_update":"1192635977", "numofapproved":"1", "id":"12881"}, -{"last_update":"1193268752", "numofapproved":"1", "id":"13721"}, -{"last_update":"1193242245", "numofapproved":"1", "id":"13621"}, -{"last_update":"1193949751", "numofapproved":"1", "id":"14621"}, -{"last_update":"1194635892", "numofapproved":"1", "id":"15621"}, -{"last_update":"1194726918", "numofapproved":"1", "id":"15664"}, -{"last_update":"1194726371", "numofapproved":"1", "id":"15662"}, -{"last_update":"1194858043", "numofapproved":"1", "id":"15781"}, -{"last_update":"1194946522", "numofapproved":"1", "id":"16101"}, -{"last_update":"1195047359", "numofapproved":"1", "id":"16521"}, -{"last_update":"1195050812", "numofapproved":"1", "id":"16503"}, -{"last_update":"1195058811", "numofapproved":"1", "id":"16621"}, -{"last_update":"1195476161", "numofapproved":"1", "id":"17241"}, -{"last_update":"1178645683", "numofapproved":"1", "id":"1305"}, -{"last_update":"1183118619", "numofapproved":"1", "id":"3801"}, -{"last_update":"1186150376", "numofapproved":"1", "id":"6121"}, -{"last_update":"1189114226", "numofapproved":"1", "id":"8501"}, -{"last_update":"1190973079", "numofapproved":"1", "id":"10666"}, -{"last_update":"1190990329", "numofapproved":"1", "id":"10704"}, -{"last_update":"1191508485", "numofapproved":"1", "id":"11361"}, -{"last_update":"1183054560", "numofapproved":"1", "id":"3721"}, -{"last_update":"1185263889", "numofapproved":"1", "id":"5241"}, -{"last_update":"1187876083", "numofapproved":"1", "id":"7346"}, -{"last_update":"1189550218", "numofapproved":"1", "id":"8861"}, -{"last_update":"1190800088", "numofapproved":"1", "id":"10221"}, -{"last_update":"1193260528", "numofapproved":"1", "id":"13661"}, -{"last_update":"1172509002", "numofapproved":"1", "id":"199"}, -{"last_update":"1172509846", "numofapproved":"1", "id":"200"}, -{"last_update":"1172589855", "numofapproved":"1", "id":"214"}, -{"last_update":"1172847322", "numofapproved":"1", "id":"236"}, -{"last_update":"1172847433", "numofapproved":"1", "id":"242"}, -{"last_update":"1173607050", "numofapproved":"1", "id":"283"}, -{"last_update":"1173703535", "numofapproved":"1", "id":"301"}, -{"last_update":"1173719825", "numofapproved":"1", "id":"302"}, -{"last_update":"1174414845", "numofapproved":"1", "id":"403"}, -{"last_update":"1174650542", "numofapproved":"1", "id":"441"}, -{"last_update":"1171475944", "numofapproved":"1", "id":"52"}, -{"last_update":"1172746278", "numofapproved":"1", "id":"231"}, -{"last_update":"1173251095", "numofapproved":"1", "id":"254"}, -{"last_update":"1173259501", "numofapproved":"1", "id":"255"}, -{"last_update":"1174899183", "numofapproved":"1", "id":"495"}, -{"last_update":"1174924714", "numofapproved":"1", "id":"524"}, -{"last_update":"1171962179", "numofapproved":"1", "id":"108"}, -{"last_update":"1172522401", "numofapproved":"1", "id":"205"}, -{"last_update":"1174299349", "numofapproved":"1", "id":"362"}, -{"last_update":"1174899291", "numofapproved":"1", "id":"500"}, -{"last_update":"1175617661", "numofapproved":"1", "id":"688"}, -{"last_update":"1176302948", "numofapproved":"1", "id":"881"}, -{"last_update":"1176467393", "numofapproved":"1", "id":"893"}, -{"last_update":"1176737599", "numofapproved":"1", "id":"982"}, -{"last_update":"1171465517", "numofapproved":"1", "id":"50"}, -{"last_update":"1171924670", "numofapproved":"1", "id":"107"}, -{"last_update":"1173880505", "numofapproved":"1", "id":"317"}, -{"last_update":"1173889350", "numofapproved":"1", "id":"329"}, -{"last_update":"1173889557", "numofapproved":"1", "id":"332"}, -{"last_update":"1176391285", "numofapproved":"1", "id":"892"}, -{"last_update":"1176673529", "numofapproved":"1", "id":"981"}, -{"last_update":"1171643442", "numofapproved":"1", "id":"69"}, -{"last_update":"1172226841", "numofapproved":"1", "id":"182"}, -{"last_update":"1174899475", "numofapproved":"1", "id":"506"}, -{"last_update":"1174915327", "numofapproved":"1", "id":"521"}, -{"last_update":"1176194461", "numofapproved":"1", "id":"821"}, -{"last_update":"1172013837", "numofapproved":"1", "id":"132"}, -{"last_update":"1172184974", "numofapproved":"1", "id":"177"}, -{"last_update":"1175777908", "numofapproved":"1", "id":"674"}, -{"last_update":"1173460745", "numofapproved":"1", "id":"281"}, -{"last_update":"1174401746", "numofapproved":"1", "id":"402"}, -{"last_update":"1171274691", "numofapproved":"1", "id":"5"}, -{"last_update":"1171799314", "numofapproved":"1", "id":"78"}, -{"last_update":"1171979089", "numofapproved":"1", "id":"127"}, -{"last_update":"1172503571", "numofapproved":"1", "id":"197"}, -{"last_update":"1174301365", "numofapproved":"1", "id":"391"}, -{"last_update":"1174301259", "numofapproved":"1", "id":"385"}, -{"last_update":"1174899163", "numofapproved":"1", "id":"494"}, -{"last_update":"1174933167", "numofapproved":"1", "id":"534"}, -{"last_update":"1176139704", "numofapproved":"1", "id":"808"}, -{"last_update":"1175502855", "numofapproved":"1", "id":"603"}, -{"last_update":"1173721122", "numofapproved":"1", "id":"303"}, -{"last_update":"1173809079", "numofapproved":"1", "id":"311"}, -{"last_update":"1174734352", "numofapproved":"1", "id":"461"}, -{"last_update":"1174898917", "numofapproved":"1", "id":"482"}, -{"last_update":"1174899374", "numofapproved":"1", "id":"503"}, -{"last_update":"1176392495", "numofapproved":"1", "id":"903"}, -{"last_update":"1176829535", "numofapproved":"1", "id":"987"}, -{"last_update":"1173889385", "numofapproved":"1", "id":"330"}, -{"last_update":"1175869070", "numofapproved":"1", "id":"783"}, -{"last_update":"1177510634", "numofapproved":"1", "id":"1042"}, -{"last_update":"1177585810", "numofapproved":"1", "id":"1062"}, -{"last_update":"1178648303", "numofapproved":"1", "id":"1309"}, -{"last_update":"1178883682", "numofapproved":"1", "id":"1363"}, -{"last_update":"1179239792", "numofapproved":"1", "id":"1402"}, -{"last_update":"1179997715", "numofapproved":"1", "id":"1644"}, -{"last_update":"1180031289", "numofapproved":"1", "id":"1654"}, -{"last_update":"1180440758", "numofapproved":"1", "id":"1921"}, -{"last_update":"1180972413", "numofapproved":"1", "id":"2221"}, -{"last_update":"1181032741", "numofapproved":"1", "id":"2261"}, -{"last_update":"1181198104", "numofapproved":"1", "id":"2401"}, -{"last_update":"1181237541", "numofapproved":"1", "id":"2581"}, -{"last_update":"1181293731", "numofapproved":"1", "id":"2641"}, -{"last_update":"1182231158", "numofapproved":"1", "id":"3204"}, -{"last_update":"1177668412", "numofapproved":"1", "id":"1121"}, -{"last_update":"1178713554", "numofapproved":"1", "id":"1342"}, -{"last_update":"1179239886", "numofapproved":"1", "id":"1404"}, -{"last_update":"1184766561", "numofapproved":"1", "id":"4961"}, -{"last_update":"1185293883", "numofapproved":"1", "id":"5341"}, -{"last_update":"1185781181", "numofapproved":"1", "id":"5761"}, -{"last_update":"1185898126", "numofapproved":"1", "id":"5862"}, -{"last_update":"1186290486", "numofapproved":"1", "id":"6164"}, -{"last_update":"1186260193", "numofapproved":"1", "id":"6162"}, -{"last_update":"1186305362", "numofapproved":"1", "id":"6201"}, -{"last_update":"1187024035", "numofapproved":"1", "id":"6563"}, -{"last_update":"1187245873", "numofapproved":"1", "id":"6761"}, -{"last_update":"1187765176", "numofapproved":"1", "id":"7142"}, -{"last_update":"1187872548", "numofapproved":"1", "id":"7343"}, -{"last_update":"1188774634", "numofapproved":"1", "id":"8061"}, -{"last_update":"1188838929", "numofapproved":"1", "id":"8181"}, -{"last_update":"1189608461", "numofapproved":"1", "id":"8881"}, -{"last_update":"1189667694", "numofapproved":"1", "id":"8921"}, -{"last_update":"1179747423", "numofapproved":"1", "id":"1541"}, -{"last_update":"1181142187", "numofapproved":"1", "id":"2381"}, -{"last_update":"1185965227", "numofapproved":"1", "id":"5921"}, -{"last_update":"1190476977", "numofapproved":"1", "id":"9761"}, -{"last_update":"1190648889", "numofapproved":"1", "id":"9961"}, -{"last_update":"1190824195", "numofapproved":"1", "id":"10381"}, -{"last_update":"1190825530", "numofapproved":"1", "id":"10401"}, -{"last_update":"1190894398", "numofapproved":"1", "id":"10501"}, -{"last_update":"1178271031", "numofapproved":"1", "id":"1242"}, -{"last_update":"1178878052", "numofapproved":"1", "id":"1359"}, -{"last_update":"1178967516", "numofapproved":"1", "id":"1364"}, -{"last_update":"1180018261", "numofapproved":"1", "id":"1652"}, -{"last_update":"1180107922", "numofapproved":"1", "id":"1841"}, -{"last_update":"1180514196", "numofapproved":"1", "id":"1941"}, -{"last_update":"1181901023", "numofapproved":"1", "id":"3082"}, -{"last_update":"1182417878", "numofapproved":"1", "id":"3361"}, -{"last_update":"1182785340", "numofapproved":"1", "id":"3521"}, -{"last_update":"1183485766", "numofapproved":"1", "id":"4101"}, -{"last_update":"1189526136", "numofapproved":"1", "id":"8803"}, -{"last_update":"1191446636", "numofapproved":"1", "id":"11185"}, -{"last_update":"1191489743", "numofapproved":"1", "id":"11241"}, -{"last_update":"1191903141", "numofapproved":"1", "id":"11882"}, -{"last_update":"1191940049", "numofapproved":"1", "id":"11941"}, -{"last_update":"1179239857", "numofapproved":"1", "id":"1403"}, -{"last_update":"1185799202", "numofapproved":"1", "id":"5801"}, -{"last_update":"1190924823", "numofapproved":"1", "id":"10562"}, -{"last_update":"1191410783", "numofapproved":"1", "id":"11065"}, -{"last_update":"1192031578", "numofapproved":"1", "id":"12121"}, -{"last_update":"1192431234", "numofapproved":"1", "id":"12562"}, -{"last_update":"1192609228", "numofapproved":"1", "id":"12802"}, -{"last_update":"1192742243", "numofapproved":"1", "id":"13161"}, -{"last_update":"1192942532", "numofapproved":"1", "id":"13201"}, -{"last_update":"1193386303", "numofapproved":"1", "id":"13962"}, -{"last_update":"1193406158", "numofapproved":"1", "id":"14121"}, -{"last_update":"1193418273", "numofapproved":"1", "id":"14201"}, -{"last_update":"1193519213", "numofapproved":"1", "id":"14281"}, -{"last_update":"1193666593", "numofapproved":"1", "id":"14401"}, -{"last_update":"1193733296", "numofapproved":"1", "id":"14421"}, -{"last_update":"1193760981", "numofapproved":"1", "id":"14481"}, -{"last_update":"1182436569", "numofapproved":"1", "id":"3422"}, -{"last_update":"1184012598", "numofapproved":"1", "id":"4481"}, -{"last_update":"1189715279", "numofapproved":"1", "id":"8981"}, -{"last_update":"1192528903", "numofapproved":"1", "id":"12701"}, -{"last_update":"1194246273", "numofapproved":"1", "id":"14901"}, -{"last_update":"1194354217", "numofapproved":"1", "id":"14888"}, -{"last_update":"1194366787", "numofapproved":"1", "id":"14891"}, -{"last_update":"1194445768", "numofapproved":"1", "id":"15104"}, -{"last_update":"1194467580", "numofapproved":"1", "id":"15107"}, -{"last_update":"1194508237", "numofapproved":"1", "id":"15262"}, -{"last_update":"1194635341", "numofapproved":"1", "id":"15581"}, -{"last_update":"1194635508", "numofapproved":"1", "id":"15582"}, -{"last_update":"1179214538", "numofapproved":"1", "id":"1386"}, -{"last_update":"1186433530", "numofapproved":"1", "id":"6167"}, -{"last_update":"1187853435", "numofapproved":"1", "id":"7321"}, -{"last_update":"1187972012", "numofapproved":"1", "id":"7421"}, -{"last_update":"1188895906", "numofapproved":"1", "id":"8201"}, -{"last_update":"1190284020", "numofapproved":"1", "id":"9561"}, -{"last_update":"1190924163", "numofapproved":"1", "id":"10561"}, -{"last_update":"1192529770", "numofapproved":"1", "id":"12663"}, -{"last_update":"1192536538", "numofapproved":"1", "id":"12666"}, -{"last_update":"1193269090", "numofapproved":"1", "id":"13741"}, -{"last_update":"1193428819", "numofapproved":"1", "id":"14221"}, -{"last_update":"1193860091", "numofapproved":"1", "id":"14521"}, -{"last_update":"1193909426", "numofapproved":"1", "id":"14526"}, -{"last_update":"1194533708", "numofapproved":"1", "id":"15321"}, -{"last_update":"1179822723", "numofapproved":"1", "id":"1601"}, -{"last_update":"1179842248", "numofapproved":"1", "id":"1666"}, -{"last_update":"1182412362", "numofapproved":"1", "id":"3352"}, -{"last_update":"1185980065", "numofapproved":"1", "id":"5961"}, -{"last_update":"1186751100", "numofapproved":"1", "id":"6385"}, -{"last_update":"1187202714", "numofapproved":"1", "id":"6721"}, -{"last_update":"1187601864", "numofapproved":"1", "id":"6923"}, -{"last_update":"1191490727", "numofapproved":"1", "id":"11281"}, -{"last_update":"1194449840", "numofapproved":"1", "id":"15161"}, -{"last_update":"1180028166", "numofapproved":"1", "id":"1781"}, -{"last_update":"1185025939", "numofapproved":"1", "id":"5201"}, -{"last_update":"1192454400", "numofapproved":"1", "id":"12621"}, -{"last_update":"1193414234", "numofapproved":"1", "id":"14141"}, -{"last_update":"1194270682", "numofapproved":"1", "id":"14961"}, -{"last_update":"1184061669", "numofapproved":"1", "id":"4561"}, -{"last_update":"1186161284", "numofapproved":"1", "id":"6141"}, -{"last_update":"1187714492", "numofapproved":"1", "id":"7061"}, -{"last_update":"1187893562", "numofapproved":"1", "id":"7361"}, -{"last_update":"1190815311", "numofapproved":"1", "id":"10301"}, -{"last_update":"1193388120", "numofapproved":"1", "id":"13951"}, -{"last_update":"1195239956", "numofapproved":"1", "id":"17041"}, -{"last_update":"1179147467", "numofapproved":"1", "id":"1381"}, -{"last_update":"1182346611", "numofapproved":"1", "id":"3341"}, -{"last_update":"1184267506", "numofapproved":"1", "id":"4802"}, -{"last_update":"1192047087", "numofapproved":"1", "id":"12161"}, -{"last_update":"1192198948", "numofapproved":"1", "id":"12441"}, -{"last_update":"1193208717", "numofapproved":"1", "id":"13528"}, -{"last_update":"1194907182", "numofapproved":"1", "id":"16001"}, -{"last_update":"1179153020", "numofapproved":"1", "id":"1385"}, -{"last_update":"1179835655", "numofapproved":"1", "id":"1641"}, -{"last_update":"1181234739", "numofapproved":"1", "id":"2542"}, -{"last_update":"1182356477", "numofapproved":"1", "id":"3343"}, -{"last_update":"1182418583", "numofapproved":"1", "id":"3381"}, -{"last_update":"1184568502", "numofapproved":"1", "id":"4905"}, -{"last_update":"1189151603", "numofapproved":"1", "id":"8581"}, -{"last_update":"1191595695", "numofapproved":"1", "id":"11621"}, -{"last_update":"1193105000", "numofapproved":"1", "id":"13421"}, -{"last_update":"1195104657", "numofapproved":"1", "id":"16701"}], -"request_timestamp":1206363392.08521, "request_call":"requestDetails", -"instance":"tbedi", "call_time":"0.10059", "request_date":"2008-03-2412:56:32 UTC", "request_url":"http://cmsdoc.cern.ch/cms/test/aprom/phedex/dev/gowri/datasvc/tbedi/requestDetails?format=json"}} -""" - -from jsonParser import jsonObject - -data = jsonObject.parseString(s) - -#~ from pprint import pprint -#~ pprint( data[0].asList() ) -#~ print -#~ print data.dump() -print(data.phedex.call_time) -print(data.phedex.instance) -print(data.phedex.request_call) -print(len(data.phedex.request)) -for req in data.phedex.request[:10]: - #~ print req.dump() - print("-", req.id, req.last_update) diff --git a/examples/removeLineBreaks.py b/examples/removeLineBreaks.py deleted file mode 100644 index ba4b498..0000000 --- a/examples/removeLineBreaks.py +++ /dev/null @@ -1,45 +0,0 @@ -# removeLineBreaks.py -# -# Demonstration of the pyparsing module, converting text files -# with hard line-breaks to text files with line breaks only -# between paragraphs. (Helps when converting downloads from Project -# Gutenberg - http://www.gutenberg.org - to import to word processing apps -# that can reformat paragraphs once hard line-breaks are removed.) -# -# Uses parse actions and transformString to remove unwanted line breaks, -# and to double up line breaks between paragraphs. -# -# Copyright 2006, by Paul McGuire -# -from pyparsing import * - -# define an expression for the body of a line of text - use a parse action to reject any -# empty lines -def mustBeNonBlank(s,l,t): - if not t[0]: - raise ParseException(s,l,"line body can't be empty") -lineBody = SkipTo(lineEnd).setParseAction(mustBeNonBlank) - -# now define a line with a trailing lineEnd, to be replaced with a space character -textLine = lineBody + Suppress(lineEnd).setParseAction(replaceWith(" ")) - -# define a paragraph, with a separating lineEnd, to be replaced with a double newline -para = OneOrMore(textLine) + Suppress(lineEnd).setParseAction(replaceWith("\n\n")) - - -# run a test -test = """ - Now is the - time for - all - good men - to come to - - the aid of their - country. -""" -print(para.transformString(test)) - -# process an entire file -z = para.transformString(file("Successful Methods of Public Speaking.txt").read()) -file("Successful Methods of Public Speaking(2).txt","w").write(z) diff --git a/examples/romanNumerals.py b/examples/romanNumerals.py deleted file mode 100644 index 27361f0..0000000 --- a/examples/romanNumerals.py +++ /dev/null @@ -1,74 +0,0 @@ -# romanNumerals.py -# -# Copyright (c) 2006, Paul McGuire -# - -from pyparsing import * - -def romanNumeralLiteral(numeralString, value): - return Literal(numeralString).setParseAction(replaceWith(value)) - -one = romanNumeralLiteral("I",1) -four = romanNumeralLiteral("IV",4) -five = romanNumeralLiteral("V",5) -nine = romanNumeralLiteral("IX",9) -ten = romanNumeralLiteral("X",10) -forty = romanNumeralLiteral("XL",40) -fifty = romanNumeralLiteral("L",50) -ninety = romanNumeralLiteral("XC",90) -onehundred = romanNumeralLiteral("C",100) -fourhundred = romanNumeralLiteral("CD",400) -fivehundred = romanNumeralLiteral("D",500) -ninehundred = romanNumeralLiteral("CM",900) -onethousand = romanNumeralLiteral("M",1000) - -numeral = ( onethousand | ninehundred | fivehundred | fourhundred | - onehundred | ninety | fifty | forty | ten | nine | five | - four | one ).leaveWhitespace() - -romanNumeral = OneOrMore(numeral).setParseAction( lambda s,l,t : sum(t) ) - -# unit tests -def makeRomanNumeral(n): - def addDigit(n,limit,c,s): - n -= limit - s += c - return n,s - - ret = "" - while n >= 1000: n,ret = addDigit(n,1000,"M",ret) - while n >= 900: n,ret = addDigit(n, 900,"CM",ret) - while n >= 500: n,ret = addDigit(n, 500,"D",ret) - while n >= 400: n,ret = addDigit(n, 400,"CD",ret) - while n >= 100: n,ret = addDigit(n, 100,"C",ret) - while n >= 90: n,ret = addDigit(n, 90,"XC",ret) - while n >= 50: n,ret = addDigit(n, 50,"L",ret) - while n >= 40: n,ret = addDigit(n, 40,"XL",ret) - while n >= 10: n,ret = addDigit(n, 10,"X",ret) - while n >= 9: n,ret = addDigit(n, 9,"IX",ret) - while n >= 5: n,ret = addDigit(n, 5,"V",ret) - while n >= 4: n,ret = addDigit(n, 4,"IV",ret) - while n >= 1: n,ret = addDigit(n, 1,"I",ret) - return ret -tests = " ".join(makeRomanNumeral(i) for i in range(1,5000+1)) - -expected = 1 -for t,s,e in romanNumeral.scanString(tests): - if t[0] != expected: - print("{} {} {}".format("==>", t, tests[s:e])) - expected += 1 - -def test(rn): - print("{} -> {}".format(rn, romanNumeral.parseString(rn)[0])) -test("XVI") -test("XXXIX") -test("XIV") -test("XIX") -test("MCMLXXX") -test("MMVI") - - - - - - diff --git a/examples/scanExamples.py b/examples/scanExamples.py deleted file mode 100644 index 24ae0e7..0000000 --- a/examples/scanExamples.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# scanExamples.py -# -# Illustration of using pyparsing's scanString,transformString, and searchString methods -# -# Copyright (c) 2004, 2006 Paul McGuire -# -from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \ - empty, Suppress, replaceWith - -# simulate some C++ code -testData = """ -#define MAX_LOCS=100 -#define USERNAME = "floyd" -#define PASSWORD = "swordfish" - -a = MAX_LOCS; -CORBA::initORB("xyzzy", USERNAME, PASSWORD ); - -""" - -################# -print("Example of an extractor") -print("----------------------") - -# simple grammar to match #define's -ident = Word(alphas, alphanums+"_") -macroDef = Literal("#define") + ident.setResultsName("name") + "=" + restOfLine.setResultsName("value") -for t,s,e in macroDef.scanString( testData ): - print(t.name,":", t.value) - -# or a quick way to make a dictionary of the names and values -# (return only key and value tokens, and construct dict from key-value pairs) -# - empty ahead of restOfLine advances past leading whitespace, does implicit lstrip during parsing -macroDef = Suppress("#define") + ident + Suppress("=") + empty + restOfLine -macros = dict(list(macroDef.searchString(testData))) -print("macros =", macros) -print() - - -################# -print("Examples of a transformer") -print("----------------------") - -# convert C++ namespaces to mangled C-compatible names -scopedIdent = ident + OneOrMore( Literal("::").suppress() + ident ) -scopedIdent.setParseAction(lambda t: "_".join(t)) - -print("(replace namespace-scoped names with C-compatible names)") -print(scopedIdent.transformString( testData )) - - -# or a crude pre-processor (use parse actions to replace matching text) -def substituteMacro(s,l,t): - if t[0] in macros: - return macros[t[0]] -ident.setParseAction( substituteMacro ) -ident.ignore(macroDef) - -print("(simulate #define pre-processor)") -print(ident.transformString( testData )) - - - -################# -print("Example of a stripper") -print("----------------------") - -from pyparsing import dblQuotedString, LineStart - -# remove all string macro definitions (after extracting to a string resource table?) -stringMacroDef = Literal("#define") + ident + "=" + dblQuotedString + LineStart() -stringMacroDef.setParseAction( replaceWith("") ) - -print(stringMacroDef.transformString( testData )) diff --git a/examples/scanYahoo.py b/examples/scanYahoo.py deleted file mode 100644 index 825c169..0000000 --- a/examples/scanYahoo.py +++ /dev/null @@ -1,14 +0,0 @@ -from pyparsing import makeHTMLTags,SkipTo,htmlComment -import urllib.request, urllib.parse, urllib.error - -serverListPage = urllib.request.urlopen( "http://www.yahoo.com" ) -htmlText = serverListPage.read() -serverListPage.close() - -aStart,aEnd = makeHTMLTags("A") - -link = aStart + SkipTo(aEnd).setResultsName("link") + aEnd -link.ignore(htmlComment) - -for toks,start,end in link.scanString(htmlText): - print(toks.link, "->", toks.startA.href) \ No newline at end of file diff --git a/examples/searchParserAppDemo.py b/examples/searchParserAppDemo.py deleted file mode 100644 index 259e0e3..0000000 --- a/examples/searchParserAppDemo.py +++ /dev/null @@ -1,34 +0,0 @@ -from searchparser import SearchQueryParser - -products = [ "grape juice", "grape jelly", "orange juice", "orange jujubees", - "strawberry jam", "prune juice", "prune butter", "orange marmalade", - "grapefruit juice" ] - -class FruitSearchParser(SearchQueryParser): - def GetWord(self, word): - return set( p for p in products if p.startswith(word + " ") ) - - def GetWordWildcard(self, word): - return set( p for p in products if p.startswith(word[:-1]) ) - - def GetQuotes(self, search_string, tmp_result): - result = Set() - # I have no idea how to use this feature... - return result - - def GetNot(self, not_set): - return set( products ) - not_set - - -parser = FruitSearchParser() - -tests = """\ - grape or orange - grape* - not(grape*) - prune and grape""".splitlines() - -for t in tests: - print(t.strip()) - print(parser.Parse(t)) - print('') \ No newline at end of file diff --git a/examples/searchparser.py b/examples/searchparser.py deleted file mode 100644 index e5b40a7..0000000 --- a/examples/searchparser.py +++ /dev/null @@ -1,292 +0,0 @@ -"""Search query parser - -version 2006-03-09 - -This search query parser uses the excellent Pyparsing module -(http://pyparsing.sourceforge.net/) to parse search queries by users. -It handles: - -* 'and', 'or' and implicit 'and' operators; -* parentheses; -* quoted strings; -* wildcards at the end of a search term (help*); - -Requirements: -* Python -* Pyparsing - -If you run this script, it will perform a number of tests. To use is as a -module, you should use inheritance on the SearchQueryParser class and overwrite -the Get... methods. The ParserTest class gives a very simple example of how this -could work. - -------------------------------------------------------------------------------- -Copyright (c) 2006, Estrate, the Netherlands -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 Estrate 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 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. - -CONTRIBUTORS: -- Steven Mooij -- Rudolph Froger -- Paul McGuire - -TODO: -- add more docs -- ask someone to check my English texts -- add more kinds of wildcards ('*' at the beginning and '*' inside a word)? -""" -from pyparsing import Word, alphanums, Keyword, Group, Combine, Forward, Suppress, Optional, OneOrMore, oneOf - -class SearchQueryParser: - - def __init__(self): - self._methods = { - 'and': self.evaluateAnd, - 'or': self.evaluateOr, - 'not': self.evaluateNot, - 'parenthesis': self.evaluateParenthesis, - 'quotes': self.evaluateQuotes, - 'word': self.evaluateWord, - 'wordwildcard': self.evaluateWordWildcard, - } - self._parser = self.parser() - - def parser(self): - """ - This function returns a parser. - The grammar should be like most full text search engines (Google, Tsearch, Lucene). - - Grammar: - - a query consists of alphanumeric words, with an optional '*' wildcard - at the end of a word - - a sequence of words between quotes is a literal string - - words can be used together by using operators ('and' or 'or') - - words with operators can be grouped with parenthesis - - a word or group of words can be preceded by a 'not' operator - - the 'and' operator precedes an 'or' operator - - if an operator is missing, use an 'and' operator - """ - operatorOr = Forward() - - operatorWord = Group(Combine(Word(alphanums) + Suppress('*'))).setResultsName('wordwildcard') | \ - Group(Word(alphanums)).setResultsName('word') - - operatorQuotesContent = Forward() - operatorQuotesContent << ( - (operatorWord + operatorQuotesContent) | operatorWord - ) - - operatorQuotes = Group( - Suppress('"') + operatorQuotesContent + Suppress('"') - ).setResultsName("quotes") | operatorWord - - operatorParenthesis = Group( - (Suppress("(") + operatorOr + Suppress(")")) - ).setResultsName("parenthesis") | operatorQuotes - - operatorNot = Forward() - operatorNot << (Group( - Suppress(Keyword("not", caseless=True)) + operatorNot - ).setResultsName("not") | operatorParenthesis) - - operatorAnd = Forward() - operatorAnd << (Group( - operatorNot + Suppress(Keyword("and", caseless=True)) + operatorAnd - ).setResultsName("and") | Group( - operatorNot + OneOrMore(~oneOf("and or") + operatorAnd) - ).setResultsName("and") | operatorNot) - - operatorOr << (Group( - operatorAnd + Suppress(Keyword("or", caseless=True)) + operatorOr - ).setResultsName("or") | operatorAnd) - - return operatorOr.parseString - - def evaluateAnd(self, argument): - return self.evaluate(argument[0]).intersection(self.evaluate(argument[1])) - - def evaluateOr(self, argument): - return self.evaluate(argument[0]).union(self.evaluate(argument[1])) - - def evaluateNot(self, argument): - return self.GetNot(self.evaluate(argument[0])) - - def evaluateParenthesis(self, argument): - return self.evaluate(argument[0]) - - def evaluateQuotes(self, argument): - """Evaluate quoted strings - - First is does an 'and' on the indidual search terms, then it asks the - function GetQuoted to only return the subset of ID's that contain the - literal string. - """ - r = set() - search_terms = [] - for item in argument: - search_terms.append(item[0]) - if len(r) == 0: - r = self.evaluate(item) - else: - r = r.intersection(self.evaluate(item)) - return self.GetQuotes(' '.join(search_terms), r) - - def evaluateWord(self, argument): - return self.GetWord(argument[0]) - - def evaluateWordWildcard(self, argument): - return self.GetWordWildcard(argument[0]) - - def evaluate(self, argument): - return self._methods[argument.getName()](argument) - - def Parse(self, query): - #print self._parser(query)[0] - return self.evaluate(self._parser(query)[0]) - - def GetWord(self, word): - return set() - - def GetWordWildcard(self, word): - return set() - - def GetQuotes(self, search_string, tmp_result): - return set() - - def GetNot(self, not_set): - return set().difference(not_set) - - -class ParserTest(SearchQueryParser): - """Tests the parser with some search queries - tests containts a dictionary with tests and expected results. - """ - tests = { - 'help': set([1, 2, 4, 5]), - 'help or hulp': set([1, 2, 3, 4, 5]), - 'help and hulp': set([2]), - 'help hulp': set([2]), - 'help and hulp or hilp': set([2, 3, 4]), - 'help or hulp and hilp': set([1, 2, 3, 4, 5]), - 'help or hulp or hilp or halp': set([1, 2, 3, 4, 5, 6]), - '(help or hulp) and (hilp or halp)': set([3, 4, 5]), - 'help and (hilp or halp)': set([4, 5]), - '(help and (hilp or halp)) or hulp': set([2, 3, 4, 5]), - 'not help': set([3, 6, 7, 8]), - 'not hulp and halp': set([5, 6]), - 'not (help and halp)': set([1, 2, 3, 4, 6, 7, 8]), - '"help me please"': set([2]), - '"help me please" or hulp': set([2, 3]), - '"help me please" or (hulp and halp)': set([2]), - 'help*': set([1, 2, 4, 5, 8]), - 'help or hulp*': set([1, 2, 3, 4, 5]), - 'help* and hulp': set([2]), - 'help and hulp* or hilp': set([2, 3, 4]), - 'help* or hulp or hilp or halp': set([1, 2, 3, 4, 5, 6, 8]), - '(help or hulp*) and (hilp* or halp)': set([3, 4, 5]), - 'help* and (hilp* or halp*)': set([4, 5]), - '(help and (hilp* or halp)) or hulp*': set([2, 3, 4, 5]), - 'not help* and halp': set([6]), - 'not (help* and helpe*)': set([1, 2, 3, 4, 5, 6, 7]), - '"help* me please"': set([2]), - '"help* me* please" or hulp*': set([2, 3]), - '"help me please*" or (hulp and halp)': set([2]), - '"help me please" not (hulp and halp)': set([2]), - '"help me please" hulp': set([2]), - 'help and hilp and not holp': set([4]), - 'help hilp not holp': set([4]), - 'help hilp and not holp': set([4]), - } - - docs = { - 1: 'help', - 2: 'help me please hulp', - 3: 'hulp hilp', - 4: 'help hilp', - 5: 'halp thinks he needs help', - 6: 'he needs halp', - 7: 'nothing', - 8: 'helper', - } - - index = { - 'help': set((1, 2, 4, 5)), - 'me': set((2,)), - 'please': set((2,)), - 'hulp': set((2, 3,)), - 'hilp': set((3, 4,)), - 'halp': set((5, 6,)), - 'thinks': set((5,)), - 'he': set((5, 6,)), - 'needs': set((5, 6,)), - 'nothing': set((7,)), - 'helper': set((8,)), - } - - def GetWord(self, word): - if (word in self.index): - return self.index[word] - else: - return set() - - def GetWordWildcard(self, word): - result = set() - for item in list(self.index.keys()): - if word == item[0:len(word)]: - result = result.union(self.index[item]) - return result - - def GetQuotes(self, search_string, tmp_result): - result = set() - for item in tmp_result: - if self.docs[item].count(search_string): - result.add(item) - return result - - def GetNot(self, not_set): - all = set(list(self.docs.keys())) - return all.difference(not_set) - - def Test(self): - all_ok = True - for item in list(self.tests.keys()): - print(item) - r = self.Parse(item) - e = self.tests[item] - print('Result: %s' % r) - print('Expect: %s' % e) - if e == r: - print('Test OK') - else: - all_ok = False - print('>>>>>>>>>>>>>>>>>>>>>>Test ERROR<<<<<<<<<<<<<<<<<<<<<') - print('') - return all_ok - -if __name__=='__main__': - if ParserTest().Test(): - print('All tests OK') - else: - print('One or more tests FAILED') diff --git a/examples/select_parser.py b/examples/select_parser.py deleted file mode 100644 index f969f02..0000000 --- a/examples/select_parser.py +++ /dev/null @@ -1,126 +0,0 @@ -# select_parser.py -# Copyright 2010, Paul McGuire -# -# a simple SELECT statement parser, taken from SQLite's SELECT statement -# definition at http://www.sqlite.org/lang_select.html -# -from pyparsing import * -ParserElement.enablePackrat() - -LPAR,RPAR,COMMA = map(Suppress,"(),") -select_stmt = Forward().setName("select statement") - -# keywords -(UNION, ALL, AND, INTERSECT, EXCEPT, COLLATE, ASC, DESC, ON, USING, NATURAL, INNER, - CROSS, LEFT, OUTER, JOIN, AS, INDEXED, NOT, SELECT, DISTINCT, FROM, WHERE, GROUP, BY, - HAVING, ORDER, BY, LIMIT, OFFSET, OR) = map(CaselessKeyword, """UNION, ALL, AND, INTERSECT, - EXCEPT, COLLATE, ASC, DESC, ON, USING, NATURAL, INNER, CROSS, LEFT, OUTER, JOIN, AS, INDEXED, NOT, SELECT, - DISTINCT, FROM, WHERE, GROUP, BY, HAVING, ORDER, BY, LIMIT, OFFSET, OR""".replace(",","").split()) -(CAST, ISNULL, NOTNULL, NULL, IS, BETWEEN, ELSE, END, CASE, WHEN, THEN, EXISTS, - COLLATE, IN, LIKE, GLOB, REGEXP, MATCH, ESCAPE, CURRENT_TIME, CURRENT_DATE, - CURRENT_TIMESTAMP) = map(CaselessKeyword, """CAST, ISNULL, NOTNULL, NULL, IS, BETWEEN, ELSE, - END, CASE, WHEN, THEN, EXISTS, COLLATE, IN, LIKE, GLOB, REGEXP, MATCH, ESCAPE, - CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP""".replace(",","").split()) -keyword = MatchFirst((UNION, ALL, INTERSECT, EXCEPT, COLLATE, ASC, DESC, ON, USING, NATURAL, INNER, - CROSS, LEFT, OUTER, JOIN, AS, INDEXED, NOT, SELECT, DISTINCT, FROM, WHERE, GROUP, BY, - HAVING, ORDER, BY, LIMIT, OFFSET, CAST, ISNULL, NOTNULL, NULL, IS, BETWEEN, ELSE, END, CASE, WHEN, THEN, EXISTS, - COLLATE, IN, LIKE, GLOB, REGEXP, MATCH, ESCAPE, CURRENT_TIME, CURRENT_DATE, - CURRENT_TIMESTAMP)) - -identifier = ~keyword + Word(alphas, alphanums+"_") -collation_name = identifier.copy() -column_name = identifier.copy() -column_alias = identifier.copy() -table_name = identifier.copy() -table_alias = identifier.copy() -index_name = identifier.copy() -function_name = identifier.copy() -parameter_name = identifier.copy() -database_name = identifier.copy() - -# expression -expr = Forward().setName("expression") - -integer = Regex(r"[+-]?\d+") -numeric_literal = Regex(r"\d+(\.\d*)?([eE][+-]?\d+)?") -string_literal = QuotedString("'") -blob_literal = Regex(r"[xX]'[0-9A-Fa-f]+'") -literal_value = ( numeric_literal | string_literal | blob_literal | - NULL | CURRENT_TIME | CURRENT_DATE | CURRENT_TIMESTAMP ) -bind_parameter = ( - Word("?",nums) | - Combine(oneOf(": @ $") + parameter_name) - ) -type_name = oneOf("TEXT REAL INTEGER BLOB NULL") - -expr_term = ( - CAST + LPAR + expr + AS + type_name + RPAR | - EXISTS + LPAR + select_stmt + RPAR | - function_name.setName("function_name") + LPAR + Optional("*" | delimitedList(expr)) + RPAR | - literal_value | - bind_parameter | - Combine(identifier+('.'+identifier)*(0,2)).setName("ident") - ) - -UNARY,BINARY,TERNARY=1,2,3 -expr << infixNotation(expr_term, - [ - (oneOf('- + ~') | NOT, UNARY, opAssoc.RIGHT), - (ISNULL | NOTNULL | NOT + NULL, UNARY, opAssoc.LEFT), - ('||', BINARY, opAssoc.LEFT), - (oneOf('* / %'), BINARY, opAssoc.LEFT), - (oneOf('+ -'), BINARY, opAssoc.LEFT), - (oneOf('<< >> & |'), BINARY, opAssoc.LEFT), - (oneOf('< <= > >='), BINARY, opAssoc.LEFT), - (oneOf('= == != <>') | IS | IN | LIKE | GLOB | MATCH | REGEXP, BINARY, opAssoc.LEFT), - ((BETWEEN,AND), TERNARY, opAssoc.LEFT), - (IN + LPAR + Group(select_stmt | delimitedList(expr)) + RPAR, UNARY, opAssoc.LEFT), - (AND, BINARY, opAssoc.LEFT), - (OR, BINARY, opAssoc.LEFT), - ]) - -compound_operator = (UNION + Optional(ALL) | INTERSECT | EXCEPT) - -ordering_term = Group(expr('order_key') + Optional(COLLATE + collation_name('collate')) + Optional(ASC | DESC)('direction')) - -join_constraint = Group(Optional(ON + expr | USING + LPAR + Group(delimitedList(column_name)) + RPAR)) - -join_op = COMMA | Group(Optional(NATURAL) + Optional(INNER | CROSS | LEFT + OUTER | LEFT | OUTER) + JOIN) - -join_source = Forward() -single_source = ( (Group(database_name("database") + "." + table_name("table*")) | table_name("table*")) + - Optional(Optional(AS) + table_alias("table_alias*")) + - Optional(INDEXED + BY + index_name("name") | NOT + INDEXED)("index") | - (LPAR + select_stmt + RPAR + Optional(Optional(AS) + table_alias)) | - (LPAR + join_source + RPAR) ) - -join_source << (Group(single_source + OneOrMore(join_op + single_source + join_constraint)) | - single_source) - -result_column = "*" | table_name + "." + "*" | Group(expr + Optional(Optional(AS) + column_alias)) -select_core = (SELECT + Optional(DISTINCT | ALL) + Group(delimitedList(result_column))("columns") + - Optional(FROM + join_source("from*")) + - Optional(WHERE + expr("where_expr")) + - Optional(GROUP + BY + Group(delimitedList(ordering_term)("group_by_terms")) + - Optional(HAVING + expr("having_expr")))) - -select_stmt << (select_core + ZeroOrMore(compound_operator + select_core) + - Optional(ORDER + BY + Group(delimitedList(ordering_term))("order_by_terms")) + - Optional(LIMIT + (Group(expr + OFFSET + expr) | Group(expr + COMMA + expr) | expr)("limit"))) - -tests = """\ - select * from xyzzy where z > 100 - select * from xyzzy where z > 100 order by zz - select * from xyzzy - select z.* from xyzzy - select a, b from test_table where 1=1 and b='yes' - select a, b from test_table where 1=1 and b in (select bb from foo) - select z.a, b from test_table where 1=1 and b in (select bb from foo) - select z.a, b from test_table where 1=1 and b in (select bb from foo) order by b,c desc,d - select z.a, b from test_table left join test2_table where 1=1 and b in (select bb from foo) - select a, db.table.b as BBB from db.table where 1=1 and BBB='yes' - select a, db.table.b as BBB from test_table,db.table where 1=1 and BBB='yes' - select a, db.table.b as BBB from test_table,db.table where 1=1 and BBB='yes' limit 50 - """ - -select_stmt.runTests(tests) diff --git a/examples/sexpParser.py b/examples/sexpParser.py deleted file mode 100644 index 963d153..0000000 --- a/examples/sexpParser.py +++ /dev/null @@ -1,167 +0,0 @@ -# sexpParser.py -# -# Demonstration of the pyparsing module, implementing a simple S-expression -# parser. -# -# Updates: -# November, 2011 - fixed errors in precedence of alternatives in simpleString; -# fixed exception raised in verifyLen to properly signal the input string -# and exception location so that markInputline works correctly; fixed -# definition of decimal to accept a single '0' and optional leading '-' -# sign; updated tests to improve parser coverage -# -# Copyright 2007-2011, by Paul McGuire -# -""" -BNF reference: http://theory.lcs.mit.edu/~rivest/sexp.txt - - :: | - :: ? ; - :: | | | | - ; - :: "[" "]" ; - :: ":" ; - :: + ; - -- decimal numbers should have no unnecessary leading zeros - -- any string of bytes, of the indicated length - :: + ; - :: ? "|" ( | )* "|" ; - :: "#" ( | )* "#" ; - :: ? - :: "\"" "\"" - :: "(" ( | )* ")" ; - :: * ; - :: | | ; - :: | | ; - :: "a" | ... | "z" ; - :: "A" | ... | "Z" ; - :: "0" | ... | "9" ; - :: | "A" | ... | "F" | "a" | ... | "f" ; - :: "-" | "." | "/" | "_" | ":" | "*" | "+" | "=" ; - :: " " | "\t" | "\r" | "\n" ; - :: | | "+" | "/" | "=" ; - :: "" ; -""" - -from pyparsing import * -from base64 import b64decode -import pprint - -def verifyLen(s,l,t): - t = t[0] - if t.len is not None: - t1len = len(t[1]) - if t1len != t.len: - raise ParseFatalException(s,l,\ - "invalid data of length %d, expected %s" % (t1len, t.len)) - return t[1] - -# define punctuation literals -LPAR, RPAR, LBRK, RBRK, LBRC, RBRC, VBAR = map(Suppress, "()[]{}|") - -decimal = Regex(r'0|[1-9]\d*').setParseAction(lambda t: int(t[0])) -hexadecimal = ("#" + OneOrMore(Word(hexnums)) + "#")\ - .setParseAction(lambda t: int("".join(t[1:-1]),16)) -bytes = Word(printables) -raw = Group(decimal("len") + Suppress(":") + bytes).setParseAction(verifyLen) -token = Word(alphanums + "-./_:*+=") -base64_ = Group(Optional(decimal|hexadecimal,default=None)("len") + VBAR - + OneOrMore(Word( alphanums +"+/=" )).setParseAction(lambda t: b64decode("".join(t))) - + VBAR).setParseAction(verifyLen) - -qString = Group(Optional(decimal,default=None)("len") + - dblQuotedString.setParseAction(removeQuotes)).setParseAction(verifyLen) -simpleString = base64_ | raw | decimal | token | hexadecimal | qString - -# extended definitions -decimal = Regex(r'-?0|[1-9]\d*').setParseAction(lambda t: int(t[0])) -real = Regex(r"[+-]?\d+\.\d*([eE][+-]?\d+)?").setParseAction(lambda tokens: float(tokens[0])) -token = Word(alphanums + "-./_:*+=!<>") - -simpleString = real | base64_ | raw | decimal | token | hexadecimal | qString - -display = LBRK + simpleString + RBRK -string_ = Optional(display) + simpleString - -sexp = Forward() -sexpList = Group(LPAR + ZeroOrMore(sexp) + RPAR) -sexp << ( string_ | sexpList ) - -######### Test data ########### -test00 = """(snicker "abc" (#03# |YWJj|))""" -test01 = """(certificate - (issuer - (name - (public-key - rsa-with-md5 - (e 15 |NFGq/E3wh9f4rJIQVXhS|) - (n |d738/4ghP9rFZ0gAIYZ5q9y6iskDJwASi5rEQpEQq8ZyMZeIZzIAR2I5iGE=|)) - aid-committee)) - (subject - (ref - (public-key - rsa-with-md5 - (e |NFGq/E3wh9f4rJIQVXhS|) - (n |d738/4ghP9rFZ0gAIYZ5q9y6iskDJwASi5rEQpEQq8ZyMZeIZzIAR2I5iGE=|)) - tom - mother)) - (not-before "1997-01-01_09:00:00") - (not-after "1998-01-01_09:00:00") - (tag - (spend (account "12345678") (* numeric range "1" "1000")))) -""" -test02 = """(lambda (x) (* x x))""" -test03 = """(def length - (lambda (x) - (cond - ((not x) 0) - ( t (+ 1 (length (cdr x)))) - ) - ) -) -""" -test04 = """(2:XX "abc" (#03# |YWJj|))""" -test05 = """(if (is (window_name) "XMMS") (set_workspace 2))""" -test06 = """(if - (and - (is (application_name) "Firefox") - (or - (contains (window_name) "Enter name of file to save to") - (contains (window_name) "Save As") - (contains (window_name) "Save Image") - () - ) - ) - (geometry "+140+122") -) -""" -test07 = """(defun factorial (x) - (if (zerop x) 1 - (* x (factorial (- x 1))))) - """ -test51 = """(2:XX "abc" (#30# |YWJj|))""" -test51error = """(3:XX "abc" (#30# |YWJj|))""" - -test52 = """ - (and - (or (> uid 1000) - (!= gid 20) - ) - (> quota 5.0e+03) - ) - """ - -# Run tests -t = None -alltests = [ locals()[t] for t in sorted(locals()) if t.startswith("test") ] - -for t in alltests: - print('-'*50) - print(t) - try: - sexpr = sexp.parseString(t, parseAll=True) - pprint.pprint(sexpr.asList()) - except ParseFatalException as pfe: - print("Error:", pfe.msg) - print(pfe.markInputline('^')) - print() diff --git a/examples/shapes.py b/examples/shapes.py deleted file mode 100644 index b5a0ebd..0000000 --- a/examples/shapes.py +++ /dev/null @@ -1,64 +0,0 @@ -# shapes.py -# -# A sample program showing how parse actions can convert parsed -# strings into a data type or object. -# -# Copyright 2012, Paul T. McGuire -# - -# define class hierarchy of Shape classes, with polymorphic area method -class Shape(object): - def __init__(self, tokens): - self.__dict__.update(tokens.asDict()) - - def area(self): - raise NotImplementedException() - - def __str__(self): - return "<%s>: %s" % (self.__class__.__name__, self.__dict__) - -class Square(Shape): - def area(self): - return self.side**2 - -class Rectangle(Shape): - def area(self): - return self.width * self.height - -class Circle(Shape): - def area(self): - return 3.14159 * self.radius**2 - - -from pyparsing import * - -number = Regex(r'-?\d+(\.\d*)?').setParseAction(lambda t:float(t[0])) - -# Shape expressions: -# square : S -# rectangle: R -# circle : C - -squareDefn = "S" + number('centerx') + number('centery') + number('side') -rectDefn = "R" + number('centerx') + number('centery') + number('width') + number('height') -circleDefn = "C" + number('centerx') + number('centery') + number('diameter') - -squareDefn.setParseAction(Square) -rectDefn.setParseAction(Rectangle) - -def computeRadius(tokens): - tokens['radius'] = tokens.diameter/2.0 -circleDefn.setParseAction(computeRadius, Circle) - -shapeExpr = squareDefn | rectDefn | circleDefn - -tests = """\ -C 0 0 100 -R 10 10 20 50 -S -1 5 10""".splitlines() - -for t in tests: - shape = shapeExpr.parseString(t)[0] - print(shape) - print("Area:", shape.area()) - print() diff --git a/examples/simpleArith.py b/examples/simpleArith.py deleted file mode 100644 index 825956b..0000000 --- a/examples/simpleArith.py +++ /dev/null @@ -1,67 +0,0 @@ -# -# simpleArith.py -# -# Example of defining an arithmetic expression parser using -# the infixNotation helper method in pyparsing. -# -# Copyright 2006, by Paul McGuire -# - -from pyparsing import * - -integer = Word(nums).setParseAction(lambda t:int(t[0])) -variable = Word(alphas,exact=1) -operand = integer | variable - -expop = Literal('^') -signop = oneOf('+ -') -multop = oneOf('* /') -plusop = oneOf('+ -') -factop = Literal('!') - -# To use the infixNotation helper: -# 1. Define the "atom" operand term of the grammar. -# For this simple grammar, the smallest operand is either -# and integer or a variable. This will be the first argument -# to the infixNotation method. -# 2. Define a list of tuples for each level of operator -# precendence. 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 -# - numTerms is the number of terms for this operator (must -# be 1 or 2) -# - rightLeftAssoc is the indicator whether the operator is -# right or left associative, using the pyparsing-defined -# constants opAssoc.RIGHT and opAssoc.LEFT. -# - parseAction is the parse action to be associated with -# expressions matching this operator expression (the -# parse action tuple member may be omitted) -# 3. Call infixNotation passing the operand expression and -# the operator precedence list, and save the returned value -# as the generated pyparsing expression. You can then use -# this expression to parse input strings, or incorporate it -# into a larger, more complex grammar. -# -expr = infixNotation( operand, - [("!", 1, opAssoc.LEFT), - ("^", 2, opAssoc.RIGHT), - (signop, 1, opAssoc.RIGHT), - (multop, 2, opAssoc.LEFT), - (plusop, 2, opAssoc.LEFT),] - ) - -test = ["9 + 2 + 3", - "9 + 2 * 3", - "(9 + 2) * 3", - "(9 + -2) * 3", - "(9 + -2) * 3^2^2", - "(9! + -2) * 3^2^2", - "M*X + B", - "M*(X + B)", - "1+2*-3^4*5+-+-6",] -for t in test: - print(t) - print(expr.parseString(t)) - print('') - diff --git a/examples/simpleBool.py b/examples/simpleBool.py deleted file mode 100644 index 5f355b7..0000000 --- a/examples/simpleBool.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# simpleBool.py -# -# Example of defining a boolean logic parser using -# the operatorGrammar helper method in pyparsing. -# -# In this example, parse actions associated with each -# operator expression will "compile" the expression -# into BoolXXX class instances, which can then -# later be evaluated for their boolean value. -# -# Copyright 2006, by Paul McGuire -# Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility -# -from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas - -# define classes to be built at parse time, as each matching -# expression type is parsed -class BoolOperand(object): - def __init__(self,t): - self.label = t[0] - self.value = eval(t[0]) - def __bool__(self): - return self.value - def __str__(self): - return self.label - __repr__ = __str__ - __nonzero__ = __bool__ - -class BoolBinOp(object): - def __init__(self,t): - self.args = t[0][0::2] - def __str__(self): - sep = " %s " % self.reprsymbol - return "(" + sep.join(map(str,self.args)) + ")" - def __bool__(self): - return self.evalop(bool(a) for a in self.args) - __nonzero__ = __bool__ - __repr__ = __str__ - -class BoolAnd(BoolBinOp): - reprsymbol = '&' - evalop = all - -class BoolOr(BoolBinOp): - reprsymbol = '|' - evalop = any - -class BoolNot(object): - def __init__(self,t): - self.arg = t[0][1] - def __bool__(self): - v = bool(self.arg) - return not v - def __str__(self): - return "~" + str(self.arg) - __repr__ = __str__ - __nonzero__ = __bool__ - -TRUE = Keyword("True") -FALSE = Keyword("False") -boolOperand = TRUE | FALSE | Word(alphas,max=1) -boolOperand.setParseAction(BoolOperand) - -# define expression, based on expression operand and -# list of operations in precedence order -boolExpr = infixNotation( boolOperand, - [ - ("not", 1, opAssoc.RIGHT, BoolNot), - ("and", 2, opAssoc.LEFT, BoolAnd), - ("or", 2, opAssoc.LEFT, BoolOr), - ]) - - -if __name__ == "__main__": - p = True - q = False - r = True - tests = [("p", True), - ("q", False), - ("p and q", False), - ("p and not q", True), - ("not not p", True), - ("not(p and q)", True), - ("q or not p and r", False), - ("q or not p or not r", False), - ("q or not (p and r)", False), - ("p or q or r", True), - ("p or q or r and False", True), - ("(p or q or r) and False", False), - ] - - print("p =", p) - print("q =", q) - print("r =", r) - print() - for t,expected in tests: - res = boolExpr.parseString(t)[0] - success = "PASS" if bool(res) == expected else "FAIL" - print (t,'\n', res, '=', bool(res),'\n', success, '\n') - - diff --git a/examples/simpleSQL.py b/examples/simpleSQL.py deleted file mode 100644 index 6cde6ce..0000000 --- a/examples/simpleSQL.py +++ /dev/null @@ -1,88 +0,0 @@ -# simpleSQL.py -# -# simple demo of using the parsing library to do simple-minded SQL parsing -# could be extended to include where clauses etc. -# -# Copyright (c) 2003,2016, Paul McGuire -# -from pyparsing import Literal, CaselessLiteral, Word, delimitedList, Optional, \ - Combine, Group, alphas, nums, alphanums, ParseException, Forward, oneOf, quotedString, \ - ZeroOrMore, restOfLine, CaselessKeyword, pyparsing_common - -# define SQL tokens -selectStmt = Forward() -SELECT, FROM, WHERE = map(CaselessKeyword, "select from where".split()) - -ident = Word( alphas, alphanums + "_$" ).setName("identifier") -columnName = delimitedList(ident, ".", combine=True).setName("column name") -columnName.addParseAction(pyparsing_common.upcaseTokens) -columnNameList = Group( delimitedList(columnName)) -tableName = delimitedList(ident, ".", combine=True).setName("table name") -tableName.addParseAction(pyparsing_common.upcaseTokens) -tableNameList = Group(delimitedList(tableName)) - -whereExpression = Forward() -and_, or_, in_ = map(CaselessKeyword, "and or in".split()) - -binop = oneOf("= != < > >= <= eq ne lt le gt ge", caseless=True) -realNum = pyparsing_common.real() -intNum = pyparsing_common.signed_integer() - -columnRval = realNum | intNum | quotedString | columnName # need to add support for alg expressions -whereCondition = Group( - ( columnName + binop + columnRval ) | - ( columnName + in_ + "(" + delimitedList( columnRval ) + ")" ) | - ( columnName + in_ + "(" + selectStmt + ")" ) | - ( "(" + whereExpression + ")" ) - ) -whereExpression << whereCondition + ZeroOrMore( ( and_ | or_ ) + whereExpression ) - -# define the grammar -selectStmt <<= (SELECT + ('*' | columnNameList)("columns") + - FROM + tableNameList( "tables" ) + - Optional(Group(WHERE + whereExpression), "")("where")) - -simpleSQL = selectStmt - -# define Oracle comment format, and ignore them -oracleSqlComment = "--" + restOfLine -simpleSQL.ignore( oracleSqlComment ) - -if __name__ == "__main__": - simpleSQL.runTests("""\ - - # multiple tables - SELECT * from XYZZY, ABC - - # dotted table name - select * from SYS.XYZZY - - Select A from Sys.dual - - Select A,B,C from Sys.dual - - Select A, B, C from Sys.dual, Table2 - - # FAIL - invalid SELECT keyword - Xelect A, B, C from Sys.dual - - # FAIL - invalid FROM keyword - Select A, B, C frox Sys.dual - - # FAIL - incomplete statement - Select - - # FAIL - incomplete statement - Select * from - - # FAIL - invalid column - Select &&& frox Sys.dual - - # where clause - Select A from Sys.dual where a in ('RED','GREEN','BLUE') - - # compound where clause - Select A from Sys.dual where a in ('RED','GREEN','BLUE') and b in (10,20,30) - - # where clause with comparison operator - Select A,b from table1,table2 where table1.id eq table2.id""") diff --git a/examples/simpleWiki.py b/examples/simpleWiki.py deleted file mode 100644 index 7a2a0ce..0000000 --- a/examples/simpleWiki.py +++ /dev/null @@ -1,32 +0,0 @@ -from pyparsing import * - -wikiInput = """ -Here is a simple Wiki input: - *This is in italics.* - **This is in bold!** - ***This is in bold italics!*** - Here's a URL to {{Pyparsing's Wiki Page->http://pyparsing.wikispaces.com}} -""" - -def convertToHTML(opening,closing): - def conversionParseAction(s,l,t): - return opening + t[0] + closing - return conversionParseAction - -italicized = QuotedString("*").setParseAction(convertToHTML("","")) -bolded = QuotedString("**").setParseAction(convertToHTML("","")) -boldItalicized = QuotedString("***").setParseAction(convertToHTML("","")) -def convertToHTML_A(s,l,t): - try: - text,url=t[0].split("->") - except ValueError: - raise ParseFatalException(s,l,"invalid URL link reference: " + t[0]) - return '%s' % (url,text) - -urlRef = QuotedString("{{",endQuoteChar="}}").setParseAction(convertToHTML_A) - -wikiMarkup = urlRef | boldItalicized | bolded | italicized - -print(wikiInput) -print() -print(wikiMarkup.transformString(wikiInput)) diff --git a/examples/sparser.py b/examples/sparser.py deleted file mode 100644 index 7c416da..0000000 --- a/examples/sparser.py +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/env python - -""" -NAME: - sparser.py - -SYNOPSIS: - sparser.py [options] filename - -DESCRIPTION: - The sparser.py script is a Specified PARSER. It is unique (as far as I can - tell) because it doesn't care about the delimiter(s). The user specifies - what is expected, and the order, for each line of text. All of the heavy - lifting is handled by pyparsing (http://pyparsing.sf.net). - -OPTIONS: - -h,--help this message - -v,--version version - -d,--debug turn on debug messages - -EXAMPLES: - 1. As standalone - sparser.py myfile - 2. As library - import sparser - ... - -#Copyright (C) 2006 Tim Cera timcera@earthlink.net -# -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 2 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 675 Mass Ave, Cambridge, MA 02139, USA. -""" - -#===imports====================== -import sys -import os -import getopt -import re -import gzip - -from pyparsing import * - - -#===globals====================== -modname = "sparser" -__version__ = "0.1" - - -#--option args-- -debug_p = 0 -#opt_b=None #string arg, default is undefined - - -#---positional args, default is empty--- -pargs = [] - - -#---other--- - - -#===utilities==================== -def msg(txt): - """Send message to stdout.""" - sys.stdout.write(txt) - sys.stdout.flush() - -def debug(ftn, txt): - """Used for debugging.""" - if debug_p: - sys.stdout.write("%s.%s:%s\n" % (modname, ftn, txt)) - sys.stdout.flush() - -def fatal(ftn, txt): - """If can't continue.""" - msg = "%s.%s:FATAL:%s\n" % (modname, ftn, txt) - raise SystemExit(msg) - -def usage(): - """Prints the docstring.""" - print(__doc__) - - - -#==================================== -class ToInteger(TokenConverter): - """Converter to make token into an integer.""" - def postParse( self, instring, loc, tokenlist ): - return int(tokenlist[0]) - -class ToFloat(TokenConverter): - """Converter to make token into a float.""" - def postParse( self, instring, loc, tokenlist ): - return float(tokenlist[0]) - -class ParseFileLineByLine: - """ - Bring data from text files into a program, optionally parsing each line - according to specifications in a parse definition file. - - ParseFileLineByLine instances can be used like normal file objects (i.e. by - calling readline(), readlines(), and write()), but can also be used as - sequences of lines in for-loops. - - ParseFileLineByLine objects also handle compression transparently. i.e. it - is possible to read lines from a compressed text file as if it were not - compressed. Compression is deduced from the file name suffixes '.Z' - (compress/uncompress), '.gz' (gzip/gunzip), and '.bz2' (bzip2). - - The parse definition file name is developed based on the input file name. - If the input file name is 'basename.ext', then the definition file is - 'basename_def.ext'. If a definition file specific to the input file is not - found, then the program searches for the file 'sparse.def' which would be - the definition file for all files in that directory without a file specific - definition file. - - Finally, ParseFileLineByLine objects accept file names that start with '~' - or '~user' to indicate a home directory, as well as URLs (for reading - only). - - Constructor: - ParseFileLineByLine(|filename|, |mode|='"r"'), where |filename| is the name - of the file (or a URL) and |mode| is one of '"r"' (read), '"w"' (write) or - '"a"' (append, not supported for .Z files). - """ - - def __init__(self, filename, mode = 'r'): - """Opens input file, and if available the definition file. If the - definition file is available __init__ will then create some pyparsing - helper variables. """ - if mode not in ['r', 'w', 'a']: - raise IOError(0, 'Illegal mode: ' + repr(mode)) - - if string.find(filename, ':/') > 1: # URL - if mode == 'w': - raise IOError("can't write to a URL") - import urllib.request, urllib.parse, urllib.error - self.file = urllib.request.urlopen(filename) - else: - filename = os.path.expanduser(filename) - if mode == 'r' or mode == 'a': - if not os.path.exists(filename): - raise IOError(2, 'No such file or directory: ' + filename) - filen, file_extension = os.path.splitext(filename) - command_dict = { - ('.Z', 'r'): - "self.file = os.popen('uncompress -c ' + filename, mode)", - ('.gz', 'r'): - "self.file = gzip.GzipFile(filename, 'rb')", - ('.bz2', 'r'): - "self.file = os.popen('bzip2 -dc ' + filename, mode)", - ('.Z', 'w'): - "self.file = os.popen('compress > ' + filename, mode)", - ('.gz', 'w'): - "self.file = gzip.GzipFile(filename, 'wb')", - ('.bz2', 'w'): - "self.file = os.popen('bzip2 > ' + filename, mode)", - ('.Z', 'a'): - "raise IOError, (0, 'Can\'t append to .Z files')", - ('.gz', 'a'): - "self.file = gzip.GzipFile(filename, 'ab')", - ('.bz2', 'a'): - "raise IOError, (0, 'Can\'t append to .bz2 files')", - } - - exec(command_dict.get((file_extension, mode), - 'self.file = open(filename, mode)')) - - self.grammar = None - - # Try to find a parse ('*_def.ext') definition file. First try to find - # a file specific parse definition file, then look for 'sparse.def' - # that would be the definition file for all files within the directory. - - # The definition file is pure Python. The one variable that needs to - # be specified is 'parse'. The 'parse' variable is a list of tuples - # defining the name, type, and because it is a list, the order of - # variables on each line in the data file. The variable name is a - # string, the type variable is defined as integer, real, and qString. - - # parse = [ - # ('year', integer), - # ('month', integer), - # ('day', integer), - # ('value', real), - # ] - - definition_file_one = filen + "_def" + file_extension - definition_file_two = os.path.dirname(filen) + os.sep + "sparse.def" - if os.path.exists(definition_file_one): - self.parsedef = definition_file_one - elif os.path.exists(definition_file_two): - self.parsedef = definition_file_two - else: - self.parsedef = None - return None - - # Create some handy pyparsing constructs. I kept 'decimal_sep' so that - # could easily change to parse if the decimal separator is a ",". - decimal_sep = "." - sign = oneOf("+ -") - # part of printables without decimal_sep, +, - - special_chars = string.replace('!"#$%&\'()*,./:;<=>?@[\\]^_`{|}~', - decimal_sep, "") - integer = ToInteger( - Combine(Optional(sign) + - Word(nums))).setName("integer") - positive_integer = ToInteger( - Combine(Optional("+") + - Word(nums))).setName("integer") - negative_integer = ToInteger( - Combine("-" + - Word(nums))).setName("integer") - real = ToFloat( - Combine(Optional(sign) + - Word(nums) + - decimal_sep + - Optional(Word(nums)) + - Optional(oneOf("E e") + - Word(nums)))).setName("real") - positive_real = ToFloat( - Combine(Optional("+") + - Word(nums) + - decimal_sep + - Optional(Word(nums)) + - Optional(oneOf("E e") + - Word(nums)))).setName("real") - negative_real = ToFloat( - Combine("-" + - Word(nums) + - decimal_sep + - Optional(Word(nums)) + - Optional(oneOf("E e") + - Word(nums)))).setName("real") - qString = ( sglQuotedString | dblQuotedString ).setName("qString") - - # add other characters we should skip over between interesting fields - integer_junk = Optional( - Suppress( - Word(alphas + - special_chars + - decimal_sep))).setName("integer_junk") - real_junk = Optional( - Suppress( - Word(alphas + - special_chars))).setName("real_junk") - qString_junk = SkipTo(qString).setName("qString_junk") - - # Now that 'integer', 'real', and 'qString' have been assigned I can - # execute the definition file. - exec(compile(open(self.parsedef).read(), self.parsedef, 'exec')) - - # Build the grammar, combination of the 'integer', 'real, 'qString', - # and '*_junk' variables assigned above in the order specified in the - # definition file. - grammar = [] - for nam, expr in parse: - grammar.append( eval(expr.name + "_junk")) - grammar.append( expr.setResultsName(nam) ) - self.grammar = And( grammar[1:] + [restOfLine] ) - - def __del__(self): - """Delete (close) the file wrapper.""" - self.close() - - def __getitem__(self, item): - """Used in 'for line in fp:' idiom.""" - line = self.readline() - if not line: - raise IndexError - return line - - def readline(self): - """Reads (and optionally parses) a single line.""" - line = self.file.readline() - if self.grammar and line: - try: - return self.grammar.parseString(line).asDict() - except ParseException: - return self.readline() - else: - return line - - def readlines(self): - """Returns a list of all lines (optionally parsed) in the file.""" - if self.grammar: - tot = [] - # Used this way instead of a 'for' loop against - # self.file.readlines() so that there wasn't two copies of the file - # in memory. - while 1: - line = self.file.readline() - if not line: - break - tot.append(line) - return tot - return self.file.readlines() - - def write(self, data): - """Write to a file.""" - self.file.write(data) - - def writelines(self, list): - """Write a list to a file. Each item in the list is a line in the - file. - """ - for line in list: - self.file.write(line) - - def close(self): - """Close the file.""" - self.file.close() - - def flush(self): - """Flush in memory contents to file.""" - self.file.flush() - - -#============================= -def main(pargs): - """This should only be used for testing. The primary mode of operation is - as an imported library. - """ - input_file = sys.argv[1] - fp = ParseFileLineByLine(input_file) - for i in fp: - print(i) - - -#------------------------- -if __name__ == '__main__': - ftn = "main" - opts, pargs = getopt.getopt(sys.argv[1:], 'hvd', - ['help', 'version', 'debug', 'bb=']) - for opt in opts: - if opt[0] == '-h' or opt[0] == '--help': - print(modname+": version="+__version__) - usage() - sys.exit(0) - elif opt[0] == '-v' or opt[0] == '--version': - print(modname+": version="+__version__) - sys.exit(0) - elif opt[0] == '-d' or opt[0] == '--debug': - debug_p = 1 - elif opt[0] == '--bb': - opt_b = opt[1] - - #---make the object and run it--- - main(pargs) - -#===Revision Log=== -#Created by mkpythonproj: -#2006-02-06 Tim Cera -# diff --git a/examples/sql2dot.py b/examples/sql2dot.py deleted file mode 100644 index 1156207..0000000 --- a/examples/sql2dot.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/python - -# sql2dot.py -# -# Creates table graphics by parsing SQL table DML commands and -# generating DOT language output. -# -# Adapted from a post at http://energyblog.blogspot.com/2006/04/blog-post_20.html. -# -sampleSQL = """ -create table student -( -student_id integer primary key, -firstname varchar(20), -lastname varchar(40), -address1 varchar(80), -address2 varchar(80), -city varchar(30), -state varchar(2), -zipcode varchar(10), -dob date -); - -create table classes -( -class_id integer primary key, -id varchar(8), -maxsize integer, -instructor varchar(40) -); - -create table student_registrations -( -reg_id integer primary key, -student_id integer, -class_id integer -); - -alter table only student_registrations - add constraint students_link - foreign key - (student_id) references students(student_id); - -alter table only student_registrations - add constraint classes_link - foreign key - (class_id) references classes(class_id); -""".upper() - -from pyparsing import Literal, CaselessLiteral, Word, delimitedList \ - ,Optional, Combine, Group, alphas, nums, alphanums, Forward \ - , oneOf, sglQuotedString, OneOrMore, ZeroOrMore, CharsNotIn \ - , replaceWith - -skobki = "(" + ZeroOrMore(CharsNotIn(")")) + ")" -field_def = OneOrMore(Word(alphas,alphanums+"_\"':-") | skobki) - -def field_act(s,loc,tok): - return ("<"+tok[0]+"> " + " ".join(tok)).replace("\"","\\\"") - -field_def.setParseAction(field_act) - -field_list_def = delimitedList( field_def ) -def field_list_act(toks): - return " | ".join(toks) - -field_list_def.setParseAction(field_list_act) - -create_table_def = Literal("CREATE") + "TABLE" + Word(alphas,alphanums+"_").setResultsName("tablename") + \ - "("+field_list_def.setResultsName("columns")+")"+ ";" - -def create_table_act(toks): - return """"%(tablename)s" [\n\t label="<%(tablename)s> %(tablename)s | %(columns)s"\n\t shape="record"\n];""" % toks -create_table_def.setParseAction(create_table_act) - -add_fkey_def=Literal("ALTER")+"TABLE"+"ONLY" + Word(alphanums+"_").setResultsName("fromtable") + "ADD" \ - + "CONSTRAINT" + Word(alphanums+"_") + "FOREIGN"+"KEY"+"("+Word(alphanums+"_").setResultsName("fromcolumn")+")" \ - +"REFERENCES"+Word(alphanums+"_").setResultsName("totable")+"("+Word(alphanums+"_").setResultsName("tocolumn")+")"+";" - -def add_fkey_act(toks): - return """ "%(fromtable)s":%(fromcolumn)s -> "%(totable)s":%(tocolumn)s """ % toks -add_fkey_def.setParseAction(add_fkey_act) - -other_statement_def = ( OneOrMore(CharsNotIn(";") ) + ";") -other_statement_def.setParseAction( replaceWith("") ) -comment_def = "--" + ZeroOrMore(CharsNotIn("\n")) -comment_def.setParseAction( replaceWith("") ) - -statement_def = comment_def | create_table_def | add_fkey_def | other_statement_def -defs = OneOrMore(statement_def) - -print("""digraph g { graph [ rankdir = "LR" ]; """) -for i in defs.parseString(sampleSQL): - if i!="": - print(i) -print("}") \ No newline at end of file diff --git a/examples/stackish.py b/examples/stackish.py deleted file mode 100644 index f80b4d6..0000000 --- a/examples/stackish.py +++ /dev/null @@ -1,81 +0,0 @@ -# stackish.py -# -# Stackish is a data representation syntax, similar to JSON or YAML. For more info on -# stackish, see http://www.savingtheinternetwithhate.com/stackish.html -# -# Copyright 2008, Paul McGuire -# - -""" -NUMBER A simple integer type that's just any series of digits. -FLOAT A simple floating point type. -STRING A string is double quotes with anything inside that's not a " or - newline character. You can include \n and \" to include these - characters. -MARK Marks a point in the stack that demarcates the boundary for a nested - group. -WORD Marks the root node of a group, with the other end being the nearest - MARK. -GROUP Acts as the root node of an anonymous group. -ATTRIBUTE Assigns an attribute name to the previously processed node. - This means that just about anything can be an attribute, unlike in XML. -BLOB A BLOB is unique to Stackish and allows you to record any content - (even binary content) inside the structure. This is done by pre- - sizing the data with the NUMBER similar to Dan Bernstein's netstrings - setup. -SPACE White space is basically ignored. This is interesting because since - Stackish is serialized consistently this means you can use \n as the - separation character and perform reasonable diffs on two structures. -""" - -from pyparsing import Suppress,Word,nums,alphas,alphanums,Combine,oneOf,\ - Optional,QuotedString,Forward,Group,ZeroOrMore,printables,srange - -MARK,UNMARK,AT,COLON,QUOTE = map(Suppress,"[]@:'") - -NUMBER = Word(nums) -NUMBER.setParseAction(lambda t:int(t[0])) -FLOAT = Combine(oneOf("+ -") + Word(nums) + "." + Optional(Word(nums))) -FLOAT.setParseAction(lambda t:float(t[0])) -STRING = QuotedString('"', multiline=True) -WORD = Word(alphas,alphanums+"_:") -ATTRIBUTE = Combine(AT + WORD) - -strBody = Forward() -def setBodyLength(tokens): - strBody << Word(srange(r'[\0x00-\0xffff]'), exact=int(tokens[0])) - return "" -BLOB = Combine(QUOTE + Word(nums).setParseAction(setBodyLength) + - COLON + strBody + QUOTE) - -item = Forward() -def assignUsing(s): - def assignPA(tokens): - if s in tokens: - tokens[tokens[s]] = tokens[0] - del tokens[s] - return assignPA -GROUP = (MARK + - Group( ZeroOrMore( - (item + - Optional(ATTRIBUTE)("attr") - ).setParseAction(assignUsing("attr")) - ) - ) + - ( WORD("name") | UNMARK ) - ).setParseAction(assignUsing("name")) -item << (NUMBER | FLOAT | STRING | BLOB | GROUP ) - -tests = """\ -[ '10:1234567890' @name 25 @age +0.45 @percentage person:zed -[ [ "hello" 1 child root -[ "child" [ 200 '4:like' "I" "hello" things root -[ [ "data" [ 2 1 ] @numbers child root -[ [ 1 2 3 ] @test 4 5 6 root -""".splitlines() - -for test in tests: - if test: - print(test) - print(item.parseString(test).dump()) - print() diff --git a/examples/stateMachine2.py b/examples/stateMachine2.py deleted file mode 100644 index eb6633d..0000000 --- a/examples/stateMachine2.py +++ /dev/null @@ -1,258 +0,0 @@ -# stateMachine.py -# -# module to define .pystate import handler -# -#import imputil -import sys -import os -import types -import urllib.parse - -DEBUG = False - -from pyparsing import Word, Group, ZeroOrMore, alphas, \ - alphanums, ParserElement, ParseException, ParseSyntaxException, \ - Empty, LineEnd, OneOrMore, col, Keyword, pythonStyleComment, \ - StringEnd, traceParseAction - - -ident = Word(alphas+"_", alphanums+"_$") - -pythonKeywords = """and as assert break class continue def - del elif else except exec finally for from global if import - in is lambda None not or pass print raise return try while with - yield True False""" -pythonKeywords = set(pythonKeywords.split()) -def no_keywords_allowed(s,l,t): - wd = t[0] - if wd in pythonKeywords: - errmsg = "cannot not use keyword '%s' " \ - "as an identifier" % wd - raise ParseException(s,l,errmsg) -ident.setParseAction(no_keywords_allowed) - -stateTransition = ident("fromState") + "->" + ident("toState") -stateMachine = Keyword("statemachine") + \ - ident("name") + ":" + \ - OneOrMore(Group(stateTransition))("transitions") - -namedStateTransition = (ident("fromState") + \ - "-(" + ident("transition") + ")->" + \ - ident("toState")) -namedStateMachine = Keyword("statemachine") + \ - ident("name") + ":" + \ - OneOrMore(Group(namedStateTransition))("transitions") - -def expand_state_definition(source, loc, tokens): - indent = " " * (col(loc,source)-1) - statedef = [] - - # build list of states - states = set() - fromTo = {} - for tn in tokens.transitions: - states.add(tn.fromState) - states.add(tn.toState) - fromTo[tn.fromState] = tn.toState - - # define base class for state classes - baseStateClass = tokens.name + "State" - statedef.extend([ - "class %s(object):" % baseStateClass, - " def __str__(self):", - " return self.__class__.__name__", - " def next_state(self):", - " return self._next_state_class()" ]) - - # define all state classes - statedef.extend( - "class %s(%s): pass" % (s,baseStateClass) - for s in states ) - statedef.extend( - "%s._next_state_class = %s" % (s,fromTo[s]) - for s in states if s in fromTo ) - - return indent + ("\n"+indent).join(statedef)+"\n" - -stateMachine.setParseAction(expand_state_definition) - -def expand_named_state_definition(source,loc,tokens): - indent = " " * (col(loc,source)-1) - statedef = [] - # build list of states and transitions - states = set() - transitions = set() - - baseStateClass = tokens.name + "State" - - fromTo = {} - for tn in tokens.transitions: - states.add(tn.fromState) - states.add(tn.toState) - transitions.add(tn.transition) - if tn.fromState in fromTo: - fromTo[tn.fromState][tn.transition] = tn.toState - else: - fromTo[tn.fromState] = {tn.transition:tn.toState} - - # add entries for terminal states - for s in states: - if s not in fromTo: - fromTo[s] = {} - - # define state transition class - statedef.extend([ - "class %sTransition:" % baseStateClass, - " def __str__(self):", - " return self.transitionName", - ]) - statedef.extend( - "%s = %sTransition()" % (tn,baseStateClass) - for tn in transitions) - statedef.extend("%s.transitionName = '%s'" % (tn,tn) - for tn in transitions) - - # define base class for state classes - excmsg = "'" + tokens.name + \ - '.%s does not support transition "%s"' \ - "'% (self, tn)" - statedef.extend([ - "class %s(object):" % baseStateClass, - " def __str__(self):", - " return self.__class__.__name__", - " def next_state(self,tn):", - " try:", - " return self.tnmap[tn]()", - " except KeyError:", - " raise Exception(%s)" % excmsg, - " def __getattr__(self,name):", - " raise Exception(%s)" % excmsg, - ]) - - # define all state classes - for s in states: - statedef.append("class %s(%s): pass" % - (s,baseStateClass)) - - # define state transition maps and transition methods - for s in states: - trns = list(fromTo[s].items()) - statedef.append("%s.tnmap = {%s}" % - (s, ",".join("%s:%s" % tn for tn in trns)) ) - statedef.extend([ - "%s.%s = staticmethod(lambda : %s())" % - (s,tn_,to_) - for tn_,to_ in trns - ]) - - return indent + ("\n"+indent).join(statedef) + "\n" - -namedStateMachine.setParseAction( - expand_named_state_definition) - -#====================================================================== -# NEW STUFF - Matt Anderson, 2009-11-26 -#====================================================================== -class SuffixImporter(object): - - """An importer designed using the mechanism defined in :pep:`302`. I read - the PEP, and also used Doug Hellmann's PyMOTW article `Modules and - Imports`_, as a pattern. - - .. _`Modules and Imports`: http://www.doughellmann.com/PyMOTW/sys/imports.html - - Define a subclass that specifies a :attr:`suffix` attribute, and - implements a :meth:`process_filedata` method. Then call the classmethod - :meth:`register` on your class to actually install it in the appropriate - places in :mod:`sys`. """ - - scheme = 'suffix' - suffix = None - path_entry = None - - @classmethod - def trigger_url(cls): - if cls.suffix is None: - raise ValueError('%s.suffix is not set' % cls.__name__) - return 'suffix:%s' % cls.suffix - - @classmethod - def register(cls): - sys.path_hooks.append(cls) - sys.path.append(cls.trigger_url()) - - def __init__(self, path_entry): - pr = urllib.parse.urlparse(str(path_entry)) - if pr.scheme != self.scheme or pr.path != self.suffix: - raise ImportError() - self.path_entry = path_entry - self._found = {} - - def checkpath_iter(self, fullname): - for dirpath in sys.path: - # if the value in sys.path_importer_cache is None, then this - # path *should* be imported by the builtin mechanism, and the - # entry is thus a path to a directory on the filesystem; - # if it's not None, then some other importer is in charge, and - # it probably isn't even a filesystem path - if sys.path_importer_cache.get(dirpath,False) is None: - checkpath = os.path.join( - dirpath,'%s.%s' % (fullname,self.suffix)) - yield checkpath - - def find_module(self, fullname, path=None): - for checkpath in self.checkpath_iter(fullname): - if os.path.isfile(checkpath): - self._found[fullname] = checkpath - return self - return None - - def load_module(self, fullname): - assert fullname in self._found - if fullname in sys.modules: - module = sys.modules[fullname] - else: - sys.modules[fullname] = module = types.ModuleType(fullname) - data = None - f = open(self._found[fullname]) - try: - data = f.read() - finally: - f.close() - - module.__dict__.clear() - module.__file__ = self._found[fullname] - module.__name__ = fullname - module.__loader__ = self - self.process_filedata(module, data) - return module - - def process_filedata(self, module, data): - pass - -class PystateImporter(SuffixImporter): - suffix = 'pystate' - - def process_filedata(self, module, data): - # MATT-NOTE: re-worked :func:`get_state_machine` - - # convert any statemachine expressions - stateMachineExpr = (stateMachine | - namedStateMachine).ignore( - pythonStyleComment) - generated_code = stateMachineExpr.transformString(data) - - if DEBUG: print(generated_code) - - # compile code object from generated code - # (strip trailing spaces and tabs, compile doesn't like - # dangling whitespace) - COMPILE_MODE = 'exec' - - codeobj = compile(generated_code.rstrip(" \t"), - module.__file__, - COMPILE_MODE) - - exec(codeobj, module.__dict__) - -PystateImporter.register() diff --git a/examples/test_bibparse.py b/examples/test_bibparse.py deleted file mode 100644 index 7440a66..0000000 --- a/examples/test_bibparse.py +++ /dev/null @@ -1,195 +0,0 @@ -""" Test for bibparse grammar """ - -from os.path import join as pjoin, dirname - -from pyparsing import ParseException -from btpyparse import Macro -import btpyparse as bp - -from nose.tools import assert_true, assert_false, assert_equal, assert_raises - - -def test_names(): - # check various types of names - # All names can contains alphas, but not some special chars - bad_chars = '"#%\'(),={}' - for name_type, dig1f in ((bp.macro_def, False), - (bp.field_name, False), - (bp.entry_type, False), - (bp.cite_key, True)): - if dig1f: # can start with digit - assert_equal(name_type.parseString('2t')[0], '2t') - else: - assert_raises(ParseException, name_type.parseString, '2t') - # All of the names cannot contain some characters - for char in bad_chars: - assert_raises(ParseException, name_type.parseString, char) - # standard strings all OK - assert_equal(name_type.parseString('simple_test')[0], 'simple_test') - # Test macro ref - mr = bp.macro_ref - # can't start with digit - assert_raises(ParseException, mr.parseString, '2t') - for char in bad_chars: - assert_raises(ParseException, mr.parseString, char) - assert_equal(mr.parseString('simple_test')[0].name, 'simple_test') - - -def test_numbers(): - assert_equal(bp.number.parseString('1066')[0], '1066') - assert_equal(bp.number.parseString('0')[0], '0') - assert_raises(ParseException, bp.number.parseString, '-4') - assert_raises(ParseException, bp.number.parseString, '+4') - assert_raises(ParseException, bp.number.parseString, '.4') - # something point something leaves a trailing .4 unmatched - assert_equal(bp.number.parseString('0.4')[0], '0') - - -def test_parse_string(): - # test string building blocks - assert_equal(bp.chars_no_quotecurly.parseString('x')[0], 'x') - assert_equal(bp.chars_no_quotecurly.parseString("a string")[0], 'a string') - assert_equal(bp.chars_no_quotecurly.parseString('a "string')[0], 'a ') - assert_equal(bp.chars_no_curly.parseString('x')[0], 'x') - assert_equal(bp.chars_no_curly.parseString("a string")[0], 'a string') - assert_equal(bp.chars_no_curly.parseString('a {string')[0], 'a ') - assert_equal(bp.chars_no_curly.parseString('a }string')[0], 'a ') - # test more general strings together - for obj in (bp.curly_string, bp.string, bp.field_value): - assert_equal(obj.parseString('{}').asList(), []) - assert_equal(obj.parseString('{a "string}')[0], 'a "string') - assert_equal(obj.parseString('{a {nested} string}').asList(), - ['a ', ['nested'], ' string']) - assert_equal(obj.parseString('{a {double {nested}} string}').asList(), - ['a ', ['double ', ['nested']], ' string']) - for obj in (bp.quoted_string, bp.string, bp.field_value): - assert_equal(obj.parseString('""').asList(), []) - assert_equal(obj.parseString('"a string"')[0], 'a string') - assert_equal(obj.parseString('"a {nested} string"').asList(), - ['a ', ['nested'], ' string']) - assert_equal(obj.parseString('"a {double {nested}} string"').asList(), - ['a ', ['double ', ['nested']], ' string']) - # check macro def in string - assert_equal(bp.string.parseString('someascii')[0], Macro('someascii')) - assert_raises(ParseException, bp.string.parseString, '%#= validstring') - # check number in string - assert_equal(bp.string.parseString('1994')[0], '1994') - - -def test_parse_field(): - # test field value - hashes included - fv = bp.field_value - # Macro - assert_equal(fv.parseString('aname')[0], Macro('aname')) - assert_equal(fv.parseString('ANAME')[0], Macro('aname')) - # String and macro - assert_equal(fv.parseString('aname # "some string"').asList(), - [Macro('aname'), 'some string']) - # Nested string - assert_equal(fv.parseString('aname # {some {string}}').asList(), - [Macro('aname'), 'some ', ['string']]) - # String and number - assert_equal(fv.parseString('"a string" # 1994').asList(), - ['a string', '1994']) - # String and number and macro - assert_equal(fv.parseString('"a string" # 1994 # a_macro').asList(), - ['a string', '1994', Macro('a_macro')]) - - -def test_comments(): - res = bp.comment.parseString('@Comment{about something}') - assert_equal(res.asList(), ['comment', '{about something}']) - assert_equal( - bp.comment.parseString('@COMMENT{about something').asList(), - ['comment', '{about something']) - assert_equal( - bp.comment.parseString('@comment(about something').asList(), - ['comment', '(about something']) - assert_equal( - bp.comment.parseString('@COMment about something').asList(), - ['comment', ' about something']) - assert_raises(ParseException, bp.comment.parseString, - '@commentabout something') - assert_raises(ParseException, bp.comment.parseString, - '@comment+about something') - assert_raises(ParseException, bp.comment.parseString, - '@comment"about something') - - -def test_preamble(): - res = bp.preamble.parseString('@preamble{"about something"}') - assert_equal(res.asList(), ['preamble', 'about something']) - assert_equal(bp.preamble.parseString( - '@PREamble{{about something}}').asList(), - ['preamble', 'about something']) - assert_equal(bp.preamble.parseString("""@PREamble{ - {about something} - }""").asList(), - ['preamble', 'about something']) - - -def test_macro(): - res = bp.macro.parseString('@string{ANAME = "about something"}') - assert_equal(res.asList(), ['string', 'aname', 'about something']) - assert_equal( - bp.macro.parseString('@string{aname = {about something}}').asList(), - ['string', 'aname', 'about something']) - - -def test_entry(): - txt = """@some_entry{akey, aname = "about something", - another={something else}}""" - res = bp.entry.parseString(txt) - assert_equal(res.asList(), - ['some_entry', 'akey', - ['aname', 'about something'], ['another', 'something else']]) - # Case conversion - txt = """@SOME_ENTRY{akey, ANAME = "about something", - another={something else}}""" - res = bp.entry.parseString(txt) - assert_equal(res.asList(), - ['some_entry', 'akey', - ['aname', 'about something'], ['another', 'something else']]) - - -def test_bibfile(): - txt = """@some_entry{akey, aname = "about something", - another={something else}}""" - res = bp.bibfile.parseString(txt) - assert_equal(res.asList(), - [['some_entry', 'akey', - ['aname', 'about something'], - ['another', 'something else']]]) - - -def test_bib1(): - # First pass whole bib-like tests - txt = """ -Some introductory text -(implicit comment) - - @ARTICLE{Brett2002marsbar, - author = {Matthew Brett and Jean-Luc Anton and Romain Valabregue and Jean-Baptise - Poline}, - title = {{Region of interest analysis using an SPM toolbox}}, - journal = {Neuroimage}, - year = {2002}, - volume = {16}, - pages = {1140--1141}, - number = {2} -} - -@some_entry{akey, aname = "about something", -another={something else}} -""" - res = bp.bibfile.parseString(txt) - assert_equal(len(res), 3) - res2 = bp.parse_str(txt) - assert_equal(res.asList(), res2.asList()) - res3 = [r.asList()[0] for r, start, end in bp.definitions.scanString(txt)] - assert_equal(res.asList(), res3) - - -if __name__ == '__main__': - import nose - nose.main() diff --git a/examples/urlExtractor.py b/examples/urlExtractor.py deleted file mode 100644 index 2c66d78..0000000 --- a/examples/urlExtractor.py +++ /dev/null @@ -1,33 +0,0 @@ -# URL extractor -# Copyright 2004, Paul McGuire -from pyparsing import makeHTMLTags, SkipTo, pyparsing_common -import urllib.request -from contextlib import closing -import pprint - -linkOpenTag, linkCloseTag = makeHTMLTags('a') - -linkBody = SkipTo(linkCloseTag) -linkBody.setParseAction(pyparsing_common.stripHTMLTags) -linkBody.addParseAction(lambda toks: ' '.join(toks[0].strip().split())) - -link = linkOpenTag + linkBody("body") + linkCloseTag.suppress() - -# Go get some HTML with some links in it. -with closing(urllib.request.urlopen("http://www.yahoo.com")) as serverListPage: - htmlText = serverListPage.read().decode("UTF-8") - -# scanString is a generator that loops through the input htmlText, and for each -# match yields the tokens and start and end locations (for this application, we are -# not interested in the start and end values). -for toks,strt,end in link.scanString(htmlText): - print(toks.asList()) - -# Create dictionary from list comprehension, assembled from each pair of tokens returned -# from a matched URL. -pprint.pprint( - dict((toks.body, toks.href) for toks,strt,end in link.scanString(htmlText)) - ) - - - diff --git a/examples/urlExtractorNew.py b/examples/urlExtractorNew.py deleted file mode 100644 index 0aac875..0000000 --- a/examples/urlExtractorNew.py +++ /dev/null @@ -1,35 +0,0 @@ -# URL extractor -# Copyright 2004, Paul McGuire -from pyparsing import Literal,Suppress,CharsNotIn,CaselessLiteral,\ - Word,dblQuotedString,alphanums,SkipTo,makeHTMLTags -import urllib.request, urllib.parse, urllib.error -import pprint - -# Define the pyparsing grammar for a URL, that is: -# URLlink ::= linkText -# URL ::= doubleQuotedString | alphanumericWordPath -# Note that whitespace may appear just about anywhere in the link. Note also -# that it is not necessary to explicitly show this in the pyparsing grammar; by default, -# pyparsing skips over whitespace between tokens. -linkOpenTag,linkCloseTag = makeHTMLTags("a") -link = linkOpenTag + SkipTo(linkCloseTag)("body") + linkCloseTag.suppress() - -# Go get some HTML with some links in it. -serverListPage = urllib.request.urlopen( "http://www.google.com" ) -htmlText = serverListPage.read() -serverListPage.close() - -# scanString is a generator that loops through the input htmlText, and for each -# match yields the tokens and start and end locations (for this application, we are -# not interested in the start and end values). -for toks,strt,end in link.scanString(htmlText): - print(toks.startA.href,"->",toks.body) - -# Create dictionary from list comprehension, assembled from each pair of tokens returned -# from a matched URL. -pprint.pprint( - dict( [ (toks.body,toks.startA.href) for toks,strt,end in link.scanString(htmlText) ] ) - ) - - - diff --git a/examples/verilogParse.py b/examples/verilogParse.py deleted file mode 100644 index 05650df..0000000 --- a/examples/verilogParse.py +++ /dev/null @@ -1,720 +0,0 @@ -# -# verilogParse.py -# -# an example of using the pyparsing module to be able to process Verilog files -# uses BNF defined at http://www.verilog.com/VerilogBNF.html -# -# Copyright (c) 2004-2011 Paul T. McGuire. All rights reserved. -# -# 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. -# -# If you find this software to be useful, please make a donation to one -# of the following charities: -# - the Red Cross (http://www.redcross.org) -# - Hospice Austin (http://www.hospiceaustin.org) -# -# DISCLAIMER: -# THIS SOFTWARE IS PROVIDED BY PAUL T. McGUIRE ``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 PAUL T. McGUIRE OR CO-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 OFUSE, -# 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. -# -# For questions or inquiries regarding this license, or commercial use of -# this software, contact the author via e-mail: ptmcg@users.sourceforge.net -# -# Todo: -# - add pre-process pass to implement compilerDirectives (ifdef, include, etc.) -# -# Revision History: -# -# 1.0 - Initial release -# 1.0.1 - Fixed grammar errors: -# . real declaration was incorrect -# . tolerant of '=>' for '*>' operator -# . tolerant of '?' as hex character -# . proper handling of mintypmax_expr within path delays -# 1.0.2 - Performance tuning (requires pyparsing 1.3) -# 1.0.3 - Performance updates, using Regex (requires pyparsing 1.4) -# 1.0.4 - Performance updates, enable packrat parsing (requires pyparsing 1.4.2) -# 1.0.5 - Converted keyword Literals to Keywords, added more use of Group to -# group parsed results tokens -# 1.0.6 - Added support for module header with no ports list (thanks, Thomas Dejanovic!) -# 1.0.7 - Fixed erroneous '<<' Forward definition in timCheckCond, omitting ()'s -# 1.0.8 - Re-released under MIT license -# 1.0.9 - Enhanced udpInstance to handle identifiers with leading '\' and subscripting -# 1.0.10 - Fixed change added in 1.0.9 to work for all identifiers, not just those used -# for udpInstance. -# 1.0.11 - Fixed bug in inst_args, content alternatives were reversed -# -import pdb -import time -import pprint -import sys - -__version__ = "1.0.11" - -from pyparsing import Literal, CaselessLiteral, Keyword, Word, OneOrMore, ZeroOrMore, \ - Forward, NotAny, delimitedList, Group, Optional, Combine, alphas, nums, restOfLine, cStyleComment, \ - alphanums, printables, dblQuotedString, empty, ParseException, ParseResults, MatchFirst, oneOf, GoToColumn, \ - ParseResults,StringEnd, FollowedBy, ParserElement, And, Regex, cppStyleComment#,__version__ -import pyparsing -usePackrat = False -usePsyco = False - -packratOn = False -psycoOn = False - -if usePackrat: - try: - ParserElement.enablePackrat() - except: - pass - else: - packratOn = True - -# comment out this section to disable psyco function compilation -if usePsyco: - try: - import psyco - psyco.full() - except: - print("failed to import psyco Python optimizer") - else: - psycoOn = True - - -def dumpTokens(s,l,t): - import pprint - pprint.pprint( t.asList() ) - -verilogbnf = None -def Verilog_BNF(): - global verilogbnf - - if verilogbnf is None: - - # compiler directives - compilerDirective = Combine( "`" + \ - oneOf("define undef ifdef else endif default_nettype " - "include resetall timescale unconnected_drive " - "nounconnected_drive celldefine endcelldefine") + \ - restOfLine ).setName("compilerDirective") - - # primitives - SEMI,COLON,LPAR,RPAR,LBRACE,RBRACE,LBRACK,RBRACK,DOT,COMMA,EQ = map(Literal,";:(){}[].,=") - - identLead = alphas+"$_" - identBody = alphanums+"$_" - identifier1 = Regex( r"\.?["+identLead+"]["+identBody+r"]*(\.["+identLead+"]["+identBody+"]*)*" - ).setName("baseIdent") - identifier2 = Regex(r"\\\S+").setParseAction(lambda t:t[0][1:]).setName("escapedIdent")#.setDebug() - identifier = identifier1 | identifier2 - assert(identifier2 == r'\abc') - - hexnums = nums + "abcdefABCDEF" + "_?" - base = Regex("'[bBoOdDhH]").setName("base") - basedNumber = Combine( Optional( Word(nums + "_") ) + base + Word(hexnums+"xXzZ"), - joinString=" ", adjacent=False ).setName("basedNumber") - #~ number = ( basedNumber | Combine( Word( "+-"+spacedNums, spacedNums ) + - #~ Optional( DOT + Optional( Word( spacedNums ) ) ) + - #~ Optional( e + Word( "+-"+spacedNums, spacedNums ) ) ).setName("numeric") ) - number = ( basedNumber | \ - Regex(r"[+-]?[0-9_]+(\.[0-9_]*)?([Ee][+-]?[0-9_]+)?") \ - ).setName("numeric") - #~ decnums = nums + "_" - #~ octnums = "01234567" + "_" - expr = Forward().setName("expr") - concat = Group( LBRACE + delimitedList( expr ) + RBRACE ) - multiConcat = Group("{" + expr + concat + "}").setName("multiConcat") - funcCall = Group(identifier + LPAR + Optional( delimitedList( expr ) ) + RPAR).setName("funcCall") - - subscrRef = Group(LBRACK + delimitedList( expr, COLON ) + RBRACK) - subscrIdentifier = Group( identifier + Optional( subscrRef ) ) - #~ scalarConst = "0" | (( FollowedBy('1') + oneOf("1'b0 1'b1 1'bx 1'bX 1'B0 1'B1 1'Bx 1'BX 1") )) - scalarConst = Regex("0|1('[Bb][01xX])?") - mintypmaxExpr = Group( expr + COLON + expr + COLON + expr ).setName("mintypmax") - primary = ( - number | - (LPAR + mintypmaxExpr + RPAR ) | - ( LPAR + Group(expr) + RPAR ).setName("nestedExpr") | - multiConcat | - concat | - dblQuotedString | - funcCall | - subscrIdentifier - ) - - unop = oneOf( "+ - ! ~ & ~& | ^| ^ ~^" ).setName("unop") - binop = oneOf( "+ - * / % == != === !== && " - "|| < <= > >= & | ^ ^~ >> << ** <<< >>>" ).setName("binop") - - expr << ( - ( unop + expr ) | # must be first! - ( primary + "?" + expr + COLON + expr ) | - ( primary + Optional( binop + expr ) ) - ) - - lvalue = subscrIdentifier | concat - - # keywords - if_ = Keyword("if") - else_ = Keyword("else") - edge = Keyword("edge") - posedge = Keyword("posedge") - negedge = Keyword("negedge") - specify = Keyword("specify") - endspecify = Keyword("endspecify") - fork = Keyword("fork") - join = Keyword("join") - begin = Keyword("begin") - end = Keyword("end") - default = Keyword("default") - forever = Keyword("forever") - repeat = Keyword("repeat") - while_ = Keyword("while") - for_ = Keyword("for") - case = oneOf( "case casez casex" ) - endcase = Keyword("endcase") - wait = Keyword("wait") - disable = Keyword("disable") - deassign = Keyword("deassign") - force = Keyword("force") - release = Keyword("release") - assign = Keyword("assign") - - eventExpr = Forward() - eventTerm = ( posedge + expr ) | ( negedge + expr ) | expr | ( LPAR + eventExpr + RPAR ) - eventExpr << ( - Group( delimitedList( eventTerm, Keyword("or") ) ) - ) - eventControl = Group( "@" + ( ( LPAR + eventExpr + RPAR ) | identifier | "*" ) ).setName("eventCtrl") - - delayArg = ( number | - Word(alphanums+"$_") | #identifier | - ( LPAR + Group( delimitedList( mintypmaxExpr | expr ) ) + RPAR ) - ).setName("delayArg")#.setDebug() - delay = Group( "#" + delayArg ).setName("delay")#.setDebug() - delayOrEventControl = delay | eventControl - - assgnmt = Group( lvalue + EQ + Optional( delayOrEventControl ) + expr ).setName( "assgnmt" ) - nbAssgnmt = Group(( lvalue + "<=" + Optional( delay ) + expr ) | - ( lvalue + "<=" + Optional( eventControl ) + expr )).setName( "nbassgnmt" ) - - range = LBRACK + expr + COLON + expr + RBRACK - - paramAssgnmt = Group( identifier + EQ + expr ).setName("paramAssgnmt") - parameterDecl = Group( "parameter" + Optional( range ) + delimitedList( paramAssgnmt ) + SEMI).setName("paramDecl") - - inputDecl = Group( "input" + Optional( range ) + delimitedList( identifier ) + SEMI ) - outputDecl = Group( "output" + Optional( range ) + delimitedList( identifier ) + SEMI ) - inoutDecl = Group( "inout" + Optional( range ) + delimitedList( identifier ) + SEMI ) - - regIdentifier = Group( identifier + Optional( LBRACK + expr + COLON + expr + RBRACK ) ) - regDecl = Group( "reg" + Optional("signed") + Optional( range ) + delimitedList( regIdentifier ) + SEMI ).setName("regDecl") - timeDecl = Group( "time" + delimitedList( regIdentifier ) + SEMI ) - integerDecl = Group( "integer" + delimitedList( regIdentifier ) + SEMI ) - - strength0 = oneOf("supply0 strong0 pull0 weak0 highz0") - strength1 = oneOf("supply1 strong1 pull1 weak1 highz1") - driveStrength = Group( LPAR + ( ( strength0 + COMMA + strength1 ) | - ( strength1 + COMMA + strength0 ) ) + RPAR ).setName("driveStrength") - nettype = oneOf("wire tri tri1 supply0 wand triand tri0 supply1 wor trior trireg") - expandRange = Optional( oneOf("scalared vectored") ) + range - realDecl = Group( "real" + delimitedList( identifier ) + SEMI ) - - eventDecl = Group( "event" + delimitedList( identifier ) + SEMI ) - - blockDecl = ( - parameterDecl | - regDecl | - integerDecl | - realDecl | - timeDecl | - eventDecl - ) - - stmt = Forward().setName("stmt")#.setDebug() - stmtOrNull = stmt | SEMI - caseItem = ( delimitedList( expr ) + COLON + stmtOrNull ) | \ - ( default + Optional(":") + stmtOrNull ) - stmt << Group( - ( begin + Group( ZeroOrMore( stmt ) ) + end ).setName("begin-end") | - ( if_ + Group(LPAR + expr + RPAR) + stmtOrNull + Optional( else_ + stmtOrNull ) ).setName("if") | - ( delayOrEventControl + stmtOrNull ) | - ( case + LPAR + expr + RPAR + OneOrMore( caseItem ) + endcase ) | - ( forever + stmt ) | - ( repeat + LPAR + expr + RPAR + stmt ) | - ( while_ + LPAR + expr + RPAR + stmt ) | - ( for_ + LPAR + assgnmt + SEMI + Group( expr ) + SEMI + assgnmt + RPAR + stmt ) | - ( fork + ZeroOrMore( stmt ) + join ) | - ( fork + COLON + identifier + ZeroOrMore( blockDecl ) + ZeroOrMore( stmt ) + end ) | - ( wait + LPAR + expr + RPAR + stmtOrNull ) | - ( "->" + identifier + SEMI ) | - ( disable + identifier + SEMI ) | - ( assign + assgnmt + SEMI ) | - ( deassign + lvalue + SEMI ) | - ( force + assgnmt + SEMI ) | - ( release + lvalue + SEMI ) | - ( begin + COLON + identifier + ZeroOrMore( blockDecl ) + ZeroOrMore( stmt ) + end ).setName("begin:label-end") | - # these *have* to go at the end of the list!!! - ( assgnmt + SEMI ) | - ( nbAssgnmt + SEMI ) | - ( Combine( Optional("$") + identifier ) + Optional( LPAR + delimitedList(expr|empty) + RPAR ) + SEMI ) - ).setName("stmtBody") - """ - x::= ; - x||= ; - x||= if ( ) - x||= if ( ) else - x||= case ( ) + endcase - x||= casez ( ) + endcase - x||= casex ( ) + endcase - x||= forever - x||= repeat ( ) - x||= while ( ) - x||= for ( ; ; ) - x||= - x||= wait ( ) - x||= -> ; - x||= - x||= - x||= - x||= - x||= disable ; - x||= disable ; - x||= assign ; - x||= deassign ; - x||= force ; - x||= release ; - """ - alwaysStmt = Group( "always" + Optional(eventControl) + stmt ).setName("alwaysStmt") - initialStmt = Group( "initial" + stmt ).setName("initialStmt") - - chargeStrength = Group( LPAR + oneOf( "small medium large" ) + RPAR ).setName("chargeStrength") - - continuousAssign = Group( - assign + Optional( driveStrength ) + Optional( delay ) + delimitedList( assgnmt ) + SEMI - ).setName("continuousAssign") - - - tfDecl = ( - parameterDecl | - inputDecl | - outputDecl | - inoutDecl | - regDecl | - timeDecl | - integerDecl | - realDecl - ) - - functionDecl = Group( - "function" + Optional( range | "integer" | "real" ) + identifier + SEMI + - Group( OneOrMore( tfDecl ) ) + - Group( ZeroOrMore( stmt ) ) + - "endfunction" - ) - - inputOutput = oneOf("input output") - netDecl1Arg = ( nettype + - Optional( expandRange ) + - Optional( delay ) + - Group( delimitedList( ~inputOutput + identifier ) ) ) - netDecl2Arg = ( "trireg" + - Optional( chargeStrength ) + - Optional( expandRange ) + - Optional( delay ) + - Group( delimitedList( ~inputOutput + identifier ) ) ) - netDecl3Arg = ( nettype + - Optional( driveStrength ) + - Optional( expandRange ) + - Optional( delay ) + - Group( delimitedList( assgnmt ) ) ) - netDecl1 = Group(netDecl1Arg + SEMI).setName("netDecl1") - netDecl2 = Group(netDecl2Arg + SEMI).setName("netDecl2") - netDecl3 = Group(netDecl3Arg + SEMI).setName("netDecl3") - - gateType = oneOf("and nand or nor xor xnor buf bufif0 bufif1 " - "not notif0 notif1 pulldown pullup nmos rnmos " - "pmos rpmos cmos rcmos tran rtran tranif0 " - "rtranif0 tranif1 rtranif1" ) - gateInstance = Optional( Group( identifier + Optional( range ) ) ) + \ - LPAR + Group( delimitedList( expr ) ) + RPAR - gateDecl = Group( gateType + - Optional( driveStrength ) + - Optional( delay ) + - delimitedList( gateInstance) + - SEMI ) - - udpInstance = Group( Group( identifier + Optional(range | subscrRef) ) + - LPAR + Group( delimitedList( expr ) ) + RPAR ) - udpInstantiation = Group( identifier - - Optional( driveStrength ) + - Optional( delay ) + - delimitedList( udpInstance ) + - SEMI ).setName("udpInstantiation") - - parameterValueAssignment = Group( Literal("#") + LPAR + Group( delimitedList( expr ) ) + RPAR ) - namedPortConnection = Group( DOT + identifier + LPAR + expr + RPAR ).setName("namedPortConnection")#.setDebug() - assert(r'.\abc (abc )' == namedPortConnection) - modulePortConnection = expr | empty - #~ moduleInstance = Group( Group ( identifier + Optional(range) ) + - #~ ( delimitedList( modulePortConnection ) | - #~ delimitedList( namedPortConnection ) ) ) - inst_args = Group( LPAR + (delimitedList( namedPortConnection ) | - delimitedList( modulePortConnection )) + RPAR).setName("inst_args") - moduleInstance = Group( Group ( identifier + Optional(range) ) + inst_args ).setName("moduleInstance")#.setDebug() - - moduleInstantiation = Group( identifier + - Optional( parameterValueAssignment ) + - delimitedList( moduleInstance ).setName("moduleInstanceList") + - SEMI ).setName("moduleInstantiation") - - parameterOverride = Group( "defparam" + delimitedList( paramAssgnmt ) + SEMI ) - task = Group( "task" + identifier + SEMI + - ZeroOrMore( tfDecl ) + - stmtOrNull + - "endtask" ) - - specparamDecl = Group( "specparam" + delimitedList( paramAssgnmt ) + SEMI ) - - pathDescr1 = Group( LPAR + subscrIdentifier + "=>" + subscrIdentifier + RPAR ) - pathDescr2 = Group( LPAR + Group( delimitedList( subscrIdentifier ) ) + "*>" + - Group( delimitedList( subscrIdentifier ) ) + RPAR ) - pathDescr3 = Group( LPAR + Group( delimitedList( subscrIdentifier ) ) + "=>" + - Group( delimitedList( subscrIdentifier ) ) + RPAR ) - pathDelayValue = Group( ( LPAR + Group( delimitedList( mintypmaxExpr | expr ) ) + RPAR ) | - mintypmaxExpr | - expr ) - pathDecl = Group( ( pathDescr1 | pathDescr2 | pathDescr3 ) + EQ + pathDelayValue + SEMI ).setName("pathDecl") - - portConditionExpr = Forward() - portConditionTerm = Optional(unop) + subscrIdentifier - portConditionExpr << portConditionTerm + Optional( binop + portConditionExpr ) - polarityOp = oneOf("+ -") - levelSensitivePathDecl1 = Group( - if_ + Group(LPAR + portConditionExpr + RPAR) + - subscrIdentifier + Optional( polarityOp ) + "=>" + subscrIdentifier + EQ + - pathDelayValue + - SEMI ) - levelSensitivePathDecl2 = Group( - if_ + Group(LPAR + portConditionExpr + RPAR) + - LPAR + Group( delimitedList( subscrIdentifier ) ) + Optional( polarityOp ) + "*>" + - Group( delimitedList( subscrIdentifier ) ) + RPAR + EQ + - pathDelayValue + - SEMI ) - levelSensitivePathDecl = levelSensitivePathDecl1 | levelSensitivePathDecl2 - - edgeIdentifier = posedge | negedge - edgeSensitivePathDecl1 = Group( - Optional( if_ + Group(LPAR + expr + RPAR) ) + - LPAR + Optional( edgeIdentifier ) + - subscrIdentifier + "=>" + - LPAR + subscrIdentifier + Optional( polarityOp ) + COLON + expr + RPAR + RPAR + - EQ + - pathDelayValue + - SEMI ) - edgeSensitivePathDecl2 = Group( - Optional( if_ + Group(LPAR + expr + RPAR) ) + - LPAR + Optional( edgeIdentifier ) + - subscrIdentifier + "*>" + - LPAR + delimitedList( subscrIdentifier ) + Optional( polarityOp ) + COLON + expr + RPAR + RPAR + - EQ + - pathDelayValue + - SEMI ) - edgeSensitivePathDecl = edgeSensitivePathDecl1 | edgeSensitivePathDecl2 - - edgeDescr = oneOf("01 10 0x x1 1x x0").setName("edgeDescr") - - timCheckEventControl = Group( posedge | negedge | (edge + LBRACK + delimitedList( edgeDescr ) + RBRACK )) - timCheckCond = Forward() - timCondBinop = oneOf("== === != !==") - timCheckCondTerm = ( expr + timCondBinop + scalarConst ) | ( Optional("~") + expr ) - timCheckCond << ( ( LPAR + timCheckCond + RPAR ) | timCheckCondTerm ) - timCheckEvent = Group( Optional( timCheckEventControl ) + - subscrIdentifier + - Optional( "&&&" + timCheckCond ) ) - timCheckLimit = expr - controlledTimingCheckEvent = Group( timCheckEventControl + subscrIdentifier + - Optional( "&&&" + timCheckCond ) ) - notifyRegister = identifier - - systemTimingCheck1 = Group( "$setup" + - LPAR + timCheckEvent + COMMA + timCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck2 = Group( "$hold" + - LPAR + timCheckEvent + COMMA + timCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck3 = Group( "$period" + - LPAR + controlledTimingCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck4 = Group( "$width" + - LPAR + controlledTimingCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + expr + COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck5 = Group( "$skew" + - LPAR + timCheckEvent + COMMA + timCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck6 = Group( "$recovery" + - LPAR + controlledTimingCheckEvent + COMMA + timCheckEvent + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck7 = Group( "$setuphold" + - LPAR + timCheckEvent + COMMA + timCheckEvent + COMMA + timCheckLimit + COMMA + timCheckLimit + - Optional( COMMA + notifyRegister ) + RPAR + - SEMI ) - systemTimingCheck = (FollowedBy('$') + ( systemTimingCheck1 | systemTimingCheck2 | systemTimingCheck3 | - systemTimingCheck4 | systemTimingCheck5 | systemTimingCheck6 | systemTimingCheck7 )).setName("systemTimingCheck") - sdpd = if_ + Group(LPAR + expr + RPAR) + \ - ( pathDescr1 | pathDescr2 ) + EQ + pathDelayValue + SEMI - - specifyItem = ~Keyword("endspecify") +( - specparamDecl | - pathDecl | - levelSensitivePathDecl | - edgeSensitivePathDecl | - systemTimingCheck | - sdpd - ) - """ - x::= - x||= - x||= - x||= - x||= - x||= - """ - specifyBlock = Group( "specify" + ZeroOrMore( specifyItem ) + "endspecify" ).setName("specifyBlock") - - moduleItem = ~Keyword("endmodule") + ( - parameterDecl | - inputDecl | - outputDecl | - inoutDecl | - regDecl | - netDecl3 | - netDecl1 | - netDecl2 | - timeDecl | - integerDecl | - realDecl | - eventDecl | - gateDecl | - parameterOverride | - continuousAssign | - specifyBlock | - initialStmt | - alwaysStmt | - task | - functionDecl | - # these have to be at the end - they start with identifiers - moduleInstantiation | - udpInstantiation - ) - """ All possible moduleItems, from Verilog grammar spec - x::= - x||= - x||= - x||= - ?||= (spec does not seem consistent for this item) - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - x||= - """ - portRef = subscrIdentifier - portExpr = portRef | Group( LBRACE + delimitedList( portRef ) + RBRACE ) - port = portExpr | Group( ( DOT + identifier + LPAR + portExpr + RPAR ) ) - - moduleHdr = Group ( oneOf("module macromodule") + identifier + - Optional( LPAR + Group( Optional( delimitedList( - Group(oneOf("input output") + - (netDecl1Arg | netDecl2Arg | netDecl3Arg) ) | - port ) ) ) + - RPAR ) + SEMI ).setName("moduleHdr") - - module = Group( moduleHdr + - Group( ZeroOrMore( moduleItem ) ) + - "endmodule" ).setName("module")#.setDebug() - - udpDecl = outputDecl | inputDecl | regDecl - #~ udpInitVal = oneOf("1'b0 1'b1 1'bx 1'bX 1'B0 1'B1 1'Bx 1'BX 1 0 x X") - udpInitVal = (Regex("1'[bB][01xX]") | Regex("[01xX]")).setName("udpInitVal") - udpInitialStmt = Group( "initial" + - identifier + EQ + udpInitVal + SEMI ).setName("udpInitialStmt") - - levelSymbol = oneOf("0 1 x X ? b B") - levelInputList = Group( OneOrMore( levelSymbol ).setName("levelInpList") ) - outputSymbol = oneOf("0 1 x X") - combEntry = Group( levelInputList + COLON + outputSymbol + SEMI ) - edgeSymbol = oneOf("r R f F p P n N *") - edge = Group( LPAR + levelSymbol + levelSymbol + RPAR ) | \ - Group( edgeSymbol ) - edgeInputList = Group( ZeroOrMore( levelSymbol ) + edge + ZeroOrMore( levelSymbol ) ) - inputList = levelInputList | edgeInputList - seqEntry = Group( inputList + COLON + levelSymbol + COLON + ( outputSymbol | "-" ) + SEMI ).setName("seqEntry") - udpTableDefn = Group( "table" + - OneOrMore( combEntry | seqEntry ) + - "endtable" ).setName("table") - - """ - - ::= primitive ( <,>* ) ; - + - ? - - endprimitive - """ - udp = Group( "primitive" + identifier + - LPAR + Group( delimitedList( identifier ) ) + RPAR + SEMI + - OneOrMore( udpDecl ) + - Optional( udpInitialStmt ) + - udpTableDefn + - "endprimitive" ) - - verilogbnf = OneOrMore( module | udp ) + StringEnd() - - verilogbnf.ignore( cppStyleComment ) - verilogbnf.ignore( compilerDirective ) - - return verilogbnf - - -def test( strng ): - tokens = [] - try: - tokens = Verilog_BNF().parseString( strng ) - except ParseException as err: - print(err.line) - print(" "*(err.column-1) + "^") - print(err) - return tokens - - -#~ if __name__ == "__main__": -if 0: - import pprint - toptest = """ - module TOP( in, out ); - input [7:0] in; - output [5:0] out; - COUNT_BITS8 count_bits( .IN( in ), .C( out ) ); - endmodule""" - pprint.pprint( test(toptest).asList() ) - -else: - def main(): - print("Verilog parser test (V %s)" % __version__) - print(" - using pyparsing version", pyparsing.__version__) - print(" - using Python version", sys.version) - if packratOn: print(" - using packrat parsing") - if psycoOn: print(" - using psyco runtime optimization") - print() - - import os - import gc - - failCount = 0 - Verilog_BNF() - numlines = 0 - startTime = time.clock() - fileDir = "verilog" - #~ fileDir = "verilog/new" - #~ fileDir = "verilog/new2" - #~ fileDir = "verilog/new3" - allFiles = [f for f in os.listdir(fileDir) if f.endswith(".v")] - #~ allFiles = [ "list_path_delays_test.v" ] - #~ allFiles = [ "escapedIdent.v" ] - #~ allFiles = filter( lambda f : f.startswith("a") and f.endswith(".v"), os.listdir(fileDir) ) - #~ allFiles = filter( lambda f : f.startswith("c") and f.endswith(".v"), os.listdir(fileDir) ) - #~ allFiles = [ "ff.v" ] - - pp = pprint.PrettyPrinter( indent=2 ) - totalTime = 0 - for vfile in allFiles: - gc.collect() - fnam = fileDir + "/"+vfile - infile = open(fnam) - filelines = infile.readlines() - infile.close() - print(fnam, len(filelines), end=' ') - numlines += len(filelines) - teststr = "".join(filelines) - time1 = time.clock() - tokens = test( teststr ) - time2 = time.clock() - elapsed = time2-time1 - totalTime += elapsed - if ( len( tokens ) ): - print("OK", elapsed) - #~ print "tokens=" - #~ pp.pprint( tokens.asList() ) - #~ print - - ofnam = fileDir + "/parseOutput/" + vfile + ".parsed.txt" - outfile = open(ofnam,"w") - outfile.write( teststr ) - outfile.write("\n") - outfile.write("\n") - outfile.write(pp.pformat(tokens.asList())) - outfile.write("\n") - outfile.close() - else: - print("failed", elapsed) - failCount += 1 - for i,line in enumerate(filelines,1): - print("%4d: %s" % (i,line.rstrip())) - endTime = time.clock() - print("Total parse time:", totalTime) - print("Total source lines:", numlines) - print("Average lines/sec:", ( "%.1f" % (float(numlines)/(totalTime+.05 ) ) )) - if failCount: - print("FAIL - %d files failed to parse" % failCount) - else: - print("SUCCESS - all files parsed") - - return 0 - - #~ from line_profiler import LineProfiler - #~ from pyparsing import ParseResults - #~ lp = LineProfiler(ParseResults.__init__) - - main() - - #~ lp.print_stats() - #~ import hotshot - #~ p = hotshot.Profile("vparse.prof",1,1) - #~ p.start() - #~ main() - #~ p.stop() - #~ p.close() diff --git a/examples/withAttribute.py b/examples/withAttribute.py deleted file mode 100644 index 062c9ae..0000000 --- a/examples/withAttribute.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# withAttribute.py -# Copyright, 2007 - Paul McGuire -# -# Simple example of using withAttribute parse action helper -# to define -# -data = """\ -  49.950  -  50.950  -  51.950  - """ - -from pyparsing import * - -tdS,tdE = makeHTMLTags("TD") -fontS,fontE = makeHTMLTags("FONT") -realNum = Combine( Word(nums) + "." + Word(nums) ).setParseAction(lambda t:float(t[0])) -NBSP = Literal(" ") -patt = tdS + fontS + NBSP + realNum("value") + NBSP + fontE + tdE - -tdS.setParseAction( withAttribute(align="right",width="80") ) -for s in patt.searchString(data): - print(s.value) diff --git a/examples/wordsToNum.py b/examples/wordsToNum.py deleted file mode 100644 index 7cebbff..0000000 --- a/examples/wordsToNum.py +++ /dev/null @@ -1,106 +0,0 @@ -# wordsToNum.py -# Copyright 2006, Paul McGuire -# -# Sample parser grammar to read a number given in words, and return the numeric value. -# -from pyparsing import * -from operator import mul -from functools import reduce - -def makeLit(s,val): - ret = CaselessLiteral(s).setName(s) - return ret.setParseAction( replaceWith(val) ) - -unitDefinitions = [ - ("zero", 0), - ("oh", 0), - ("zip", 0), - ("zilch", 0), - ("nada", 0), - ("bupkis", 0), - ("one", 1), - ("two", 2), - ("three", 3), - ("four", 4), - ("five", 5), - ("six", 6), - ("seven", 7), - ("eight", 8), - ("nine", 9), - ("ten", 10), - ("eleven", 11), - ("twelve", 12), - ("thirteen", 13), - ("fourteen", 14), - ("fifteen", 15), - ("sixteen", 16), - ("seventeen", 17), - ("eighteen", 18), - ("nineteen", 19), - ] -units = Or(makeLit(s,v) for s,v in unitDefinitions) - -tensDefinitions = [ - ("ten", 10), - ("twenty", 20), - ("thirty", 30), - ("forty", 40), - ("fourty", 40), # for the spelling-challenged... - ("fifty", 50), - ("sixty", 60), - ("seventy", 70), - ("eighty", 80), - ("ninety", 90), - ] -tens = Or(makeLit(s,v) for s,v in tensDefinitions) - -hundreds = makeLit("hundred", 100) - -majorDefinitions = [ - ("thousand", int(1e3)), - ("million", int(1e6)), - ("billion", int(1e9)), - ("trillion", int(1e12)), - ("quadrillion", int(1e15)), - ("quintillion", int(1e18)), - ] -mag = Or(makeLit(s,v) for s,v in majorDefinitions) - -wordprod = lambda t: reduce(mul,t) -wordsum = lambda t: sum(t) -numPart = (((( units + Optional(hundreds) ).setParseAction(wordprod) + - Optional(tens)).setParseAction(wordsum) - ^ tens ) - + Optional(units) ).setParseAction(wordsum) -numWords = OneOrMore( (numPart + Optional(mag)).setParseAction(wordprod) - ).setParseAction(wordsum) + StringEnd() -numWords.ignore(Literal("-")) -numWords.ignore(CaselessLiteral("and")) - -def test(s,expected): - try: - fail_expected = (expected is None) - success, results_tup = numWords.runTests(s, failureTests=fail_expected) - assert success, "Failed test!" - if not fail_expected: - teststr, results = results_tup[0] - observed = results[0] - assert expected == observed, "incorrect parsed value, {} -> {}, should be {}".format(teststr, observed, expected) - except Exception as exc: - print("{}: {}".format(type(exc).__name__, exc)) - -test("one hundred twenty hundred", None) -test("one hundred and twennty", None) -test("one hundred and twenty", 120) -test("one hundred and three", 103) -test("one hundred twenty-three", 123) -test("one hundred and twenty three", 123) -test("one hundred twenty three million", 123000000) -test("one hundred and twenty three million", 123000000) -test("one hundred twenty three million and three", 123000003) -test("fifteen hundred and sixty five", 1565) -test("seventy-seven thousand eight hundred and nineteen", 77819) -test("seven hundred seventy-seven thousand seven hundred and seventy-seven", 777777) -test("zero", 0) -test("forty two", 42) -test("fourty two", 42) \ No newline at end of file diff --git a/htmldoc/api-objects.txt b/htmldoc/api-objects.txt deleted file mode 100644 index 52e9517..0000000 --- a/htmldoc/api-objects.txt +++ /dev/null @@ -1,2944 +0,0 @@ -pyparsing pyparsing-module.html -pyparsing.removeQuotes pyparsing-module.html#removeQuotes -pyparsing.alphanums pyparsing-module.html#alphanums -pyparsing._bslash pyparsing-module.html#_bslash -pyparsing._escapedPunc pyparsing-module.html#_escapedPunc -pyparsing._escapedOctChar pyparsing-module.html#_escapedOctChar -pyparsing.PY_3 pyparsing-module.html#PY_3 -pyparsing._trim_arity pyparsing-module.html#_trim_arity -pyparsing.infixNotation pyparsing-module.html#infixNotation -pyparsing._defaultStartDebugAction pyparsing-module.html#_defaultStartDebugAction -pyparsing._charRange pyparsing-module.html#_charRange -pyparsing.withClass pyparsing-module.html#withClass -pyparsing.delimitedList pyparsing-module.html#delimitedList -pyparsing.lineEnd pyparsing-module.html#lineEnd -pyparsing.dictOf pyparsing-module.html#dictOf -pyparsing.makeHTMLTags pyparsing-module.html#makeHTMLTags -pyparsing.commaSeparatedList pyparsing-module.html#commaSeparatedList -pyparsing.stringStart pyparsing-module.html#stringStart -pyparsing._makeTags pyparsing-module.html#_makeTags -pyparsing._reBracketExpr pyparsing-module.html#_reBracketExpr -pyparsing.oneOf pyparsing-module.html#oneOf -pyparsing._flatten pyparsing-module.html#_flatten -pyparsing.pythonStyleComment pyparsing-module.html#pythonStyleComment -pyparsing.__versionTime__ pyparsing-module.html#__versionTime__ -pyparsing._ustr pyparsing-module.html#_ustr -pyparsing.matchPreviousExpr pyparsing-module.html#matchPreviousExpr -pyparsing.matchOnlyAtCol pyparsing-module.html#matchOnlyAtCol -pyparsing.cStyleComment pyparsing-module.html#cStyleComment -pyparsing.downcaseTokens pyparsing-module.html#downcaseTokens -pyparsing._commasepitem pyparsing-module.html#_commasepitem -pyparsing._defaultSuccessDebugAction pyparsing-module.html#_defaultSuccessDebugAction -pyparsing.lineno pyparsing-module.html#lineno -pyparsing.replaceWith pyparsing-module.html#replaceWith -pyparsing.alphas8bit pyparsing-module.html#alphas8bit -pyparsing._escapeRegexRangeChars pyparsing-module.html#_escapeRegexRangeChars -pyparsing._singleChar pyparsing-module.html#_singleChar -pyparsing.unicodeString pyparsing-module.html#unicodeString -pyparsing.alphas pyparsing-module.html#alphas -pyparsing.javaStyleComment pyparsing-module.html#javaStyleComment -pyparsing.stringEnd pyparsing-module.html#stringEnd -pyparsing.anyCloseTag pyparsing-module.html#anyCloseTag -pyparsing.cppStyleComment pyparsing-module.html#cppStyleComment -pyparsing.col pyparsing-module.html#col -pyparsing.originalTextFor pyparsing-module.html#originalTextFor -pyparsing._optionalNotMatched pyparsing-module.html#_optionalNotMatched -pyparsing.makeXMLTags pyparsing-module.html#makeXMLTags -pyparsing.singleArgBuiltins pyparsing-module.html#singleArgBuiltins -pyparsing.traceParseAction pyparsing-module.html#traceParseAction -pyparsing.quotedString pyparsing-module.html#quotedString -pyparsing.tokenMap pyparsing-module.html#tokenMap -pyparsing.withAttribute pyparsing-module.html#withAttribute -pyparsing.lineStart pyparsing-module.html#lineStart -pyparsing.matchPreviousLiteral pyparsing-module.html#matchPreviousLiteral -pyparsing.empty pyparsing-module.html#empty -pyparsing._htmlEntityMap pyparsing-module.html#_htmlEntityMap -pyparsing.ungroup pyparsing-module.html#ungroup -pyparsing.anyOpenTag pyparsing-module.html#anyOpenTag -pyparsing.line pyparsing-module.html#line -pyparsing.system_version pyparsing-module.html#system_version -pyparsing.operatorPrecedence pyparsing-module.html#operatorPrecedence -pyparsing.__doc__ pyparsing-module.html#__doc__ -pyparsing.upcaseTokens pyparsing-module.html#upcaseTokens -pyparsing.opAssoc pyparsing-module.html#opAssoc -pyparsing.punc8bit pyparsing-module.html#punc8bit -pyparsing.locatedExpr pyparsing-module.html#locatedExpr -pyparsing.sglQuotedString pyparsing-module.html#sglQuotedString -pyparsing.srange pyparsing-module.html#srange -pyparsing.dblSlashComment pyparsing-module.html#dblSlashComment -pyparsing._defaultExceptionDebugAction pyparsing-module.html#_defaultExceptionDebugAction -pyparsing.nullDebugAction pyparsing-module.html#nullDebugAction -pyparsing.unichr pyparsing-module.html#unichr -pyparsing.dblQuotedString pyparsing-module.html#dblQuotedString -pyparsing.commonHTMLEntity pyparsing-module.html#commonHTMLEntity -pyparsing.__package__ pyparsing-module.html#__package__ -pyparsing.fname pyparsing-module.html#fname -pyparsing.nestedExpr pyparsing-module.html#nestedExpr -pyparsing.htmlComment pyparsing-module.html#htmlComment -pyparsing.nums pyparsing-module.html#nums -pyparsing.countedArray pyparsing-module.html#countedArray -pyparsing.restOfLine pyparsing-module.html#restOfLine -pyparsing._xml_escape pyparsing-module.html#_xml_escape -pyparsing._MAX_INT pyparsing-module.html#_MAX_INT -pyparsing._escapedHexChar pyparsing-module.html#_escapedHexChar -pyparsing.hexnums pyparsing-module.html#hexnums -pyparsing.indentedBlock pyparsing-module.html#indentedBlock -pyparsing.replaceHTMLEntity pyparsing-module.html#replaceHTMLEntity -pyparsing.printables pyparsing-module.html#printables -pyparsing.And pyparsing.And-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.And.__str__ pyparsing.And-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParseExpression.append pyparsing.ParseExpression-class.html#append -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.And.__slotnames__ pyparsing.And-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.And.parseImpl pyparsing.And-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.And.__init__ pyparsing.And-class.html#__init__ -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParseExpression.leaveWhitespace pyparsing.ParseExpression-class.html#leaveWhitespace -pyparsing.ParseExpression.__getitem__ pyparsing.ParseExpression-class.html#__getitem__ -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParseExpression.setResultsName pyparsing.ParseExpression-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseExpression.streamline pyparsing.ParseExpression-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseExpression.validate pyparsing.ParseExpression-class.html#validate -pyparsing.ParseExpression.copy pyparsing.ParseExpression-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.And.__iadd__ pyparsing.And-class.html#__iadd__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseExpression.ignore pyparsing.ParseExpression-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.And.checkRecursion pyparsing.And-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.CaselessKeyword pyparsing.CaselessKeyword-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.CaselessKeyword.__init__ pyparsing.CaselessKeyword-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.Keyword.setDefaultKeywordChars pyparsing.Keyword-class.html#setDefaultKeywordChars -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.CaselessKeyword.parseImpl pyparsing.CaselessKeyword-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.Keyword.DEFAULT_KEYWORD_CHARS pyparsing.Keyword-class.html#DEFAULT_KEYWORD_CHARS -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.Keyword.copy pyparsing.Keyword-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.CaselessLiteral pyparsing.CaselessLiteral-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.CaselessLiteral.__init__ pyparsing.CaselessLiteral-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Literal.__slotnames__ pyparsing.Literal-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.CaselessLiteral.parseImpl pyparsing.CaselessLiteral-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.CharsNotIn pyparsing.CharsNotIn-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.CharsNotIn.__str__ pyparsing.CharsNotIn-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.CharsNotIn.__init__ pyparsing.CharsNotIn-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.CharsNotIn.parseImpl pyparsing.CharsNotIn-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.CloseMatch pyparsing.CloseMatch-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.CloseMatch.__init__ pyparsing.CloseMatch-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.CloseMatch.parseImpl pyparsing.CloseMatch-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Combine pyparsing.Combine-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Combine.__init__ pyparsing.Combine-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Combine.__slotnames__ pyparsing.Combine-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.Combine.postParse pyparsing.Combine-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.Combine.ignore pyparsing.Combine-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Dict pyparsing.Dict-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Dict.__init__ pyparsing.Dict-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Dict.__slotnames__ pyparsing.Dict-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.Dict.postParse pyparsing.Dict-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Each pyparsing.Each-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.Each.__str__ pyparsing.Each-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParseExpression.append pyparsing.ParseExpression-class.html#append -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Each.parseImpl pyparsing.Each-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.Each.__init__ pyparsing.Each-class.html#__init__ -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParseExpression.leaveWhitespace pyparsing.ParseExpression-class.html#leaveWhitespace -pyparsing.ParseExpression.__getitem__ pyparsing.ParseExpression-class.html#__getitem__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParseExpression.setResultsName pyparsing.ParseExpression-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseExpression.streamline pyparsing.ParseExpression-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseExpression.validate pyparsing.ParseExpression-class.html#validate -pyparsing.ParseExpression.copy pyparsing.ParseExpression-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseExpression.ignore pyparsing.ParseExpression-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.Each.checkRecursion pyparsing.Each-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Empty pyparsing.Empty-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Empty.__init__ pyparsing.Empty-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParserElement.parseImpl pyparsing.ParserElement-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.FollowedBy pyparsing.FollowedBy-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.FollowedBy.__init__ pyparsing.FollowedBy-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.FollowedBy.parseImpl pyparsing.FollowedBy-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Forward pyparsing.Forward-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.Forward.__str__ pyparsing.Forward-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Forward.__init__ pyparsing.Forward-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.Forward.leaveWhitespace pyparsing.Forward-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.Forward.streamline pyparsing.Forward-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.Forward.__lshift__ pyparsing.Forward-class.html#__lshift__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.Forward.validate pyparsing.Forward-class.html#validate -pyparsing.Forward.copy pyparsing.Forward-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.Forward.__ilshift__ pyparsing.Forward-class.html#__ilshift__ -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.GoToColumn pyparsing.GoToColumn-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.GoToColumn.__init__ pyparsing.GoToColumn-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.GoToColumn.parseImpl pyparsing.GoToColumn-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.GoToColumn.preParse pyparsing.GoToColumn-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Group pyparsing.Group-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Group.__init__ pyparsing.Group-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Group.__slotnames__ pyparsing.Group-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.Group.postParse pyparsing.Group-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Keyword pyparsing.Keyword-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Keyword.__init__ pyparsing.Keyword-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.Keyword.setDefaultKeywordChars pyparsing.Keyword-class.html#setDefaultKeywordChars -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Keyword.parseImpl pyparsing.Keyword-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.Keyword.DEFAULT_KEYWORD_CHARS pyparsing.Keyword-class.html#DEFAULT_KEYWORD_CHARS -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.Keyword.copy pyparsing.Keyword-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.LineEnd pyparsing.LineEnd-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.LineEnd.__init__ pyparsing.LineEnd-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.LineEnd.__slotnames__ pyparsing.LineEnd-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.LineEnd.parseImpl pyparsing.LineEnd-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.LineStart pyparsing.LineStart-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.LineStart.__init__ pyparsing.LineStart-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.LineStart.parseImpl pyparsing.LineStart-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Literal pyparsing.Literal-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Literal.__init__ pyparsing.Literal-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Literal.__slotnames__ pyparsing.Literal-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Literal.parseImpl pyparsing.Literal-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.MatchFirst pyparsing.MatchFirst-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.MatchFirst.__str__ pyparsing.MatchFirst-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParseExpression.append pyparsing.ParseExpression-class.html#append -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.MatchFirst.__slotnames__ pyparsing.MatchFirst-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.MatchFirst.parseImpl pyparsing.MatchFirst-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.MatchFirst.__init__ pyparsing.MatchFirst-class.html#__init__ -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParseExpression.leaveWhitespace pyparsing.ParseExpression-class.html#leaveWhitespace -pyparsing.ParseExpression.__getitem__ pyparsing.ParseExpression-class.html#__getitem__ -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParseExpression.setResultsName pyparsing.ParseExpression-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseExpression.streamline pyparsing.ParseExpression-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseExpression.validate pyparsing.ParseExpression-class.html#validate -pyparsing.ParseExpression.copy pyparsing.ParseExpression-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseExpression.ignore pyparsing.ParseExpression-class.html#ignore -pyparsing.MatchFirst.__ior__ pyparsing.MatchFirst-class.html#__ior__ -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.MatchFirst.checkRecursion pyparsing.MatchFirst-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.NoMatch pyparsing.NoMatch-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.NoMatch.__init__ pyparsing.NoMatch-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.NoMatch.parseImpl pyparsing.NoMatch-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.NotAny pyparsing.NotAny-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.NotAny.__str__ pyparsing.NotAny-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.NotAny.__init__ pyparsing.NotAny-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.NotAny.__slotnames__ pyparsing.NotAny-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.NotAny.parseImpl pyparsing.NotAny-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.OneOrMore pyparsing.OneOrMore-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.OneOrMore.__str__ pyparsing.OneOrMore-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.OneOrMore.__slotnames__ pyparsing.OneOrMore-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.OnlyOnce pyparsing.OnlyOnce-class.html -pyparsing.OnlyOnce.reset pyparsing.OnlyOnce-class.html#reset -pyparsing.OnlyOnce.__call__ pyparsing.OnlyOnce-class.html#__call__ -pyparsing.OnlyOnce.__init__ pyparsing.OnlyOnce-class.html#__init__ -pyparsing.Optional pyparsing.Optional-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.Optional.__str__ pyparsing.Optional-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Optional.__init__ pyparsing.Optional-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Optional.__slotnames__ pyparsing.Optional-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Optional.parseImpl pyparsing.Optional-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Or pyparsing.Or-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.Or.__str__ pyparsing.Or-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParseExpression.append pyparsing.ParseExpression-class.html#append -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Or.parseImpl pyparsing.Or-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.Or.__init__ pyparsing.Or-class.html#__init__ -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.Or.__ixor__ pyparsing.Or-class.html#__ixor__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParseExpression.leaveWhitespace pyparsing.ParseExpression-class.html#leaveWhitespace -pyparsing.ParseExpression.__getitem__ pyparsing.ParseExpression-class.html#__getitem__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParseExpression.setResultsName pyparsing.ParseExpression-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseExpression.streamline pyparsing.ParseExpression-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseExpression.validate pyparsing.ParseExpression-class.html#validate -pyparsing.ParseExpression.copy pyparsing.ParseExpression-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseExpression.ignore pyparsing.ParseExpression-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.Or.checkRecursion pyparsing.Or-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.ParseBaseException pyparsing.ParseBaseException-class.html -pyparsing.ParseBaseException.__str__ pyparsing.ParseBaseException-class.html#__str__ -pyparsing.ParseBaseException.__init__ pyparsing.ParseBaseException-class.html#__init__ -pyparsing.ParseBaseException.__getattr__ pyparsing.ParseBaseException-class.html#__getattr__ -pyparsing.ParseBaseException.__dir__ pyparsing.ParseBaseException-class.html#__dir__ -pyparsing.ParseBaseException.markInputline pyparsing.ParseBaseException-class.html#markInputline -pyparsing.ParseBaseException.__repr__ pyparsing.ParseBaseException-class.html#__repr__ -pyparsing.ParseBaseException._from_exception pyparsing.ParseBaseException-class.html#_from_exception -pyparsing.ParseElementEnhance pyparsing.ParseElementEnhance-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParseElementEnhance.__init__ pyparsing.ParseElementEnhance-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.ParseException pyparsing.ParseException-class.html -pyparsing.ParseBaseException.__str__ pyparsing.ParseBaseException-class.html#__str__ -pyparsing.ParseBaseException.__init__ pyparsing.ParseBaseException-class.html#__init__ -pyparsing.ParseBaseException.__getattr__ pyparsing.ParseBaseException-class.html#__getattr__ -pyparsing.ParseBaseException.__dir__ pyparsing.ParseBaseException-class.html#__dir__ -pyparsing.ParseBaseException.markInputline pyparsing.ParseBaseException-class.html#markInputline -pyparsing.ParseBaseException.__repr__ pyparsing.ParseBaseException-class.html#__repr__ -pyparsing.ParseBaseException._from_exception pyparsing.ParseBaseException-class.html#_from_exception -pyparsing.ParseExpression pyparsing.ParseExpression-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseExpression.__str__ pyparsing.ParseExpression-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParseExpression.__init__ pyparsing.ParseExpression-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParserElement.parseImpl pyparsing.ParserElement-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParseExpression.append pyparsing.ParseExpression-class.html#append -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParseExpression.leaveWhitespace pyparsing.ParseExpression-class.html#leaveWhitespace -pyparsing.ParseExpression.__getitem__ pyparsing.ParseExpression-class.html#__getitem__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParseExpression.setResultsName pyparsing.ParseExpression-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseExpression.streamline pyparsing.ParseExpression-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseExpression.validate pyparsing.ParseExpression-class.html#validate -pyparsing.ParseExpression.copy pyparsing.ParseExpression-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseExpression.ignore pyparsing.ParseExpression-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.ParseFatalException pyparsing.ParseFatalException-class.html -pyparsing.ParseBaseException.__str__ pyparsing.ParseBaseException-class.html#__str__ -pyparsing.ParseBaseException.__init__ pyparsing.ParseBaseException-class.html#__init__ -pyparsing.ParseBaseException.__getattr__ pyparsing.ParseBaseException-class.html#__getattr__ -pyparsing.ParseBaseException.__dir__ pyparsing.ParseBaseException-class.html#__dir__ -pyparsing.ParseBaseException.markInputline pyparsing.ParseBaseException-class.html#markInputline -pyparsing.ParseBaseException.__repr__ pyparsing.ParseBaseException-class.html#__repr__ -pyparsing.ParseBaseException._from_exception pyparsing.ParseBaseException-class.html#_from_exception -pyparsing.ParseResults pyparsing.ParseResults-class.html -pyparsing.ParseResults.haskeys pyparsing.ParseResults-class.html#haskeys -pyparsing.ParseResults.asXML pyparsing.ParseResults-class.html#asXML -pyparsing.ParseResults.dump pyparsing.ParseResults-class.html#dump -pyparsing.ParseResults.__str__ pyparsing.ParseResults-class.html#__str__ -pyparsing.ParseResults.pop pyparsing.ParseResults-class.html#pop -pyparsing.ParseResults.__radd__ pyparsing.ParseResults-class.html#__radd__ -pyparsing.ParseResults.__getnewargs__ pyparsing.ParseResults-class.html#__getnewargs__ -pyparsing.ParseResults.__init__ pyparsing.ParseResults-class.html#__init__ -pyparsing.ParseResults.__lookup pyparsing.ParseResults-class.html#__lookup -pyparsing.ParseResults.__new__ pyparsing.ParseResults-class.html#__new__ -pyparsing.ParseResults.__contains__ pyparsing.ParseResults-class.html#__contains__ -pyparsing.ParseResults.getName pyparsing.ParseResults-class.html#getName -pyparsing.ParseResults.pprint pyparsing.ParseResults-class.html#pprint -pyparsing.ParseResults._asStringList pyparsing.ParseResults-class.html#_asStringList -pyparsing.ParseResults.__getattr__ pyparsing.ParseResults-class.html#__getattr__ -pyparsing.ParseResults.append pyparsing.ParseResults-class.html#append -pyparsing.ParseResults.itervalues pyparsing.ParseResults-class.html#itervalues -pyparsing.ParseResults.__getstate__ pyparsing.ParseResults-class.html#__getstate__ -pyparsing.ParseResults._iterkeys pyparsing.ParseResults-class.html#_iterkeys -pyparsing.ParseResults.__len__ pyparsing.ParseResults-class.html#__len__ -pyparsing.ParseResults._iteritems pyparsing.ParseResults-class.html#_iteritems -pyparsing.ParseResults.__getitem__ pyparsing.ParseResults-class.html#__getitem__ -pyparsing.ParseResults.get pyparsing.ParseResults-class.html#get -pyparsing.ParseResults.keys pyparsing.ParseResults-class.html#keys -pyparsing.ParseResults.__iter__ pyparsing.ParseResults-class.html#__iter__ -pyparsing.ParseResults.__add__ pyparsing.ParseResults-class.html#__add__ -pyparsing.ParseResults.iteritems pyparsing.ParseResults-class.html#iteritems -pyparsing.ParseResults.__bool__ pyparsing.ParseResults-class.html#__bool__ -pyparsing.ParseResults.copy pyparsing.ParseResults-class.html#copy -pyparsing.ParseResults.iterkeys pyparsing.ParseResults-class.html#iterkeys -pyparsing.ParseResults.asList pyparsing.ParseResults-class.html#asList -pyparsing.ParseResults.extend pyparsing.ParseResults-class.html#extend -pyparsing.ParseResults.__delitem__ pyparsing.ParseResults-class.html#__delitem__ -pyparsing.ParseResults.__reversed__ pyparsing.ParseResults-class.html#__reversed__ -pyparsing.ParseResults.__nonzero__ pyparsing.ParseResults-class.html#__nonzero__ -pyparsing.ParseResults._itervalues pyparsing.ParseResults-class.html#_itervalues -pyparsing.ParseResults.__setstate__ pyparsing.ParseResults-class.html#__setstate__ -pyparsing.ParseResults.insert pyparsing.ParseResults-class.html#insert -pyparsing.ParseResults.__setitem__ pyparsing.ParseResults-class.html#__setitem__ -pyparsing.ParseResults.__iadd__ pyparsing.ParseResults-class.html#__iadd__ -pyparsing.ParseResults.values pyparsing.ParseResults-class.html#values -pyparsing.ParseResults.__repr__ pyparsing.ParseResults-class.html#__repr__ -pyparsing.ParseResults.asDict pyparsing.ParseResults-class.html#asDict -pyparsing.ParseResults.items pyparsing.ParseResults-class.html#items -pyparsing.ParseResults.__dir__ pyparsing.ParseResults-class.html#__dir__ -pyparsing.ParseResults.clear pyparsing.ParseResults-class.html#clear -pyparsing.ParseSyntaxException pyparsing.ParseSyntaxException-class.html -pyparsing.ParseBaseException.__str__ pyparsing.ParseBaseException-class.html#__str__ -pyparsing.ParseBaseException.__init__ pyparsing.ParseBaseException-class.html#__init__ -pyparsing.ParseBaseException.__getattr__ pyparsing.ParseBaseException-class.html#__getattr__ -pyparsing.ParseBaseException.__dir__ pyparsing.ParseBaseException-class.html#__dir__ -pyparsing.ParseBaseException.markInputline pyparsing.ParseBaseException-class.html#markInputline -pyparsing.ParseBaseException.__repr__ pyparsing.ParseBaseException-class.html#__repr__ -pyparsing.ParseBaseException._from_exception pyparsing.ParseBaseException-class.html#_from_exception -pyparsing.ParserElement pyparsing.ParserElement-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ParserElement.__init__ pyparsing.ParserElement-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParserElement.parseImpl pyparsing.ParserElement-class.html#parseImpl -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.QuotedString pyparsing.QuotedString-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.QuotedString.__str__ pyparsing.QuotedString-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.QuotedString.__init__ pyparsing.QuotedString-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.QuotedString.parseImpl pyparsing.QuotedString-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.RecursiveGrammarException pyparsing.RecursiveGrammarException-class.html -pyparsing.RecursiveGrammarException.__str__ pyparsing.RecursiveGrammarException-class.html#__str__ -pyparsing.RecursiveGrammarException.__init__ pyparsing.RecursiveGrammarException-class.html#__init__ -pyparsing.Regex pyparsing.Regex-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.Regex.__str__ pyparsing.Regex-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Regex.__init__ pyparsing.Regex-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Regex.__slotnames__ pyparsing.Regex-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.Regex.compiledREtype pyparsing.Regex.compiledREtype-class.html -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Regex.parseImpl pyparsing.Regex-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Regex.compiledREtype pyparsing.Regex.compiledREtype-class.html -pyparsing.Regex.compiledREtype.finditer pyparsing.Regex.compiledREtype-class.html#finditer -pyparsing.Regex.compiledREtype.scanner pyparsing.Regex.compiledREtype-class.html#scanner -pyparsing.Regex.compiledREtype.subn pyparsing.Regex.compiledREtype-class.html#subn -pyparsing.Regex.compiledREtype.groupindex pyparsing.Regex.compiledREtype-class.html#groupindex -pyparsing.Regex.compiledREtype.findall pyparsing.Regex.compiledREtype-class.html#findall -pyparsing.Regex.compiledREtype.sub pyparsing.Regex.compiledREtype-class.html#sub -pyparsing.Regex.compiledREtype.pattern pyparsing.Regex.compiledREtype-class.html#pattern -pyparsing.Regex.compiledREtype.split pyparsing.Regex.compiledREtype-class.html#split -pyparsing.Regex.compiledREtype.match pyparsing.Regex.compiledREtype-class.html#match -pyparsing.Regex.compiledREtype.__deepcopy__ pyparsing.Regex.compiledREtype-class.html#__deepcopy__ -pyparsing.Regex.compiledREtype.groups pyparsing.Regex.compiledREtype-class.html#groups -pyparsing.Regex.compiledREtype.search pyparsing.Regex.compiledREtype-class.html#search -pyparsing.Regex.compiledREtype.flags pyparsing.Regex.compiledREtype-class.html#flags -pyparsing.Regex.compiledREtype.__copy__ pyparsing.Regex.compiledREtype-class.html#__copy__ -pyparsing.SkipTo pyparsing.SkipTo-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.SkipTo.__init__ pyparsing.SkipTo-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.SkipTo.parseImpl pyparsing.SkipTo-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.StringEnd pyparsing.StringEnd-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.StringEnd.__init__ pyparsing.StringEnd-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.StringEnd.parseImpl pyparsing.StringEnd-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.StringStart pyparsing.StringStart-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.StringStart.__init__ pyparsing.StringStart-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.StringStart.parseImpl pyparsing.StringStart-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Suppress pyparsing.Suppress-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.TokenConverter.__init__ pyparsing.TokenConverter-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Suppress.__slotnames__ pyparsing.Suppress-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.Suppress.postParse pyparsing.Suppress-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.Suppress.suppress pyparsing.Suppress-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Token pyparsing.Token-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Token.__init__ pyparsing.Token-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParserElement.parseImpl pyparsing.ParserElement-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.TokenConverter pyparsing.TokenConverter-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParseElementEnhance.__str__ pyparsing.ParseElementEnhance-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.TokenConverter.__init__ pyparsing.TokenConverter-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ParseElementEnhance.parseImpl pyparsing.ParseElementEnhance-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.White pyparsing.White-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.White.__init__ pyparsing.White-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.White.__slotnames__ pyparsing.White-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.White.parseImpl pyparsing.White-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.White.whiteStrs pyparsing.White-class.html#whiteStrs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.Word pyparsing.Word-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.Word.__str__ pyparsing.Word-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.Word.__init__ pyparsing.Word-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.Word.__slotnames__ pyparsing.Word-class.html#__slotnames__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.Word.parseImpl pyparsing.Word-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.WordEnd pyparsing.WordEnd-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.WordEnd.__init__ pyparsing.WordEnd-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.WordEnd.parseImpl pyparsing.WordEnd-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.WordStart pyparsing.WordStart-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.WordStart.__init__ pyparsing.WordStart-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.WordStart.parseImpl pyparsing.WordStart-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.__str__ pyparsing.ParserElement-class.html#__str__ -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParserElement.leaveWhitespace pyparsing.ParserElement-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParserElement.ignore pyparsing.ParserElement-class.html#ignore -pyparsing.ParserElement.validate pyparsing.ParserElement-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.streamline pyparsing.ParserElement-class.html#streamline -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParserElement.checkRecursion pyparsing.ParserElement-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.ZeroOrMore pyparsing.ZeroOrMore-class.html -pyparsing.ParserElement._parseCache pyparsing.ParserElement-class.html#_parseCache -pyparsing.ParserElement.__ror__ pyparsing.ParserElement-class.html#__ror__ -pyparsing.ZeroOrMore.__str__ pyparsing.ZeroOrMore-class.html#__str__ -pyparsing.ParserElement.resetCache pyparsing.ParserElement-class.html#resetCache -pyparsing.ParserElement.__radd__ pyparsing.ParserElement-class.html#__radd__ -pyparsing.ParserElement._parseNoCache pyparsing.ParserElement-class.html#_parseNoCache -pyparsing.ParserElement.__rmul__ pyparsing.ParserElement-class.html#__rmul__ -pyparsing.ParserElement.__rsub__ pyparsing.ParserElement-class.html#__rsub__ -pyparsing.ParserElement.inlineLiteralsUsing pyparsing.ParserElement-class.html#inlineLiteralsUsing -pyparsing.ParserElement.__and__ pyparsing.ParserElement-class.html#__and__ -pyparsing.ZeroOrMore.__init__ pyparsing.ZeroOrMore-class.html#__init__ -pyparsing.ParserElement.setFailAction pyparsing.ParserElement-class.html#setFailAction -pyparsing.ParserElement.transformString pyparsing.ParserElement-class.html#transformString -pyparsing.ParserElement.__rand__ pyparsing.ParserElement-class.html#__rand__ -pyparsing.ParserElement.parseString pyparsing.ParserElement-class.html#parseString -pyparsing.ParserElement.packrat_cache pyparsing.ParserElement-class.html#packrat_cache -pyparsing.ParserElement.__req__ pyparsing.ParserElement-class.html#__req__ -pyparsing.ParserElement.__xor__ pyparsing.ParserElement-class.html#__xor__ -pyparsing.ParserElement.setDefaultWhitespaceChars pyparsing.ParserElement-class.html#setDefaultWhitespaceChars -pyparsing.ParserElement._packratEnabled pyparsing.ParserElement-class.html#_packratEnabled -pyparsing.ZeroOrMore.parseImpl pyparsing.ZeroOrMore-class.html#parseImpl -pyparsing.ParserElement.__invert__ pyparsing.ParserElement-class.html#__invert__ -pyparsing.ParserElement.packrat_cache_lock pyparsing.ParserElement-class.html#packrat_cache_lock -pyparsing.ParserElement.postParse pyparsing.ParserElement-class.html#postParse -pyparsing.ParserElement.__call__ pyparsing.ParserElement-class.html#__call__ -pyparsing.ParserElement.addParseAction pyparsing.ParserElement-class.html#addParseAction -pyparsing.ParserElement.setWhitespaceChars pyparsing.ParserElement-class.html#setWhitespaceChars -pyparsing.ParserElement.split pyparsing.ParserElement-class.html#split -pyparsing.ParserElement.__ne__ pyparsing.ParserElement-class.html#__ne__ -pyparsing.ParseElementEnhance.leaveWhitespace pyparsing.ParseElementEnhance-class.html#leaveWhitespace -pyparsing.ParserElement.setName pyparsing.ParserElement-class.html#setName -pyparsing.ParserElement.matches pyparsing.ParserElement-class.html#matches -pyparsing.ParserElement.suppress pyparsing.ParserElement-class.html#suppress -pyparsing.ParserElement.enablePackrat pyparsing.ParserElement-class.html#enablePackrat -pyparsing.ParserElement.packrat_cache_stats pyparsing.ParserElement-class.html#packrat_cache_stats -pyparsing.ParserElement.setResultsName pyparsing.ParserElement-class.html#setResultsName -pyparsing.ParserElement.parseFile pyparsing.ParserElement-class.html#parseFile -pyparsing.ParserElement.addCondition pyparsing.ParserElement-class.html#addCondition -pyparsing.ParseElementEnhance.streamline pyparsing.ParseElementEnhance-class.html#streamline -pyparsing.ParserElement.__or__ pyparsing.ParserElement-class.html#__or__ -pyparsing.ParserElement.__add__ pyparsing.ParserElement-class.html#__add__ -pyparsing.ParserElement.__sub__ pyparsing.ParserElement-class.html#__sub__ -pyparsing.ParserElement.tryParse pyparsing.ParserElement-class.html#tryParse -pyparsing.ParseElementEnhance.validate pyparsing.ParseElementEnhance-class.html#validate -pyparsing.ParserElement.copy pyparsing.ParserElement-class.html#copy -pyparsing.ParserElement.__eq__ pyparsing.ParserElement-class.html#__eq__ -pyparsing.ParserElement.__rxor__ pyparsing.ParserElement-class.html#__rxor__ -pyparsing.ParserElement.runTests pyparsing.ParserElement-class.html#runTests -pyparsing.ParserElement.DEFAULT_WHITE_CHARS pyparsing.ParserElement-class.html#DEFAULT_WHITE_CHARS -pyparsing.ParserElement.parseWithTabs pyparsing.ParserElement-class.html#parseWithTabs -pyparsing.ParserElement.searchString pyparsing.ParserElement-class.html#searchString -pyparsing.ParserElement.scanString pyparsing.ParserElement-class.html#scanString -pyparsing.ParserElement.setParseAction pyparsing.ParserElement-class.html#setParseAction -pyparsing.ParserElement.preParse pyparsing.ParserElement-class.html#preParse -pyparsing.ParserElement.setDebug pyparsing.ParserElement-class.html#setDebug -pyparsing.ParserElement.__rne__ pyparsing.ParserElement-class.html#__rne__ -pyparsing.ParserElement.setBreak pyparsing.ParserElement-class.html#setBreak -pyparsing.ParseElementEnhance.ignore pyparsing.ParseElementEnhance-class.html#ignore -pyparsing.ParserElement.setDebugActions pyparsing.ParserElement-class.html#setDebugActions -pyparsing.ParserElement.__mul__ pyparsing.ParserElement-class.html#__mul__ -pyparsing.ParserElement.__repr__ pyparsing.ParserElement-class.html#__repr__ -pyparsing.ParseElementEnhance.checkRecursion pyparsing.ParseElementEnhance-class.html#checkRecursion -pyparsing.ParserElement.__hash__ pyparsing.ParserElement-class.html#__hash__ -pyparsing.ParserElement.canParseNext pyparsing.ParserElement-class.html#canParseNext -pyparsing.ParserElement._parse pyparsing.ParserElement-class.html#_parse -pyparsing.ParserElement._skipIgnorables pyparsing.ParserElement-class.html#_skipIgnorables -pyparsing.ParserElement._literalStringClass pyparsing.Literal-class.html -pyparsing.ParserElement.verbose_stacktrace pyparsing.ParserElement-class.html#verbose_stacktrace -pyparsing.pyparsing_common pyparsing.pyparsing_common-class.html -pyparsing.pyparsing_common.fnumber pyparsing.pyparsing_common-class.html#fnumber -pyparsing.pyparsing_common.comma_separated_list pyparsing.pyparsing_common-class.html#comma_separated_list -pyparsing.pyparsing_common.stripHTMLTags pyparsing.pyparsing_common-class.html#stripHTMLTags -pyparsing.pyparsing_common._commasepitem pyparsing.pyparsing_common-class.html#_commasepitem -pyparsing.pyparsing_common._mixed_ipv6_address pyparsing.pyparsing_common-class.html#_mixed_ipv6_address -pyparsing.pyparsing_common.hex_integer pyparsing.pyparsing_common-class.html#hex_integer -pyparsing.pyparsing_common.number pyparsing.pyparsing_common-class.html#number -pyparsing.pyparsing_common.convertToInteger pyparsing.pyparsing_common-class.html#convertToInteger -pyparsing.pyparsing_common.sci_real pyparsing.pyparsing_common-class.html#sci_real -pyparsing.pyparsing_common.uuid pyparsing.pyparsing_common-class.html#uuid -pyparsing.pyparsing_common.convertToFloat pyparsing.pyparsing_common-class.html#convertToFloat -pyparsing.pyparsing_common.convertToDate pyparsing.pyparsing_common-class.html#convertToDate -pyparsing.pyparsing_common.downcaseTokens pyparsing.pyparsing_common-class.html#downcaseTokens -pyparsing.pyparsing_common.convertToDatetime pyparsing.pyparsing_common-class.html#convertToDatetime -pyparsing.pyparsing_common.fraction pyparsing.pyparsing_common-class.html#fraction -pyparsing.pyparsing_common._full_ipv6_address pyparsing.pyparsing_common-class.html#_full_ipv6_address -pyparsing.pyparsing_common.signed_integer pyparsing.pyparsing_common-class.html#signed_integer -pyparsing.pyparsing_common.real pyparsing.pyparsing_common-class.html#real -pyparsing.pyparsing_common.mac_address pyparsing.pyparsing_common-class.html#mac_address -pyparsing.pyparsing_common.iso8601_date pyparsing.pyparsing_common-class.html#iso8601_date -pyparsing.pyparsing_common.ipv4_address pyparsing.pyparsing_common-class.html#ipv4_address -pyparsing.pyparsing_common.integer pyparsing.pyparsing_common-class.html#integer -pyparsing.pyparsing_common._ipv6_part pyparsing.pyparsing_common-class.html#_ipv6_part -pyparsing.pyparsing_common.iso8601_datetime pyparsing.pyparsing_common-class.html#iso8601_datetime -pyparsing.pyparsing_common.identifier pyparsing.pyparsing_common-class.html#identifier -pyparsing.pyparsing_common.upcaseTokens pyparsing.pyparsing_common-class.html#upcaseTokens -pyparsing.pyparsing_common._short_ipv6_address pyparsing.pyparsing_common-class.html#_short_ipv6_address -pyparsing.pyparsing_common.ipv6_address pyparsing.pyparsing_common-class.html#ipv6_address -pyparsing.pyparsing_common.mixed_integer pyparsing.pyparsing_common-class.html#mixed_integer -pyparsing.pyparsing_common._html_stripper pyparsing.pyparsing_common-class.html#_html_stripper diff --git a/htmldoc/class-tree.html b/htmldoc/class-tree.html deleted file mode 100644 index 57a2323..0000000 --- a/htmldoc/class-tree.html +++ /dev/null @@ -1,339 +0,0 @@ - - - - - Class Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - -
[frames] | no frames]
-
-
- [ Module Hierarchy - | Class Hierarchy ] -

-

Class Hierarchy

-
    -
  • object: - The most base type -
      -
    • exceptions.BaseException: - Common base class for all exceptions - -
    • -
    • pyparsing.OnlyOnce: - Wrapper for parse actions, to ensure they are only called once. -
    • -
    • pyparsing.ParseResults: - Structured parse results, to provide multiple means of access to - the parsed data: -
    • -
    • pyparsing.ParserElement: - Abstract base level parser element class. -
        -
      • pyparsing.ParseElementEnhance: - Abstract subclass of ParserElement, for combining and - post-processing parsed tokens. -
          -
        • pyparsing.FollowedBy: - Lookahead matching of the given parse expression. -
        • -
        • pyparsing.Forward: - Forward declaration of an expression to be defined later - used for - recursive grammars, such as algebraic infix notation. -
            -
          -
        • -
        • pyparsing.NotAny: - Lookahead to disallow matching with the given parse expression. -
        • -
        • pyparsing.Optional: - Optional matching of the given expression. -
        • -
        • pyparsing.SkipTo: - Token for skipping over all undefined text until the matched - expression is found. -
        • -
        • pyparsing.TokenConverter: - Abstract subclass of ParseExpression, for converting - parsed results. -
            -
          • pyparsing.Combine: - Converter to concatenate all matching tokens to a single string. -
          • -
          • pyparsing.Dict: - Converter to return a repetitive expression as a list, but also as - a dictionary. -
          • -
          • pyparsing.Group: - Converter to return the matched tokens as a list - useful for - returning tokens of ZeroOrMore and OneOrMore expressions. -
          • -
          • pyparsing.Suppress: - Converter for ignoring the results of a parsed expression. -
          • -
          -
        • -
        • pyparsing._MultipleMatch - -
        • -
        -
      • -
      • pyparsing.ParseExpression: - Abstract subclass of ParserElement, for combining and - post-processing parsed tokens. -
          -
        • pyparsing.And: - Requires all given ParseExpressions to be found in the - given order. -
        • -
        • pyparsing.Each: - Requires all given ParseExpressions to be found, but - in any order. -
        • -
        • pyparsing.MatchFirst: - Requires that at least one ParseExpression is found. -
        • -
        • pyparsing.Or: - Requires that at least one ParseExpression is found. -
        • -
        -
      • -
      • pyparsing.Token: - Abstract ParserElement subclass, for defining atomic - matching patterns. -
          -
        • pyparsing.CharsNotIn: - Token for matching words composed of characters not in a - given set (will include whitespace in matched characters if not - listed in the provided exclusion set - see example). -
        • -
        • pyparsing.CloseMatch: - A variation on Literal which matches - "close" matches, that is, strings with at most 'n' - mismatching characters. -
        • -
        • pyparsing.Empty: - An empty token, will always match. -
            -
          -
        • -
        • pyparsing.Keyword: - Token to exactly match a specified string as a keyword, that is, it - must be immediately followed by a non-keyword character. - -
        • -
        • pyparsing.Literal: - Token to exactly match a specified string. - -
        • -
        • pyparsing.NoMatch: - A token that will never match. -
        • -
        • pyparsing.QuotedString: - Token for matching strings that are delimited by quoting - characters. -
        • -
        • pyparsing.Regex: - Token for matching strings that match a given regular expression. -
        • -
        • pyparsing.White: - Special matching class for matching whitespace. -
        • -
        • pyparsing.Word: - Token for matching words composed of allowed character sets. -
        • -
        • pyparsing._PositionToken -
            -
          • pyparsing.GoToColumn: - Token to advance to a specific column of input text; useful for - tabular report scraping. -
          • -
          • pyparsing.LineEnd: - Matches if current position is at the end of a line within the - parse string -
          • -
          • pyparsing.LineStart: - Matches if current position is at the beginning of a line within - the parse string -
          • -
          • pyparsing.StringEnd: - Matches if current position is at the end of the parse string -
          • -
          • pyparsing.StringStart: - Matches if current position is at the beginning of the parse string -
          • -
          • pyparsing.WordEnd: - Matches if the current position is at the end of a Word, and is not - followed by any character in a given set of wordChars - (default=printables). -
          • -
          • pyparsing.WordStart: - Matches if the current position is at the beginning of a Word, and - is not preceded by any character in a given set of - wordChars (default=printables). -
          • -
          -
        • -
        -
      • -
      -
    • -
    • pyparsing.Regex.compiledREtype: - Compiled regular expression objects -
    • -
    -
  • -
  • pyparsing.pyparsing_common: - Here are some common low-level expressions that may be useful in - jump-starting parser development: -
  • -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/crarr.png b/htmldoc/crarr.png deleted file mode 100644 index 26b43c52433b71e72a9a478c52d446278335f0e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^f?NMQuI$%1#8??M1uoZK z0}62#ctjR6FvuMOVaB`*rFK9;mUKs7M+SzC{oH>NS%G}l0G|-o|NsA=J-p%i`2!7U zCdJ_j4{u-SDsoA1U`TRixpVcz%O`iHHAYk?=&YaLkmD!Pp6~GW^M_S4D^grJKD>P~ zuPf!ku`N^TLavn`Edv_JSQ6wH%;50sMjDXg>*?YcQgJIe!GUqln>_|<+Os&OOUQS1 zY~Wzutud*iVS#|PHMc&?2WHoZpEo8l+6!Oc$x~=%U)469Gl^f?nq7UBw#1AXkrEde cmFKWBXcRFE*(?@T0vgQV>FVdQ&MBb@0LpZ4r2qf` diff --git a/htmldoc/epydoc.css b/htmldoc/epydoc.css deleted file mode 100644 index a21beda..0000000 --- a/htmldoc/epydoc.css +++ /dev/null @@ -1,322 +0,0 @@ - - -/* Epydoc CSS Stylesheet - * - * This stylesheet can be used to customize the appearance of epydoc's - * HTML output. - * - */ - -/* Default Colors & Styles - * - Set the default foreground & background color with 'body'; and - * link colors with 'a:link' and 'a:visited'. - * - Use bold for decision list terms. - * - The heading styles defined here are used for headings *within* - * docstring descriptions. All headings used by epydoc itself use - * either class='epydoc' or class='toc' (CSS styles for both - * defined below). - */ -body { background: #ffffff; color: #000000; } -p { margin-top: 0.5em; margin-bottom: 0.5em; } -a:link { color: #0000ff; } -a:visited { color: #204080; } -dt { font-weight: bold; } -h1 { font-size: +140%; font-style: italic; - font-weight: bold; } -h2 { font-size: +125%; font-style: italic; - font-weight: bold; } -h3 { font-size: +110%; font-style: italic; - font-weight: normal; } -code { font-size: 100%; } -/* N.B.: class, not pseudoclass */ -a.link { font-family: monospace; } - -/* Page Header & Footer - * - The standard page header consists of a navigation bar (with - * pointers to standard pages such as 'home' and 'trees'); a - * breadcrumbs list, which can be used to navigate to containing - * classes or modules; options links, to show/hide private - * variables and to show/hide frames; and a page title (using - *

). The page title may be followed by a link to the - * corresponding source code (using 'span.codelink'). - * - The footer consists of a navigation bar, a timestamp, and a - * pointer to epydoc's homepage. - */ -h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } -h2.epydoc { font-size: +130%; font-weight: bold; } -h3.epydoc { font-size: +115%; font-weight: bold; - margin-top: 0.2em; } -td h3.epydoc { font-size: +115%; font-weight: bold; - margin-bottom: 0; } -table.navbar { background: #a0c0ff; color: #000000; - border: 2px groove #c0d0d0; } -table.navbar table { color: #000000; } -th.navbar-select { background: #70b0ff; - color: #000000; } -table.navbar a { text-decoration: none; } -table.navbar a:link { color: #0000ff; } -table.navbar a:visited { color: #204080; } -span.breadcrumbs { font-size: 85%; font-weight: bold; } -span.options { font-size: 70%; } -span.codelink { font-size: 85%; } -td.footer { font-size: 85%; } - -/* Table Headers - * - Each summary table and details section begins with a 'header' - * row. This row contains a section title (marked by - * 'span.table-header') as well as a show/hide private link - * (marked by 'span.options', defined above). - * - Summary tables that contain user-defined groups mark those - * groups using 'group header' rows. - */ -td.table-header { background: #70b0ff; color: #000000; - border: 1px solid #608090; } -td.table-header table { color: #000000; } -td.table-header table a:link { color: #0000ff; } -td.table-header table a:visited { color: #204080; } -span.table-header { font-size: 120%; font-weight: bold; } -th.group-header { background: #c0e0f8; color: #000000; - text-align: left; font-style: italic; - font-size: 115%; - border: 1px solid #608090; } - -/* Summary Tables (functions, variables, etc) - * - Each object is described by a single row of the table with - * two cells. The left cell gives the object's type, and is - * marked with 'code.summary-type'. The right cell gives the - * object's name and a summary description. - * - CSS styles for the table's header and group headers are - * defined above, under 'Table Headers' - */ -table.summary { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin-bottom: 0.5em; } -td.summary { border: 1px solid #608090; } -code.summary-type { font-size: 85%; } -table.summary a:link { color: #0000ff; } -table.summary a:visited { color: #204080; } - - -/* Details Tables (functions, variables, etc) - * - Each object is described in its own div. - * - A single-row summary table w/ table-header is used as - * a header for each details section (CSS style for table-header - * is defined above, under 'Table Headers'). - */ -table.details { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin: .2em 0 0 0; } -table.details table { color: #000000; } -table.details a:link { color: #0000ff; } -table.details a:visited { color: #204080; } - -/* Fields */ -dl.fields { margin-left: 2em; margin-top: 1em; - margin-bottom: 1em; } -dl.fields dd ul { margin-left: 0em; padding-left: 0em; } -dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } -div.fields { margin-left: 2em; } -div.fields p { margin-bottom: 0.5em; } - -/* Index tables (identifier index, term index, etc) - * - link-index is used for indices containing lists of links - * (namely, the identifier index & term index). - * - index-where is used in link indices for the text indicating - * the container/source for each link. - * - metadata-index is used for indices containing metadata - * extracted from fields (namely, the bug index & todo index). - */ -table.link-index { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; } -td.link-index { border-width: 0px; } -table.link-index a:link { color: #0000ff; } -table.link-index a:visited { color: #204080; } -span.index-where { font-size: 70%; } -table.metadata-index { border-collapse: collapse; - background: #e8f0f8; color: #000000; - border: 1px solid #608090; - margin: .2em 0 0 0; } -td.metadata-index { border-width: 1px; border-style: solid; } -table.metadata-index a:link { color: #0000ff; } -table.metadata-index a:visited { color: #204080; } - -/* Function signatures - * - sig* is used for the signature in the details section. - * - .summary-sig* is used for the signature in the summary - * table, and when listing property accessor functions. - * */ -.sig-name { color: #006080; } -.sig-arg { color: #008060; } -.sig-default { color: #602000; } -.summary-sig { font-family: monospace; } -.summary-sig-name { color: #006080; font-weight: bold; } -table.summary a.summary-sig-name:link - { color: #006080; font-weight: bold; } -table.summary a.summary-sig-name:visited - { color: #006080; font-weight: bold; } -.summary-sig-arg { color: #006040; } -.summary-sig-default { color: #501800; } - -/* Subclass list - */ -ul.subclass-list { display: inline; } -ul.subclass-list li { display: inline; } - -/* To render variables, classes etc. like functions */ -table.summary .summary-name { color: #006080; font-weight: bold; - font-family: monospace; } -table.summary - a.summary-name:link { color: #006080; font-weight: bold; - font-family: monospace; } -table.summary - a.summary-name:visited { color: #006080; font-weight: bold; - font-family: monospace; } - -/* Variable values - * - In the 'variable details' sections, each varaible's value is - * listed in a 'pre.variable' box. The width of this box is - * restricted to 80 chars; if the value's repr is longer than - * this it will be wrapped, using a backslash marked with - * class 'variable-linewrap'. If the value's repr is longer - * than 3 lines, the rest will be ellided; and an ellipsis - * marker ('...' marked with 'variable-ellipsis') will be used. - * - If the value is a string, its quote marks will be marked - * with 'variable-quote'. - * - If the variable is a regexp, it is syntax-highlighted using - * the re* CSS classes. - */ -pre.variable { padding: .5em; margin: 0; - background: #dce4ec; color: #000000; - border: 1px solid #708890; } -.variable-linewrap { color: #604000; font-weight: bold; } -.variable-ellipsis { color: #604000; font-weight: bold; } -.variable-quote { color: #604000; font-weight: bold; } -.variable-group { color: #008000; font-weight: bold; } -.variable-op { color: #604000; font-weight: bold; } -.variable-string { color: #006030; } -.variable-unknown { color: #a00000; font-weight: bold; } -.re { color: #000000; } -.re-char { color: #006030; } -.re-op { color: #600000; } -.re-group { color: #003060; } -.re-ref { color: #404040; } - -/* Base tree - * - Used by class pages to display the base class hierarchy. - */ -pre.base-tree { font-size: 80%; margin: 0; } - -/* Frames-based table of contents headers - * - Consists of two frames: one for selecting modules; and - * the other listing the contents of the selected module. - * - h1.toc is used for each frame's heading - * - h2.toc is used for subheadings within each frame. - */ -h1.toc { text-align: center; font-size: 105%; - margin: 0; font-weight: bold; - padding: 0; } -h2.toc { font-size: 100%; font-weight: bold; - margin: 0.5em 0 0 -0.3em; } - -/* Syntax Highlighting for Source Code - * - doctest examples are displayed in a 'pre.py-doctest' block. - * If the example is in a details table entry, then it will use - * the colors specified by the 'table pre.py-doctest' line. - * - Source code listings are displayed in a 'pre.py-src' block. - * Each line is marked with 'span.py-line' (used to draw a line - * down the left margin, separating the code from the line - * numbers). Line numbers are displayed with 'span.py-lineno'. - * The expand/collapse block toggle button is displayed with - * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not - * modify the font size of the text.) - * - If a source code page is opened with an anchor, then the - * corresponding code block will be highlighted. The code - * block's header is highlighted with 'py-highlight-hdr'; and - * the code block's body is highlighted with 'py-highlight'. - * - The remaining py-* classes are used to perform syntax - * highlighting (py-string for string literals, py-name for names, - * etc.) - */ -pre.py-doctest { padding: .5em; margin: 1em; - background: #e8f0f8; color: #000000; - border: 1px solid #708890; } -table pre.py-doctest { background: #dce4ec; - color: #000000; } -pre.py-src { border: 2px solid #000000; - background: #f0f0f0; color: #000000; } -.py-line { border-left: 2px solid #000000; - margin-left: .2em; padding-left: .4em; } -.py-lineno { font-style: italic; font-size: 90%; - padding-left: .5em; } -a.py-toggle { text-decoration: none; } -div.py-highlight-hdr { border-top: 2px solid #000000; - border-bottom: 2px solid #000000; - background: #d8e8e8; } -div.py-highlight { border-bottom: 2px solid #000000; - background: #d0e0e0; } -.py-prompt { color: #005050; font-weight: bold;} -.py-more { color: #005050; font-weight: bold;} -.py-string { color: #006030; } -.py-comment { color: #003060; } -.py-keyword { color: #600000; } -.py-output { color: #404040; } -.py-name { color: #000050; } -.py-name:link { color: #000050 !important; } -.py-name:visited { color: #000050 !important; } -.py-number { color: #005000; } -.py-defname { color: #000060; font-weight: bold; } -.py-def-name { color: #000060; font-weight: bold; } -.py-base-class { color: #000060; } -.py-param { color: #000060; } -.py-docstring { color: #006030; } -.py-decorator { color: #804020; } -/* Use this if you don't want links to names underlined: */ -/*a.py-name { text-decoration: none; }*/ - -/* Graphs & Diagrams - * - These CSS styles are used for graphs & diagrams generated using - * Graphviz dot. 'img.graph-without-title' is used for bare - * diagrams (to remove the border created by making the image - * clickable). - */ -img.graph-without-title { border: none; } -img.graph-with-title { border: 1px solid #000000; } -span.graph-title { font-weight: bold; } -span.graph-caption { } - -/* General-purpose classes - * - 'p.indent-wrapped-lines' defines a paragraph whose first line - * is not indented, but whose subsequent lines are. - * - The 'nomargin-top' class is used to remove the top margin (e.g. - * from lists). The 'nomargin' class is used to remove both the - * top and bottom margin (but not the left or right margin -- - * for lists, that would cause the bullets to disappear.) - */ -p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; - margin: 0; } -.nomargin-top { margin-top: 0; } -.nomargin { margin-top: 0; margin-bottom: 0; } - -/* HTML Log */ -div.log-block { padding: 0; margin: .5em 0 .5em 0; - background: #e8f0f8; color: #000000; - border: 1px solid #000000; } -div.log-error { padding: .1em .3em .1em .3em; margin: 4px; - background: #ffb0b0; color: #000000; - border: 1px solid #000000; } -div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; - background: #ffffb0; color: #000000; - border: 1px solid #000000; } -div.log-info { padding: .1em .3em .1em .3em; margin: 4px; - background: #b0ffb0; color: #000000; - border: 1px solid #000000; } -h2.log-hdr { background: #70b0ff; color: #000000; - margin: 0; padding: 0em 0.5em 0em 0.5em; - border-bottom: 1px solid #000000; font-size: 110%; } -p.log { font-weight: bold; margin: .5em 0 .5em 0; } -tr.opt-changed { color: #000000; font-weight: bold; } -tr.opt-default { color: #606060; } -pre.log { margin: 0; padding: 0; padding-left: 1em; } diff --git a/htmldoc/epydoc.js b/htmldoc/epydoc.js deleted file mode 100644 index 95875d6..0000000 --- a/htmldoc/epydoc.js +++ /dev/null @@ -1,293 +0,0 @@ -function toggle_private() { - // Search for any private/public links on this page. Store - // their old text in "cmd," so we will know what action to - // take; and change their text to the opposite action. - var cmd = "?"; - var elts = document.getElementsByTagName("a"); - for(var i=0; i...
"; - elt.innerHTML = s; - } -} - -function toggle(id) { - elt = document.getElementById(id+"-toggle"); - if (elt.innerHTML == "-") - collapse(id); - else - expand(id); - return false; -} - -function highlight(id) { - var elt = document.getElementById(id+"-def"); - if (elt) elt.className = "py-highlight-hdr"; - var elt = document.getElementById(id+"-expanded"); - if (elt) elt.className = "py-highlight"; - var elt = document.getElementById(id+"-collapsed"); - if (elt) elt.className = "py-highlight"; -} - -function num_lines(s) { - var n = 1; - var pos = s.indexOf("\n"); - while ( pos > 0) { - n += 1; - pos = s.indexOf("\n", pos+1); - } - return n; -} - -// Collapse all blocks that mave more than `min_lines` lines. -function collapse_all(min_lines) { - var elts = document.getElementsByTagName("div"); - for (var i=0; i 0) - if (elt.id.substring(split, elt.id.length) == "-expanded") - if (num_lines(elt.innerHTML) > min_lines) - collapse(elt.id.substring(0, split)); - } -} - -function expandto(href) { - var start = href.indexOf("#")+1; - if (start != 0 && start != href.length) { - if (href.substring(start, href.length) != "-") { - collapse_all(4); - pos = href.indexOf(".", start); - while (pos != -1) { - var id = href.substring(start, pos); - expand(id); - pos = href.indexOf(".", pos+1); - } - var id = href.substring(start, href.length); - expand(id); - highlight(id); - } - } -} - -function kill_doclink(id) { - var parent = document.getElementById(id); - parent.removeChild(parent.childNodes.item(0)); -} -function auto_kill_doclink(ev) { - if (!ev) var ev = window.event; - if (!this.contains(ev.toElement)) { - var parent = document.getElementById(this.parentID); - parent.removeChild(parent.childNodes.item(0)); - } -} - -function doclink(id, name, targets_id) { - var elt = document.getElementById(id); - - // If we already opened the box, then destroy it. - // (This case should never occur, but leave it in just in case.) - if (elt.childNodes.length > 1) { - elt.removeChild(elt.childNodes.item(0)); - } - else { - // The outer box: relative + inline positioning. - var box1 = document.createElement("div"); - box1.style.position = "relative"; - box1.style.display = "inline"; - box1.style.top = 0; - box1.style.left = 0; - - // A shadow for fun - var shadow = document.createElement("div"); - shadow.style.position = "absolute"; - shadow.style.left = "-1.3em"; - shadow.style.top = "-1.3em"; - shadow.style.background = "#404040"; - - // The inner box: absolute positioning. - var box2 = document.createElement("div"); - box2.style.position = "relative"; - box2.style.border = "1px solid #a0a0a0"; - box2.style.left = "-.2em"; - box2.style.top = "-.2em"; - box2.style.background = "white"; - box2.style.padding = ".3em .4em .3em .4em"; - box2.style.fontStyle = "normal"; - box2.onmouseout=auto_kill_doclink; - box2.parentID = id; - - // Get the targets - var targets_elt = document.getElementById(targets_id); - var targets = targets_elt.getAttribute("targets"); - var links = ""; - target_list = targets.split(","); - for (var i=0; i" + - target[0] + ""; - } - - // Put it all together. - elt.insertBefore(box1, elt.childNodes.item(0)); - //box1.appendChild(box2); - box1.appendChild(shadow); - shadow.appendChild(box2); - box2.innerHTML = - "Which "+name+" do you want to see documentation for?" + - ""; - } - return false; -} - -function get_anchor() { - var href = location.href; - var start = href.indexOf("#")+1; - if ((start != 0) && (start != href.length)) - return href.substring(start, href.length); - } -function redirect_url(dottedName) { - // Scan through each element of the "pages" list, and check - // if "name" matches with any of them. - for (var i=0; i-m" or "-c"; - // extract the portion & compare it to dottedName. - var pagename = pages[i].substring(0, pages[i].length-2); - if (pagename == dottedName.substring(0,pagename.length)) { - - // We've found a page that matches `dottedName`; - // construct its URL, using leftover `dottedName` - // content to form an anchor. - var pagetype = pages[i].charAt(pages[i].length-1); - var url = pagename + ((pagetype=="m")?"-module.html": - "-class.html"); - if (dottedName.length > pagename.length) - url += "#" + dottedName.substring(pagename.length+1, - dottedName.length); - return url; - } - } - } diff --git a/htmldoc/frames.html b/htmldoc/frames.html deleted file mode 100644 index b34844e..0000000 --- a/htmldoc/frames.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - pyparsing - - - - - - - - - diff --git a/htmldoc/help.html b/htmldoc/help.html deleted file mode 100644 index b2c302a..0000000 --- a/htmldoc/help.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - - Help - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - -
[frames] | no frames]
-
- -

API Documentation

- -

This document contains the API (Application Programming Interface) -documentation for pyparsing. Documentation for the Python -objects defined by the project is divided into separate pages for each -package, module, and class. The API documentation also includes two -pages containing information about the project as a whole: a trees -page, and an index page.

- -

Object Documentation

- -

Each Package Documentation page contains:

-
    -
  • A description of the package.
  • -
  • A list of the modules and sub-packages contained by the - package.
  • -
  • A summary of the classes defined by the package.
  • -
  • A summary of the functions defined by the package.
  • -
  • A summary of the variables defined by the package.
  • -
  • A detailed description of each function defined by the - package.
  • -
  • A detailed description of each variable defined by the - package.
  • -
- -

Each Module Documentation page contains:

-
    -
  • A description of the module.
  • -
  • A summary of the classes defined by the module.
  • -
  • A summary of the functions defined by the module.
  • -
  • A summary of the variables defined by the module.
  • -
  • A detailed description of each function defined by the - module.
  • -
  • A detailed description of each variable defined by the - module.
  • -
- -

Each Class Documentation page contains:

-
    -
  • A class inheritance diagram.
  • -
  • A list of known subclasses.
  • -
  • A description of the class.
  • -
  • A summary of the methods defined by the class.
  • -
  • A summary of the instance variables defined by the class.
  • -
  • A summary of the class (static) variables defined by the - class.
  • -
  • A detailed description of each method defined by the - class.
  • -
  • A detailed description of each instance variable defined by the - class.
  • -
  • A detailed description of each class (static) variable defined - by the class.
  • -
- -

Project Documentation

- -

The Trees page contains the module and class hierarchies:

-
    -
  • The module hierarchy lists every package and module, with - modules grouped into packages. At the top level, and within each - package, modules and sub-packages are listed alphabetically.
  • -
  • The class hierarchy lists every class, grouped by base - class. If a class has more than one base class, then it will be - listed under each base class. At the top level, and under each base - class, classes are listed alphabetically.
  • -
- -

The Index page contains indices of terms and - identifiers:

-
    -
  • The term index lists every term indexed by any object's - documentation. For each term, the index provides links to each - place where the term is indexed.
  • -
  • The identifier index lists the (short) name of every package, - module, class, method, function, variable, and parameter. For each - identifier, the index provides a short description, and a link to - its documentation.
  • -
- -

The Table of Contents

- -

The table of contents occupies the two frames on the left side of -the window. The upper-left frame displays the project -contents, and the lower-left frame displays the module -contents:

- - - - - - - - - -
- Project
Contents
...
- API
Documentation
Frame


-
- Module
Contents
 
...
  -

- -

The project contents frame contains a list of all packages -and modules that are defined by the project. Clicking on an entry -will display its contents in the module contents frame. Clicking on a -special entry, labeled "Everything," will display the contents of -the entire project.

- -

The module contents frame contains a list of every -submodule, class, type, exception, function, and variable defined by a -module or package. Clicking on an entry will display its -documentation in the API documentation frame. Clicking on the name of -the module, at the top of the frame, will display the documentation -for the module itself.

- -

The "frames" and "no frames" buttons below the top -navigation bar can be used to control whether the table of contents is -displayed or not.

- -

The Navigation Bar

- -

A navigation bar is located at the top and bottom of every page. -It indicates what type of page you are currently viewing, and allows -you to go to related pages. The following table describes the labels -on the navigation bar. Note that not some labels (such as -[Parent]) are not displayed on all pages.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LabelHighlighted when...Links to...
[Parent](never highlighted) the parent of the current package
[Package]viewing a packagethe package containing the current object -
[Module]viewing a modulethe module containing the current object -
[Class]viewing a class the class containing the current object
[Trees]viewing the trees page the trees page
[Index]viewing the index page the index page
[Help]viewing the help page the help page
- -

The "show private" and "hide private" buttons below -the top navigation bar can be used to control whether documentation -for private objects is displayed. Private objects are usually defined -as objects whose (short) names begin with a single underscore, but do -not end with an underscore. For example, "_x", -"__pprint", and "epydoc.epytext._tokenize" -are private objects; but "re.sub", -"__init__", and "type_" are not. However, -if a module defines the "__all__" variable, then its -contents are used to decide which objects are private.

- -

A timestamp below the bottom navigation bar indicates when each -page was last updated.

- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/identifier-index.html b/htmldoc/identifier-index.html deleted file mode 100644 index b13a071..0000000 --- a/htmldoc/identifier-index.html +++ /dev/null @@ -1,1406 +0,0 @@ - - - - - Identifier Index - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - -
[frames] | no frames]
-
- -
-

Identifier Index

-
-[ - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z - _ -] -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

A

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

C

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

D

- - - - - - - - - - - - - - - - - - - - - - -

E

- - - - - - - - - - - - -

F

- - - - - - - - - - - - - - - - - -

G

- - - - - - - - - - - - -

H

- - - - - - - - - - - - -

I

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

J

- - - - - - - - -

K

- - - - - - - - -

L

- - - - - - - - - - - - - - - - - - - - - - -

M

- - - - - - - - - - - - - - - - - - - - - - -

N

- - - - - - - - - - - - -

O

- - - - - - - - - - - - - - - - - -

P

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Q

- - - - - - - - -

R

- - - - - - - - - - - - - - - - - - - - - - -

S

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

T

- - - - - - - - - - - - -

U

- - - - - - - - - - - - -

V

- - - - - - - - - - - - -

W

- - - - - - - - - - - - - - - - - -

Z

- - - - - - - - -

_

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/index.html b/htmldoc/index.html deleted file mode 100644 index 212e466..0000000 --- a/htmldoc/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - pyparsing - - - - - - - - - diff --git a/htmldoc/module-tree.html b/htmldoc/module-tree.html deleted file mode 100644 index bf1418a..0000000 --- a/htmldoc/module-tree.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - Module Hierarchy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - - - -
[frames] | no frames]
-
-
- [ Module Hierarchy - | Class Hierarchy ] -

-

Module Hierarchy

-
    -
  • pyparsing: pyparsing module - Classes and methods to define and execute - parsing grammars
  • -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing-module.html b/htmldoc/pyparsing-module.html deleted file mode 100644 index 80c36b2..0000000 --- a/htmldoc/pyparsing-module.html +++ /dev/null @@ -1,2689 +0,0 @@ - - - - - pyparsing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing - - - - - -
[frames] | no frames]
-
- -

Module pyparsing

source code

-

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 "<salutation>, - <addressee>!"), built up using Word, Literal, and And elements ('+' - operator gives And - expressions, strings are auto-converted to 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 ParseResults object returned from 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 -
  • -
- -
-

Version: - 2.2.0 -

-

Author: - Paul McGuire <ptmcg@users.sourceforge.net> -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Classes
-   - - ParseBaseException
- base exception class for all parsing runtime exceptions -
-   - - ParseException
- Exception thrown when parse expressions don't match class; - supported attributes by name are: -
-   - - ParseFatalException
- user-throwable exception thrown when inconsistent parse content is - found; stops all parsing immediately -
-   - - ParseSyntaxException
- just like ParseFatalException, but thrown internally when an - ErrorStop ('-' operator) indicates that parsing is to stop - immediately because an unbacktrackable syntax error has been found -
-   - - RecursiveGrammarException
- exception thrown by ParserElement.validate if the grammar could be - improperly recursive -
-   - - ParseResults
- Structured parse results, to provide multiple means of access to - the parsed data: -
-   - - ParserElement
- Abstract base level parser element class. -
-   - - Token
- Abstract ParserElement subclass, for defining atomic - matching patterns. -
-   - - Empty
- An empty token, will always match. -
-   - - NoMatch
- A token that will never match. -
-   - - Literal
- Token to exactly match a specified string. -
-   - - Keyword
- Token to exactly match a specified string as a keyword, that is, it - must be immediately followed by a non-keyword character. -
-   - - CaselessLiteral
- Token to match a specified string, ignoring case of letters. -
-   - - CaselessKeyword
- Caseless version of Keyword. -
-   - - CloseMatch
- A variation on Literal which matches - "close" matches, that is, strings with at most 'n' - mismatching characters. -
-   - - Word
- Token for matching words composed of allowed character sets. -
-   - - Regex
- Token for matching strings that match a given regular expression. -
-   - - QuotedString
- Token for matching strings that are delimited by quoting - characters. -
-   - - CharsNotIn
- Token for matching words composed of characters not in a - given set (will include whitespace in matched characters if not - listed in the provided exclusion set - see example). -
-   - - White
- Special matching class for matching whitespace. -
-   - - GoToColumn
- Token to advance to a specific column of input text; useful for - tabular report scraping. -
-   - - LineStart
- Matches if current position is at the beginning of a line within - the parse string -
-   - - LineEnd
- Matches if current position is at the end of a line within the - parse string -
-   - - StringStart
- Matches if current position is at the beginning of the parse string -
-   - - StringEnd
- Matches if current position is at the end of the parse string -
-   - - WordStart
- Matches if the current position is at the beginning of a Word, and - is not preceded by any character in a given set of - wordChars (default=printables). -
-   - - WordEnd
- Matches if the current position is at the end of a Word, and is not - followed by any character in a given set of wordChars - (default=printables). -
-   - - ParseExpression
- Abstract subclass of ParserElement, for combining and - post-processing parsed tokens. -
-   - - And
- Requires all given ParseExpressions to be found in the - given order. -
-   - - Or
- Requires that at least one ParseExpression is found. -
-   - - MatchFirst
- Requires that at least one ParseExpression is found. -
-   - - Each
- Requires all given ParseExpressions to be found, but - in any order. -
-   - - ParseElementEnhance
- Abstract subclass of ParserElement, for combining and - post-processing parsed tokens. -
-   - - FollowedBy
- Lookahead matching of the given parse expression. -
-   - - NotAny
- Lookahead to disallow matching with the given parse expression. -
-   - - OneOrMore
- Repetition of one or more of the given expression. -
-   - - ZeroOrMore
- Optional repetition of zero or more of the given expression. -
-   - - Optional
- Optional matching of the given expression. -
-   - - SkipTo
- Token for skipping over all undefined text until the matched - expression is found. -
-   - - Forward
- Forward declaration of an expression to be defined later - used for - recursive grammars, such as algebraic infix notation. -
-   - - TokenConverter
- Abstract subclass of ParseExpression, for converting - parsed results. -
-   - - Combine
- Converter to concatenate all matching tokens to a single string. -
-   - - Group
- Converter to return the matched tokens as a list - useful for - returning tokens of ZeroOrMore and OneOrMore expressions. -
-   - - Dict
- Converter to return a repetitive expression as a list, but also as - a dictionary. -
-   - - Suppress
- Converter for ignoring the results of a parsed expression. -
-   - - OnlyOnce
- Wrapper for parse actions, to ensure they are only called once. -
-   - - pyparsing_common
- Here are some common low-level expressions that may be useful in - jump-starting parser development: -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Functions
-   - - - - - - -
col(loc, - strg)
- Returns current column within a string, counting newlines as line - separators.
- source code - -
- -
-   - - - - - - -
lineno(loc, - strg)
- Returns current line number within a string, counting newlines as - line separators.
- source code - -
- -
-   - - - - - - -
line(loc, - strg)
- Returns the line of text containing loc within a string, counting - newlines as line separators.
- source code - -
- -
-   - - - - - - -
nullDebugAction(*args)
- 'Do-nothing' debug action, to suppress debugging output during - parsing.
- source code - -
- -
-   - - - - - - -
traceParseAction(f)
- Decorator for debugging parse actions.
- source code - -
- -
-   - - - - - - -
delimitedList(expr, - delim=',', - combine=False)
- Helper to define a delimited list of expressions - the delimiter - defaults to ','.
- source code - -
- -
-   - - - - - - -
countedArray(expr, - intExpr=None)
- Helper to define a counted list of expressions.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
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 MatchFirst for best performance.
- source code - -
- -
-   - - - - - - -
dictOf(key, - value)
- Helper to easily and clearly define a dictionary by specifying the - respective patterns for the key and value.
- source code - -
- -
-   - - - - - - -
originalTextFor(expr, - asString=True)
- Helper to return the original, untokenized text for a given - expression.
- source code - -
- -
-   - - - - - - -
ungroup(expr)
- Helper to undo pyparsing's default grouping of And expressions, even - if all but one are non-empty.
- source code - -
- -
-   - - - - - - -
locatedExpr(expr)
- Helper to decorate a returned token with its starting and ending - locations in the input string.
- source code - -
- -
-   - - - - - - -
srange(s)
- Helper to easily define string ranges for use in Word construction.
- source code - -
- -
-   - - - - - - -
matchOnlyAtCol(n)
- Helper method for defining parse actions that require matching at a - specific column in the input text.
- source code - -
- -
-   - - - - - - -
replaceWith(replStr)
- Helper method for common parse actions that simply return a literal - value.
- source code - -
- -
-   - - - - - - -
removeQuotes(s, - l, - t)
- Helper parse action for removing quotation marks from parsed quoted - strings.
- source code - -
- -
-   - - - - - - -
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 hex_integer = - Word(hexnums).setParseAction(tokenMap(int, 16)), which will - convert the parsed data to an integer using base 16.
- source code - -
- -
-   - - - - - - -
upcaseTokens(s, - l, - t)
- (Deprecated) Helper parse action to convert tokens to upper case.
- source code - -
- -
-   - - - - - - -
downcaseTokens(s, - l, - t)
- (Deprecated) Helper parse action to convert tokens to lower case.
- source code - -
- -
-   - - - - - - -
makeHTMLTags(tagStr)
- Helper to construct opening and closing tag expressions for HTML, - given a tag name.
- source code - -
- -
-   - - - - - - -
makeXMLTags(tagStr)
- Helper to construct opening and closing tag expressions for XML, - given a tag name.
- source code - -
- -
-   - - - - - - -
withAttribute(*args, - **attrDict)
- Helper to create a validating parse action to be used with start tags - created with makeXMLTags or makeHTMLTags.
- source code - -
- -
-   - - - - - - -
withClass(classname, - namespace='')
- Simplified version of withAttribute when matching on a div class - - made difficult because class is a reserved word in - Python.
- source code - -
- -
-   - - - - - - -
infixNotation(baseExpr, - opList, - lpar=Suppress:("("), - rpar=Suppress:(")"))
- Helper method for constructing grammars of expressions made up of - operators working in a precedence hierarchy.
- source code - -
- -
-   - - - - - - -
operatorPrecedence(baseExpr, - opList, - lpar=Suppress:("("), - rpar=Suppress:(")"))
- (Deprecated) Former name of infixNotation, will be dropped in a future - release.
- source code - -
- -
-   - - - - - - -
nestedExpr(opener='(', - closer=')', - content=None, - ignoreExpr=quotedString using single or double quotes)
- Helper method for defining nested lists enclosed in opening and - closing delimiters ("(" and ")" are the default).
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
replaceHTMLEntity(t)
- Helper parser action to replace common HTML entities with their - special characters
- source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Variables
-   - - alphas = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' -
-   - - nums = '0123456789' -
-   - - hexnums = '0123456789ABCDEFabcdef' -
-   - - alphanums = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw... -
-   - - printables = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL... -
-   - - empty = empty -
-   - - lineStart = lineStart -
-   - - lineEnd = lineEnd -
-   - - stringStart = stringStart -
-   - - stringEnd = stringEnd -
-   - - opAssoc = _Constants() -
-   - - dblQuotedString = string enclosed in double quotes -
-   - - sglQuotedString = string enclosed in single quotes -
-   - - quotedString = quotedString using single or double quotes -
-   - - unicodeString = unicode string literal -
-   - - alphas8bit = u'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîï... -
-   - - punc8bit = u'¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿×÷' -
-   - - commonHTMLEntity = common HTML entity -
-   - - cStyleComment = C style comment
- Comment of the form /* ... */ -
-   - - htmlComment = HTML comment
- Comment of the form <!-- ... --> -
-   - - restOfLine = rest of line -
-   - - dblSlashComment = // comment
- Comment of the form // ... (to end of line) -
-   - - cppStyleComment = C++ style comment
- Comment of either form cStyleComment or dblSlashComment -
-   - - javaStyleComment = C++ style comment
- Same as cppStyleComment -
-   - - pythonStyleComment = Python style comment
- Comment of the form # ... (to end of line) -
-   - - commaSeparatedList = commaSeparatedList
- (Deprecated) Predefined expression of 1 or more printable words or - quoted strings, separated by commas. -
-   - - anyCloseTag = </any tag> -
-   - - anyOpenTag = <any tag> -
- - - - - - -
- Function Details
- -
- -
- - -
-

col(loc, - strg) -

-
source code  -
- -

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 ParserElement.parseString for more information on - parsing strings containing <TAB>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.

-
-
-
-
- -
- -
- - -
-

lineno(loc, - strg) -

-
source code  -
- -

Returns current line number within a string, counting newlines as line - separators. The first line is number 1.

-

Note: the default parsing behavior is to expand tabs in the input - string before starting the parsing process. See ParserElement.parseString for more information on - parsing strings containing <TAB>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.

-
-
-
-
- -
- -
- - -
-

traceParseAction(f) -

-
source code  -
- -

Decorator for debugging parse actions.

-

When the parse action is called, this decorator will print - ">> entering - method-name(line:current_source_line, - parse_location, matched_tokens)". When the - parse action completes, the decorator will print - "<<" 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'], {}))
-   <<leaving remove_duplicate_chars (ret: 'dfjkls')
-   ['dfjkls']
-
-
-
-
-
- -
- -
- - -
-

delimitedList(expr, - delim=',', - combine=False) -

-
source code  -
- -

Helper to define a delimited list of expressions - the delimiter - defaults to ','. By default, the list elements and delimiters can have - intervening whitespace, and comments, but this can be overridden by - passing combine=True in the constructor. If - combine is set to True, the matching tokens are - returned as a single token string, with the delimiters included; - otherwise, the matching tokens are returned as a list of tokens, with the - delimiters suppressed.

-

Example:

-
-   delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc']
-   delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
-
-
-
-
-
- -
- -
- - -
-

countedArray(expr, - intExpr=None) -

-
source code  -
- -

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 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']
-
-
-
-
-
- -
- -
- - -
-

matchPreviousLiteral(expr) -

-
source code  -
- -

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 "1:1", but not - "1:2". Because this matches a previous literal, - will also match the leading "1:1" in - "1:10". If this is not desired, use - matchPreviousExpr. Do not use with packrat parsing - enabled.

-
-
-
-
- -
- -
- - -
-

matchPreviousExpr(expr) -

-
source code  -
- -

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 "1:1", but not - "1:2". Because this matches by expressions, will - not match the leading "1:1" in - "1:10"; the expressions are evaluated first, and - then compared, so "1" is compared with - "10". Do not use with packrat parsing - enabled.

-
-
-
-
- -
- -
- - -
-

oneOf(strs, - caseless=False, - useRegex=True) -

-
source code  -
- -

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 MatchFirst - for best performance.

-

Parameters:

-
    -
  • - strs - a string of space-delimited literals, or a collection of - string literals -
  • -
  • - caseless - (default=False) - treat all literals as - caseless -
  • -
  • - useRegex - (default=True) - as an optimization, will - generate a Regex object; otherwise, will generate a - MatchFirst object (if caseless=True, or if - creating a 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']]
-
-
-
-
-
- -
- -
- - -
-

dictOf(key, - value) -

-
source code  -
- -

Helper to easily and clearly define a dictionary by specifying the - respective patterns for the key and value. Takes care of defining the - Dict, - ZeroOrMore, and 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 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'}
-
-
-
-
-
- -
- -
- - -
-

originalTextFor(expr, - asString=True) -

-
source code  -
- -

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 asString argument is passed as - False, then the return value is a 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 - originalTextFor contains expressions with defined - results names, you must set asString to False - if you want to preserve those results name values.

-

Example:

-
-   src = "this is test <b> bold <i>text</i> </b> normal text "
-   for tag in ("b","i"):
-       opener,closer = makeHTMLTags(tag)
-       patt = originalTextFor(opener + SkipTo(closer) + closer)
-       print(patt.searchString(src)[0])
-
-

prints:

-
-   ['<b> bold <i>text</i> </b>']
-   ['<i>text</i>']
-
-
-
-
-
- -
- -
- - -
-

locatedExpr(expr) -

-
source code  -
- -

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 <TAB> - characters, you may want to call 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]]
-
-
-
-
-
- -
- -
- - -
-

srange(s) -

-
source code  -
- -

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 - \- or \]) -
  • -
  • - an escaped hex character with a leading '\x' - (\x21, which is a '!' character) - (\0x## is also supported for backwards compatibility) -
  • -
  • - an escaped octal character with a leading '\0' - (\041, which is a '!' character) -
  • -
  • - a range of any of the above, separated by a dash ('a-z', - etc.) -
  • -
  • - any combination of the above ('aeiouy', - 'a-zA-Z0-9_$', etc.) -
  • -
-
-
-
-
- -
- -
- - -
-

replaceWith(replStr) -

-
source code  -
- -

Helper method for common parse actions that simply return a literal - value. Especially useful when used with 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]
-
-
-
-
-
- -
- -
- - -
-

removeQuotes(s, - l, - t) -

-
source code  -
- -

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"]
-
-
-
-
-
- -
- -
- - -
-

tokenMap(func, - *args) -

-
source code  -
- -

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 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 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']
-
-
-
-
-
- -
- -
- - -
-

upcaseTokens(s, - l, - t) -

-
source code  -
- -

(Deprecated) Helper parse action to convert tokens to upper case. - Deprecated in favor of pyparsing_common.upcaseTokens

-
-
-
-
- -
- -
- - -
-

downcaseTokens(s, - l, - t) -

-
source code  -
- -

(Deprecated) Helper parse action to convert tokens to lower case. - Deprecated in favor of pyparsing_common.downcaseTokens

-
-
-
-
- -
- -
- - -
-

makeHTMLTags(tagStr) -

-
source code  -
- -

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 = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
-   # 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 <A> tag (like "href" shown here) are also accessible as named results
-       print(link.link_text, '->', link.href)
-
-

prints:

-
-   pyparsing -> http://pyparsing.wikispaces.com
-
-
-
-
-
- -
- -
- - -
-

makeXMLTags(tagStr) -

-
source code  -
- -

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 makeHTMLTags

-
-
-
-
- -
- -
- - -
-

withAttribute(*args, - **attrDict) -

-
source code  -
- -

Helper to create a validating parse action to be used with start tags - created with makeXMLTags or makeHTMLTags. Use withAttribute to - qualify a starting tag with a required attribute value, to avoid false - matches on common tags such as <TD> or - <DIV>.

-

Call withAttribute with a series of attribute names and - values. Specify the list of filter attributes names and values as:

-
    -
  • - keyword arguments, as in (align="right"), or -
  • -
  • - as an explicit dict with ** operator, when an attribute - name is also a Python reserved word, as in - **{"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 class (with or without a namespace), - use withClass.

-

To verify that the attribute exists, but without specifying a value, - pass withAttribute.ANY_VALUE as the value.

-

Example:

-
-   html = '''
-       <div>
-       Some text
-       <div type="grid">1 4 0 1 0</div>
-       <div type="graph">1,3 2,3 1,1</div>
-       <div>this has no type</div>
-       </div>
-           
-   '''
-   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
-
-
-
-
-
- -
- -
- - -
-

withClass(classname, - namespace='') -

-
source code  -
- -

Simplified version of withAttribute when matching on a div class - made - difficult because class is a reserved word in Python.

-

Example:

-
-   html = '''
-       <div>
-       Some text
-       <div class="grid">1 4 0 1 0</div>
-       <div class="graph">1,3 2,3 1,1</div>
-       <div>this &lt;div&gt; has no class</div>
-       </div>
-           
-   '''
-   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
-
-
-
-
-
- -
- -
- - -
-

infixNotation(baseExpr, - opList, - lpar=Suppress:("("), - rpar=Suppress:(")")) -

-
source code  -
- -

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 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 - opAssoc.RIGHT and 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 - setParseAction(*fn) (ParserElement.setParseAction) -
    • -
    -
  • -
  • - lpar - expression for matching left-parentheses - (default=Suppress('(')) -
  • -
  • - rpar - expression for matching right-parentheses - (default=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]]]
-
-
-
-
-
- -
- -
- - -
-

operatorPrecedence(baseExpr, - opList, - lpar=Suppress:("("), - rpar=Suppress:(")")) -

-
source code  -
- -

(Deprecated) Former name of infixNotation, will be dropped in a future - release.

-
-
-
-
- -
- -
- - -
-

nestedExpr(opener='(', - closer=')', - content=None, - ignoreExpr=quotedString using single or double quotes) -

-
source code  -
- -

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="("); can also be a pyparsing - expression -
  • -
  • - closer - closing character for a nested list - (default=")"); can also be a pyparsing - expression -
  • -
  • - content - expression for items within the nested lists - (default=None) -
  • -
  • - ignoreExpr - expression for ignoring opening and closing delimiters - (default=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 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 Or or MatchFirst. The default is quotedString, - but if no expressions are to be ignored, then pass 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']]
-
-
-
-
-
- -
- -
- - -
-

indentedBlock(blockStatementExpr, - indentStack, - indent=True) -

-
source code  -
- -

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=True) -
  • -
-

A valid block must contain at least one - 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']]]]]]] 
-
-
-
-
-
-
- - - - - - -
- Variables Details
- -
- -
-

alphanums

- -
-
-
-
Value:
-
-'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
-
-
-
-
-
- -
- -
-

printables

- -
-
-
-
Value:
-
-'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\\
-'()*+,-./:;<=>?@[\\]^_`{|}~'
-
-
-
-
-
- -
- -
-

alphas8bit

- -
-
-
-
Value:
-
-u'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
-
-
-
-
-
- -
- -
-

commaSeparatedList

-

(Deprecated) Predefined expression of 1 or more printable words or - quoted strings, separated by commas. This expression is deprecated in - favor of pyparsing_common.comma_separated_list.

-
-
-
-
Value:
-
-commaSeparatedList
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing-pysrc.html b/htmldoc/pyparsing-pysrc.html deleted file mode 100644 index ead9525..0000000 --- a/htmldoc/pyparsing-pysrc.html +++ /dev/null @@ -1,7968 +0,0 @@ - - - - - pyparsing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing - - - - - -
[frames] | no frames]
-
-

Source Code for Module pyparsing

-
-   1  # module pyparsing.py 
-   2  # 
-   3  # Copyright (c) 2003-2016  Paul T. McGuire 
-   4  # 
-   5  # Permission is hereby granted, free of charge, to any person obtaining 
-   6  # a copy of this software and associated documentation files (the 
-   7  # "Software"), to deal in the Software without restriction, including 
-   8  # without limitation the rights to use, copy, modify, merge, publish, 
-   9  # distribute, sublicense, and/or sell copies of the Software, and to 
-  10  # permit persons to whom the Software is furnished to do so, subject to 
-  11  # the following conditions: 
-  12  # 
-  13  # The above copyright notice and this permission notice shall be 
-  14  # included in all copies or substantial portions of the Software. 
-  15  # 
-  16  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-  17  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
-  18  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-  19  # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
-  20  # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
-  21  # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
-  22  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
-  23  # 
-  24   
-  25  __doc__ = \ 
-  26  """ 
-  27  pyparsing module - Classes and methods to define and execute parsing grammars 
-  28   
-  29  The pyparsing module is an alternative approach to creating and executing simple grammars, 
-  30  vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you 
-  31  don't need to learn a new syntax for defining grammars or matching expressions - the parsing module 
-  32  provides a library of classes that you use to construct the grammar directly in Python. 
-  33   
-  34  Here is a program to parse "Hello, World!" (or any greeting of the form  
-  35  C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements  
-  36  (L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to 
-  37  L{Literal} expressions):: 
-  38   
-  39      from pyparsing import Word, alphas 
-  40   
-  41      # define grammar of a greeting 
-  42      greet = Word(alphas) + "," + Word(alphas) + "!" 
-  43   
-  44      hello = "Hello, World!" 
-  45      print (hello, "->", greet.parseString(hello)) 
-  46   
-  47  The program outputs the following:: 
-  48   
-  49      Hello, World! -> ['Hello', ',', 'World', '!'] 
-  50   
-  51  The Python representation of the grammar is quite readable, owing to the self-explanatory 
-  52  class names, and the use of '+', '|' and '^' operators. 
-  53   
-  54  The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an 
-  55  object with named attributes. 
-  56   
-  57  The pyparsing module handles some of the problems that are typically vexing when writing text parsers: 
-  58   - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.) 
-  59   - quoted strings 
-  60   - embedded comments 
-  61  """ 
-  62   
-  63  __version__ = "2.2.0" 
-  64  __versionTime__ = "06 Mar 2017 02:06 UTC" 
-  65  __author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" 
-  66   
-  67  import string 
-  68  from weakref import ref as wkref 
-  69  import copy 
-  70  import sys 
-  71  import warnings 
-  72  import re 
-  73  import sre_constants 
-  74  import collections 
-  75  import pprint 
-  76  import traceback 
-  77  import types 
-  78  from datetime import datetime 
-  79   
-  80  try: 
-  81      from _thread import RLock 
-  82  except ImportError: 
-  83      from threading import RLock 
-  84   
-  85  try: 
-  86      from collections import OrderedDict as _OrderedDict 
-  87  except ImportError: 
-  88      try: 
-  89          from ordereddict import OrderedDict as _OrderedDict 
-  90      except ImportError: 
-  91          _OrderedDict = None 
-  92   
-  93  #~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) 
-  94   
-  95  __all__ = [ 
-  96  'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', 
-  97  'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', 
-  98  'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', 
-  99  'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', 
- 100  'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', 
- 101  'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter',  
- 102  'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', 
- 103  'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', 
- 104  'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', 
- 105  'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', 
- 106  'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', 
- 107  'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', 
- 108  'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', 
- 109  'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity',  
- 110  'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', 
- 111  'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', 
- 112  'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', 
- 113  'CloseMatch', 'tokenMap', 'pyparsing_common', 
- 114  ] 
- 115   
- 116  system_version = tuple(sys.version_info)[:3] 
- 117  PY_3 = system_version[0] == 3 
- 118  if PY_3: 
- 119      _MAX_INT = sys.maxsize 
- 120      basestring = str 
- 121      unichr = chr 
- 122      _ustr = str 
- 123   
- 124      # build list of single arg builtins, that can be used as parse actions 
- 125      singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] 
- 126   
- 127  else: 
- 128      _MAX_INT = sys.maxint 
- 129      range = xrange 
-
130 - 131 - def _ustr(obj): -
132 """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries - 133 str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It - 134 then < returns the unicode object | encodes it with the default encoding | ... >. - 135 """ - 136 if isinstance(obj,unicode): - 137 return obj - 138 - 139 try: - 140 # If this works, then _ustr(obj) has the same behaviour as str(obj), so - 141 # it won't break any existing code. - 142 return str(obj) - 143 - 144 except UnicodeEncodeError: - 145 # Else encode it - 146 ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') - 147 xmlcharref = Regex(r'&#\d+;') - 148 xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) - 149 return xmlcharref.transformString(ret) -
150 - 151 # build list of single arg builtins, tolerant of Python version, that can be used as parse actions - 152 singleArgBuiltins = [] - 153 import __builtin__ - 154 for fname in "sum len sorted reversed list tuple set any all min max".split(): - 155 try: - 156 singleArgBuiltins.append(getattr(__builtin__,fname)) - 157 except AttributeError: - 158 continue - 159 - 160 _generatorType = type((y for y in range(1))) -
161 - 162 -def _xml_escape(data): -
163 """Escape &, <, >, ", ', etc. in a string of data.""" - 164 - 165 # ampersand must be replaced first - 166 from_symbols = '&><"\'' - 167 to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) - 168 for from_,to_ in zip(from_symbols, to_symbols): - 169 data = data.replace(from_, to_) - 170 return data -
171 -
172 -class _Constants(object): -
173 pass -
174 - 175 alphas = string.ascii_uppercase + string.ascii_lowercase - 176 nums = "0123456789" - 177 hexnums = nums + "ABCDEFabcdef" - 178 alphanums = alphas + nums - 179 _bslash = chr(92) - 180 printables = "".join(c for c in string.printable if c not in string.whitespace) -
181 - 182 -class ParseBaseException(Exception): -
183 """base exception class for all parsing runtime exceptions""" - 184 # Performance tuning: we construct a *lot* of these, so keep this - 185 # constructor as small and fast as possible -
186 - def __init__( self, pstr, loc=0, msg=None, elem=None ): -
187 self.loc = loc - 188 if msg is None: - 189 self.msg = pstr - 190 self.pstr = "" - 191 else: - 192 self.msg = msg - 193 self.pstr = pstr - 194 self.parserElement = elem - 195 self.args = (pstr, loc, msg) -
196 - 197 @classmethod -
198 - def _from_exception(cls, pe): -
199 """ - 200 internal factory method to simplify creating one type of ParseException - 201 from another - avoids having __init__ signature conflicts among subclasses - 202 """ - 203 return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) -
204 -
205 - def __getattr__( self, aname ): -
206 """supported attributes by name are: - 207 - lineno - returns the line number of the exception text - 208 - col - returns the column number of the exception text - 209 - line - returns the line containing the exception text - 210 """ - 211 if( aname == "lineno" ): - 212 return lineno( self.loc, self.pstr ) - 213 elif( aname in ("col", "column") ): - 214 return col( self.loc, self.pstr ) - 215 elif( aname == "line" ): - 216 return line( self.loc, self.pstr ) - 217 else: - 218 raise AttributeError(aname) -
219 -
220 - def __str__( self ): -
221 return "%s (at char %d), (line:%d, col:%d)" % \ - 222 ( self.msg, self.loc, self.lineno, self.column ) -
223 - def __repr__( self ): -
224 return _ustr(self) -
225 - def markInputline( self, markerString = ">!<" ): -
226 """Extracts the exception line from the input string, and marks - 227 the location of the exception with a special symbol. - 228 """ - 229 line_str = self.line - 230 line_column = self.column - 1 - 231 if markerString: - 232 line_str = "".join((line_str[:line_column], - 233 markerString, line_str[line_column:])) - 234 return line_str.strip() -
235 - def __dir__(self): -
236 return "lineno col line".split() + dir(type(self)) -
237 -
238 -class ParseException(ParseBaseException): -
239 """ - 240 Exception thrown when parse expressions don't match class; - 241 supported attributes by name are: - 242 - lineno - returns the line number of the exception text - 243 - col - returns the column number of the exception text - 244 - line - returns the line containing the exception text - 245 - 246 Example:: - 247 try: - 248 Word(nums).setName("integer").parseString("ABC") - 249 except ParseException as pe: - 250 print(pe) - 251 print("column: {}".format(pe.col)) - 252 - 253 prints:: - 254 Expected integer (at char 0), (line:1, col:1) - 255 column: 1 - 256 """ - 257 pass -
258 -
259 -class ParseFatalException(ParseBaseException): -
260 """user-throwable exception thrown when inconsistent parse content - 261 is found; stops all parsing immediately""" - 262 pass -
263 -
264 -class ParseSyntaxException(ParseFatalException): -
265 """just like L{ParseFatalException}, but thrown internally when an - 266 L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop - 267 immediately because an unbacktrackable syntax error has been found""" - 268 pass -
269 -
270 #~ class ReparseException(ParseBaseException): - 271 #~ """Experimental class - parse actions can raise this exception to cause - 272 #~ pyparsing to reparse the input string: - 273 #~ - with a modified input string, and/or - 274 #~ - with a modified start location - 275 #~ Set the values of the ReparseException in the constructor, and raise the - 276 #~ exception in a parse action to cause pyparsing to use the new string/location. - 277 #~ Setting the values as None causes no change to be made. - 278 #~ """ - 279 #~ def __init_( self, newstring, restartLoc ): - 280 #~ self.newParseText = newstring - 281 #~ self.reparseLoc = restartLoc - 282 - 283 -class RecursiveGrammarException(Exception): -
284 """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" -
285 - def __init__( self, parseElementList ): -
286 self.parseElementTrace = parseElementList -
287 -
288 - def __str__( self ): -
289 return "RecursiveGrammarException: %s" % self.parseElementTrace -
290 -
291 -class _ParseResultsWithOffset(object): -
292 - def __init__(self,p1,p2): -
293 self.tup = (p1,p2) -
294 - def __getitem__(self,i): -
295 return self.tup[i] -
296 - def __repr__(self): -
297 return repr(self.tup[0]) -
298 - def setOffset(self,i): -
299 self.tup = (self.tup[0],i) -
300 -
301 -class ParseResults(object): -
302 """ - 303 Structured parse results, to provide multiple means of access to the parsed data: - 304 - as a list (C{len(results)}) - 305 - by list index (C{results[0], results[1]}, etc.) - 306 - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) - 307 - 308 Example:: - 309 integer = Word(nums) - 310 date_str = (integer.setResultsName("year") + '/' - 311 + integer.setResultsName("month") + '/' - 312 + integer.setResultsName("day")) - 313 # equivalent form: - 314 # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - 315 - 316 # parseString returns a ParseResults object - 317 result = date_str.parseString("1999/12/31") - 318 - 319 def test(s, fn=repr): - 320 print("%s -> %s" % (s, fn(eval(s)))) - 321 test("list(result)") - 322 test("result[0]") - 323 test("result['month']") - 324 test("result.day") - 325 test("'month' in result") - 326 test("'minutes' in result") - 327 test("result.dump()", str) - 328 prints:: - 329 list(result) -> ['1999', '/', '12', '/', '31'] - 330 result[0] -> '1999' - 331 result['month'] -> '12' - 332 result.day -> '31' - 333 'month' in result -> True - 334 'minutes' in result -> False - 335 result.dump() -> ['1999', '/', '12', '/', '31'] - 336 - day: 31 - 337 - month: 12 - 338 - year: 1999 - 339 """ -
340 - def __new__(cls, toklist=None, name=None, asList=True, modal=True ): -
341 if isinstance(toklist, cls): - 342 return toklist - 343 retobj = object.__new__(cls) - 344 retobj.__doinit = True - 345 return retobj -
346 - 347 # Performance tuning: we construct a *lot* of these, so keep this - 348 # constructor as small and fast as possible -
349 - def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): -
350 if self.__doinit: - 351 self.__doinit = False - 352 self.__name = None - 353 self.__parent = None - 354 self.__accumNames = {} - 355 self.__asList = asList - 356 self.__modal = modal - 357 if toklist is None: - 358 toklist = [] - 359 if isinstance(toklist, list): - 360 self.__toklist = toklist[:] - 361 elif isinstance(toklist, _generatorType): - 362 self.__toklist = list(toklist) - 363 else: - 364 self.__toklist = [toklist] - 365 self.__tokdict = dict() - 366 - 367 if name is not None and name: - 368 if not modal: - 369 self.__accumNames[name] = 0 - 370 if isinstance(name,int): - 371 name = _ustr(name) # will always return a str, but use _ustr for consistency - 372 self.__name = name - 373 if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): - 374 if isinstance(toklist,basestring): - 375 toklist = [ toklist ] - 376 if asList: - 377 if isinstance(toklist,ParseResults): - 378 self[name] = _ParseResultsWithOffset(toklist.copy(),0) - 379 else: - 380 self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) - 381 self[name].__name = name - 382 else: - 383 try: - 384 self[name] = toklist[0] - 385 except (KeyError,TypeError,IndexError): - 386 self[name] = toklist -
387 -
388 - def __getitem__( self, i ): -
389 if isinstance( i, (int,slice) ): - 390 return self.__toklist[i] - 391 else: - 392 if i not in self.__accumNames: - 393 return self.__tokdict[i][-1][0] - 394 else: - 395 return ParseResults([ v[0] for v in self.__tokdict[i] ]) -
396 -
397 - def __setitem__( self, k, v, isinstance=isinstance ): -
398 if isinstance(v,_ParseResultsWithOffset): - 399 self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] - 400 sub = v[0] - 401 elif isinstance(k,(int,slice)): - 402 self.__toklist[k] = v - 403 sub = v - 404 else: - 405 self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] - 406 sub = v - 407 if isinstance(sub,ParseResults): - 408 sub.__parent = wkref(self) -
409 -
410 - def __delitem__( self, i ): -
411 if isinstance(i,(int,slice)): - 412 mylen = len( self.__toklist ) - 413 del self.__toklist[i] - 414 - 415 # convert int to slice - 416 if isinstance(i, int): - 417 if i < 0: - 418 i += mylen - 419 i = slice(i, i+1) - 420 # get removed indices - 421 removed = list(range(*i.indices(mylen))) - 422 removed.reverse() - 423 # fixup indices in token dictionary - 424 for name,occurrences in self.__tokdict.items(): - 425 for j in removed: - 426 for k, (value, position) in enumerate(occurrences): - 427 occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) - 428 else: - 429 del self.__tokdict[i] -
430 -
431 - def __contains__( self, k ): -
432 return k in self.__tokdict -
433 -
434 - def __len__( self ): return len( self.__toklist ) -
435 - def __bool__(self): return ( not not self.__toklist ) -
436 __nonzero__ = __bool__ -
437 - def __iter__( self ): return iter( self.__toklist ) -
438 - def __reversed__( self ): return iter( self.__toklist[::-1] ) -
439 - def _iterkeys( self ): -
440 if hasattr(self.__tokdict, "iterkeys"): - 441 return self.__tokdict.iterkeys() - 442 else: - 443 return iter(self.__tokdict) -
444 -
445 - def _itervalues( self ): -
446 return (self[k] for k in self._iterkeys()) -
447 -
448 - def _iteritems( self ): -
449 return ((k, self[k]) for k in self._iterkeys()) -
450 - 451 if PY_3: - 452 keys = _iterkeys - 453 """Returns an iterator of all named result keys (Python 3.x only).""" - 454 - 455 values = _itervalues - 456 """Returns an iterator of all named result values (Python 3.x only).""" - 457 - 458 items = _iteritems - 459 """Returns an iterator of all named result key-value tuples (Python 3.x only).""" - 460 - 461 else: - 462 iterkeys = _iterkeys - 463 """Returns an iterator of all named result keys (Python 2.x only).""" - 464 - 465 itervalues = _itervalues - 466 """Returns an iterator of all named result values (Python 2.x only).""" - 467 - 468 iteritems = _iteritems - 469 """Returns an iterator of all named result key-value tuples (Python 2.x only).""" - 470 -
471 - def keys( self ): -
472 """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" - 473 return list(self.iterkeys()) -
474 -
475 - def values( self ): -
476 """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" - 477 return list(self.itervalues()) -
478 -
479 - def items( self ): -
480 """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" - 481 return list(self.iteritems()) -
482 -
483 - def haskeys( self ): -
484 """Since keys() returns an iterator, this method is helpful in bypassing - 485 code that looks for the existence of any defined results names.""" - 486 return bool(self.__tokdict) -
487 -
488 - def pop( self, *args, **kwargs): -
489 """ - 490 Removes and returns item at specified index (default=C{last}). - 491 Supports both C{list} and C{dict} semantics for C{pop()}. If passed no - 492 argument or an integer argument, it will use C{list} semantics - 493 and pop tokens from the list of parsed tokens. If passed a - 494 non-integer argument (most likely a string), it will use C{dict} - 495 semantics and pop the corresponding value from any defined - 496 results names. A second default return value argument is - 497 supported, just as in C{dict.pop()}. - 498 - 499 Example:: - 500 def remove_first(tokens): - 501 tokens.pop(0) - 502 print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - 503 print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] - 504 - 505 label = Word(alphas) - 506 patt = label("LABEL") + OneOrMore(Word(nums)) - 507 print(patt.parseString("AAB 123 321").dump()) - 508 - 509 # Use pop() in a parse action to remove named result (note that corresponding value is not - 510 # removed from list form of results) - 511 def remove_LABEL(tokens): - 512 tokens.pop("LABEL") - 513 return tokens - 514 patt.addParseAction(remove_LABEL) - 515 print(patt.parseString("AAB 123 321").dump()) - 516 prints:: - 517 ['AAB', '123', '321'] - 518 - LABEL: AAB - 519 - 520 ['AAB', '123', '321'] - 521 """ - 522 if not args: - 523 args = [-1] - 524 for k,v in kwargs.items(): - 525 if k == 'default': - 526 args = (args[0], v) - 527 else: - 528 raise TypeError("pop() got an unexpected keyword argument '%s'" % k) - 529 if (isinstance(args[0], int) or - 530 len(args) == 1 or - 531 args[0] in self): - 532 index = args[0] - 533 ret = self[index] - 534 del self[index] - 535 return ret - 536 else: - 537 defaultvalue = args[1] - 538 return defaultvalue -
539 -
540 - def get(self, key, defaultValue=None): -
541 """ - 542 Returns named result matching the given key, or if there is no - 543 such name, then returns the given C{defaultValue} or C{None} if no - 544 C{defaultValue} is specified. - 545 - 546 Similar to C{dict.get()}. - 547 - 548 Example:: - 549 integer = Word(nums) - 550 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - 551 - 552 result = date_str.parseString("1999/12/31") - 553 print(result.get("year")) # -> '1999' - 554 print(result.get("hour", "not specified")) # -> 'not specified' - 555 print(result.get("hour")) # -> None - 556 """ - 557 if key in self: - 558 return self[key] - 559 else: - 560 return defaultValue -
561 -
562 - def insert( self, index, insStr ): -
563 """ - 564 Inserts new element at location index in the list of parsed tokens. - 565 - 566 Similar to C{list.insert()}. - 567 - 568 Example:: - 569 print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - 570 - 571 # use a parse action to insert the parse location in the front of the parsed results - 572 def insert_locn(locn, tokens): - 573 tokens.insert(0, locn) - 574 print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] - 575 """ - 576 self.__toklist.insert(index, insStr) - 577 # fixup indices in token dictionary - 578 for name,occurrences in self.__tokdict.items(): - 579 for k, (value, position) in enumerate(occurrences): - 580 occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) -
581 -
582 - def append( self, item ): -
583 """ - 584 Add single element to end of ParseResults list of elements. - 585 - 586 Example:: - 587 print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] - 588 - 589 # use a parse action to compute the sum of the parsed integers, and add it to the end - 590 def append_sum(tokens): - 591 tokens.append(sum(map(int, tokens))) - 592 print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] - 593 """ - 594 self.__toklist.append(item) -
595 -
596 - def extend( self, itemseq ): -
597 """ - 598 Add sequence of elements to end of ParseResults list of elements. - 599 - 600 Example:: - 601 patt = OneOrMore(Word(alphas)) - 602 - 603 # use a parse action to append the reverse of the matched strings, to make a palindrome - 604 def make_palindrome(tokens): - 605 tokens.extend(reversed([t[::-1] for t in tokens])) - 606 return ''.join(tokens) - 607 print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' - 608 """ - 609 if isinstance(itemseq, ParseResults): - 610 self += itemseq - 611 else: - 612 self.__toklist.extend(itemseq) -
613 -
614 - def clear( self ): -
615 """ - 616 Clear all elements and results names. - 617 """ - 618 del self.__toklist[:] - 619 self.__tokdict.clear() -
620 -
621 - def __getattr__( self, name ): -
622 try: - 623 return self[name] - 624 except KeyError: - 625 return "" - 626 - 627 if name in self.__tokdict: - 628 if name not in self.__accumNames: - 629 return self.__tokdict[name][-1][0] - 630 else: - 631 return ParseResults([ v[0] for v in self.__tokdict[name] ]) - 632 else: - 633 return "" -
634 -
635 - def __add__( self, other ): -
636 ret = self.copy() - 637 ret += other - 638 return ret -
639 -
640 - def __iadd__( self, other ): -
641 if other.__tokdict: - 642 offset = len(self.__toklist) - 643 addoffset = lambda a: offset if a<0 else a+offset - 644 otheritems = other.__tokdict.items() - 645 otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) - 646 for (k,vlist) in otheritems for v in vlist] - 647 for k,v in otherdictitems: - 648 self[k] = v - 649 if isinstance(v[0],ParseResults): - 650 v[0].__parent = wkref(self) - 651 - 652 self.__toklist += other.__toklist - 653 self.__accumNames.update( other.__accumNames ) - 654 return self -
655 -
656 - def __radd__(self, other): -
657 if isinstance(other,int) and other == 0: - 658 # useful for merging many ParseResults using sum() builtin - 659 return self.copy() - 660 else: - 661 # this may raise a TypeError - so be it - 662 return other + self -
663 -
664 - def __repr__( self ): -
665 return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) -
666 -
667 - def __str__( self ): -
668 return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' -
669 -
670 - def _asStringList( self, sep='' ): -
671 out = [] - 672 for item in self.__toklist: - 673 if out and sep: - 674 out.append(sep) - 675 if isinstance( item, ParseResults ): - 676 out += item._asStringList() - 677 else: - 678 out.append( _ustr(item) ) - 679 return out -
680 -
681 - def asList( self ): -
682 """ - 683 Returns the parse results as a nested list of matching tokens, all converted to strings. - 684 - 685 Example:: - 686 patt = OneOrMore(Word(alphas)) - 687 result = patt.parseString("sldkj lsdkj sldkj") - 688 # even though the result prints in string-like form, it is actually a pyparsing ParseResults - 689 print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] - 690 - 691 # Use asList() to create an actual list - 692 result_list = result.asList() - 693 print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] - 694 """ - 695 return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] -
696 -
697 - def asDict( self ): -
698 """ - 699 Returns the named parse results as a nested dictionary. - 700 - 701 Example:: - 702 integer = Word(nums) - 703 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - 704 - 705 result = date_str.parseString('12/31/1999') - 706 print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) - 707 - 708 result_dict = result.asDict() - 709 print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} - 710 - 711 # even though a ParseResults supports dict-like access, sometime you just need to have a dict - 712 import json - 713 print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable - 714 print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} - 715 """ - 716 if PY_3: - 717 item_fn = self.items - 718 else: - 719 item_fn = self.iteritems - 720 - 721 def toItem(obj): - 722 if isinstance(obj, ParseResults): - 723 if obj.haskeys(): - 724 return obj.asDict() - 725 else: - 726 return [toItem(v) for v in obj] - 727 else: - 728 return obj -
729 - 730 return dict((k,toItem(v)) for k,v in item_fn()) -
731 -
732 - def copy( self ): -
733 """ - 734 Returns a new copy of a C{ParseResults} object. - 735 """ - 736 ret = ParseResults( self.__toklist ) - 737 ret.__tokdict = self.__tokdict.copy() - 738 ret.__parent = self.__parent - 739 ret.__accumNames.update( self.__accumNames ) - 740 ret.__name = self.__name - 741 return ret -
742 -
743 - def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): -
744 """ - 745 (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. - 746 """ - 747 nl = "\n" - 748 out = [] - 749 namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() - 750 for v in vlist) - 751 nextLevelIndent = indent + " " - 752 - 753 # collapse out indents if formatting is not desired - 754 if not formatted: - 755 indent = "" - 756 nextLevelIndent = "" - 757 nl = "" - 758 - 759 selfTag = None - 760 if doctag is not None: - 761 selfTag = doctag - 762 else: - 763 if self.__name: - 764 selfTag = self.__name - 765 - 766 if not selfTag: - 767 if namedItemsOnly: - 768 return "" - 769 else: - 770 selfTag = "ITEM" - 771 - 772 out += [ nl, indent, "<", selfTag, ">" ] - 773 - 774 for i,res in enumerate(self.__toklist): - 775 if isinstance(res,ParseResults): - 776 if i in namedItems: - 777 out += [ res.asXML(namedItems[i], - 778 namedItemsOnly and doctag is None, - 779 nextLevelIndent, - 780 formatted)] - 781 else: - 782 out += [ res.asXML(None, - 783 namedItemsOnly and doctag is None, - 784 nextLevelIndent, - 785 formatted)] - 786 else: - 787 # individual token, see if there is a name for it - 788 resTag = None - 789 if i in namedItems: - 790 resTag = namedItems[i] - 791 if not resTag: - 792 if namedItemsOnly: - 793 continue - 794 else: - 795 resTag = "ITEM" - 796 xmlBodyText = _xml_escape(_ustr(res)) - 797 out += [ nl, nextLevelIndent, "<", resTag, ">", - 798 xmlBodyText, - 799 "</", resTag, ">" ] - 800 - 801 out += [ nl, indent, "</", selfTag, ">" ] - 802 return "".join(out) -
803 -
804 - def __lookup(self,sub): -
805 for k,vlist in self.__tokdict.items(): - 806 for v,loc in vlist: - 807 if sub is v: - 808 return k - 809 return None -
810 -
811 - def getName(self): -
812 r""" - 813 Returns the results name for this token expression. Useful when several - 814 different expressions might match at a particular location. - 815 - 816 Example:: - 817 integer = Word(nums) - 818 ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") - 819 house_number_expr = Suppress('#') + Word(nums, alphanums) - 820 user_data = (Group(house_number_expr)("house_number") - 821 | Group(ssn_expr)("ssn") - 822 | Group(integer)("age")) - 823 user_info = OneOrMore(user_data) - 824 - 825 result = user_info.parseString("22 111-22-3333 #221B") - 826 for item in result: - 827 print(item.getName(), ':', item[0]) - 828 prints:: - 829 age : 22 - 830 ssn : 111-22-3333 - 831 house_number : 221B - 832 """ - 833 if self.__name: - 834 return self.__name - 835 elif self.__parent: - 836 par = self.__parent() - 837 if par: - 838 return par.__lookup(self) - 839 else: - 840 return None - 841 elif (len(self) == 1 and - 842 len(self.__tokdict) == 1 and - 843 next(iter(self.__tokdict.values()))[0][1] in (0,-1)): - 844 return next(iter(self.__tokdict.keys())) - 845 else: - 846 return None -
847 -
848 - def dump(self, indent='', depth=0, full=True): -
849 """ - 850 Diagnostic method for listing out the contents of a C{ParseResults}. - 851 Accepts an optional C{indent} argument so that this string can be embedded - 852 in a nested display of other data. - 853 - 854 Example:: - 855 integer = Word(nums) - 856 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") - 857 - 858 result = date_str.parseString('12/31/1999') - 859 print(result.dump()) - 860 prints:: - 861 ['12', '/', '31', '/', '1999'] - 862 - day: 1999 - 863 - month: 31 - 864 - year: 12 - 865 """ - 866 out = [] - 867 NL = '\n' - 868 out.append( indent+_ustr(self.asList()) ) - 869 if full: - 870 if self.haskeys(): - 871 items = sorted((str(k), v) for k,v in self.items()) - 872 for k,v in items: - 873 if out: - 874 out.append(NL) - 875 out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) - 876 if isinstance(v,ParseResults): - 877 if v: - 878 out.append( v.dump(indent,depth+1) ) - 879 else: - 880 out.append(_ustr(v)) - 881 else: - 882 out.append(repr(v)) - 883 elif any(isinstance(vv,ParseResults) for vv in self): - 884 v = self - 885 for i,vv in enumerate(v): - 886 if isinstance(vv,ParseResults): - 887 out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) - 888 else: - 889 out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) - 890 - 891 return "".join(out) -
892 -
893 - def pprint(self, *args, **kwargs): -
894 """ - 895 Pretty-printer for parsed results as a list, using the C{pprint} module. - 896 Accepts additional positional or keyword args as defined for the - 897 C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) - 898 - 899 Example:: - 900 ident = Word(alphas, alphanums) - 901 num = Word(nums) - 902 func = Forward() - 903 term = ident | num | Group('(' + func + ')') - 904 func <<= ident + Group(Optional(delimitedList(term))) - 905 result = func.parseString("fna a,b,(fnb c,d,200),100") - 906 result.pprint(width=40) - 907 prints:: - 908 ['fna', - 909 ['a', - 910 'b', - 911 ['(', 'fnb', ['c', 'd', '200'], ')'], - 912 '100']] - 913 """ - 914 pprint.pprint(self.asList(), *args, **kwargs) -
915 - 916 # add support for pickle protocol -
917 - def __getstate__(self): -
918 return ( self.__toklist, - 919 ( self.__tokdict.copy(), - 920 self.__parent is not None and self.__parent() or None, - 921 self.__accumNames, - 922 self.__name ) ) -
923 -
924 - def __setstate__(self,state): -
925 self.__toklist = state[0] - 926 (self.__tokdict, - 927 par, - 928 inAccumNames, - 929 self.__name) = state[1] - 930 self.__accumNames = {} - 931 self.__accumNames.update(inAccumNames) - 932 if par is not None: - 933 self.__parent = wkref(par) - 934 else: - 935 self.__parent = None -
936 -
937 - def __getnewargs__(self): -
938 return self.__toklist, self.__name, self.__asList, self.__modal -
939 -
940 - def __dir__(self): -
941 return (dir(type(self)) + list(self.keys())) -

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 F{|7KOEieE8 diff --git a/docs/pyparsingClassDiagram.JPG b/docs/pyparsingClassDiagram.JPG deleted file mode 100644 index ef10424899c565f0f4e1067395c6a11a68728abb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236402 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�T%b9f2%Vi0Aw`szWLat!eO+OJV!HG_ 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 X+b(?7;+ROuaH?W<9%BDUxZSq9I=y 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 diff --git a/docs/pyparsingClassDiagram.PNG b/docs/pyparsingClassDiagram.PNG deleted file mode 100644 index f59baaf3929638e74d5f21565f0bf95a1aca14a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141354 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 Z+&&!R1)g40ct$~;qS&#VMq~TJQ2ao)9 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⋙L8`K{4C7h3f`%mZzs*|Ms5wW|1eM=BM6 z$7Yq~aItpcDeQ(uV|1fLi<{VL@Kot8*!UvDZ(D)>t!5~ss$m^qxM8qTZd-7{J^3}t z5x6*M%%;OVOM4%mbWWS9*Dp<%-Y&KB@s~ahz%bZD9QH_{FNp14vVWCs2ufe4UwG@< z-1#8i25T~HdPIZepP{wjpdUL~U<)(@JxSPhf)9mIuTWA;3M`3bN^H zH+b(1%$tqxLSJ8foIbkh)2BPm(4q>?QJ45`@#khjQjK*WI;3~}*8&#&Y4P;%u zf95?$0JJjd$-*!tnRDI$7!`QGl!Fr?`Gl zU0Ehj{q}Y6ioKu|xT6E+(f5HCP@e~i?4&Wxc!}-%j=R5J$TC{IKJU83l~%Jhw4Ce> zd9=?}Y^)~N<{z)2Qb?TCymO<8qkXkZSJ>rPAUTO)o(3FsWl3PWyESCJe6qC8pDS)2NGrt~1m*-c9&Gszix3Xy1*v8fbFOmH;qexIlR@efsC zB zJ~P-oKg`xJfT&5{4yK!2sM!w@8wPmBxS`3KSA*|od2n9tjZ{K7;^TM})v@s=kVPV%1*pB}el%QK1 zOHfq-tX?nY5>hN+Wui@k_xA4EKO$b)U}Z_3{w+iJ?n&CN7d!niAMBjM41SU}=w zR(Nt%l3bp_t0ZJKKXa4ngKEQ9AorEb53G&Ymc^l?aZ}QC{N50zP zZFf1dEj94TY`U$3HHed--J_gR$x|iOH;=}kxrPkuCq=8Y*+mwR-|c z5bf`y3&;= z$R2KbotcHZHSl|d(C*Bfu<0k}rCfgq{@3_iZ%y<^k4EDn}5gYDWdT|HP^oPfoA>mJ=UEYj(6a)-6!gfnHED^<9Wm706F0&^`Cv zrmX3X90X#7IUc@OJF;i0?bUss)g8Y7CnJ}A#gP9}0N=FM<)Q)eRqF(swEAe*cTdXr zssq~0#XrzBeBNKU8AuPpUUa{@i><$^f+AgZHR`3pP0*aAV&URQ3xLuCw{~h&rg?DM zCjp)HH));zn|{6W4GGbbhs)Mhi&(b(ZyVoE3QMPI)tfX4iSqr;#CtV#?VVD}O2by2 z+urI2l-`EVncXfD9kvIfY8|tEO6_6FN$Shcex~cxxkpaa4>}9CV*c(|XqVQei-4J= z!MVU5W*9CvKXYaPF+?TE$6{&dZ6?S=-IqYe)JYXSG6{S-@#Cn)U)s4_$C|yxyEW(B zpBWmi?Fio0_D96uqc231N@or^Gc_ERYFB|Qb!Nnj9gf-2B2<9S#n*K$Pl4yTaUrx> z2f~}ZT^;E=QG&Rde%P)G}a;Sf{&yL?~adF zzk{yudSzA#aE zER0b#sk7N-{ZmNzqc1=3;Hk@ -pyparsing Examples - -

942 - 943 collections.MutableMapping.register(ParseResults) -
944 - 945 -def col (loc,strg): -
946 """Returns current column within a string, counting newlines as line separators. - 947 The first column is number 1. - 948 - 949 Note: the default parsing behavior is to expand tabs in the input string - 950 before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information - 951 on parsing strings containing C{<TAB>}s, and suggested methods to maintain a - 952 consistent view of the parsed string, the parse location, and line and column - 953 positions within the parsed string. - 954 """ - 955 s = strg - 956 return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) -
957 -
958 -def lineno(loc,strg): -
959 """Returns current line number within a string, counting newlines as line separators. - 960 The first line is number 1. - 961 - 962 Note: the default parsing behavior is to expand tabs in the input string - 963 before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information - 964 on parsing strings containing C{<TAB>}s, and suggested methods to maintain a - 965 consistent view of the parsed string, the parse location, and line and column - 966 positions within the parsed string. - 967 """ - 968 return strg.count("\n",0,loc) + 1 -
969 -
970 -def line( loc, strg ): -
971 """Returns the line of text containing loc within a string, counting newlines as line separators. - 972 """ - 973 lastCR = strg.rfind("\n", 0, loc) - 974 nextCR = strg.find("\n", loc) - 975 if nextCR >= 0: - 976 return strg[lastCR+1:nextCR] - 977 else: - 978 return strg[lastCR+1:] -
979 -
980 -def _defaultStartDebugAction( instring, loc, expr ): -
981 print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) -
982 -
983 -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): -
984 print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) -
985 -
986 -def _defaultExceptionDebugAction( instring, loc, expr, exc ): -
987 print ("Exception raised:" + _ustr(exc)) -
988 -
989 -def nullDebugAction(*args): -
990 """'Do-nothing' debug action, to suppress debugging output during parsing.""" - 991 pass -
992 - 993 # Only works on Python 3.x - nonlocal is toxic to Python 2 installs - 994 #~ 'decorator to trim function calls to match the arity of the target' - 995 #~ def _trim_arity(func, maxargs=3): - 996 #~ if func in singleArgBuiltins: - 997 #~ return lambda s,l,t: func(t) - 998 #~ limit = 0 - 999 #~ foundArity = False -1000 #~ def wrapper(*args): -1001 #~ nonlocal limit,foundArity -1002 #~ while 1: -1003 #~ try: -1004 #~ ret = func(*args[limit:]) -1005 #~ foundArity = True -1006 #~ return ret -1007 #~ except TypeError: -1008 #~ if limit == maxargs or foundArity: -1009 #~ raise -1010 #~ limit += 1 -1011 #~ continue -1012 #~ return wrapper -1013 -1014 # this version is Python 2.x-3.x cross-compatible -1015 'decorator to trim function calls to match the arity of the target' -
1016 -def _trim_arity(func, maxargs=2): -
1017 if func in singleArgBuiltins: -1018 return lambda s,l,t: func(t) -1019 limit = [0] -1020 foundArity = [False] -1021 -1022 # traceback return data structure changed in Py3.5 - normalize back to plain tuples -1023 if system_version[:2] >= (3,5): -1024 def extract_stack(limit=0): -1025 # special handling for Python 3.5.0 - extra deep call stack by 1 -1026 offset = -3 if system_version == (3,5,0) else -2 -1027 frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] -1028 return [(frame_summary.filename, frame_summary.lineno)] -
1029 def extract_tb(tb, limit=0): -1030 frames = traceback.extract_tb(tb, limit=limit) -1031 frame_summary = frames[-1] -1032 return [(frame_summary.filename, frame_summary.lineno)] -1033 else: -1034 extract_stack = traceback.extract_stack -1035 extract_tb = traceback.extract_tb -1036 -1037 # synthesize what would be returned by traceback.extract_stack at the call to -1038 # user's parse action 'func', so that we don't incur call penalty at parse time -1039 -1040 LINE_DIFF = 6 -1041 # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND -1042 # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! -1043 this_line = extract_stack(limit=2)[-1] -1044 pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) -1045 -1046 def wrapper(*args): -1047 while 1: -1048 try: -1049 ret = func(*args[limit[0]:]) -1050 foundArity[0] = True -1051 return ret -1052 except TypeError: -1053 # re-raise TypeErrors if they did not come from our arity testing -1054 if foundArity[0]: -1055 raise -1056 else: -1057 try: -1058 tb = sys.exc_info()[-1] -1059 if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: -1060 raise -1061 finally: -1062 del tb -1063 -1064 if limit[0] <= maxargs: -1065 limit[0] += 1 -1066 continue -1067 raise -1068 -1069 # copy func name to wrapper for sensible debug output -1070 func_name = "<parse action>" -1071 try: -1072 func_name = getattr(func, '__name__', -1073 getattr(func, '__class__').__name__) -1074 except Exception: -1075 func_name = str(func) -1076 wrapper.__name__ = func_name -1077 -1078 return wrapper -1079 -
1080 -class ParserElement(object): -
1081 """Abstract base level parser element class.""" -1082 DEFAULT_WHITE_CHARS = " \n\t\r" -1083 verbose_stacktrace = False -1084 -1085 @staticmethod -
1086 - def setDefaultWhitespaceChars( chars ): -
1087 r""" -1088 Overrides the default whitespace chars -1089 -1090 Example:: -1091 # default whitespace chars are space, <TAB> and newline -1092 OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] -1093 -1094 # change to just treat newline as significant -1095 ParserElement.setDefaultWhitespaceChars(" \t") -1096 OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] -1097 """ -1098 ParserElement.DEFAULT_WHITE_CHARS = chars -
1099 -1100 @staticmethod -
1101 - def inlineLiteralsUsing(cls): -
1102 """ -1103 Set class to be used for inclusion of string literals into a parser. -1104 -1105 Example:: -1106 # default literal class used is Literal -1107 integer = Word(nums) -1108 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") -1109 -1110 date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] -1111 -1112 -1113 # change to Suppress -1114 ParserElement.inlineLiteralsUsing(Suppress) -1115 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") -1116 -1117 date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] -1118 """ -1119 ParserElement._literalStringClass = cls -
1120 -
1121 - def __init__( self, savelist=False ): -
1122 self.parseAction = list() -1123 self.failAction = None -1124 #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall -1125 self.strRepr = None -1126 self.resultsName = None -1127 self.saveAsList = savelist -1128 self.skipWhitespace = True -1129 self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS -1130 self.copyDefaultWhiteChars = True -1131 self.mayReturnEmpty = False # used when checking for left-recursion -1132 self.keepTabs = False -1133 self.ignoreExprs = list() -1134 self.debug = False -1135 self.streamlined = False -1136 self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index -1137 self.errmsg = "" -1138 self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) -1139 self.debugActions = ( None, None, None ) #custom debug actions -1140 self.re = None -1141 self.callPreparse = True # used to avoid redundant calls to preParse -1142 self.callDuringTry = False -
1143 -
1144 - def copy( self ): -
1145 """ -1146 Make a copy of this C{ParserElement}. Useful for defining different parse actions -1147 for the same parsing pattern, using copies of the original parse element. -1148 -1149 Example:: -1150 integer = Word(nums).setParseAction(lambda toks: int(toks[0])) -1151 integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") -1152 integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") -1153 -1154 print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) -1155 prints:: -1156 [5120, 100, 655360, 268435456] -1157 Equivalent form of C{expr.copy()} is just C{expr()}:: -1158 integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") -1159 """ -1160 cpy = copy.copy( self ) -1161 cpy.parseAction = self.parseAction[:] -1162 cpy.ignoreExprs = self.ignoreExprs[:] -1163 if self.copyDefaultWhiteChars: -1164 cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS -1165 return cpy -
1166 -
1167 - def setName( self, name ): -
1168 """ -1169 Define name for this expression, makes debugging and exception messages clearer. -1170 -1171 Example:: -1172 Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) -1173 Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) -1174 """ -1175 self.name = name -1176 self.errmsg = "Expected " + self.name -1177 if hasattr(self,"exception"): -1178 self.exception.msg = self.errmsg -1179 return self -
1180 -
1181 - def setResultsName( self, name, listAllMatches=False ): -
1182 """ -1183 Define name for referencing matching tokens as a nested attribute -1184 of the returned parse results. -1185 NOTE: this returns a *copy* of the original C{ParserElement} object; -1186 this is so that the client can define a basic element, such as an -1187 integer, and reference it in multiple places with different names. -1188 -1189 You can also set results names using the abbreviated syntax, -1190 C{expr("name")} in place of C{expr.setResultsName("name")} - -1191 see L{I{__call__}<__call__>}. -1192 -1193 Example:: -1194 date_str = (integer.setResultsName("year") + '/' -1195 + integer.setResultsName("month") + '/' -1196 + integer.setResultsName("day")) -1197 -1198 # equivalent form: -1199 date_str = integer("year") + '/' + integer("month") + '/' + integer("day") -1200 """ -1201 newself = self.copy() -1202 if name.endswith("*"): -1203 name = name[:-1] -1204 listAllMatches=True -1205 newself.resultsName = name -1206 newself.modalResults = not listAllMatches -1207 return newself -
1208 -
1209 - def setBreak(self,breakFlag = True): -
1210 """Method to invoke the Python pdb debugger when this element is -1211 about to be parsed. Set C{breakFlag} to True to enable, False to -1212 disable. -1213 """ -1214 if breakFlag: -1215 _parseMethod = self._parse -1216 def breaker(instring, loc, doActions=True, callPreParse=True): -1217 import pdb -1218 pdb.set_trace() -1219 return _parseMethod( instring, loc, doActions, callPreParse ) -
1220 breaker._originalParseMethod = _parseMethod -1221 self._parse = breaker -1222 else: -1223 if hasattr(self._parse,"_originalParseMethod"): -1224 self._parse = self._parse._originalParseMethod -1225 return self -
1226 -
1227 - def setParseAction( self, *fns, **kwargs ): -
1228 """ -1229 Define one or more actions to perform when successfully matching parse element definition. -1230 Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, -1231 C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: -1232 - s = the original string being parsed (see note below) -1233 - loc = the location of the matching substring -1234 - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object -1235 If the functions in fns modify the tokens, they can return them as the return -1236 value from fn, and the modified list of tokens will replace the original. -1237 Otherwise, fn does not need to return any value. -1238 -1239 Optional keyword arguments: -1240 - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing -1241 -1242 Note: the default parsing behavior is to expand tabs in the input string -1243 before starting the parsing process. See L{I{parseString}<parseString>} for more information -1244 on parsing strings containing C{<TAB>}s, and suggested methods to maintain a -1245 consistent view of the parsed string, the parse location, and line and column -1246 positions within the parsed string. -1247 -1248 Example:: -1249 integer = Word(nums) -1250 date_str = integer + '/' + integer + '/' + integer -1251 -1252 date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] -1253 -1254 # use parse action to convert to ints at parse time -1255 integer = Word(nums).setParseAction(lambda toks: int(toks[0])) -1256 date_str = integer + '/' + integer + '/' + integer -1257 -1258 # note that integer fields are now ints, not strings -1259 date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] -1260 """ -1261 self.parseAction = list(map(_trim_arity, list(fns))) -1262 self.callDuringTry = kwargs.get("callDuringTry", False) -1263 return self -
1264 -
1265 - def addParseAction( self, *fns, **kwargs ): -
1266 """ -1267 Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. -1268 -1269 See examples in L{I{copy}<copy>}. -1270 """ -1271 self.parseAction += list(map(_trim_arity, list(fns))) -1272 self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) -1273 return self -
1274 -
1275 - def addCondition(self, *fns, **kwargs): -
1276 """Add a boolean predicate function to expression's list of parse actions. See -1277 L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, -1278 functions passed to C{addCondition} need to return boolean success/fail of the condition. -1279 -1280 Optional keyword arguments: -1281 - message = define a custom message to be used in the raised exception -1282 - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException -1283 -1284 Example:: -1285 integer = Word(nums).setParseAction(lambda toks: int(toks[0])) -1286 year_int = integer.copy() -1287 year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") -1288 date_str = year_int + '/' + integer + '/' + integer -1289 -1290 result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) -1291 """ -1292 msg = kwargs.get("message", "failed user-defined condition") -1293 exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException -1294 for fn in fns: -1295 def pa(s,l,t): -1296 if not bool(_trim_arity(fn)(s,l,t)): -1297 raise exc_type(s,l,msg) -
1298 self.parseAction.append(pa) -1299 self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) -1300 return self -1301 -
1302 - def setFailAction( self, fn ): -
1303 """Define action to perform if parsing fails at this expression. -1304 Fail acton fn is a callable function that takes the arguments -1305 C{fn(s,loc,expr,err)} where: -1306 - s = string being parsed -1307 - loc = location where expression match was attempted and failed -1308 - expr = the parse expression that failed -1309 - err = the exception thrown -1310 The function returns no value. It may throw C{L{ParseFatalException}} -1311 if it is desired to stop parsing immediately.""" -1312 self.failAction = fn -1313 return self -
1314 -
1315 - def _skipIgnorables( self, instring, loc ): -
1316 exprsFound = True -1317 while exprsFound: -1318 exprsFound = False -1319 for e in self.ignoreExprs: -1320 try: -1321 while 1: -1322 loc,dummy = e._parse( instring, loc ) -1323 exprsFound = True -1324 except ParseException: -1325 pass -1326 return loc -
1327 -
1328 - def preParse( self, instring, loc ): -
1329 if self.ignoreExprs: -1330 loc = self._skipIgnorables( instring, loc ) -1331 -1332 if self.skipWhitespace: -1333 wt = self.whiteChars -1334 instrlen = len(instring) -1335 while loc < instrlen and instring[loc] in wt: -1336 loc += 1 -1337 -1338 return loc -
1339 -
1340 - def parseImpl( self, instring, loc, doActions=True ): -
1341 return loc, [] -
1342 -
1343 - def postParse( self, instring, loc, tokenlist ): -
1344 return tokenlist -
1345 -1346 #~ @profile -
1347 - def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): -
1348 debugging = ( self.debug ) #and doActions ) -1349 -1350 if debugging or self.failAction: -1351 #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) -1352 if (self.debugActions[0] ): -1353 self.debugActions[0]( instring, loc, self ) -1354 if callPreParse and self.callPreparse: -1355 preloc = self.preParse( instring, loc ) -1356 else: -1357 preloc = loc -1358 tokensStart = preloc -1359 try: -1360 try: -1361 loc,tokens = self.parseImpl( instring, preloc, doActions ) -1362 except IndexError: -1363 raise ParseException( instring, len(instring), self.errmsg, self ) -1364 except ParseBaseException as err: -1365 #~ print ("Exception raised:", err) -1366 if self.debugActions[2]: -1367 self.debugActions[2]( instring, tokensStart, self, err ) -1368 if self.failAction: -1369 self.failAction( instring, tokensStart, self, err ) -1370 raise -1371 else: -1372 if callPreParse and self.callPreparse: -1373 preloc = self.preParse( instring, loc ) -1374 else: -1375 preloc = loc -1376 tokensStart = preloc -1377 if self.mayIndexError or loc >= len(instring): -1378 try: -1379 loc,tokens = self.parseImpl( instring, preloc, doActions ) -1380 except IndexError: -1381 raise ParseException( instring, len(instring), self.errmsg, self ) -1382 else: -1383 loc,tokens = self.parseImpl( instring, preloc, doActions ) -1384 -1385 tokens = self.postParse( instring, loc, tokens ) -1386 -1387 retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) -1388 if self.parseAction and (doActions or self.callDuringTry): -1389 if debugging: -1390 try: -1391 for fn in self.parseAction: -1392 tokens = fn( instring, tokensStart, retTokens ) -1393 if tokens is not None: -1394 retTokens = ParseResults( tokens, -1395 self.resultsName, -1396 asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), -1397 modal=self.modalResults ) -1398 except ParseBaseException as err: -1399 #~ print "Exception raised in user parse action:", err -1400 if (self.debugActions[2] ): -1401 self.debugActions[2]( instring, tokensStart, self, err ) -1402 raise -1403 else: -1404 for fn in self.parseAction: -1405 tokens = fn( instring, tokensStart, retTokens ) -1406 if tokens is not None: -1407 retTokens = ParseResults( tokens, -1408 self.resultsName, -1409 asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), -1410 modal=self.modalResults ) -1411 -1412 if debugging: -1413 #~ print ("Matched",self,"->",retTokens.asList()) -1414 if (self.debugActions[1] ): -1415 self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) -1416 -1417 return loc, retTokens -
1418 -
1419 - def tryParse( self, instring, loc ): -
1420 try: -1421 return self._parse( instring, loc, doActions=False )[0] -1422 except ParseFatalException: -1423 raise ParseException( instring, loc, self.errmsg, self) -
1424 -
1425 - def canParseNext(self, instring, loc): -
1426 try: -1427 self.tryParse(instring, loc) -1428 except (ParseException, IndexError): -1429 return False -1430 else: -1431 return True -
1432 -
1433 - class _UnboundedCache(object): -
1434 - def __init__(self): -
1435 cache = {} -1436 self.not_in_cache = not_in_cache = object() -1437 -1438 def get(self, key): -1439 return cache.get(key, not_in_cache) -
1440 -1441 def set(self, key, value): -1442 cache[key] = value -
1443 -1444 def clear(self): -1445 cache.clear() -1446 -1447 def cache_len(self): -1448 return len(cache) -1449 -1450 self.get = types.MethodType(get, self) -1451 self.set = types.MethodType(set, self) -1452 self.clear = types.MethodType(clear, self) -1453 self.__len__ = types.MethodType(cache_len, self) -1454 -1455 if _OrderedDict is not None: -
1456 - class _FifoCache(object): -
1457 - def __init__(self, size): -
1458 self.not_in_cache = not_in_cache = object() -1459 -1460 cache = _OrderedDict() -1461 -1462 def get(self, key): -1463 return cache.get(key, not_in_cache) -
1464 -1465 def set(self, key, value): -1466 cache[key] = value -1467 while len(cache) > size: -1468 try: -1469 cache.popitem(False) -1470 except KeyError: -1471 pass -
1472 -1473 def clear(self): -1474 cache.clear() -1475 -1476 def cache_len(self): -1477 return len(cache) -1478 -1479 self.get = types.MethodType(get, self) -1480 self.set = types.MethodType(set, self) -1481 self.clear = types.MethodType(clear, self) -1482 self.__len__ = types.MethodType(cache_len, self) -1483 -1484 else: -
1485 - class _FifoCache(object): -
1486 - def __init__(self, size): -
1487 self.not_in_cache = not_in_cache = object() -1488 -1489 cache = {} -1490 key_fifo = collections.deque([], size) -1491 -1492 def get(self, key): -1493 return cache.get(key, not_in_cache) -
1494 -1495 def set(self, key, value): -1496 cache[key] = value -1497 while len(key_fifo) > size: -1498 cache.pop(key_fifo.popleft(), None) -1499 key_fifo.append(key) -
1500 -1501 def clear(self): -1502 cache.clear() -1503 key_fifo.clear() -1504 -1505 def cache_len(self): -1506 return len(cache) -1507 -1508 self.get = types.MethodType(get, self) -1509 self.set = types.MethodType(set, self) -1510 self.clear = types.MethodType(clear, self) -1511 self.__len__ = types.MethodType(cache_len, self) -1512 -1513 # argument cache for optimizing repeated calls when backtracking through recursive expressions -1514 packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail -1515 packrat_cache_lock = RLock() -1516 packrat_cache_stats = [0, 0] -1517 -1518 # this method gets repeatedly called during backtracking with the same arguments - -1519 # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression -
1520 - def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): -
1521 HIT, MISS = 0, 1 -1522 lookup = (self, instring, loc, callPreParse, doActions) -1523 with ParserElement.packrat_cache_lock: -1524 cache = ParserElement.packrat_cache -1525 value = cache.get(lookup) -1526 if value is cache.not_in_cache: -1527 ParserElement.packrat_cache_stats[MISS] += 1 -1528 try: -1529 value = self._parseNoCache(instring, loc, doActions, callPreParse) -1530 except ParseBaseException as pe: -1531 # cache a copy of the exception, without the traceback -1532 cache.set(lookup, pe.__class__(*pe.args)) -1533 raise -1534 else: -1535 cache.set(lookup, (value[0], value[1].copy())) -1536 return value -1537 else: -1538 ParserElement.packrat_cache_stats[HIT] += 1 -1539 if isinstance(value, Exception): -1540 raise value -1541 return (value[0], value[1].copy()) -
1542 -1543 _parse = _parseNoCache -1544 -1545 @staticmethod -
1546 - def resetCache(): -
1549 -1550 _packratEnabled = False -1551 @staticmethod -
1552 - def enablePackrat(cache_size_limit=128): -
1553 """Enables "packrat" parsing, which adds memoizing to the parsing logic. -1554 Repeated parse attempts at the same string location (which happens -1555 often in many complex grammars) can immediately return a cached value, -1556 instead of re-executing parsing/validating code. Memoizing is done of -1557 both valid results and parsing exceptions. -1558 -1559 Parameters: -1560 - cache_size_limit - (default=C{128}) - if an integer value is provided -1561 will limit the size of the packrat cache; if None is passed, then -1562 the cache size will be unbounded; if 0 is passed, the cache will -1563 be effectively disabled. -1564 -1565 This speedup may break existing programs that use parse actions that -1566 have side-effects. For this reason, packrat parsing is disabled when -1567 you first import pyparsing. To activate the packrat feature, your -1568 program must call the class method C{ParserElement.enablePackrat()}. If -1569 your program uses C{psyco} to "compile as you go", you must call -1570 C{enablePackrat} before calling C{psyco.full()}. If you do not do this, -1571 Python will crash. For best results, call C{enablePackrat()} immediately -1572 after importing pyparsing. -1573 -1574 Example:: -1575 import pyparsing -1576 pyparsing.ParserElement.enablePackrat() -1577 """ -1578 if not ParserElement._packratEnabled: -1579 ParserElement._packratEnabled = True -1580 if cache_size_limit is None: -1581 ParserElement.packrat_cache = ParserElement._UnboundedCache() -1582 else: -1583 ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) -1584 ParserElement._parse = ParserElement._parseCache -
1585 -
1586 - def parseString( self, instring, parseAll=False ): -
1587 """ -1588 Execute the parse expression with the given string. -1589 This is the main interface to the client code, once the complete -1590 expression has been built. -1591 -1592 If you want the grammar to require that the entire input string be -1593 successfully parsed, then set C{parseAll} to True (equivalent to ending -1594 the grammar with C{L{StringEnd()}}). -1595 -1596 Note: C{parseString} implicitly calls C{expandtabs()} on the input string, -1597 in order to report proper column numbers in parse actions. -1598 If the input string contains tabs and -1599 the grammar uses parse actions that use the C{loc} argument to index into the -1600 string being parsed, you can ensure you have a consistent view of the input -1601 string by: -1602 - calling C{parseWithTabs} on your grammar before calling C{parseString} -1603 (see L{I{parseWithTabs}<parseWithTabs>}) -1604 - define your parse action using the full C{(s,loc,toks)} signature, and -1605 reference the input string using the parse action's C{s} argument -1606 - explictly expand the tabs in your input string before calling -1607 C{parseString} -1608 -1609 Example:: -1610 Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] -1611 Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text -1612 """ -1613 ParserElement.resetCache() -1614 if not self.streamlined: -1615 self.streamline() -1616 #~ self.saveAsList = True -1617 for e in self.ignoreExprs: -1618 e.streamline() -1619 if not self.keepTabs: -1620 instring = instring.expandtabs() -1621 try: -1622 loc, tokens = self._parse( instring, 0 ) -1623 if parseAll: -1624 loc = self.preParse( instring, loc ) -1625 se = Empty() + StringEnd() -1626 se._parse( instring, loc ) -1627 except ParseBaseException as exc: -1628 if ParserElement.verbose_stacktrace: -1629 raise -1630 else: -1631 # catch and re-raise exception from here, clears out pyparsing internal stack trace -1632 raise exc -1633 else: -1634 return tokens -
1635 -
1636 - def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): -
1637 """ -1638 Scan the input string for expression matches. Each match will return the -1639 matching tokens, start location, and end location. May be called with optional -1640 C{maxMatches} argument, to clip scanning after 'n' matches are found. If -1641 C{overlap} is specified, then overlapping matches will be reported. -1642 -1643 Note that the start and end locations are reported relative to the string -1644 being parsed. See L{I{parseString}<parseString>} for more information on parsing -1645 strings with embedded tabs. -1646 -1647 Example:: -1648 source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" -1649 print(source) -1650 for tokens,start,end in Word(alphas).scanString(source): -1651 print(' '*start + '^'*(end-start)) -1652 print(' '*start + tokens[0]) -1653 -1654 prints:: -1655 -1656 sldjf123lsdjjkf345sldkjf879lkjsfd987 -1657 ^^^^^ -1658 sldjf -1659 ^^^^^^^ -1660 lsdjjkf -1661 ^^^^^^ -1662 sldkjf -1663 ^^^^^^ -1664 lkjsfd -1665 """ -1666 if not self.streamlined: -1667 self.streamline() -1668 for e in self.ignoreExprs: -1669 e.streamline() -1670 -1671 if not self.keepTabs: -1672 instring = _ustr(instring).expandtabs() -1673 instrlen = len(instring) -1674 loc = 0 -1675 preparseFn = self.preParse -1676 parseFn = self._parse -1677 ParserElement.resetCache() -1678 matches = 0 -1679 try: -1680 while loc <= instrlen and matches < maxMatches: -1681 try: -1682 preloc = preparseFn( instring, loc ) -1683 nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) -1684 except ParseException: -1685 loc = preloc+1 -1686 else: -1687 if nextLoc > loc: -1688 matches += 1 -1689 yield tokens, preloc, nextLoc -1690 if overlap: -1691 nextloc = preparseFn( instring, loc ) -1692 if nextloc > loc: -1693 loc = nextLoc -1694 else: -1695 loc += 1 -1696 else: -1697 loc = nextLoc -1698 else: -1699 loc = preloc+1 -1700 except ParseBaseException as exc: -1701 if ParserElement.verbose_stacktrace: -1702 raise -1703 else: -1704 # catch and re-raise exception from here, clears out pyparsing internal stack trace -1705 raise exc -
1706 -
1707 - def transformString( self, instring ): -
1708 """ -1709 Extension to C{L{scanString}}, to modify matching text with modified tokens that may -1710 be returned from a parse action. To use C{transformString}, define a grammar and -1711 attach a parse action to it that modifies the returned token list. -1712 Invoking C{transformString()} on a target string will then scan for matches, -1713 and replace the matched text patterns according to the logic in the parse -1714 action. C{transformString()} returns the resulting transformed string. -1715 -1716 Example:: -1717 wd = Word(alphas) -1718 wd.setParseAction(lambda toks: toks[0].title()) -1719 -1720 print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) -1721 Prints:: -1722 Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. -1723 """ -1724 out = [] -1725 lastE = 0 -1726 # force preservation of <TAB>s, to minimize unwanted transformation of string, and to -1727 # keep string locs straight between transformString and scanString -1728 self.keepTabs = True -1729 try: -1730 for t,s,e in self.scanString( instring ): -1731 out.append( instring[lastE:s] ) -1732 if t: -1733 if isinstance(t,ParseResults): -1734 out += t.asList() -1735 elif isinstance(t,list): -1736 out += t -1737 else: -1738 out.append(t) -1739 lastE = e -1740 out.append(instring[lastE:]) -1741 out = [o for o in out if o] -1742 return "".join(map(_ustr,_flatten(out))) -1743 except ParseBaseException as exc: -1744 if ParserElement.verbose_stacktrace: -1745 raise -1746 else: -1747 # catch and re-raise exception from here, clears out pyparsing internal stack trace -1748 raise exc -
1749 -
1750 - def searchString( self, instring, maxMatches=_MAX_INT ): -
1751 """ -1752 Another extension to C{L{scanString}}, simplifying the access to the tokens found -1753 to match the given parse expression. May be called with optional -1754 C{maxMatches} argument, to clip searching after 'n' matches are found. -1755 -1756 Example:: -1757 # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters -1758 cap_word = Word(alphas.upper(), alphas.lower()) -1759 -1760 print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) -1761 -1762 # the sum() builtin can be used to merge results into a single ParseResults object -1763 print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) -1764 prints:: -1765 [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] -1766 ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] -1767 """ -1768 try: -1769 return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) -1770 except ParseBaseException as exc: -1771 if ParserElement.verbose_stacktrace: -1772 raise -1773 else: -1774 # catch and re-raise exception from here, clears out pyparsing internal stack trace -1775 raise exc -
1776 -
1777 - def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): -
1778 """ -1779 Generator method to split a string using the given expression as a separator. -1780 May be called with optional C{maxsplit} argument, to limit the number of splits; -1781 and the optional C{includeSeparators} argument (default=C{False}), if the separating -1782 matching text should be included in the split results. -1783 -1784 Example:: -1785 punc = oneOf(list(".,;:/-!?")) -1786 print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) -1787 prints:: -1788 ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] -1789 """ -1790 splits = 0 -1791 last = 0 -1792 for t,s,e in self.scanString(instring, maxMatches=maxsplit): -1793 yield instring[last:s] -1794 if includeSeparators: -1795 yield t[0] -1796 last = e -1797 yield instring[last:] -
1798 -
1799 - def __add__(self, other ): -
1800 """ -1801 Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement -1802 converts them to L{Literal}s by default. -1803 -1804 Example:: -1805 greet = Word(alphas) + "," + Word(alphas) + "!" -1806 hello = "Hello, World!" -1807 print (hello, "->", greet.parseString(hello)) -1808 Prints:: -1809 Hello, World! -> ['Hello', ',', 'World', '!'] -1810 """ -1811 if isinstance( other, basestring ): -1812 other = ParserElement._literalStringClass( other ) -1813 if not isinstance( other, ParserElement ): -1814 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1815 SyntaxWarning, stacklevel=2) -1816 return None -1817 return And( [ self, other ] ) -
1818 -
1819 - def __radd__(self, other ): -
1820 """ -1821 Implementation of + operator when left operand is not a C{L{ParserElement}} -1822 """ -1823 if isinstance( other, basestring ): -1824 other = ParserElement._literalStringClass( other ) -1825 if not isinstance( other, ParserElement ): -1826 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1827 SyntaxWarning, stacklevel=2) -1828 return None -1829 return other + self -
1830 -
1831 - def __sub__(self, other): -
1832 """ -1833 Implementation of - operator, returns C{L{And}} with error stop -1834 """ -1835 if isinstance( other, basestring ): -1836 other = ParserElement._literalStringClass( other ) -1837 if not isinstance( other, ParserElement ): -1838 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1839 SyntaxWarning, stacklevel=2) -1840 return None -1841 return self + And._ErrorStop() + other -
1842 -
1843 - def __rsub__(self, other ): -
1844 """ -1845 Implementation of - operator when left operand is not a C{L{ParserElement}} -1846 """ -1847 if isinstance( other, basestring ): -1848 other = ParserElement._literalStringClass( other ) -1849 if not isinstance( other, ParserElement ): -1850 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1851 SyntaxWarning, stacklevel=2) -1852 return None -1853 return other - self -
1854 -
1855 - def __mul__(self,other): -
1856 """ -1857 Implementation of * operator, allows use of C{expr * 3} in place of -1858 C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer -1859 tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples -1860 may also include C{None} as in: -1861 - C{expr*(n,None)} or C{expr*(n,)} is equivalent -1862 to C{expr*n + L{ZeroOrMore}(expr)} -1863 (read as "at least n instances of C{expr}") -1864 - C{expr*(None,n)} is equivalent to C{expr*(0,n)} -1865 (read as "0 to n instances of C{expr}") -1866 - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} -1867 - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} -1868 -1869 Note that C{expr*(None,n)} does not raise an exception if -1870 more than n exprs exist in the input stream; that is, -1871 C{expr*(None,n)} does not enforce a maximum number of expr -1872 occurrences. If this behavior is desired, then write -1873 C{expr*(None,n) + ~expr} -1874 """ -1875 if isinstance(other,int): -1876 minElements, optElements = other,0 -1877 elif isinstance(other,tuple): -1878 other = (other + (None, None))[:2] -1879 if other[0] is None: -1880 other = (0, other[1]) -1881 if isinstance(other[0],int) and other[1] is None: -1882 if other[0] == 0: -1883 return ZeroOrMore(self) -1884 if other[0] == 1: -1885 return OneOrMore(self) -1886 else: -1887 return self*other[0] + ZeroOrMore(self) -1888 elif isinstance(other[0],int) and isinstance(other[1],int): -1889 minElements, optElements = other -1890 optElements -= minElements -1891 else: -1892 raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) -1893 else: -1894 raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) -1895 -1896 if minElements < 0: -1897 raise ValueError("cannot multiply ParserElement by negative value") -1898 if optElements < 0: -1899 raise ValueError("second tuple value must be greater or equal to first tuple value") -1900 if minElements == optElements == 0: -1901 raise ValueError("cannot multiply ParserElement by 0 or (0,0)") -1902 -1903 if (optElements): -1904 def makeOptionalList(n): -1905 if n>1: -1906 return Optional(self + makeOptionalList(n-1)) -1907 else: -1908 return Optional(self) -
1909 if minElements: -1910 if minElements == 1: -1911 ret = self + makeOptionalList(optElements) -1912 else: -1913 ret = And([self]*minElements) + makeOptionalList(optElements) -1914 else: -1915 ret = makeOptionalList(optElements) -1916 else: -1917 if minElements == 1: -1918 ret = self -1919 else: -1920 ret = And([self]*minElements) -1921 return ret -1922 -
1923 - def __rmul__(self, other): -
1924 return self.__mul__(other) -
1925 -
1926 - def __or__(self, other ): -
1927 """ -1928 Implementation of | operator - returns C{L{MatchFirst}} -1929 """ -1930 if isinstance( other, basestring ): -1931 other = ParserElement._literalStringClass( other ) -1932 if not isinstance( other, ParserElement ): -1933 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1934 SyntaxWarning, stacklevel=2) -1935 return None -1936 return MatchFirst( [ self, other ] ) -
1937 -
1938 - def __ror__(self, other ): -
1939 """ -1940 Implementation of | operator when left operand is not a C{L{ParserElement}} -1941 """ -1942 if isinstance( other, basestring ): -1943 other = ParserElement._literalStringClass( other ) -1944 if not isinstance( other, ParserElement ): -1945 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1946 SyntaxWarning, stacklevel=2) -1947 return None -1948 return other | self -
1949 -
1950 - def __xor__(self, other ): -
1951 """ -1952 Implementation of ^ operator - returns C{L{Or}} -1953 """ -1954 if isinstance( other, basestring ): -1955 other = ParserElement._literalStringClass( other ) -1956 if not isinstance( other, ParserElement ): -1957 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1958 SyntaxWarning, stacklevel=2) -1959 return None -1960 return Or( [ self, other ] ) -
1961 -
1962 - def __rxor__(self, other ): -
1963 """ -1964 Implementation of ^ operator when left operand is not a C{L{ParserElement}} -1965 """ -1966 if isinstance( other, basestring ): -1967 other = ParserElement._literalStringClass( other ) -1968 if not isinstance( other, ParserElement ): -1969 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1970 SyntaxWarning, stacklevel=2) -1971 return None -1972 return other ^ self -
1973 -
1974 - def __and__(self, other ): -
1975 """ -1976 Implementation of & operator - returns C{L{Each}} -1977 """ -1978 if isinstance( other, basestring ): -1979 other = ParserElement._literalStringClass( other ) -1980 if not isinstance( other, ParserElement ): -1981 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1982 SyntaxWarning, stacklevel=2) -1983 return None -1984 return Each( [ self, other ] ) -
1985 -
1986 - def __rand__(self, other ): -
1987 """ -1988 Implementation of & operator when left operand is not a C{L{ParserElement}} -1989 """ -1990 if isinstance( other, basestring ): -1991 other = ParserElement._literalStringClass( other ) -1992 if not isinstance( other, ParserElement ): -1993 warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), -1994 SyntaxWarning, stacklevel=2) -1995 return None -1996 return other & self -
1997 -
1998 - def __invert__( self ): -
1999 """ -2000 Implementation of ~ operator - returns C{L{NotAny}} -2001 """ -2002 return NotAny( self ) -
2003 -
2004 - def __call__(self, name=None): -
2005 """ -2006 Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. -2007 -2008 If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be -2009 passed as C{True}. -2010 -2011 If C{name} is omitted, same as calling C{L{copy}}. -2012 -2013 Example:: -2014 # these are equivalent -2015 userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") -2016 userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") -2017 """ -2018 if name is not None: -2019 return self.setResultsName(name) -2020 else: -2021 return self.copy() -
2022 -
2023 - def suppress( self ): -
2024 """ -2025 Suppresses the output of this C{ParserElement}; useful to keep punctuation from -2026 cluttering up returned output. -2027 """ -2028 return Suppress( self ) -
2029 -
2030 - def leaveWhitespace( self ): -
2031 """ -2032 Disables the skipping of whitespace before matching the characters in the -2033 C{ParserElement}'s defined pattern. This is normally only used internally by -2034 the pyparsing module, but may be needed in some whitespace-sensitive grammars. -2035 """ -2036 self.skipWhitespace = False -2037 return self -
2038 -
2039 - def setWhitespaceChars( self, chars ): -
2040 """ -2041 Overrides the default whitespace chars -2042 """ -2043 self.skipWhitespace = True -2044 self.whiteChars = chars -2045 self.copyDefaultWhiteChars = False -2046 return self -
2047 -
2048 - def parseWithTabs( self ): -
2049 """ -2050 Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. -2051 Must be called before C{parseString} when the input grammar contains elements that -2052 match C{<TAB>} characters. -2053 """ -2054 self.keepTabs = True -2055 return self -
2056 -
2057 - def ignore( self, other ): -
2058 """ -2059 Define expression to be ignored (e.g., comments) while doing pattern -2060 matching; may be called repeatedly, to define multiple comment or other -2061 ignorable patterns. -2062 -2063 Example:: -2064 patt = OneOrMore(Word(alphas)) -2065 patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] -2066 -2067 patt.ignore(cStyleComment) -2068 patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] -2069 """ -2070 if isinstance(other, basestring): -2071 other = Suppress(other) -2072 -2073 if isinstance( other, Suppress ): -2074 if other not in self.ignoreExprs: -2075 self.ignoreExprs.append(other) -2076 else: -2077 self.ignoreExprs.append( Suppress( other.copy() ) ) -2078 return self -
2079 -
2080 - def setDebugActions( self, startAction, successAction, exceptionAction ): -
2081 """ -2082 Enable display of debugging messages while doing pattern matching. -2083 """ -2084 self.debugActions = (startAction or _defaultStartDebugAction, -2085 successAction or _defaultSuccessDebugAction, -2086 exceptionAction or _defaultExceptionDebugAction) -2087 self.debug = True -2088 return self -
2089 -
2090 - def setDebug( self, flag=True ): -
2091 """ -2092 Enable display of debugging messages while doing pattern matching. -2093 Set C{flag} to True to enable, False to disable. -2094 -2095 Example:: -2096 wd = Word(alphas).setName("alphaword") -2097 integer = Word(nums).setName("numword") -2098 term = wd | integer -2099 -2100 # turn on debugging for wd -2101 wd.setDebug() -2102 -2103 OneOrMore(term).parseString("abc 123 xyz 890") -2104 -2105 prints:: -2106 Match alphaword at loc 0(1,1) -2107 Matched alphaword -> ['abc'] -2108 Match alphaword at loc 3(1,4) -2109 Exception raised:Expected alphaword (at char 4), (line:1, col:5) -2110 Match alphaword at loc 7(1,8) -2111 Matched alphaword -> ['xyz'] -2112 Match alphaword at loc 11(1,12) -2113 Exception raised:Expected alphaword (at char 12), (line:1, col:13) -2114 Match alphaword at loc 15(1,16) -2115 Exception raised:Expected alphaword (at char 15), (line:1, col:16) -2116 -2117 The output shown is that produced by the default debug actions - custom debug actions can be -2118 specified using L{setDebugActions}. Prior to attempting -2119 to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} -2120 is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} -2121 message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, -2122 which makes debugging and exception messages easier to understand - for instance, the default -2123 name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. -2124 """ -2125 if flag: -2126 self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) -2127 else: -2128 self.debug = False -2129 return self -
2130 -
2131 - def __str__( self ): -
2132 return self.name -
2133 -
2134 - def __repr__( self ): -
2135 return _ustr(self) -
2136 -
2137 - def streamline( self ): -
2138 self.streamlined = True -2139 self.strRepr = None -2140 return self -
2141 -
2142 - def checkRecursion( self, parseElementList ): -
2143 pass -
2144 -
2145 - def validate( self, validateTrace=[] ): -
2146 """ -2147 Check defined expressions for valid structure, check for infinite recursive definitions. -2148 """ -2149 self.checkRecursion( [] ) -
2150 -
2151 - def parseFile( self, file_or_filename, parseAll=False ): -
2152 """ -2153 Execute the parse expression on the given file or filename. -2154 If a filename is specified (instead of a file object), -2155 the entire file is opened, read, and closed before parsing. -2156 """ -2157 try: -2158 file_contents = file_or_filename.read() -2159 except AttributeError: -2160 with open(file_or_filename, "r") as f: -2161 file_contents = f.read() -2162 try: -2163 return self.parseString(file_contents, parseAll) -2164 except ParseBaseException as exc: -2165 if ParserElement.verbose_stacktrace: -2166 raise -2167 else: -2168 # catch and re-raise exception from here, clears out pyparsing internal stack trace -2169 raise exc -
2170 -
2171 - def __eq__(self,other): -
2172 if isinstance(other, ParserElement): -2173 return self is other or vars(self) == vars(other) -2174 elif isinstance(other, basestring): -2175 return self.matches(other) -2176 else: -2177 return super(ParserElement,self)==other -
2178 -
2179 - def __ne__(self,other): -
2180 return not (self == other) -
2181 -
2182 - def __hash__(self): -
2183 return hash(id(self)) -
2184 -
2185 - def __req__(self,other): -
2186 return self == other -
2187 -
2188 - def __rne__(self,other): -
2189 return not (self == other) -
2190 -
2191 - def matches(self, testString, parseAll=True): -
2192 """ -2193 Method for quick testing of a parser against a test string. Good for simple -2194 inline microtests of sub expressions while building up larger parser. -2195 -2196 Parameters: -2197 - testString - to test against this expression for a match -2198 - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests -2199 -2200 Example:: -2201 expr = Word(nums) -2202 assert expr.matches("100") -2203 """ -2204 try: -2205 self.parseString(_ustr(testString), parseAll=parseAll) -2206 return True -2207 except ParseBaseException: -2208 return False -
2209 -
2210 - def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): -
2211 """ -2212 Execute the parse expression on a series of test strings, showing each -2213 test, the parsed results or where the parse failed. Quick and easy way to -2214 run a parse expression against a list of sample strings. -2215 -2216 Parameters: -2217 - tests - a list of separate test strings, or a multiline string of test strings -2218 - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests -2219 - comment - (default=C{'#'}) - expression for indicating embedded comments in the test -2220 string; pass None to disable comment filtering -2221 - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; -2222 if False, only dump nested list -2223 - printResults - (default=C{True}) prints test output to stdout -2224 - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing -2225 -2226 Returns: a (success, results) tuple, where success indicates that all tests succeeded -2227 (or failed if C{failureTests} is True), and the results contain a list of lines of each -2228 test's output -2229 -2230 Example:: -2231 number_expr = pyparsing_common.number.copy() -2232 -2233 result = number_expr.runTests(''' -2234 # unsigned integer -2235 100 -2236 # negative integer -2237 -100 -2238 # float with scientific notation -2239 6.02e23 -2240 # integer with scientific notation -2241 1e-12 -2242 ''') -2243 print("Success" if result[0] else "Failed!") -2244 -2245 result = number_expr.runTests(''' -2246 # stray character -2247 100Z -2248 # missing leading digit before '.' -2249 -.100 -2250 # too many '.' -2251 3.14.159 -2252 ''', failureTests=True) -2253 print("Success" if result[0] else "Failed!") -2254 prints:: -2255 # unsigned integer -2256 100 -2257 [100] -2258 -2259 # negative integer -2260 -100 -2261 [-100] -2262 -2263 # float with scientific notation -2264 6.02e23 -2265 [6.02e+23] -2266 -2267 # integer with scientific notation -2268 1e-12 -2269 [1e-12] -2270 -2271 Success -2272 -2273 # stray character -2274 100Z -2275 ^ -2276 FAIL: Expected end of text (at char 3), (line:1, col:4) -2277 -2278 # missing leading digit before '.' -2279 -.100 -2280 ^ -2281 FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) -2282 -2283 # too many '.' -2284 3.14.159 -2285 ^ -2286 FAIL: Expected end of text (at char 4), (line:1, col:5) -2287 -2288 Success -2289 -2290 Each test string must be on a single line. If you want to test a string that spans multiple -2291 lines, create a test like this:: -2292 -2293 expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") -2294 -2295 (Note that this is a raw string literal, you must include the leading 'r'.) -2296 """ -2297 if isinstance(tests, basestring): -2298 tests = list(map(str.strip, tests.rstrip().splitlines())) -2299 if isinstance(comment, basestring): -2300 comment = Literal(comment) -2301 allResults = [] -2302 comments = [] -2303 success = True -2304 for t in tests: -2305 if comment is not None and comment.matches(t, False) or comments and not t: -2306 comments.append(t) -2307 continue -2308 if not t: -2309 continue -2310 out = ['\n'.join(comments), t] -2311 comments = [] -2312 try: -2313 t = t.replace(r'\n','\n') -2314 result = self.parseString(t, parseAll=parseAll) -2315 out.append(result.dump(full=fullDump)) -2316 success = success and not failureTests -2317 except ParseBaseException as pe: -2318 fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" -2319 if '\n' in t: -2320 out.append(line(pe.loc, t)) -2321 out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) -2322 else: -2323 out.append(' '*pe.loc + '^' + fatal) -2324 out.append("FAIL: " + str(pe)) -2325 success = success and failureTests -2326 result = pe -2327 except Exception as exc: -2328 out.append("FAIL-EXCEPTION: " + str(exc)) -2329 success = success and failureTests -2330 result = exc -2331 -2332 if printResults: -2333 if fullDump: -2334 out.append('') -2335 print('\n'.join(out)) -2336 -2337 allResults.append((t, result)) -2338 -2339 return success, allResults -
2340 -
2341 -2342 -class Token(ParserElement): -
2343 """ -2344 Abstract C{ParserElement} subclass, for defining atomic matching patterns. -2345 """ -
2346 - def __init__( self ): -
2347 super(Token,self).__init__( savelist=False ) -
2348 -
2349 -2350 -class Empty(Token): -
2351 """ -2352 An empty token, will always match. -2353 """ -
2354 - def __init__( self ): -
2355 super(Empty,self).__init__() -2356 self.name = "Empty" -2357 self.mayReturnEmpty = True -2358 self.mayIndexError = False -
2359 -
2360 -2361 -class NoMatch(Token): -
2362 """ -2363 A token that will never match. -2364 """ -
2365 - def __init__( self ): -
2366 super(NoMatch,self).__init__() -2367 self.name = "NoMatch" -2368 self.mayReturnEmpty = True -2369 self.mayIndexError = False -2370 self.errmsg = "Unmatchable token" -
2371 -
2372 - def parseImpl( self, instring, loc, doActions=True ): -
2373 raise ParseException(instring, loc, self.errmsg, self) -
2374 -
2375 -2376 -class Literal(Token): -
2377 """ -2378 Token to exactly match a specified string. -2379 -2380 Example:: -2381 Literal('blah').parseString('blah') # -> ['blah'] -2382 Literal('blah').parseString('blahfooblah') # -> ['blah'] -2383 Literal('blah').parseString('bla') # -> Exception: Expected "blah" -2384 -2385 For case-insensitive matching, use L{CaselessLiteral}. -2386 -2387 For keyword matching (force word break before and after the matched string), -2388 use L{Keyword} or L{CaselessKeyword}. -2389 """ -
2390 - def __init__( self, matchString ): -
2391 super(Literal,self).__init__() -2392 self.match = matchString -2393 self.matchLen = len(matchString) -2394 try: -2395 self.firstMatchChar = matchString[0] -2396 except IndexError: -2397 warnings.warn("null string passed to Literal; use Empty() instead", -2398 SyntaxWarning, stacklevel=2) -2399 self.__class__ = Empty -2400 self.name = '"%s"' % _ustr(self.match) -2401 self.errmsg = "Expected " + self.name -2402 self.mayReturnEmpty = False -2403 self.mayIndexError = False -
2404 -2405 # Performance tuning: this routine gets called a *lot* -2406 # if this is a single character match string and the first character matches, -2407 # short-circuit as quickly as possible, and avoid calling startswith -2408 #~ @profile -
2409 - def parseImpl( self, instring, loc, doActions=True ): -
2410 if (instring[loc] == self.firstMatchChar and -2411 (self.matchLen==1 or instring.startswith(self.match,loc)) ): -2412 return loc+self.matchLen, self.match -2413 raise ParseException(instring, loc, self.errmsg, self) -
2414 _L = Literal -2415 ParserElement._literalStringClass = Literal -
2416 -2417 -class Keyword(Token): -
2418 """ -2419 Token to exactly match a specified string as a keyword, that is, it must be -2420 immediately followed by a non-keyword character. Compare with C{L{Literal}}: -2421 - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. -2422 - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} -2423 Accepts two optional constructor arguments in addition to the keyword string: -2424 - C{identChars} is a string of characters that would be valid identifier characters, -2425 defaulting to all alphanumerics + "_" and "$" -2426 - C{caseless} allows case-insensitive matching, default is C{False}. -2427 -2428 Example:: -2429 Keyword("start").parseString("start") # -> ['start'] -2430 Keyword("start").parseString("starting") # -> Exception -2431 -2432 For case-insensitive matching, use L{CaselessKeyword}. -2433 """ -2434 DEFAULT_KEYWORD_CHARS = alphanums+"_$" -2435 -
2436 - def __init__( self, matchString, identChars=None, caseless=False ): -
2437 super(Keyword,self).__init__() -2438 if identChars is None: -2439 identChars = Keyword.DEFAULT_KEYWORD_CHARS -2440 self.match = matchString -2441 self.matchLen = len(matchString) -2442 try: -2443 self.firstMatchChar = matchString[0] -2444 except IndexError: -2445 warnings.warn("null string passed to Keyword; use Empty() instead", -2446 SyntaxWarning, stacklevel=2) -2447 self.name = '"%s"' % self.match -2448 self.errmsg = "Expected " + self.name -2449 self.mayReturnEmpty = False -2450 self.mayIndexError = False -2451 self.caseless = caseless -2452 if caseless: -2453 self.caselessmatch = matchString.upper() -2454 identChars = identChars.upper() -2455 self.identChars = set(identChars) -
2456 -
2457 - def parseImpl( self, instring, loc, doActions=True ): -
2458 if self.caseless: -2459 if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and -2460 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and -2461 (loc == 0 or instring[loc-1].upper() not in self.identChars) ): -2462 return loc+self.matchLen, self.match -2463 else: -2464 if (instring[loc] == self.firstMatchChar and -2465 (self.matchLen==1 or instring.startswith(self.match,loc)) and -2466 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and -2467 (loc == 0 or instring[loc-1] not in self.identChars) ): -2468 return loc+self.matchLen, self.match -2469 raise ParseException(instring, loc, self.errmsg, self) -
2470 -
2471 - def copy(self): -
2472 c = super(Keyword,self).copy() -2473 c.identChars = Keyword.DEFAULT_KEYWORD_CHARS -2474 return c -
2475 -2476 @staticmethod -
2477 - def setDefaultKeywordChars( chars ): -
2478 """Overrides the default Keyword chars -2479 """ -2480 Keyword.DEFAULT_KEYWORD_CHARS = chars -
2481 -
2482 -class CaselessLiteral(Literal): -
2483 """ -2484 Token to match a specified string, ignoring case of letters. -2485 Note: the matched results will always be in the case of the given -2486 match string, NOT the case of the input text. -2487 -2488 Example:: -2489 OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] -2490 -2491 (Contrast with example for L{CaselessKeyword}.) -2492 """ -
2493 - def __init__( self, matchString ): -
2494 super(CaselessLiteral,self).__init__( matchString.upper() ) -2495 # Preserve the defining literal. -2496 self.returnString = matchString -2497 self.name = "'%s'" % self.returnString -2498 self.errmsg = "Expected " + self.name -
2499 -
2500 - def parseImpl( self, instring, loc, doActions=True ): -
2501 if instring[ loc:loc+self.matchLen ].upper() == self.match: -2502 return loc+self.matchLen, self.returnString -2503 raise ParseException(instring, loc, self.errmsg, self) -
2504 -
2505 -class CaselessKeyword(Keyword): -
2506 """ -2507 Caseless version of L{Keyword}. -2508 -2509 Example:: -2510 OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] -2511 -2512 (Contrast with example for L{CaselessLiteral}.) -2513 """ -
2514 - def __init__( self, matchString, identChars=None ): -
2515 super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) -
2516 -
2517 - def parseImpl( self, instring, loc, doActions=True ): -
2518 if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and -2519 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): -2520 return loc+self.matchLen, self.match -2521 raise ParseException(instring, loc, self.errmsg, self) -
2522 -
2523 -class CloseMatch(Token): -
2524 """ -2525 A variation on L{Literal} which matches "close" matches, that is, -2526 strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: -2527 - C{match_string} - string to be matched -2528 - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match -2529 -2530 The results from a successful parse will contain the matched text from the input string and the following named results: -2531 - C{mismatches} - a list of the positions within the match_string where mismatches were found -2532 - C{original} - the original match_string used to compare against the input string -2533 -2534 If C{mismatches} is an empty list, then the match was an exact match. -2535 -2536 Example:: -2537 patt = CloseMatch("ATCATCGAATGGA") -2538 patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) -2539 patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) -2540 -2541 # exact match -2542 patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) -2543 -2544 # close match allowing up to 2 mismatches -2545 patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) -2546 patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) -2547 """ -
2548 - def __init__(self, match_string, maxMismatches=1): -
2549 super(CloseMatch,self).__init__() -2550 self.name = match_string -2551 self.match_string = match_string -2552 self.maxMismatches = maxMismatches -2553 self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) -2554 self.mayIndexError = False -2555 self.mayReturnEmpty = False -
2556 -
2557 - def parseImpl( self, instring, loc, doActions=True ): -
2558 start = loc -2559 instrlen = len(instring) -2560 maxloc = start + len(self.match_string) -2561 -2562 if maxloc <= instrlen: -2563 match_string = self.match_string -2564 match_stringloc = 0 -2565 mismatches = [] -2566 maxMismatches = self.maxMismatches -2567 -2568 for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): -2569 src,mat = s_m -2570 if src != mat: -2571 mismatches.append(match_stringloc) -2572 if len(mismatches) > maxMismatches: -2573 break -2574 else: -2575 loc = match_stringloc + 1 -2576 results = ParseResults([instring[start:loc]]) -2577 results['original'] = self.match_string -2578 results['mismatches'] = mismatches -2579 return loc, results -2580 -2581 raise ParseException(instring, loc, self.errmsg, self) -
2582 -
2583 -2584 -class Word(Token): -
2585 """ -2586 Token for matching words composed of allowed character sets. -2587 Defined with string containing all allowed initial characters, -2588 an optional string containing allowed body characters (if omitted, -2589 defaults to the initial character set), and an optional minimum, -2590 maximum, and/or exact length. The default value for C{min} is 1 (a -2591 minimum value < 1 is not valid); the default values for C{max} and C{exact} -2592 are 0, meaning no maximum or exact length restriction. An optional -2593 C{excludeChars} parameter can list characters that might be found in -2594 the input C{bodyChars} string; useful to define a word of all printables -2595 except for one or two characters, for instance. -2596 -2597 L{srange} is useful for defining custom character set strings for defining -2598 C{Word} expressions, using range notation from regular expression character sets. -2599 -2600 A common mistake is to use C{Word} to match a specific literal string, as in -2601 C{Word("Address")}. Remember that C{Word} uses the string argument to define -2602 I{sets} of matchable characters. This expression would match "Add", "AAA", -2603 "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. -2604 To match an exact literal string, use L{Literal} or L{Keyword}. -2605 -2606 pyparsing includes helper strings for building Words: -2607 - L{alphas} -2608 - L{nums} -2609 - L{alphanums} -2610 - L{hexnums} -2611 - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) -2612 - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) -2613 - L{printables} (any non-whitespace character) -2614 -2615 Example:: -2616 # a word composed of digits -2617 integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) -2618 -2619 # a word with a leading capital, and zero or more lowercase -2620 capital_word = Word(alphas.upper(), alphas.lower()) -2621 -2622 # hostnames are alphanumeric, with leading alpha, and '-' -2623 hostname = Word(alphas, alphanums+'-') -2624 -2625 # roman numeral (not a strict parser, accepts invalid mix of characters) -2626 roman = Word("IVXLCDM") -2627 -2628 # any string of non-whitespace characters, except for ',' -2629 csv_value = Word(printables, excludeChars=",") -2630 """ -
2631 - def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): -
2632 super(Word,self).__init__() -2633 if excludeChars: -2634 initChars = ''.join(c for c in initChars if c not in excludeChars) -2635 if bodyChars: -2636 bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) -2637 self.initCharsOrig = initChars -2638 self.initChars = set(initChars) -2639 if bodyChars : -2640 self.bodyCharsOrig = bodyChars -2641 self.bodyChars = set(bodyChars) -2642 else: -2643 self.bodyCharsOrig = initChars -2644 self.bodyChars = set(initChars) -2645 -2646 self.maxSpecified = max > 0 -2647 -2648 if min < 1: -2649 raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") -2650 -2651 self.minLen = min -2652 -2653 if max > 0: -2654 self.maxLen = max -2655 else: -2656 self.maxLen = _MAX_INT -2657 -2658 if exact > 0: -2659 self.maxLen = exact -2660 self.minLen = exact -2661 -2662 self.name = _ustr(self) -2663 self.errmsg = "Expected " + self.name -2664 self.mayIndexError = False -2665 self.asKeyword = asKeyword -2666 -2667 if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): -2668 if self.bodyCharsOrig == self.initCharsOrig: -2669 self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) -2670 elif len(self.initCharsOrig) == 1: -2671 self.reString = "%s[%s]*" % \ -2672 (re.escape(self.initCharsOrig), -2673 _escapeRegexRangeChars(self.bodyCharsOrig),) -2674 else: -2675 self.reString = "[%s][%s]*" % \ -2676 (_escapeRegexRangeChars(self.initCharsOrig), -2677 _escapeRegexRangeChars(self.bodyCharsOrig),) -2678 if self.asKeyword: -2679 self.reString = r"\b"+self.reString+r"\b" -2680 try: -2681 self.re = re.compile( self.reString ) -2682 except Exception: -2683 self.re = None -
2684 -
2685 - def parseImpl( self, instring, loc, doActions=True ): -
2686 if self.re: -2687 result = self.re.match(instring,loc) -2688 if not result: -2689 raise ParseException(instring, loc, self.errmsg, self) -2690 -2691 loc = result.end() -2692 return loc, result.group() -2693 -2694 if not(instring[ loc ] in self.initChars): -2695 raise ParseException(instring, loc, self.errmsg, self) -2696 -2697 start = loc -2698 loc += 1 -2699 instrlen = len(instring) -2700 bodychars = self.bodyChars -2701 maxloc = start + self.maxLen -2702 maxloc = min( maxloc, instrlen ) -2703 while loc < maxloc and instring[loc] in bodychars: -2704 loc += 1 -2705 -2706 throwException = False -2707 if loc - start < self.minLen: -2708 throwException = True -2709 if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: -2710 throwException = True -2711 if self.asKeyword: -2712 if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): -2713 throwException = True -2714 -2715 if throwException: -2716 raise ParseException(instring, loc, self.errmsg, self) -2717 -2718 return loc, instring[start:loc] -
2719 -
2720 - def __str__( self ): -
2721 try: -2722 return super(Word,self).__str__() -2723 except Exception: -2724 pass -2725 -2726 -2727 if self.strRepr is None: -2728 -2729 def charsAsStr(s): -2730 if len(s)>4: -2731 return s[:4]+"..." -2732 else: -2733 return s -
2734 -2735 if ( self.initCharsOrig != self.bodyCharsOrig ): -2736 self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) -2737 else: -2738 self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) -2739 -2740 return self.strRepr -
2741 -
2742 -2743 -class Regex(Token): -
2744 r""" -2745 Token for matching strings that match a given regular expression. -2746 Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. -2747 If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as -2748 named parse results. -2749 -2750 Example:: -2751 realnum = Regex(r"[+-]?\d+\.\d*") -2752 date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') -2753 # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression -2754 roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") -2755 """ -2756 compiledREtype = type(re.compile("[A-Z]")) -
2757 - def __init__( self, pattern, flags=0): -
2758 """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.""" -2759 super(Regex,self).__init__() -2760 -2761 if isinstance(pattern, basestring): -2762 if not pattern: -2763 warnings.warn("null string passed to Regex; use Empty() instead", -2764 SyntaxWarning, stacklevel=2) -2765 -2766 self.pattern = pattern -2767 self.flags = flags -2768 -2769 try: -2770 self.re = re.compile(self.pattern, self.flags) -2771 self.reString = self.pattern -2772 except sre_constants.error: -2773 warnings.warn("invalid pattern (%s) passed to Regex" % pattern, -2774 SyntaxWarning, stacklevel=2) -2775 raise -2776 -2777 elif isinstance(pattern, Regex.compiledREtype): -2778 self.re = pattern -2779 self.pattern = \ -2780 self.reString = str(pattern) -2781 self.flags = flags -2782 -2783 else: -2784 raise ValueError("Regex may only be constructed with a string or a compiled RE object") -2785 -2786 self.name = _ustr(self) -2787 self.errmsg = "Expected " + self.name -2788 self.mayIndexError = False -2789 self.mayReturnEmpty = True -
2790 -
2791 - def parseImpl( self, instring, loc, doActions=True ): -
2792 result = self.re.match(instring,loc) -2793 if not result: -2794 raise ParseException(instring, loc, self.errmsg, self) -2795 -2796 loc = result.end() -2797 d = result.groupdict() -2798 ret = ParseResults(result.group()) -2799 if d: -2800 for k in d: -2801 ret[k] = d[k] -2802 return loc,ret -
2803 -
2804 - def __str__( self ): -
2805 try: -2806 return super(Regex,self).__str__() -2807 except Exception: -2808 pass -2809 -2810 if self.strRepr is None: -2811 self.strRepr = "Re:(%s)" % repr(self.pattern) -2812 -2813 return self.strRepr -
2814 -
2815 -2816 -class QuotedString(Token): -
2817 r""" -2818 Token for matching strings that are delimited by quoting characters. -2819 -2820 Defined with the following parameters: -2821 - quoteChar - string of one or more characters defining the quote delimiting string -2822 - escChar - character to escape quotes, typically backslash (default=C{None}) -2823 - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) -2824 - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) -2825 - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) -2826 - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) -2827 - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) -2828 -2829 Example:: -2830 qs = QuotedString('"') -2831 print(qs.searchString('lsjdf "This is the quote" sldjf')) -2832 complex_qs = QuotedString('{{', endQuoteChar='}}') -2833 print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) -2834 sql_qs = QuotedString('"', escQuote='""') -2835 print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) -2836 prints:: -2837 [['This is the quote']] -2838 [['This is the "quote"']] -2839 [['This is the quote with "embedded" quotes']] -2840 """ -
2841 - def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): -
2842 super(QuotedString,self).__init__() -2843 -2844 # remove white space from quote chars - wont work anyway -2845 quoteChar = quoteChar.strip() -2846 if not quoteChar: -2847 warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) -2848 raise SyntaxError() -2849 -2850 if endQuoteChar is None: -2851 endQuoteChar = quoteChar -2852 else: -2853 endQuoteChar = endQuoteChar.strip() -2854 if not endQuoteChar: -2855 warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) -2856 raise SyntaxError() -2857 -2858 self.quoteChar = quoteChar -2859 self.quoteCharLen = len(quoteChar) -2860 self.firstQuoteChar = quoteChar[0] -2861 self.endQuoteChar = endQuoteChar -2862 self.endQuoteCharLen = len(endQuoteChar) -2863 self.escChar = escChar -2864 self.escQuote = escQuote -2865 self.unquoteResults = unquoteResults -2866 self.convertWhitespaceEscapes = convertWhitespaceEscapes -2867 -2868 if multiline: -2869 self.flags = re.MULTILINE | re.DOTALL -2870 self.pattern = r'%s(?:[^%s%s]' % \ -2871 ( re.escape(self.quoteChar), -2872 _escapeRegexRangeChars(self.endQuoteChar[0]), -2873 (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) -2874 else: -2875 self.flags = 0 -2876 self.pattern = r'%s(?:[^%s\n\r%s]' % \ -2877 ( re.escape(self.quoteChar), -2878 _escapeRegexRangeChars(self.endQuoteChar[0]), -2879 (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) -2880 if len(self.endQuoteChar) > 1: -2881 self.pattern += ( -2882 '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), -2883 _escapeRegexRangeChars(self.endQuoteChar[i])) -2884 for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' -2885 ) -2886 if escQuote: -2887 self.pattern += (r'|(?:%s)' % re.escape(escQuote)) -2888 if escChar: -2889 self.pattern += (r'|(?:%s.)' % re.escape(escChar)) -2890 self.escCharReplacePattern = re.escape(self.escChar)+"(.)" -2891 self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) -2892 -2893 try: -2894 self.re = re.compile(self.pattern, self.flags) -2895 self.reString = self.pattern -2896 except sre_constants.error: -2897 warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, -2898 SyntaxWarning, stacklevel=2) -2899 raise -2900 -2901 self.name = _ustr(self) -2902 self.errmsg = "Expected " + self.name -2903 self.mayIndexError = False -2904 self.mayReturnEmpty = True -
2905 -
2906 - def parseImpl( self, instring, loc, doActions=True ): -
2907 result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None -2908 if not result: -2909 raise ParseException(instring, loc, self.errmsg, self) -2910 -2911 loc = result.end() -2912 ret = result.group() -2913 -2914 if self.unquoteResults: -2915 -2916 # strip off quotes -2917 ret = ret[self.quoteCharLen:-self.endQuoteCharLen] -2918 -2919 if isinstance(ret,basestring): -2920 # replace escaped whitespace -2921 if '\\' in ret and self.convertWhitespaceEscapes: -2922 ws_map = { -2923 r'\t' : '\t', -2924 r'\n' : '\n', -2925 r'\f' : '\f', -2926 r'\r' : '\r', -2927 } -2928 for wslit,wschar in ws_map.items(): -2929 ret = ret.replace(wslit, wschar) -2930 -2931 # replace escaped characters -2932 if self.escChar: -2933 ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) -2934 -2935 # replace escaped quotes -2936 if self.escQuote: -2937 ret = ret.replace(self.escQuote, self.endQuoteChar) -2938 -2939 return loc, ret -
2940 -
2941 - def __str__( self ): -
2942 try: -2943 return super(QuotedString,self).__str__() -2944 except Exception: -2945 pass -2946 -2947 if self.strRepr is None: -2948 self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) -2949 -2950 return self.strRepr -
2951 -
2952 -2953 -class CharsNotIn(Token): -
2954 """ -2955 Token for matching words composed of characters I{not} in a given set (will -2956 include whitespace in matched characters if not listed in the provided exclusion set - see example). -2957 Defined with string containing all disallowed characters, and an optional -2958 minimum, maximum, and/or exact length. The default value for C{min} is 1 (a -2959 minimum value < 1 is not valid); the default values for C{max} and C{exact} -2960 are 0, meaning no maximum or exact length restriction. -2961 -2962 Example:: -2963 # define a comma-separated-value as anything that is not a ',' -2964 csv_value = CharsNotIn(',') -2965 print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) -2966 prints:: -2967 ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] -2968 """ -
2969 - def __init__( self, notChars, min=1, max=0, exact=0 ): -
2970 super(CharsNotIn,self).__init__() -2971 self.skipWhitespace = False -2972 self.notChars = notChars -2973 -2974 if min < 1: -2975 raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") -2976 -2977 self.minLen = min -2978 -2979 if max > 0: -2980 self.maxLen = max -2981 else: -2982 self.maxLen = _MAX_INT -2983 -2984 if exact > 0: -2985 self.maxLen = exact -2986 self.minLen = exact -2987 -2988 self.name = _ustr(self) -2989 self.errmsg = "Expected " + self.name -2990 self.mayReturnEmpty = ( self.minLen == 0 ) -2991 self.mayIndexError = False -
2992 -
2993 - def parseImpl( self, instring, loc, doActions=True ): -
2994 if instring[loc] in self.notChars: -2995 raise ParseException(instring, loc, self.errmsg, self) -2996 -2997 start = loc -2998 loc += 1 -2999 notchars = self.notChars -3000 maxlen = min( start+self.maxLen, len(instring) ) -3001 while loc < maxlen and \ -3002 (instring[loc] not in notchars): -3003 loc += 1 -3004 -3005 if loc - start < self.minLen: -3006 raise ParseException(instring, loc, self.errmsg, self) -3007 -3008 return loc, instring[start:loc] -
3009 -
3010 - def __str__( self ): -
3011 try: -3012 return super(CharsNotIn, self).__str__() -3013 except Exception: -3014 pass -3015 -3016 if self.strRepr is None: -3017 if len(self.notChars) > 4: -3018 self.strRepr = "!W:(%s...)" % self.notChars[:4] -3019 else: -3020 self.strRepr = "!W:(%s)" % self.notChars -3021 -3022 return self.strRepr -
3023 -
3024 -class White(Token): -
3025 """ -3026 Special matching class for matching whitespace. Normally, whitespace is ignored -3027 by pyparsing grammars. This class is included when some whitespace structures -3028 are significant. Define with a string containing the whitespace characters to be -3029 matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, -3030 as defined for the C{L{Word}} class. -3031 """ -3032 whiteStrs = { -3033 " " : "<SPC>", -3034 "\t": "<TAB>", -3035 "\n": "<LF>", -3036 "\r": "<CR>", -3037 "\f": "<FF>", -3038 } -
3039 - def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): -
3040 super(White,self).__init__() -3041 self.matchWhite = ws -3042 self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) -3043 #~ self.leaveWhitespace() -3044 self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) -3045 self.mayReturnEmpty = True -3046 self.errmsg = "Expected " + self.name -3047 -3048 self.minLen = min -3049 -3050 if max > 0: -3051 self.maxLen = max -3052 else: -3053 self.maxLen = _MAX_INT -3054 -3055 if exact > 0: -3056 self.maxLen = exact -3057 self.minLen = exact -
3058 -
3059 - def parseImpl( self, instring, loc, doActions=True ): -
3060 if not(instring[ loc ] in self.matchWhite): -3061 raise ParseException(instring, loc, self.errmsg, self) -3062 start = loc -3063 loc += 1 -3064 maxloc = start + self.maxLen -3065 maxloc = min( maxloc, len(instring) ) -3066 while loc < maxloc and instring[loc] in self.matchWhite: -3067 loc += 1 -3068 -3069 if loc - start < self.minLen: -3070 raise ParseException(instring, loc, self.errmsg, self) -3071 -3072 return loc, instring[start:loc] -
3073 -
3074 -3075 -class _PositionToken(Token): -
3076 - def __init__( self ): -
3077 super(_PositionToken,self).__init__() -3078 self.name=self.__class__.__name__ -3079 self.mayReturnEmpty = True -3080 self.mayIndexError = False -
3081 -
3082 -class GoToColumn(_PositionToken): -
3083 """ -3084 Token to advance to a specific column of input text; useful for tabular report scraping. -3085 """ -
3086 - def __init__( self, colno ): -
3087 super(GoToColumn,self).__init__() -3088 self.col = colno -
3089 -
3090 - def preParse( self, instring, loc ): -
3091 if col(loc,instring) != self.col: -3092 instrlen = len(instring) -3093 if self.ignoreExprs: -3094 loc = self._skipIgnorables( instring, loc ) -3095 while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : -3096 loc += 1 -3097 return loc -
3098 -
3099 - def parseImpl( self, instring, loc, doActions=True ): -
3100 thiscol = col( loc, instring ) -3101 if thiscol > self.col: -3102 raise ParseException( instring, loc, "Text not in expected column", self ) -3103 newloc = loc + self.col - thiscol -3104 ret = instring[ loc: newloc ] -3105 return newloc, ret -
3106 -
3107 -3108 -class LineStart(_PositionToken): -
3109 """ -3110 Matches if current position is at the beginning of a line within the parse string -3111 -3112 Example:: -3113 -3114 test = '''\ -3115 AAA this line -3116 AAA and this line -3117 AAA but not this one -3118 B AAA and definitely not this one -3119 ''' -3120 -3121 for t in (LineStart() + 'AAA' + restOfLine).searchString(test): -3122 print(t) -3123 -3124 Prints:: -3125 ['AAA', ' this line'] -3126 ['AAA', ' and this line'] -3127 -3128 """ -
3129 - def __init__( self ): -
3130 super(LineStart,self).__init__() -3131 self.errmsg = "Expected start of line" -
3132 -
3133 - def parseImpl( self, instring, loc, doActions=True ): -
3134 if col(loc, instring) == 1: -3135 return loc, [] -3136 raise ParseException(instring, loc, self.errmsg, self) -
3137 -
3138 -class LineEnd(_PositionToken): -
3139 """ -3140 Matches if current position is at the end of a line within the parse string -3141 """ -
3142 - def __init__( self ): -
3143 super(LineEnd,self).__init__() -3144 self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) -3145 self.errmsg = "Expected end of line" -
3146 -
3147 - def parseImpl( self, instring, loc, doActions=True ): -
3148 if loc<len(instring): -3149 if instring[loc] == "\n": -3150 return loc+1, "\n" -3151 else: -3152 raise ParseException(instring, loc, self.errmsg, self) -3153 elif loc == len(instring): -3154 return loc+1, [] -3155 else: -3156 raise ParseException(instring, loc, self.errmsg, self) -
3157 -
3158 -class StringStart(_PositionToken): -
3159 """ -3160 Matches if current position is at the beginning of the parse string -3161 """ -
3162 - def __init__( self ): -
3163 super(StringStart,self).__init__() -3164 self.errmsg = "Expected start of text" -
3165 -
3166 - def parseImpl( self, instring, loc, doActions=True ): -
3167 if loc != 0: -3168 # see if entire string up to here is just whitespace and ignoreables -3169 if loc != self.preParse( instring, 0 ): -3170 raise ParseException(instring, loc, self.errmsg, self) -3171 return loc, [] -
3172 -
3173 -class StringEnd(_PositionToken): -
3174 """ -3175 Matches if current position is at the end of the parse string -3176 """ -
3177 - def __init__( self ): -
3178 super(StringEnd,self).__init__() -3179 self.errmsg = "Expected end of text" -
3180 -
3181 - def parseImpl( self, instring, loc, doActions=True ): -
3182 if loc < len(instring): -3183 raise ParseException(instring, loc, self.errmsg, self) -3184 elif loc == len(instring): -3185 return loc+1, [] -3186 elif loc > len(instring): -3187 return loc, [] -3188 else: -3189 raise ParseException(instring, loc, self.errmsg, self) -
3190 -
3191 -class WordStart(_PositionToken): -
3192 """ -3193 Matches if the current position is at the beginning of a Word, and -3194 is not preceded by any character in a given set of C{wordChars} -3195 (default=C{printables}). To emulate the C{\b} behavior of regular expressions, -3196 use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of -3197 the string being parsed, or at the beginning of a line. -3198 """ -
3199 - def __init__(self, wordChars = printables): -
3200 super(WordStart,self).__init__() -3201 self.wordChars = set(wordChars) -3202 self.errmsg = "Not at the start of a word" -
3203 -
3204 - def parseImpl(self, instring, loc, doActions=True ): -
3205 if loc != 0: -3206 if (instring[loc-1] in self.wordChars or -3207 instring[loc] not in self.wordChars): -3208 raise ParseException(instring, loc, self.errmsg, self) -3209 return loc, [] -
3210 -
3211 -class WordEnd(_PositionToken): -
3212 """ -3213 Matches if the current position is at the end of a Word, and -3214 is not followed by any character in a given set of C{wordChars} -3215 (default=C{printables}). To emulate the C{\b} behavior of regular expressions, -3216 use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of -3217 the string being parsed, or at the end of a line. -3218 """ -
3219 - def __init__(self, wordChars = printables): -
3220 super(WordEnd,self).__init__() -3221 self.wordChars = set(wordChars) -3222 self.skipWhitespace = False -3223 self.errmsg = "Not at the end of a word" -
3224 -
3225 - def parseImpl(self, instring, loc, doActions=True ): -
3226 instrlen = len(instring) -3227 if instrlen>0 and loc<instrlen: -3228 if (instring[loc] in self.wordChars or -3229 instring[loc-1] not in self.wordChars): -3230 raise ParseException(instring, loc, self.errmsg, self) -3231 return loc, [] -
3232 -
3233 -3234 -class ParseExpression(ParserElement): -
3235 """ -3236 Abstract subclass of ParserElement, for combining and post-processing parsed tokens. -3237 """ -
3238 - def __init__( self, exprs, savelist = False ): -
3239 super(ParseExpression,self).__init__(savelist) -3240 if isinstance( exprs, _generatorType ): -3241 exprs = list(exprs) -3242 -3243 if isinstance( exprs, basestring ): -3244 self.exprs = [ ParserElement._literalStringClass( exprs ) ] -3245 elif isinstance( exprs, collections.Iterable ): -3246 exprs = list(exprs) -3247 # if sequence of strings provided, wrap with Literal -3248 if all(isinstance(expr, basestring) for expr in exprs): -3249 exprs = map(ParserElement._literalStringClass, exprs) -3250 self.exprs = list(exprs) -3251 else: -3252 try: -3253 self.exprs = list( exprs ) -3254 except TypeError: -3255 self.exprs = [ exprs ] -3256 self.callPreparse = False -
3257 -
3258 - def __getitem__( self, i ): -
3259 return self.exprs[i] -
3260 -
3261 - def append( self, other ): -
3262 self.exprs.append( other ) -3263 self.strRepr = None -3264 return self -
3265 -
3266 - def leaveWhitespace( self ): -
3267 """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on -3268 all contained expressions.""" -3269 self.skipWhitespace = False -3270 self.exprs = [ e.copy() for e in self.exprs ] -3271 for e in self.exprs: -3272 e.leaveWhitespace() -3273 return self -
3274 -
3275 - def ignore( self, other ): -
3276 if isinstance( other, Suppress ): -3277 if other not in self.ignoreExprs: -3278 super( ParseExpression, self).ignore( other ) -3279 for e in self.exprs: -3280 e.ignore( self.ignoreExprs[-1] ) -3281 else: -3282 super( ParseExpression, self).ignore( other ) -3283 for e in self.exprs: -3284 e.ignore( self.ignoreExprs[-1] ) -3285 return self -
3286 -
3287 - def __str__( self ): -
3288 try: -3289 return super(ParseExpression,self).__str__() -3290 except Exception: -3291 pass -3292 -3293 if self.strRepr is None: -3294 self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) -3295 return self.strRepr -
3296 -
3297 - def streamline( self ): -
3298 super(ParseExpression,self).streamline() -3299 -3300 for e in self.exprs: -3301 e.streamline() -3302 -3303 # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) -3304 # but only if there are no parse actions or resultsNames on the nested And's -3305 # (likewise for Or's and MatchFirst's) -3306 if ( len(self.exprs) == 2 ): -3307 other = self.exprs[0] -3308 if ( isinstance( other, self.__class__ ) and -3309 not(other.parseAction) and -3310 other.resultsName is None and -3311 not other.debug ): -3312 self.exprs = other.exprs[:] + [ self.exprs[1] ] -3313 self.strRepr = None -3314 self.mayReturnEmpty |= other.mayReturnEmpty -3315 self.mayIndexError |= other.mayIndexError -3316 -3317 other = self.exprs[-1] -3318 if ( isinstance( other, self.__class__ ) and -3319 not(other.parseAction) and -3320 other.resultsName is None and -3321 not other.debug ): -3322 self.exprs = self.exprs[:-1] + other.exprs[:] -3323 self.strRepr = None -3324 self.mayReturnEmpty |= other.mayReturnEmpty -3325 self.mayIndexError |= other.mayIndexError -3326 -3327 self.errmsg = "Expected " + _ustr(self) -3328 -3329 return self -
3330 -
3331 - def setResultsName( self, name, listAllMatches=False ): -
3332 ret = super(ParseExpression,self).setResultsName(name,listAllMatches) -3333 return ret -
3334 -
3335 - def validate( self, validateTrace=[] ): -
3336 tmp = validateTrace[:]+[self] -3337 for e in self.exprs: -3338 e.validate(tmp) -3339 self.checkRecursion( [] ) -
3340 -
3341 - def copy(self): -
3342 ret = super(ParseExpression,self).copy() -3343 ret.exprs = [e.copy() for e in self.exprs] -3344 return ret -
3345 -
3346 -class And(ParseExpression): -
3347 """ -3348 Requires all given C{ParseExpression}s to be found in the given order. -3349 Expressions may be separated by whitespace. -3350 May be constructed using the C{'+'} operator. -3351 May also be constructed using the C{'-'} operator, which will suppress backtracking. -3352 -3353 Example:: -3354 integer = Word(nums) -3355 name_expr = OneOrMore(Word(alphas)) -3356 -3357 expr = And([integer("id"),name_expr("name"),integer("age")]) -3358 # more easily written as: -3359 expr = integer("id") + name_expr("name") + integer("age") -3360 """ -3361 -
3362 - class _ErrorStop(Empty): -
3363 - def __init__(self, *args, **kwargs): -
3364 super(And._ErrorStop,self).__init__(*args, **kwargs) -3365 self.name = '-' -3366 self.leaveWhitespace() -
3367 -
3368 - def __init__( self, exprs, savelist = True ): -
3369 super(And,self).__init__(exprs, savelist) -3370 self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) -3371 self.setWhitespaceChars( self.exprs[0].whiteChars ) -3372 self.skipWhitespace = self.exprs[0].skipWhitespace -3373 self.callPreparse = True -
3374 -
3375 - def parseImpl( self, instring, loc, doActions=True ): -
3376 # pass False as last arg to _parse for first element, since we already -3377 # pre-parsed the string as part of our And pre-parsing -3378 loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) -3379 errorStop = False -3380 for e in self.exprs[1:]: -3381 if isinstance(e, And._ErrorStop): -3382 errorStop = True -3383 continue -3384 if errorStop: -3385 try: -3386 loc, exprtokens = e._parse( instring, loc, doActions ) -3387 except ParseSyntaxException: -3388 raise -3389 except ParseBaseException as pe: -3390 pe.__traceback__ = None -3391 raise ParseSyntaxException._from_exception(pe) -3392 except IndexError: -3393 raise ParseSyntaxException(instring, len(instring), self.errmsg, self) -3394 else: -3395 loc, exprtokens = e._parse( instring, loc, doActions ) -3396 if exprtokens or exprtokens.haskeys(): -3397 resultlist += exprtokens -3398 return loc, resultlist -
3399 -
3400 - def __iadd__(self, other ): -
3401 if isinstance( other, basestring ): -3402 other = ParserElement._literalStringClass( other ) -3403 return self.append( other ) #And( [ self, other ] ) -
3404 -
3405 - def checkRecursion( self, parseElementList ): -
3406 subRecCheckList = parseElementList[:] + [ self ] -3407 for e in self.exprs: -3408 e.checkRecursion( subRecCheckList ) -3409 if not e.mayReturnEmpty: -3410 break -
3411 -
3412 - def __str__( self ): -
3413 if hasattr(self,"name"): -3414 return self.name -3415 -3416 if self.strRepr is None: -3417 self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" -3418 -3419 return self.strRepr -
3420 -
3421 -3422 -class Or(ParseExpression): -
3423 """ -3424 Requires that at least one C{ParseExpression} is found. -3425 If two expressions match, the expression that matches the longest string will be used. -3426 May be constructed using the C{'^'} operator. -3427 -3428 Example:: -3429 # construct Or using '^' operator -3430 -3431 number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) -3432 print(number.searchString("123 3.1416 789")) -3433 prints:: -3434 [['123'], ['3.1416'], ['789']] -3435 """ -
3436 - def __init__( self, exprs, savelist = False ): -
3437 super(Or,self).__init__(exprs, savelist) -3438 if self.exprs: -3439 self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) -3440 else: -3441 self.mayReturnEmpty = True -
3442 -
3443 - def parseImpl( self, instring, loc, doActions=True ): -
3444 maxExcLoc = -1 -3445 maxException = None -3446 matches = [] -3447 for e in self.exprs: -3448 try: -3449 loc2 = e.tryParse( instring, loc ) -3450 except ParseException as err: -3451 err.__traceback__ = None -3452 if err.loc > maxExcLoc: -3453 maxException = err -3454 maxExcLoc = err.loc -3455 except IndexError: -3456 if len(instring) > maxExcLoc: -3457 maxException = ParseException(instring,len(instring),e.errmsg,self) -3458 maxExcLoc = len(instring) -3459 else: -3460 # save match among all matches, to retry longest to shortest -3461 matches.append((loc2, e)) -3462 -3463 if matches: -3464 matches.sort(key=lambda x: -x[0]) -3465 for _,e in matches: -3466 try: -3467 return e._parse( instring, loc, doActions ) -3468 except ParseException as err: -3469 err.__traceback__ = None -3470 if err.loc > maxExcLoc: -3471 maxException = err -3472 maxExcLoc = err.loc -3473 -3474 if maxException is not None: -3475 maxException.msg = self.errmsg -3476 raise maxException -3477 else: -3478 raise ParseException(instring, loc, "no defined alternatives to match", self) -
3479 -3480 -
3481 - def __ixor__(self, other ): -
3482 if isinstance( other, basestring ): -3483 other = ParserElement._literalStringClass( other ) -3484 return self.append( other ) #Or( [ self, other ] ) -
3485 -
3486 - def __str__( self ): -
3487 if hasattr(self,"name"): -3488 return self.name -3489 -3490 if self.strRepr is None: -3491 self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" -3492 -3493 return self.strRepr -
3494 -
3495 - def checkRecursion( self, parseElementList ): -
3496 subRecCheckList = parseElementList[:] + [ self ] -3497 for e in self.exprs: -3498 e.checkRecursion( subRecCheckList ) -
3499 -
3500 -3501 -class MatchFirst(ParseExpression): -
3502 """ -3503 Requires that at least one C{ParseExpression} is found. -3504 If two expressions match, the first one listed is the one that will match. -3505 May be constructed using the C{'|'} operator. -3506 -3507 Example:: -3508 # construct MatchFirst using '|' operator -3509 -3510 # watch the order of expressions to match -3511 number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) -3512 print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] -3513 -3514 # put more selective expression first -3515 number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) -3516 print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] -3517 """ -
3518 - def __init__( self, exprs, savelist = False ): -
3519 super(MatchFirst,self).__init__(exprs, savelist) -3520 if self.exprs: -3521 self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) -3522 else: -3523 self.mayReturnEmpty = True -
3524 -
3525 - def parseImpl( self, instring, loc, doActions=True ): -
3526 maxExcLoc = -1 -3527 maxException = None -3528 for e in self.exprs: -3529 try: -3530 ret = e._parse( instring, loc, doActions ) -3531 return ret -3532 except ParseException as err: -3533 if err.loc > maxExcLoc: -3534 maxException = err -3535 maxExcLoc = err.loc -3536 except IndexError: -3537 if len(instring) > maxExcLoc: -3538 maxException = ParseException(instring,len(instring),e.errmsg,self) -3539 maxExcLoc = len(instring) -3540 -3541 # only got here if no expression matched, raise exception for match that made it the furthest -3542 else: -3543 if maxException is not None: -3544 maxException.msg = self.errmsg -3545 raise maxException -3546 else: -3547 raise ParseException(instring, loc, "no defined alternatives to match", self) -
3548 -
3549 - def __ior__(self, other ): -
3550 if isinstance( other, basestring ): -3551 other = ParserElement._literalStringClass( other ) -3552 return self.append( other ) #MatchFirst( [ self, other ] ) -
3553 -
3554 - def __str__( self ): -
3555 if hasattr(self,"name"): -3556 return self.name -3557 -3558 if self.strRepr is None: -3559 self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" -3560 -3561 return self.strRepr -
3562 -
3563 - def checkRecursion( self, parseElementList ): -
3564 subRecCheckList = parseElementList[:] + [ self ] -3565 for e in self.exprs: -3566 e.checkRecursion( subRecCheckList ) -
3567 -
3568 -3569 -class Each(ParseExpression): -
3570 """ -3571 Requires all given C{ParseExpression}s to be found, but in any order. -3572 Expressions may be separated by whitespace. -3573 May be constructed using the C{'&'} operator. -3574 -3575 Example:: -3576 color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") -3577 shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") -3578 integer = Word(nums) -3579 shape_attr = "shape:" + shape_type("shape") -3580 posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") -3581 color_attr = "color:" + color("color") -3582 size_attr = "size:" + integer("size") -3583 -3584 # use Each (using operator '&') to accept attributes in any order -3585 # (shape and posn are required, color and size are optional) -3586 shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) -3587 -3588 shape_spec.runTests(''' -3589 shape: SQUARE color: BLACK posn: 100, 120 -3590 shape: CIRCLE size: 50 color: BLUE posn: 50,80 -3591 color:GREEN size:20 shape:TRIANGLE posn:20,40 -3592 ''' -3593 ) -3594 prints:: -3595 shape: SQUARE color: BLACK posn: 100, 120 -3596 ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] -3597 - color: BLACK -3598 - posn: ['100', ',', '120'] -3599 - x: 100 -3600 - y: 120 -3601 - shape: SQUARE -3602 -3603 -3604 shape: CIRCLE size: 50 color: BLUE posn: 50,80 -3605 ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] -3606 - color: BLUE -3607 - posn: ['50', ',', '80'] -3608 - x: 50 -3609 - y: 80 -3610 - shape: CIRCLE -3611 - size: 50 -3612 -3613 -3614 color: GREEN size: 20 shape: TRIANGLE posn: 20,40 -3615 ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] -3616 - color: GREEN -3617 - posn: ['20', ',', '40'] -3618 - x: 20 -3619 - y: 40 -3620 - shape: TRIANGLE -3621 - size: 20 -3622 """ -
3623 - def __init__( self, exprs, savelist = True ): -
3624 super(Each,self).__init__(exprs, savelist) -3625 self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) -3626 self.skipWhitespace = True -3627 self.initExprGroups = True -
3628 -
3629 - def parseImpl( self, instring, loc, doActions=True ): -
3630 if self.initExprGroups: -3631 self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) -3632 opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] -3633 opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] -3634 self.optionals = opt1 + opt2 -3635 self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] -3636 self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] -3637 self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] -3638 self.required += self.multirequired -3639 self.initExprGroups = False -3640 tmpLoc = loc -3641 tmpReqd = self.required[:] -3642 tmpOpt = self.optionals[:] -3643 matchOrder = [] -3644 -3645 keepMatching = True -3646 while keepMatching: -3647 tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired -3648 failed = [] -3649 for e in tmpExprs: -3650 try: -3651 tmpLoc = e.tryParse( instring, tmpLoc ) -3652 except ParseException: -3653 failed.append(e) -3654 else: -3655 matchOrder.append(self.opt1map.get(id(e),e)) -3656 if e in tmpReqd: -3657 tmpReqd.remove(e) -3658 elif e in tmpOpt: -3659 tmpOpt.remove(e) -3660 if len(failed) == len(tmpExprs): -3661 keepMatching = False -3662 -3663 if tmpReqd: -3664 missing = ", ".join(_ustr(e) for e in tmpReqd) -3665 raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) -3666 -3667 # add any unmatched Optionals, in case they have default values defined -3668 matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] -3669 -3670 resultlist = [] -3671 for e in matchOrder: -3672 loc,results = e._parse(instring,loc,doActions) -3673 resultlist.append(results) -3674 -3675 finalResults = sum(resultlist, ParseResults([])) -3676 return loc, finalResults -
3677 -
3678 - def __str__( self ): -
3679 if hasattr(self,"name"): -3680 return self.name -3681 -3682 if self.strRepr is None: -3683 self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" -3684 -3685 return self.strRepr -
3686 -
3687 - def checkRecursion( self, parseElementList ): -
3688 subRecCheckList = parseElementList[:] + [ self ] -3689 for e in self.exprs: -3690 e.checkRecursion( subRecCheckList ) -
3691 -
3692 -3693 -class ParseElementEnhance(ParserElement): -
3694 """ -3695 Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. -3696 """ -
3697 - def __init__( self, expr, savelist=False ): -
3698 super(ParseElementEnhance,self).__init__(savelist) -3699 if isinstance( expr, basestring ): -3700 if issubclass(ParserElement._literalStringClass, Token): -3701 expr = ParserElement._literalStringClass(expr) -3702 else: -3703 expr = ParserElement._literalStringClass(Literal(expr)) -3704 self.expr = expr -3705 self.strRepr = None -3706 if expr is not None: -3707 self.mayIndexError = expr.mayIndexError -3708 self.mayReturnEmpty = expr.mayReturnEmpty -3709 self.setWhitespaceChars( expr.whiteChars ) -3710 self.skipWhitespace = expr.skipWhitespace -3711 self.saveAsList = expr.saveAsList -3712 self.callPreparse = expr.callPreparse -3713 self.ignoreExprs.extend(expr.ignoreExprs) -
3714 -
3715 - def parseImpl( self, instring, loc, doActions=True ): -
3716 if self.expr is not None: -3717 return self.expr._parse( instring, loc, doActions, callPreParse=False ) -3718 else: -3719 raise ParseException("",loc,self.errmsg,self) -
3720 -
3721 - def leaveWhitespace( self ): -
3722 self.skipWhitespace = False -3723 self.expr = self.expr.copy() -3724 if self.expr is not None: -3725 self.expr.leaveWhitespace() -3726 return self -
3727 -
3728 - def ignore( self, other ): -
3729 if isinstance( other, Suppress ): -3730 if other not in self.ignoreExprs: -3731 super( ParseElementEnhance, self).ignore( other ) -3732 if self.expr is not None: -3733 self.expr.ignore( self.ignoreExprs[-1] ) -3734 else: -3735 super( ParseElementEnhance, self).ignore( other ) -3736 if self.expr is not None: -3737 self.expr.ignore( self.ignoreExprs[-1] ) -3738 return self -
3739 -
3740 - def streamline( self ): -
3741 super(ParseElementEnhance,self).streamline() -3742 if self.expr is not None: -3743 self.expr.streamline() -3744 return self -
3745 -
3746 - def checkRecursion( self, parseElementList ): -
3747 if self in parseElementList: -3748 raise RecursiveGrammarException( parseElementList+[self] ) -3749 subRecCheckList = parseElementList[:] + [ self ] -3750 if self.expr is not None: -3751 self.expr.checkRecursion( subRecCheckList ) -
3752 -
3753 - def validate( self, validateTrace=[] ): -
3754 tmp = validateTrace[:]+[self] -3755 if self.expr is not None: -3756 self.expr.validate(tmp) -3757 self.checkRecursion( [] ) -
3758 -
3759 - def __str__( self ): -
3760 try: -3761 return super(ParseElementEnhance,self).__str__() -3762 except Exception: -3763 pass -3764 -3765 if self.strRepr is None and self.expr is not None: -3766 self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) -3767 return self.strRepr -
3768 -
3769 -3770 -class FollowedBy(ParseElementEnhance): -
3771 """ -3772 Lookahead matching of the given parse expression. C{FollowedBy} -3773 does I{not} advance the parsing position within the input string, it only -3774 verifies that the specified parse expression matches at the current -3775 position. C{FollowedBy} always returns a null token list. -3776 -3777 Example:: -3778 # use FollowedBy to match a label only if it is followed by a ':' -3779 data_word = Word(alphas) -3780 label = data_word + FollowedBy(':') -3781 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) -3782 -3783 OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() -3784 prints:: -3785 [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] -3786 """ -
3787 - def __init__( self, expr ): -
3788 super(FollowedBy,self).__init__(expr) -3789 self.mayReturnEmpty = True -
3790 -
3791 - def parseImpl( self, instring, loc, doActions=True ): -
3792 self.expr.tryParse( instring, loc ) -3793 return loc, [] -
3794 -
3795 -3796 -class NotAny(ParseElementEnhance): -
3797 """ -3798 Lookahead to disallow matching with the given parse expression. C{NotAny} -3799 does I{not} advance the parsing position within the input string, it only -3800 verifies that the specified parse expression does I{not} match at the current -3801 position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} -3802 always returns a null token list. May be constructed using the '~' operator. -3803 -3804 Example:: -3805 -3806 """ -
3807 - def __init__( self, expr ): -
3808 super(NotAny,self).__init__(expr) -3809 #~ self.leaveWhitespace() -3810 self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs -3811 self.mayReturnEmpty = True -3812 self.errmsg = "Found unwanted token, "+_ustr(self.expr) -
3813 -
3814 - def parseImpl( self, instring, loc, doActions=True ): -
3815 if self.expr.canParseNext(instring, loc): -3816 raise ParseException(instring, loc, self.errmsg, self) -3817 return loc, [] -
3818 -
3819 - def __str__( self ): -
3820 if hasattr(self,"name"): -3821 return self.name -3822 -3823 if self.strRepr is None: -3824 self.strRepr = "~{" + _ustr(self.expr) + "}" -3825 -3826 return self.strRepr -
3827 -
3828 -class _MultipleMatch(ParseElementEnhance): -
3829 - def __init__( self, expr, stopOn=None): -
3830 super(_MultipleMatch, self).__init__(expr) -3831 self.saveAsList = True -3832 ender = stopOn -3833 if isinstance(ender, basestring): -3834 ender = ParserElement._literalStringClass(ender) -3835 self.not_ender = ~ender if ender is not None else None -
3836 -
3837 - def parseImpl( self, instring, loc, doActions=True ): -
3838 self_expr_parse = self.expr._parse -3839 self_skip_ignorables = self._skipIgnorables -3840 check_ender = self.not_ender is not None -3841 if check_ender: -3842 try_not_ender = self.not_ender.tryParse -3843 -3844 # must be at least one (but first see if we are the stopOn sentinel; -3845 # if so, fail) -3846 if check_ender: -3847 try_not_ender(instring, loc) -3848 loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) -3849 try: -3850 hasIgnoreExprs = (not not self.ignoreExprs) -3851 while 1: -3852 if check_ender: -3853 try_not_ender(instring, loc) -3854 if hasIgnoreExprs: -3855 preloc = self_skip_ignorables( instring, loc ) -3856 else: -3857 preloc = loc -3858 loc, tmptokens = self_expr_parse( instring, preloc, doActions ) -3859 if tmptokens or tmptokens.haskeys(): -3860 tokens += tmptokens -3861 except (ParseException,IndexError): -3862 pass -3863 -3864 return loc, tokens -
3865 -
3866 -class OneOrMore(_MultipleMatch): -
3867 """ -3868 Repetition of one or more of the given expression. -3869 -3870 Parameters: -3871 - expr - expression that must match one or more times -3872 - stopOn - (default=C{None}) - expression for a terminating sentinel -3873 (only required if the sentinel would ordinarily match the repetition -3874 expression) -3875 -3876 Example:: -3877 data_word = Word(alphas) -3878 label = data_word + FollowedBy(':') -3879 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) -3880 -3881 text = "shape: SQUARE posn: upper left color: BLACK" -3882 OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] -3883 -3884 # use stopOn attribute for OneOrMore to avoid reading label string as part of the data -3885 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) -3886 OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] -3887 -3888 # could also be written as -3889 (attr_expr * (1,)).parseString(text).pprint() -3890 """ -3891 -
3892 - def __str__( self ): -
3893 if hasattr(self,"name"): -3894 return self.name -3895 -3896 if self.strRepr is None: -3897 self.strRepr = "{" + _ustr(self.expr) + "}..." -3898 -3899 return self.strRepr -
3900 -
3901 -class ZeroOrMore(_MultipleMatch): -
3902 """ -3903 Optional repetition of zero or more of the given expression. -3904 -3905 Parameters: -3906 - expr - expression that must match zero or more times -3907 - stopOn - (default=C{None}) - expression for a terminating sentinel -3908 (only required if the sentinel would ordinarily match the repetition -3909 expression) -3910 -3911 Example: similar to L{OneOrMore} -3912 """ -
3913 - def __init__( self, expr, stopOn=None): -
3914 super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) -3915 self.mayReturnEmpty = True -
3916 -
3917 - def parseImpl( self, instring, loc, doActions=True ): -
3918 try: -3919 return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) -3920 except (ParseException,IndexError): -3921 return loc, [] -
3922 -
3923 - def __str__( self ): -
3924 if hasattr(self,"name"): -3925 return self.name -3926 -3927 if self.strRepr is None: -3928 self.strRepr = "[" + _ustr(self.expr) + "]..." -3929 -3930 return self.strRepr -
3931 -
3932 -class _NullToken(object): -
3933 - def __bool__(self): -
3934 return False -
3935 __nonzero__ = __bool__ -
3936 - def __str__(self): -
3937 return "" -
3938 -3939 _optionalNotMatched = _NullToken() -
3940 -class Optional(ParseElementEnhance): -
3941 """ -3942 Optional matching of the given expression. -3943 -3944 Parameters: -3945 - expr - expression that must match zero or more times -3946 - default (optional) - value to be returned if the optional expression is not found. -3947 -3948 Example:: -3949 # US postal code can be a 5-digit zip, plus optional 4-digit qualifier -3950 zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) -3951 zip.runTests(''' -3952 # traditional ZIP code -3953 12345 -3954 -3955 # ZIP+4 form -3956 12101-0001 -3957 -3958 # invalid ZIP -3959 98765- -3960 ''') -3961 prints:: -3962 # traditional ZIP code -3963 12345 -3964 ['12345'] -3965 -3966 # ZIP+4 form -3967 12101-0001 -3968 ['12101-0001'] -3969 -3970 # invalid ZIP -3971 98765- -3972 ^ -3973 FAIL: Expected end of text (at char 5), (line:1, col:6) -3974 """ -
3975 - def __init__( self, expr, default=_optionalNotMatched ): -
3976 super(Optional,self).__init__( expr, savelist=False ) -3977 self.saveAsList = self.expr.saveAsList -3978 self.defaultValue = default -3979 self.mayReturnEmpty = True -
3980 -
3981 - def parseImpl( self, instring, loc, doActions=True ): -
3982 try: -3983 loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) -3984 except (ParseException,IndexError): -3985 if self.defaultValue is not _optionalNotMatched: -3986 if self.expr.resultsName: -3987 tokens = ParseResults([ self.defaultValue ]) -3988 tokens[self.expr.resultsName] = self.defaultValue -3989 else: -3990 tokens = [ self.defaultValue ] -3991 else: -3992 tokens = [] -3993 return loc, tokens -
3994 -
3995 - def __str__( self ): -
3996 if hasattr(self,"name"): -3997 return self.name -3998 -3999 if self.strRepr is None: -4000 self.strRepr = "[" + _ustr(self.expr) + "]" -4001 -4002 return self.strRepr -
4003 -
4004 -class SkipTo(ParseElementEnhance): -
4005 """ -4006 Token for skipping over all undefined text until the matched expression is found. -4007 -4008 Parameters: -4009 - expr - target expression marking the end of the data to be skipped -4010 - include - (default=C{False}) if True, the target expression is also parsed -4011 (the skipped text and target expression are returned as a 2-element list). -4012 - ignore - (default=C{None}) used to define grammars (typically quoted strings and -4013 comments) that might contain false matches to the target expression -4014 - failOn - (default=C{None}) define expressions that are not allowed to be -4015 included in the skipped test; if found before the target expression is found, -4016 the SkipTo is not a match -4017 -4018 Example:: -4019 report = ''' -4020 Outstanding Issues Report - 1 Jan 2000 -4021 -4022 # | Severity | Description | Days Open -4023 -----+----------+-------------------------------------------+----------- -4024 101 | Critical | Intermittent system crash | 6 -4025 94 | Cosmetic | Spelling error on Login ('log|n') | 14 -4026 79 | Minor | System slow when running too many reports | 47 -4027 ''' -4028 integer = Word(nums) -4029 SEP = Suppress('|') -4030 # use SkipTo to simply match everything up until the next SEP -4031 # - ignore quoted strings, so that a '|' character inside a quoted string does not match -4032 # - parse action will call token.strip() for each matched token, i.e., the description body -4033 string_data = SkipTo(SEP, ignore=quotedString) -4034 string_data.setParseAction(tokenMap(str.strip)) -4035 ticket_expr = (integer("issue_num") + SEP -4036 + string_data("sev") + SEP -4037 + string_data("desc") + SEP -4038 + integer("days_open")) -4039 -4040 for tkt in ticket_expr.searchString(report): -4041 print tkt.dump() -4042 prints:: -4043 ['101', 'Critical', 'Intermittent system crash', '6'] -4044 - days_open: 6 -4045 - desc: Intermittent system crash -4046 - issue_num: 101 -4047 - sev: Critical -4048 ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] -4049 - days_open: 14 -4050 - desc: Spelling error on Login ('log|n') -4051 - issue_num: 94 -4052 - sev: Cosmetic -4053 ['79', 'Minor', 'System slow when running too many reports', '47'] -4054 - days_open: 47 -4055 - desc: System slow when running too many reports -4056 - issue_num: 79 -4057 - sev: Minor -4058 """ -
4059 - def __init__( self, other, include=False, ignore=None, failOn=None ): -
4060 super( SkipTo, self ).__init__( other ) -4061 self.ignoreExpr = ignore -4062 self.mayReturnEmpty = True -4063 self.mayIndexError = False -4064 self.includeMatch = include -4065 self.asList = False -4066 if isinstance(failOn, basestring): -4067 self.failOn = ParserElement._literalStringClass(failOn) -4068 else: -4069 self.failOn = failOn -4070 self.errmsg = "No match found for "+_ustr(self.expr) -
4071 -
4072 - def parseImpl( self, instring, loc, doActions=True ): -
4073 startloc = loc -4074 instrlen = len(instring) -4075 expr = self.expr -4076 expr_parse = self.expr._parse -4077 self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None -4078 self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None -4079 -4080 tmploc = loc -4081 while tmploc <= instrlen: -4082 if self_failOn_canParseNext is not None: -4083 # break if failOn expression matches -4084 if self_failOn_canParseNext(instring, tmploc): -4085 break -4086 -4087 if self_ignoreExpr_tryParse is not None: -4088 # advance past ignore expressions -4089 while 1: -4090 try: -4091 tmploc = self_ignoreExpr_tryParse(instring, tmploc) -4092 except ParseBaseException: -4093 break -4094 -4095 try: -4096 expr_parse(instring, tmploc, doActions=False, callPreParse=False) -4097 except (ParseException, IndexError): -4098 # no match, advance loc in string -4099 tmploc += 1 -4100 else: -4101 # matched skipto expr, done -4102 break -4103 -4104 else: -4105 # ran off the end of the input string without matching skipto expr, fail -4106 raise ParseException(instring, loc, self.errmsg, self) -4107 -4108 # build up return values -4109 loc = tmploc -4110 skiptext = instring[startloc:loc] -4111 skipresult = ParseResults(skiptext) -4112 -4113 if self.includeMatch: -4114 loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) -4115 skipresult += mat -4116 -4117 return loc, skipresult -
4118 -
4119 -class Forward(ParseElementEnhance): -
4120 """ -4121 Forward declaration of an expression to be defined later - -4122 used for recursive grammars, such as algebraic infix notation. -4123 When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. -4124 -4125 Note: take care when assigning to C{Forward} not to overlook precedence of operators. -4126 Specifically, '|' has a lower precedence than '<<', so that:: -4127 fwdExpr << a | b | c -4128 will actually be evaluated as:: -4129 (fwdExpr << a) | b | c -4130 thereby leaving b and c out as parseable alternatives. It is recommended that you -4131 explicitly group the values inserted into the C{Forward}:: -4132 fwdExpr << (a | b | c) -4133 Converting to use the '<<=' operator instead will avoid this problem. -4134 -4135 See L{ParseResults.pprint} for an example of a recursive parser created using -4136 C{Forward}. -4137 """ -
4138 - def __init__( self, other=None ): -
4139 super(Forward,self).__init__( other, savelist=False ) -
4140 -
4141 - def __lshift__( self, other ): -
4142 if isinstance( other, basestring ): -4143 other = ParserElement._literalStringClass(other) -4144 self.expr = other -4145 self.strRepr = None -4146 self.mayIndexError = self.expr.mayIndexError -4147 self.mayReturnEmpty = self.expr.mayReturnEmpty -4148 self.setWhitespaceChars( self.expr.whiteChars ) -4149 self.skipWhitespace = self.expr.skipWhitespace -4150 self.saveAsList = self.expr.saveAsList -4151 self.ignoreExprs.extend(self.expr.ignoreExprs) -4152 return self -
4153 -
4154 - def __ilshift__(self, other): -
4155 return self << other -
4156 -
4157 - def leaveWhitespace( self ): -
4158 self.skipWhitespace = False -4159 return self -
4160 -
4161 - def streamline( self ): -
4162 if not self.streamlined: -4163 self.streamlined = True -4164 if self.expr is not None: -4165 self.expr.streamline() -4166 return self -
4167 -
4168 - def validate( self, validateTrace=[] ): -
4169 if self not in validateTrace: -4170 tmp = validateTrace[:]+[self] -4171 if self.expr is not None: -4172 self.expr.validate(tmp) -4173 self.checkRecursion([]) -
4174 -
4175 - def __str__( self ): -
4176 if hasattr(self,"name"): -4177 return self.name -4178 return self.__class__.__name__ + ": ..." -4179 -4180 # stubbed out for now - creates awful memory and perf issues -4181 self._revertClass = self.__class__ -4182 self.__class__ = _ForwardNoRecurse -4183 try: -4184 if self.expr is not None: -4185 retString = _ustr(self.expr) -4186 else: -4187 retString = "None" -4188 finally: -4189 self.__class__ = self._revertClass -4190 return self.__class__.__name__ + ": " + retString -
4191 -
4192 - def copy(self): -
4193 if self.expr is not None: -4194 return super(Forward,self).copy() -4195 else: -4196 ret = Forward() -4197 ret <<= self -4198 return ret -
4199 -
4200 -class _ForwardNoRecurse(Forward): -
4201 - def __str__( self ): -
4202 return "..." -
4203 -
4204 -class TokenConverter(ParseElementEnhance): -
4205 """ -4206 Abstract subclass of C{ParseExpression}, for converting parsed results. -4207 """ -
4208 - def __init__( self, expr, savelist=False ): -
4209 super(TokenConverter,self).__init__( expr )#, savelist ) -4210 self.saveAsList = False -
4211 -
4212 -class Combine(TokenConverter): -
4213 """ -4214 Converter to concatenate all matching tokens to a single string. -4215 By default, the matching patterns must also be contiguous in the input string; -4216 this can be disabled by specifying C{'adjacent=False'} in the constructor. -4217 -4218 Example:: -4219 real = Word(nums) + '.' + Word(nums) -4220 print(real.parseString('3.1416')) # -> ['3', '.', '1416'] -4221 # will also erroneously match the following -4222 print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] -4223 -4224 real = Combine(Word(nums) + '.' + Word(nums)) -4225 print(real.parseString('3.1416')) # -> ['3.1416'] -4226 # no match when there are internal spaces -4227 print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) -4228 """ -
4229 - def __init__( self, expr, joinString="", adjacent=True ): -
4230 super(Combine,self).__init__( expr ) -4231 # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself -4232 if adjacent: -4233 self.leaveWhitespace() -4234 self.adjacent = adjacent -4235 self.skipWhitespace = True -4236 self.joinString = joinString -4237 self.callPreparse = True -
4238 -
4239 - def ignore( self, other ): -
4240 if self.adjacent: -4241 ParserElement.ignore(self, other) -4242 else: -4243 super( Combine, self).ignore( other ) -4244 return self -
4245 -
4246 - def postParse( self, instring, loc, tokenlist ): -
4247 retToks = tokenlist.copy() -4248 del retToks[:] -4249 retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) -4250 -4251 if self.resultsName and retToks.haskeys(): -4252 return [ retToks ] -4253 else: -4254 return retToks -
4255 -
4256 -class Group(TokenConverter): -
4257 """ -4258 Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. -4259 -4260 Example:: -4261 ident = Word(alphas) -4262 num = Word(nums) -4263 term = ident | num -4264 func = ident + Optional(delimitedList(term)) -4265 print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] -4266 -4267 func = ident + Group(Optional(delimitedList(term))) -4268 print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] -4269 """ -
4270 - def __init__( self, expr ): -
4271 super(Group,self).__init__( expr ) -4272 self.saveAsList = True -
4273 -
4274 - def postParse( self, instring, loc, tokenlist ): -
4275 return [ tokenlist ] -
4276 -
4277 -class Dict(TokenConverter): -
4278 """ -4279 Converter to return a repetitive expression as a list, but also as a dictionary. -4280 Each element can also be referenced using the first token in the expression as its key. -4281 Useful for tabular report scraping when the first column can be used as a item key. -4282 -4283 Example:: -4284 data_word = Word(alphas) -4285 label = data_word + FollowedBy(':') -4286 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) -4287 -4288 text = "shape: SQUARE posn: upper left color: light blue texture: burlap" -4289 attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) -4290 -4291 # print attributes as plain groups -4292 print(OneOrMore(attr_expr).parseString(text).dump()) -4293 -4294 # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names -4295 result = Dict(OneOrMore(Group(attr_expr))).parseString(text) -4296 print(result.dump()) -4297 -4298 # access named fields as dict entries, or output as dict -4299 print(result['shape']) -4300 print(result.asDict()) -4301 prints:: -4302 ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] -4303 -4304 [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] -4305 - color: light blue -4306 - posn: upper left -4307 - shape: SQUARE -4308 - texture: burlap -4309 SQUARE -4310 {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} -4311 See more examples at L{ParseResults} of accessing fields by results name. -4312 """ -
4313 - def __init__( self, expr ): -
4314 super(Dict,self).__init__( expr ) -4315 self.saveAsList = True -
4316 -
4317 - def postParse( self, instring, loc, tokenlist ): -
4318 for i,tok in enumerate(tokenlist): -4319 if len(tok) == 0: -4320 continue -4321 ikey = tok[0] -4322 if isinstance(ikey,int): -4323 ikey = _ustr(tok[0]).strip() -4324 if len(tok)==1: -4325 tokenlist[ikey] = _ParseResultsWithOffset("",i) -4326 elif len(tok)==2 and not isinstance(tok[1],ParseResults): -4327 tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) -4328 else: -4329 dictvalue = tok.copy() #ParseResults(i) -4330 del dictvalue[0] -4331 if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): -4332 tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) -4333 else: -4334 tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) -4335 -4336 if self.resultsName: -4337 return [ tokenlist ] -4338 else: -4339 return tokenlist -
4340 -
4341 -4342 -class Suppress(TokenConverter): -
4343 """ -4344 Converter for ignoring the results of a parsed expression. -4345 -4346 Example:: -4347 source = "a, b, c,d" -4348 wd = Word(alphas) -4349 wd_list1 = wd + ZeroOrMore(',' + wd) -4350 print(wd_list1.parseString(source)) -4351 -4352 # often, delimiters that are useful during parsing are just in the -4353 # way afterward - use Suppress to keep them out of the parsed output -4354 wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) -4355 print(wd_list2.parseString(source)) -4356 prints:: -4357 ['a', ',', 'b', ',', 'c', ',', 'd'] -4358 ['a', 'b', 'c', 'd'] -4359 (See also L{delimitedList}.) -4360 """ -
4361 - def postParse( self, instring, loc, tokenlist ): -
4362 return [] -
4363 -
4364 - def suppress( self ): -
4365 return self -
4366 -
4367 -4368 -class OnlyOnce(object): -
4369 """ -4370 Wrapper for parse actions, to ensure they are only called once. -4371 """ -
4372 - def __init__(self, methodCall): -
4373 self.callable = _trim_arity(methodCall) -4374 self.called = False -
4375 - def __call__(self,s,l,t): -
4376 if not self.called: -4377 results = self.callable(s,l,t) -4378 self.called = True -4379 return results -4380 raise ParseException(s,l,"") -
4381 - def reset(self): -
4382 self.called = False -
4383 -
4384 -def traceParseAction(f): -
4385 """ -4386 Decorator for debugging parse actions. -4387 -4388 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})".} -4389 When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. -4390 -4391 Example:: -4392 wd = Word(alphas) -4393 -4394 @traceParseAction -4395 def remove_duplicate_chars(tokens): -4396 return ''.join(sorted(set(''.join(tokens))) -4397 -4398 wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) -4399 print(wds.parseString("slkdjs sld sldd sdlf sdljf")) -4400 prints:: -4401 >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) -4402 <<leaving remove_duplicate_chars (ret: 'dfjkls') -4403 ['dfjkls'] -4404 """ -4405 f = _trim_arity(f) -4406 def z(*paArgs): -4407 thisFunc = f.__name__ -4408 s,l,t = paArgs[-3:] -4409 if len(paArgs)>3: -4410 thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc -4411 sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) -4412 try: -4413 ret = f(*paArgs) -4414 except Exception as exc: -4415 sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) -4416 raise -4417 sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) -4418 return ret -
4419 try: -4420 z.__name__ = f.__name__ -4421 except AttributeError: -4422 pass -4423 return z -4424 -
4425 # -4426 # global helpers -4427 # -4428 -def delimitedList( expr, delim=",", combine=False ): -
4429 """ -4430 Helper to define a delimited list of expressions - the delimiter defaults to ','. -4431 By default, the list elements and delimiters can have intervening whitespace, and -4432 comments, but this can be overridden by passing C{combine=True} in the constructor. -4433 If C{combine} is set to C{True}, the matching tokens are returned as a single token -4434 string, with the delimiters included; otherwise, the matching tokens are returned -4435 as a list of tokens, with the delimiters suppressed. -4436 -4437 Example:: -4438 delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] -4439 delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] -4440 """ -4441 dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." -4442 if combine: -4443 return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) -4444 else: -4445 return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) -
4446 -
4447 -def countedArray( expr, intExpr=None ): -
4448 """ -4449 Helper to define a counted list of expressions. -4450 This helper defines a pattern of the form:: -4451 integer expr expr expr... -4452 where the leading integer tells how many expr expressions follow. -4453 The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. -4454 -4455 If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. -4456 -4457 Example:: -4458 countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] -4459 -4460 # in this parser, the leading integer value is given in binary, -4461 # '10' indicating that 2 values are in the array -4462 binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) -4463 countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] -4464 """ -4465 arrayExpr = Forward() -4466 def countFieldParseAction(s,l,t): -4467 n = t[0] -4468 arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) -4469 return [] -
4470 if intExpr is None: -4471 intExpr = Word(nums).setParseAction(lambda t:int(t[0])) -4472 else: -4473 intExpr = intExpr.copy() -4474 intExpr.setName("arrayLen") -4475 intExpr.addParseAction(countFieldParseAction, callDuringTry=True) -4476 return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') -4477 -
4478 -def _flatten(L): -
4479 ret = [] -4480 for i in L: -4481 if isinstance(i,list): -4482 ret.extend(_flatten(i)) -4483 else: -4484 ret.append(i) -4485 return ret -
4486 -
4487 -def matchPreviousLiteral(expr): -
4488 """ -4489 Helper to define an expression that is indirectly defined from -4490 the tokens matched in a previous expression, that is, it looks -4491 for a 'repeat' of a previous expression. For example:: -4492 first = Word(nums) -4493 second = matchPreviousLiteral(first) -4494 matchExpr = first + ":" + second -4495 will match C{"1:1"}, but not C{"1:2"}. Because this matches a -4496 previous literal, will also match the leading C{"1:1"} in C{"1:10"}. -4497 If this is not desired, use C{matchPreviousExpr}. -4498 Do I{not} use with packrat parsing enabled. -4499 """ -4500 rep = Forward() -4501 def copyTokenToRepeater(s,l,t): -4502 if t: -4503 if len(t) == 1: -4504 rep << t[0] -4505 else: -4506 # flatten t tokens -4507 tflat = _flatten(t.asList()) -4508 rep << And(Literal(tt) for tt in tflat) -4509 else: -4510 rep << Empty() -
4511 expr.addParseAction(copyTokenToRepeater, callDuringTry=True) -4512 rep.setName('(prev) ' + _ustr(expr)) -4513 return rep -4514 -
4515 -def matchPreviousExpr(expr): -
4516 """ -4517 Helper to define an expression that is indirectly defined from -4518 the tokens matched in a previous expression, that is, it looks -4519 for a 'repeat' of a previous expression. For example:: -4520 first = Word(nums) -4521 second = matchPreviousExpr(first) -4522 matchExpr = first + ":" + second -4523 will match C{"1:1"}, but not C{"1:2"}. Because this matches by -4524 expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; -4525 the expressions are evaluated first, and then compared, so -4526 C{"1"} is compared with C{"10"}. -4527 Do I{not} use with packrat parsing enabled. -4528 """ -4529 rep = Forward() -4530 e2 = expr.copy() -4531 rep <<= e2 -4532 def copyTokenToRepeater(s,l,t): -4533 matchTokens = _flatten(t.asList()) -4534 def mustMatchTheseTokens(s,l,t): -4535 theseTokens = _flatten(t.asList()) -4536 if theseTokens != matchTokens: -4537 raise ParseException("",0,"") -
4538 rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) -4539 expr.addParseAction(copyTokenToRepeater, callDuringTry=True) -4540 rep.setName('(prev) ' + _ustr(expr)) -4541 return rep -4542 -
4544 #~ escape these chars: ^-] -4545 for c in r"\^-]": -4546 s = s.replace(c,_bslash+c) -4547 s = s.replace("\n",r"\n") -4548 s = s.replace("\t",r"\t") -4549 return _ustr(s) -
4550 -
4551 -def oneOf( strs, caseless=False, useRegex=True ): -
4552 """ -4553 Helper to quickly define a set of alternative Literals, and makes sure to do -4554 longest-first testing when there is a conflict, regardless of the input order, -4555 but returns a C{L{MatchFirst}} for best performance. -4556 -4557 Parameters: -4558 - strs - a string of space-delimited literals, or a collection of string literals -4559 - caseless - (default=C{False}) - treat all literals as caseless -4560 - useRegex - (default=C{True}) - as an optimization, will generate a Regex -4561 object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or -4562 if creating a C{Regex} raises an exception) -4563 -4564 Example:: -4565 comp_oper = oneOf("< = > <= >= !=") -4566 var = Word(alphas) -4567 number = Word(nums) -4568 term = var | number -4569 comparison_expr = term + comp_oper + term -4570 print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) -4571 prints:: -4572 [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] -4573 """ -4574 if caseless: -4575 isequal = ( lambda a,b: a.upper() == b.upper() ) -4576 masks = ( lambda a,b: b.upper().startswith(a.upper()) ) -4577 parseElementClass = CaselessLiteral -4578 else: -4579 isequal = ( lambda a,b: a == b ) -4580 masks = ( lambda a,b: b.startswith(a) ) -4581 parseElementClass = Literal -4582 -4583 symbols = [] -4584 if isinstance(strs,basestring): -4585 symbols = strs.split() -4586 elif isinstance(strs, collections.Iterable): -4587 symbols = list(strs) -4588 else: -4589 warnings.warn("Invalid argument to oneOf, expected string or iterable", -4590 SyntaxWarning, stacklevel=2) -4591 if not symbols: -4592 return NoMatch() -4593 -4594 i = 0 -4595 while i < len(symbols)-1: -4596 cur = symbols[i] -4597 for j,other in enumerate(symbols[i+1:]): -4598 if ( isequal(other, cur) ): -4599 del symbols[i+j+1] -4600 break -4601 elif ( masks(cur, other) ): -4602 del symbols[i+j+1] -4603 symbols.insert(i,other) -4604 cur = other -4605 break -4606 else: -4607 i += 1 -4608 -4609 if not caseless and useRegex: -4610 #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) -4611 try: -4612 if len(symbols)==len("".join(symbols)): -4613 return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) -4614 else: -4615 return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) -4616 except Exception: -4617 warnings.warn("Exception creating Regex for oneOf, building MatchFirst", -4618 SyntaxWarning, stacklevel=2) -4619 -4620 -4621 # last resort, just use MatchFirst -4622 return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) -
4623 -
4624 -def dictOf( key, value ): -
4625 """ -4626 Helper to easily and clearly define a dictionary by specifying the respective patterns -4627 for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens -4628 in the proper order. The key pattern can include delimiting markers or punctuation, -4629 as long as they are suppressed, thereby leaving the significant key text. The value -4630 pattern can include named results, so that the C{Dict} results can include named token -4631 fields. -4632 -4633 Example:: -4634 text = "shape: SQUARE posn: upper left color: light blue texture: burlap" -4635 attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) -4636 print(OneOrMore(attr_expr).parseString(text).dump()) -4637 -4638 attr_label = label -4639 attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) -4640 -4641 # similar to Dict, but simpler call format -4642 result = dictOf(attr_label, attr_value).parseString(text) -4643 print(result.dump()) -4644 print(result['shape']) -4645 print(result.shape) # object attribute access works too -4646 print(result.asDict()) -4647 prints:: -4648 [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] -4649 - color: light blue -4650 - posn: upper left -4651 - shape: SQUARE -4652 - texture: burlap -4653 SQUARE -4654 SQUARE -4655 {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} -4656 """ -4657 return Dict( ZeroOrMore( Group ( key + value ) ) ) -
4658 -
4659 -def originalTextFor(expr, asString=True): -
4660 """ -4661 Helper to return the original, untokenized text for a given expression. Useful to -4662 restore the parsed fields of an HTML start tag into the raw tag text itself, or to -4663 revert separate tokens with intervening whitespace back to the original matching -4664 input text. By default, returns astring containing the original parsed text. -4665 -4666 If the optional C{asString} argument is passed as C{False}, then the return value is a -4667 C{L{ParseResults}} containing any results names that were originally matched, and a -4668 single token containing the original matched text from the input string. So if -4669 the expression passed to C{L{originalTextFor}} contains expressions with defined -4670 results names, you must set C{asString} to C{False} if you want to preserve those -4671 results name values. -4672 -4673 Example:: -4674 src = "this is test <b> bold <i>text</i> </b> normal text " -4675 for tag in ("b","i"): -4676 opener,closer = makeHTMLTags(tag) -4677 patt = originalTextFor(opener + SkipTo(closer) + closer) -4678 print(patt.searchString(src)[0]) -4679 prints:: -4680 ['<b> bold <i>text</i> </b>'] -4681 ['<i>text</i>'] -4682 """ -4683 locMarker = Empty().setParseAction(lambda s,loc,t: loc) -4684 endlocMarker = locMarker.copy() -4685 endlocMarker.callPreparse = False -4686 matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") -4687 if asString: -4688 extractText = lambda s,l,t: s[t._original_start:t._original_end] -4689 else: -4690 def extractText(s,l,t): -4691 t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] -
4692 matchExpr.setParseAction(extractText) -4693 matchExpr.ignoreExprs = expr.ignoreExprs -4694 return matchExpr -4695 -
4696 -def ungroup(expr): -
4697 """ -4698 Helper to undo pyparsing's default grouping of And expressions, even -4699 if all but one are non-empty. -4700 """ -4701 return TokenConverter(expr).setParseAction(lambda t:t[0]) -4702 -
4703 -def locatedExpr(expr): -
4704 """ -4705 Helper to decorate a returned token with its starting and ending locations in the input string. -4706 This helper adds the following results names: -4707 - locn_start = location where matched expression begins -4708 - locn_end = location where matched expression ends -4709 - value = the actual parsed results -4710 -4711 Be careful if the input text contains C{<TAB>} characters, you may want to call -4712 C{L{ParserElement.parseWithTabs}} -4713 -4714 Example:: -4715 wd = Word(alphas) -4716 for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): -4717 print(match) -4718 prints:: -4719 [[0, 'ljsdf', 5]] -4720 [[8, 'lksdjjf', 15]] -4721 [[18, 'lkkjj', 23]] -4722 """ -4723 locator = Empty().setParseAction(lambda s,l,t: l) -4724 return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) -
4725 -4726 -4727 # convenience constants for positional expressions -4728 empty = Empty().setName("empty") -4729 lineStart = LineStart().setName("lineStart") -4730 lineEnd = LineEnd().setName("lineEnd") -4731 stringStart = StringStart().setName("stringStart") -4732 stringEnd = StringEnd().setName("stringEnd") -4733 -4734 _escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) -4735 _escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) -4736 _escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) -4737 _singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE) -4738 _charRange = Group(_singleChar + Suppress("-") + _singleChar) -4739 _reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" -
4740 -4741 -def srange(s): -
4742 r""" -4743 Helper to easily define string ranges for use in Word construction. Borrows -4744 syntax from regexp '[]' string range definitions:: -4745 srange("[0-9]") -> "0123456789" -4746 srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" -4747 srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" -4748 The input string must be enclosed in []'s, and the returned string is the expanded -4749 character set joined into a single string. -4750 The values enclosed in the []'s may be: -4751 - a single character -4752 - an escaped character with a leading backslash (such as C{\-} or C{\]}) -4753 - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) -4754 (C{\0x##} is also supported for backwards compatibility) -4755 - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) -4756 - a range of any of the above, separated by a dash (C{'a-z'}, etc.) -4757 - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) -4758 """ -4759 _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) -4760 try: -4761 return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) -4762 except Exception: -4763 return "" -
4764 -
4765 -def matchOnlyAtCol(n): -
4766 """ -4767 Helper method for defining parse actions that require matching at a specific -4768 column in the input text. -4769 """ -4770 def verifyCol(strg,locn,toks): -4771 if col(locn,strg) != n: -4772 raise ParseException(strg,locn,"matched token not at column %d" % n) -
4773 return verifyCol -4774 -
4775 -def replaceWith(replStr): -
4776 """ -4777 Helper method for common parse actions that simply return a literal value. Especially -4778 useful when used with C{L{transformString<ParserElement.transformString>}()}. -4779 -4780 Example:: -4781 num = Word(nums).setParseAction(lambda toks: int(toks[0])) -4782 na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) -4783 term = na | num -4784 -4785 OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] -4786 """ -4787 return lambda s,l,t: [replStr] -
4788 -
4789 -def removeQuotes(s,l,t): -
4790 """ -4791 Helper parse action for removing quotation marks from parsed quoted strings. -4792 -4793 Example:: -4794 # by default, quotation marks are included in parsed results -4795 quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] -4796 -4797 # use removeQuotes to strip quotation marks from parsed results -4798 quotedString.setParseAction(removeQuotes) -4799 quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] -4800 """ -4801 return t[0][1:-1] -
4802 -
4803 -def tokenMap(func, *args): -
4804 """ -4805 Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional -4806 args are passed, they are forwarded to the given function as additional arguments after -4807 the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the -4808 parsed data to an integer using base 16. -4809 -4810 Example (compare the last to example in L{ParserElement.transformString}:: -4811 hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) -4812 hex_ints.runTests(''' -4813 00 11 22 aa FF 0a 0d 1a -4814 ''') -4815 -4816 upperword = Word(alphas).setParseAction(tokenMap(str.upper)) -4817 OneOrMore(upperword).runTests(''' -4818 my kingdom for a horse -4819 ''') -4820 -4821 wd = Word(alphas).setParseAction(tokenMap(str.title)) -4822 OneOrMore(wd).setParseAction(' '.join).runTests(''' -4823 now is the winter of our discontent made glorious summer by this sun of york -4824 ''') -4825 prints:: -4826 00 11 22 aa FF 0a 0d 1a -4827 [0, 17, 34, 170, 255, 10, 13, 26] -4828 -4829 my kingdom for a horse -4830 ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] -4831 -4832 now is the winter of our discontent made glorious summer by this sun of york -4833 ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] -4834 """ -4835 def pa(s,l,t): -4836 return [func(tokn, *args) for tokn in t] -
4837 -4838 try: -4839 func_name = getattr(func, '__name__', -4840 getattr(func, '__class__').__name__) -4841 except Exception: -4842 func_name = str(func) -4843 pa.__name__ = func_name -4844 -4845 return pa -4846 -4847 upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) -4848 """(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" -4849 -4850 downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) -4851 """(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" -
4852 -4853 -def _makeTags(tagStr, xml): -
4854 """Internal helper to construct opening and closing tag expressions, given a tag name""" -4855 if isinstance(tagStr,basestring): -4856 resname = tagStr -4857 tagStr = Keyword(tagStr, caseless=not xml) -4858 else: -4859 resname = tagStr.name -4860 -4861 tagAttrName = Word(alphas,alphanums+"_-:") -4862 if (xml): -4863 tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) -4864 openTag = Suppress("<") + tagStr("tag") + \ -4865 Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ -4866 Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") -4867 else: -4868 printablesLessRAbrack = "".join(c for c in printables if c not in ">") -4869 tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) -4870 openTag = Suppress("<") + tagStr("tag") + \ -4871 Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ -4872 Optional( Suppress("=") + tagAttrValue ) ))) + \ -4873 Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") -4874 closeTag = Combine(_L("</") + tagStr + ">") -4875 -4876 openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) -4877 closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) -4878 openTag.tag = resname -4879 closeTag.tag = resname -4880 return openTag, closeTag -
4881 -
4882 -def makeHTMLTags(tagStr): -
4883 """ -4884 Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches -4885 tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. -4886 -4887 Example:: -4888 text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' -4889 # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple -4890 a,a_end = makeHTMLTags("A") -4891 link_expr = a + SkipTo(a_end)("link_text") + a_end -4892 -4893 for link in link_expr.searchString(text): -4894 # attributes in the <A> tag (like "href" shown here) are also accessible as named results -4895 print(link.link_text, '->', link.href) -4896 prints:: -4897 pyparsing -> http://pyparsing.wikispaces.com -4898 """ -4899 return _makeTags( tagStr, False ) -
4900 -
4901 -def makeXMLTags(tagStr): -
4902 """ -4903 Helper to construct opening and closing tag expressions for XML, given a tag name. Matches -4904 tags only in the given upper/lower case. -4905 -4906 Example: similar to L{makeHTMLTags} -4907 """ -4908 return _makeTags( tagStr, True ) -
4909 -
4910 -def withAttribute(*args,**attrDict): -
4911 """ -4912 Helper to create a validating parse action to be used with start tags created -4913 with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag -4914 with a required attribute value, to avoid false matches on common tags such as -4915 C{<TD>} or C{<DIV>}. -4916 -4917 Call C{withAttribute} with a series of attribute names and values. Specify the list -4918 of filter attributes names and values as: -4919 - keyword arguments, as in C{(align="right")}, or -4920 - as an explicit dict with C{**} operator, when an attribute name is also a Python -4921 reserved word, as in C{**{"class":"Customer", "align":"right"}} -4922 - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) -4923 For attribute names with a namespace prefix, you must use the second form. Attribute -4924 names are matched insensitive to upper/lower case. -4925 -4926 If just testing for C{class} (with or without a namespace), use C{L{withClass}}. -4927 -4928 To verify that the attribute exists, but without specifying a value, pass -4929 C{withAttribute.ANY_VALUE} as the value. -4930 -4931 Example:: -4932 html = ''' -4933 <div> -4934 Some text -4935 <div type="grid">1 4 0 1 0</div> -4936 <div type="graph">1,3 2,3 1,1</div> -4937 <div>this has no type</div> -4938 </div> -4939 -4940 ''' -4941 div,div_end = makeHTMLTags("div") -4942 -4943 # only match div tag having a type attribute with value "grid" -4944 div_grid = div().setParseAction(withAttribute(type="grid")) -4945 grid_expr = div_grid + SkipTo(div | div_end)("body") -4946 for grid_header in grid_expr.searchString(html): -4947 print(grid_header.body) -4948 -4949 # construct a match with any div tag having a type attribute, regardless of the value -4950 div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) -4951 div_expr = div_any_type + SkipTo(div | div_end)("body") -4952 for div_header in div_expr.searchString(html): -4953 print(div_header.body) -4954 prints:: -4955 1 4 0 1 0 -4956 -4957 1 4 0 1 0 -4958 1,3 2,3 1,1 -4959 """ -4960 if args: -4961 attrs = args[:] -4962 else: -4963 attrs = attrDict.items() -4964 attrs = [(k,v) for k,v in attrs] -4965 def pa(s,l,tokens): -4966 for attrName,attrValue in attrs: -4967 if attrName not in tokens: -4968 raise ParseException(s,l,"no matching attribute " + attrName) -4969 if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: -4970 raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % -4971 (attrName, tokens[attrName], attrValue)) -
4972 return pa -4973 withAttribute.ANY_VALUE = object() -
4974 -4975 -def withClass(classname, namespace=''): -
4976 """ -4977 Simplified version of C{L{withAttribute}} when matching on a div class - made -4978 difficult because C{class} is a reserved word in Python. -4979 -4980 Example:: -4981 html = ''' -4982 <div> -4983 Some text -4984 <div class="grid">1 4 0 1 0</div> -4985 <div class="graph">1,3 2,3 1,1</div> -4986 <div>this &lt;div&gt; has no class</div> -4987 </div> -4988 -4989 ''' -4990 div,div_end = makeHTMLTags("div") -4991 div_grid = div().setParseAction(withClass("grid")) -4992 -4993 grid_expr = div_grid + SkipTo(div | div_end)("body") -4994 for grid_header in grid_expr.searchString(html): -4995 print(grid_header.body) -4996 -4997 div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) -4998 div_expr = div_any_type + SkipTo(div | div_end)("body") -4999 for div_header in div_expr.searchString(html): -5000 print(div_header.body) -5001 prints:: -5002 1 4 0 1 0 -5003 -5004 1 4 0 1 0 -5005 1,3 2,3 1,1 -5006 """ -5007 classattr = "%s:class" % namespace if namespace else "class" -5008 return withAttribute(**{classattr : classname}) -
5009 -5010 opAssoc = _Constants() -5011 opAssoc.LEFT = object() -5012 opAssoc.RIGHT = object() -
5013 -5014 -def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): -
5015 """ -5016 Helper method for constructing grammars of expressions made up of -5017 operators working in a precedence hierarchy. Operators may be unary or -5018 binary, left- or right-associative. Parse actions can also be attached -5019 to operator expressions. The generated parser will also recognize the use -5020 of parentheses to override operator precedences (see example below). -5021 -5022 Note: if you define a deep operator list, you may see performance issues -5023 when using infixNotation. See L{ParserElement.enablePackrat} for a -5024 mechanism to potentially improve your parser performance. -5025 -5026 Parameters: -5027 - baseExpr - expression representing the most basic element for the nested -5028 - opList - list of tuples, one for each operator precedence level in the -5029 expression grammar; each tuple is of the form -5030 (opExpr, numTerms, rightLeftAssoc, parseAction), where: -5031 - opExpr is the pyparsing expression for the operator; -5032 may also be a string, which will be converted to a Literal; -5033 if numTerms is 3, opExpr is a tuple of two expressions, for the -5034 two operators separating the 3 terms -5035 - numTerms is the number of terms for this operator (must -5036 be 1, 2, or 3) -5037 - rightLeftAssoc is the indicator whether the operator is -5038 right or left associative, using the pyparsing-defined -5039 constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. -5040 - parseAction is the parse action to be associated with -5041 expressions matching this operator expression (the -5042 parse action tuple member may be omitted); if the parse action -5043 is passed a tuple or list of functions, this is equivalent to -5044 calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) -5045 - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) -5046 - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) -5047 -5048 Example:: -5049 # simple example of four-function arithmetic with ints and variable names -5050 integer = pyparsing_common.signed_integer -5051 varname = pyparsing_common.identifier -5052 -5053 arith_expr = infixNotation(integer | varname, -5054 [ -5055 ('-', 1, opAssoc.RIGHT), -5056 (oneOf('* /'), 2, opAssoc.LEFT), -5057 (oneOf('+ -'), 2, opAssoc.LEFT), -5058 ]) -5059 -5060 arith_expr.runTests(''' -5061 5+3*6 -5062 (5+3)*6 -5063 -2--11 -5064 ''', fullDump=False) -5065 prints:: -5066 5+3*6 -5067 [[5, '+', [3, '*', 6]]] -5068 -5069 (5+3)*6 -5070 [[[5, '+', 3], '*', 6]] -5071 -5072 -2--11 -5073 [[['-', 2], '-', ['-', 11]]] -5074 """ -5075 ret = Forward() -5076 lastExpr = baseExpr | ( lpar + ret + rpar ) -5077 for i,operDef in enumerate(opList): -5078 opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] -5079 termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr -5080 if arity == 3: -5081 if opExpr is None or len(opExpr) != 2: -5082 raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") -5083 opExpr1, opExpr2 = opExpr -5084 thisExpr = Forward().setName(termName) -5085 if rightLeftAssoc == opAssoc.LEFT: -5086 if arity == 1: -5087 matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) -5088 elif arity == 2: -5089 if opExpr is not None: -5090 matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) -5091 else: -5092 matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) -5093 elif arity == 3: -5094 matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ -5095 Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) -5096 else: -5097 raise ValueError("operator must be unary (1), binary (2), or ternary (3)") -5098 elif rightLeftAssoc == opAssoc.RIGHT: -5099 if arity == 1: -5100 # try to avoid LR with this extra test -5101 if not isinstance(opExpr, Optional): -5102 opExpr = Optional(opExpr) -5103 matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) -5104 elif arity == 2: -5105 if opExpr is not None: -5106 matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) -5107 else: -5108 matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) -5109 elif arity == 3: -5110 matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ -5111 Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) -5112 else: -5113 raise ValueError("operator must be unary (1), binary (2), or ternary (3)") -5114 else: -5115 raise ValueError("operator must indicate right or left associativity") -5116 if pa: -5117 if isinstance(pa, (tuple, list)): -5118 matchExpr.setParseAction(*pa) -5119 else: -5120 matchExpr.setParseAction(pa) -5121 thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) -5122 lastExpr = thisExpr -5123 ret <<= lastExpr -5124 return ret -
5125 -5126 operatorPrecedence = infixNotation -5127 """(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" -5128 -5129 dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") -5130 sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") -5131 quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| -5132 Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") -5133 unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") -
5134 -5135 -def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): -
5136 """ -5137 Helper method for defining nested lists enclosed in opening and closing -5138 delimiters ("(" and ")" are the default). -5139 -5140 Parameters: -5141 - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression -5142 - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression -5143 - content - expression for items within the nested lists (default=C{None}) -5144 - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) -5145 -5146 If an expression is not provided for the content argument, the nested -5147 expression will capture all whitespace-delimited content between delimiters -5148 as a list of separate values. -5149 -5150 Use the C{ignoreExpr} argument to define expressions that may contain -5151 opening or closing characters that should not be treated as opening -5152 or closing characters for nesting, such as quotedString or a comment -5153 expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. -5154 The default is L{quotedString}, but if no expressions are to be ignored, -5155 then pass C{None} for this argument. -5156 -5157 Example:: -5158 data_type = oneOf("void int short long char float double") -5159 decl_data_type = Combine(data_type + Optional(Word('*'))) -5160 ident = Word(alphas+'_', alphanums+'_') -5161 number = pyparsing_common.number -5162 arg = Group(decl_data_type + ident) -5163 LPAR,RPAR = map(Suppress, "()") -5164 -5165 code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) -5166 -5167 c_function = (decl_data_type("type") -5168 + ident("name") -5169 + LPAR + Optional(delimitedList(arg), [])("args") + RPAR -5170 + code_body("body")) -5171 c_function.ignore(cStyleComment) -5172 -5173 source_code = ''' -5174 int is_odd(int x) { -5175 return (x%2); -5176 } -5177 -5178 int dec_to_hex(char hchar) { -5179 if (hchar >= '0' && hchar <= '9') { -5180 return (ord(hchar)-ord('0')); -5181 } else { -5182 return (10+ord(hchar)-ord('A')); -5183 } -5184 } -5185 ''' -5186 for func in c_function.searchString(source_code): -5187 print("%(name)s (%(type)s) args: %(args)s" % func) -5188 -5189 prints:: -5190 is_odd (int) args: [['int', 'x']] -5191 dec_to_hex (int) args: [['char', 'hchar']] -5192 """ -5193 if opener == closer: -5194 raise ValueError("opening and closing strings cannot be the same") -5195 if content is None: -5196 if isinstance(opener,basestring) and isinstance(closer,basestring): -5197 if len(opener) == 1 and len(closer)==1: -5198 if ignoreExpr is not None: -5199 content = (Combine(OneOrMore(~ignoreExpr + -5200 CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) -5201 ).setParseAction(lambda t:t[0].strip())) -5202 else: -5203 content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS -5204 ).setParseAction(lambda t:t[0].strip())) -5205 else: -5206 if ignoreExpr is not None: -5207 content = (Combine(OneOrMore(~ignoreExpr + -5208 ~Literal(opener) + ~Literal(closer) + -5209 CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) -5210 ).setParseAction(lambda t:t[0].strip())) -5211 else: -5212 content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + -5213 CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) -5214 ).setParseAction(lambda t:t[0].strip())) -5215 else: -5216 raise ValueError("opening and closing arguments must be strings if no content expression is given") -5217 ret = Forward() -5218 if ignoreExpr is not None: -5219 ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) -5220 else: -5221 ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) -5222 ret.setName('nested %s%s expression' % (opener,closer)) -5223 return ret -
5224 -
5225 -def indentedBlock(blockStatementExpr, indentStack, indent=True): -
5226 """ -5227 Helper method for defining space-delimited indentation blocks, such as -5228 those used to define block statements in Python source code. -5229 -5230 Parameters: -5231 - blockStatementExpr - expression defining syntax of statement that -5232 is repeated within the indented block -5233 - indentStack - list created by caller to manage indentation stack -5234 (multiple statementWithIndentedBlock expressions within a single grammar -5235 should share a common indentStack) -5236 - indent - boolean indicating whether block must be indented beyond the -5237 the current level; set to False for block of left-most statements -5238 (default=C{True}) -5239 -5240 A valid block must contain at least one C{blockStatement}. -5241 -5242 Example:: -5243 data = ''' -5244 def A(z): -5245 A1 -5246 B = 100 -5247 G = A2 -5248 A2 -5249 A3 -5250 B -5251 def BB(a,b,c): -5252 BB1 -5253 def BBA(): -5254 bba1 -5255 bba2 -5256 bba3 -5257 C -5258 D -5259 def spam(x,y): -5260 def eggs(z): -5261 pass -5262 ''' -5263 -5264 -5265 indentStack = [1] -5266 stmt = Forward() -5267 -5268 identifier = Word(alphas, alphanums) -5269 funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") -5270 func_body = indentedBlock(stmt, indentStack) -5271 funcDef = Group( funcDecl + func_body ) -5272 -5273 rvalue = Forward() -5274 funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") -5275 rvalue << (funcCall | identifier | Word(nums)) -5276 assignment = Group(identifier + "=" + rvalue) -5277 stmt << ( funcDef | assignment | identifier ) -5278 -5279 module_body = OneOrMore(stmt) -5280 -5281 parseTree = module_body.parseString(data) -5282 parseTree.pprint() -5283 prints:: -5284 [['def', -5285 'A', -5286 ['(', 'z', ')'], -5287 ':', -5288 [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], -5289 'B', -5290 ['def', -5291 'BB', -5292 ['(', 'a', 'b', 'c', ')'], -5293 ':', -5294 [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], -5295 'C', -5296 'D', -5297 ['def', -5298 'spam', -5299 ['(', 'x', 'y', ')'], -5300 ':', -5301 [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] -5302 """ -5303 def checkPeerIndent(s,l,t): -5304 if l >= len(s): return -5305 curCol = col(l,s) -5306 if curCol != indentStack[-1]: -5307 if curCol > indentStack[-1]: -5308 raise ParseFatalException(s,l,"illegal nesting") -5309 raise ParseException(s,l,"not a peer entry") -
5310 -5311 def checkSubIndent(s,l,t): -5312 curCol = col(l,s) -5313 if curCol > indentStack[-1]: -5314 indentStack.append( curCol ) -5315 else: -5316 raise ParseException(s,l,"not a subentry") -5317 -5318 def checkUnindent(s,l,t): -5319 if l >= len(s): return -5320 curCol = col(l,s) -5321 if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): -5322 raise ParseException(s,l,"not an unindent") -5323 indentStack.pop() -5324 -5325 NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) -5326 INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') -5327 PEER = Empty().setParseAction(checkPeerIndent).setName('') -5328 UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') -5329 if indent: -5330 smExpr = Group( Optional(NL) + -5331 #~ FollowedBy(blockStatementExpr) + -5332 INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) -5333 else: -5334 smExpr = Group( Optional(NL) + -5335 (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) -5336 blockStatementExpr.ignore(_bslash + LineEnd()) -5337 return smExpr.setName('indented block') -5338 -5339 alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") -5340 punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") -5341 -5342 anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) -5343 _htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) -5344 commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") -
5345 -def replaceHTMLEntity(t): -
5346 """Helper parser action to replace common HTML entities with their special characters""" -5347 return _htmlEntityMap.get(t.entity) -
5348 -5349 # it's easy to get these comment structures wrong - they're very common, so may as well make them available -5350 cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") -5351 "Comment of the form C{/* ... */}" -5352 -5353 htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") -5354 "Comment of the form C{<!-- ... -->}" -5355 -5356 restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") -5357 dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") -5358 "Comment of the form C{// ... (to end of line)}" -5359 -5360 cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") -5361 "Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" -5362 -5363 javaStyleComment = cppStyleComment -5364 "Same as C{L{cppStyleComment}}" -5365 -5366 pythonStyleComment = Regex(r"#.*").setName("Python style comment") -5367 "Comment of the form C{# ... (to end of line)}" -5368 -5369 _commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + -5370 Optional( Word(" \t") + -5371 ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") -5372 commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") -5373 """(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. -5374 This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" -
5375 -5376 # some other useful expressions - using lower-case class name since we are really using this as a namespace -5377 -class pyparsing_common: -
5378 """ -5379 Here are some common low-level expressions that may be useful in jump-starting parser development: -5380 - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) -5381 - common L{programming identifiers<identifier>} -5382 - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) -5383 - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} -5384 - L{UUID<uuid>} -5385 - L{comma-separated list<comma_separated_list>} -5386 Parse actions: -5387 - C{L{convertToInteger}} -5388 - C{L{convertToFloat}} -5389 - C{L{convertToDate}} -5390 - C{L{convertToDatetime}} -5391 - C{L{stripHTMLTags}} -5392 - C{L{upcaseTokens}} -5393 - C{L{downcaseTokens}} -5394 -5395 Example:: -5396 pyparsing_common.number.runTests(''' -5397 # any int or real number, returned as the appropriate type -5398 100 -5399 -100 -5400 +100 -5401 3.14159 -5402 6.02e23 -5403 1e-12 -5404 ''') -5405 -5406 pyparsing_common.fnumber.runTests(''' -5407 # any int or real number, returned as float -5408 100 -5409 -100 -5410 +100 -5411 3.14159 -5412 6.02e23 -5413 1e-12 -5414 ''') -5415 -5416 pyparsing_common.hex_integer.runTests(''' -5417 # hex numbers -5418 100 -5419 FF -5420 ''') -5421 -5422 pyparsing_common.fraction.runTests(''' -5423 # fractions -5424 1/2 -5425 -3/4 -5426 ''') -5427 -5428 pyparsing_common.mixed_integer.runTests(''' -5429 # mixed fractions -5430 1 -5431 1/2 -5432 -3/4 -5433 1-3/4 -5434 ''') -5435 -5436 import uuid -5437 pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) -5438 pyparsing_common.uuid.runTests(''' -5439 # uuid -5440 12345678-1234-5678-1234-567812345678 -5441 ''') -5442 prints:: -5443 # any int or real number, returned as the appropriate type -5444 100 -5445 [100] -5446 -5447 -100 -5448 [-100] -5449 -5450 +100 -5451 [100] -5452 -5453 3.14159 -5454 [3.14159] -5455 -5456 6.02e23 -5457 [6.02e+23] -5458 -5459 1e-12 -5460 [1e-12] -5461 -5462 # any int or real number, returned as float -5463 100 -5464 [100.0] -5465 -5466 -100 -5467 [-100.0] -5468 -5469 +100 -5470 [100.0] -5471 -5472 3.14159 -5473 [3.14159] -5474 -5475 6.02e23 -5476 [6.02e+23] -5477 -5478 1e-12 -5479 [1e-12] -5480 -5481 # hex numbers -5482 100 -5483 [256] -5484 -5485 FF -5486 [255] -5487 -5488 # fractions -5489 1/2 -5490 [0.5] -5491 -5492 -3/4 -5493 [-0.75] -5494 -5495 # mixed fractions -5496 1 -5497 [1] -5498 -5499 1/2 -5500 [0.5] -5501 -5502 -3/4 -5503 [-0.75] -5504 -5505 1-3/4 -5506 [1.75] -5507 -5508 # uuid -5509 12345678-1234-5678-1234-567812345678 -5510 [UUID('12345678-1234-5678-1234-567812345678')] -5511 """ -5512 -5513 convertToInteger = tokenMap(int) -5514 """ -5515 Parse action for converting parsed integers to Python int -5516 """ -5517 -5518 convertToFloat = tokenMap(float) -5519 """ -5520 Parse action for converting parsed numbers to Python float -5521 """ -5522 -5523 integer = Word(nums).setName("integer").setParseAction(convertToInteger) -5524 """expression that parses an unsigned integer, returns an int""" -5525 -5526 hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) -5527 """expression that parses a hexadecimal integer, returns an int""" -5528 -5529 signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) -5530 """expression that parses an integer with optional leading sign, returns an int""" -5531 -5532 fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") -5533 """fractional expression of an integer divided by an integer, returns a float""" -5534 fraction.addParseAction(lambda t: t[0]/t[-1]) -5535 -5536 mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") -5537 """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" -5538 mixed_integer.addParseAction(sum) -5539 -5540 real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) -5541 """expression that parses a floating point number and returns a float""" -5542 -5543 sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) -5544 """expression that parses a floating point number with optional scientific notation and returns a float""" -5545 -5546 # streamlining this expression makes the docs nicer-looking -5547 number = (sci_real | real | signed_integer).streamline() -5548 """any numeric expression, returns the corresponding Python type""" -5549 -5550 fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) -5551 """any int or real number, returned as float""" -5552 -5553 identifier = Word(alphas+'_', alphanums+'_').setName("identifier") -5554 """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" -5555 -5556 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") -5557 "IPv4 address (C{0.0.0.0 - 255.255.255.255})" -5558 -5559 _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") -5560 _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") -5561 _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") -5562 _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) -5563 _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") -5564 ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") -5565 "IPv6 address (long, short, or mixed form)" -5566 -5567 mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") -5568 "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" -5569 -5570 @staticmethod -
5571 - def convertToDate(fmt="%Y-%m-%d"): -
5572 """ -5573 Helper to create a parse action for converting parsed date string to Python datetime.date -5574 -5575 Params - -5576 - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) -5577 -5578 Example:: -5579 date_expr = pyparsing_common.iso8601_date.copy() -5580 date_expr.setParseAction(pyparsing_common.convertToDate()) -5581 print(date_expr.parseString("1999-12-31")) -5582 prints:: -5583 [datetime.date(1999, 12, 31)] -5584 """ -5585 def cvt_fn(s,l,t): -5586 try: -5587 return datetime.strptime(t[0], fmt).date() -5588 except ValueError as ve: -5589 raise ParseException(s, l, str(ve)) -
5590 return cvt_fn -
5591 -5592 @staticmethod -
5593 - def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): -
5594 """ -5595 Helper to create a parse action for converting parsed datetime string to Python datetime.datetime -5596 -5597 Params - -5598 - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) -5599 -5600 Example:: -5601 dt_expr = pyparsing_common.iso8601_datetime.copy() -5602 dt_expr.setParseAction(pyparsing_common.convertToDatetime()) -5603 print(dt_expr.parseString("1999-12-31T23:59:59.999")) -5604 prints:: -5605 [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] -5606 """ -5607 def cvt_fn(s,l,t): -5608 try: -5609 return datetime.strptime(t[0], fmt) -5610 except ValueError as ve: -5611 raise ParseException(s, l, str(ve)) -
5612 return cvt_fn -5613 -5614 iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") -5615 "ISO8601 date (C{yyyy-mm-dd})" -5616 -5617 iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") -5618 "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" -5619 -5620 uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") -5621 "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" -5622 -5623 _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() -5624 @staticmethod -
5625 - def stripHTMLTags(s, l, tokens): -
5626 """ -5627 Parse action to remove HTML tags from web page HTML source -5628 -5629 Example:: -5630 # strip HTML links from normal text -5631 text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' -5632 td,td_end = makeHTMLTags("TD") -5633 table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end -5634 -5635 print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' -5636 """ -5637 return pyparsing_common._html_stripper.transformString(tokens[0]) -
5638 -5639 _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') -5640 + Optional( White(" \t") ) ) ).streamline().setName("commaItem") -5641 comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") -5642 """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" -5643 -5644 upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) -5645 """Parse action to convert tokens to upper case.""" -5646 -5647 downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) -5648 """Parse action to convert tokens to lower case.""" -5649 -5650 -5651 if __name__ == "__main__": -5652 -5653 selectToken = CaselessLiteral("select") -5654 fromToken = CaselessLiteral("from") -5655 -5656 ident = Word(alphas, alphanums + "_$") -5657 -5658 columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) -5659 columnNameList = Group(delimitedList(columnName)).setName("columns") -5660 columnSpec = ('*' | columnNameList) -5661 -5662 tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) -5663 tableNameList = Group(delimitedList(tableName)).setName("tables") -5664 -5665 simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") -5666 -5667 # demo runTests method, including embedded comments in test string -5668 simpleSQL.runTests(""" -5669 # '*' as column list and dotted table name -5670 select * from SYS.XYZZY -5671 -5672 # caseless match on "SELECT", and casts back to "select" -5673 SELECT * from XYZZY, ABC -5674 -5675 # list of column names, and mixed case SELECT keyword -5676 Select AA,BB,CC from Sys.dual -5677 -5678 # multiple tables -5679 Select A, B, C from Sys.dual, Table2 -5680 -5681 # invalid SELECT keyword - should fail -5682 Xelect A, B, C from Sys.dual -5683 -5684 # incomplete command - should fail -5685 Select -5686 -5687 # invalid column name - should fail -5688 Select ^^^ frox Sys.dual -5689 -5690 """) -5691 -5692 pyparsing_common.number.runTests(""" -5693 100 -5694 -100 -5695 +100 -5696 3.14159 -5697 6.02e23 -5698 1e-12 -5699 """) -5700 -5701 # any int or real number, returned as float -5702 pyparsing_common.fnumber.runTests(""" -5703 100 -5704 -100 -5705 +100 -5706 3.14159 -5707 6.02e23 -5708 1e-12 -5709 """) -5710 -5711 pyparsing_common.hex_integer.runTests(""" -5712 100 -5713 FF -5714 """) -5715 -5716 import uuid -5717 pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) -5718 pyparsing_common.uuid.runTests(""" -5719 12345678-1234-5678-1234-567812345678 -5720 """) -5721 - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.And-class.html b/htmldoc/pyparsing.And-class.html deleted file mode 100644 index 5dcfccf..0000000 --- a/htmldoc/pyparsing.And-class.html +++ /dev/null @@ -1,476 +0,0 @@ - - - - - pyparsing.And - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class And - - - - - -
[frames] | no frames]
-
- -

Class And

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-  ParseExpression --+
-                    |
-                   And
-
- -
-

Requires all given ParseExpressions to be found in the - given order. Expressions may be separated by whitespace. May be - constructed using the '+' operator. May also be constructed - using the '-' operator, which will suppress - backtracking.

-

Example:

-
-   integer = Word(nums)
-   name_expr = OneOrMore(Word(alphas))
-
-   expr = And([integer("id"),name_expr("name"),integer("age")])
-   # more easily written as:
-   expr = integer("id") + name_expr("name") + integer("age")
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - exprs, - savelist=True)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__iadd__(self, - other) - source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParseExpression: - __getitem__, - append, - copy, - ignore, - leaveWhitespace, - setResultsName, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - exprs, - savelist=True) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

checkRecursion(self, - parseElementList) -

-
source code  -
- - -
-
Overrides: - ParserElement.checkRecursion -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.CaselessKeyword-class.html b/htmldoc/pyparsing.CaselessKeyword-class.html deleted file mode 100644 index 4be3f0e..0000000 --- a/htmldoc/pyparsing.CaselessKeyword-class.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - pyparsing.CaselessKeyword - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class CaselessKeyword - - - - - -
[frames] | no frames]
-
- -

Class CaselessKeyword

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-              Keyword --+
-                        |
-                       CaselessKeyword
-
- -
-

Caseless version of Keyword.

-

Example:

-
-   OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
-
-

(Contrast with example for CaselessLiteral.)

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - matchString, - identChars=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from Keyword: - copy -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from Keyword: - setDefaultKeywordChars -

-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from Keyword: - DEFAULT_KEYWORD_CHARS -

-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - matchString, - identChars=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.CaselessLiteral-class.html b/htmldoc/pyparsing.CaselessLiteral-class.html deleted file mode 100644 index d97d7f3..0000000 --- a/htmldoc/pyparsing.CaselessLiteral-class.html +++ /dev/null @@ -1,368 +0,0 @@ - - - - - pyparsing.CaselessLiteral - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class CaselessLiteral - - - - - -
[frames] | no frames]
-
- -

Class CaselessLiteral

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-              Literal --+
-                        |
-                       CaselessLiteral
-
- -
-

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 CaselessKeyword.)

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - matchString)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from Literal: - __slotnames__ -

-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - matchString) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.CharsNotIn-class.html b/htmldoc/pyparsing.CharsNotIn-class.html deleted file mode 100644 index 531f317..0000000 --- a/htmldoc/pyparsing.CharsNotIn-class.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - pyparsing.CharsNotIn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class CharsNotIn - - - - - -
[frames] | no frames]
-
- -

Class CharsNotIn

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   CharsNotIn
-
- -
-

Token for matching words composed of characters 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 min is 1 (a minimum value - < 1 is not valid); the default values for max and - 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']
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - notChars, - min=1, - max=0, - exact=0)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - notChars, - min=1, - max=0, - exact=0) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.CloseMatch-class.html b/htmldoc/pyparsing.CloseMatch-class.html deleted file mode 100644 index f21210f..0000000 --- a/htmldoc/pyparsing.CloseMatch-class.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - pyparsing.CloseMatch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class CloseMatch - - - - - -
[frames] | no frames]
-
- -

Class CloseMatch

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   CloseMatch
-
- -
-

A variation on Literal which matches "close" - matches, that is, strings with at most 'n' mismatching characters. - CloseMatch takes parameters:

-
    -
  • - match_string - string to be matched -
  • -
  • - maxMismatches - (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:

-
    -
  • - mismatches - a list of the positions within the - match_string where mismatches were found -
  • -
  • - original - the original match_string used to compare - against the input string -
  • -
-

If 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']})
-
- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - match_string, - maxMismatches=1)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - match_string, - maxMismatches=1) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Combine-class.html b/htmldoc/pyparsing.Combine-class.html deleted file mode 100644 index 42ac149..0000000 --- a/htmldoc/pyparsing.Combine-class.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - pyparsing.Combine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Combine - - - - - -
[frames] | no frames]
-
- -

Class Combine

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         TokenConverter --+
-                          |
-                         Combine
-
- -
-

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 '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...)
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr, - joinString='', - adjacent=True)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
postParse(self, - instring, - loc, - tokenlist) - source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - leaveWhitespace, - parseImpl, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr, - joinString='', - adjacent=True) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

ignore(self, - other) -

-
source code  -
- -

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']
-
-
-
Overrides: - ParserElement.ignore -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

postParse(self, - instring, - loc, - tokenlist) -

-
source code  -
- - -
-
Overrides: - ParserElement.postParse -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Dict-class.html b/htmldoc/pyparsing.Dict-class.html deleted file mode 100644 index fe3587a..0000000 --- a/htmldoc/pyparsing.Dict-class.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - pyparsing.Dict - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Dict - - - - - -
[frames] | no frames]
-
- -

Class Dict

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         TokenConverter --+
-                          |
-                         Dict
-
- -
-

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 ParseResults of accessing fields by results name.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
postParse(self, - instring, - loc, - tokenlist) - source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - parseImpl, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

postParse(self, - instring, - loc, - tokenlist) -

-
source code  -
- - -
-
Overrides: - ParserElement.postParse -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Each-class.html b/htmldoc/pyparsing.Each-class.html deleted file mode 100644 index e5c3dc0..0000000 --- a/htmldoc/pyparsing.Each-class.html +++ /dev/null @@ -1,492 +0,0 @@ - - - - - pyparsing.Each - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Each - - - - - -
[frames] | no frames]
-
- -

Class Each

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-  ParseExpression --+
-                    |
-                   Each
-
- -
-

Requires all given ParseExpressions to be found, but in - any order. Expressions may be separated by whitespace. May be constructed - using the '&' 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
-
- - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - exprs, - savelist=True)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-

Inherited from ParseExpression: - __getitem__, - append, - copy, - ignore, - leaveWhitespace, - setResultsName, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - exprs, - savelist=True) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

checkRecursion(self, - parseElementList) -

-
source code  -
- - -
-
Overrides: - ParserElement.checkRecursion -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Empty-class.html b/htmldoc/pyparsing.Empty-class.html deleted file mode 100644 index ebb1937..0000000 --- a/htmldoc/pyparsing.Empty-class.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - pyparsing.Empty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Empty - - - - - -
[frames] | no frames]
-
- -

Class Empty

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   Empty
-
- -
Known Subclasses:
-
-
    -
  • And._ErrorStop
-
- -
-

An empty token, will always match.

- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseImpl, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.FollowedBy-class.html b/htmldoc/pyparsing.FollowedBy-class.html deleted file mode 100644 index 776bf5e..0000000 --- a/htmldoc/pyparsing.FollowedBy-class.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - pyparsing.FollowedBy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class FollowedBy - - - - - -
[frames] | no frames]
-
- -

Class FollowedBy

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     FollowedBy
-
- -
-

Lookahead matching of the given parse expression. - FollowedBy does not advance the parsing position - within the input string, it only verifies that the specified parse - expression matches at the current position. 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']]
-
- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Forward-class.html b/htmldoc/pyparsing.Forward-class.html deleted file mode 100644 index 6f3109d..0000000 --- a/htmldoc/pyparsing.Forward-class.html +++ /dev/null @@ -1,598 +0,0 @@ - - - - - pyparsing.Forward - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Forward - - - - - -
[frames] | no frames]
-
- -

Class Forward

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     Forward
-
- -
Known Subclasses:
-
-
    -
  • _ForwardNoRecurse
-
- -
-

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 Forward variable using the - '<<' operator.

-

Note: take care when assigning to 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 - Forward:

-
-   fwdExpr << (a | b | c)
-
-

Converting to use the '<<=' operator instead will avoid this - problem.

-

See ParseResults.pprint for an example of a recursive parser - created using Forward.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - other=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__lshift__(self, - other) - source code - -
- -
-   - - - - - - -
__ilshift__(self, - other) - source code - -
- -
-   - - - - - - -
leaveWhitespace(self)
- Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern.
- source code - -
- -
-   - - - - - - -
streamline(self) - source code - -
- -
-   - - - - - - -
validate(self, - validateTrace=[])
- Check defined expressions for valid structure, check for infinite - recursive definitions.
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
copy(self)
- Make a copy of this ParserElement.
- source code - -
- -
-

Inherited from ParseElementEnhance: - checkRecursion, - ignore, - parseImpl -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - other=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

leaveWhitespace(self) -

-
source code  -
- -

Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern. This is normally only - used internally by the pyparsing module, but may be needed in some - whitespace-sensitive grammars.

-
-
Overrides: - ParserElement.leaveWhitespace -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

streamline(self) -

-
source code  -
- - -
-
Overrides: - ParserElement.streamline -
-
-
-
- -
- -
- - -
-

validate(self, - validateTrace=[]) -

-
source code  -
- -

Check defined expressions for valid structure, check for infinite - recursive definitions.

-
-
Overrides: - ParserElement.validate -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

copy(self) -

-
source code  -
- -

Make a copy of this 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 expr.copy() is just - expr():

-
-   integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
-
-
-
Overrides: - ParserElement.copy -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.GoToColumn-class.html b/htmldoc/pyparsing.GoToColumn-class.html deleted file mode 100644 index ccbecd8..0000000 --- a/htmldoc/pyparsing.GoToColumn-class.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - pyparsing.GoToColumn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class GoToColumn - - - - - -
[frames] | no frames]
-
- -

Class GoToColumn

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       GoToColumn
-
- -
-

Token to advance to a specific column of input text; useful for - tabular report scraping.

- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - colno)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
preParse(self, - instring, - loc) - source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - colno) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

preParse(self, - instring, - loc) -

-
source code  -
- - -
-
Overrides: - ParserElement.preParse -
-
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Group-class.html b/htmldoc/pyparsing.Group-class.html deleted file mode 100644 index 9e949be..0000000 --- a/htmldoc/pyparsing.Group-class.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - pyparsing.Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Group - - - - - -
[frames] | no frames]
-
- -

Class Group

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         TokenConverter --+
-                          |
-                         Group
-
- -
-

Converter to return the matched tokens as a list - useful for - returning tokens of ZeroOrMore and 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']]
-
- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
postParse(self, - instring, - loc, - tokenlist) - source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - parseImpl, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

postParse(self, - instring, - loc, - tokenlist) -

-
source code  -
- - -
-
Overrides: - ParserElement.postParse -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Keyword-class.html b/htmldoc/pyparsing.Keyword-class.html deleted file mode 100644 index a135b2a..0000000 --- a/htmldoc/pyparsing.Keyword-class.html +++ /dev/null @@ -1,509 +0,0 @@ - - - - - pyparsing.Keyword - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Keyword - - - - - -
[frames] | no frames]
-
- -

Class Keyword

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   Keyword
-
- -
Known Subclasses:
-
- -
- -
-

Token to exactly match a specified string as a keyword, that is, it - must be immediately followed by a non-keyword character. Compare with - Literal:

-
    -
  • - Literal("if") will match the leading - 'if' in 'ifAndOnlyIf'. -
  • -
  • - Keyword("if") will not; it will only match the - leading 'if' in 'if x=1', or - 'if(y==2)' -
  • -
-

Accepts two optional constructor arguments in addition to the keyword - string:

-
    -
  • - identChars is a string of characters that would be valid - identifier characters, defaulting to all alphanumerics + - "_" and "$" -
  • -
  • - caseless allows case-insensitive matching, default is - False. -
  • -
-

Example:

-
-   Keyword("start").parseString("start")  # -> ['start']
-   Keyword("start").parseString("starting")  # -> Exception
-
-

For case-insensitive matching, use CaselessKeyword.

- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - matchString, - identChars=None, - caseless=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
copy(self)
- Make a copy of this ParserElement.
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - - - - -
- Static Methods
-   - - - - - - -
setDefaultKeywordChars(chars)
- Overrides the default Keyword chars
- source code - -
- -
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - DEFAULT_KEYWORD_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijk... -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - matchString, - identChars=None, - caseless=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

copy(self) -

-
source code  -
- -

Make a copy of this 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 expr.copy() is just - expr():

-
-   integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
-
-
-
Overrides: - ParserElement.copy -
(inherited documentation)
- -
-
-
-
- - - - - - -
- Class Variable Details
- -
- -
-

DEFAULT_KEYWORD_CHARS

- -
-
-
-
Value:
-
-'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$'
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.LineEnd-class.html b/htmldoc/pyparsing.LineEnd-class.html deleted file mode 100644 index e61591c..0000000 --- a/htmldoc/pyparsing.LineEnd-class.html +++ /dev/null @@ -1,362 +0,0 @@ - - - - - pyparsing.LineEnd - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class LineEnd - - - - - -
[frames] | no frames]
-
- -

Class LineEnd

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       LineEnd
-
- -
-

Matches if current position is at the end of a line within the parse - string

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.LineStart-class.html b/htmldoc/pyparsing.LineStart-class.html deleted file mode 100644 index d960615..0000000 --- a/htmldoc/pyparsing.LineStart-class.html +++ /dev/null @@ -1,371 +0,0 @@ - - - - - pyparsing.LineStart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class LineStart - - - - - -
[frames] | no frames]
-
- -

Class LineStart

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       LineStart
-
- -
-

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']    
-
- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Literal-class.html b/htmldoc/pyparsing.Literal-class.html deleted file mode 100644 index 612991b..0000000 --- a/htmldoc/pyparsing.Literal-class.html +++ /dev/null @@ -1,381 +0,0 @@ - - - - - pyparsing.Literal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Literal - - - - - -
[frames] | no frames]
-
- -

Class Literal

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   Literal
-
- -
Known Subclasses:
-
- -
- -
-

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 CaselessLiteral.

-

For keyword matching (force word break before and after the matched - string), use Keyword or CaselessKeyword.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - matchString)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - matchString) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.MatchFirst-class.html b/htmldoc/pyparsing.MatchFirst-class.html deleted file mode 100644 index 2eca9d3..0000000 --- a/htmldoc/pyparsing.MatchFirst-class.html +++ /dev/null @@ -1,477 +0,0 @@ - - - - - pyparsing.MatchFirst - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class MatchFirst - - - - - -
[frames] | no frames]
-
- -

Class MatchFirst

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-  ParseExpression --+
-                    |
-                   MatchFirst
-
- -
-

Requires that at least one ParseExpression is found. If - two expressions match, the first one listed is the one that will match. - May be constructed using the '|' 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']]
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - exprs, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__ior__(self, - other) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-

Inherited from ParseExpression: - __getitem__, - append, - copy, - ignore, - leaveWhitespace, - setResultsName, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - exprs, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

checkRecursion(self, - parseElementList) -

-
source code  -
- - -
-
Overrides: - ParserElement.checkRecursion -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.NoMatch-class.html b/htmldoc/pyparsing.NoMatch-class.html deleted file mode 100644 index 43ade05..0000000 --- a/htmldoc/pyparsing.NoMatch-class.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - pyparsing.NoMatch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class NoMatch - - - - - -
[frames] | no frames]
-
- -

Class NoMatch

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   NoMatch
-
- -
-

A token that will never match.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.NotAny-class.html b/htmldoc/pyparsing.NotAny-class.html deleted file mode 100644 index 1fb60ee..0000000 --- a/htmldoc/pyparsing.NotAny-class.html +++ /dev/null @@ -1,413 +0,0 @@ - - - - - pyparsing.NotAny - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class NotAny - - - - - -
[frames] | no frames]
-
- -

Class NotAny

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     NotAny
-
- -
-

Lookahead to disallow matching with the given parse expression. - NotAny does not advance the parsing position within - the input string, it only verifies that the specified parse expression - does not match at the current position. Also, NotAny - does not skip over leading whitespace. NotAny always - returns a null token list. May be constructed using the '~' - operator.

-

Example:

-
-   
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParseElementEnhance: - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.OneOrMore-class.html b/htmldoc/pyparsing.OneOrMore-class.html deleted file mode 100644 index c7cb682..0000000 --- a/htmldoc/pyparsing.OneOrMore-class.html +++ /dev/null @@ -1,349 +0,0 @@ - - - - - pyparsing.OneOrMore - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class OneOrMore - - - - - -
[frames] | no frames]
-
- -

Class OneOrMore

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         _MultipleMatch --+
-                          |
-                         OneOrMore
-
- -
-

Repetition of one or more of the given expression.

-

Parameters:

-
    -
  • - expr - expression that must match one or more times -
  • -
  • - stopOn - (default=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()
-
- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from _MultipleMatch: - __init__, - parseImpl -

-

Inherited from ParseElementEnhance: - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.OnlyOnce-class.html b/htmldoc/pyparsing.OnlyOnce-class.html deleted file mode 100644 index 2c398e9..0000000 --- a/htmldoc/pyparsing.OnlyOnce-class.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - pyparsing.OnlyOnce - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class OnlyOnce - - - - - -
[frames] | no frames]
-
- -

Class OnlyOnce

source code

-
-object --+
-         |
-        OnlyOnce
-
- -
-

Wrapper for parse actions, to ensure they are only called once.

- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - methodCall)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__call__(self, - s, - l, - t) - source code - -
- -
-   - - - - - - -
reset(self) - source code - -
- -
-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __hash__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __sizeof__, - __str__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - methodCall) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Optional-class.html b/htmldoc/pyparsing.Optional-class.html deleted file mode 100644 index 727d309..0000000 --- a/htmldoc/pyparsing.Optional-class.html +++ /dev/null @@ -1,445 +0,0 @@ - - - - - pyparsing.Optional - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Optional - - - - - -
[frames] | no frames]
-
- -

Class Optional

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     Optional
-
- -
-

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)
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr, - default=_NullToken())
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParseElementEnhance: - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr, - default=_NullToken()) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Or-class.html b/htmldoc/pyparsing.Or-class.html deleted file mode 100644 index f39c31f..0000000 --- a/htmldoc/pyparsing.Or-class.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - - pyparsing.Or - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Or - - - - - -
[frames] | no frames]
-
- -

Class Or

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-  ParseExpression --+
-                    |
-                   Or
-
- -
-

Requires that at least one ParseExpression is found. If - two expressions match, the expression that matches the longest string - will be used. May be constructed using the '^' operator.

-

Example:

-
-   # construct Or using '^' operator
-   
-   number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
-   print(number.searchString("123 3.1416 789"))
-
-

prints:

-
-   [['123'], ['3.1416'], ['789']]
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - exprs, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__ixor__(self, - other) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-

Inherited from ParseExpression: - __getitem__, - append, - copy, - ignore, - leaveWhitespace, - setResultsName, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - exprs, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

checkRecursion(self, - parseElementList) -

-
source code  -
- - -
-
Overrides: - ParserElement.checkRecursion -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseBaseException-class.html b/htmldoc/pyparsing.ParseBaseException-class.html deleted file mode 100644 index fa8373f..0000000 --- a/htmldoc/pyparsing.ParseBaseException-class.html +++ /dev/null @@ -1,410 +0,0 @@ - - - - - pyparsing.ParseBaseException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseBaseException - - - - - -
[frames] | no frames]
-
- -

Class ParseBaseException

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              ParseBaseException
-
- -
Known Subclasses:
-
- -
- -
-

base exception class for all parsing runtime exceptions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - pstr, - loc=0, - msg=None, - elem=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__getattr__(self, - aname)
- supported attributes by name are:
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
markInputline(self, - markerString='>!<')
- Extracts the exception line from the input string, and marks the - location of the exception with a special symbol.
- source code - -
- -
-   - - - - - - -
__dir__(self) - source code - -
- -
-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__, - __unicode__ -

-

Inherited from object: - __format__, - __hash__, - __reduce_ex__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - pstr, - loc=0, - msg=None, - elem=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__getattr__(self, - aname) -
(Qualification operator) -

-
source code  -
- -

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 -
  • -
-
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseElementEnhance-class.html b/htmldoc/pyparsing.ParseElementEnhance-class.html deleted file mode 100644 index 5e7bec6..0000000 --- a/htmldoc/pyparsing.ParseElementEnhance-class.html +++ /dev/null @@ -1,616 +0,0 @@ - - - - - pyparsing.ParseElementEnhance - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseElementEnhance - - - - - -
[frames] | no frames]
-
- -

Class ParseElementEnhance

source code

-
-   object --+    
-            |    
-ParserElement --+
-                |
-               ParseElementEnhance
-
- -
Known Subclasses:
-
- -
- -
-

Abstract subclass of ParserElement, for combining and - post-processing parsed tokens.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
leaveWhitespace(self)
- Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
streamline(self) - source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-   - - - - - - -
validate(self, - validateTrace=[])
- Check defined expressions for valid structure, check for infinite - recursive definitions.
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

leaveWhitespace(self) -

-
source code  -
- -

Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern. This is normally only - used internally by the pyparsing module, but may be needed in some - whitespace-sensitive grammars.

-
-
Overrides: - ParserElement.leaveWhitespace -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

ignore(self, - other) -

-
source code  -
- -

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']
-
-
-
Overrides: - ParserElement.ignore -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

streamline(self) -

-
source code  -
- - -
-
Overrides: - ParserElement.streamline -
-
-
-
- -
- -
- - -
-

checkRecursion(self, - parseElementList) -

-
source code  -
- - -
-
Overrides: - ParserElement.checkRecursion -
-
-
-
- -
- -
- - -
-

validate(self, - validateTrace=[]) -

-
source code  -
- -

Check defined expressions for valid structure, check for infinite - recursive definitions.

-
-
Overrides: - ParserElement.validate -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseException-class.html b/htmldoc/pyparsing.ParseException-class.html deleted file mode 100644 index a2bdb94..0000000 --- a/htmldoc/pyparsing.ParseException-class.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - pyparsing.ParseException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseException - - - - - -
[frames] | no frames]
-
- -

Class ParseException

source code

-
-              object --+            
-                       |            
-exceptions.BaseException --+        
-                           |        
-        exceptions.Exception --+    
-                               |    
-              ParseBaseException --+
-                                   |
-                                  ParseException
-
- -
-

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
-
- - - - - - - - - - -
- Instance Methods
-

Inherited from ParseBaseException: - __dir__, - __getattr__, - __init__, - __repr__, - __str__, - markInputline -

-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__, - __unicode__ -

-

Inherited from object: - __format__, - __hash__, - __reduce_ex__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseExpression-class.html b/htmldoc/pyparsing.ParseExpression-class.html deleted file mode 100644 index 3bf8344..0000000 --- a/htmldoc/pyparsing.ParseExpression-class.html +++ /dev/null @@ -1,685 +0,0 @@ - - - - - pyparsing.ParseExpression - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseExpression - - - - - -
[frames] | no frames]
-
- -

Class ParseExpression

source code

-
-   object --+    
-            |    
-ParserElement --+
-                |
-               ParseExpression
-
- -
Known Subclasses:
-
- -
- -
-

Abstract subclass of ParserElement, for combining and post-processing - parsed tokens.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - exprs, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__getitem__(self, - i) - source code - -
- -
-   - - - - - - -
append(self, - other) - source code - -
- -
-   - - - - - - -
leaveWhitespace(self)
- Extends leaveWhitespace defined in base class, and also - invokes leaveWhitespace on all contained expressions.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
streamline(self) - source code - -
- -
-   - - - - - - -
setResultsName(self, - name, - listAllMatches=False)
- Define name for referencing matching tokens as a nested attribute of - the returned parse results.
- source code - -
- -
-   - - - - - - -
validate(self, - validateTrace=[])
- Check defined expressions for valid structure, check for infinite - recursive definitions.
- source code - -
- -
-   - - - - - - -
copy(self)
- Make a copy of this ParserElement.
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - matches, - parseFile, - parseImpl, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - exprs, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

leaveWhitespace(self) -

-
source code  -
- -

Extends leaveWhitespace defined in base class, and also - invokes leaveWhitespace on all contained expressions.

-
-
Overrides: - ParserElement.leaveWhitespace -
-
-
-
- -
- -
- - -
-

ignore(self, - other) -

-
source code  -
- -

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']
-
-
-
Overrides: - ParserElement.ignore -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

streamline(self) -

-
source code  -
- - -
-
Overrides: - ParserElement.streamline -
-
-
-
- -
- -
- - -
-

setResultsName(self, - name, - listAllMatches=False) -

-
source code  -
- -

Define name for referencing matching tokens as a nested attribute of - the returned parse results. NOTE: this returns a *copy* of the original - 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, - expr("name") in place of - expr.setResultsName("name") - see __call__.

-

Example:

-
-   date_str = (integer.setResultsName("year") + '/' 
-               + integer.setResultsName("month") + '/' 
-               + integer.setResultsName("day"))
-
-   # equivalent form:
-   date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
-
-
Overrides: - ParserElement.setResultsName -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

validate(self, - validateTrace=[]) -

-
source code  -
- -

Check defined expressions for valid structure, check for infinite - recursive definitions.

-
-
Overrides: - ParserElement.validate -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

copy(self) -

-
source code  -
- -

Make a copy of this 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 expr.copy() is just - expr():

-
-   integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
-
-
-
Overrides: - ParserElement.copy -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseFatalException-class.html b/htmldoc/pyparsing.ParseFatalException-class.html deleted file mode 100644 index 5755ed3..0000000 --- a/htmldoc/pyparsing.ParseFatalException-class.html +++ /dev/null @@ -1,195 +0,0 @@ - - - - - pyparsing.ParseFatalException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseFatalException - - - - - -
[frames] | no frames]
-
- -

Class ParseFatalException

source code

-
-              object --+            
-                       |            
-exceptions.BaseException --+        
-                           |        
-        exceptions.Exception --+    
-                               |    
-              ParseBaseException --+
-                                   |
-                                  ParseFatalException
-
- -
Known Subclasses:
-
- -
- -
-

user-throwable exception thrown when inconsistent parse content is - found; stops all parsing immediately

- - - - - - - - - - -
- Instance Methods
-

Inherited from ParseBaseException: - __dir__, - __getattr__, - __init__, - __repr__, - __str__, - markInputline -

-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__, - __unicode__ -

-

Inherited from object: - __format__, - __hash__, - __reduce_ex__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseResults-class.html b/htmldoc/pyparsing.ParseResults-class.html deleted file mode 100644 index a6fdab7..0000000 --- a/htmldoc/pyparsing.ParseResults-class.html +++ /dev/null @@ -1,1455 +0,0 @@ - - - - - pyparsing.ParseResults - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseResults - - - - - -
[frames] | no frames]
-
- -

Class ParseResults

source code

-
-object --+
-         |
-        ParseResults
-
- -
-

Structured parse results, to provide multiple means of access to the - parsed data:

-
    -
  • - as a list (len(results)) -
  • -
  • - by list index (results[0], results[1], etc.) -
  • -
  • - by attribute (results.<resultsName> - see 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
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - toklist=None, - name=None, - asList=True, - modal=True, - isinstance=<built-in function isinstance>)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__getitem__(self, - i) - source code - -
- -
-   - - - - - - -
__setitem__(self, - k, - v, - isinstance=<built-in function isinstance>) - source code - -
- -
-   - - - - - - -
__delitem__(self, - i) - source code - -
- -
-   - - - - - - -
__contains__(self, - k) - source code - -
- -
-   - - - - - - -
__len__(self) - source code - -
- -
-   - - - - - - -
__bool__(self) - source code - -
- -
-   - - - - - - -
__nonzero__(self) - source code - -
- -
-   - - - - - - -
__iter__(self) - source code - -
- -
-   - - - - - - -
__reversed__(self) - source code - -
- -
-   - - - - - - -
iterkeys(self)
- Returns an iterator of all named result keys (Python 2.x only).
- source code - -
- -
-   - - - - - - -
itervalues(self)
- Returns an iterator of all named result values (Python 2.x only).
- source code - -
- -
-   - - - - - - -
iteritems(self)
- Returns an iterator of all named result key-value tuples (Python 2.x - only).
- source code - -
- -
-   - - - - - - -
keys(self)
- Returns all named result keys (as a list in Python 2.x, as an - iterator in Python 3.x).
- source code - -
- -
-   - - - - - - -
values(self)
- Returns all named result values (as a list in Python 2.x, as an - iterator in Python 3.x).
- source code - -
- -
-   - - - - - - -
items(self)
- Returns all named result key-values (as a list of tuples in Python - 2.x, as an iterator in Python 3.x).
- source code - -
- -
-   - - - - - - -
haskeys(self)
- Since keys() returns an iterator, this method is helpful in bypassing - code that looks for the existence of any defined results names.
- source code - -
- -
-   - - - - - - -
pop(self, - *args, - **kwargs)
- Removes and returns item at specified index - (default=last).
- source code - -
- -
-   - - - - - - -
get(self, - key, - defaultValue=None)
- Returns named result matching the given key, or if there is no such - name, then returns the given defaultValue or - None if no defaultValue is specified.
- source code - -
- -
-   - - - - - - -
insert(self, - index, - insStr)
- Inserts new element at location index in the list of parsed tokens.
- source code - -
- -
-   - - - - - - -
append(self, - item)
- Add single element to end of ParseResults list of elements.
- source code - -
- -
-   - - - - - - -
extend(self, - itemseq)
- Add sequence of elements to end of ParseResults list of elements.
- source code - -
- -
-   - - - - - - -
clear(self)
- Clear all elements and results names.
- source code - -
- -
-   - - - - - - -
__getattr__(self, - name) - source code - -
- -
-   - - - - - - -
__add__(self, - other) - source code - -
- -
-   - - - - - - -
__iadd__(self, - other) - source code - -
- -
-   - - - - - - -
__radd__(self, - other) - source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
asList(self)
- Returns the parse results as a nested list of matching tokens, all - converted to strings.
- source code - -
- -
-   - - - - - - -
asDict(self)
- Returns the named parse results as a nested dictionary.
- source code - -
- -
-   - - - - - - -
copy(self)
- Returns a new copy of a ParseResults object.
- source code - -
- -
-   - - - - - - -
asXML(self, - doctag=None, - namedItemsOnly=False, - indent='', - formatted=True)
- (Deprecated) Returns the parse results as XML.
- source code - -
- -
-   - - - - - - -
getName(self)
- Returns the results name for this token expression.
- source code - -
- -
-   - - - - - - -
dump(self, - indent='', - depth=0, - full=True)
- Diagnostic method for listing out the contents of a - ParseResults.
- source code - -
- -
-   - - - - - - -
pprint(self, - *args, - **kwargs)
- Pretty-printer for parsed results as a list, using the - pprint module.
- source code - -
- -
-   - - - - - - -
__getstate__(self) - source code - -
- -
-   - - - - - - -
__setstate__(self, - state) - source code - -
- -
-   - - - - - - -
__getnewargs__(self) - source code - -
- -
-   - - - - - - -
__dir__(self) - source code - -
- -
-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __hash__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
- a new object with type S, a subtype of T - - - - - - -
__new__(cls, - toklist=None, - name=None, - asList=True, - modal=True) - source code - -
- -
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__new__(cls, - toklist=None, - name=None, - asList=True, - modal=True) -
Static Method -

-
source code  -
- - -
-
Returns: a new object with type S, a subtype of T
-
Overrides: - object.__new__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__init__(self, - toklist=None, - name=None, - asList=True, - modal=True, - isinstance=<built-in function isinstance>) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

pop(self, - *args, - **kwargs) -

-
source code  -
- -

Removes and returns item at specified index - (default=last). Supports both list and - dict semantics for pop(). If passed no argument - or an integer argument, it will use list semantics and pop - tokens from the list of parsed tokens. If passed a non-integer argument - (most likely a string), it will use dict semantics and pop - the corresponding value from any defined results names. A second default - return value argument is supported, just as in - 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']
-
-
-
-
-
- -
- -
- - -
-

get(self, - key, - defaultValue=None) -

-
source code  -
- -

Returns named result matching the given key, or if there is no such - name, then returns the given defaultValue or - None if no defaultValue is specified.

-

Similar to 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
-
-
-
-
-
- -
- -
- - -
-

insert(self, - index, - insStr) -

-
source code  -
- -

Inserts new element at location index in the list of parsed - tokens.

-

Similar to 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']
-
-
-
-
-
- -
- -
- - -
-

append(self, - item) -

-
source code  -
- -

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]
-
-
-
-
-
- -
- -
- - -
-

extend(self, - itemseq) -

-
source code  -
- -

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'
-
-
-
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

asList(self) -

-
source code  -
- -

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) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
-   
-   # Use asList() to create an actual list
-   result_list = result.asList()
-   print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
-
-
-
-
-
- -
- -
- - -
-

asDict(self) -

-
source code  -
- -

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)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
-   
-   result_dict = result.asDict()
-   print(type(result_dict), repr(result_dict)) # -> <class '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"}
-
-
-
-
-
- -
- -
- - -
-

asXML(self, - doctag=None, - namedItemsOnly=False, - indent='', - formatted=True) -

-
source code  -
- -

(Deprecated) Returns the parse results as XML. Tags are created for - tokens and lists that have defined results names.

-
-
-
-
- -
- -
- - -
-

getName(self) -

-
source code  -
- -

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
-
-
-
-
-
- -
- -
- - -
-

dump(self, - indent='', - depth=0, - full=True) -

-
source code  -
- -

Diagnostic method for listing out the contents of a - ParseResults. Accepts an optional 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
-
-
-
-
-
- -
- -
- - -
-

pprint(self, - *args, - **kwargs) -

-
source code  -
- -

Pretty-printer for parsed results as a list, using the - pprint module. Accepts additional positional or keyword args - as defined for the pprint.pprint method. (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']]
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParseSyntaxException-class.html b/htmldoc/pyparsing.ParseSyntaxException-class.html deleted file mode 100644 index 5ddc0ec..0000000 --- a/htmldoc/pyparsing.ParseSyntaxException-class.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - pyparsing.ParseSyntaxException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParseSyntaxException - - - - - -
[frames] | no frames]
-
- -

Class ParseSyntaxException

source code

-
-              object --+                
-                       |                
-exceptions.BaseException --+            
-                           |            
-        exceptions.Exception --+        
-                               |        
-              ParseBaseException --+    
-                                   |    
-                 ParseFatalException --+
-                                       |
-                                      ParseSyntaxException
-
- -
-

just like ParseFatalException, but thrown internally when an - ErrorStop ('-' operator) indicates that parsing is to stop immediately - because an unbacktrackable syntax error has been found

- - - - - - - - - - -
- Instance Methods
-

Inherited from ParseBaseException: - __dir__, - __getattr__, - __init__, - __repr__, - __str__, - markInputline -

-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __setattr__, - __setstate__, - __unicode__ -

-

Inherited from object: - __format__, - __hash__, - __reduce_ex__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ParserElement-class.html b/htmldoc/pyparsing.ParserElement-class.html deleted file mode 100644 index ea7eda6..0000000 --- a/htmldoc/pyparsing.ParserElement-class.html +++ /dev/null @@ -1,2482 +0,0 @@ - - - - - pyparsing.ParserElement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ParserElement - - - - - -
[frames] | no frames]
-
- -

Class ParserElement

source code

-
-object --+
-         |
-        ParserElement
-
- -
Known Subclasses:
-
- -
- -
-

Abstract base level parser element class.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
copy(self)
- Make a copy of this ParserElement.
- source code - -
- -
-   - - - - - - -
setName(self, - name)
- Define name for this expression, makes debugging and exception - messages clearer.
- source code - -
- -
-   - - - - - - -
setResultsName(self, - name, - listAllMatches=False)
- Define name for referencing matching tokens as a nested attribute of - the returned parse results.
- source code - -
- -
-   - - - - - - -
setBreak(self, - breakFlag=True)
- Method to invoke the Python pdb debugger when this element is about - to be parsed.
- source code - -
- -
-   - - - - - - -
setParseAction(self, - *fns, - **kwargs)
- Define one or more actions to perform when successfully matching - parse element definition.
- source code - -
- -
-   - - - - - - -
addParseAction(self, - *fns, - **kwargs)
- Add one or more parse actions to expression's list of parse actions.
- source code - -
- -
-   - - - - - - -
addCondition(self, - *fns, - **kwargs)
- Add a boolean predicate function to expression's list of parse - actions.
- source code - -
- -
-   - - - - - - -
setFailAction(self, - fn)
- Define action to perform if parsing fails at this expression.
- source code - -
- -
-   - - - - - - -
preParse(self, - instring, - loc) - source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
postParse(self, - instring, - loc, - tokenlist) - source code - -
- -
-   - - - - - - -
tryParse(self, - instring, - loc) - source code - -
- -
-   - - - - - - -
canParseNext(self, - instring, - loc) - source code - -
- -
-   - - - - - - -
parseString(self, - instring, - parseAll=False)
- Execute the parse expression with the given string.
- source code - -
- -
-   - - - - - - -
scanString(self, - instring, - maxMatches=2147483647, - overlap=False)
- Scan the input string for expression matches.
- source code - -
- -
-   - - - - - - -
transformString(self, - instring)
- Extension to scanString, to modify matching text with - modified tokens that may be returned from a parse action.
- source code - -
- -
-   - - - - - - -
searchString(self, - instring, - maxMatches=2147483647)
- Another extension to scanString, simplifying the access to the - tokens found to match the given parse expression.
- source code - -
- -
-   - - - - - - -
split(self, - instring, - maxsplit=2147483647, - includeSeparators=False)
- Generator method to split a string using the given expression as a - separator.
- source code - -
- -
-   - - - - - - -
__add__(self, - other)
- Implementation of + operator - returns And.
- source code - -
- -
-   - - - - - - -
__radd__(self, - other)
- Implementation of + operator when left operand is not a ParserElement
- source code - -
- -
-   - - - - - - -
__sub__(self, - other)
- Implementation of - operator, returns And with - error stop
- source code - -
- -
-   - - - - - - -
__rsub__(self, - other)
- Implementation of - operator when left operand is not a ParserElement
- source code - -
- -
-   - - - - - - -
__mul__(self, - other)
- Implementation of * operator, allows use of expr * 3 in - place of expr + expr + expr.
- source code - -
- -
-   - - - - - - -
__rmul__(self, - other) - source code - -
- -
-   - - - - - - -
__or__(self, - other)
- Implementation of | operator - returns MatchFirst
- source code - -
- -
-   - - - - - - -
__ror__(self, - other)
- Implementation of | operator when left operand is not a ParserElement
- source code - -
- -
-   - - - - - - -
__xor__(self, - other)
- Implementation of ^ operator - returns Or
- source code - -
- -
-   - - - - - - -
__rxor__(self, - other)
- Implementation of ^ operator when left operand is not a ParserElement
- source code - -
- -
-   - - - - - - -
__and__(self, - other)
- Implementation of & operator - returns Each
- source code - -
- -
-   - - - - - - -
__rand__(self, - other)
- Implementation of & operator when left operand is not a ParserElement
- source code - -
- -
-   - - - - - - -
__invert__(self)
- Implementation of ~ operator - returns NotAny
- source code - -
- -
-   - - - - - - -
__call__(self, - name=None)
- Shortcut for setResultsName, with - listAllMatches=False.
- source code - -
- -
-   - - - - - - -
suppress(self)
- Suppresses the output of this ParserElement; useful to - keep punctuation from cluttering up returned output.
- source code - -
- -
-   - - - - - - -
leaveWhitespace(self)
- Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern.
- source code - -
- -
-   - - - - - - -
setWhitespaceChars(self, - chars)
- Overrides the default whitespace chars
- source code - -
- -
-   - - - - - - -
parseWithTabs(self)
- Overrides default behavior to expand <TAB>s to - spaces before parsing the input string.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-   - - - - - - -
setDebugActions(self, - startAction, - successAction, - exceptionAction)
- Enable display of debugging messages while doing pattern matching.
- source code - -
- -
-   - - - - - - -
setDebug(self, - flag=True)
- Enable display of debugging messages while doing pattern matching.
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-   - - - - - - -
__repr__(self)
- repr(x)
- source code - -
- -
-   - - - - - - -
streamline(self) - source code - -
- -
-   - - - - - - -
checkRecursion(self, - parseElementList) - source code - -
- -
-   - - - - - - -
validate(self, - validateTrace=[])
- Check defined expressions for valid structure, check for infinite - recursive definitions.
- source code - -
- -
-   - - - - - - -
parseFile(self, - file_or_filename, - parseAll=False)
- Execute the parse expression on the given file or filename.
- source code - -
- -
-   - - - - - - -
__eq__(self, - other) - source code - -
- -
-   - - - - - - -
__ne__(self, - other) - source code - -
- -
-   - - - - - - -
__hash__(self)
- hash(x)
- source code - -
- -
-   - - - - - - -
__req__(self, - other) - source code - -
- -
-   - - - - - - -
__rne__(self, - other) - source code - -
- -
-   - - - - - - -
matches(self, - testString, - parseAll=True)
- Method for quick testing of a parser against a test string.
- source code - -
- -
-   - - - - - - -
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.
- source code - -
- -
-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - - - - - - - - - - -
- Static Methods
-   - - - - - - -
setDefaultWhitespaceChars(chars)
- Overrides the default whitespace chars
- source code - -
- -
-   - - - - - - -
inlineLiteralsUsing(cls)
- Set class to be used for inclusion of string literals into a parser.
- source code - -
- -
-   - - - - - - -
resetCache() - source code - -
- -
-   - - - - - - -
enablePackrat(cache_size_limit=128)
- Enables "packrat" parsing, which adds memoizing to the - parsing logic.
- source code - -
- -
- - - - - - - - - - - - - - - - - - - - - -
- Class Variables
-   - - DEFAULT_WHITE_CHARS = ' \n\t\r' -
-   - - verbose_stacktrace = False -
-   - - packrat_cache = {} -
-   - - packrat_cache_lock = <_RLock owner=None count=0> -
-   - - packrat_cache_stats = [0, 0] -
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

setDefaultWhitespaceChars(chars) -
Static Method -

-
source code  -
- -

Overrides the default whitespace chars

-

Example:

-
-   # default whitespace chars are space, <TAB> 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']
-
-
-
-
-
- -
- -
- - -
-

inlineLiteralsUsing(cls) -
Static Method -

-
source code  -
- -

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']
-
-
-
-
-
- -
- -
- - -
-

__init__(self, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

copy(self) -

-
source code  -
- -

Make a copy of this 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 expr.copy() is just - expr():

-
-   integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
-
-
-
-
-
- -
- -
- - -
-

setName(self, - name) -

-
source code  -
- -

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)
-
-
-
-
-
- -
- -
- - -
-

setResultsName(self, - name, - listAllMatches=False) -

-
source code  -
- -

Define name for referencing matching tokens as a nested attribute of - the returned parse results. NOTE: this returns a *copy* of the original - 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, - expr("name") in place of - expr.setResultsName("name") - see __call__.

-

Example:

-
-   date_str = (integer.setResultsName("year") + '/' 
-               + integer.setResultsName("month") + '/' 
-               + integer.setResultsName("day"))
-
-   # equivalent form:
-   date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
-
-
-
-
- -
- -
- - -
-

setBreak(self, - breakFlag=True) -

-
source code  -
- -

Method to invoke the Python pdb debugger when this element is about to - be parsed. Set breakFlag to True to enable, False to - disable.

-
-
-
-
- -
- -
- - -
-

setParseAction(self, - *fns, - **kwargs) -

-
source code  -
- -

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 fn(s,loc,toks), - fn(loc,toks), fn(toks), or just - 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 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=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 parseString for more information on parsing - strings containing <TAB>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]
-
-
-
-
-
- -
- -
- - -
-

addParseAction(self, - *fns, - **kwargs) -

-
source code  -
- -

Add one or more parse actions to expression's list of parse actions. - See setParseAction.

-

See examples in copy.

-
-
-
-
- -
- -
- - -
-

addCondition(self, - *fns, - **kwargs) -

-
source code  -
- -

Add a boolean predicate function to expression's list of parse - actions. See setParseAction for function call signatures. - Unlike setParseAction, functions passed to - 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)
-
-
-
-
-
- -
- -
- - -
-

setFailAction(self, - fn) -

-
source code  -
- -

Define action to perform if parsing fails at this expression. Fail - acton fn is a callable function that takes the arguments - 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 ParseFatalException if it is desired to stop - parsing immediately.

-
-
-
-
- -
- -
- - -
-

enablePackrat(cache_size_limit=128) -
Static Method -

-
source code  -
- -

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=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 ParserElement.enablePackrat(). - If your program uses psyco to "compile as you go", - you must call enablePackrat before calling - psyco.full(). If you do not do this, Python will crash. - For best results, call enablePackrat() immediately after - importing pyparsing.

-

Example:

-
-   import pyparsing
-   pyparsing.ParserElement.enablePackrat()
-
-
-
-
-
- -
- -
- - -
-

parseString(self, - instring, - parseAll=False) -

-
source code  -
- -

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 parseAll to True (equivalent - to ending the grammar with StringEnd()).

-

Note: parseString implicitly calls - 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 loc argument to - index into the string being parsed, you can ensure you have a consistent - view of the input string by:

-
    -
  • - calling parseWithTabs on your grammar before calling - parseString (see parseWithTabs) -
  • -
  • - define your parse action using the full (s,loc,toks) - signature, and reference the input string using the parse action's - s argument -
  • -
  • - explictly expand the tabs in your input string before calling - parseString -
  • -
-

Example:

-
-   Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
-   Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
-
-
-
-
-
- -
- -
- - -
-

scanString(self, - instring, - maxMatches=2147483647, - overlap=False) -

-
source code  -
- -

Scan the input string for expression matches. Each match will return - the matching tokens, start location, and end location. May be called - with optional maxMatches argument, to clip scanning after - 'n' matches are found. If 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 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
-
-
-
-
-
- -
- -
- - -
-

transformString(self, - instring) -

-
source code  -
- -

Extension to scanString, to modify matching text with modified - tokens that may be returned from a parse action. To use - transformString, define a grammar and attach a parse action - to it that modifies the returned token list. Invoking - transformString() on a target string will then scan for - matches, and replace the matched text patterns according to the logic in - the parse action. 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.
-
-
-
-
-
- -
- -
- - -
-

searchString(self, - instring, - maxMatches=2147483647) -

-
source code  -
- -

Another extension to scanString, simplifying the access to the tokens - found to match the given parse expression. May be called with optional - 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']
-
-
-
-
-
- -
- -
- - -
-

split(self, - instring, - maxsplit=2147483647, - includeSeparators=False) -

-
source code  -
- -

Generator method to split a string using the given expression as a - separator. May be called with optional maxsplit argument, to - limit the number of splits; and the optional - includeSeparators argument (default=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', '']
-
-
-
-
-
- -
- -
- - -
-

__add__(self, - other) -
(Addition operator) -

-
source code  -
- -

Implementation of + operator - returns And. Adding - strings to a ParserElement converts them to Literals by default.

-

Example:

-
-   greet = Word(alphas) + "," + Word(alphas) + "!"
-   hello = "Hello, World!"
-   print (hello, "->", greet.parseString(hello))
-
-

Prints:

-
-   Hello, World! -> ['Hello', ',', 'World', '!']
-
-
-
-
-
- -
- -
- - -
-

__mul__(self, - other) -

-
source code  -
- -

Implementation of * operator, allows use of expr * 3 in - place of expr + expr + expr. Expressions may also me - multiplied by a 2-integer tuple, similar to {min,max} - multipliers in regular expressions. Tuples may also include - None as in:

-
    -
  • - expr*(n,None) or expr*(n,) is equivalent to - expr*n + ZeroOrMore(expr) (read as "at least n - instances of expr") -
  • -
  • - expr*(None,n) is equivalent to expr*(0,n) - (read as "0 to n instances of expr") -
  • -
  • - expr*(None,None) is equivalent to ZeroOrMore(expr) -
  • -
  • - expr*(1,None) is equivalent to OneOrMore(expr) -
  • -
-

Note that expr*(None,n) does not raise an exception if - more than n exprs exist in the input stream; that is, - expr*(None,n) does not enforce a maximum number of expr - occurrences. If this behavior is desired, then write expr*(None,n) - + ~expr

-
-
-
-
- -
- -
- - -
-

__call__(self, - name=None) -
(Call operator) -

-
source code  -
- -

Shortcut for setResultsName, with - listAllMatches=False.

-

If name is given with a trailing '*' - character, then listAllMatches will be passed as - True.

-

If name is omitted, same as calling copy.

-

Example:

-
-   # these are equivalent
-   userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
-   userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
-
-
-
-
-
- -
- -
- - -
-

leaveWhitespace(self) -

-
source code  -
- -

Disables the skipping of whitespace before matching the characters in - the ParserElement's defined pattern. This is normally only - used internally by the pyparsing module, but may be needed in some - whitespace-sensitive grammars.

-
-
-
-
- -
- -
- - -
-

parseWithTabs(self) -

-
source code  -
- -

Overrides default behavior to expand <TAB>s to - spaces before parsing the input string. Must be called before - parseString when the input grammar contains elements that - match <TAB> characters.

-
-
-
-
- -
- -
- - -
-

ignore(self, - other) -

-
source code  -
- -

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']
-
-
-
-
-
- -
- -
- - -
-

setDebug(self, - flag=True) -

-
source code  -
- -

Enable display of debugging messages while doing pattern matching. Set - 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 setDebugActions. Prior to attempting to match the - wd expression, the debugging message "Match - <exprname> at loc <n>(<line>,<col>)" - is shown. Then if the parse succeeds, a "Matched" - message is shown, or an "Exception raised" message - is shown. Also note the use of 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 - Word expression without calling setName is - "W:(ABCD...)".

-
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__repr__(self) -
(Representation operator) -

-
source code  -
- -

repr(x)

-
-
Overrides: - object.__repr__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseFile(self, - file_or_filename, - parseAll=False) -

-
source code  -
- -

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.

-
-
-
-
- -
- -
- - -
-

__hash__(self) -
(Hashing function) -

-
source code  -
- -

hash(x)

-
-
Overrides: - object.__hash__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

matches(self, - testString, - parseAll=True) -

-
source code  -
- -

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=True) - flag to pass to parseString when running tests -
  • -
-

Example:

-
-   expr = Word(nums)
-   assert expr.matches("100")
-
-
-
-
-
- -
- -
- - -
-

runTests(self, - tests, - parseAll=True, - comment='#', - fullDump=True, - printResults=True, - failureTests=False) -

-
source code  -
- -

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=True) - flag to pass to parseString when running tests -
  • -
  • - comment - (default='#') - expression for indicating - embedded comments in the test string; pass None to disable comment - filtering -
  • -
  • - fullDump - (default=True) - dump results as list - followed by results names in nested outline; if False, only dump - nested list -
  • -
  • - printResults - (default=True) prints test output to - stdout -
  • -
  • - failureTests - (default=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 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'.)

-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.QuotedString-class.html b/htmldoc/pyparsing.QuotedString-class.html deleted file mode 100644 index 4c6ec32..0000000 --- a/htmldoc/pyparsing.QuotedString-class.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - pyparsing.QuotedString - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class QuotedString - - - - - -
[frames] | no frames]
-
- -

Class QuotedString

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   QuotedString
-
- -
-

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=None) -
  • -
  • - escQuote - special quote sequence to escape an embedded quote string - (such as SQL's "" to escape an embedded ") - (default=None) -
  • -
  • - multiline - boolean indicating whether quotes can span multiple lines - (default=False) -
  • -
  • - unquoteResults - boolean indicating whether the matched text should - be unquoted (default=True) -
  • -
  • - endQuoteChar - string of one or more characters defining the end of - the quote delimited string (default=None => same as - quoteChar) -
  • -
  • - convertWhitespaceEscapes - convert escaped whitespace - ('\t', '\n', etc.) to actual whitespace - (default=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']]
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - quoteChar, - escChar=None, - escQuote=None, - multiline=False, - unquoteResults=True, - endQuoteChar=None, - convertWhitespaceEscapes=True)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - quoteChar, - escChar=None, - escQuote=None, - multiline=False, - unquoteResults=True, - endQuoteChar=None, - convertWhitespaceEscapes=True) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Recipes-class.html b/htmldoc/pyparsing.Recipes-class.html deleted file mode 100644 index efd9dbd..0000000 --- a/htmldoc/pyparsing.Recipes-class.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - pyparsing.Recipes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Recipes - - - - - -
[frames] | no frames]
-
- -

Class Recipes

source code

-

Here are some common low-level expressions that may be useful in - jump-starting your parser development:

-
-   
-
- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
convertToInteger(t)
- Parse action for converting parsed integers to Python int
- source code - -
- -
-   - - - - - - -
convertToFloat(t)
- Parse action for converting parsed numbers to Python float
- source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Class Variables
-   - - integer = integer -
-   - - signedInteger = signed integer -
-   - - real = real number -
-   - - sciReal = real number with scientfic notation -
-   - - numeric = {real number with scientfic notation | real number |... -
-   - - number = number -
-   - - identifier = identifier -
- - - - - - -
- Class Variable Details
- -
- -
-

numeric

- -
-
-
-
Value:
-
-{real number with scientfic notation | real number | integer | signed \
-integer}
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.RecursiveGrammarException-class.html b/htmldoc/pyparsing.RecursiveGrammarException-class.html deleted file mode 100644 index ea4e7b4..0000000 --- a/htmldoc/pyparsing.RecursiveGrammarException-class.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - - pyparsing.RecursiveGrammarException - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class RecursiveGrammarException - - - - - -
[frames] | no frames]
-
- -

Class RecursiveGrammarException

source code

-
-              object --+        
-                       |        
-exceptions.BaseException --+    
-                           |    
-        exceptions.Exception --+
-                               |
-                              RecursiveGrammarException
-
- -
-

exception thrown by ParserElement.validate if the grammar could be - improperly recursive

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - parseElementList)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from exceptions.Exception: - __new__ -

-

Inherited from exceptions.BaseException: - __delattr__, - __getattribute__, - __getitem__, - __getslice__, - __reduce__, - __repr__, - __setattr__, - __setstate__, - __unicode__ -

-

Inherited from object: - __format__, - __hash__, - __reduce_ex__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Properties
-

Inherited from exceptions.BaseException: - args, - message -

-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - parseElementList) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Regex-class.html b/htmldoc/pyparsing.Regex-class.html deleted file mode 100644 index a8f44ea..0000000 --- a/htmldoc/pyparsing.Regex-class.html +++ /dev/null @@ -1,434 +0,0 @@ - - - - - pyparsing.Regex - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Regex - - - - - -
[frames] | no frames]
-
- -

Class Regex

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   Regex
-
- -
-

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 (?P<name>...)), these will - be preserved as named parse results.

-

Example:

-
-   realnum = Regex(r"[+-]?\d+\.\d*")
-   date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\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})")
-
- - - - - - - - - - -
- Nested Classes
-   - - compiledREtype
- Compiled regular expression objects -
- - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - pattern, - flags=0)
- The parameters pattern and flags are passed - to the re.compile() function as-is.
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - pattern, - flags=0) -
(Constructor) -

-
source code  -
- -

The parameters pattern and flags are passed - to the re.compile() function as-is. See the Python - re module for an explanation of the acceptable patterns and - flags.

-
-
Overrides: - object.__init__ -
-
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Regex.compiledREtype-class.html b/htmldoc/pyparsing.Regex.compiledREtype-class.html deleted file mode 100644 index 2564adb..0000000 --- a/htmldoc/pyparsing.Regex.compiledREtype-class.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - pyparsing.Regex.compiledREtype - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Regex :: - Class compiledREtype - - - - - -
[frames] | no frames]
-
- -

Class compiledREtype

-
-object --+
-         |
-        pyparsing.Regex.compiledREtype
-
- -
-

Compiled regular expression objects

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__copy__(...) - - -
- -
-   - - - - - - -
__deepcopy__(...) - - -
- -
-   - - - - - - -
findall(...)
- findall(string[, pos[, endpos]]) --> list.
- - -
- -
-   - - - - - - -
finditer(...)
- finditer(string[, pos[, endpos]]) --> iterator.
- - -
- -
-   - - - - - - -
match(...)
- match(string[, pos[, endpos]]) --> match object or None.
- - -
- -
-   - - - - - - -
scanner(...) - - -
- -
-   - - - - - - -
search(...)
- search(string[, pos[, endpos]]) --> match object or None.
- - -
- -
-   - - - - - - -
split(...)
- split(string[, maxsplit = 0]) --> list.
- - -
- -
-   - - - - - - -
sub(...)
- sub(repl, string[, count = 0]) --> newstring Return the string - obtained by replacing the leftmost non-overlapping occurrences of - pattern in string by the replacement repl.
- - -
- -
-   - - - - - - -
subn(repl, - string, - count=... = 0) --> (newstring, - number of subs)
- Return the tuple (new_string, number_of_subs_made) found by replacing - the leftmost non-overlapping occurrences of pattern with the - replacement repl.
- - -
- -
-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __hash__, - __init__, - __new__, - __reduce__, - __reduce_ex__, - __repr__, - __setattr__, - __sizeof__, - __str__, - __subclasshook__ -

-
- - - - - - - - - - - - - - - - - - - - - -
- Properties
-   - - flags -
-   - - groupindex -
-   - - groups -
-   - - pattern -
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

findall(...) -

-
  -
- -

findall(string[, pos[, endpos]]) --> list. Return a list of all - non-overlapping matches of pattern in string.

-
-
-
-
- -
- -
- - -
-

finditer(...) -

-
  -
- -

finditer(string[, pos[, endpos]]) --> iterator. Return an iterator - over all non-overlapping matches for the RE pattern in string. For each - match, the iterator returns a match object.

-
-
-
-
- -
- -
- - -
-

match(...) -

-
  -
- -

match(string[, pos[, endpos]]) --> match object or None. Matches - zero or more characters at the beginning of the string

-
-
-
-
- -
- -
- - -
-

search(...) -

-
  -
- -

search(string[, pos[, endpos]]) --> match object or None. Scan - through string looking for a match, and return a corresponding match - object instance. Return None if no position in the string matches.

-
-
-
-
- -
- -
- - -
-

split(...) -

-
  -
- -

split(string[, maxsplit = 0]) --> list. Split string by the - occurrences of pattern.

-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.SkipTo-class.html b/htmldoc/pyparsing.SkipTo-class.html deleted file mode 100644 index 83c71f5..0000000 --- a/htmldoc/pyparsing.SkipTo-class.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - pyparsing.SkipTo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class SkipTo - - - - - -
[frames] | no frames]
-
- -

Class SkipTo

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     SkipTo
-
- -
-

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=False) if True, the target expression - is also parsed (the skipped text and target expression are returned - as a 2-element list). -
  • -
  • - ignore - (default=None) used to define grammars - (typically quoted strings and comments) that might contain false - matches to the target expression -
  • -
  • - failOn - (default=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
-
- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - other, - include=False, - ignore=None, - failOn=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - other, - include=False, - ignore=None, - failOn=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.StringEnd-class.html b/htmldoc/pyparsing.StringEnd-class.html deleted file mode 100644 index d33c54f..0000000 --- a/htmldoc/pyparsing.StringEnd-class.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - pyparsing.StringEnd - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class StringEnd - - - - - -
[frames] | no frames]
-
- -

Class StringEnd

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       StringEnd
-
- -
-

Matches if current position is at the end of the parse string

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.StringStart-class.html b/htmldoc/pyparsing.StringStart-class.html deleted file mode 100644 index 8627cad..0000000 --- a/htmldoc/pyparsing.StringStart-class.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - - pyparsing.StringStart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class StringStart - - - - - -
[frames] | no frames]
-
- -

Class StringStart

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       StringStart
-
- -
-

Matches if current position is at the beginning of the parse - string

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Suppress-class.html b/htmldoc/pyparsing.Suppress-class.html deleted file mode 100644 index fd5db7f..0000000 --- a/htmldoc/pyparsing.Suppress-class.html +++ /dev/null @@ -1,385 +0,0 @@ - - - - - pyparsing.Suppress - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Suppress - - - - - -
[frames] | no frames]
-
- -

Class Suppress

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         TokenConverter --+
-                          |
-                         Suppress
-
- -
-

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 delimitedList.)

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
postParse(self, - instring, - loc, - tokenlist) - source code - -
- -
-   - - - - - - -
suppress(self)
- Suppresses the output of this ParserElement; useful to - keep punctuation from cluttering up returned output.
- source code - -
- -
-

Inherited from TokenConverter: - __init__ -

-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - parseImpl, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

postParse(self, - instring, - loc, - tokenlist) -

-
source code  -
- - -
-
Overrides: - ParserElement.postParse -
-
-
-
- -
- -
- - -
-

suppress(self) -

-
source code  -
- -

Suppresses the output of this ParserElement; useful to - keep punctuation from cluttering up returned output.

-
-
Overrides: - ParserElement.suppress -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Token-class.html b/htmldoc/pyparsing.Token-class.html deleted file mode 100644 index 8da8ebe..0000000 --- a/htmldoc/pyparsing.Token-class.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - pyparsing.Token - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Token - - - - - -
[frames] | no frames]
-
- -

Class Token

source code

-
-   object --+    
-            |    
-ParserElement --+
-                |
-               Token
-
- -
Known Subclasses:
-
- -
- -
-

Abstract ParserElement subclass, for defining atomic - matching patterns.

- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseImpl, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.TokenConverter-class.html b/htmldoc/pyparsing.TokenConverter-class.html deleted file mode 100644 index 4b714d3..0000000 --- a/htmldoc/pyparsing.TokenConverter-class.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - pyparsing.TokenConverter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class TokenConverter - - - - - -
[frames] | no frames]
-
- -

Class TokenConverter

source code

-
-     object --+        
-              |        
-  ParserElement --+    
-                  |    
-ParseElementEnhance --+
-                      |
-                     TokenConverter
-
- -
Known Subclasses:
-
- -
- -
-

Abstract subclass of ParseExpression, for converting - parsed results.

- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr, - savelist=False)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-

Inherited from ParseElementEnhance: - __str__, - checkRecursion, - ignore, - leaveWhitespace, - parseImpl, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr, - savelist=False) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.White-class.html b/htmldoc/pyparsing.White-class.html deleted file mode 100644 index 75bd4bf..0000000 --- a/htmldoc/pyparsing.White-class.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - pyparsing.White - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class White - - - - - -
[frames] | no frames]
-
- -

Class White

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   White
-
- -
-

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 " - \t\r\n". Also takes optional min, - max, and exact arguments, as defined for the - Word - class.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - ws=' \t\r\n', - min=1, - max=0, - exact=0)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - - - - -
- Class Variables
-   - - whiteStrs = {'\t': '<TAB>', '\n': '<LF>', '\x0c': '<FF>', '\r'... -
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - ws=' \t\r\n', - min=1, - max=0, - exact=0) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - -
- Class Variable Details
- -
- -
-

whiteStrs

- -
-
-
-
Value:
-
-{'\t': '<TAB>',
- '''
-''': '<LF>',
- '\x0c': '<FF>',
- '\r': '<CR>',
- ' ': '<SPC>'}
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.Word-class.html b/htmldoc/pyparsing.Word-class.html deleted file mode 100644 index a3eba1f..0000000 --- a/htmldoc/pyparsing.Word-class.html +++ /dev/null @@ -1,482 +0,0 @@ - - - - - pyparsing.Word - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class Word - - - - - -
[frames] | no frames]
-
- -

Class Word

source code

-
-   object --+        
-            |        
-ParserElement --+    
-                |    
-            Token --+
-                    |
-                   Word
-
- -
-

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 min is 1 (a minimum value < 1 is - not valid); the default values for max and - exact are 0, meaning no maximum or exact length restriction. - An optional excludeChars parameter can list characters that - might be found in the input bodyChars string; useful to - define a word of all printables except for one or two characters, for - instance.

-

srange is - useful for defining custom character set strings for defining - Word expressions, using range notation from regular - expression character sets.

-

A common mistake is to use Word to match a specific - literal string, as in Word("Address"). Remember - that Word uses the string argument to define 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 Literal or Keyword.

-

pyparsing includes helper strings for building Words:

-
    -
  • - alphas -
  • -
  • - nums -
  • -
  • - alphanums -
  • -
  • - hexnums -
  • -
  • - alphas8bit (alphabetic characters in ASCII range - 128-255 - accented, tilded, umlauted, etc.) -
  • -
  • - punc8bit - (non-alphabetic characters in ASCII range 128-255 - currency, - symbols, superscripts, diacriticals, etc.) -
  • -
  • - 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=",")
-
- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - initChars, - bodyChars=None, - min=1, - max=0, - exact=0, - asKeyword=False, - excludeChars=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - - - - -
- Class Variables
-   - - __slotnames__ = [] -
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - initChars, - bodyChars=None, - min=1, - max=0, - exact=0, - asKeyword=False, - excludeChars=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.WordEnd-class.html b/htmldoc/pyparsing.WordEnd-class.html deleted file mode 100644 index f7f80b7..0000000 --- a/htmldoc/pyparsing.WordEnd-class.html +++ /dev/null @@ -1,361 +0,0 @@ - - - - - pyparsing.WordEnd - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class WordEnd - - - - - -
[frames] | no frames]
-
- -

Class WordEnd

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       WordEnd
-
- -
-

Matches if the current position is at the end of a Word, and is not - followed by any character in a given set of wordChars - (default=printables). To emulate the  behavior - of regular expressions, use WordEnd(alphanums). - WordEnd will also match at the end of the string being - parsed, or at the end of a line.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - wordChars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY...)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - wordChars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY...) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.WordStart-class.html b/htmldoc/pyparsing.WordStart-class.html deleted file mode 100644 index 985fbc0..0000000 --- a/htmldoc/pyparsing.WordStart-class.html +++ /dev/null @@ -1,361 +0,0 @@ - - - - - pyparsing.WordStart - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class WordStart - - - - - -
[frames] | no frames]
-
- -

Class WordStart

source code

-
-   object --+            
-            |            
-ParserElement --+        
-                |        
-            Token --+    
-                    |    
-       _PositionToken --+
-                        |
-                       WordStart
-
- -
-

Matches if the current position is at the beginning of a Word, and is - not preceded by any character in a given set of wordChars - (default=printables). To emulate the  behavior - of regular expressions, use WordStart(alphanums). - WordStart will also match at the beginning of the string - being parsed, or at the beginning of a line.

- - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - wordChars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY...)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __str__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - checkRecursion, - copy, - ignore, - leaveWhitespace, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - streamline, - suppress, - transformString, - tryParse, - validate -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - wordChars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY...) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.ZeroOrMore-class.html b/htmldoc/pyparsing.ZeroOrMore-class.html deleted file mode 100644 index 50acc48..0000000 --- a/htmldoc/pyparsing.ZeroOrMore-class.html +++ /dev/null @@ -1,413 +0,0 @@ - - - - - pyparsing.ZeroOrMore - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class ZeroOrMore - - - - - -
[frames] | no frames]
-
- -

Class ZeroOrMore

source code

-
-     object --+            
-              |            
-  ParserElement --+        
-                  |        
-ParseElementEnhance --+    
-                      |    
-         _MultipleMatch --+
-                          |
-                         ZeroOrMore
-
- -
-

Optional repetition of zero or more of the given expression.

-

Parameters:

-
    -
  • - expr - expression that must match zero or more times -
  • -
  • - stopOn - (default=None) - expression for a terminating - sentinel (only required if the sentinel would ordinarily match the - repetition expression) -
  • -
-

Example: similar to OneOrMore

- - - - - - - - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
__init__(self, - expr, - stopOn=None)
- x.__init__(...) initializes x; see help(type(x)) for signature
- source code - -
- -
-   - - - - - - -
parseImpl(self, - instring, - loc, - doActions=True) - source code - -
- -
-   - - - - - - -
__str__(self)
- str(x)
- source code - -
- -
-

Inherited from ParseElementEnhance: - checkRecursion, - ignore, - leaveWhitespace, - streamline, - validate -

-

Inherited from ParserElement: - __add__, - __and__, - __call__, - __eq__, - __hash__, - __invert__, - __mul__, - __ne__, - __or__, - __radd__, - __rand__, - __repr__, - __req__, - __rmul__, - __rne__, - __ror__, - __rsub__, - __rxor__, - __sub__, - __xor__, - addCondition, - addParseAction, - canParseNext, - copy, - matches, - parseFile, - parseString, - parseWithTabs, - postParse, - preParse, - runTests, - scanString, - searchString, - setBreak, - setDebug, - setDebugActions, - setFailAction, - setName, - setParseAction, - setResultsName, - setWhitespaceChars, - split, - suppress, - transformString, - tryParse -

-

Inherited from object: - __delattr__, - __format__, - __getattribute__, - __new__, - __reduce__, - __reduce_ex__, - __setattr__, - __sizeof__, - __subclasshook__ -

-
- - - - - - - - - -
- Static Methods
-

Inherited from ParserElement: - enablePackrat, - inlineLiteralsUsing, - resetCache, - setDefaultWhitespaceChars -

-
- - - - - - - - - -
- Class Variables
-

Inherited from ParserElement: - DEFAULT_WHITE_CHARS, - packrat_cache, - packrat_cache_lock, - packrat_cache_stats, - verbose_stacktrace -

-
- - - - - - - - - -
- Properties
-

Inherited from object: - __class__ -

-
- - - - - - -
- Method Details
- -
- -
- - -
-

__init__(self, - expr, - stopOn=None) -
(Constructor) -

-
source code  -
- -

x.__init__(...) initializes x; see help(type(x)) for signature

-
-
Overrides: - object.__init__ -
(inherited documentation)
- -
-
-
- -
- -
- - -
-

parseImpl(self, - instring, - loc, - doActions=True) -

-
source code  -
- - -
-
Overrides: - ParserElement.parseImpl -
-
-
-
- -
- -
- - -
-

__str__(self) -
(Informal representation operator) -

-
source code  -
- -

str(x)

-
-
Overrides: - object.__str__ -
(inherited documentation)
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/pyparsing.pyparsing_common-class.html b/htmldoc/pyparsing.pyparsing_common-class.html deleted file mode 100644 index f518637..0000000 --- a/htmldoc/pyparsing.pyparsing_common-class.html +++ /dev/null @@ -1,753 +0,0 @@ - - - - - pyparsing.pyparsing_common - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Module pyparsing :: - Class pyparsing_common - - - - - -
[frames] | no frames]
-
- -

Class pyparsing_common

source code

-

Here are some common low-level expressions that may be useful in - jump-starting parser development:

- -

Parse actions:

- -

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')]
-
- - - - - - - - - - - - - -
- Instance Methods
-   - - - - - - -
convertToInteger(s, - l, - t)
- Parse action for converting parsed integers to Python int
- source code - -
- -
-   - - - - - - -
convertToFloat(s, - l, - t)
- Parse action for converting parsed numbers to Python float
- source code - -
- -
- - - - - - - - - - - - - - - - - - - - - -
- Static Methods
-   - - - - - - -
convertToDate(fmt='%Y-%m-%d')
- Helper to create a parse action for converting parsed date string to - Python datetime.date
- source code - -
- -
-   - - - - - - -
convertToDatetime(fmt='%Y-%m-%dT%H:%M:%S.%f')
- Helper to create a parse action for converting parsed datetime string - to Python datetime.datetime
- source code - -
- -
-   - - - - - - -
stripHTMLTags(s, - l, - tokens)
- Parse action to remove HTML tags from web page HTML source
- source code - -
- -
-   - - - - - - -
upcaseTokens(s, - l, - t)
- Parse action to convert tokens to upper case.
- source code - -
- -
-   - - - - - - -
downcaseTokens(s, - l, - t)
- Parse action to convert tokens to lower case.
- source code - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Class Variables
-   - - integer = integer
- expression that parses an unsigned integer, returns an int -
-   - - hex_integer = hex integer
- expression that parses a hexadecimal integer, returns an int -
-   - - signed_integer = signed integer
- expression that parses an integer with optional leading sign, returns - an int -
-   - - fraction = fraction
- fractional expression of an integer divided by an integer, returns a - float -
-   - - mixed_integer = fraction or mixed integer-fraction
- mixed integer of the form 'integer - fraction', with optional leading - integer, returns float -
-   - - real = real number
- expression that parses a floating point number and returns a float -
-   - - sci_real = real number with scientific notation
- expression that parses a floating point number with optional - scientific notation and returns a float -
-   - - number = {real number with scientific notation | real number |...
- any numeric expression, returns the corresponding Python type -
-   - - fnumber = fnumber
- any int or real number, returned as float -
-   - - identifier = identifier
- typical code identifier (leading alpha or '_', followed by 0 or more - alphas, nums, or '_') -
-   - - ipv4_address = IPv4 address
- IPv4 address (0.0.0.0 - 255.255.255.255) -
-   - - ipv6_address = IPv6 address
- IPv6 address (long, short, or mixed form) -
-   - - mac_address = MAC address
- MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters) -
-   - - iso8601_date = ISO8601 date
- ISO8601 date (yyyy-mm-dd) -
-   - - iso8601_datetime = ISO8601 datetime
- ISO8601 datetime (yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)) - - trailing seconds, milliseconds, and timezone optional; accepts - separating 'T' or ' ' -
-   - - uuid = UUID
- UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) -
-   - - comma_separated_list = comma separated list
- Predefined expression of 1 or more printable words or quoted strings, - separated by commas. -
- - - - - - -
- Method Details
- -
- -
- - -
-

convertToDate(fmt='%Y-%m-%d') -
Static Method -

-
source code  -
- -

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="%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)]
-
-
-
-
-
- -
- -
- - -
-

convertToDatetime(fmt='%Y-%m-%dT%H:%M:%S.%f') -
Static Method -

-
source code  -
- -

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="%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)]
-
-
-
-
-
- -
- -
- - -
-

stripHTMLTags(s, - l, - tokens) -
Static Method -

-
source code  -
- -

Parse action to remove HTML tags from web page HTML source

-

Example:

-
-   # strip HTML links from normal text 
-   text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
-   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'
-
-
-
-
-
-
- - - - - - -
- Class Variable Details
- -
- -
-

number

-

any numeric expression, returns the corresponding Python type

-
-
-
-
Value:
-
-{real number with scientific notation | real number | signed integer}
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - diff --git a/htmldoc/redirect.html b/htmldoc/redirect.html deleted file mode 100644 index 9414159..0000000 --- a/htmldoc/redirect.html +++ /dev/null @@ -1,38 +0,0 @@ -Epydoc Redirect Page - - - - - - - - -

Epydoc Auto-redirect page

- -

When javascript is enabled, this page will redirect URLs of -the form redirect.html#dotted.name to the -documentation for the object with the given fully-qualified -dotted name.

-

 

- - - - - diff --git a/htmldoc/toc-everything.html b/htmldoc/toc-everything.html deleted file mode 100644 index 9d59845..0000000 --- a/htmldoc/toc-everything.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - Everything - - - - - -

Everything

-
-

All Classes

- pyparsing.And
pyparsing.CaselessKeyword
pyparsing.CaselessLiteral
pyparsing.CharsNotIn
pyparsing.CloseMatch
pyparsing.Combine
pyparsing.Dict
pyparsing.Each
pyparsing.Empty
pyparsing.FollowedBy
pyparsing.Forward
pyparsing.GoToColumn
pyparsing.Group
pyparsing.Keyword
pyparsing.LineEnd
pyparsing.LineStart
pyparsing.Literal
pyparsing.MatchFirst
pyparsing.NoMatch
pyparsing.NotAny
pyparsing.OneOrMore
pyparsing.OnlyOnce
pyparsing.Optional
pyparsing.Or
pyparsing.ParseBaseException
pyparsing.ParseElementEnhance
pyparsing.ParseException
pyparsing.ParseExpression
pyparsing.ParseFatalException
pyparsing.ParseResults
pyparsing.ParseSyntaxException
pyparsing.ParserElement
pyparsing.QuotedString
pyparsing.RecursiveGrammarException
pyparsing.Regex
pyparsing.Regex.compiledREtype
pyparsing.SkipTo
pyparsing.StringEnd
pyparsing.StringStart
pyparsing.Suppress
pyparsing.Token
pyparsing.TokenConverter
pyparsing.White
pyparsing.Word
pyparsing.WordEnd
pyparsing.WordStart
pyparsing.ZeroOrMore
pyparsing.pyparsing_common

All Functions

- pyparsing.col
pyparsing.countedArray
pyparsing.delimitedList
pyparsing.dictOf
pyparsing.downcaseTokens
pyparsing.indentedBlock
pyparsing.infixNotation
pyparsing.line
pyparsing.lineno
pyparsing.locatedExpr
pyparsing.makeHTMLTags
pyparsing.makeXMLTags
pyparsing.matchOnlyAtCol
pyparsing.matchPreviousExpr
pyparsing.matchPreviousLiteral
pyparsing.nestedExpr
pyparsing.nullDebugAction
pyparsing.oneOf
pyparsing.originalTextFor
pyparsing.removeQuotes
pyparsing.replaceHTMLEntity
pyparsing.replaceWith
pyparsing.srange
pyparsing.tokenMap
pyparsing.traceParseAction
pyparsing.ungroup
pyparsing.upcaseTokens
pyparsing.withAttribute
pyparsing.withClass

All Variables

- pyparsing.alphanums
pyparsing.alphas
pyparsing.alphas8bit
pyparsing.anyCloseTag
pyparsing.anyOpenTag
pyparsing.cStyleComment
pyparsing.commaSeparatedList
pyparsing.commonHTMLEntity
pyparsing.cppStyleComment
pyparsing.dblQuotedString
pyparsing.dblSlashComment
pyparsing.empty
pyparsing.hexnums
pyparsing.htmlComment
pyparsing.javaStyleComment
pyparsing.lineEnd
pyparsing.lineStart
pyparsing.nums
pyparsing.opAssoc
pyparsing.printables
pyparsing.punc8bit
pyparsing.pythonStyleComment
pyparsing.quotedString
pyparsing.restOfLine
pyparsing.sglQuotedString
pyparsing.stringEnd
pyparsing.stringStart
pyparsing.unicodeString

- - - - diff --git a/htmldoc/toc-pyparsing-module.html b/htmldoc/toc-pyparsing-module.html deleted file mode 100644 index 0813d53..0000000 --- a/htmldoc/toc-pyparsing-module.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - pyparsing - - - - - -

Module pyparsing

-
-

Classes

- And
CaselessKeyword
CaselessLiteral
CharsNotIn
CloseMatch
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
pyparsing_common

Functions

- col
countedArray
delimitedList
dictOf
downcaseTokens
indentedBlock
infixNotation
line
lineno
locatedExpr
makeHTMLTags
makeXMLTags
matchOnlyAtCol
matchPreviousExpr
matchPreviousLiteral
nestedExpr
nullDebugAction
oneOf
operatorPrecedence
originalTextFor
removeQuotes
replaceHTMLEntity
replaceWith
srange
tokenMap
traceParseAction
ungroup
upcaseTokens
withAttribute
withClass

Variables

- alphanums
alphas
alphas8bit
anyCloseTag
anyOpenTag
cStyleComment
commaSeparatedList
commonHTMLEntity
cppStyleComment
dblQuotedString
dblSlashComment
empty
hexnums
htmlComment
javaStyleComment
lineEnd
lineStart
nums
opAssoc
printables
punc8bit
pythonStyleComment
quotedString
restOfLine
sglQuotedString
stringEnd
stringStart
unicodeString

- - - - diff --git a/htmldoc/toc.html b/htmldoc/toc.html deleted file mode 100644 index 2ae8afb..0000000 --- a/htmldoc/toc.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Table of Contents - - - - - -

Table of Contents

-
- Everything -
-

Modules

- pyparsing

- - - - diff --git a/pyparsing.egg-info/PKG-INFO b/pyparsing.egg-info/PKG-INFO index 437c191..2deb689 100644 --- a/pyparsing.egg-info/PKG-INFO +++ b/pyparsing.egg-info/PKG-INFO @@ -1,23 +1,27 @@ -Metadata-Version: 1.1 -Name: pyparsing -Version: 2.2.0 -Summary: Python parsing module -Home-page: http://pyparsing.wikispaces.com/ -Author: Paul McGuire -Author-email: ptmcg@users.sourceforge.net -License: MIT License -Download-URL: http://sourceforge.net/project/showfiles.php?group_id=97203 -Description: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Information Technology -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 +Metadata-Version: 1.2 +Name: pyparsing +Version: 2.2.1 +Summary: Python parsing module +Home-page: https://github.com/pyparsing/pyparsing/ +Author: Paul McGuire +Author-email: ptmcg@users.sourceforge.net +License: MIT License +Download-URL: https://pypi.org/project/pyparsing/ +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.* diff --git a/pyparsing.egg-info/SOURCES.txt b/pyparsing.egg-info/SOURCES.txt index 7e44c4e..658824c 100644 --- a/pyparsing.egg-info/SOURCES.txt +++ b/pyparsing.egg-info/SOURCES.txt @@ -1,175 +1,7 @@ -CHANGES -HowToUsePyparsing.html -LICENSE -MANIFEST.in -README +README.md pyparsing.py -pyparsingClassDiagram.JPG -pyparsingClassDiagram.PNG -robots.txt setup.cfg setup.py -docs/HowToUsePyparsing.html -docs/pycon06-AdventureEngineUsingPyparsing-notes.pdf -docs/pycon06-IntroToPyparsing-notes.pdf -docs/pyparsingClassDiagram.JPG -docs/pyparsingClassDiagram.PNG -examples/0README.html -examples/AcManForm.dfm -examples/LAparser.py -examples/Setup.ini -examples/SimpleCalc.py -examples/SingleForm.dfm -examples/TAP.py -examples/__init__.py -examples/adventureEngine.py -examples/antlr_grammar.py -examples/antlr_grammar_tests.py -examples/apicheck.py -examples/btpyparse.py -examples/builtin_parse_action_demo.py -examples/cLibHeader.py -examples/chemicalFormulas.py -examples/commasep.py -examples/configParse.py -examples/cpp_enum_parser.py -examples/datetimeParseActions.py -examples/deltaTime.py -examples/dfmparse.py -examples/dhcpd_leases_parser.py -examples/dictExample.py -examples/dictExample2.py -examples/ebnf.py -examples/ebnftest.py -examples/eval_arith.py -examples/excelExpr.py -examples/fourFn.py -examples/gen_ctypes.py -examples/getNTPservers.py -examples/getNTPserversNew.py -examples/greeting.py -examples/greetingInGreek.py -examples/greetingInKorean.py -examples/groupUsingListAllMatches.py -examples/holaMundo.py -examples/htmlStripper.py -examples/httpServerLogParser.py -examples/idlParse.py -examples/indentedGrammarExample.py -examples/invRegex.py -examples/jsonParser.py -examples/linenoExample.py -examples/list1.py -examples/listAllMatches.py -examples/lucene_grammar.py -examples/macroExpander.py -examples/makeHTMLTagExample.py -examples/matchPreviousDemo.py -examples/mozilla.ics -examples/mozillaCalendarParser.py -examples/nested.py -examples/numerics.py -examples/oc.py -examples/parseListString.py -examples/parsePythonValue.py -examples/parseResultsSumExample.py -examples/parseTabularData.py -examples/partial_gene_match.py -examples/pgn.py -examples/position.py -examples/protobuf_parser.py -examples/pymicko.py -examples/pythonGrammarParser.py -examples/rangeCheck.py -examples/readJson.py -examples/removeLineBreaks.py -examples/romanNumerals.py -examples/scanExamples.py -examples/scanYahoo.py -examples/searchParserAppDemo.py -examples/searchparser.py -examples/select_parser.py -examples/sexpParser.py -examples/shapes.py -examples/simpleArith.py -examples/simpleBool.py -examples/simpleSQL.py -examples/simpleWiki.py -examples/sparser.py -examples/sql2dot.py -examples/stackish.py -examples/stateMachine2.py -examples/test_bibparse.py -examples/urlExtractor.py -examples/urlExtractorNew.py -examples/verilogParse.py -examples/withAttribute.py -examples/wordsToNum.py -htmldoc/api-objects.txt -htmldoc/class-tree.html -htmldoc/crarr.png -htmldoc/epydoc.css -htmldoc/epydoc.js -htmldoc/frames.html -htmldoc/help.html -htmldoc/identifier-index.html -htmldoc/index.html -htmldoc/module-tree.html -htmldoc/pyparsing-module.html -htmldoc/pyparsing-pysrc.html -htmldoc/pyparsing.And-class.html -htmldoc/pyparsing.CaselessKeyword-class.html -htmldoc/pyparsing.CaselessLiteral-class.html -htmldoc/pyparsing.CharsNotIn-class.html -htmldoc/pyparsing.CloseMatch-class.html -htmldoc/pyparsing.Combine-class.html -htmldoc/pyparsing.Dict-class.html -htmldoc/pyparsing.Each-class.html -htmldoc/pyparsing.Empty-class.html -htmldoc/pyparsing.FollowedBy-class.html -htmldoc/pyparsing.Forward-class.html -htmldoc/pyparsing.GoToColumn-class.html -htmldoc/pyparsing.Group-class.html -htmldoc/pyparsing.Keyword-class.html -htmldoc/pyparsing.LineEnd-class.html -htmldoc/pyparsing.LineStart-class.html -htmldoc/pyparsing.Literal-class.html -htmldoc/pyparsing.MatchFirst-class.html -htmldoc/pyparsing.NoMatch-class.html -htmldoc/pyparsing.NotAny-class.html -htmldoc/pyparsing.OneOrMore-class.html -htmldoc/pyparsing.OnlyOnce-class.html -htmldoc/pyparsing.Optional-class.html -htmldoc/pyparsing.Or-class.html -htmldoc/pyparsing.ParseBaseException-class.html -htmldoc/pyparsing.ParseElementEnhance-class.html -htmldoc/pyparsing.ParseException-class.html -htmldoc/pyparsing.ParseExpression-class.html -htmldoc/pyparsing.ParseFatalException-class.html -htmldoc/pyparsing.ParseResults-class.html -htmldoc/pyparsing.ParseSyntaxException-class.html -htmldoc/pyparsing.ParserElement-class.html -htmldoc/pyparsing.QuotedString-class.html -htmldoc/pyparsing.Recipes-class.html -htmldoc/pyparsing.RecursiveGrammarException-class.html -htmldoc/pyparsing.Regex-class.html -htmldoc/pyparsing.Regex.compiledREtype-class.html -htmldoc/pyparsing.SkipTo-class.html -htmldoc/pyparsing.StringEnd-class.html -htmldoc/pyparsing.StringStart-class.html -htmldoc/pyparsing.Suppress-class.html -htmldoc/pyparsing.Token-class.html -htmldoc/pyparsing.TokenConverter-class.html -htmldoc/pyparsing.White-class.html -htmldoc/pyparsing.Word-class.html -htmldoc/pyparsing.WordEnd-class.html -htmldoc/pyparsing.WordStart-class.html -htmldoc/pyparsing.ZeroOrMore-class.html -htmldoc/pyparsing.pyparsing_common-class.html -htmldoc/redirect.html -htmldoc/toc-everything.html -htmldoc/toc-pyparsing-module.html -htmldoc/toc.html pyparsing.egg-info/PKG-INFO pyparsing.egg-info/SOURCES.txt pyparsing.egg-info/dependency_links.txt diff --git a/pyparsing.py b/pyparsing.py index e8aefc8..cf75e1e 100644 --- a/pyparsing.py +++ b/pyparsing.py @@ -1,6 +1,6 @@ # module pyparsing.py # -# Copyright (c) 2003-2016 Paul T. McGuire +# 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 @@ -25,6 +25,7 @@ __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 @@ -58,10 +59,23 @@ The pyparsing module handles some of the problems that are typically vexing when - 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.0" -__versionTime__ = "06 Mar 2017 02:06 UTC" +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" __author__ = "Paul McGuire " import string @@ -82,6 +96,15 @@ try: 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: @@ -940,7 +963,7 @@ class ParseResults(object): def __dir__(self): return (dir(type(self)) + list(self.keys())) -collections.MutableMapping.register(ParseResults) +MutableMapping.register(ParseResults) def col (loc,strg): """Returns current column within a string, counting newlines as line separators. @@ -1025,11 +1048,11 @@ def _trim_arity(func, maxargs=2): # 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.filename, frame_summary.lineno)] + return [frame_summary[:2]] def extract_tb(tb, limit=0): frames = traceback.extract_tb(tb, limit=limit) frame_summary = frames[-1] - return [(frame_summary.filename, frame_summary.lineno)] + return [frame_summary[:2]] else: extract_stack = traceback.extract_stack extract_tb = traceback.extract_tb @@ -1374,7 +1397,7 @@ class ParserElement(object): else: preloc = loc tokensStart = preloc - if self.mayIndexError or loc >= len(instring): + if self.mayIndexError or preloc >= len(instring): try: loc,tokens = self.parseImpl( instring, preloc, doActions ) except IndexError: @@ -1408,7 +1431,6 @@ class ParserElement(object): self.resultsName, asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), modal=self.modalResults ) - if debugging: #~ print ("Matched",self,"->",retTokens.asList()) if (self.debugActions[1] ): @@ -3242,7 +3264,7 @@ class ParseExpression(ParserElement): if isinstance( exprs, basestring ): self.exprs = [ ParserElement._literalStringClass( exprs ) ] - elif isinstance( exprs, collections.Iterable ): + elif isinstance( exprs, Iterable ): exprs = list(exprs) # if sequence of strings provided, wrap with Literal if all(isinstance(expr, basestring) for expr in exprs): @@ -4393,7 +4415,7 @@ def traceParseAction(f): @traceParseAction def remove_duplicate_chars(tokens): - return ''.join(sorted(set(''.join(tokens))) + return ''.join(sorted(set(''.join(tokens)))) wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) print(wds.parseString("slkdjs sld sldd sdlf sdljf")) @@ -4583,7 +4605,7 @@ def oneOf( strs, caseless=False, useRegex=True ): symbols = [] if isinstance(strs,basestring): symbols = strs.split() - elif isinstance(strs, collections.Iterable): + elif isinstance(strs, Iterable): symbols = list(strs) else: warnings.warn("Invalid argument to oneOf, expected string or iterable", @@ -4734,7 +4756,7 @@ 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 | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) _charRange = Group(_singleChar + Suppress("-") + _singleChar) _reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" diff --git a/pyparsingClassDiagram.JPG b/pyparsingClassDiagram.JPG deleted file mode 100644 index ef10424899c565f0f4e1067395c6a11a68728abb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236402 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�T%b9f2%Vi0Aw`szWLat!eO+OJV!HG_ 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 X+b(?7;+ROuaH?W<9%BDUxZSq9I=y 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 diff --git a/pyparsingClassDiagram.PNG b/pyparsingClassDiagram.PNG deleted file mode 100644 index f59baaf3929638e74d5f21565f0bf95a1aca14a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141354 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 Z+&&!R1)g40ct$~;qS&#VMq~TJQ2ao)9 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⋙L8`K{4C7h3f`%mZzs*|Ms5wW|1eM=BM6 z$7Yq~aItpcDeQ(uV|1fLi<{VL@Kot8*!UvDZ(D)>t!5~ss$m^qxM8qTZd-7{J^3}t z5x6*M%%;OVOM4%mbWWS9*Dp<%-Y&KB@s~ahz%bZD9QH_{FNp14vVWCs2ufe4UwG@< z-1#8i25T~HdPIZepP{wjpdUL~U<)(@JxSPhf)9mIuTWA;3M`3bN^H zH+b(1%$tqxLSJ8foIbkh)2BPm(4q>?QJ45`@#khjQjK*WI;3~}*8&#&Y4P;%u zf95?$0JJjd$-*!tnRDI$7!`QGl!Fr?`Gl zU0Ehj{q}Y6ioKu|xT6E+(f5HCP@e~i?4&Wxc!}-%j=R5J$TC{IKJU83l~%Jhw4Ce> zd9=?}Y^)~N<{z)2Qb?TCymO<8qkXkZSJ>rPAUTO)o(3FsWl3PWyESCJe6qC8pDS)2NGrt~1m*-c9&Gszix3Xy1*v8fbFOmH;qexIlR@efsC zB zJ~P-oKg`xJfT&5{4yK!2sM!w@8wPmBxS`3KSA*|od2n9tjZ{K7;^TM})v@s=kVPV%1*pB}el%QK1 zOHfq-tX?nY5>hN+Wui@k_xA4EKO$b)U}Z_3{w+iJ?n&CN7d!niAMBjM41SU}=w zR(Nt%l3bp_t0ZJKKXa4ngKEQ9AorEb53G&Ymc^l?aZ}QC{N50zP zZFf1dEj94TY`U$3HHed--J_gR$x|iOH;=}kxrPkuCq=8Y*+mwR-|c z5bf`y3&;= z$R2KbotcHZHSl|d(C*Bfu<0k}rCfgq{@3_iZ%y<^k4EDn}5gYDWdT|HP^oPfoA>mJ=UEYj(6a)-6!gfnHED^<9Wm706F0&^`Cv zrmX3X90X#7IUc@OJF;i0?bUss)g8Y7CnJ}A#gP9}0N=FM<)Q)eRqF(swEAe*cTdXr zssq~0#XrzBeBNKU8AuPpUUa{@i><$^f+AgZHR`3pP0*aAV&URQ3xLuCw{~h&rg?DM zCjp)HH));zn|{6W4GGbbhs)Mhi&(b(ZyVoE3QMPI)tfX4iSqr;#CtV#?VVD}O2by2 z+urI2l-`EVncXfD9kvIfY8|tEO6_6FN$Shcex~cxxkpaa4>}9CV*c(|XqVQei-4J= z!MVU5W*9CvKXYaPF+?TE$6{&dZ6?S=-IqYe)JYXSG6{S-@#Cn)U)s4_$C|yxyEW(B zpBWmi?Fio0_D96uqc231N@or^Gc_ERYFB|Qb!Nnj9gf-2B2<9S#n*K$Pl4yTaUrx> z2f~}ZT^;E=QG&Rde%P)G}a;Sf{&yL?~adF zzk{yudSzA#aE zER0b#sk7N-{ZmNzqc1=3;Hk@