summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-08-09 21:50:19 +0000
committerptmcg <ptmcg@9bf210a0-9d2d-494c-87cf-cfb32e7dff7b>2016-08-09 21:50:19 +0000
commit0b19bb71ba5a4afa84e673a8239935426fa0db23 (patch)
treee9abae9c616fdfdfebd9a8a0931d8f21824f30d2
parentb2c3ade75384efe76b8774b607e17fe98fab92ef (diff)
downloadpyparsing-0b19bb71ba5a4afa84e673a8239935426fa0db23.tar.gz
Remove incorrect tag directorypyparsing_2.1.6
git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/tags/pyparsing_2.1.6@405 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b
-rw-r--r--trunk/src/CHANGES2139
-rw-r--r--trunk/src/HowToUsePyparsing.html1289
-rw-r--r--trunk/src/HowToUsePyparsing.txt993
-rw-r--r--trunk/src/LICENSE18
-rw-r--r--trunk/src/MANIFEST.in_bdist7
-rw-r--r--trunk/src/MANIFEST.in_src7
-rw-r--r--trunk/src/README80
-rw-r--r--trunk/src/examples/0README.html309
-rw-r--r--trunk/src/examples/AcManForm.dfm885
-rw-r--r--trunk/src/examples/LAparser.py417
-rw-r--r--trunk/src/examples/Setup.ini73
-rw-r--r--trunk/src/examples/SimpleCalc.py118
-rw-r--r--trunk/src/examples/SingleForm.dfm751
-rw-r--r--trunk/src/examples/TAP.py217
-rw-r--r--trunk/src/examples/__init__.py0
-rw-r--r--trunk/src/examples/adventureEngine.py648
-rw-r--r--trunk/src/examples/antlr_grammar.py218
-rw-r--r--trunk/src/examples/antlr_grammar_tests.py85
-rw-r--r--trunk/src/examples/apicheck.py55
-rw-r--r--trunk/src/examples/btpyparse.py128
-rw-r--r--trunk/src/examples/builtin_parse_action_demo.py29
-rw-r--r--trunk/src/examples/cLibHeader.py25
-rw-r--r--trunk/src/examples/chemicalFormulas.py67
-rw-r--r--trunk/src/examples/commasep.py23
-rw-r--r--trunk/src/examples/configParse.py72
-rw-r--r--trunk/src/examples/cpp_enum_parser.py52
-rw-r--r--trunk/src/examples/datetimeParseActions.py43
-rw-r--r--trunk/src/examples/deltaTime.py208
-rw-r--r--trunk/src/examples/dfmparse.py176
-rw-r--r--trunk/src/examples/dhcpd_leases_parser.py87
-rw-r--r--trunk/src/examples/dictExample.py41
-rw-r--r--trunk/src/examples/dictExample2.py59
-rw-r--r--trunk/src/examples/ebnf.py149
-rw-r--r--trunk/src/examples/ebnftest.py66
-rw-r--r--trunk/src/examples/eval_arith.py227
-rw-r--r--trunk/src/examples/excelExpr.py68
-rw-r--r--trunk/src/examples/fourFn.py192
-rw-r--r--trunk/src/examples/gen_ctypes.py167
-rw-r--r--trunk/src/examples/getNTPservers.py30
-rw-r--r--trunk/src/examples/getNTPserversNew.py35
-rw-r--r--trunk/src/examples/greeting.py17
-rw-r--r--trunk/src/examples/greetingInGreek.py18
-rw-r--r--trunk/src/examples/greetingInKorean.py20
-rw-r--r--trunk/src/examples/groupUsingListAllMatches.py16
-rw-r--r--trunk/src/examples/holaMundo.py30
-rw-r--r--trunk/src/examples/htmlStripper.py39
-rw-r--r--trunk/src/examples/httpServerLogParser.py71
-rw-r--r--trunk/src/examples/idlParse.py222
-rw-r--r--trunk/src/examples/indentedGrammarExample.py54
-rw-r--r--trunk/src/examples/invRegex.py257
-rw-r--r--trunk/src/examples/javascript_grammar.g894
-rw-r--r--trunk/src/examples/jsonParser.py111
-rw-r--r--trunk/src/examples/linenoExample.py49
-rw-r--r--trunk/src/examples/list1.py50
-rw-r--r--trunk/src/examples/listAllMatches.py52
-rw-r--r--trunk/src/examples/lucene_grammar.py330
-rw-r--r--trunk/src/examples/macroExpander.py60
-rw-r--r--trunk/src/examples/makeHTMLTagExample.py21
-rw-r--r--trunk/src/examples/matchPreviousDemo.py33
-rw-r--r--trunk/src/examples/mozilla.ics50
-rw-r--r--trunk/src/examples/mozillaCalendarParser.py81
-rw-r--r--trunk/src/examples/nested.py30
-rw-r--r--trunk/src/examples/numerics.py62
-rw-r--r--trunk/src/examples/oc.py193
-rw-r--r--trunk/src/examples/parseListString.py82
-rw-r--r--trunk/src/examples/parsePythonValue.py70
-rw-r--r--trunk/src/examples/parseResultsSumExample.py26
-rw-r--r--trunk/src/examples/parseTabularData.py50
-rw-r--r--trunk/src/examples/partial_gene_match.py88
-rw-r--r--trunk/src/examples/pgn.py94
-rw-r--r--trunk/src/examples/position.py55
-rw-r--r--trunk/src/examples/protobuf_parser.py100
-rw-r--r--trunk/src/examples/pymicko.py1387
-rw-r--r--trunk/src/examples/pythonGrammarParser.py220
-rw-r--r--trunk/src/examples/rangeCheck.py62
-rw-r--r--trunk/src/examples/readJson.py1917
-rw-r--r--trunk/src/examples/removeLineBreaks.py45
-rw-r--r--trunk/src/examples/romanNumerals.py74
-rw-r--r--trunk/src/examples/scanExamples.py75
-rw-r--r--trunk/src/examples/scanYahoo.py14
-rw-r--r--trunk/src/examples/searchParserAppDemo.py34
-rw-r--r--trunk/src/examples/searchparser.py292
-rw-r--r--trunk/src/examples/select_parser.py126
-rw-r--r--trunk/src/examples/sexpParser.py167
-rw-r--r--trunk/src/examples/shapes.py64
-rw-r--r--trunk/src/examples/simpleArith.py67
-rw-r--r--trunk/src/examples/simpleBool.py102
-rw-r--r--trunk/src/examples/simpleSQL.py72
-rw-r--r--trunk/src/examples/simpleWiki.py32
-rw-r--r--trunk/src/examples/snmp_api.h795
-rw-r--r--trunk/src/examples/sparser.py365
-rw-r--r--trunk/src/examples/sql2dot.py96
-rw-r--r--trunk/src/examples/stackish.py81
-rw-r--r--trunk/src/examples/stateMachine2.py258
-rw-r--r--trunk/src/examples/test_bibparse.py195
-rw-r--r--trunk/src/examples/urlExtractor.py33
-rw-r--r--trunk/src/examples/urlExtractorNew.py35
-rw-r--r--trunk/src/examples/verilogParse.py720
-rw-r--r--trunk/src/examples/withAttribute.py24
-rw-r--r--trunk/src/examples/wordsToNum.py98
-rw-r--r--trunk/src/genEpydoc.bat2
-rw-r--r--trunk/src/makeRelease.bat24
-rw-r--r--trunk/src/pyparsing.py5528
-rw-r--r--trunk/src/pyparsingClassDiagram.JPGbin236402 -> 0 bytes
-rw-r--r--trunk/src/pyparsingClassDiagram.PNGbin141354 -> 0 bytes
-rw-r--r--trunk/src/setup.cfg5
-rw-r--r--trunk/src/setup.py37
-rw-r--r--trunk/src/test/__init__.py0
-rw-r--r--trunk/src/test/jsonParserTests.py360
-rw-r--r--trunk/src/test/karthik.ini14
-rw-r--r--trunk/src/test/parsefiletest_input_file.txt1
-rw-r--r--trunk/src/unitTests.py3169
-rw-r--r--trunk/src/update_pyparsing_timestamp.py17
113 files changed, 0 insertions, 30185 deletions
diff --git a/trunk/src/CHANGES b/trunk/src/CHANGES
deleted file mode 100644
index 0e48b21..0000000
--- a/trunk/src/CHANGES
+++ /dev/null
@@ -1,2139 +0,0 @@
-==========
-Change Log
-==========
-
-Version 2.1.6 -
-------------------------------
-- *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 "<lambda>() 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 &quot; to ', now correctly maps
- to ". (Also added support for mapping &apos; 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 <ITEM> 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 <TD> or <DIV>.
-
-- 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 "<td nowrap>"), 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 "&lt;", "&gt;", "&amp;", "&nbsp;", and "&quot;". 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 "&lt;", "&gt;", "&amp;", "&nbsp;", and
- "&quot;" 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 &lt;, &gt; and
- &amp;. (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 "<<This is a string in double angle brackets.>>". 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 '<XYZ Abc="1" DEF="2" ghi="3">', 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, '<tagname>') and one for the closing tag ('</tagname>').
- 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 '<BODY/>' which is equivalent to '<BODY></BODY>').
- 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 <TAB>'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 <classname>:[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/trunk/src/HowToUsePyparsing.html b/trunk/src/HowToUsePyparsing.html
deleted file mode 100644
index 1bd180b..0000000
--- a/trunk/src/HowToUsePyparsing.html
+++ /dev/null
@@ -1,1289 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.8: http://docutils.sourceforge.net/" />
-<title>Using the pyparsing module</title>
-<meta name="author" content="Paul McGuire" />
-<meta name="date" content="June, 2011" />
-<meta name="copyright" content="Copyright © 2003-2011 Paul McGuire." />
-<style type="text/css">
-
-/*
-:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 6387 2010-08-13 12:23:41Z milde $
-:Copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the HTML output of Docutils.
-
-See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
-customize this style sheet.
-*/
-
-/* used to remove borders from tables and images */
-.borderless, table.borderless td, table.borderless th {
- border: 0 }
-
-table.borderless td, table.borderless th {
- /* Override padding for "table.docutils td" with "! important".
- The right padding separates the table cells. */
- padding: 0 0.5em 0 0 ! important }
-
-.first {
- /* Override more specific margin styles with "! important". */
- margin-top: 0 ! important }
-
-.last, .with-subtitle {
- margin-bottom: 0 ! important }
-
-.hidden {
- display: none }
-
-a.toc-backref {
- text-decoration: none ;
- color: black }
-
-blockquote.epigraph {
- margin: 2em 5em ; }
-
-dl.docutils dd {
- margin-bottom: 0.5em }
-
-object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
- overflow: hidden;
-}
-
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
- font-weight: bold }
-*/
-
-div.abstract {
- margin: 2em 5em }
-
-div.abstract p.topic-title {
- font-weight: bold ;
- text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
- margin: 2em ;
- border: medium outset ;
- padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
- font-weight: bold ;
- font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title {
- color: red ;
- font-weight: bold ;
- font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
- compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
- margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
- margin-top: 0.5em }
-*/
-
-div.dedication {
- margin: 2em 5em ;
- text-align: center ;
- font-style: italic }
-
-div.dedication p.topic-title {
- font-weight: bold ;
- font-style: normal }
-
-div.figure {
- margin-left: 2em ;
- margin-right: 2em }
-
-div.footer, div.header {
- clear: both;
- font-size: smaller }
-
-div.line-block {
- display: block ;
- margin-top: 1em ;
- margin-bottom: 1em }
-
-div.line-block div.line-block {
- margin-top: 0 ;
- margin-bottom: 0 ;
- margin-left: 1.5em }
-
-div.sidebar {
- margin: 0 0 0.5em 1em ;
- border: medium outset ;
- padding: 1em ;
- background-color: #ffffee ;
- width: 40% ;
- float: right ;
- clear: right }
-
-div.sidebar p.rubric {
- font-family: sans-serif ;
- font-size: medium }
-
-div.system-messages {
- margin: 5em }
-
-div.system-messages h1 {
- color: red }
-
-div.system-message {
- border: medium outset ;
- padding: 1em }
-
-div.system-message p.system-message-title {
- color: red ;
- font-weight: bold }
-
-div.topic {
- margin: 2em }
-
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
- margin-top: 0.4em }
-
-h1.title {
- text-align: center }
-
-h2.subtitle {
- text-align: center }
-
-hr.docutils {
- width: 75% }
-
-img.align-left, .figure.align-left, object.align-left {
- clear: left ;
- float: left ;
- margin-right: 1em }
-
-img.align-right, .figure.align-right, object.align-right {
- clear: right ;
- float: right ;
- margin-left: 1em }
-
-img.align-center, .figure.align-center, object.align-center {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-.align-left {
- text-align: left }
-
-.align-center {
- clear: both ;
- text-align: center }
-
-.align-right {
- text-align: right }
-
-/* reset inner alignment in figures */
-div.align-right {
- text-align: left }
-
-/* div.align-center * { */
-/* text-align: left } */
-
-ol.simple, ul.simple {
- margin-bottom: 1em }
-
-ol.arabic {
- list-style: decimal }
-
-ol.loweralpha {
- list-style: lower-alpha }
-
-ol.upperalpha {
- list-style: upper-alpha }
-
-ol.lowerroman {
- list-style: lower-roman }
-
-ol.upperroman {
- list-style: upper-roman }
-
-p.attribution {
- text-align: right ;
- margin-left: 50% }
-
-p.caption {
- font-style: italic }
-
-p.credits {
- font-style: italic ;
- font-size: smaller }
-
-p.label {
- white-space: nowrap }
-
-p.rubric {
- font-weight: bold ;
- font-size: larger ;
- color: maroon ;
- text-align: center }
-
-p.sidebar-title {
- font-family: sans-serif ;
- font-weight: bold ;
- font-size: larger }
-
-p.sidebar-subtitle {
- font-family: sans-serif ;
- font-weight: bold }
-
-p.topic-title {
- font-weight: bold }
-
-pre.address {
- margin-bottom: 0 ;
- margin-top: 0 ;
- font: inherit }
-
-pre.literal-block, pre.doctest-block {
- margin-left: 2em ;
- margin-right: 2em }
-
-span.classifier {
- font-family: sans-serif ;
- font-style: oblique }
-
-span.classifier-delimiter {
- font-family: sans-serif ;
- font-weight: bold }
-
-span.interpreted {
- font-family: sans-serif }
-
-span.option {
- white-space: nowrap }
-
-span.pre {
- white-space: pre }
-
-span.problematic {
- color: red }
-
-span.section-subtitle {
- /* font-size relative to parent (h1..h6 element) */
- font-size: 80% }
-
-table.citation {
- border-left: solid 1px gray;
- margin-left: 1px }
-
-table.docinfo {
- margin: 2em 4em }
-
-table.docutils {
- margin-top: 0.5em ;
- margin-bottom: 0.5em }
-
-table.footnote {
- border-left: solid 1px black;
- margin-left: 1px }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
- padding-left: 0.5em ;
- padding-right: 0.5em ;
- vertical-align: top }
-
-table.docutils th.field-name, table.docinfo th.docinfo-name {
- font-weight: bold ;
- text-align: left ;
- white-space: nowrap ;
- padding-left: 0 }
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
- font-size: 100% }
-
-ul.auto-toc {
- list-style-type: none }
-
-</style>
-</head>
-<body>
-<div class="document" id="using-the-pyparsing-module">
-<h1 class="title">Using the pyparsing module</h1>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Author:</th>
-<td>Paul McGuire</td></tr>
-<tr><th class="docinfo-name">Address:</th>
-<td><pre class="address">
-<a class="first last reference external" href="mailto:ptmcg&#64;users.sourceforge.net">ptmcg&#64;users.sourceforge.net</a>
-</pre>
-</td></tr>
-<tr><th class="docinfo-name">Revision:</th>
-<td>2.0.1</td></tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>July, 2013</td></tr>
-<tr><th class="docinfo-name">Copyright:</th>
-<td>Copyright © 2003-2013 Paul McGuire.</td></tr>
-</tbody>
-</table>
-<table class="docutils field-list" frame="void" rules="none">
-<col class="field-name" />
-<col class="field-body" />
-<tbody valign="top">
-<tr class="field"><th class="field-name">abstract:</th><td class="field-body">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.</td>
-</tr>
-</tbody>
-</table>
-<div class="contents topic" id="contents">
-<p class="topic-title first">Contents</p>
-<ul class="auto-toc simple">
-<li><a class="reference internal" href="#steps-to-follow" id="id1">1&nbsp;&nbsp;&nbsp;Steps to follow</a><ul class="auto-toc">
-<li><a class="reference internal" href="#hello-world" id="id2">1.1&nbsp;&nbsp;&nbsp;Hello, World!</a></li>
-<li><a class="reference internal" href="#usage-notes" id="id3">1.2&nbsp;&nbsp;&nbsp;Usage notes</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#classes" id="id4">2&nbsp;&nbsp;&nbsp;Classes</a><ul class="auto-toc">
-<li><a class="reference internal" href="#classes-in-the-pyparsing-module" id="id5">2.1&nbsp;&nbsp;&nbsp;Classes in the pyparsing module</a></li>
-<li><a class="reference internal" href="#basic-parserelement-subclasses" id="id6">2.2&nbsp;&nbsp;&nbsp;Basic ParserElement subclasses</a></li>
-<li><a class="reference internal" href="#expression-subclasses" id="id7">2.3&nbsp;&nbsp;&nbsp;Expression subclasses</a></li>
-<li><a class="reference internal" href="#expression-operators" id="id8">2.4&nbsp;&nbsp;&nbsp;Expression operators</a></li>
-<li><a class="reference internal" href="#positional-subclasses" id="id9">2.5&nbsp;&nbsp;&nbsp;Positional subclasses</a></li>
-<li><a class="reference internal" href="#converter-subclasses" id="id10">2.6&nbsp;&nbsp;&nbsp;Converter subclasses</a></li>
-<li><a class="reference internal" href="#special-subclasses" id="id11">2.7&nbsp;&nbsp;&nbsp;Special subclasses</a></li>
-<li><a class="reference internal" href="#other-classes" id="id12">2.8&nbsp;&nbsp;&nbsp;Other classes</a></li>
-<li><a class="reference internal" href="#exception-classes-and-troubleshooting" id="id13">2.9&nbsp;&nbsp;&nbsp;Exception classes and Troubleshooting</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#miscellaneous-attributes-and-methods" id="id14">3&nbsp;&nbsp;&nbsp;Miscellaneous attributes and methods</a><ul class="auto-toc">
-<li><a class="reference internal" href="#helper-methods" id="id15">3.1&nbsp;&nbsp;&nbsp;Helper methods</a></li>
-<li><a class="reference internal" href="#helper-parse-actions" id="id16">3.2&nbsp;&nbsp;&nbsp;Helper parse actions</a></li>
-<li><a class="reference internal" href="#common-string-and-token-constants" id="id17">3.3&nbsp;&nbsp;&nbsp;Common string and token constants</a></li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section" id="steps-to-follow">
-<h1><a class="toc-backref" href="#id1">1&nbsp;&nbsp;&nbsp;Steps to follow</a></h1>
-<p>To parse an incoming data string, the client code must follow these steps:</p>
-<ol class="arabic simple">
-<li>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.</li>
-<li>Call <tt class="docutils literal">parseString()</tt> or <tt class="docutils literal">scanString()</tt> 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.</li>
-<li>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 <tt class="docutils literal">setResultsName()</tt>.</li>
-</ol>
-<div class="section" id="hello-world">
-<h2><a class="toc-backref" href="#id2">1.1&nbsp;&nbsp;&nbsp;Hello, World!</a></h2>
-<p>The following complete Python program will parse the greeting &quot;Hello, World!&quot;,
-or any other greeting of the form &quot;&lt;salutation&gt;, &lt;addressee&gt;!&quot;:</p>
-<pre class="literal-block">
-from pyparsing import Word, alphas
-
-greet = Word( alphas ) + &quot;,&quot; + Word( alphas ) + &quot;!&quot;
-greeting = greet.parseString( &quot;Hello, World!&quot; )
-print greeting
-</pre>
-<p>The parsed tokens are returned in the following form:</p>
-<pre class="literal-block">
-['Hello', ',', 'World', '!']
-</pre>
-</div>
-<div class="section" id="usage-notes">
-<h2><a class="toc-backref" href="#id3">1.2&nbsp;&nbsp;&nbsp;Usage notes</a></h2>
-<ul>
-<li><p class="first">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 (&quot;screen
-or report scraping&quot;). 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.</p>
-</li>
-<li><p class="first">To keep up the readability of your code, use <a class="reference internal" href="#operators">operators</a> such as <tt class="docutils literal">+</tt>, <tt class="docutils literal">|</tt>,
-<tt class="docutils literal">^</tt>, and <tt class="docutils literal">~</tt> to combine expressions. You can also combine
-string literals with ParseExpressions - they will be
-automatically converted to Literal objects. For example:</p>
-<pre class="literal-block">
-integer = Word( nums ) # simple unsigned integer
-variable = Word( alphas, max=1 ) # single letter variable, such as x, z, m, etc.
-arithOp = Word( &quot;+-*/&quot;, max=1 ) # arithmetic operators
-equation = variable + &quot;=&quot; + integer + arithOp + integer # will match &quot;x=2+2&quot;, etc.
-</pre>
-<p>In the definition of <tt class="docutils literal">equation</tt>, the string <tt class="docutils literal">&quot;=&quot;</tt> will get added as
-a <tt class="docutils literal"><span class="pre">Literal(&quot;=&quot;)</span></tt>, but in a more readable way.</p>
-</li>
-<li><p class="first">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 <tt class="docutils literal">equation</tt>, without having to clutter it up with
-extraneous <tt class="docutils literal">ws</tt> markers. The <tt class="docutils literal">equation</tt> grammar will successfully parse all of the
-following statements:</p>
-<pre class="literal-block">
-x=2+2
-x = 2+2
-a = 10 * 4
-r= 1234/ 100000
-</pre>
-<p>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 <tt class="docutils literal">e</tt> or <tt class="docutils literal">pi</tt>). See <tt class="docutils literal">fourFn.py</tt>, included in the examples directory.</p>
-</li>
-<li><p class="first">To modify pyparsing's default whitespace skipping, you can use one or
-more of the following methods:</p>
-<ul>
-<li><p class="first">use the static method <tt class="docutils literal">ParserElement.setDefaultWhitespaceChars</tt>
-to override the normal set of whitespace chars (' tn'). For instance
-when defining a grammar in which newlines are significant, you should
-call <tt class="docutils literal">ParserElement.setDefaultWhitespaceChars(' \t')</tt> to remove
-newline from the set of skippable whitespace characters. Calling
-this method will affect all pyparsing expressions defined afterward.</p>
-</li>
-<li><p class="first">call <tt class="docutils literal">leaveWhitespace()</tt> on individual expressions, to suppress the
-skipping of whitespace before trying to match the expression</p>
-</li>
-<li><p class="first">use <tt class="docutils literal">Combine</tt> to require that successive expressions must be
-adjacent in the input string. For instance, this expression:</p>
-<pre class="literal-block">
-real = Word(nums) + '.' + Word(nums)
-</pre>
-<p>will match &quot;3.14159&quot;, but will also match &quot;3 . 12&quot;. It will also
-return the matched results as ['3', '.', '14159']. By changing this
-expression to:</p>
-<pre class="literal-block">
-real = Combine( Word(nums) + '.' + Word(nums) )
-</pre>
-<p>it will not match numbers with embedded spaces, and it will return a
-single concatenated string '3.14159' as the parsed token.</p>
-</li>
-</ul>
-</li>
-<li><p class="first">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:</p>
-<ul class="simple">
-<li><tt class="docutils literal">expr*3</tt> is equivalent to <tt class="docutils literal">expr + expr + expr</tt></li>
-<li><tt class="docutils literal"><span class="pre">expr*(2,3)</span></tt> is equivalent to <tt class="docutils literal">expr + expr + Optional(expr)</tt></li>
-<li><tt class="docutils literal"><span class="pre">expr*(n,None)</span></tt> or <tt class="docutils literal"><span class="pre">expr*(n,)</span></tt> is equivalent
-to <tt class="docutils literal">expr*n + ZeroOrMore(expr)</tt> (read as &quot;at least n instances of expr&quot;)</li>
-<li><tt class="docutils literal"><span class="pre">expr*(None,n)</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">expr*(0,n)</span></tt>
-(read as &quot;0 to n instances of expr&quot;)</li>
-<li><tt class="docutils literal"><span class="pre">expr*(None,None)</span></tt> is equivalent to <tt class="docutils literal">ZeroOrMore(expr)</tt></li>
-<li><tt class="docutils literal"><span class="pre">expr*(1,None)</span></tt> is equivalent to <tt class="docutils literal">OneOrMore(expr)</tt></li>
-</ul>
-<p>Note that <tt class="docutils literal"><span class="pre">expr*(None,n)</span></tt> does not raise an exception if
-more than n exprs exist in the input stream; that is,
-<tt class="docutils literal"><span class="pre">expr*(None,n)</span></tt> does not enforce a maximum number of expr
-occurrences. If this behavior is desired, then write
-<tt class="docutils literal"><span class="pre">expr*(None,n)</span> + ~expr</tt>.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">MatchFirst</tt> 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 <tt class="docutils literal">^</tt> operator) - they will always
-match the longest expression, although they are more
-compute-intensive.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">Or</tt> expressions will evaluate all of the specified subexpressions
-to determine which is the &quot;best&quot; match, that is, which matches
-the longest string in the input data. In case of a tie, the
-left-most expression in the <tt class="docutils literal">Or</tt> list will win.</p>
-</li>
-<li><p class="first">If parsing the contents of an entire file, pass it to the
-<tt class="docutils literal">parseFile</tt> method using:</p>
-<pre class="literal-block">
-expr.parseFile( sourceFile )
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">ParseExceptions</tt> will report the location where an expected token
-or expression failed to match. For example, if we tried to use our
-&quot;Hello, World!&quot; parser to parse &quot;Hello World!&quot; (leaving out the separating
-comma), we would get an exception, with the message:</p>
-<pre class="literal-block">
-pyparsing.ParseException: Expected &quot;,&quot; (6), (1,7)
-</pre>
-<p>In the case of complex
-expressions, the reported location may not be exactly where you
-would expect. See more information under <a class="reference internal" href="#parseexception">ParseException</a> .</p>
-</li>
-<li><p class="first">Use the <tt class="docutils literal">Group</tt> 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).</p>
-</li>
-<li><p class="first">Punctuation may be significant for matching, but is rarely of
-much interest in the parsed results. Use the <tt class="docutils literal">suppress()</tt> method
-to keep these tokens from cluttering up your returned lists of
-tokens. For example, <tt class="docutils literal">delimitedList()</tt> 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.</p>
-</li>
-<li><p class="first">Parse actions can be used to convert values from strings to
-other data types (ints, floats, booleans, etc.).</p>
-</li>
-<li><p class="first">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 <tt class="docutils literal">setResultsName</tt> call:</p>
-<pre class="literal-block">
-stats = &quot;AVE:&quot; + realNum.setResultsName(&quot;average&quot;) + \
- &quot;MIN:&quot; + realNum.setResultsName(&quot;min&quot;) + \
- &quot;MAX:&quot; + realNum.setResultsName(&quot;max&quot;)
-</pre>
-<p>can now be written as this:</p>
-<pre class="literal-block">
-stats = &quot;AVE:&quot; + realNum(&quot;average&quot;) + \
- &quot;MIN:&quot; + realNum(&quot;min&quot;) + \
- &quot;MAX:&quot; + realNum(&quot;max&quot;)
-</pre>
-</li>
-<li><p class="first">Be careful when defining parse actions that modify global variables or
-data structures (as in <tt class="docutils literal">fourFn.py</tt>), especially for low level tokens
-or expressions that may occur within an <tt class="docutils literal">And</tt> expression; an early element
-of an <tt class="docutils literal">And</tt> may match, but the overall expression may fail.</p>
-</li>
-<li><p class="first">Performance of pyparsing may be slow for complex grammars and/or large
-input strings. The <a class="reference external" href="http://psyco.sourceforge.net/">psyco</a> 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.</p>
-</li>
-</ul>
-</div>
-</div>
-<div class="section" id="classes">
-<h1><a class="toc-backref" href="#id4">2&nbsp;&nbsp;&nbsp;Classes</a></h1>
-<div class="section" id="classes-in-the-pyparsing-module">
-<h2><a class="toc-backref" href="#id5">2.1&nbsp;&nbsp;&nbsp;Classes in the pyparsing module</a></h2>
-<p><tt class="docutils literal">ParserElement</tt> - abstract base class for all pyparsing classes;
-methods for code to use are:</p>
-<ul>
-<li><p class="first"><tt class="docutils literal">parseString( sourceString, parseAll=False )</tt> - only called once, on the overall
-matching pattern; returns a <a class="reference internal" href="#parseresults">ParseResults</a> 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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">parseFile( sourceFile )</tt> - a convenience function, that accepts an
-input file object or filename. The file contents are passed as a
-string to <tt class="docutils literal">parseString()</tt>. <tt class="docutils literal">parseFile</tt> also supports the <tt class="docutils literal">parseAll</tt> argument.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">scanString( sourceString )</tt> - generator function, used to find and
-extract matching text in the given source string; for each matched text,
-returns a tuple of:</p>
-<ul class="simple">
-<li>matched tokens (packaged as a <a class="reference internal" href="#parseresults">ParseResults</a> object)</li>
-<li>start location of the matched text in the given source string</li>
-<li>end location in the given source string</li>
-</ul>
-<p><tt class="docutils literal">scanString</tt> 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 <tt class="docutils literal">parseString</tt>).</p>
-</li>
-<li><p class="first"><tt class="docutils literal">transformString( sourceString )</tt> - convenience wrapper function for
-<tt class="docutils literal">scanString</tt>, to process the input source string, and replace matching
-text with the tokens returned from parse actions defined in the grammar
-(see <a class="reference internal" href="#setparseaction">setParseAction</a>).</p>
-</li>
-<li><p class="first"><tt class="docutils literal">searchString( sourceString )</tt> - another convenience wrapper function for
-<tt class="docutils literal">scanString</tt>, returns a list of the matching tokens returned from each
-call to <tt class="docutils literal">scanString</tt>.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setName( name )</tt> - associate a short descriptive name for this
-element, useful in displaying exceptions and trace information</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setResultsName( string, listAllMatches=False )</tt> - name to be given
-to tokens matching
-the element; if multiple tokens within
-a repetition group (such as <tt class="docutils literal">ZeroOrMore</tt> or <tt class="docutils literal">delimitedList</tt>) 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:
-<tt class="docutils literal">setResultsName</tt> returns a <em>copy</em> of the element so that a single
-basic element can be referenced multiple times and given
-different names within a complex grammar.</p>
-</li>
-</ul>
-<ul id="setparseaction">
-<li><p class="first"><tt class="docutils literal">setParseAction( *fn )</tt> - specify one or more functions to call after successful
-matching of the element; each function is defined as <tt class="docutils literal">fn( s,
-loc, toks )</tt>, where:</p>
-<ul class="simple">
-<li><tt class="docutils literal">s</tt> is the original parse string</li>
-<li><tt class="docutils literal">loc</tt> is the location in the string where matching started</li>
-<li><tt class="docutils literal">toks</tt> is the list of the matched tokens, packaged as a <a class="reference internal" href="#parseresults">ParseResults</a> object</li>
-</ul>
-<p>Multiple functions can be attached to a ParserElement by specifying multiple
-arguments to setParseAction, or by calling setParseAction multiple times.</p>
-<p>Each parse action function can return a modified <tt class="docutils literal">toks</tt> list, to perform conversion, or
-string modifications. For brevity, <tt class="docutils literal">fn</tt> may also be a
-lambda - here is an example of using a parse action to convert matched
-integer tokens from strings to integers:</p>
-<pre class="literal-block">
-intNumber = Word(nums).setParseAction( lambda s,l,t: [ int(t[0]) ] )
-</pre>
-<p>If <tt class="docutils literal">fn</tt> does not modify the <tt class="docutils literal">toks</tt> list, it does not need to return
-anything at all.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setBreak( breakFlag=True )</tt> - if breakFlag is True, calls pdb.set_break()
-as this expression is about to be parsed</p>
-</li>
-<li><p class="first"><tt class="docutils literal">copy()</tt> - 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">leaveWhitespace()</tt> - change default behavior of skipping
-whitespace before starting matching (mostly used internally to the
-pyparsing module, rarely used by client code)</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setWhitespaceChars( chars )</tt> - 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)</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setDefaultWhitespaceChars( chars )</tt> - 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)</p>
-</li>
-<li><p class="first"><tt class="docutils literal">suppress()</tt> - convenience function to suppress the output of the
-given element, instead of wrapping it with a Suppress object.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">ignore( expr )</tt> - 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">setDebug( dbgFlag=True )</tt> - function to enable/disable tracing output
-when trying to match this element</p>
-</li>
-<li><p class="first"><tt class="docutils literal">validate()</tt> - function to verify that the defined grammar does not
-contain infinitely recursive constructs</p>
-</li>
-</ul>
-<ul class="simple" id="parsewithtabs">
-<li><tt class="docutils literal">parseWithTabs()</tt> - 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 <a class="reference internal" href="#white">White</a> class.</li>
-<li><tt class="docutils literal">enablePackrat()</tt> - a class-level static method to enable a memoizing
-performance enhancement, known as &quot;packrat parsing&quot;. 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 &quot;compile as you go&quot;, 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.</li>
-</ul>
-</div>
-<div class="section" id="basic-parserelement-subclasses">
-<h2><a class="toc-backref" href="#id6">2.2&nbsp;&nbsp;&nbsp;Basic ParserElement subclasses</a></h2>
-<ul class="simple">
-<li><tt class="docutils literal">Literal</tt> - construct with a string to be matched exactly</li>
-<li><tt class="docutils literal">CaselessLiteral</tt> - 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</li>
-<li><tt class="docutils literal">Keyword</tt> - 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</li>
-<li><tt class="docutils literal">CaselessKeyword</tt> - similar to Keyword, but with caseless matching
-behavior</li>
-</ul>
-<ul id="word">
-<li><p class="first"><tt class="docutils literal">Word</tt> - 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, <tt class="docutils literal">a</tt>, <tt class="docutils literal">i</tt>, <tt class="docutils literal">MAX_LENGTH</tt>, <tt class="docutils literal">_a1</tt>, <tt class="docutils literal">b_109_</tt>, and
-<tt class="docutils literal">plan9FromOuterSpace</tt>
-are all valid identifiers; <tt class="docutils literal">9b7z</tt>, <tt class="docutils literal">$a</tt>, <tt class="docutils literal">.section</tt>, and <tt class="docutils literal">0debug</tt>
-are not. To
-define an identifier using a Word, use either of the following:</p>
-<pre class="literal-block">
-- Word( alphas+&quot;_&quot;, alphanums+&quot;_&quot; )
-- Word( srange(&quot;[a-zA-Z_]&quot;), srange(&quot;[a-zA-Z0-9_]&quot;) )
-</pre>
-<p>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:</p>
-<pre class="literal-block">
-- Word( &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ_&quot; )
-- Word( srange(&quot;[A-Z_]&quot;) )
-</pre>
-<p>A Word may
-also be constructed with any of the following optional parameters:</p>
-<ul class="simple">
-<li><tt class="docutils literal">min</tt> - indicating a minimum length of matching characters</li>
-<li><tt class="docutils literal">max</tt> - indicating a maximum length of matching characters</li>
-<li><tt class="docutils literal">exact</tt> - indicating an exact length of matching characters</li>
-</ul>
-<p>If exact is specified, it will override any values for min or max.</p>
-<p>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 <tt class="docutils literal">excludeChars</tt> 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 <tt class="docutils literal">Word</tt>.
-With this change, you can just create <tt class="docutils literal">Word(printables, <span class="pre">excludeChars='.')</span></tt>.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">CharsNotIn</tt> - similar to <a class="reference internal" href="#word">Word</a>, 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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">Regex</tt> - 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 <a class="reference internal" href="#parseresults">ParseResults</a></p>
-</li>
-<li><p class="first"><tt class="docutils literal">QuotedString</tt> - 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:</p>
-<ul class="simple">
-<li><tt class="docutils literal">quoteChar</tt> - string of one or more characters defining the quote delimiting string</li>
-<li><tt class="docutils literal">escChar</tt> - character to escape quotes, typically backslash (default=None)</li>
-<li><tt class="docutils literal">escQuote</tt> - special quote sequence to escape an embedded quote string (such as SQL's &quot;&quot; to escape an embedded &quot;) (default=None)</li>
-<li><tt class="docutils literal">multiline</tt> - boolean indicating whether quotes can span multiple lines (default=<tt class="docutils literal">False</tt>)</li>
-<li><tt class="docutils literal">unquoteResults</tt> - boolean indicating whether the matched text should be unquoted (default=<tt class="docutils literal">True</tt>)</li>
-<li><tt class="docutils literal">endQuoteChar</tt> - string of one or more characters defining the end of the quote delimited string (default=None =&gt; same as quoteChar)</li>
-</ul>
-</li>
-<li><p class="first"><tt class="docutils literal">SkipTo</tt> - skips ahead in the input string, accepting any
-characters up to the specified pattern; may be constructed with
-the following optional parameters:</p>
-<ul class="simple">
-<li><tt class="docutils literal">include</tt> - if set to true, also consumes the match expression
-(default is <tt class="docutils literal">False</tt>)</li>
-<li><tt class="docutils literal">ignore</tt> - allows the user to specify patterns to not be matched,
-to prevent false matches</li>
-<li><tt class="docutils literal">failOn</tt> - if a literal string or expression is given for this argument, it defines an expression that
-should cause the <tt class="docutils literal">SkipTo</tt> expression to fail, and not skip over that expression</li>
-</ul>
-</li>
-</ul>
-<ul class="simple" id="white">
-<li><tt class="docutils literal">White</tt> - also similar to <a class="reference internal" href="#word">Word</a>, 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
-<a class="reference internal" href="#parsewithtabs">parseWithTabs</a> on the top-level parse element.)</li>
-<li><tt class="docutils literal">Empty</tt> - a null expression, requiring no characters - will always
-match; useful for debugging and for specialized grammars</li>
-<li><tt class="docutils literal">NoMatch</tt> - opposite of Empty, will never match; useful for debugging
-and for specialized grammars</li>
-</ul>
-</div>
-<div class="section" id="expression-subclasses">
-<h2><a class="toc-backref" href="#id7">2.3&nbsp;&nbsp;&nbsp;Expression subclasses</a></h2>
-<ul>
-<li><p class="first"><tt class="docutils literal">And</tt> - 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:</p>
-<pre class="literal-block">
-ipAddress = Word(nums) + ('.'+Word(nums))*3
-</pre>
-<p>A tuple can be used as the multiplier, indicating a min/max:</p>
-<pre class="literal-block">
-usPhoneNumber = Word(nums) + ('-'+Word(nums))*(1,2)
-</pre>
-<p>A special form of <tt class="docutils literal">And</tt> 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:</p>
-<pre class="literal-block">
-strictIpAddress = Word(nums) - ('.'+Word(nums))*3
-</pre>
-<p>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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">Or</tt> - 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">MatchFirst</tt> - 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">Each</tt> - 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 '&amp;' operator</p>
-</li>
-<li><p class="first"><tt class="docutils literal">Optional</tt> - construct with a ParserElement, but this element is
-not required to match; can be constructed with an optional <tt class="docutils literal">default</tt> 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">ZeroOrMore</tt> - similar to Optional, but can be repeated</p>
-</li>
-<li><p class="first"><tt class="docutils literal">OneOrMore</tt> - similar to ZeroOrMore, but at least one match must
-be present</p>
-</li>
-<li><p class="first"><tt class="docutils literal">FollowedBy</tt> - a lookahead expression, requires matching of the given
-expressions, but does not advance the parsing position within the input string</p>
-</li>
-<li><p class="first"><tt class="docutils literal">NotAny</tt> - 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</p>
-</li>
-</ul>
-</div>
-<div class="section" id="expression-operators">
-<span id="operators"></span><h2><a class="toc-backref" href="#id8">2.4&nbsp;&nbsp;&nbsp;Expression operators</a></h2>
-<ul class="simple">
-<li><tt class="docutils literal">~</tt> - creates NotAny using the expression after the operator</li>
-<li><tt class="docutils literal">+</tt> - creates And using the expressions before and after the operator</li>
-<li><tt class="docutils literal">|</tt> - creates MatchFirst (first left-to-right match) using the expressions before and after the operator</li>
-<li><tt class="docutils literal">^</tt> - creates Or (longest match) using the expressions before and after the operator</li>
-<li><tt class="docutils literal">&amp;</tt> - creates Each using the expressions before and after the operator</li>
-<li><tt class="docutils literal">*</tt> - 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 &quot;{min,max}&quot; form in regular expressions); if
-min is None, intepret as (0,max); if max is None, interpret as
-expr*min + ZeroOrMore(expr)</li>
-<li><tt class="docutils literal">-</tt> - like <tt class="docutils literal">+</tt> but with no backup and retry of alternatives</li>
-<li><tt class="docutils literal">*</tt> - repetition of expression</li>
-<li><tt class="docutils literal">==</tt> - matching expression to string; returns True if the string matches the given expression</li>
-<li><tt class="docutils literal">&lt;&lt;=</tt> - inserts the expression following the operator as the body of the
-Forward expression before the operator (formerly &lt;&lt;, which is now deprecated)</li>
-</ul>
-</div>
-<div class="section" id="positional-subclasses">
-<h2><a class="toc-backref" href="#id9">2.5&nbsp;&nbsp;&nbsp;Positional subclasses</a></h2>
-<ul class="simple">
-<li><tt class="docutils literal">StringStart</tt> - matches beginning of the text</li>
-<li><tt class="docutils literal">StringEnd</tt> - matches the end of the text</li>
-<li><tt class="docutils literal">LineStart</tt> - matches beginning of a line (lines delimited by <tt class="docutils literal">\n</tt> characters)</li>
-<li><tt class="docutils literal">LineEnd</tt> - matches the end of a line</li>
-<li><tt class="docutils literal">WordStart</tt> - matches a leading word boundary</li>
-<li><tt class="docutils literal">WordEnd</tt> - matches a trailing word boundary</li>
-</ul>
-</div>
-<div class="section" id="converter-subclasses">
-<h2><a class="toc-backref" href="#id10">2.6&nbsp;&nbsp;&nbsp;Converter subclasses</a></h2>
-<ul class="simple">
-<li><tt class="docutils literal">Upcase</tt> - converts matched tokens to uppercase (deprecated -
-use <tt class="docutils literal">upcaseTokens</tt> parse action instead)</li>
-<li><tt class="docutils literal">Combine</tt> - joins all matched tokens into a single string, using
-specified joinString (default <tt class="docutils literal"><span class="pre">joinString=&quot;&quot;</span></tt>); expects
-all matching tokens to be adjacent, with no intervening
-whitespace (can be overridden by specifying <tt class="docutils literal">adjacent=False</tt> in constructor)</li>
-<li><tt class="docutils literal">Suppress</tt> - clears matched tokens; useful to keep returned
-results from being cluttered with required but uninteresting
-tokens (such as list delimiters)</li>
-</ul>
-</div>
-<div class="section" id="special-subclasses">
-<h2><a class="toc-backref" href="#id11">2.7&nbsp;&nbsp;&nbsp;Special subclasses</a></h2>
-<ul class="simple">
-<li><tt class="docutils literal">Group</tt> - causes the matched tokens to be enclosed in a list;
-useful in repeated elements like <tt class="docutils literal">ZeroOrMore</tt> and <tt class="docutils literal">OneOrMore</tt> to
-break up matched tokens into groups for each repeated pattern</li>
-<li><tt class="docutils literal">Dict</tt> - like <tt class="docutils literal">Group</tt>, 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</li>
-<li><tt class="docutils literal">SkipTo</tt> - catch-all matching expression that accepts all characters
-up until the given pattern is found to match; useful for specifying
-incomplete grammars</li>
-<li><tt class="docutils literal">Forward</tt> - placeholder token used to define recursive token
-patterns; when defining the actual expression later in the
-program, insert it into the <tt class="docutils literal">Forward</tt> object using the <tt class="docutils literal">&lt;&lt;=</tt>
-operator (see <tt class="docutils literal">fourFn.py</tt> for an example).</li>
-</ul>
-</div>
-<div class="section" id="other-classes">
-<h2><a class="toc-backref" href="#id12">2.8&nbsp;&nbsp;&nbsp;Other classes</a></h2>
-<ul id="parseresults">
-<li><p class="first"><tt class="docutils literal">ParseResults</tt> - 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:</p>
-<ul class="simple">
-<li>as a list<ul>
-<li>total list of elements can be found using len()</li>
-<li>individual elements can be found using [0], [1], [-1], etc.</li>
-<li>elements can be deleted using <tt class="docutils literal">del</tt></li>
-<li>the -1th element can be extracted and removed in a single operation
-using <tt class="docutils literal">pop()</tt>, or any element can be extracted and removed
-using <tt class="docutils literal">pop(n)</tt></li>
-</ul>
-</li>
-<li>as a dictionary<ul>
-<li>if <tt class="docutils literal">setResultsName()</tt> is used to name elements within the
-overall parse expression, then these fields can be referenced
-as dictionary elements or as attributes</li>
-<li>the Dict class generates dictionary entries using the data of the
-input text - in addition to ParseResults listed as <tt class="docutils literal">[ [ a1, b1, c1, <span class="pre">...],</span> [ a2, b2, c2, <span class="pre">...]</span>&nbsp; ]</tt>
-it also acts as a dictionary with entries defined as <tt class="docutils literal">{ a1 : [ b1, c1, ... ] }, { a2 : [ b2, c2, ... ] }</tt>;
-this is especially useful when processing tabular data where the first column contains a key
-value for that line of data</li>
-<li>list elements that are deleted using <tt class="docutils literal">del</tt> will still be accessible by their
-dictionary keys</li>
-<li>supports <tt class="docutils literal">get()</tt>, <tt class="docutils literal">items()</tt> and <tt class="docutils literal">keys()</tt> methods, similar to a dictionary</li>
-<li>a keyed item can be extracted and removed using <tt class="docutils literal">pop(key)</tt>. Here
-key must be non-numeric (such as a string), in order to use dict
-extraction instead of list extraction.</li>
-<li>new named elements can be added (in a parse action, for instance), using the same
-syntax as adding an item to a dict (<tt class="docutils literal"><span class="pre">parseResults[&quot;X&quot;]=&quot;new</span> item&quot;</tt>); named elements can be removed using <tt class="docutils literal">del <span class="pre">parseResults[&quot;X&quot;]</span></tt></li>
-</ul>
-</li>
-<li>as a nested list<ul>
-<li>results returned from the Group class are encapsulated within their
-own list structure, so that the tokens can be handled as a hierarchical
-tree</li>
-</ul>
-</li>
-</ul>
-<p>ParseResults can also be converted to an ordinary list of strings
-by calling <tt class="docutils literal">asList()</tt>. Note that this will strip the results of any
-field names that have been defined for any embedded parse elements.
-(The <tt class="docutils literal">pprint</tt> module is especially good at printing out the nested contents
-given by <tt class="docutils literal">asList()</tt>.)</p>
-<p>Finally, ParseResults can be converted to an XML string by calling <tt class="docutils literal">asXML()</tt>. Where
-possible, results will be tagged using the results names defined for the respective
-ParseExpressions. <tt class="docutils literal">asXML()</tt> takes two optional arguments:</p>
-<ul class="simple">
-<li><tt class="docutils literal">doctagname</tt> - for ParseResults that do not have a defined name, this argument
-will wrap the resulting XML in a set of opening and closing tags <tt class="docutils literal">&lt;doctagname&gt;</tt>
-and <tt class="docutils literal">&lt;/doctagname&gt;</tt>.</li>
-<li><tt class="docutils literal">namedItemsOnly</tt> (default=<tt class="docutils literal">False</tt>) - 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.</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section" id="exception-classes-and-troubleshooting">
-<h2><a class="toc-backref" href="#id13">2.9&nbsp;&nbsp;&nbsp;Exception classes and Troubleshooting</a></h2>
-<ul id="parseexception">
-<li><p class="first"><tt class="docutils literal">ParseException</tt> - 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:</p>
-<pre class="literal-block">
-except ParseException, err:
- print err.line
- print &quot; &quot;*(err.column-1) + &quot;^&quot;
- print err
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">RecursiveGrammarException</tt> - exception returned by <tt class="docutils literal">validate()</tt> if
-the grammar contains a recursive infinite loop, such as:</p>
-<pre class="literal-block">
-badGrammar = Forward()
-goodToken = Literal(&quot;A&quot;)
-badGrammar &lt;&lt;= Optional(goodToken) + badGrammar
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">ParseFatalException</tt> - 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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">ParseSyntaxException</tt> - subclass of <tt class="docutils literal">ParseFatalException</tt> raised when a
-syntax error is found, based on the use of the '-' operator when defining
-a sequence of expressions in an <tt class="docutils literal">And</tt> expression.</p>
-</li>
-</ul>
-<p>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().</p>
-</div>
-</div>
-<div class="section" id="miscellaneous-attributes-and-methods">
-<h1><a class="toc-backref" href="#id14">3&nbsp;&nbsp;&nbsp;Miscellaneous attributes and methods</a></h1>
-<div class="section" id="helper-methods">
-<h2><a class="toc-backref" href="#id15">3.1&nbsp;&nbsp;&nbsp;Helper methods</a></h2>
-<ul>
-<li><p class="first"><tt class="docutils literal">delimitedList( expr, <span class="pre">delim=',')</span></tt> - 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 <tt class="docutils literal">combine=True</tt>,
-indicating that the expressions and delimiters should be returned as one
-combined value (useful for scoped variables, such as &quot;a.b.c&quot;, or
-&quot;a::b::c&quot;, or paths such as &quot;a/b/c&quot;).</p>
-</li>
-<li><p class="first"><tt class="docutils literal">countedArray( expr )</tt> - 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).</p>
-</li>
-<li><p class="first"><tt class="docutils literal">oneOf( string, caseless=False )</tt> - convenience function for quickly declaring an
-alternative set of <tt class="docutils literal">Literal</tt> 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 <tt class="docutils literal">caseless=True</tt>,
-will create an alternative set of CaselessLiteral tokens.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">dictOf( key, value )</tt> - convenience function for quickly declaring a
-dictionary pattern of <tt class="docutils literal">Dict( ZeroOrMore( Group( key + value ) ) )</tt>.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">makeHTMLTags( tagName )</tt> and <tt class="docutils literal">makeXMLTags( tagName )</tt> - convenience
-functions to create definitions of opening and closing tag expressions. Returns
-a pair of expressions, for the corresponding &lt;tag&gt; and &lt;/tag&gt; strings. Includes
-support for attributes in the opening tag, such as &lt;tag attr1=&quot;abc&quot;&gt; - attributes
-are returned as keyed tokens in the returned ParseResults. <tt class="docutils literal">makeHTMLTags</tt> is less
-restrictive than <tt class="docutils literal">makeXMLTags</tt>, especially with respect to case sensitivity.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">infixNotation(baseOperand, operatorList)</tt> - (formerly named <tt class="docutils literal">operatorPrecedence</tt>) convenience function to define a
-grammar for parsing infix notation
-expressions with a hierarchical precedence of operators. To use the <tt class="docutils literal">infixNotation</tt>
-helper:</p>
-<ol class="arabic simple">
-<li>Define the base &quot;atom&quot; 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 <tt class="docutils literal">infixNotation</tt> method.</li>
-<li>Define a list of tuples for each level of operator
-precendence. Each tuple is of the form
-<tt class="docutils literal">(opExpr, numTerms, rightLeftAssoc, parseAction)</tt>, where:<ul>
-<li><tt class="docutils literal">opExpr</tt> 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 &quot;y = mx + b&quot;.
-If <tt class="docutils literal">numTerms</tt> parameter is 3, this must be a 2-tuple containing the 2 delimiting operators.</li>
-<li><tt class="docutils literal">numTerms</tt> is the number of terms for this operator (must
-be 1,2, or 3)</li>
-<li><tt class="docutils literal">rightLeftAssoc</tt> is the indicator whether the operator is
-right or left associative, using the pyparsing-defined
-constants <tt class="docutils literal">opAssoc.RIGHT</tt> and <tt class="docutils literal">opAssoc.LEFT</tt>.</li>
-<li><tt class="docutils literal">parseAction</tt> is the parse action to be associated with
-expressions matching this operator expression (the
-parse action tuple member may be omitted)</li>
-</ul>
-</li>
-<li>Call <tt class="docutils literal">infixNotation</tt> 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.</li>
-</ol>
-</li>
-<li><p class="first"><tt class="docutils literal">matchPreviousLiteral</tt> and <tt class="docutils literal">matchPreviousExpr</tt> - function to define and
-expression that matches the same content
-as was parsed in a previous parse expression. For instance:</p>
-<pre class="literal-block">
-first = Word(nums)
-matchExpr = first + &quot;:&quot; + matchPreviousLiteral(first)
-</pre>
-<p>will match &quot;1:1&quot;, but not &quot;1:2&quot;. Since this matches at the literal
-level, this will also match the leading &quot;1:1&quot; in &quot;1:10&quot;.</p>
-<p>In contrast:</p>
-<pre class="literal-block">
-first = Word(nums)
-matchExpr = first + &quot;:&quot; + matchPreviousExpr(first)
-</pre>
-<p>will <em>not</em> match the leading &quot;1:1&quot; in &quot;1:10&quot;; the expressions are
-evaluated first, and then compared, so &quot;1&quot; is compared with &quot;10&quot;.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">nestedExpr(opener, closer, content=None, ignoreExpr=quotedString)</tt> - method for defining nested
-lists enclosed in opening and closing delimiters.</p>
-<ul class="simple">
-<li><tt class="docutils literal">opener</tt> - opening character for a nested list (default=&quot;(&quot;); can also be a pyparsing expression</li>
-<li><tt class="docutils literal">closer</tt> - closing character for a nested list (default=&quot;)&quot;); can also be a pyparsing expression</li>
-<li><tt class="docutils literal">content</tt> - expression for items within the nested lists (default=None)</li>
-<li><tt class="docutils literal">ignoreExpr</tt> - expression for ignoring opening and closing delimiters (default=quotedString)</li>
-</ul>
-<p>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.</p>
-<p>Use the <tt class="docutils literal">ignoreExpr</tt> 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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">indentedBlock( statementExpr, indentationStackVar, indent=True)</tt> -
-function to define an indented block of statements, similar to
-indentation-based blocking in Python source code:</p>
-<ul class="simple">
-<li><tt class="docutils literal">statementExpr</tt> - the expression defining a statement that
-will be found in the indented block; a valid indentedBlock
-must contain at least 1 matching statementExpr</li>
-<li><tt class="docutils literal">indentationStackVar</tt> - a Python list variable; this variable
-should be common to all <tt class="docutils literal">indentedBlock</tt> expressions defined
-within the same grammar, and should be reinitialized to [1]
-each time the grammar is to be used</li>
-<li><tt class="docutils literal">indent</tt> - 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</li>
-</ul>
-</li>
-</ul>
-<ul id="originaltextfor">
-<li><p class="first"><tt class="docutils literal">originalTextFor( expr )</tt> - 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:</p>
-<pre class="literal-block">
-fullName = Word(alphas) + Word(alphas)
-</pre>
-<p>will return the parse of &quot;John Smith&quot; 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 <tt class="docutils literal">originalTextFor</tt>:</p>
-<pre class="literal-block">
-fullName = originalTextFor(Word(alphas) + Word(alphas))
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">ungroup( expr )</tt> - function to &quot;ungroup&quot; 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)</p>
-</li>
-<li><p class="first"><tt class="docutils literal">lineno( loc, string )</tt> - function to give the line number of the
-location within the string; the first line is line 1, newlines
-start new rows</p>
-</li>
-<li><p class="first"><tt class="docutils literal">col( loc, string )</tt> - 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">line( loc, string )</tt> - function to retrieve the line of text
-representing <tt class="docutils literal">lineno( loc, string )</tt>; useful when printing out diagnostic
-messages for exceptions</p>
-</li>
-<li><p class="first"><tt class="docutils literal">srange( rangeSpec )</tt> - function to define a string of characters,
-given a string of the form used by regexp string ranges, such as <tt class="docutils literal"><span class="pre">&quot;[0-9]&quot;</span></tt> for
-all numeric digits, <tt class="docutils literal"><span class="pre">&quot;[A-Z_]&quot;</span></tt> for uppercase characters plus underscore, and
-so on (note that rangeSpec does not include support for generic regular
-expressions, just string range specs)</p>
-</li>
-<li><p class="first"><tt class="docutils literal">getTokensEndLoc()</tt> - function to call from within a parse action to get
-the ending location for the matched tokens</p>
-</li>
-<li><p class="first"><tt class="docutils literal">traceParseAction(fn)</tt> - decorator function to debug parse actions. Lists
-each call, called arguments, and return value or exception</p>
-</li>
-</ul>
-</div>
-<div class="section" id="helper-parse-actions">
-<h2><a class="toc-backref" href="#id16">3.2&nbsp;&nbsp;&nbsp;Helper parse actions</a></h2>
-<ul>
-<li><p class="first"><tt class="docutils literal">removeQuotes</tt> - removes the first and last characters of a quoted string;
-useful to remove the delimiting quotes from quoted strings</p>
-</li>
-<li><p class="first"><tt class="docutils literal">replaceWith(replString)</tt> - returns a parse action that simply returns the
-replString; useful when using transformString, or converting HTML entities, as in:</p>
-<pre class="literal-block">
-nbsp = Literal(&quot;&amp;nbsp;&quot;).setParseAction( replaceWith(&quot;&lt;BLANK&gt;&quot;) )
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">keepOriginalText</tt>- (deprecated, use <a class="reference internal" href="#originaltextfor">originalTextFor</a> 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.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">withAttribute( *args, **kwargs )</tt> - helper to create a validating parse action to be used with start tags created
-with <tt class="docutils literal">makeXMLTags</tt> or <tt class="docutils literal">makeHTMLTags</tt>. Use <tt class="docutils literal">withAttribute</tt> to qualify a starting tag
-with a required attribute value, to avoid false matches on common tags such as
-<tt class="docutils literal">&lt;TD&gt;</tt> or <tt class="docutils literal">&lt;DIV&gt;</tt>.</p>
-<p><tt class="docutils literal">withAttribute</tt> can be called with:</p>
-<ul class="simple">
-<li>keyword arguments, as in <tt class="docutils literal"><span class="pre">(class=&quot;Customer&quot;,align=&quot;right&quot;)</span></tt>, or</li>
-<li>a list of name-value tuples, as in <tt class="docutils literal">( (&quot;ns1:class&quot;, <span class="pre">&quot;Customer&quot;),</span> <span class="pre">(&quot;ns2:align&quot;,&quot;right&quot;)</span> )</tt></li>
-</ul>
-<p>An attribute can be specified to have the special value
-<tt class="docutils literal">withAttribute.ANY_VALUE</tt>, which will match any value - use this to
-ensure that an attribute is present but any attribute value is
-acceptable.</p>
-</li>
-<li><p class="first"><tt class="docutils literal">downcaseTokens</tt> - converts all matched tokens to lowercase</p>
-</li>
-<li><p class="first"><tt class="docutils literal">upcaseTokens</tt> - converts all matched tokens to uppercase</p>
-</li>
-<li><p class="first"><tt class="docutils literal">matchOnlyAtCol( columnNumber )</tt> - 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</p>
-</li>
-</ul>
-</div>
-<div class="section" id="common-string-and-token-constants">
-<h2><a class="toc-backref" href="#id17">3.3&nbsp;&nbsp;&nbsp;Common string and token constants</a></h2>
-<ul>
-<li><p class="first"><tt class="docutils literal">alphas</tt> - same as <tt class="docutils literal">string.letters</tt></p>
-</li>
-<li><p class="first"><tt class="docutils literal">nums</tt> - same as <tt class="docutils literal">string.digits</tt></p>
-</li>
-<li><p class="first"><tt class="docutils literal">alphanums</tt> - a string containing <tt class="docutils literal">alphas + nums</tt></p>
-</li>
-<li><p class="first"><tt class="docutils literal">alphas8bit</tt> - a string containing alphabetic 8-bit characters:</p>
-<pre class="literal-block">
-ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ
-</pre>
-</li>
-<li><p class="first"><tt class="docutils literal">printables</tt> - same as <tt class="docutils literal">string.printable</tt>, minus the space (<tt class="docutils literal">' '</tt>) character</p>
-</li>
-<li><p class="first"><tt class="docutils literal">empty</tt> - a global <tt class="docutils literal">Empty()</tt>; will always match</p>
-</li>
-<li><p class="first"><tt class="docutils literal">sglQuotedString</tt> - a string of characters enclosed in 's; may
-include whitespace, but not newlines</p>
-</li>
-<li><p class="first"><tt class="docutils literal">dblQuotedString</tt> - a string of characters enclosed in &quot;s; may
-include whitespace, but not newlines</p>
-</li>
-<li><p class="first"><tt class="docutils literal">quotedString</tt> - <tt class="docutils literal">sglQuotedString | dblQuotedString</tt></p>
-</li>
-<li><p class="first"><tt class="docutils literal">cStyleComment</tt> - a comment block delimited by <tt class="docutils literal"><span class="pre">'/*'</span></tt> and <tt class="docutils literal"><span class="pre">'*/'</span></tt> sequences; can span
-multiple lines, but does not support nesting of comments</p>
-</li>
-<li><p class="first"><tt class="docutils literal">htmlComment</tt> - a comment block delimited by <tt class="docutils literal"><span class="pre">'&lt;!--'</span></tt> and <tt class="docutils literal"><span class="pre">'--&gt;'</span></tt> sequences; can span
-multiple lines, but does not support nesting of comments</p>
-</li>
-<li><p class="first"><tt class="docutils literal">commaSeparatedList</tt> - similar to <tt class="docutils literal">delimitedList</tt>, 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</p>
-</li>
-<li><p class="first"><tt class="docutils literal">restOfLine</tt> - all remaining printable characters up to but not including the next
-newline</p>
-</li>
-</ul>
-</div>
-</div>
-</div>
-</body>
-</html>
diff --git a/trunk/src/HowToUsePyparsing.txt b/trunk/src/HowToUsePyparsing.txt
deleted file mode 100644
index 71d5313..0000000
--- a/trunk/src/HowToUsePyparsing.txt
+++ /dev/null
@@ -1,993 +0,0 @@
-==========================
-Using the pyparsing module
-==========================
-
-:author: Paul McGuire
-:address: ptmcg@users.sourceforge.net
-
-:revision: 2.0.1
-:date: July, 2013
-
-:copyright: Copyright |copy| 2003-2013 Paul McGuire.
-
-.. |copy| unicode:: 0xA9
-
-: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.
-
-.. sectnum:: :depth: 4
-
-.. contents:: :depth: 4
-
-
-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. 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.
-
-3. 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()``.
-
-
-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', '!']
-
-
-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 (' \t\n'). 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.
-
-.. _psyco: http://psyco.sourceforge.net/
-
-
-Classes
-=======
-
-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:
-
-- ``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:
-
-- ``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.
-
-
-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:
-
-- ``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:
-
-- ``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
-
-
-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
-
-
-.. _operators:
-
-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
-
-
-
-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
-
-
-
-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)
-
-
-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).
-
-
-Other classes
--------------
-.. _ParseResults:
-
-- ``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.
-
-
-Exception classes and Troubleshooting
--------------------------------------
-
-.. _ParseException:
-
-- ``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().
-
-
-Miscellaneous attributes and methods
-====================================
-
-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. Define a list of tuples for each level of operator
- precendence. Each tuple is of the form
- ``(opExpr, numTerms, rightLeftAssoc, parseAction)``, where:
-
- - ``opExpr`` - 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".
-
- - ``numTerms`` - 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
- ``parseAction`` 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.
-
-- ``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:
-
-- ``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
-
-
-
-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
-
-
-
-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/trunk/src/LICENSE b/trunk/src/LICENSE
deleted file mode 100644
index bbc959e..0000000
--- a/trunk/src/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/trunk/src/MANIFEST.in_bdist b/trunk/src/MANIFEST.in_bdist
deleted file mode 100644
index 5f2b98b..0000000
--- a/trunk/src/MANIFEST.in_bdist
+++ /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/trunk/src/MANIFEST.in_src b/trunk/src/MANIFEST.in_src
deleted file mode 100644
index 5f2b98b..0000000
--- a/trunk/src/MANIFEST.in_src
+++ /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/trunk/src/README b/trunk/src/README
deleted file mode 100644
index dc959ec..0000000
--- a/trunk/src/README
+++ /dev/null
@@ -1,80 +0,0 @@
-====================================
-PyParsing -- A Python Parsing Module
-====================================
-
-Introduction
-============
-
-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. 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 )
-
-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 '^' operator
-definitions.
-
-The parsed results returned from 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
-
-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:
-
- python setup.py install
-
-(pyparsing requires Python 2.6 or later.)
-
-Or corresponding commands using pip, easy_install, or wheel:
-
- pip install pyparsing
-
- easy_install pyparsing
-
- wheel install pyparsing
-
-
-Documentation
-=============
-
-See:
-
- HowToUsePyparsing.html
-
-
-License
-=======
-
- MIT License. See header of pyparsing.py
-
-History
-=======
-
- See CHANGES file.
diff --git a/trunk/src/examples/0README.html b/trunk/src/examples/0README.html
deleted file mode 100644
index 303d44d..0000000
--- a/trunk/src/examples/0README.html
+++ /dev/null
@@ -1,309 +0,0 @@
-<HTML>
-<title>pyparsing Examples</title>
-<body>
-<h1>pyparsing Examples</h1>
-<p>
-This directory contains a number of Python scripts that can get you started in learning to use pyparsing.
-
-<ul>
-<li><a href="greeting.py">greeting.py</a><br>
-Parse "Hello, World!".
-</li>
-<p>
-
-<li><a href="greetingInKorean.py">greetingInKorean.py</a> <i>~ submission by June Kim</i><br>
-Unicode example to parse "Hello, World!" in Korean.
-</li>
-<p>
-
-<li><a href="greetingInGreek.py">greetingInGreek.py</a> <i>~ submission by ???</i><br>
-Unicode example to parse "Hello, World!" in Greek.
-</li>
-<p>
-
-<li><a href="holaMundo.py">holaMundo.py</a> <i>~ submission by Marco Alfonso</i><br>
-"Hello, World!" example translated to Spanish, from Marco Alfonso's blog.
-</li>
-<p>
-
-<li><a href="chemicalFormulas.py">chemicalFormulas.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="wordsToNum.py">wordsToNum.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="pythonGrammarparser.py">pythonGrammarparser.py</a> <i>~ suggested by JH Stovall</i><br>
-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.
-</li>
-<p>
-
-<li><a href="commasep.py">commasep.py</a><br>
-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(',').
-</li>
-<p>
-
-<li><a href="dictExample.py">dictExample.py</a><br>
-A demonstration of using the Dict class, to parse a table of ASCII tabulated data.
-</li>
-<p>
-
-<li><a href="dictExample2.py">dictExample2.py</a> <i>~ submission by Mike Kelly</i><br>
-An extended version of dictExample.py, in which Mike Kelly also parses the column headers, and generates a transposed version of the original table!
-</li>
-<p>
-
-<li><a href="scanExamples.py">scanExamples.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="urlExtractor.py">urlExtractor.py</a><br>
-Another example using scanString, this time to extract all HREF references found on Yahoo!'s home page, and return them as a dictionary.
-</li>
-<p>
-
-<li><a href="makeHTMLTagExample.py">makeHTMLTagExample.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="urlExtractorNew.py">urlExtractorNew.py</a><br>
-Another updated version of urlExtractor.py, using the new makeHTMLTags() method.
-</li>
-<p>
-
-<li><a href="fourFn.py">fourFn.py</a><br>
-A simple algebraic expression parser, that performs +,-,*,/, and ^ arithmetic operations. (With suggestions and bug-fixes graciously offered by Andrea Griffini.)
-</li>
-<p>
-
-<li><a href="SimpleCalc.py">SimpleCalc.py</a> <i>~ submission by Steven Siew</i><br>
-An interactive version of fourFn.py, with support for variables.
-</li>
-<p>
-
-<li><a href="LAParser.py">LAParser.py</a> <i>~ submission by Mike Ellis</i><br>
-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.
-</li>
-<p>
-
-<li><a href="configParse.py">configParse.py</a><br>
-A simple alternative to Python's ConfigParse module, demonstrating the use of the Dict class to return nested dictionary access to configuration values.
-</li>
-<p>
-
-<li><a href="getNTPservers.py">getNTPservers.py</a><br>
-Yet another scanString example, to read/extract the list of NTP servers from NIST's web site.
-</li>
-<p>
-
-<li><a href="getNTPserversNew.py">getNTPserversNew.py</a><br>
-An updated version of getNTPservers.py, using the new makeHTMLTags() method.
-</li>
-<p>
-
-<li><a href="httpServerLogParser.py">httpServerLogParser.py</a><br>
-Parser for Apache server log files.
-</li>
-<p>
-
-<li><a href="idlParse.py">idlParse.py</a><br>
-Parser for CORBA IDL files.
-</li>
-<p>
-
-<li><a href="mozillaCalendarParser.py">mozillaCalendarParser.py</a>
-<i>~ submission by Petri Savolainen</i><br>
-Parser for Mozilla calendar (*.ics) files.
-</li>
-<p>
-
-<li><a href="pgn.py">pgn.py</a> <i>~ submission by Alberto Santini</i><br>
-Parser for PGN (Portable Game Notation) files, the standard form for documenting the moves in chess games.
-</li>
-<p>
-
-<li><a href="simpleSQL.py">simpleSQL.py</a><br>
-A simple parser that will extract table and column names from SQL SELECT statements..
-</li>
-<p>
-
-<li><a href="dfmparse.py">dfmparse.py</a> <i>~ submission by Dan Griffith</i><br>
-Parser for Delphi forms.
-</li>
-<p>
-
-<li><a href="ebnf.py">ebnf.py / ebnftest.py</a> <i>~ submission by Seo Sanghyeon</i><br>
-An EBNF-compiler that reads EBNF and generates a pyparsing grammar! Including a test that compiles... EBNF itself!
-</li>
-<p>
-
-<li><a href="searchparser.py">searchparser.py</a> <i>~ submission by Steven Mooij and Rudolph Froger</i><br>
-An expression parser that parses search strings, with special keyword and expression operations using (), not, and, or, and quoted strings.
-</li>
-<p>
-
-<li><a href="sparser.py">sparser.py</a> <i>~ submission by Tim Cera</i><br>
-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.
-<p>
-See <a href="mayport_florida_8720220_data_def.txt">mayport_florida_8720220_data_def.txt</a> for an
-example configuration file.
-</li>
-<p>
-
-<li><a href="romanNumerals.py">romanNumerals.py</a><br>
-A Roman numeral generator and parser example, showing the power of parse actions
-to compile Roman numerals into their integer values.
-</li>
-<p>
-
-<li><a href="removeLineBreaks.py">removeLineBreaks.py</a><br>
-A string transformer that converts text files with hard line-breaks into one with line breaks
-only between paragraphs. Useful when converting downloads from
-<a href="http://www.gutenberg.org">Project Gutenberg</a> 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.
-<p>
-See <a href="Successful Methods of Public Speaking.txt">Successful Methods of Public Speaking.txt</a> and
-<a href="Successful Methods of Public Speaking(2).txt">Successful Methods of Public Speaking(2).txt</a> for a sample
-before and after (text file courtesy of Project Gutenberg).
-</li>
-<p>
-
-<li><a href="listAllMatches.py">listAllMatches.py</a><br>
-An example program showing the utility of the listAllMatches option when specifying results naming.
-</li>
-<p>
-
-<li><a href="linenoExample.py">linenoExample.py</a><br>
-An example program showing how to use the string location to extract line and column numbers, or the
-source line of text.
-</li>
-<p>
-
-<li><a href="parseListString.py">parseListString.py</a><br>
-An example program showing a progression of steps, how to parse a string representation of a Python
-list back into a true list.
-</li>
-<p>
-
-<li><a href="parsePythonValue.py">parsePythonValue.py</a><br>
-An extension of parseListString.py to parse tuples and dicts, including nested values,
-returning a Python value of the original type.
-</li>
-<p>
-
-<li><a href="indentedGrammarExample.py">indentedGrammarExample.py</a><br>
-An example program showing how to parse a grammar using indentation for grouping,
-such as is done in Python.
-</li>
-<p>
-
-<li><a href="simpleArith.py">simpleArith.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="simpleBool.py">simpleBool.py</a><br>
-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.
-</li>
-<p>
-
-<li><a href="simpleWiki.py">simpleWiki.py</a><br>
-An example program showing how to use transformString to implement a simple Wiki markup parser.
-</li>
-<p>
-
-<li><a href="sql2dot.py">sql2dot.py</a><i>~ submission by EnErGy [CSDX]</i><br>
-A nice graphing program that generates schema diagrams from SQL table definition statements.
-</li>
-<p>
-
-<li><a href="htmlStripper.py">htmlStripper.py</a><br>
-An example implementation of a common application, removing HTML markup tags from an HTML page,
-leaving just the text content.
-</li>
-<p>
-
-<li><a href="macroExpansion.py">macroExpansion.py</a><br>
-An example implementation of a simple preprocessor, that will read embedded macro definitions
-and replace macro references with the defined substitution string.
-</li>
-<p>
-
-<li><a href="sexpParser.py">sexpParser.py</a><br>
-A parser that uses a recursive grammar to parse S-expressions.
-</li>
-<p>
-
-<li><a href="nested.py">nested.py</a><br>
-An example using nestedExpr, a helper method to simplify definitions of expressions of nested lists.
-</li>
-<p>
-
-<li><a href="withAttribute.py">withAttribute.py</a><br>
-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 &lt;DIV&gt; and &lt;TD&gt;.
-</li>
-<p>
-
-<li><a href="stackish.py">stackish.py</a><br>
-A parser for the data representation format, Stackish.
-</li>
-<p>
-
-<li><a href="builtin_parse_action_demo.py">builtin_parse_action_demo.py</a><br>
-<b>New in version 1.5.7</b><br>
-Demonstration of using builtins (min, max, sum, len, etc.) as parse actions.
-</li>
-<p>
-
-<li><a href="antlr_grammar.py">antlr_grammar.py</a><i>~ submission by Luca DellOlio</i><br>
-<b>New in version 1.5.7</b><br>
-Pyparsing example parsing ANTLR .a files and generating a working pyparsing parser.
-</li>
-<p>
-
-<li><a href="shapes.py">shapes.py</a><br>
-<b>New in version 1.5.7</b><br>
-Parse actions example simple shape definition syntax, and returning the matched tokens as
-domain objects instead of just strings.
-</li>
-<p>
-
-<li><a href="datetimeParseActions.py">datetimeParseActions.py</a><br>
-<b>New in version 1.5.7</b><br>
-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.
-</li>
-<p>
-
-<li><a href="position.py">position.py</a><br>
-<b>New in version 1.5.7</b><br>
-Demonstration of a couple of different ways to capture the location a particular
-expression was found within the overall input string.
-</li>
-<p>
-
-
-</ul>
-
-</body></html>
diff --git a/trunk/src/examples/AcManForm.dfm b/trunk/src/examples/AcManForm.dfm
deleted file mode 100644
index db80f6a..0000000
--- a/trunk/src/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/trunk/src/examples/LAparser.py b/trunk/src/examples/LAparser.py
deleted file mode 100644
index ec75d6c..0000000
--- a/trunk/src/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/trunk/src/examples/Setup.ini b/trunk/src/examples/Setup.ini
deleted file mode 100644
index 4574b1c..0000000
--- a/trunk/src/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/trunk/src/examples/SimpleCalc.py b/trunk/src/examples/SimpleCalc.py
deleted file mode 100644
index 46a5dff..0000000
--- a/trunk/src/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/trunk/src/examples/SingleForm.dfm b/trunk/src/examples/SingleForm.dfm
deleted file mode 100644
index 7a52734..0000000
--- a/trunk/src/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/trunk/src/examples/TAP.py b/trunk/src/examples/TAP.py
deleted file mode 100644
index 139e47c..0000000
--- a/trunk/src/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/trunk/src/examples/__init__.py b/trunk/src/examples/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/trunk/src/examples/__init__.py
+++ /dev/null
diff --git a/trunk/src/examples/adventureEngine.py b/trunk/src/examples/adventureEngine.py
deleted file mode 100644
index be09770..0000000
--- a/trunk/src/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("<Crash!>")
- 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<b
- |
- A
-"""
-rooms = createRooms( roomMap )
-rooms["A"].desc = "You are standing on the front porch of a wooden shack."
-rooms["b"].desc = "You are in a garden."
-rooms["c"].desc = "You are in a kitchen."
-rooms["d"].desc = "You are on the back porch."
-rooms["e"].desc = "You are in a library."
-rooms["f"].desc = "You are on the patio."
-rooms["q"].desc = "You are sinking in quicksand. You're dead..."
-rooms["q"].gameOver = True
-
-# define global variables for referencing rooms
-frontPorch = rooms["A"]
-garden = rooms["b"]
-kitchen = rooms["c"]
-backPorch = rooms["d"]
-library = rooms["e"]
-patio = rooms["f"]
-
-# create items
-itemNames = """sword.diamond.apple.flower.coin.shovel.book.mirror.telescope.gold bar""".split(".")
-for itemName in itemNames:
- Item( itemName )
-Item.items["apple"].isDeadly = True
-Item.items["mirror"].isFragile = True
-Item.items["coin"].isVisible = False
-Item.items["shovel"].usableConditionTest = ( lambda p,t: p.room is garden )
-def useShovel(p,subj,target):
- coin = Item.items["coin"]
- if not coin.isVisible and coin in p.room.inv:
- coin.isVisible = True
-Item.items["shovel"].useAction = useShovel
-
-Item.items["telescope"].isTakeable = False
-def useTelescope(p,subj,target):
- print("You don't see anything.")
-Item.items["telescope"].useAction = useTelescope
-
-OpenableItem("treasure chest", Item.items["gold bar"])
-Item.items["chest"] = Item.items["treasure chest"]
-Item.items["chest"].isTakeable = False
-Item.items["chest"].cantTakeMessage = "It's too heavy!"
-
-OpenableItem("mailbox")
-Item.items["mailbox"].isTakeable = False
-Item.items["mailbox"].cantTakeMessage = "It's nailed to the wall!"
-
-putItemInRoom("mailbox", frontPorch)
-putItemInRoom("shovel", frontPorch)
-putItemInRoom("coin", garden)
-putItemInRoom("flower", garden)
-putItemInRoom("apple", library)
-putItemInRoom("mirror", library)
-putItemInRoom("telescope", library)
-putItemInRoom("book", kitchen)
-putItemInRoom("diamond", backPorch)
-putItemInRoom("treasure chest", patio)
-
-# create player
-plyr = Player("Bob")
-plyr.take( Item.items["sword"] )
-
-# start game
-playGame( plyr, frontPorch )
diff --git a/trunk/src/examples/antlr_grammar.py b/trunk/src/examples/antlr_grammar.py
deleted file mode 100644
index adf877e..0000000
--- a/trunk/src/examples/antlr_grammar.py
+++ /dev/null
@@ -1,218 +0,0 @@
-'''
-antlr_grammar.py
-
-Created on 4 sept. 2010
-
-@author: luca
-
-(Minor updates by Paul McGuire, June, 2012)
-'''
-from pyparsing import Word, ZeroOrMore, printables, Suppress, OneOrMore, Group, \
- LineEnd, Optional, White, originalTextFor, hexnums, nums, Combine, Literal, Keyword, \
- cStyleComment, Regex, Forward, MatchFirst, And, srange, oneOf, alphas, alphanums, \
- delimitedList
-
-# http://www.antlr.org/grammar/ANTLR/ANTLRv3.g
-
-# Tokens
-EOL = Suppress(LineEnd()) # $
-singleTextString = originalTextFor(ZeroOrMore(~EOL + (White(" \t") | Word(printables)))).leaveWhitespace()
-XDIGIT = hexnums
-INT = Word(nums)
-ESC = Literal('\\') + (oneOf(list(r'nrtbf\">'+"'")) | ('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/trunk/src/examples/antlr_grammar_tests.py b/trunk/src/examples/antlr_grammar_tests.py
deleted file mode 100644
index 31aab29..0000000
--- a/trunk/src/examples/antlr_grammar_tests.py
+++ /dev/null
@@ -1,85 +0,0 @@
-'''
-Created on 4 sept. 2010
-
-@author: luca
-'''
-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/trunk/src/examples/apicheck.py b/trunk/src/examples/apicheck.py
deleted file mode 100644
index 4315ac9..0000000
--- a/trunk/src/examples/apicheck.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# apicheck.py
-# A simple source code scanner for finding patterns of the form
-# [ procname1 $arg1 $arg2 ]
-# and verifying the number of arguments
-
-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/trunk/src/examples/btpyparse.py b/trunk/src/examples/btpyparse.py
deleted file mode 100644
index f3c11ae..0000000
--- a/trunk/src/examples/btpyparse.py
+++ /dev/null
@@ -1,128 +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.
-
-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("[\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/trunk/src/examples/builtin_parse_action_demo.py b/trunk/src/examples/builtin_parse_action_demo.py
deleted file mode 100644
index 3ec6af8..0000000
--- a/trunk/src/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/trunk/src/examples/cLibHeader.py b/trunk/src/examples/cLibHeader.py
deleted file mode 100644
index bb98521..0000000
--- a/trunk/src/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/trunk/src/examples/chemicalFormulas.py b/trunk/src/examples/chemicalFormulas.py
deleted file mode 100644
index ce66afd..0000000
--- a/trunk/src/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/trunk/src/examples/commasep.py b/trunk/src/examples/commasep.py
deleted file mode 100644
index 7696871..0000000
--- a/trunk/src/examples/commasep.py
+++ /dev/null
@@ -1,23 +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
-
-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/trunk/src/examples/configParse.py b/trunk/src/examples/configParse.py
deleted file mode 100644
index 769249c..0000000
--- a/trunk/src/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/trunk/src/examples/cpp_enum_parser.py b/trunk/src/examples/cpp_enum_parser.py
deleted file mode 100644
index cbd0932..0000000
--- a/trunk/src/examples/cpp_enum_parser.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# cpp_enum_parser.py
-#
-# Posted by Mark Tolenen 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/trunk/src/examples/datetimeParseActions.py b/trunk/src/examples/datetimeParseActions.py
deleted file mode 100644
index 26d96a3..0000000
--- a/trunk/src/examples/datetimeParseActions.py
+++ /dev/null
@@ -1,43 +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')
-
-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 = "'%d/%d/%d' 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
- 2000/13/1 # invalid month
- 1900/2/29 # 1900 was not a leap year
- 2000/2/29 # but 2000 was
- """) \ No newline at end of file
diff --git a/trunk/src/examples/deltaTime.py b/trunk/src/examples/deltaTime.py
deleted file mode 100644
index e38da00..0000000
--- a/trunk/src/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/trunk/src/examples/dfmparse.py b/trunk/src/examples/dfmparse.py
deleted file mode 100644
index 96afbad..0000000
--- a/trunk/src/examples/dfmparse.py
+++ /dev/null
@@ -1,176 +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 <pythondev - dang at lazytwinacres . net>"
-
-
-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:
- tf = sys.argv[1:]
- elif type(tf) == str:
- tf = [tf]
- testfiles = []
- for arg in tf:
- for i in glob.glob(arg):
- testfiles.append(i)
- 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)
-
- 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/trunk/src/examples/dhcpd_leases_parser.py b/trunk/src/examples/dhcpd_leases_parser.py
deleted file mode 100644
index 145e6ea..0000000
--- a/trunk/src/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/trunk/src/examples/dictExample.py b/trunk/src/examples/dictExample.py
deleted file mode 100644
index 5085aed..0000000
--- a/trunk/src/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/trunk/src/examples/dictExample2.py b/trunk/src/examples/dictExample2.py
deleted file mode 100644
index cae463b..0000000
--- a/trunk/src/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/trunk/src/examples/ebnf.py b/trunk/src/examples/ebnf.py
deleted file mode 100644
index 8dfcaea..0000000
--- a/trunk/src/examples/ebnf.py
+++ /dev/null
@@ -1,149 +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
-
-
-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/trunk/src/examples/ebnftest.py b/trunk/src/examples/ebnftest.py
deleted file mode 100644
index 32c7fed..0000000
--- a/trunk/src/examples/ebnftest.py
+++ /dev/null
@@ -1,66 +0,0 @@
-print('Importing pyparsing...')
-from pyparsing import *
-
-print('Constructing EBNF parser with pyparsing...')
-import ebnf
-import sets
-
-
-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 = sets.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/trunk/src/examples/eval_arith.py b/trunk/src/examples/eval_arith.py
deleted file mode 100644
index 9562253..0000000
--- a/trunk/src/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/trunk/src/examples/excelExpr.py b/trunk/src/examples/excelExpr.py
deleted file mode 100644
index 2700100..0000000
--- a/trunk/src/examples/excelExpr.py
+++ /dev/null
@@ -1,68 +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)
-ParserElement.enablePackrat()
-
-EQ,EXCL,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 = Regex(r"\-?\d+(\.\d+)?")
-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))
-""") \ No newline at end of file
diff --git a/trunk/src/examples/fourFn.py b/trunk/src/examples/fourFn.py
deleted file mode 100644
index 75f3909..0000000
--- a/trunk/src/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/trunk/src/examples/gen_ctypes.py b/trunk/src/examples/gen_ctypes.py
deleted file mode 100644
index 2c909e4..0000000
--- a/trunk/src/examples/gen_ctypes.py
+++ /dev/null
@@ -1,167 +0,0 @@
-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/trunk/src/examples/getNTPservers.py b/trunk/src/examples/getNTPservers.py
deleted file mode 100644
index bbf1d60..0000000
--- a/trunk/src/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("<td>")
-tdEnd = Suppress("</td>")
-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/trunk/src/examples/getNTPserversNew.py b/trunk/src/examples/getNTPserversNew.py
deleted file mode 100644
index 14e710c..0000000
--- a/trunk/src/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/trunk/src/examples/greeting.py b/trunk/src/examples/greeting.py
deleted file mode 100644
index 2e6b241..0000000
--- a/trunk/src/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/trunk/src/examples/greetingInGreek.py b/trunk/src/examples/greetingInGreek.py
deleted file mode 100644
index 07a8f0a..0000000
--- a/trunk/src/examples/greetingInGreek.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# vim:fileencoding=utf-8
-#
-# greetingInGreek.py
-#
-# Demonstration of the parsing module, on the prototypical "Hello, World!" example
-#
-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/trunk/src/examples/greetingInKorean.py b/trunk/src/examples/greetingInKorean.py
deleted file mode 100644
index d0ea0e5..0000000
--- a/trunk/src/examples/greetingInKorean.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# vim:fileencoding=utf-8
-#
-# greetingInKorean.py
-#
-# Demonstration of the parsing module, on the prototypical "Hello, World!" example
-#
-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/trunk/src/examples/groupUsingListAllMatches.py b/trunk/src/examples/groupUsingListAllMatches.py
deleted file mode 100644
index d5037b8..0000000
--- a/trunk/src/examples/groupUsingListAllMatches.py
+++ /dev/null
@@ -1,16 +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.
-#
-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*"))
-
-results = grammar.parseString("A1 B1 A2 C1 B2 A3")
-print(results.dump())
diff --git a/trunk/src/examples/holaMundo.py b/trunk/src/examples/holaMundo.py
deleted file mode 100644
index 357e3c8..0000000
--- a/trunk/src/examples/holaMundo.py
+++ /dev/null
@@ -1,30 +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í la 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"))
-
-# Excelente!!, bueno, los dejo, me voy a seguir tirando código…
diff --git a/trunk/src/examples/htmlStripper.py b/trunk/src/examples/htmlStripper.py
deleted file mode 100644
index 0b0f459..0000000
--- a/trunk/src/examples/htmlStripper.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# htmlStripper.py
-#
-# Sample code for stripping HTML markup tags and scripts from
-# HTML source files.
-#
-# Copyright (c) 2006, Paul McGuire
-#
-from pyparsing import *
-import urllib.request, urllib.parse, urllib.error
-
-removeText = replaceWith("")
-scriptOpen,scriptClose = makeHTMLTags("script")
-scriptBody = scriptOpen + SkipTo(scriptClose) + scriptClose
-scriptBody.setParseAction(removeText)
-
-anyTag,anyClose = makeHTMLTags(Word(alphas,alphanums+":_"))
-anyTag.setParseAction(removeText)
-anyClose.setParseAction(removeText)
-htmlComment.setParseAction(removeText)
-
-commonHTMLEntity.setParseAction(replaceHTMLEntity)
-
-# get some HTML
-targetURL = "http://wiki.python.org/moin/PythonDecoratorLibrary"
-targetPage = urllib.request.urlopen( targetURL )
-targetHTML = targetPage.read()
-targetPage.close()
-
-# first pass, strip out tags and translate entities
-firstPass = (htmlComment | scriptBody | commonHTMLEntity |
- anyTag | anyClose ).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/trunk/src/examples/httpServerLogParser.py b/trunk/src/examples/httpServerLogParser.py
deleted file mode 100644
index 1a808ae..0000000
--- a/trunk/src/examples/httpServerLogParser.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# httpServerLogParser.py
-#
-"""
-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/trunk/src/examples/idlParse.py b/trunk/src/examples/idlParse.py
deleted file mode 100644
index dd556e5..0000000
--- a/trunk/src/examples/idlParse.py
+++ /dev/null
@@ -1,222 +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 = Literal(":")
- lbrace = Literal("{")
- rbrace = Literal("}")
- lbrack = Literal("[")
- rbrack = Literal("]")
- lparen = Literal("(")
- rparen = Literal(")")
- equals = Literal("=")
- comma = Literal(",")
- dot = Literal(".")
- slash = Literal("/")
- bslash = Literal("\\")
- star = Literal("*")
- semi = Literal(";")
- langle = Literal("<")
- rangle = Literal(">")
-
- # keywords
- any_ = Keyword("any")
- attribute_ = Keyword("attribute")
- boolean_ = Keyword("boolean")
- case_ = Keyword("case")
- char_ = Keyword("char")
- const_ = Keyword("const")
- context_ = Keyword("context")
- default_ = Keyword("default")
- double_ = Keyword("double")
- enum_ = Keyword("enum")
- exception_ = Keyword("exception")
- false_ = Keyword("FALSE")
- fixed_ = Keyword("fixed")
- float_ = Keyword("float")
- inout_ = Keyword("inout")
- interface_ = Keyword("interface")
- in_ = Keyword("in")
- long_ = Keyword("long")
- module_ = Keyword("module")
- object_ = Keyword("Object")
- octet_ = Keyword("octet")
- oneway_ = Keyword("oneway")
- out_ = Keyword("out")
- raises_ = Keyword("raises")
- readonly_ = Keyword("readonly")
- sequence_ = Keyword("sequence")
- short_ = Keyword("short")
- string_ = Keyword("string")
- struct_ = Keyword("struct")
- switch_ = Keyword("switch")
- true_ = Keyword("TRUE")
- typedef_ = Keyword("typedef")
- unsigned_ = Keyword("unsigned")
- union_ = Keyword("union")
- void_ = Keyword("void")
- wchar_ = Keyword("wchar")
- wstring_ = Keyword("wstring")
-
- identifier = Word( alphas, alphanums + "_" ).setName("identifier")
-
- #~ real = Combine( Word(nums+"+-", nums) + dot + Optional( Word(nums) )
- #~ + Optional( CaselessLiteral("E") + Word(nums+"+-",nums) ) )
- real = Regex(r"[+-]?\d+\.\d*([Ee][+-]?\d+)?").setName("real")
- #~ integer = ( Combine( CaselessLiteral("0x") + Word( nums+"abcdefABCDEF" ) ) |
- #~ Word( nums+"+-", nums ) ).setName("int")
- integer = Regex(r"0x[0-9a-fA-F]+|[+-]?\d+").setName("int")
-
- udTypeName = delimitedList( identifier, "::", combine=True ).setName("udType")
- # have to use longest match for type, in case a user-defined type name starts with a keyword type, like "stringSeq" or "longArray"
- 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<string> stringSeq;
- typedef sequence< sequence<string> > 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<string> /*comment inside an And */ stringSeq;
- /* */ /**/ /***/ /****/
- typedef sequence< sequence<string> > 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<string> 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/trunk/src/examples/indentedGrammarExample.py b/trunk/src/examples/indentedGrammarExample.py
deleted file mode 100644
index 442e6a4..0000000
--- a/trunk/src/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/trunk/src/examples/invRegex.py b/trunk/src/examples/invRegex.py
deleted file mode 100644
index b6fe1f1..0000000
--- a/trunk/src/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):
- """Call this routine as a generator to return all the strings that
- match the input regular expression.
- for s in invert("[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/trunk/src/examples/javascript_grammar.g b/trunk/src/examples/javascript_grammar.g
deleted file mode 100644
index c30eac2..0000000
--- a/trunk/src/examples/javascript_grammar.g
+++ /dev/null
@@ -1,894 +0,0 @@
-/*
- Copyright 2008 Chris Lambrou.
- All rights reserved.
-*/
-
-grammar JavaScript;
-
-options
-{
- output=AST;
- backtrack=true;
- memoize=true;
-}
-
-program
- : LT!* sourceElements LT!* EOF!
- ;
-
-sourceElements
- : sourceElement (LT!* sourceElement)*
- ;
-
-sourceElement
- : functionDeclaration
- | statement
- ;
-
-// functions
-functionDeclaration
- : 'function' LT!* Identifier LT!* formalParameterList LT!* functionBody
- ;
-
-functionExpression
- : 'function' LT!* Identifier? LT!* formalParameterList LT!* functionBody
- ;
-
-formalParameterList
- : '(' (LT!* Identifier (LT!* ',' LT!* Identifier)*)? LT!* ')'
- ;
-
-functionBody
- : '{' LT!* sourceElements LT!* '}'
- ;
-
-// statements
-statement
- : statementBlock
- | variableStatement
- | emptyStatement
- | expressionStatement
- | ifStatement
- | iterationStatement
- | continueStatement
- | breakStatement
- | returnStatement
- | withStatement
- | labelledStatement
- | switchStatement
- | throwStatement
- | tryStatement
- ;
-
-statementBlock
- : '{' LT!* statementList? LT!* '}'
- ;
-
-statementList
- : statement (LT!* statement)*
- ;
-
-variableStatement
- : 'var' LT!* variableDeclarationList (LT | ';')!
- ;
-
-variableDeclarationList
- : variableDeclaration (LT!* ',' LT!* variableDeclaration)*
- ;
-
-variableDeclarationListNoIn
- : variableDeclarationNoIn (LT!* ',' LT!* variableDeclarationNoIn)*
- ;
-
-variableDeclaration
- : Identifier LT!* initialiser?
- ;
-
-variableDeclarationNoIn
- : Identifier LT!* initialiserNoIn?
- ;
-
-initialiser
- : '=' LT!* assignmentExpression
- ;
-
-initialiserNoIn
- : '=' LT!* assignmentExpressionNoIn
- ;
-
-emptyStatement
- : ';'
- ;
-
-expressionStatement
- : expression (LT | ';')!
- ;
-
-ifStatement
- : 'if' LT!* '(' LT!* expression LT!* ')' LT!* statement (LT!* 'else' LT!* statement)?
- ;
-
-iterationStatement
- : doWhileStatement
- | whileStatement
- | forStatement
- | forInStatement
- ;
-
-doWhileStatement
- : 'do' LT!* statement LT!* 'while' LT!* '(' expression ')' (LT | ';')!
- ;
-
-whileStatement
- : 'while' LT!* '(' LT!* expression LT!* ')' LT!* statement
- ;
-
-forStatement
- : 'for' LT!* '(' (LT!* forStatementInitialiserPart)? LT!* ';' (LT!* expression)? LT!* ';' (LT!* expression)? LT!* ')' LT!* statement
- ;
-
-forStatementInitialiserPart
- : expressionNoIn
- | 'var' LT!* variableDeclarationListNoIn
- ;
-
-forInStatement
- : 'for' LT!* '(' LT!* forInStatementInitialiserPart LT!* 'in' LT!* expression LT!* ')' LT!* statement
- ;
-
-forInStatementInitialiserPart
- : leftHandSideExpression
- | 'var' LT!* variableDeclarationNoIn
- ;
-
-continueStatement
- : 'continue' Identifier? (LT | ';')!
- ;
-
-breakStatement
- : 'break' Identifier? (LT | ';')!
- ;
-
-returnStatement
- : 'return' expression? (LT | ';')!
- ;
-
-withStatement
- : 'with' LT!* '(' LT!* expression LT!* ')' LT!* statement
- ;
-
-labelledStatement
- : Identifier LT!* ':' LT!* statement
- ;
-
-switchStatement
- : 'switch' LT!* '(' LT!* expression LT!* ')' LT!* caseBlock
- ;
-
-caseBlock
- : '{' (LT!* caseClause)* (LT!* defaultClause (LT!* caseClause)*)? LT!* '}'
- ;
-
-caseClause
- : 'case' LT!* expression LT!* ':' LT!* statementList?
- ;
-
-defaultClause
- : 'default' LT!* ':' LT!* statementList?
- ;
-
-throwStatement
- : 'throw' expression (LT | ';')!
- ;
-
-tryStatement
- : 'try' LT!* statementBlock LT!* (finallyClause | catchClause (LT!* finallyClause)?)
- ;
-
-catchClause
- : 'catch' LT!* '(' LT!* Identifier LT!* ')' LT!* statementBlock
- ;
-
-finallyClause
- : 'finally' LT!* statementBlock
- ;
-
-// expressions
-expression
- : assignmentExpression (LT!* ',' LT!* assignmentExpression)*
- ;
-
-expressionNoIn
- : assignmentExpressionNoIn (LT!* ',' LT!* assignmentExpressionNoIn)*
- ;
-
-assignmentExpression
- : conditionalExpression
- | leftHandSideExpression LT!* assignmentOperator LT!* assignmentExpression
- ;
-
-assignmentExpressionNoIn
- : conditionalExpressionNoIn
- | leftHandSideExpression LT!* assignmentOperator LT!* assignmentExpressionNoIn
- ;
-
-leftHandSideExpression
- : callExpression
- | newExpression
- ;
-
-newExpression
- : memberExpression
- | 'new' LT!* newExpression
- ;
-
-memberExpression
- : (primaryExpression | functionExpression | 'new' LT!* memberExpression LT!* arguments) (LT!* memberExpressionSuffix)*
- ;
-
-memberExpressionSuffix
- : indexSuffix
- | propertyReferenceSuffix
- ;
-
-callExpression
- : memberExpression LT!* arguments (LT!* callExpressionSuffix)*
- ;
-
-callExpressionSuffix
- : arguments
- | indexSuffix
- | propertyReferenceSuffix
- ;
-
-arguments
- : '(' (LT!* assignmentExpression (LT!* ',' LT!* assignmentExpression)*)? LT!* ')'
- ;
-
-indexSuffix
- : '[' LT!* expression LT!* ']'
- ;
-
-propertyReferenceSuffix
- : '.' LT!* Identifier
- ;
-
-assignmentOperator
- : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
- ;
-
-conditionalExpression
- : logicalORExpression (LT!* '?' LT!* assignmentExpression LT!* ':' LT!* assignmentExpression)?
- ;
-
-conditionalExpressionNoIn
- : logicalORExpressionNoIn (LT!* '?' LT!* assignmentExpressionNoIn LT!* ':' LT!* assignmentExpressionNoIn)?
- ;
-
-logicalORExpression
- : logicalANDExpression (LT!* '||' LT!* logicalANDExpression)*
- ;
-
-logicalORExpressionNoIn
- : logicalANDExpressionNoIn (LT!* '||' LT!* logicalANDExpressionNoIn)*
- ;
-
-logicalANDExpression
- : bitwiseORExpression (LT!* '&&' LT!* bitwiseORExpression)*
- ;
-
-logicalANDExpressionNoIn
- : bitwiseORExpressionNoIn (LT!* '&&' LT!* bitwiseORExpressionNoIn)*
- ;
-
-bitwiseORExpression
- : bitwiseXORExpression (LT!* '|' LT!* bitwiseXORExpression)*
- ;
-
-bitwiseORExpressionNoIn
- : bitwiseXORExpressionNoIn (LT!* '|' LT!* bitwiseXORExpressionNoIn)*
- ;
-
-bitwiseXORExpression
- : bitwiseANDExpression (LT!* '^' LT!* bitwiseANDExpression)*
- ;
-
-bitwiseXORExpressionNoIn
- : bitwiseANDExpressionNoIn (LT!* '^' LT!* bitwiseANDExpressionNoIn)*
- ;
-
-bitwiseANDExpression
- : equalityExpression (LT!* '&' LT!* equalityExpression)*
- ;
-
-bitwiseANDExpressionNoIn
- : equalityExpressionNoIn (LT!* '&' LT!* equalityExpressionNoIn)*
- ;
-
-equalityExpression
- : relationalExpression (LT!* ('==' | '!=' | '===' | '!==') LT!* relationalExpression)*
- ;
-
-equalityExpressionNoIn
- : relationalExpressionNoIn (LT!* ('==' | '!=' | '===' | '!==') LT!* relationalExpressionNoIn)*
- ;
-
-relationalExpression
- : shiftExpression (LT!* ('<' | '>' | '<=' | '>=' | 'instanceof' | 'in') LT!* shiftExpression)*
- ;
-
-relationalExpressionNoIn
- : shiftExpression (LT!* ('<' | '>' | '<=' | '>=' | 'instanceof') LT!* shiftExpression)*
- ;
-
-shiftExpression
- : additiveExpression (LT!* ('<<' | '>>' | '>>>') LT!* additiveExpression)*
- ;
-
-additiveExpression
- : multiplicativeExpression (LT!* ('+' | '-') LT!* multiplicativeExpression)*
- ;
-
-multiplicativeExpression
- : unaryExpression (LT!* ('*' | '/' | '%') LT!* unaryExpression)*
- ;
-
-unaryExpression
- : postfixExpression
- | ('delete' | 'void' | 'typeof' | '++' | '--' | '+' | '-' | '~' | '!') unaryExpression
- ;
-
-postfixExpression
- : leftHandSideExpression ('++' | '--')?
- ;
-
-primaryExpression
- : 'this'
- | Identifier
- | literal
- | arrayLiteral
- | objectLiteral
- | '(' LT!* expression LT!* ')'
- ;
-
-// arrayLiteral definition.
-arrayLiteral
- : '[' LT!* assignmentExpression? (LT!* ',' (LT!* assignmentExpression)?)* LT!* ']'
- ;
-
-// objectLiteral definition.
-objectLiteral
- : '{' LT!* propertyNameAndValue (LT!* ',' LT!* propertyNameAndValue)* LT!* '}'
- ;
-
-propertyNameAndValue
- : propertyName LT!* ':' LT!* assignmentExpression
- ;
-
-propertyName
- : Identifier
- | StringLiteral
- | NumericLiteral
- ;
-
-// primitive literal definition.
-literal
- : 'null'
- | 'true'
- | 'false'
- | StringLiteral
- | NumericLiteral
- ;
-
-// lexer rules.
-StringLiteral
- : '"' DoubleStringCharacter* '"'
- | '\'' SingleStringCharacter* '\''
- ;
-
-fragment DoubleStringCharacter
- : ~('"' | '\\' | LT)
- | '\\' EscapeSequence
- ;
-
-fragment SingleStringCharacter
- : ~('\'' | '\\' | LT)
- | '\\' EscapeSequence
- ;
-
-fragment EscapeSequence
- : CharacterEscapeSequence
- | '0'
- | HexEscapeSequence
- | UnicodeEscapeSequence
- ;
-
-fragment CharacterEscapeSequence
- : SingleEscapeCharacter
- | NonEscapeCharacter
- ;
-
-fragment NonEscapeCharacter
- : ~(EscapeCharacter | LT)
- ;
-
-fragment SingleEscapeCharacter
- : '\'' | '"' | '\\' | 'b' | 'f' | 'n' | 'r' | 't' | 'v'
- ;
-
-fragment EscapeCharacter
- : SingleEscapeCharacter
- | DecimalDigit
- | 'x'
- | 'u'
- ;
-
-fragment HexEscapeSequence
- : 'x' HexDigit HexDigit
- ;
-
-fragment UnicodeEscapeSequence
- : 'u' HexDigit HexDigit HexDigit HexDigit
- ;
-
-NumericLiteral
- : DecimalLiteral
- | HexIntegerLiteral
- ;
-
-fragment HexIntegerLiteral
- : '0' ('x' | 'X') HexDigit+
- ;
-
-fragment HexDigit
- : DecimalDigit | ('a'..'f') | ('A'..'F')
- ;
-
-fragment DecimalLiteral
- : DecimalDigit+ '.' DecimalDigit* ExponentPart?
- | '.'? DecimalDigit+ ExponentPart?
- ;
-
-fragment DecimalDigit
- : ('0'..'9')
- ;
-
-fragment ExponentPart
- : ('e' | 'E') ('+' | '-') ? DecimalDigit+
- ;
-
-Identifier
- : IdentifierStart IdentifierPart*
- ;
-
-fragment IdentifierStart
- : UnicodeLetter
- | '$'
- | '_'
- | '\\' UnicodeEscapeSequence
- ;
-
-fragment IdentifierPart
- : (IdentifierStart) => IdentifierStart // Avoids ambiguity, as some IdentifierStart chars also match following alternatives.
- | UnicodeDigit
- | UnicodeConnectorPunctuation
- ;
-
-fragment UnicodeLetter // Any character in the Unicode categories "Uppercase letter (Lu)",
- : '\u0041'..'\u005A' // "Lowercase letter (Ll)", "Titlecase letter (Lt)",
- | '\u0061'..'\u007A' // "Modifier letter (Lm)", "Other letter (Lo)", or "Letter number (Nl)".
- | '\u00AA'
- | '\u00B5'
- | '\u00BA'
- | '\u00C0'..'\u00D6'
- | '\u00D8'..'\u00F6'
- | '\u00F8'..'\u021F'
- | '\u0222'..'\u0233'
- | '\u0250'..'\u02AD'
- | '\u02B0'..'\u02B8'
- | '\u02BB'..'\u02C1'
- | '\u02D0'..'\u02D1'
- | '\u02E0'..'\u02E4'
- | '\u02EE'
- | '\u037A'
- | '\u0386'
- | '\u0388'..'\u038A'
- | '\u038C'
- | '\u038E'..'\u03A1'
- | '\u03A3'..'\u03CE'
- | '\u03D0'..'\u03D7'
- | '\u03DA'..'\u03F3'
- | '\u0400'..'\u0481'
- | '\u048C'..'\u04C4'
- | '\u04C7'..'\u04C8'
- | '\u04CB'..'\u04CC'
- | '\u04D0'..'\u04F5'
- | '\u04F8'..'\u04F9'
- | '\u0531'..'\u0556'
- | '\u0559'
- | '\u0561'..'\u0587'
- | '\u05D0'..'\u05EA'
- | '\u05F0'..'\u05F2'
- | '\u0621'..'\u063A'
- | '\u0640'..'\u064A'
- | '\u0671'..'\u06D3'
- | '\u06D5'
- | '\u06E5'..'\u06E6'
- | '\u06FA'..'\u06FC'
- | '\u0710'
- | '\u0712'..'\u072C'
- | '\u0780'..'\u07A5'
- | '\u0905'..'\u0939'
- | '\u093D'
- | '\u0950'
- | '\u0958'..'\u0961'
- | '\u0985'..'\u098C'
- | '\u098F'..'\u0990'
- | '\u0993'..'\u09A8'
- | '\u09AA'..'\u09B0'
- | '\u09B2'
- | '\u09B6'..'\u09B9'
- | '\u09DC'..'\u09DD'
- | '\u09DF'..'\u09E1'
- | '\u09F0'..'\u09F1'
- | '\u0A05'..'\u0A0A'
- | '\u0A0F'..'\u0A10'
- | '\u0A13'..'\u0A28'
- | '\u0A2A'..'\u0A30'
- | '\u0A32'..'\u0A33'
- | '\u0A35'..'\u0A36'
- | '\u0A38'..'\u0A39'
- | '\u0A59'..'\u0A5C'
- | '\u0A5E'
- | '\u0A72'..'\u0A74'
- | '\u0A85'..'\u0A8B'
- | '\u0A8D'
- | '\u0A8F'..'\u0A91'
- | '\u0A93'..'\u0AA8'
- | '\u0AAA'..'\u0AB0'
- | '\u0AB2'..'\u0AB3'
- | '\u0AB5'..'\u0AB9'
- | '\u0ABD'
- | '\u0AD0'
- | '\u0AE0'
- | '\u0B05'..'\u0B0C'
- | '\u0B0F'..'\u0B10'
- | '\u0B13'..'\u0B28'
- | '\u0B2A'..'\u0B30'
- | '\u0B32'..'\u0B33'
- | '\u0B36'..'\u0B39'
- | '\u0B3D'
- | '\u0B5C'..'\u0B5D'
- | '\u0B5F'..'\u0B61'
- | '\u0B85'..'\u0B8A'
- | '\u0B8E'..'\u0B90'
- | '\u0B92'..'\u0B95'
- | '\u0B99'..'\u0B9A'
- | '\u0B9C'
- | '\u0B9E'..'\u0B9F'
- | '\u0BA3'..'\u0BA4'
- | '\u0BA8'..'\u0BAA'
- | '\u0BAE'..'\u0BB5'
- | '\u0BB7'..'\u0BB9'
- | '\u0C05'..'\u0C0C'
- | '\u0C0E'..'\u0C10'
- | '\u0C12'..'\u0C28'
- | '\u0C2A'..'\u0C33'
- | '\u0C35'..'\u0C39'
- | '\u0C60'..'\u0C61'
- | '\u0C85'..'\u0C8C'
- | '\u0C8E'..'\u0C90'
- | '\u0C92'..'\u0CA8'
- | '\u0CAA'..'\u0CB3'
- | '\u0CB5'..'\u0CB9'
- | '\u0CDE'
- | '\u0CE0'..'\u0CE1'
- | '\u0D05'..'\u0D0C'
- | '\u0D0E'..'\u0D10'
- | '\u0D12'..'\u0D28'
- | '\u0D2A'..'\u0D39'
- | '\u0D60'..'\u0D61'
- | '\u0D85'..'\u0D96'
- | '\u0D9A'..'\u0DB1'
- | '\u0DB3'..'\u0DBB'
- | '\u0DBD'
- | '\u0DC0'..'\u0DC6'
- | '\u0E01'..'\u0E30'
- | '\u0E32'..'\u0E33'
- | '\u0E40'..'\u0E46'
- | '\u0E81'..'\u0E82'
- | '\u0E84'
- | '\u0E87'..'\u0E88'
- | '\u0E8A'
- | '\u0E8D'
- | '\u0E94'..'\u0E97'
- | '\u0E99'..'\u0E9F'
- | '\u0EA1'..'\u0EA3'
- | '\u0EA5'
- | '\u0EA7'
- | '\u0EAA'..'\u0EAB'
- | '\u0EAD'..'\u0EB0'
- | '\u0EB2'..'\u0EB3'
- | '\u0EBD'..'\u0EC4'
- | '\u0EC6'
- | '\u0EDC'..'\u0EDD'
- | '\u0F00'
- | '\u0F40'..'\u0F6A'
- | '\u0F88'..'\u0F8B'
- | '\u1000'..'\u1021'
- | '\u1023'..'\u1027'
- | '\u1029'..'\u102A'
- | '\u1050'..'\u1055'
- | '\u10A0'..'\u10C5'
- | '\u10D0'..'\u10F6'
- | '\u1100'..'\u1159'
- | '\u115F'..'\u11A2'
- | '\u11A8'..'\u11F9'
- | '\u1200'..'\u1206'
- | '\u1208'..'\u1246'
- | '\u1248'
- | '\u124A'..'\u124D'
- | '\u1250'..'\u1256'
- | '\u1258'
- | '\u125A'..'\u125D'
- | '\u1260'..'\u1286'
- | '\u1288'
- | '\u128A'..'\u128D'
- | '\u1290'..'\u12AE'
- | '\u12B0'
- | '\u12B2'..'\u12B5'
- | '\u12B8'..'\u12BE'
- | '\u12C0'
- | '\u12C2'..'\u12C5'
- | '\u12C8'..'\u12CE'
- | '\u12D0'..'\u12D6'
- | '\u12D8'..'\u12EE'
- | '\u12F0'..'\u130E'
- | '\u1310'
- | '\u1312'..'\u1315'
- | '\u1318'..'\u131E'
- | '\u1320'..'\u1346'
- | '\u1348'..'\u135A'
- | '\u13A0'..'\u13B0'
- | '\u13B1'..'\u13F4'
- | '\u1401'..'\u1676'
- | '\u1681'..'\u169A'
- | '\u16A0'..'\u16EA'
- | '\u1780'..'\u17B3'
- | '\u1820'..'\u1877'
- | '\u1880'..'\u18A8'
- | '\u1E00'..'\u1E9B'
- | '\u1EA0'..'\u1EE0'
- | '\u1EE1'..'\u1EF9'
- | '\u1F00'..'\u1F15'
- | '\u1F18'..'\u1F1D'
- | '\u1F20'..'\u1F39'
- | '\u1F3A'..'\u1F45'
- | '\u1F48'..'\u1F4D'
- | '\u1F50'..'\u1F57'
- | '\u1F59'
- | '\u1F5B'
- | '\u1F5D'
- | '\u1F5F'..'\u1F7D'
- | '\u1F80'..'\u1FB4'
- | '\u1FB6'..'\u1FBC'
- | '\u1FBE'
- | '\u1FC2'..'\u1FC4'
- | '\u1FC6'..'\u1FCC'
- | '\u1FD0'..'\u1FD3'
- | '\u1FD6'..'\u1FDB'
- | '\u1FE0'..'\u1FEC'
- | '\u1FF2'..'\u1FF4'
- | '\u1FF6'..'\u1FFC'
- | '\u207F'
- | '\u2102'
- | '\u2107'
- | '\u210A'..'\u2113'
- | '\u2115'
- | '\u2119'..'\u211D'
- | '\u2124'
- | '\u2126'
- | '\u2128'
- | '\u212A'..'\u212D'
- | '\u212F'..'\u2131'
- | '\u2133'..'\u2139'
- | '\u2160'..'\u2183'
- | '\u3005'..'\u3007'
- | '\u3021'..'\u3029'
- | '\u3031'..'\u3035'
- | '\u3038'..'\u303A'
- | '\u3041'..'\u3094'
- | '\u309D'..'\u309E'
- | '\u30A1'..'\u30FA'
- | '\u30FC'..'\u30FE'
- | '\u3105'..'\u312C'
- | '\u3131'..'\u318E'
- | '\u31A0'..'\u31B7'
- | '\u3400'
- | '\u4DB5'
- | '\u4E00'
- | '\u9FA5'
- | '\uA000'..'\uA48C'
- | '\uAC00'
- | '\uD7A3'
- | '\uF900'..'\uFA2D'
- | '\uFB00'..'\uFB06'
- | '\uFB13'..'\uFB17'
- | '\uFB1D'
- | '\uFB1F'..'\uFB28'
- | '\uFB2A'..'\uFB36'
- | '\uFB38'..'\uFB3C'
- | '\uFB3E'
- | '\uFB40'..'\uFB41'
- | '\uFB43'..'\uFB44'
- | '\uFB46'..'\uFBB1'
- | '\uFBD3'..'\uFD3D'
- | '\uFD50'..'\uFD8F'
- | '\uFD92'..'\uFDC7'
- | '\uFDF0'..'\uFDFB'
- | '\uFE70'..'\uFE72'
- | '\uFE74'
- | '\uFE76'..'\uFEFC'
- | '\uFF21'..'\uFF3A'
- | '\uFF41'..'\uFF5A'
- | '\uFF66'..'\uFFBE'
- | '\uFFC2'..'\uFFC7'
- | '\uFFCA'..'\uFFCF'
- | '\uFFD2'..'\uFFD7'
- | '\uFFDA'..'\uFFDC'
- ;
-
-fragment UnicodeCombiningMark // Any character in the Unicode categories "Non-spacing mark (Mn)"
- : '\u0300'..'\u034E' // or "Combining spacing mark (Mc)".
- | '\u0360'..'\u0362'
- | '\u0483'..'\u0486'
- | '\u0591'..'\u05A1'
- | '\u05A3'..'\u05B9'
- | '\u05BB'..'\u05BD'
- | '\u05BF'
- | '\u05C1'..'\u05C2'
- | '\u05C4'
- | '\u064B'..'\u0655'
- | '\u0670'
- | '\u06D6'..'\u06DC'
- | '\u06DF'..'\u06E4'
- | '\u06E7'..'\u06E8'
- | '\u06EA'..'\u06ED'
- | '\u0711'
- | '\u0730'..'\u074A'
- | '\u07A6'..'\u07B0'
- | '\u0901'..'\u0903'
- | '\u093C'
- | '\u093E'..'\u094D'
- | '\u0951'..'\u0954'
- | '\u0962'..'\u0963'
- | '\u0981'..'\u0983'
- | '\u09BC'..'\u09C4'
- | '\u09C7'..'\u09C8'
- | '\u09CB'..'\u09CD'
- | '\u09D7'
- | '\u09E2'..'\u09E3'
- | '\u0A02'
- | '\u0A3C'
- | '\u0A3E'..'\u0A42'
- | '\u0A47'..'\u0A48'
- | '\u0A4B'..'\u0A4D'
- | '\u0A70'..'\u0A71'
- | '\u0A81'..'\u0A83'
- | '\u0ABC'
- | '\u0ABE'..'\u0AC5'
- | '\u0AC7'..'\u0AC9'
- | '\u0ACB'..'\u0ACD'
- | '\u0B01'..'\u0B03'
- | '\u0B3C'
- | '\u0B3E'..'\u0B43'
- | '\u0B47'..'\u0B48'
- | '\u0B4B'..'\u0B4D'
- | '\u0B56'..'\u0B57'
- | '\u0B82'..'\u0B83'
- | '\u0BBE'..'\u0BC2'
- | '\u0BC6'..'\u0BC8'
- | '\u0BCA'..'\u0BCD'
- | '\u0BD7'
- | '\u0C01'..'\u0C03'
- | '\u0C3E'..'\u0C44'
- | '\u0C46'..'\u0C48'
- | '\u0C4A'..'\u0C4D'
- | '\u0C55'..'\u0C56'
- | '\u0C82'..'\u0C83'
- | '\u0CBE'..'\u0CC4'
- | '\u0CC6'..'\u0CC8'
- | '\u0CCA'..'\u0CCD'
- | '\u0CD5'..'\u0CD6'
- | '\u0D02'..'\u0D03'
- | '\u0D3E'..'\u0D43'
- | '\u0D46'..'\u0D48'
- | '\u0D4A'..'\u0D4D'
- | '\u0D57'
- | '\u0D82'..'\u0D83'
- | '\u0DCA'
- | '\u0DCF'..'\u0DD4'
- | '\u0DD6'
- | '\u0DD8'..'\u0DDF'
- | '\u0DF2'..'\u0DF3'
- | '\u0E31'
- | '\u0E34'..'\u0E3A'
- | '\u0E47'..'\u0E4E'
- | '\u0EB1'
- | '\u0EB4'..'\u0EB9'
- | '\u0EBB'..'\u0EBC'
- | '\u0EC8'..'\u0ECD'
- | '\u0F18'..'\u0F19'
- | '\u0F35'
- | '\u0F37'
- | '\u0F39'
- | '\u0F3E'..'\u0F3F'
- | '\u0F71'..'\u0F84'
- | '\u0F86'..'\u0F87'
- | '\u0F90'..'\u0F97'
- | '\u0F99'..'\u0FBC'
- | '\u0FC6'
- | '\u102C'..'\u1032'
- | '\u1036'..'\u1039'
- | '\u1056'..'\u1059'
- | '\u17B4'..'\u17D3'
- | '\u18A9'
- | '\u20D0'..'\u20DC'
- | '\u20E1'
- | '\u302A'..'\u302F'
- | '\u3099'..'\u309A'
- | '\uFB1E'
- | '\uFE20'..'\uFE23'
- ;
-
-fragment UnicodeDigit // Any character in the Unicode category "Decimal number (Nd)".
- : '\u0030'..'\u0039'
- | '\u0660'..'\u0669'
- | '\u06F0'..'\u06F9'
- | '\u0966'..'\u096F'
- | '\u09E6'..'\u09EF'
- | '\u0A66'..'\u0A6F'
- | '\u0AE6'..'\u0AEF'
- | '\u0B66'..'\u0B6F'
- | '\u0BE7'..'\u0BEF'
- | '\u0C66'..'\u0C6F'
- | '\u0CE6'..'\u0CEF'
- | '\u0D66'..'\u0D6F'
- | '\u0E50'..'\u0E59'
- | '\u0ED0'..'\u0ED9'
- | '\u0F20'..'\u0F29'
- | '\u1040'..'\u1049'
- | '\u1369'..'\u1371'
- | '\u17E0'..'\u17E9'
- | '\u1810'..'\u1819'
- | '\uFF10'..'\uFF19'
- ;
-
-fragment UnicodeConnectorPunctuation // Any character in the Unicode category "Connector punctuation (Pc)".
- : '\u005F'
- | '\u203F'..'\u2040'
- | '\u30FB'
- | '\uFE33'..'\uFE34'
- | '\uFE4D'..'\uFE4F'
- | '\uFF3F'
- | '\uFF65'
- ;
-
-Comment
- : '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;}
- ;
-
-LineComment
- : '//' ~(LT)* {$channel=HIDDEN;}
- ;
-
-LT
- : '\n' // Line feed.
- | '\r' // Carriage return.
- | '\u2028' // Line separator.
- | '\u2029' // Paragraph separator.
- ;
-
-WhiteSpace // Tab, vertical tab, form feed, space, non-breaking space and any other unicode "space separator".
- : ('\t' | '\v' | '\f' | ' ' | '\u00A0') {$channel=HIDDEN;}
- ;
diff --git a/trunk/src/examples/jsonParser.py b/trunk/src/examples/jsonParser.py
deleted file mode 100644
index 45cdef3..0000000
--- a/trunk/src/examples/jsonParser.py
+++ /dev/null
@@ -1,111 +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
-#
-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 *
-
-TRUE = Keyword("true").setParseAction( replaceWith(True) )
-FALSE = Keyword("false").setParseAction( replaceWith(False) )
-NULL = Keyword("null").setParseAction( replaceWith(None) )
-
-jsonString = dblQuotedString.setParseAction( removeQuotes )
-jsonNumber = Combine( Optional('-') + ( '0' | Word('123456789',nums) ) +
- Optional( '.' + Word(nums) ) +
- Optional( Word('eE',exact=1) + Word(nums+'+-',nums) ) )
-
-jsonObject = Forward()
-jsonValue = Forward()
-jsonElements = delimitedList( jsonValue )
-jsonArray = Group(Suppress('[') + Optional(jsonElements, []) + Suppress(']') )
-jsonValue << ( jsonString | jsonNumber | Group(jsonObject) | jsonArray | TRUE | FALSE | NULL )
-memberDef = Group( jsonString + Suppress(':') + jsonValue )
-jsonMembers = delimitedList( memberDef )
-jsonObject << Dict( Suppress('{') + Optional(jsonMembers) + Suppress('}') )
-
-jsonComment = cppStyleComment
-jsonObject.ignore( jsonComment )
-
-def convertNumbers(s,l,toks):
- n = toks[0]
- try:
- return int(n)
- except ValueError as ve:
- return float(n)
-
-jsonNumber.setParseAction( convertNumbers )
-
-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/trunk/src/examples/linenoExample.py b/trunk/src/examples/linenoExample.py
deleted file mode 100644
index 1186f48..0000000
--- a/trunk/src/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/trunk/src/examples/list1.py b/trunk/src/examples/list1.py
deleted file mode 100644
index e410070..0000000
--- a/trunk/src/examples/list1.py
+++ /dev/null
@@ -1,50 +0,0 @@
-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 = 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
-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 = Combine(Optional(oneOf("+ -")) + Word(nums) + "." +
- Optional(Word(nums))).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/trunk/src/examples/listAllMatches.py b/trunk/src/examples/listAllMatches.py
deleted file mode 100644
index 1b1bdd4..0000000
--- a/trunk/src/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/trunk/src/examples/lucene_grammar.py b/trunk/src/examples/lucene_grammar.py
deleted file mode 100644
index 179f25e..0000000
--- a/trunk/src/examples/lucene_grammar.py
+++ /dev/null
@@ -1,330 +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)
-ParserElement.enablePackrat()
-
-COLON,LBRACK,RBRACK,LBRACE,RBRACE,TILDE,CARAT = map(Literal,":[]{}~^")
-LPAR,RPAR = map(Suppress,"()")
-and_ = CaselessKeyword("AND")
-or_ = CaselessKeyword("OR")
-not_ = CaselessKeyword("NOT")
-to_ = CaselessKeyword("TO")
-keyword = and_ | or_ | not_
-
-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 = Regex(r'\d+(\.\d+)?').setParseAction(lambda t:float(t[0]))
-fuzzy_modifier = TILDE + Optional(number, default=0.5)("fuzzy")
-
-term = Forward()
-field_name = valid_word.copy().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
- """.splitlines()
-
-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* ]
- """.splitlines()
-
-allpass = True
-for t in [_f for _f in map(str.strip,tests) if _f]:
- print(t)
- try:
- #~ expression.parseString(t,parseAll=True)
- print(expression.parseString(t,parseAll=True))
- except ParseException as pe:
- print(t)
- print(pe)
- allpass = False
- print('')
-
-print(("FAIL", "OK")[allpass])
diff --git a/trunk/src/examples/macroExpander.py b/trunk/src/examples/macroExpander.py
deleted file mode 100644
index 327976c..0000000
--- a/trunk/src/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/trunk/src/examples/makeHTMLTagExample.py b/trunk/src/examples/makeHTMLTagExample.py
deleted file mode 100644
index 3b771c7..0000000
--- a/trunk/src/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/trunk/src/examples/matchPreviousDemo.py b/trunk/src/examples/matchPreviousDemo.py
deleted file mode 100644
index f0812e9..0000000
--- a/trunk/src/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/trunk/src/examples/mozilla.ics b/trunk/src/examples/mozilla.ics
deleted file mode 100644
index e6dd3dc..0000000
--- a/trunk/src/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/trunk/src/examples/mozillaCalendarParser.py b/trunk/src/examples/mozillaCalendarParser.py
deleted file mode 100644
index 210f284..0000000
--- a/trunk/src/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 <firstname.lastname@iki.fi>
-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/trunk/src/examples/nested.py b/trunk/src/examples/nested.py
deleted file mode 100644
index 24cf2f4..0000000
--- a/trunk/src/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/trunk/src/examples/numerics.py b/trunk/src/examples/numerics.py
deleted file mode 100644
index 5ab99dd..0000000
--- a/trunk/src/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/trunk/src/examples/oc.py b/trunk/src/examples/oc.py
deleted file mode 100644
index 77ea195..0000000
--- a/trunk/src/examples/oc.py
+++ /dev/null
@@ -1,193 +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 = Keyword("int")
-CHAR = Keyword("char")
-WHILE = Keyword("while")
-DO = Keyword("do")
-IF = Keyword("if")
-ELSE = Keyword("else")
-RETURN = Keyword("return")
-
-NAME = Word(alphas+"_", alphanums+"_")
-integer = Regex(r"[+-]?\d+")
-char = Regex(r"'.'")
-string_ = dblQuotedString
-
-INT = Keyword("int")
-CHAR = Keyword("char")
-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/trunk/src/examples/parseListString.py b/trunk/src/examples/parseListString.py
deleted file mode 100644
index d74f3af..0000000
--- a/trunk/src/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/trunk/src/examples/parsePythonValue.py b/trunk/src/examples/parsePythonValue.py
deleted file mode 100644
index 53c61fc..0000000
--- a/trunk/src/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/trunk/src/examples/parseResultsSumExample.py b/trunk/src/examples/parseResultsSumExample.py
deleted file mode 100644
index 1fb694a..0000000
--- a/trunk/src/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/trunk/src/examples/parseTabularData.py b/trunk/src/examples/parseTabularData.py
deleted file mode 100644
index 3846310..0000000
--- a/trunk/src/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/trunk/src/examples/partial_gene_match.py b/trunk/src/examples/partial_gene_match.py
deleted file mode 100644
index 8bf5f7c..0000000
--- a/trunk/src/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("<exact match>")
- print("at location", startLoc)
- print()
- print() \ No newline at end of file
diff --git a/trunk/src/examples/pgn.py b/trunk/src/examples/pgn.py
deleted file mode 100644
index d13f83e..0000000
--- a/trunk/src/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/trunk/src/examples/position.py b/trunk/src/examples/position.py
deleted file mode 100644
index 984c018..0000000
--- a/trunk/src/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/trunk/src/examples/protobuf_parser.py b/trunk/src/examples/protobuf_parser.py
deleted file mode 100644
index 04ce0d8..0000000
--- a/trunk/src/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/trunk/src/examples/pymicko.py b/trunk/src/examples/pymicko.py
deleted file mode 100644
index b136689..0000000
--- a/trunk/src/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 <http://www.gnu.org/licenses/>.
-
-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
-# -> <empty>
-# -> parameter_list
-
-# parameter_list
-# -> variable
-# -> parameter_list "," variable
-
-# body
-# -> "{" variable_list statement_list "}"
-# -> "{" statement_list "}"
-
-# statement_list
-# -> <empty>
-# -> 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
-# -> <empty>
-# -> 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/trunk/src/examples/pythonGrammarParser.py b/trunk/src/examples/pythonGrammarParser.py
deleted file mode 100644
index f0631b8..0000000
--- a/trunk/src/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 = """
-# 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 <fdrake@acm.org> 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/trunk/src/examples/rangeCheck.py b/trunk/src/examples/rangeCheck.py
deleted file mode 100644
index 67cf267..0000000
--- a/trunk/src/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/trunk/src/examples/readJson.py b/trunk/src/examples/readJson.py
deleted file mode 100644
index deca53b..0000000
--- a/trunk/src/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/trunk/src/examples/removeLineBreaks.py b/trunk/src/examples/removeLineBreaks.py
deleted file mode 100644
index ba4b498..0000000
--- a/trunk/src/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/trunk/src/examples/romanNumerals.py b/trunk/src/examples/romanNumerals.py
deleted file mode 100644
index 27361f0..0000000
--- a/trunk/src/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/trunk/src/examples/scanExamples.py b/trunk/src/examples/scanExamples.py
deleted file mode 100644
index 24ae0e7..0000000
--- a/trunk/src/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/trunk/src/examples/scanYahoo.py b/trunk/src/examples/scanYahoo.py
deleted file mode 100644
index 825c169..0000000
--- a/trunk/src/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/trunk/src/examples/searchParserAppDemo.py b/trunk/src/examples/searchParserAppDemo.py
deleted file mode 100644
index 259e0e3..0000000
--- a/trunk/src/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/trunk/src/examples/searchparser.py b/trunk/src/examples/searchparser.py
deleted file mode 100644
index e5b40a7..0000000
--- a/trunk/src/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/trunk/src/examples/select_parser.py b/trunk/src/examples/select_parser.py
deleted file mode 100644
index da106ac..0000000
--- a/trunk/src/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/trunk/src/examples/sexpParser.py b/trunk/src/examples/sexpParser.py
deleted file mode 100644
index 963d153..0000000
--- a/trunk/src/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
-
-<sexp> :: <string> | <list>
-<string> :: <display>? <simple-string> ;
-<simple-string> :: <raw> | <token> | <base-64> | <hexadecimal> |
- <quoted-string> ;
-<display> :: "[" <simple-string> "]" ;
-<raw> :: <decimal> ":" <bytes> ;
-<decimal> :: <decimal-digit>+ ;
- -- decimal numbers should have no unnecessary leading zeros
-<bytes> -- any string of bytes, of the indicated length
-<token> :: <tokenchar>+ ;
-<base-64> :: <decimal>? "|" ( <base-64-char> | <whitespace> )* "|" ;
-<hexadecimal> :: "#" ( <hex-digit> | <white-space> )* "#" ;
-<quoted-string> :: <decimal>? <quoted-string-body>
-<quoted-string-body> :: "\"" <bytes> "\""
-<list> :: "(" ( <sexp> | <whitespace> )* ")" ;
-<whitespace> :: <whitespace-char>* ;
-<token-char> :: <alpha> | <decimal-digit> | <simple-punc> ;
-<alpha> :: <upper-case> | <lower-case> | <digit> ;
-<lower-case> :: "a" | ... | "z" ;
-<upper-case> :: "A" | ... | "Z" ;
-<decimal-digit> :: "0" | ... | "9" ;
-<hex-digit> :: <decimal-digit> | "A" | ... | "F" | "a" | ... | "f" ;
-<simple-punc> :: "-" | "." | "/" | "_" | ":" | "*" | "+" | "=" ;
-<whitespace-char> :: " " | "\t" | "\r" | "\n" ;
-<base-64-char> :: <alpha> | <decimal-digit> | "+" | "/" | "=" ;
-<null> :: "" ;
-"""
-
-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/trunk/src/examples/shapes.py b/trunk/src/examples/shapes.py
deleted file mode 100644
index b5a0ebd..0000000
--- a/trunk/src/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 <centerx> <centery> <side>
-# rectangle: R <centerx> <centery> <width> <height>
-# circle : C <centerx> <centery> <diameter>
-
-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/trunk/src/examples/simpleArith.py b/trunk/src/examples/simpleArith.py
deleted file mode 100644
index 825956b..0000000
--- a/trunk/src/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/trunk/src/examples/simpleBool.py b/trunk/src/examples/simpleBool.py
deleted file mode 100644
index 5f355b7..0000000
--- a/trunk/src/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/trunk/src/examples/simpleSQL.py b/trunk/src/examples/simpleSQL.py
deleted file mode 100644
index 66dc18c..0000000
--- a/trunk/src/examples/simpleSQL.py
+++ /dev/null
@@ -1,72 +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, Keyword, upcaseTokens
-
-# define SQL tokens
-selectStmt = Forward()
-SELECT = Keyword("select", caseless=True)
-FROM = Keyword("from", caseless=True)
-WHERE = Keyword("where", caseless=True)
-
-ident = Word( alphas, alphanums + "_$" ).setName("identifier")
-columnName = ( delimitedList( ident, ".", combine=True ) ).addParseAction(upcaseTokens)
-columnNameList = Group( delimitedList( columnName ) )
-tableName = ( delimitedList( ident, ".", combine=True ) ).addParseAction(upcaseTokens)
-tableNameList = Group( delimitedList( tableName ) )
-
-whereExpression = Forward()
-and_ = Keyword("and", caseless=True)
-or_ = Keyword("or", caseless=True)
-in_ = Keyword("in", caseless=True)
-
-E = CaselessLiteral("E")
-binop = oneOf("= != < > >= <= eq ne lt le gt ge", caseless=True)
-arithSign = Word("+-",exact=1)
-realNum = Combine( Optional(arithSign) + ( Word( nums ) + "." + Optional( Word(nums) ) |
- ( "." + Word(nums) ) ) +
- Optional( E + Optional(arithSign) + Word(nums) ) )
-intNum = Combine( Optional(arithSign) + Word( nums ) +
- Optional( E + Optional("+") + Word(nums) ) )
-
-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("""\
- SELECT * from XYZZY, ABC
- select * from SYS.XYZZY
- Select A from Sys.dual
- Select A,B,C from Sys.dual
- Select A, B, C from Sys.dual
- Select A, B, C from Sys.dual, Table2
- Xelect A, B, C from Sys.dual
- Select A, B, C frox Sys.dual
- Select
- Select &&& frox Sys.dual
- Select A from Sys.dual where a in ('RED','GREEN','BLUE')
- Select A from Sys.dual where a in ('RED','GREEN','BLUE') and b in (10,20,30)
- Select A,b from table1,table2 where table1.id eq table2.id -- test out comparison operators""")
diff --git a/trunk/src/examples/simpleWiki.py b/trunk/src/examples/simpleWiki.py
deleted file mode 100644
index 7a2a0ce..0000000
--- a/trunk/src/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("<I>","</I>"))
-bolded = QuotedString("**").setParseAction(convertToHTML("<B>","</B>"))
-boldItalicized = QuotedString("***").setParseAction(convertToHTML("<B><I>","</I></B>"))
-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 '<A href="%s">%s</A>' % (url,text)
-
-urlRef = QuotedString("{{",endQuoteChar="}}").setParseAction(convertToHTML_A)
-
-wikiMarkup = urlRef | boldItalicized | bolded | italicized
-
-print(wikiInput)
-print()
-print(wikiMarkup.transformString(wikiInput))
diff --git a/trunk/src/examples/snmp_api.h b/trunk/src/examples/snmp_api.h
deleted file mode 100644
index d75cb12..0000000
--- a/trunk/src/examples/snmp_api.h
+++ /dev/null
@@ -1,795 +0,0 @@
-#ifndef SNMP_API_H
-#define SNMP_API_H
-
-/*
- * snmp_api.h - API for access to snmp.
- *
- * Caution: when using this library in a multi-threaded application,
- * the values of global variables "snmp_errno" and "snmp_detail"
- * cannot be reliably determined. Suggest using snmp_error()
- * to obtain the library error codes.
- */
-
-#ifndef DONT_SHARE_ERROR_WITH_OTHER_THREADS
-#define SET_SNMP_ERROR(x) snmp_errno=(x)
-#else
-#define SET_SNMP_ERROR(x)
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/***********************************************************
- Copyright 1989 by Carnegie Mellon University
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of CMU not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-******************************************************************/
-
-
-struct variable_list;
-struct timeval;
-
-
- /*
- * Mimic size and alignment of 'struct sockaddr_storage' (see RFC 2553)
- * But retain field names of traditional 'struct sockaddr'
- */
-
-#define _UCD_SS_MAXSIZE 92 /* <= sizeof( sockaddr_un ) */
-#define _UCD_SS_ALIGNSIZE (sizeof (long))
-
-#define _UCD_SS_PAD1SIZE (_UCD_SS_ALIGNSIZE - sizeof( unsigned short ))
-#define _UCD_SS_PAD2SIZE (_UCD_SS_MAXSIZE - \
- (sizeof( unsigned short ) + _UCD_SS_PAD1SIZE + _UCD_SS_ALIGNSIZE ))
-
-typedef struct {
-
-#ifdef STRUCT_SOCKADDR_HAS_SA_UNION_SA_GENERIC_SA_FAMILY2
- /*
- * Certain systems (notably Irix 6.x) have a non-traditional
- * socket structure, and #define the traditional field names.
- * This local definition should reproduce this structure, and still
- * be large enough to handle any necessary Unix domain addresses.
- */
- union {
- struct {
-#ifdef _HAVE_SA_LEN
- unsigned char sa_len2;
- unsigned char sa_family2;
-#else
- unsigned short sa_family2;
-#endif
- char sa_data2[ _UCD_SS_PAD1SIZE ];
- } sa_generic;
- long sa_align;
- char sa_pad2[ _UCD_SS_PAD2SIZE ];
- } sa_union;
-
-#else
-
-#ifdef STRUCT_SOCKADDR_HAS_SA_LEN
- unsigned char sa_len;
- unsigned char sa_family;
-#else
- unsigned short sa_family;
-#endif
- char sa_data[ _UCD_SS_PAD1SIZE ];
- long sa_align;
- char sa_pad2[ _UCD_SS_PAD2SIZE ];
-#endif
-
-} snmp_ipaddr;
-
-#define USM_AUTH_KU_LEN 32
-#define USM_PRIV_KU_LEN 32
-
-struct snmp_pdu {
-
- /*
- * Protocol-version independent fields
- */
- long version;
- int command; /* Type of this PDU */
- long reqid; /* Request id - note: not incremented on retries */
- long msgid; /* Message id for V3 messages
- * note: incremented for each retry */
- long transid; /* Unique ID for incoming transactions */
- long sessid; /* Session id for AgentX messages */
- long errstat; /* Error status (non_repeaters in GetBulk) */
- long errindex; /* Error index (max_repetitions in GetBulk) */
- u_long time; /* Uptime */
- u_long flags;
-
- int securityModel;
- int securityLevel; /* noAuthNoPriv, authNoPriv, authPriv */
- int msgParseModel;
-
- snmp_ipaddr address; /* Address of peer or trap destination */
-
- struct variable_list *variables;
-
-
- /*
- * SNMPv1 & SNMPv2c fields
- */
- u_char *community; /* community for outgoing requests. */
- size_t community_len; /* Length of community name. */
-
- /*
- * Trap information
- */
- oid *enterprise; /* System OID */
- size_t enterprise_length;
- long trap_type; /* trap type */
- long specific_type; /* specific type */
- snmp_ipaddr agent_addr;
-
- /*
- * SNMPv3 fields
- */
- u_char *contextEngineID; /* context snmpEngineID */
- size_t contextEngineIDLen; /* Length of contextEngineID */
- char *contextName; /* authoritative contextName */
- size_t contextNameLen; /* Length of contextName */
- u_char *securityEngineID; /* authoritative snmpEngineID for security */
- size_t securityEngineIDLen;/* Length of securityEngineID */
- char *securityName; /* on behalf of this principal */
- size_t securityNameLen; /* Length of securityName. */
-
- /*
- * AgentX fields
- * (also uses SNMPv1 community field)
- */
- int priority;
- int range_subid;
-
- void * securityStateRef;
-};
-
-struct snmp_session;
-typedef int (*snmp_callback) (int, struct snmp_session *, int, struct snmp_pdu *, void *);
-
-struct snmp_session {
- /*
- * Protocol-version independent fields
- */
- long version;
- int retries; /* Number of retries before timeout. */
- long timeout; /* Number of uS until first timeout, then exponential backoff */
- u_long flags;
- struct snmp_session *subsession;
- struct snmp_session *next;
-
- char *peername; /* Domain name or dotted IP address of default peer */
- u_short remote_port;/* UDP port number of peer. */
- u_short local_port; /* My UDP port number, 0 for default, picked randomly */
- /* Authentication function or NULL if null authentication is used */
- u_char *(*authenticator) (u_char *, size_t *, u_char *, size_t);
- snmp_callback callback; /* Function to interpret incoming data */
- /* Pointer to data that the callback function may consider important */
- void *callback_magic;
-
- int s_errno; /* copy of system errno */
- int s_snmp_errno; /* copy of library errno */
- long sessid; /* Session id - AgentX only */
-
- /*
- * SNMPv1 & SNMPv2c fields
- */
- u_char *community; /* community for outgoing requests. */
- size_t community_len; /* Length of community name. */
-
- /*
- * SNMPv3 fields
- */
- u_char isAuthoritative; /* are we the authoritative engine? */
- u_char *contextEngineID; /* authoritative snmpEngineID */
- size_t contextEngineIDLen; /* Length of contextEngineID */
- u_int engineBoots; /* initial engineBoots for remote engine */
- u_int engineTime; /* initial engineTime for remote engine */
- char *contextName; /* authoritative contextName */
- size_t contextNameLen; /* Length of contextName */
- u_char *securityEngineID; /* authoritative snmpEngineID */
- size_t securityEngineIDLen; /* Length of contextEngineID */
- char *securityName; /* on behalf of this principal */
- size_t securityNameLen; /* Length of securityName. */
- oid *securityAuthProto; /* auth protocol oid */
- size_t securityAuthProtoLen; /* Length of auth protocol oid */
- u_char securityAuthKey[USM_AUTH_KU_LEN]; /* Ku for auth protocol XXX */
- size_t securityAuthKeyLen; /* Length of Ku for auth protocol */
- oid *securityPrivProto; /* priv protocol oid */
- size_t securityPrivProtoLen; /* Length of priv protocol oid */
- u_char securityPrivKey[USM_PRIV_KU_LEN]; /* Ku for privacy protocol XXX */
- size_t securityPrivKeyLen; /* Length of Ku for priv protocol */
- int securityModel;
- int securityLevel; /* noAuthNoPriv, authNoPriv, authPriv */
-};
-
-/*
- * A list of all the outstanding requests for a particular session.
- */
-#ifdef SNMP_NEED_REQUEST_LIST
-struct request_list {
- struct request_list *next_request;
- long request_id; /* request id */
- long message_id; /* message id */
- snmp_callback callback; /* user callback per request (NULL if unused) */
- void *cb_data; /* user callback data per request (NULL if unused) */
- int retries; /* Number of retries */
- u_long timeout; /* length to wait for timeout */
- struct timeval time; /* Time this request was made */
- struct timeval expire; /* time this request is due to expire */
- struct snmp_session *session;
- struct snmp_pdu *pdu; /* The pdu for this request
- (saved so it can be retransmitted */
-};
-#endif /* SNMP_NEED_REQUEST_LIST */
-
-/*
- * Set fields in session and pdu to the following to get a default or unconfigured value.
- */
-#define SNMP_DEFAULT_COMMUNITY_LEN 0 /* to get a default community name */
-#define SNMP_DEFAULT_RETRIES -1
-#define SNMP_DEFAULT_TIMEOUT -1
-#define SNMP_DEFAULT_REMPORT 0
-#define SNMP_DEFAULT_REQID -1
-#define SNMP_DEFAULT_MSGID -1
-#define SNMP_DEFAULT_ERRSTAT -1
-#define SNMP_DEFAULT_ERRINDEX -1
-#define SNMP_DEFAULT_ADDRESS 0
-#define SNMP_DEFAULT_PEERNAME NULL
-#define SNMP_DEFAULT_ENTERPRISE_LENGTH 0
-#define SNMP_DEFAULT_TIME 0
-#define SNMP_DEFAULT_VERSION -1
-#define SNMP_DEFAULT_CONTEXT ""
-#define SNMP_DEFAULT_AUTH_PROTO usmHMACMD5AuthProtocol
-#define SNMP_DEFAULT_AUTH_PROTOLEN USM_LENGTH_OID_TRANSFORM
-#define SNMP_DEFAULT_PRIV_PROTO usmDESPrivProtocol
-#define SNMP_DEFAULT_PRIV_PROTOLEN USM_LENGTH_OID_TRANSFORM
-
-extern const char *snmp_api_errstring (int);
-extern void snmp_perror (const char *);
-extern void snmp_set_detail (const char *);
-
-#define SNMP_MAX_MSG_SIZE 1472 /* ethernet MTU minus IP/UDP header */
-#define SNMP_MAX_MSG_V3_HDRS (4+3+4+7+7+3+7+16) /* fudge factor=16 */
-#define SNMP_MAX_ENG_SIZE 32
-#define SNMP_MAX_SEC_NAME_SIZE 256
-#define SNMP_MAX_CONTEXT_SIZE 256
-#define SNMP_SEC_PARAM_BUF_SIZE 256
-
-/* set to one to ignore unauthenticated Reports */
-#define SNMPV3_IGNORE_UNAUTH_REPORTS 0
-
-/* authoritative engine definitions */
-#define SNMP_SESS_NONAUTHORITATIVE 0 /* should be 0 to default to this */
-#define SNMP_SESS_AUTHORITATIVE 1 /* don't learn engineIDs */
-#define SNMP_SESS_UNKNOWNAUTH 2 /* sometimes (like NRs) */
-
-/* to determine type of Report from varbind_list */
-#define REPORT_STATS_LEN 9
-#define REPORT_snmpUnknownSecurityModels_NUM 1
-#define REPORT_snmpInvalidMsgs_NUM 2
-#define REPORT_usmStatsUnsupportedSecLevels_NUM 1
-#define REPORT_usmStatsNotInTimeWindows_NUM 2
-#define REPORT_usmStatsUnknownUserNames_NUM 3
-#define REPORT_usmStatsUnknownEngineIDs_NUM 4
-#define REPORT_usmStatsWrongDigests_NUM 5
-#define REPORT_usmStatsDecryptionErrors_NUM 6
-
-#define SNMP_DETAIL_SIZE 512
-
-#define SNMP_FLAGS_DONT_PROBE 0x100 /* don't probe for an engineID */
-#define SNMP_FLAGS_STREAM_SOCKET 0x80
-#define SNMP_FLAGS_LISTENING 0x40 /* Server stream sockets only */
-#define SNMP_FLAGS_SUBSESSION 0x20
-#define SNMP_FLAGS_STRIKE2 0x02
-#define SNMP_FLAGS_STRIKE1 0x01
-
-#define CLEAR_SNMP_STRIKE_FLAGS(x) \
- x &= ~(SNMP_FLAGS_STRIKE2|SNMP_FLAGS_STRIKE1)
-
- /*
- * returns '1' if the session is to be regarded as dead,
- * otherwise set the strike flags appropriately, and return 0
- */
-#define SET_SNMP_STRIKE_FLAGS(x) \
- (( x & SNMP_FLAGS_STRIKE2 ) ? 1 : \
- ((( x & SNMP_FLAGS_STRIKE1 ) ? ( x |= SNMP_FLAGS_STRIKE2 ) : \
- ( x |= SNMP_FLAGS_STRIKE1 )), \
- 0))
-
-/*
- * Error return values.
- *
- * SNMPERR_SUCCESS is the non-PDU "success" code.
- *
- * XXX These should be merged with SNMP_ERR_* defines and confined
- * to values < 0. ???
- */
-#define SNMPERR_SUCCESS (0) /* XXX Non-PDU "success" code. */
-#define SNMPERR_GENERR (-1)
-#define SNMPERR_BAD_LOCPORT (-2)
-#define SNMPERR_BAD_ADDRESS (-3)
-#define SNMPERR_BAD_SESSION (-4)
-#define SNMPERR_TOO_LONG (-5)
-#define SNMPERR_NO_SOCKET (-6)
-#define SNMPERR_V2_IN_V1 (-7)
-#define SNMPERR_V1_IN_V2 (-8)
-#define SNMPERR_BAD_REPEATERS (-9)
-#define SNMPERR_BAD_REPETITIONS (-10)
-#define SNMPERR_BAD_ASN1_BUILD (-11)
-#define SNMPERR_BAD_SENDTO (-12)
-#define SNMPERR_BAD_PARSE (-13)
-#define SNMPERR_BAD_VERSION (-14)
-#define SNMPERR_BAD_SRC_PARTY (-15)
-#define SNMPERR_BAD_DST_PARTY (-16)
-#define SNMPERR_BAD_CONTEXT (-17)
-#define SNMPERR_BAD_COMMUNITY (-18)
-#define SNMPERR_NOAUTH_DESPRIV (-19)
-#define SNMPERR_BAD_ACL (-20)
-#define SNMPERR_BAD_PARTY (-21)
-#define SNMPERR_ABORT (-22)
-#define SNMPERR_UNKNOWN_PDU (-23)
-#define SNMPERR_TIMEOUT (-24)
-#define SNMPERR_BAD_RECVFROM (-25)
-#define SNMPERR_BAD_ENG_ID (-26)
-#define SNMPERR_BAD_SEC_NAME (-27)
-#define SNMPERR_BAD_SEC_LEVEL (-28)
-#define SNMPERR_ASN_PARSE_ERR (-29)
-#define SNMPERR_UNKNOWN_SEC_MODEL (-30)
-#define SNMPERR_INVALID_MSG (-31)
-#define SNMPERR_UNKNOWN_ENG_ID (-32)
-#define SNMPERR_UNKNOWN_USER_NAME (-33)
-#define SNMPERR_UNSUPPORTED_SEC_LEVEL (-34)
-#define SNMPERR_AUTHENTICATION_FAILURE (-35)
-#define SNMPERR_NOT_IN_TIME_WINDOW (-36)
-#define SNMPERR_DECRYPTION_ERR (-37)
-#define SNMPERR_SC_GENERAL_FAILURE (-38)
-#define SNMPERR_SC_NOT_CONFIGURED (-39)
-#define SNMPERR_KT_NOT_AVAILABLE (-40)
-#define SNMPERR_UNKNOWN_REPORT (-41)
-#define SNMPERR_USM_GENERICERROR (-42)
-#define SNMPERR_USM_UNKNOWNSECURITYNAME (-43)
-#define SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL (-44)
-#define SNMPERR_USM_ENCRYPTIONERROR (-45)
-#define SNMPERR_USM_AUTHENTICATIONFAILURE (-46)
-#define SNMPERR_USM_PARSEERROR (-47)
-#define SNMPERR_USM_UNKNOWNENGINEID (-48)
-#define SNMPERR_USM_NOTINTIMEWINDOW (-49)
-#define SNMPERR_USM_DECRYPTIONERROR (-50)
-#define SNMPERR_NOMIB (-51)
-#define SNMPERR_RANGE (-52)
-#define SNMPERR_MAX_SUBID (-53)
-#define SNMPERR_BAD_SUBID (-54)
-#define SNMPERR_LONG_OID (-55)
-#define SNMPERR_BAD_NAME (-56)
-#define SNMPERR_VALUE (-57)
-#define SNMPERR_UNKNOWN_OBJID (-58)
-#define SNMPERR_NULL_PDU (-59)
-#define SNMPERR_NO_VARS (-60)
-#define SNMPERR_VAR_TYPE (-61)
-#define SNMPERR_MALLOC (-62)
-
-#define SNMPERR_MAX (-62)
-
-#define non_repeaters errstat
-#define max_repetitions errindex
-
-
-struct variable_list {
- struct variable_list *next_variable; /* NULL for last variable */
- oid *name; /* Object identifier of variable */
- size_t name_length; /* number of subid's in name */
- u_char type; /* ASN type of variable */
- union { /* value of variable */
- long *integer;
- u_char *string;
- oid *objid;
- u_char *bitstring;
- struct counter64 *counter64;
-#ifdef OPAQUE_SPECIAL_TYPES
- float *floatVal;
- double *doubleVal;
-/* t_union *unionVal; */
-#endif /* OPAQUE_SPECIAL_TYPES */
- } val;
- size_t val_len;
- oid name_loc[MAX_OID_LEN]; /* 90 percentile < 24. */
- u_char buf[40]; /* 90 percentile < 40. */
- void *data; /* (Opaque) hook for additional data */
- int index;
-};
-
-
-
-/*
- * struct snmp_session *snmp_open(session)
- * struct snmp_session *session;
- *
- * Sets up the session with the snmp_session information provided
- * by the user. Then opens and binds the necessary UDP port.
- * A handle to the created session is returned (this is different than
- * the pointer passed to snmp_open()). On any error, NULL is returned
- * and snmp_errno is set to the appropriate error code.
- */
-struct snmp_session *snmp_open (struct snmp_session *);
-
-/*
- * int snmp_close(session)
- * struct snmp_session *session;
- *
- * Close the input session. Frees all data allocated for the session,
- * dequeues any pending requests, and closes any sockets allocated for
- * the session. Returns 0 on error, 1 otherwise.
- *
- * snmp_close_sessions() does the same thing for all open sessions
- */
-int snmp_close (struct snmp_session *);
-int snmp_close_sessions (void);
-
-
-/*
- * int snmp_send(session, pdu)
- * struct snmp_session *session;
- * struct snmp_pdu *pdu;
- *
- * Sends the input pdu on the session after calling snmp_build to create
- * a serialized packet. If necessary, set some of the pdu data from the
- * session defaults. Add a request corresponding to this pdu to the list
- * of outstanding requests on this session, then send the pdu.
- * Returns the request id of the generated packet if applicable, otherwise 1.
- * On any error, 0 is returned.
- * The pdu is freed by snmp_send() unless a failure occured.
- */
-int snmp_send (struct snmp_session *, struct snmp_pdu *);
-
-/*
- * int snmp_async_send(session, pdu, callback, cb_data)
- * struct snmp_session *session;
- * struct snmp_pdu *pdu;
- * snmp_callback callback;
- * void *cb_data;
- *
- * Sends the input pdu on the session after calling snmp_build to create
- * a serialized packet. If necessary, set some of the pdu data from the
- * session defaults. Add a request corresponding to this pdu to the list
- * of outstanding requests on this session and store callback and data,
- * then send the pdu.
- * Returns the request id of the generated packet if applicable, otherwise 1.
- * On any error, 0 is returned.
- * The pdu is freed by snmp_send() unless a failure occured.
- */
-int snmp_async_send (struct snmp_session *, struct snmp_pdu *,
- snmp_callback, void *);
-
-
-/*
- * void snmp_read(fdset)
- * fd_set *fdset;
- *
- * Checks to see if any of the fd's set in the fdset belong to
- * snmp. Each socket with it's fd set has a packet read from it
- * and snmp_parse is called on the packet received. The resulting pdu
- * is passed to the callback routine for that session. If the callback
- * routine returns successfully, the pdu and it's request are deleted.
- */
-void snmp_read (fd_set *);
-
-
-
-/*
- * void
- * snmp_free_pdu(pdu)
- * struct snmp_pdu *pdu;
- *
- * Frees the pdu and any malloc'd data associated with it.
- */
-void snmp_free_pdu (struct snmp_pdu *);
-
-void snmp_free_var (struct variable_list *); /* frees just this one */
-
-void snmp_free_varbind(struct variable_list *var); /* frees all in list */
-
-/*
- * int snmp_select_info(numfds, fdset, timeout, block)
- * int *numfds;
- * fd_set *fdset;
- * struct timeval *timeout;
- * int *block;
- *
- * Returns info about what snmp requires from a select statement.
- * numfds is the number of fds in the list that are significant.
- * All file descriptors opened for SNMP are OR'd into the fdset.
- * If activity occurs on any of these file descriptors, snmp_read
- * should be called with that file descriptor set.
- *
- * The timeout is the latest time that SNMP can wait for a timeout. The
- * select should be done with the minimum time between timeout and any other
- * timeouts necessary. This should be checked upon each invocation of select.
- * If a timeout is received, snmp_timeout should be called to check if the
- * timeout was for SNMP. (snmp_timeout is idempotent)
- *
- * Block is 1 if the select is requested to block indefinitely, rather than
- * time out. If block is input as 1, the timeout value will be treated as
- * undefined, but it must be available for setting in snmp_select_info. On
- * return, if block is true, the value of timeout will be undefined.
- *
- * snmp_select_info returns the number of open sockets. (i.e. The number
- * of sessions open)
- */
-int snmp_select_info (int *, fd_set *, struct timeval *, int *);
-
-
-
-/*
- * void snmp_timeout();
- *
- * snmp_timeout should be called whenever the timeout from snmp_select_info
- * expires, but it is idempotent, so snmp_timeout can be polled (probably a
- * cpu expensive proposition). snmp_timeout checks to see if any of the
- * sessions have an outstanding request that has timed out. If it finds one
- * (or more), and that pdu has more retries available, a new packet is formed
- * from the pdu and is resent. If there are no more retries available, the
- * callback for the session is used to alert the user of the timeout.
- */
-
-void snmp_timeout (void);
-
-
-/*
- * This routine must be supplied by the application:
- *
- * u_char *authenticator(pdu, length, community, community_len)
- * u_char *pdu; The rest of the PDU to be authenticated
- * int *length; The length of the PDU (updated by the authenticator)
- * u_char *community; The community name to authenticate under.
- * int community_len The length of the community name.
- *
- * Returns the authenticated pdu, or NULL if authentication failed.
- * If null authentication is used, the authenticator in snmp_session can be
- * set to NULL(0).
- */
-
-
-
-/*
- * This routine must be supplied by the application:
- *
- * int callback(operation, session, reqid, pdu, magic)
- * int operation;
- * struct snmp_session *session; The session authenticated under.
- * int reqid; The request id of this pdu (0 for TRAP)
- * struct snmp_pdu *pdu; The pdu information.
- * void *magic A link to the data for this routine.
- *
- * Returns 1 if request was successful, 0 if it should be kept pending.
- * Any data in the pdu must be copied because it will be freed elsewhere.
- * Operations are defined below:
- */
-
-#define RECEIVED_MESSAGE 1
-#define TIMED_OUT 2
-#define SEND_FAILED 3
-
-long snmp_get_next_msgid(void);
-long snmp_get_next_reqid(void);
-long snmp_get_next_sessid(void);
-long snmp_get_next_transid(void);
-/* provide for backwards compatibility */
-void snmp_set_dump_packet(int);
-int snmp_get_dump_packet(void);
-void snmp_set_quick_print(int);
-int snmp_get_quick_print(void);
-void snmp_set_suffix_only(int);
-int snmp_get_suffix_only(void);
-void snmp_set_full_objid(int);
-int snmp_get_full_objid(void);
-void snmp_set_random_access(int);
-int snmp_get_random_access(void);
-
-int snmp_oid_compare (const oid *, size_t, const oid *, size_t);
-void init_snmp (const char *);
-u_char *snmp_pdu_build (struct snmp_pdu *, u_char *, size_t *);
-#ifdef USE_REVERSE_ASNENCODING
-u_char *snmp_pdu_rbuild (struct snmp_pdu *, u_char *, size_t *);
-#endif
-int snmpv3_parse(struct snmp_pdu *, u_char *, size_t *, u_char **, struct snmp_session *);
-int snmpv3_dparse(struct snmp_pdu *, u_char *, size_t *, u_char **, int);
-int snmpv3_packet_build(struct snmp_pdu *pdu, u_char *packet, size_t *out_length, u_char *pdu_data, size_t pdu_data_len);
-int snmpv3_packet_rbuild(struct snmp_pdu *pdu, u_char *packet, size_t *out_length, u_char *pdu_data, size_t pdu_data_len);
-int snmpv3_make_report(struct snmp_pdu *pdu, int error);
-int snmpv3_get_report_type(struct snmp_pdu *pdu);
-int snmp_pdu_parse(struct snmp_pdu *pdu, u_char *data, size_t *length);
-int snmp_pdu_dparse(struct snmp_pdu *pdu, u_char *data, size_t *length, int);
-u_char* snmpv3_scopedPDU_parse(struct snmp_pdu *pdu, u_char *cp, size_t *length);
-u_char* snmpv3_scopedPDU_dparse(struct snmp_pdu *pdu, u_char *cp, size_t *length, int);
-void snmp_store(const char *type);
-void snmp_shutdown(const char *type);
-struct variable_list *snmp_pdu_add_variable (struct snmp_pdu *, oid *, size_t, u_char, u_char *, size_t);
-struct variable_list *snmp_varlist_add_variable(struct variable_list **varlist,
- oid *name, size_t name_length, u_char type, u_char *value, size_t len);
-int hex_to_binary (const char *, u_char *);
-int ascii_to_binary (const char *, u_char *);
-int snmp_add_var (struct snmp_pdu *, oid*, size_t, char, const char *);
-oid *snmp_duplicate_objid(oid *objToCopy, size_t);
-u_int snmp_increment_statistic(int which);
-u_int snmp_increment_statistic_by(int which, int count);
-u_int snmp_get_statistic(int which);
-void snmp_init_statistics(void);
-int create_user_from_session(struct snmp_session *session);
-
-/* extended open */
-struct snmp_session *snmp_open_ex (struct snmp_session *,
- int (*fpre_parse) (struct snmp_session *, snmp_ipaddr),
- int (*fparse) (struct snmp_session *, struct snmp_pdu *, u_char *, size_t),
- int (*fpost_parse) (struct snmp_session *, struct snmp_pdu *, int),
- int (*fbuild) (struct snmp_session *, struct snmp_pdu *, u_char *, size_t *),
- int (*fcheck) (u_char *, size_t)
-);
-
-/* provided for backwards compatability. Don't use these functions.
- See snmp_debug.h and snmp_debug.c instead.
-*/
-#if HAVE_STDARG_H
-void DEBUGP (const char *, ...);
-#else
-void DEBUGP (va_alist);
-#endif
-void DEBUGPOID(oid *, size_t);
-void snmp_set_do_debugging (int);
-int snmp_get_do_debugging (void);
-
-#ifdef CMU_COMPATIBLE
-extern int snmp_dump_packet;
-extern int quick_print;
-#endif
-
-size_t snmp_socket_length (int family);
-
-/*
- * snmp_error - return error data
- * Inputs : address of errno, address of snmp_errno, address of string
- * Caller must free the string returned after use.
- */
-void snmp_error (struct snmp_session *, int *, int *, char **);
-/*
- * single session API.
- *
- * These functions perform similar actions as snmp_XX functions,
- * but operate on a single session only.
- *
- * Synopsis:
-
- void * sessp;
- struct snmp_session session, *ss;
- struct snmp_pdu *pdu, *response;
-
- snmp_sess_init(&session);
- session.retries = ...
- session.remote_port = ...
- sessp = snmp_sess_open(&session);
- ss = snmp_sess_session(sessp);
- if (ss == NULL)
- exit(1);
- ...
- if (ss->community) free(ss->community);
- ss->community = strdup(gateway);
- ss->community_len = strlen(gateway);
- ...
- snmp_sess_synch_response(sessp, pdu, &response);
- ...
- snmp_sess_close(sessp);
-
- * See also:
- * snmp_sess_synch_response, in snmp_client.h.
-
- * Notes:
- * 1. Invoke snmp_sess_session after snmp_sess_open.
- * 2. snmp_sess_session return value is an opaque pointer.
- * 3. Do NOT free memory returned by snmp_sess_session.
- * 4. Replace snmp_send(ss,pdu) with snmp_sess_send(sessp,pdu)
- */
-
-void snmp_sess_init (struct snmp_session *);
-void * snmp_sess_open (struct snmp_session *);
-struct snmp_session * snmp_sess_session (void *);
-
-/* use return value from snmp_sess_open as void * parameter */
-
-int snmp_sess_send (void *, struct snmp_pdu *);
-int snmp_sess_async_send (void *, struct snmp_pdu *,
- snmp_callback, void *);
-int snmp_sess_select_info (void *, int *, fd_set *,
- struct timeval *, int *);
-int snmp_sess_read (void *, fd_set *);
-void snmp_sess_timeout (void *);
-int snmp_sess_close (void *);
-
-void snmp_sess_error (void *, int *, int *, char **);
-void snmp_sess_perror (const char *prog_string, struct snmp_session *ss);
-
-/* end single session API */
-
-/* generic statistic counters */
-
-/* snmpv3 statistics */
-
-/* mpd stats */
-#define STAT_SNMPUNKNOWNSECURITYMODELS 0
-#define STAT_SNMPINVALIDMSGS 1
-#define STAT_SNMPUNKNOWNPDUHANDLERS 2
-#define STAT_MPD_STATS_START STAT_SNMPUNKNOWNSECURITYMODELS
-#define STAT_MPD_STATS_END STAT_SNMPUNKNOWNPDUHANDLERS
-
-/* usm stats */
-#define STAT_USMSTATSUNSUPPORTEDSECLEVELS 3
-#define STAT_USMSTATSNOTINTIMEWINDOWS 4
-#define STAT_USMSTATSUNKNOWNUSERNAMES 5
-#define STAT_USMSTATSUNKNOWNENGINEIDS 6
-#define STAT_USMSTATSWRONGDIGESTS 7
-#define STAT_USMSTATSDECRYPTIONERRORS 8
-#define STAT_USM_STATS_START STAT_USMSTATSUNSUPPORTEDSECLEVELS
-#define STAT_USM_STATS_END STAT_USMSTATSDECRYPTIONERRORS
-
-/* snmp counters */
-#define STAT_SNMPINPKTS 9
-#define STAT_SNMPOUTPKTS 10
-#define STAT_SNMPINBADVERSIONS 11
-#define STAT_SNMPINBADCOMMUNITYNAMES 12
-#define STAT_SNMPINBADCOMMUNITYUSES 13
-#define STAT_SNMPINASNPARSEERRS 14
-/* #define STAT_SNMPINBADTYPES 15 */
-#define STAT_SNMPINTOOBIGS 16
-#define STAT_SNMPINNOSUCHNAMES 17
-#define STAT_SNMPINBADVALUES 18
-#define STAT_SNMPINREADONLYS 19
-#define STAT_SNMPINGENERRS 20
-#define STAT_SNMPINTOTALREQVARS 21
-#define STAT_SNMPINTOTALSETVARS 22
-#define STAT_SNMPINGETREQUESTS 23
-#define STAT_SNMPINGETNEXTS 24
-#define STAT_SNMPINSETREQUESTS 25
-#define STAT_SNMPINGETRESPONSES 26
-#define STAT_SNMPINTRAPS 27
-#define STAT_SNMPOUTTOOBIGS 28
-#define STAT_SNMPOUTNOSUCHNAMES 29
-#define STAT_SNMPOUTBADVALUES 30
-/* #define STAT_SNMPOUTREADONLYS 31 */
-#define STAT_SNMPOUTGENERRS 32
-#define STAT_SNMPOUTGETREQUESTS 33
-#define STAT_SNMPOUTGETNEXTS 34
-#define STAT_SNMPOUTSETREQUESTS 35
-#define STAT_SNMPOUTGETRESPONSES 36
-#define STAT_SNMPOUTTRAPS 37
-/* AUTHTRAPENABLE 38 */
-#define STAT_SNMPSILENTDROPS 39
-#define STAT_SNMPPROXYDROPS 40
-#define STAT_SNMP_STATS_START STAT_SNMPINPKTS
-#define STAT_SNMP_STATS_END STAT_SNMPOUTTRAPS
-
-#define MAX_STATS 41
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SNMP_API_H */
diff --git a/trunk/src/examples/sparser.py b/trunk/src/examples/sparser.py
deleted file mode 100644
index 7c416da..0000000
--- a/trunk/src/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/trunk/src/examples/sql2dot.py b/trunk/src/examples/sql2dot.py
deleted file mode 100644
index 1156207..0000000
--- a/trunk/src/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/trunk/src/examples/stackish.py b/trunk/src/examples/stackish.py
deleted file mode 100644
index f80b4d6..0000000
--- a/trunk/src/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/trunk/src/examples/stateMachine2.py b/trunk/src/examples/stateMachine2.py
deleted file mode 100644
index eb6633d..0000000
--- a/trunk/src/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/trunk/src/examples/test_bibparse.py b/trunk/src/examples/test_bibparse.py
deleted file mode 100644
index 7440a66..0000000
--- a/trunk/src/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/trunk/src/examples/urlExtractor.py b/trunk/src/examples/urlExtractor.py
deleted file mode 100644
index 2c66d78..0000000
--- a/trunk/src/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/trunk/src/examples/urlExtractorNew.py b/trunk/src/examples/urlExtractorNew.py
deleted file mode 100644
index 0aac875..0000000
--- a/trunk/src/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 ::= <a href= URL>linkText</a>
-# 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/trunk/src/examples/verilogParse.py b/trunk/src/examples/verilogParse.py
deleted file mode 100644
index 2b7fd35..0000000
--- a/trunk/src/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+"]*(\.["+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::=<blocking_assignment> ;
- x||= <non_blocking_assignment> ;
- x||= if ( <expression> ) <statement_or_null>
- x||= if ( <expression> ) <statement_or_null> else <statement_or_null>
- x||= case ( <expression> ) <case_item>+ endcase
- x||= casez ( <expression> ) <case_item>+ endcase
- x||= casex ( <expression> ) <case_item>+ endcase
- x||= forever <statement>
- x||= repeat ( <expression> ) <statement>
- x||= while ( <expression> ) <statement>
- x||= for ( <assignment> ; <expression> ; <assignment> ) <statement>
- x||= <delay_or_event_control> <statement_or_null>
- x||= wait ( <expression> ) <statement_or_null>
- x||= -> <name_of_event> ;
- x||= <seq_block>
- x||= <par_block>
- x||= <task_enable>
- x||= <system_task_enable>
- x||= disable <name_of_task> ;
- x||= disable <name_of_block> ;
- x||= assign <assignment> ;
- x||= deassign <lvalue> ;
- x||= force <assignment> ;
- x||= release <lvalue> ;
- """
- 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::= <specparam_declaration>
- x||= <path_declaration>
- x||= <level_sensitive_path_declaration>
- x||= <edge_sensitive_path_declaration>
- x||= <system_timing_check>
- x||= <sdpd>
- """
- 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::= <parameter_declaration>
- x||= <input_declaration>
- x||= <output_declaration>
- x||= <inout_declaration>
- ?||= <net_declaration> (spec does not seem consistent for this item)
- x||= <reg_declaration>
- x||= <time_declaration>
- x||= <integer_declaration>
- x||= <real_declaration>
- x||= <event_declaration>
- x||= <gate_declaration>
- x||= <UDP_instantiation>
- x||= <module_instantiation>
- x||= <parameter_override>
- x||= <continuous_assign>
- x||= <specify_block>
- x||= <initial_statement>
- x||= <always_statement>
- x||= <task>
- x||= <function>
- """
- 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")
-
- """
- <UDP>
- ::= primitive <name_of_UDP> ( <name_of_variable> <,<name_of_variable>>* ) ;
- <UDP_declaration>+
- <UDP_initial_statement>?
- <table_definition>
- 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/trunk/src/examples/withAttribute.py b/trunk/src/examples/withAttribute.py
deleted file mode 100644
index 062c9ae..0000000
--- a/trunk/src/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 = """\
- <td align=right width=80><font size=2 face="New Times Roman,Times,Serif">&nbsp;49.950&nbsp;</font></td>
- <td align=left width=80><font size=2 face="New Times Roman,Times,Serif">&nbsp;50.950&nbsp;</font></td>
- <td align=right width=80><font size=2 face="New Times Roman,Times,Serif">&nbsp;51.950&nbsp;</font></td>
- """
-
-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("&nbsp;")
-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/trunk/src/examples/wordsToNum.py b/trunk/src/examples/wordsToNum.py
deleted file mode 100644
index 60c7c3d..0000000
--- a/trunk/src/examples/wordsToNum.py
+++ /dev/null
@@ -1,98 +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):
- print ("Expecting %s" % expected)
- numWords.runTests(s)
-
-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/trunk/src/genEpydoc.bat b/trunk/src/genEpydoc.bat
deleted file mode 100644
index 988954b..0000000
--- a/trunk/src/genEpydoc.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-xcopy /y ..\sourceforge\svn\trunk\src\pyparsing.py .
-c:\python27\python c:\python27\scripts\epydoc -v --name pyparsing -o htmldoc --inheritance listed --no-private pyparsing.py
diff --git a/trunk/src/makeRelease.bat b/trunk/src/makeRelease.bat
deleted file mode 100644
index 692e572..0000000
--- a/trunk/src/makeRelease.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-copy ..\sourceforge\svn\trunk\src\CHANGES .
-copy ..\sourceforge\svn\trunk\src\setup.py .
-copy ..\sourceforge\svn\trunk\src\pyparsing.py .
-copy ..\sourceforge\svn\trunk\src\MANIFEST.in_bdist .
-copy ..\sourceforge\svn\trunk\src\MANIFEST.in_src .
-copy ..\sourceforge\svn\trunk\src\examples\* .\examples\
-
-rmdir build
-rmdir dist
-
-copy/y MANIFEST.in_src MANIFEST.in
-if exist MANIFEST del MANIFEST
-python setup.py sdist --formats=gztar,zip
-
-copy/y MANIFEST.in_bdist MANIFEST.in
-if exist MANIFEST del MANIFEST
-
-python setup.py bdist_wheel
-python setup.py bdist_wininst --target-version=2.6 --plat-name=win32
-python setup.py bdist_wininst --target-version=2.7 --plat-name=win32
-python setup.py bdist_wininst --target-version=3.3 --plat-name=win32
-python setup.py bdist_wininst --target-version=3.4 --plat-name=win32
-python setup.py bdist_wininst --target-version=3.5 --plat-name=win32
-
diff --git a/trunk/src/pyparsing.py b/trunk/src/pyparsing.py
deleted file mode 100644
index 6a3f582..0000000
--- a/trunk/src/pyparsing.py
+++ /dev/null
@@ -1,5528 +0,0 @@
-# module pyparsing.py
-#
-# Copyright (c) 2003-2015 Paul T. McGuire
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__doc__ = \
-"""
-pyparsing module - Classes and methods to define and execute parsing grammars
-
-The pyparsing module is an alternative approach to creating and executing simple grammars,
-vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you
-don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
-provides a library of classes that you use to construct the grammar directly in Python.
-
-Here is a program to parse "Hello, World!" (or any greeting of the form C{"<salutation>, <addressee>!"})::
-
- 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 parsed results returned from L{I{ParserElement.parseString}<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.1.6"
-__versionTime__ = "07 Aug 2016 04:42 UTC"
-__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
-
-import string
-from weakref import ref as wkref
-import copy
-import sys
-import warnings
-import re
-import sre_constants
-import collections
-import pprint
-import traceback
-import types
-from datetime import datetime
-
-try:
- from _thread import RLock
-except ImportError:
- from threading import RLock
-
-try:
- from collections import OrderedDict as _OrderedDict
-except ImportError:
- try:
- from ordereddict import OrderedDict as _OrderedDict
- except ImportError:
- _OrderedDict = None
-
-#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
-
-__all__ = [
-'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
-'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
-'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
-'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
-'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
-'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter',
-'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
-'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
-'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
-'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
-'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
-'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
-'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
-'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity',
-'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
-'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
-'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
-'tokenMap', 'pyparsing_common',
-]
-
-system_version = tuple(sys.version_info)[:3]
-PY_3 = system_version[0] == 3
-if PY_3:
- _MAX_INT = sys.maxsize
- basestring = str
- unichr = chr
- _ustr = str
-
- # build list of single arg builtins, that can be used as parse actions
- singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
-
-else:
- _MAX_INT = sys.maxint
- range = xrange
-
- def _ustr(obj):
- """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
- str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
- then < returns the unicode object | encodes it with the default encoding | ... >.
- """
- if isinstance(obj,unicode):
- return obj
-
- try:
- # If this works, then _ustr(obj) has the same behaviour as str(obj), so
- # it won't break any existing code.
- return str(obj)
-
- except UnicodeEncodeError:
- # Else encode it
- ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
- xmlcharref = Regex('&#\d+;')
- xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
- return xmlcharref.transformString(ret)
-
- # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
- singleArgBuiltins = []
- import __builtin__
- for fname in "sum len sorted reversed list tuple set any all min max".split():
- try:
- singleArgBuiltins.append(getattr(__builtin__,fname))
- except AttributeError:
- continue
-
-_generatorType = type((y for y in range(1)))
-
-def _xml_escape(data):
- """Escape &, <, >, ", ', etc. in a string of data."""
-
- # ampersand must be replaced first
- from_symbols = '&><"\''
- to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
- for from_,to_ in zip(from_symbols, to_symbols):
- data = data.replace(from_, to_)
- return data
-
-class _Constants(object):
- pass
-
-alphas = string.ascii_uppercase + string.ascii_lowercase
-nums = "0123456789"
-hexnums = nums + "ABCDEFabcdef"
-alphanums = alphas + nums
-_bslash = chr(92)
-printables = "".join(c for c in string.printable if c not in string.whitespace)
-
-class ParseBaseException(Exception):
- """base exception class for all parsing runtime exceptions"""
- # Performance tuning: we construct a *lot* of these, so keep this
- # constructor as small and fast as possible
- def __init__( self, pstr, loc=0, msg=None, elem=None ):
- self.loc = loc
- if msg is None:
- self.msg = pstr
- self.pstr = ""
- else:
- self.msg = msg
- self.pstr = pstr
- self.parserElement = elem
- self.args = (pstr, loc, msg)
-
- def __getattr__( self, aname ):
- """supported attributes by name are:
- - lineno - returns the line number of the exception text
- - col - returns the column number of the exception text
- - line - returns the line containing the exception text
- """
- if( aname == "lineno" ):
- return lineno( self.loc, self.pstr )
- elif( aname in ("col", "column") ):
- return col( self.loc, self.pstr )
- elif( aname == "line" ):
- return line( self.loc, self.pstr )
- else:
- raise AttributeError(aname)
-
- def __str__( self ):
- return "%s (at char %d), (line:%d, col:%d)" % \
- ( self.msg, self.loc, self.lineno, self.column )
- def __repr__( self ):
- return _ustr(self)
- def markInputline( self, markerString = ">!<" ):
- """Extracts the exception line from the input string, and marks
- the location of the exception with a special symbol.
- """
- line_str = self.line
- line_column = self.column - 1
- if markerString:
- line_str = "".join((line_str[:line_column],
- markerString, line_str[line_column:]))
- return line_str.strip()
- def __dir__(self):
- return "lineno col line".split() + dir(type(self))
-
-class ParseException(ParseBaseException):
- """
- Exception thrown when parse expressions don't match class;
- supported attributes by name are:
- - lineno - returns the line number of the exception text
- - col - returns the column number of the exception text
- - line - returns the line containing the exception text
-
- Example::
- try:
- Word(nums).setName("integer").parseString("ABC")
- except ParseException as pe:
- print(pe)
- print("column: {}".format(pe.col))
-
- prints::
- Expected integer (at char 0), (line:1, col:1)
- column: 1
- """
- pass
-
-class ParseFatalException(ParseBaseException):
- """user-throwable exception thrown when inconsistent parse content
- is found; stops all parsing immediately"""
- pass
-
-class ParseSyntaxException(ParseFatalException):
- """just like C{L{ParseFatalException}}, but thrown internally when an
- C{L{ErrorStop<And._ErrorStop>}} ('-' operator) indicates that parsing is to stop immediately because
- an unbacktrackable syntax error has been found"""
- def __init__(self, pe):
- super(ParseSyntaxException, self).__init__(
- pe.pstr, pe.loc, pe.msg, pe.parserElement)
-
-#~ class ReparseException(ParseBaseException):
- #~ """Experimental class - parse actions can raise this exception to cause
- #~ pyparsing to reparse the input string:
- #~ - with a modified input string, and/or
- #~ - with a modified start location
- #~ Set the values of the ReparseException in the constructor, and raise the
- #~ exception in a parse action to cause pyparsing to use the new string/location.
- #~ Setting the values as None causes no change to be made.
- #~ """
- #~ def __init_( self, newstring, restartLoc ):
- #~ self.newParseText = newstring
- #~ self.reparseLoc = restartLoc
-
-class RecursiveGrammarException(Exception):
- """exception thrown by C{validate()} if the grammar could be improperly recursive"""
- def __init__( self, parseElementList ):
- self.parseElementTrace = parseElementList
-
- def __str__( self ):
- return "RecursiveGrammarException: %s" % self.parseElementTrace
-
-class _ParseResultsWithOffset(object):
- def __init__(self,p1,p2):
- self.tup = (p1,p2)
- def __getitem__(self,i):
- return self.tup[i]
- def __repr__(self):
- return repr(self.tup)
- def setOffset(self,i):
- self.tup = (self.tup[0],i)
-
-class ParseResults(object):
- """
- Structured parse results, to provide multiple means of access to the parsed data:
- - as a list (C{len(results)})
- - by list index (C{results[0], results[1]}, etc.)
- - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName})
-
- Example::
- integer = Word(nums)
- date_str = (integer.setResultsName("year") + '/'
- + integer.setResultsName("month") + '/'
- + integer.setResultsName("day"))
- # equivalent form:
- # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- result = date_str.parseString("1999/12/31")
- print(list(result))
- print(result[0])
- print(result['month'])
- print(result.day)
- print('month' in result)
- print('minutes' in result)
- print(result.dump())
- prints::
- ['1999', '/', '12', '/', '31']
- 1999
- 12
- 31
- True
- False
- ['1999', '/', '12', '/', '31']
- - day: 31
- - month: 12
- - year: 1999
- """
- def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
- if isinstance(toklist, cls):
- return toklist
- retobj = object.__new__(cls)
- retobj.__doinit = True
- return retobj
-
- # Performance tuning: we construct a *lot* of these, so keep this
- # constructor as small and fast as possible
- def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
- if self.__doinit:
- self.__doinit = False
- self.__name = None
- self.__parent = None
- self.__accumNames = {}
- self.__asList = asList
- self.__modal = modal
- if toklist is None:
- toklist = []
- if isinstance(toklist, list):
- self.__toklist = toklist[:]
- elif isinstance(toklist, _generatorType):
- self.__toklist = list(toklist)
- else:
- self.__toklist = [toklist]
- self.__tokdict = dict()
-
- if name is not None and name:
- if not modal:
- self.__accumNames[name] = 0
- if isinstance(name,int):
- name = _ustr(name) # will always return a str, but use _ustr for consistency
- self.__name = name
- if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
- if isinstance(toklist,basestring):
- toklist = [ toklist ]
- if asList:
- if isinstance(toklist,ParseResults):
- self[name] = _ParseResultsWithOffset(toklist.copy(),0)
- else:
- self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
- self[name].__name = name
- else:
- try:
- self[name] = toklist[0]
- except (KeyError,TypeError,IndexError):
- self[name] = toklist
-
- def __getitem__( self, i ):
- if isinstance( i, (int,slice) ):
- return self.__toklist[i]
- else:
- if i not in self.__accumNames:
- return self.__tokdict[i][-1][0]
- else:
- return ParseResults([ v[0] for v in self.__tokdict[i] ])
-
- def __setitem__( self, k, v, isinstance=isinstance ):
- if isinstance(v,_ParseResultsWithOffset):
- self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
- sub = v[0]
- elif isinstance(k,(int,slice)):
- self.__toklist[k] = v
- sub = v
- else:
- self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
- sub = v
- if isinstance(sub,ParseResults):
- sub.__parent = wkref(self)
-
- def __delitem__( self, i ):
- if isinstance(i,(int,slice)):
- mylen = len( self.__toklist )
- del self.__toklist[i]
-
- # convert int to slice
- if isinstance(i, int):
- if i < 0:
- i += mylen
- i = slice(i, i+1)
- # get removed indices
- removed = list(range(*i.indices(mylen)))
- removed.reverse()
- # fixup indices in token dictionary
- for name,occurrences in self.__tokdict.items():
- for j in removed:
- for k, (value, position) in enumerate(occurrences):
- occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
- else:
- del self.__tokdict[i]
-
- def __contains__( self, k ):
- return k in self.__tokdict
-
- def __len__( self ): return len( self.__toklist )
- def __bool__(self): return ( not not self.__toklist )
- __nonzero__ = __bool__
- def __iter__( self ): return iter( self.__toklist )
- def __reversed__( self ): return iter( self.__toklist[::-1] )
- def _iterkeys( self ):
- if hasattr(self.__tokdict, "iterkeys"):
- return self.__tokdict.iterkeys()
- else:
- return iter(self.__tokdict)
-
- def _itervalues( self ):
- return (self[k] for k in self._iterkeys())
-
- def _iteritems( self ):
- return ((k, self[k]) for k in self._iterkeys())
-
- if PY_3:
- keys = _iterkeys
- """Returns an iterator of all named result keys (Python 3.x only)."""
-
- values = _itervalues
- """Returns an iterator of all named result values (Python 3.x only)."""
-
- items = _iteritems
- """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
-
- else:
- iterkeys = _iterkeys
- """Returns an iterator of all named result keys (Python 2.x only)."""
-
- itervalues = _itervalues
- """Returns an iterator of all named result values (Python 2.x only)."""
-
- iteritems = _iteritems
- """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
-
- def keys( self ):
- """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
- return list(self.iterkeys())
-
- def values( self ):
- """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
- return list(self.itervalues())
-
- def items( self ):
- """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
- return list(self.iteritems())
-
- def haskeys( self ):
- """Since keys() returns an iterator, this method is helpful in bypassing
- code that looks for the existence of any defined results names."""
- return bool(self.__tokdict)
-
- def pop( self, *args, **kwargs):
- """
- Removes and returns item at specified index (default=C{last}).
- Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
- argument or an integer argument, it will use C{list} semantics
- and pop tokens from the list of parsed tokens. If passed a
- non-integer argument (most likely a string), it will use C{dict}
- semantics and pop the corresponding value from any defined
- results names. A second default return value argument is
- supported, just as in C{dict.pop()}.
-
- Example::
- def remove_first(tokens):
- tokens.pop(0)
- print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
- print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
-
- label = Word(alphas)
- patt = label("LABEL") + OneOrMore(Word(nums))
- print(patt.parseString("AAB 123 321").dump())
-
- # Use pop() in a parse action to remove named result (note that corresponding value is not
- # removed from list form of results)
- def remove_LABEL(tokens):
- tokens.pop("LABEL")
- return tokens
- patt.addParseAction(remove_LABEL)
- print(patt.parseString("AAB 123 321").dump())
- prints::
- ['AAB', '123', '321']
- - LABEL: AAB
-
- ['AAB', '123', '321']
- """
- if not args:
- args = [-1]
- for k,v in kwargs.items():
- if k == 'default':
- args = (args[0], v)
- else:
- raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
- if (isinstance(args[0], int) or
- len(args) == 1 or
- args[0] in self):
- index = args[0]
- ret = self[index]
- del self[index]
- return ret
- else:
- defaultvalue = args[1]
- return defaultvalue
-
- def get(self, key, defaultValue=None):
- """
- Returns named result matching the given key, or if there is no
- such name, then returns the given C{defaultValue} or C{None} if no
- C{defaultValue} is specified.
-
- Similar to C{dict.get()}.
-
- Example::
- integer = Word(nums)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- result = date_str.parseString("1999/12/31")
- print(result.get("year")) # -> '1999'
- print(result.get("hour", "not specified")) # -> 'not specified'
- print(result.get("hour")) # -> None
- """
- if key in self:
- return self[key]
- else:
- return defaultValue
-
- def insert( self, index, insStr ):
- """
- Inserts new element at location index in the list of parsed tokens.
-
- Similar to C{list.insert()}.
-
- Example::
- print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
-
- # use a parse action to insert the parse location in the front of the parsed results
- def insert_locn(locn, tokens):
- tokens.insert(0, locn)
- print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
- """
- self.__toklist.insert(index, insStr)
- # fixup indices in token dictionary
- for name,occurrences in self.__tokdict.items():
- for k, (value, position) in enumerate(occurrences):
- occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
-
- def append( self, item ):
- """
- Add single element to end of ParseResults list of elements.
-
- Example::
- print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
-
- # use a parse action to compute the sum of the parsed integers, and add it to the end
- def append_sum(tokens):
- tokens.append(sum(map(int, tokens)))
- print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
- """
- self.__toklist.append(item)
-
- def extend( self, itemseq ):
- """
- Add sequence of elements to end of ParseResults list of elements.
-
- Example::
- patt = OneOrMore(Word(alphas))
-
- # use a parse action to append the reverse of the matched strings, to make a palindrome
- def make_palindrome(tokens):
- tokens.extend(reversed([t[::-1] for t in tokens]))
- return ''.join(tokens)
- print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
- """
- if isinstance(itemseq, ParseResults):
- self += itemseq
- else:
- self.__toklist.extend(itemseq)
-
- def clear( self ):
- """
- Clear all elements and results names.
- """
- del self.__toklist[:]
- self.__tokdict.clear()
-
- def __getattr__( self, name ):
- try:
- return self[name]
- except KeyError:
- return ""
-
- if name in self.__tokdict:
- if name not in self.__accumNames:
- return self.__tokdict[name][-1][0]
- else:
- return ParseResults([ v[0] for v in self.__tokdict[name] ])
- else:
- return ""
-
- def __add__( self, other ):
- ret = self.copy()
- ret += other
- return ret
-
- def __iadd__( self, other ):
- if other.__tokdict:
- offset = len(self.__toklist)
- addoffset = lambda a: offset if a<0 else a+offset
- otheritems = other.__tokdict.items()
- otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
- for (k,vlist) in otheritems for v in vlist]
- for k,v in otherdictitems:
- self[k] = v
- if isinstance(v[0],ParseResults):
- v[0].__parent = wkref(self)
-
- self.__toklist += other.__toklist
- self.__accumNames.update( other.__accumNames )
- return self
-
- def __radd__(self, other):
- if isinstance(other,int) and other == 0:
- # useful for merging many ParseResults using sum() builtin
- return self.copy()
- else:
- # this may raise a TypeError - so be it
- return other + self
-
- def __repr__( self ):
- return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
-
- def __str__( self ):
- return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
-
- def _asStringList( self, sep='' ):
- out = []
- for item in self.__toklist:
- if out and sep:
- out.append(sep)
- if isinstance( item, ParseResults ):
- out += item._asStringList()
- else:
- out.append( _ustr(item) )
- return out
-
- def asList( self ):
- """
- Returns the parse results as a nested list of matching tokens, all converted to strings.
-
- Example::
- patt = OneOrMore(Word(alphas))
- result = patt.parseString("sldkj lsdkj sldkj")
- # even though the result prints in string-like form, it is actually a pyparsing ParseResults
- print(type(result), result) # -> <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']
- """
- return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
-
- def asDict( self ):
- """
- Returns the named parse results as a nested dictionary.
-
- Example::
- integer = Word(nums)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- result = date_str.parseString('12/31/1999')
- print(type(result), repr(result)) # -> <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"}
- """
- if PY_3:
- item_fn = self.items
- else:
- item_fn = self.iteritems
-
- def toItem(obj):
- if isinstance(obj, ParseResults):
- if obj.haskeys():
- return obj.asDict()
- else:
- return [toItem(v) for v in obj]
- else:
- return obj
-
- return dict((k,toItem(v)) for k,v in item_fn())
-
- def copy( self ):
- """
- Returns a new copy of a C{ParseResults} object.
- """
- ret = ParseResults( self.__toklist )
- ret.__tokdict = self.__tokdict.copy()
- ret.__parent = self.__parent
- ret.__accumNames.update( self.__accumNames )
- ret.__name = self.__name
- return ret
-
- def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
- """
- (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
- """
- nl = "\n"
- out = []
- namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
- for v in vlist)
- nextLevelIndent = indent + " "
-
- # collapse out indents if formatting is not desired
- if not formatted:
- indent = ""
- nextLevelIndent = ""
- nl = ""
-
- selfTag = None
- if doctag is not None:
- selfTag = doctag
- else:
- if self.__name:
- selfTag = self.__name
-
- if not selfTag:
- if namedItemsOnly:
- return ""
- else:
- selfTag = "ITEM"
-
- out += [ nl, indent, "<", selfTag, ">" ]
-
- for i,res in enumerate(self.__toklist):
- if isinstance(res,ParseResults):
- if i in namedItems:
- out += [ res.asXML(namedItems[i],
- namedItemsOnly and doctag is None,
- nextLevelIndent,
- formatted)]
- else:
- out += [ res.asXML(None,
- namedItemsOnly and doctag is None,
- nextLevelIndent,
- formatted)]
- else:
- # individual token, see if there is a name for it
- resTag = None
- if i in namedItems:
- resTag = namedItems[i]
- if not resTag:
- if namedItemsOnly:
- continue
- else:
- resTag = "ITEM"
- xmlBodyText = _xml_escape(_ustr(res))
- out += [ nl, nextLevelIndent, "<", resTag, ">",
- xmlBodyText,
- "</", resTag, ">" ]
-
- out += [ nl, indent, "</", selfTag, ">" ]
- return "".join(out)
-
- def __lookup(self,sub):
- for k,vlist in self.__tokdict.items():
- for v,loc in vlist:
- if sub is v:
- return k
- return None
-
- def getName(self):
- """
- Returns the results name for this token expression. Useful when several
- different expressions might match at a particular location.
-
- Example::
- integer = Word(nums)
- ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
- house_number_expr = Suppress('#') + Word(nums, alphanums)
- user_data = (Group(house_number_expr)("house_number")
- | Group(ssn_expr)("ssn")
- | Group(integer)("age"))
- user_info = OneOrMore(user_data)
-
- result = user_info.parseString("22 111-22-3333 #221B")
- for item in result:
- print(item.getName(), ':', item[0])
- prints::
- age : 22
- ssn : 111-22-3333
- house_number : 221B
- """
- if self.__name:
- return self.__name
- elif self.__parent:
- par = self.__parent()
- if par:
- return par.__lookup(self)
- else:
- return None
- elif (len(self) == 1 and
- len(self.__tokdict) == 1 and
- self.__tokdict.values()[0][0][1] in (0,-1)):
- return self.__tokdict.keys()[0]
- else:
- return None
-
- def dump(self, indent='', depth=0, full=True):
- """
- Diagnostic method for listing out the contents of a C{ParseResults}.
- Accepts an optional C{indent} argument so that this string can be embedded
- in a nested display of other data.
-
- Example::
- integer = Word(nums)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- result = date_str.parseString('12/31/1999')
- print(result.dump())
- prints::
- ['12', '/', '31', '/', '1999']
- - day: 1999
- - month: 31
- - year: 12
- """
- out = []
- NL = '\n'
- out.append( indent+_ustr(self.asList()) )
- if full:
- if self.haskeys():
- items = sorted(self.items())
- for k,v in items:
- if out:
- out.append(NL)
- out.append( "%s%s- %s: " % (indent,(' '*depth), k) )
- if isinstance(v,ParseResults):
- if v:
- out.append( v.dump(indent,depth+1) )
- else:
- out.append(_ustr(v))
- else:
- out.append(_ustr(v))
- elif any(isinstance(vv,ParseResults) for vv in self):
- v = self
- for i,vv in enumerate(v):
- if isinstance(vv,ParseResults):
- out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) ))
- else:
- out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv)))
-
- return "".join(out)
-
- def pprint(self, *args, **kwargs):
- """
- Pretty-printer for parsed results as a list, using the C{pprint} module.
- Accepts additional positional or keyword args as defined for the
- C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
-
- Example::
- ident = Word(alphas, alphanums)
- num = Word(nums)
- func = Forward()
- term = ident | num | Group('(' + func + ')')
- func <<= ident + Group(Optional(delimitedList(term)))
- result = func.parseString("fna a,b,(fnb c,d,200),100")
- result.pprint(width=40)
- prints::
- ['fna',
- ['a',
- 'b',
- ['(', 'fnb', ['c', 'd', '200'], ')'],
- '100']]
- """
- pprint.pprint(self.asList(), *args, **kwargs)
-
- # add support for pickle protocol
- def __getstate__(self):
- return ( self.__toklist,
- ( self.__tokdict.copy(),
- self.__parent is not None and self.__parent() or None,
- self.__accumNames,
- self.__name ) )
-
- def __setstate__(self,state):
- self.__toklist = state[0]
- (self.__tokdict,
- par,
- inAccumNames,
- self.__name) = state[1]
- self.__accumNames = {}
- self.__accumNames.update(inAccumNames)
- if par is not None:
- self.__parent = wkref(par)
- else:
- self.__parent = None
-
- def __getnewargs__(self):
- return self.__toklist, self.__name, self.__asList, self.__modal
-
- def __dir__(self):
- return (dir(type(self)) + list(self.keys()))
-
-collections.MutableMapping.register(ParseResults)
-
-def col (loc,strg):
- """Returns current column within a string, counting newlines as line separators.
- The first column is number 1.
-
- Note: the default parsing behavior is to expand tabs in the input string
- before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
- on parsing strings containing C{<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.
- """
- s = strg
- return 1 if loc<len(s) and s[loc] == '\n' else loc - s.rfind("\n", 0, loc)
-
-def lineno(loc,strg):
- """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 L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
- on parsing strings containing C{<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.
- """
- return strg.count("\n",0,loc) + 1
-
-def line( loc, strg ):
- """Returns the line of text containing loc within a string, counting newlines as line separators.
- """
- lastCR = strg.rfind("\n", 0, loc)
- nextCR = strg.find("\n", loc)
- if nextCR >= 0:
- return strg[lastCR+1:nextCR]
- else:
- return strg[lastCR+1:]
-
-def _defaultStartDebugAction( instring, loc, expr ):
- print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
-
-def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
- print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
-
-def _defaultExceptionDebugAction( instring, loc, expr, exc ):
- print ("Exception raised:" + _ustr(exc))
-
-def nullDebugAction(*args):
- """'Do-nothing' debug action, to suppress debugging output during parsing."""
- pass
-
-# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
-#~ 'decorator to trim function calls to match the arity of the target'
-#~ def _trim_arity(func, maxargs=3):
- #~ if func in singleArgBuiltins:
- #~ return lambda s,l,t: func(t)
- #~ limit = 0
- #~ foundArity = False
- #~ def wrapper(*args):
- #~ nonlocal limit,foundArity
- #~ while 1:
- #~ try:
- #~ ret = func(*args[limit:])
- #~ foundArity = True
- #~ return ret
- #~ except TypeError:
- #~ if limit == maxargs or foundArity:
- #~ raise
- #~ limit += 1
- #~ continue
- #~ return wrapper
-
-# this version is Python 2.x-3.x cross-compatible
-'decorator to trim function calls to match the arity of the target'
-def _trim_arity(func, maxargs=2):
- if func in singleArgBuiltins:
- return lambda s,l,t: func(t)
- limit = [0]
- foundArity = [False]
-
- # traceback return data structure changed in Py3.5 - normalize back to plain tuples
- if system_version[:2] >= (3,5):
- def extract_stack():
- # 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()[offset]
- return [(frame_summary.filename, frame_summary.lineno)]
- def extract_tb(tb):
- frames = traceback.extract_tb(tb)
- frame_summary = frames[-1]
- return [(frame_summary.filename, frame_summary.lineno)]
- else:
- extract_stack = traceback.extract_stack
- extract_tb = traceback.extract_tb
-
- # synthesize what would be returned by traceback.extract_stack at the call to
- # user's parse action 'func', so that we don't incur call penalty at parse time
-
- LINE_DIFF = 6
- # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND
- # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
- this_line = extract_stack()[-1]
- pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
-
- def wrapper(*args):
- while 1:
- try:
- ret = func(*args[limit[0]:])
- foundArity[0] = True
- return ret
- except TypeError:
- # re-raise TypeErrors if they did not come from our arity testing
- if foundArity[0]:
- raise
- else:
- try:
- tb = sys.exc_info()[-1]
- if not extract_tb(tb)[-1][:2] == pa_call_line_synth:
- raise
- finally:
- del tb
-
- if limit[0] <= maxargs:
- limit[0] += 1
- continue
- raise
-
- # copy func name to wrapper for sensible debug output
- func_name = "<parse action>"
- try:
- func_name = getattr(func, '__name__',
- getattr(func, '__class__').__name__)
- except Exception:
- func_name = str(func)
- wrapper.__name__ = func_name
-
- return wrapper
-
-class ParserElement(object):
- """Abstract base level parser element class."""
- DEFAULT_WHITE_CHARS = " \n\t\r"
- verbose_stacktrace = False
-
- @staticmethod
- def setDefaultWhitespaceChars( chars ):
- r"""
- Overrides the default whitespace chars
-
- Example::
- # default whitespace chars are space, <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']
- """
- ParserElement.DEFAULT_WHITE_CHARS = chars
-
- @staticmethod
- def inlineLiteralsUsing(cls):
- """
- Set class to be used for inclusion of string literals into a parser.
-
- Example::
- # default literal class used is Literal
- integer = Word(nums)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31']
-
-
- # change to Suppress
- ParserElement.inlineLiteralsUsing(Suppress)
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
-
- date_str.parseString("1999/12/31") # -> ['1999', '12', '31']
- """
- ParserElement._literalStringClass = cls
-
- def __init__( self, savelist=False ):
- self.parseAction = list()
- self.failAction = None
- #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall
- self.strRepr = None
- self.resultsName = None
- self.saveAsList = savelist
- self.skipWhitespace = True
- self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
- self.copyDefaultWhiteChars = True
- self.mayReturnEmpty = False # used when checking for left-recursion
- self.keepTabs = False
- self.ignoreExprs = list()
- self.debug = False
- self.streamlined = False
- self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
- self.errmsg = ""
- self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
- self.debugActions = ( None, None, None ) #custom debug actions
- self.re = None
- self.callPreparse = True # used to avoid redundant calls to preParse
- self.callDuringTry = False
-
- def copy( self ):
- """
- Make a copy of this C{ParserElement}. Useful for defining different parse actions
- for the same parsing pattern, using copies of the original parse element.
-
- Example::
- integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
- integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
- integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
-
- print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
- prints::
- [5120, 100, 655360, 268435456]
- Equivalent form of C{expr.copy()} is just C{expr()}::
- integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
- """
- cpy = copy.copy( self )
- cpy.parseAction = self.parseAction[:]
- cpy.ignoreExprs = self.ignoreExprs[:]
- if self.copyDefaultWhiteChars:
- cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
- return cpy
-
- def setName( self, name ):
- """
- Define name for this expression, makes exception messages clearer.
-
- Example::
- Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
- Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1)
- """
- self.name = name
- self.errmsg = "Expected " + self.name
- if hasattr(self,"exception"):
- self.exception.msg = self.errmsg
- return self
-
- def setResultsName( self, name, listAllMatches=False ):
- """
- Define name for referencing matching tokens as a nested attribute
- of the returned parse results.
- NOTE: this returns a *copy* of the original C{ParserElement} object;
- this is so that the client can define a basic element, such as an
- integer, and reference it in multiple places with different names.
-
- You can also set results names using the abbreviated syntax,
- C{expr("name")} in place of C{expr.setResultsName("name")} -
- see L{I{__call__}<__call__>}.
-
- Example::
- date_str = (integer.setResultsName("year") + '/'
- + integer.setResultsName("month") + '/'
- + integer.setResultsName("day"))
-
- # equivalent form:
- date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
- """
- newself = self.copy()
- if name.endswith("*"):
- name = name[:-1]
- listAllMatches=True
- newself.resultsName = name
- newself.modalResults = not listAllMatches
- return newself
-
- def setBreak(self,breakFlag = True):
- """Method to invoke the Python pdb debugger when this element is
- about to be parsed. Set C{breakFlag} to True to enable, False to
- disable.
- """
- if breakFlag:
- _parseMethod = self._parse
- def breaker(instring, loc, doActions=True, callPreParse=True):
- import pdb
- pdb.set_trace()
- return _parseMethod( instring, loc, doActions, callPreParse )
- breaker._originalParseMethod = _parseMethod
- self._parse = breaker
- else:
- if hasattr(self._parse,"_originalParseMethod"):
- self._parse = self._parse._originalParseMethod
- return self
-
- def setParseAction( self, *fns, **kwargs ):
- """
- Define action to perform when successfully matching parse element definition.
- Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
- C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
- - s = the original string being parsed (see note below)
- - loc = the location of the matching substring
- - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
- If the functions in fns modify the tokens, they can return them as the return
- value from fn, and the modified list of tokens will replace the original.
- Otherwise, fn does not need to return any value.
-
- Optional keyword arguments:
- - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
-
- Note: the default parsing behavior is to expand tabs in the input string
- before starting the parsing process. See L{I{parseString}<parseString>} for more information
- on parsing strings containing C{<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]
- """
- self.parseAction = list(map(_trim_arity, list(fns)))
- self.callDuringTry = kwargs.get("callDuringTry", False)
- return self
-
- def addParseAction( self, *fns, **kwargs ):
- """
- Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
-
- See examples in L{I{copy}<copy>}.
- """
- self.parseAction += list(map(_trim_arity, list(fns)))
- self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
- return self
-
- def addCondition(self, *fns, **kwargs):
- """Add a boolean predicate function to expression's list of parse actions. See
- L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction},
- functions passed to C{addCondition} need to return boolean success/fail of the condition.
-
- Optional keyword arguments:
- - message = define a custom message to be used in the raised exception
- - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
-
- Example::
- integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
- year_int = integer.copy()
- year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
- date_str = year_int + '/' + integer + '/' + integer
-
- result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
- """
- msg = kwargs.get("message", "failed user-defined condition")
- exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
- for fn in fns:
- def pa(s,l,t):
- if not bool(_trim_arity(fn)(s,l,t)):
- raise exc_type(s,l,msg)
- self.parseAction.append(pa)
- self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
- return self
-
- def setFailAction( self, fn ):
- """Define action to perform if parsing fails at this expression.
- Fail acton fn is a callable function that takes the arguments
- C{fn(s,loc,expr,err)} where:
- - s = string being parsed
- - loc = location where expression match was attempted and failed
- - expr = the parse expression that failed
- - err = the exception thrown
- The function returns no value. It may throw C{L{ParseFatalException}}
- if it is desired to stop parsing immediately."""
- self.failAction = fn
- return self
-
- def _skipIgnorables( self, instring, loc ):
- exprsFound = True
- while exprsFound:
- exprsFound = False
- for e in self.ignoreExprs:
- try:
- while 1:
- loc,dummy = e._parse( instring, loc )
- exprsFound = True
- except ParseException:
- pass
- return loc
-
- def preParse( self, instring, loc ):
- if self.ignoreExprs:
- loc = self._skipIgnorables( instring, loc )
-
- if self.skipWhitespace:
- wt = self.whiteChars
- instrlen = len(instring)
- while loc < instrlen and instring[loc] in wt:
- loc += 1
-
- return loc
-
- def parseImpl( self, instring, loc, doActions=True ):
- return loc, []
-
- def postParse( self, instring, loc, tokenlist ):
- return tokenlist
-
- #~ @profile
- def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
- debugging = ( self.debug ) #and doActions )
-
- if debugging or self.failAction:
- #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
- if (self.debugActions[0] ):
- self.debugActions[0]( instring, loc, self )
- if callPreParse and self.callPreparse:
- preloc = self.preParse( instring, loc )
- else:
- preloc = loc
- tokensStart = preloc
- try:
- try:
- loc,tokens = self.parseImpl( instring, preloc, doActions )
- except IndexError:
- raise ParseException( instring, len(instring), self.errmsg, self )
- except ParseBaseException as err:
- #~ print ("Exception raised:", err)
- if self.debugActions[2]:
- self.debugActions[2]( instring, tokensStart, self, err )
- if self.failAction:
- self.failAction( instring, tokensStart, self, err )
- raise
- else:
- if callPreParse and self.callPreparse:
- preloc = self.preParse( instring, loc )
- else:
- preloc = loc
- tokensStart = preloc
- if self.mayIndexError or loc >= len(instring):
- try:
- loc,tokens = self.parseImpl( instring, preloc, doActions )
- except IndexError:
- raise ParseException( instring, len(instring), self.errmsg, self )
- else:
- loc,tokens = self.parseImpl( instring, preloc, doActions )
-
- tokens = self.postParse( instring, loc, tokens )
-
- retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
- if self.parseAction and (doActions or self.callDuringTry):
- if debugging:
- try:
- for fn in self.parseAction:
- tokens = fn( instring, tokensStart, retTokens )
- if tokens is not None:
- retTokens = ParseResults( tokens,
- self.resultsName,
- asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
- modal=self.modalResults )
- except ParseBaseException as err:
- #~ print "Exception raised in user parse action:", err
- if (self.debugActions[2] ):
- self.debugActions[2]( instring, tokensStart, self, err )
- raise
- else:
- for fn in self.parseAction:
- tokens = fn( instring, tokensStart, retTokens )
- if tokens is not None:
- retTokens = ParseResults( tokens,
- self.resultsName,
- asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
- modal=self.modalResults )
-
- if debugging:
- #~ print ("Matched",self,"->",retTokens.asList())
- if (self.debugActions[1] ):
- self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
-
- return loc, retTokens
-
- def tryParse( self, instring, loc ):
- try:
- return self._parse( instring, loc, doActions=False )[0]
- except ParseFatalException:
- raise ParseException( instring, loc, self.errmsg, self)
-
- def canParseNext(self, instring, loc):
- try:
- self.tryParse(instring, loc)
- except (ParseException, IndexError):
- return False
- else:
- return True
-
- class _UnboundedCache(object):
- def __init__(self):
- cache = {}
- self.not_in_cache = not_in_cache = object()
-
- def get(self, key):
- return cache.get(key, not_in_cache)
-
- def set(self, key, value):
- cache[key] = value
-
- def clear(self):
- cache.clear()
-
- self.get = types.MethodType(get, self)
- self.set = types.MethodType(set, self)
- self.clear = types.MethodType(clear, self)
-
- if _OrderedDict is not None:
- class _FifoCache(object):
- def __init__(self, size):
- self.not_in_cache = not_in_cache = object()
-
- cache = _OrderedDict()
-
- def get(self, key):
- return cache.get(key, not_in_cache)
-
- def set(self, key, value):
- cache[key] = value
- if len(cache) > size:
- cache.popitem(False)
-
- def clear(self):
- cache.clear()
-
- self.get = types.MethodType(get, self)
- self.set = types.MethodType(set, self)
- self.clear = types.MethodType(clear, self)
-
- else:
- class _FifoCache(object):
- def __init__(self, size):
- self.not_in_cache = not_in_cache = object()
-
- cache = {}
- key_fifo = collections.deque([], size)
-
- def get(self, key):
- return cache.get(key, not_in_cache)
-
- def set(self, key, value):
- cache[key] = value
- if len(cache) > size:
- cache.pop(key_fifo.popleft(), None)
- key_fifo.append(key)
-
- def clear(self):
- cache.clear()
- key_fifo.clear()
-
- self.get = types.MethodType(get, self)
- self.set = types.MethodType(set, self)
- self.clear = types.MethodType(clear, self)
-
- # argument cache for optimizing repeated calls when backtracking through recursive expressions
- packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
- packrat_cache_lock = RLock()
- packrat_cache_stats = [0, 0]
-
- # this method gets repeatedly called during backtracking with the same arguments -
- # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
- def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
- HIT, MISS = 0, 1
- lookup = (self, instring, loc, callPreParse, doActions)
- with ParserElement.packrat_cache_lock:
- cache = ParserElement.packrat_cache
- value = cache.get(lookup)
- if value is cache.not_in_cache:
- ParserElement.packrat_cache_stats[MISS] += 1
- try:
- value = self._parseNoCache(instring, loc, doActions, callPreParse)
- except ParseBaseException as pe:
- # cache a copy of the exception, without the traceback
- cache.set(lookup, pe.__class__(*pe.args))
- raise
- else:
- cache.set(lookup, (value[0], value[1].copy()))
- return value
- else:
- ParserElement.packrat_cache_stats[HIT] += 1
- if isinstance(value, Exception):
- raise value
- return (value[0], value[1].copy())
-
- _parse = _parseNoCache
-
- @staticmethod
- def resetCache():
- ParserElement.packrat_cache.clear()
- ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
-
- _packratEnabled = False
- @staticmethod
- def enablePackrat(cache_size_limit=128):
- """Enables "packrat" parsing, which adds memoizing to the parsing logic.
- Repeated parse attempts at the same string location (which happens
- often in many complex grammars) can immediately return a cached value,
- instead of re-executing parsing/validating code. Memoizing is done of
- both valid results and parsing exceptions.
-
- Parameters:
- - cache_size_limit - (default=C{128}) - if an integer value is provided
- will limit the size of the packrat cache; if None is passed, then
- the cache size will be unbounded; if 0 is passed, the cache will
- be effectively disabled.
-
- This speedup may break existing programs that use parse actions that
- have side-effects. For this reason, packrat parsing is disabled when
- you first import pyparsing. To activate the packrat feature, your
- program must call the class method C{ParserElement.enablePackrat()}. If
- your program uses C{psyco} to "compile as you go", you must call
- C{enablePackrat} before calling C{psyco.full()}. If you do not do this,
- Python will crash. For best results, call C{enablePackrat()} immediately
- after importing pyparsing.
-
- Example::
- import pyparsing
- pyparsing.ParserElement.enablePackrat()
- """
- if not ParserElement._packratEnabled:
- ParserElement._packratEnabled = True
- if cache_size_limit is None:
- ParserElement.packrat_cache = ParserElement._UnboundedCache()
- else:
- ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
- ParserElement._parse = ParserElement._parseCache
-
- def parseString( self, instring, parseAll=False ):
- """
- Execute the parse expression with the given string.
- This is the main interface to the client code, once the complete
- expression has been built.
-
- If you want the grammar to require that the entire input string be
- successfully parsed, then set C{parseAll} to True (equivalent to ending
- the grammar with C{L{StringEnd()}}).
-
- Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
- in order to report proper column numbers in parse actions.
- If the input string contains tabs and
- the grammar uses parse actions that use the C{loc} argument to index into the
- string being parsed, you can ensure you have a consistent view of the input
- string by:
- - calling C{parseWithTabs} on your grammar before calling C{parseString}
- (see L{I{parseWithTabs}<parseWithTabs>})
- - define your parse action using the full C{(s,loc,toks)} signature, and
- reference the input string using the parse action's C{s} argument
- - explictly expand the tabs in your input string before calling
- C{parseString}
-
- Example::
- Word('a').parseString('aaaaabaaa') # -> ['aaaaa']
- Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text
- """
- ParserElement.resetCache()
- if not self.streamlined:
- self.streamline()
- #~ self.saveAsList = True
- for e in self.ignoreExprs:
- e.streamline()
- if not self.keepTabs:
- instring = instring.expandtabs()
- try:
- loc, tokens = self._parse( instring, 0 )
- if parseAll:
- loc = self.preParse( instring, loc )
- se = Empty() + StringEnd()
- se._parse( instring, loc )
- except ParseBaseException as exc:
- if ParserElement.verbose_stacktrace:
- raise
- else:
- # catch and re-raise exception from here, clears out pyparsing internal stack trace
- raise exc
- else:
- return tokens
-
- def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
- """
- Scan the input string for expression matches. Each match will return the
- matching tokens, start location, and end location. May be called with optional
- C{maxMatches} argument, to clip scanning after 'n' matches are found. If
- C{overlap} is specified, then overlapping matches will be reported.
-
- Note that the start and end locations are reported relative to the string
- being parsed. See L{I{parseString}<parseString>} for more information on parsing
- strings with embedded tabs.
-
- Example::
- source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
- print(source)
- for tokens,start,end in Word(alphas).scanString(source):
- print(' '*start + '^'*(end-start))
- print(' '*start + tokens[0])
-
- prints::
-
- sldjf123lsdjjkf345sldkjf879lkjsfd987
- ^^^^^
- sldjf
- ^^^^^^^
- lsdjjkf
- ^^^^^^
- sldkjf
- ^^^^^^
- lkjsfd
- """
- if not self.streamlined:
- self.streamline()
- for e in self.ignoreExprs:
- e.streamline()
-
- if not self.keepTabs:
- instring = _ustr(instring).expandtabs()
- instrlen = len(instring)
- loc = 0
- preparseFn = self.preParse
- parseFn = self._parse
- ParserElement.resetCache()
- matches = 0
- try:
- while loc <= instrlen and matches < maxMatches:
- try:
- preloc = preparseFn( instring, loc )
- nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
- except ParseException:
- loc = preloc+1
- else:
- if nextLoc > loc:
- matches += 1
- yield tokens, preloc, nextLoc
- if overlap:
- nextloc = preparseFn( instring, loc )
- if nextloc > loc:
- loc = nextLoc
- else:
- loc += 1
- else:
- loc = nextLoc
- else:
- loc = preloc+1
- except ParseBaseException as exc:
- if ParserElement.verbose_stacktrace:
- raise
- else:
- # catch and re-raise exception from here, clears out pyparsing internal stack trace
- raise exc
-
- def transformString( self, instring ):
- """
- Extension to C{L{scanString}}, to modify matching text with modified tokens that may
- be returned from a parse action. To use C{transformString}, define a grammar and
- attach a parse action to it that modifies the returned token list.
- Invoking C{transformString()} on a target string will then scan for matches,
- and replace the matched text patterns according to the logic in the parse
- action. C{transformString()} returns the resulting transformed string.
-
- Example::
- wd = Word(alphas)
- wd.setParseAction(lambda toks: toks[0].title())
-
- print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
- Prints::
- Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
- """
- out = []
- lastE = 0
- # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
- # keep string locs straight between transformString and scanString
- self.keepTabs = True
- try:
- for t,s,e in self.scanString( instring ):
- out.append( instring[lastE:s] )
- if t:
- if isinstance(t,ParseResults):
- out += t.asList()
- elif isinstance(t,list):
- out += t
- else:
- out.append(t)
- lastE = e
- out.append(instring[lastE:])
- out = [o for o in out if o]
- return "".join(map(_ustr,_flatten(out)))
- except ParseBaseException as exc:
- if ParserElement.verbose_stacktrace:
- raise
- else:
- # catch and re-raise exception from here, clears out pyparsing internal stack trace
- raise exc
-
- def searchString( self, instring, maxMatches=_MAX_INT ):
- """
- Another extension to C{L{scanString}}, simplifying the access to the tokens found
- to match the given parse expression. May be called with optional
- C{maxMatches} argument, to clip searching after 'n' matches are found.
-
- Example::
- # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
- cap_word = Word(alphas.upper(), alphas.lower())
-
- print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
- prints::
- ['More', 'Iron', 'Lead', 'Gold', 'I']
- """
- try:
- return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
- except ParseBaseException as exc:
- if ParserElement.verbose_stacktrace:
- raise
- else:
- # catch and re-raise exception from here, clears out pyparsing internal stack trace
- raise exc
-
- def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
- """
- Generator method to split a string using the given expression as a separator.
- May be called with optional C{maxsplit} argument, to limit the number of splits;
- and the optional C{includeSeparators} argument (default=C{False}), if the separating
- matching text should be included in the split results.
-
- Example::
- punc = oneOf(list(".,;:/-!?"))
- print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
- prints::
- ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
- """
- splits = 0
- last = 0
- for t,s,e in self.scanString(instring, maxMatches=maxsplit):
- yield instring[last:s]
- if includeSeparators:
- yield t[0]
- last = e
- yield instring[last:]
-
- def __add__(self, other ):
- """
- Implementation of + operator - returns C{L{And}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return And( [ self, other ] )
-
- def __radd__(self, other ):
- """
- Implementation of + operator when left operand is not a C{L{ParserElement}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return other + self
-
- def __sub__(self, other):
- """
- Implementation of - operator, returns C{L{And}} with error stop
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return And( [ self, And._ErrorStop(), other ] )
-
- def __rsub__(self, other ):
- """
- Implementation of - operator when left operand is not a C{L{ParserElement}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return other - self
-
- def __mul__(self,other):
- """
- Implementation of * operator, allows use of C{expr * 3} in place of
- C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer
- tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples
- may also include C{None} as in:
- - C{expr*(n,None)} or C{expr*(n,)} is equivalent
- to C{expr*n + L{ZeroOrMore}(expr)}
- (read as "at least n instances of C{expr}")
- - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
- (read as "0 to n instances of C{expr}")
- - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
- - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
-
- Note that C{expr*(None,n)} does not raise an exception if
- more than n exprs exist in the input stream; that is,
- C{expr*(None,n)} does not enforce a maximum number of expr
- occurrences. If this behavior is desired, then write
- C{expr*(None,n) + ~expr}
- """
- if isinstance(other,int):
- minElements, optElements = other,0
- elif isinstance(other,tuple):
- other = (other + (None, None))[:2]
- if other[0] is None:
- other = (0, other[1])
- if isinstance(other[0],int) and other[1] is None:
- if other[0] == 0:
- return ZeroOrMore(self)
- if other[0] == 1:
- return OneOrMore(self)
- else:
- return self*other[0] + ZeroOrMore(self)
- elif isinstance(other[0],int) and isinstance(other[1],int):
- minElements, optElements = other
- optElements -= minElements
- else:
- raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
- else:
- raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
-
- if minElements < 0:
- raise ValueError("cannot multiply ParserElement by negative value")
- if optElements < 0:
- raise ValueError("second tuple value must be greater or equal to first tuple value")
- if minElements == optElements == 0:
- raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
-
- if (optElements):
- def makeOptionalList(n):
- if n>1:
- return Optional(self + makeOptionalList(n-1))
- else:
- return Optional(self)
- if minElements:
- if minElements == 1:
- ret = self + makeOptionalList(optElements)
- else:
- ret = And([self]*minElements) + makeOptionalList(optElements)
- else:
- ret = makeOptionalList(optElements)
- else:
- if minElements == 1:
- ret = self
- else:
- ret = And([self]*minElements)
- return ret
-
- def __rmul__(self, other):
- return self.__mul__(other)
-
- def __or__(self, other ):
- """
- Implementation of | operator - returns C{L{MatchFirst}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return MatchFirst( [ self, other ] )
-
- def __ror__(self, other ):
- """
- Implementation of | operator when left operand is not a C{L{ParserElement}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return other | self
-
- def __xor__(self, other ):
- """
- Implementation of ^ operator - returns C{L{Or}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return Or( [ self, other ] )
-
- def __rxor__(self, other ):
- """
- Implementation of ^ operator when left operand is not a C{L{ParserElement}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return other ^ self
-
- def __and__(self, other ):
- """
- Implementation of & operator - returns C{L{Each}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return Each( [ self, other ] )
-
- def __rand__(self, other ):
- """
- Implementation of & operator when left operand is not a C{L{ParserElement}}
- """
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- if not isinstance( other, ParserElement ):
- warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
- SyntaxWarning, stacklevel=2)
- return None
- return other & self
-
- def __invert__( self ):
- """
- Implementation of ~ operator - returns C{L{NotAny}}
- """
- return NotAny( self )
-
- def __call__(self, name=None):
- """
- Shortcut for C{L{setResultsName}}, with C{listAllMatches=default}.
-
- If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
- passed as C{True}.
-
- If C{name} is omitted, same as calling C{L{copy}}.
-
- Example::
- # these are equivalent
- userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
- userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")
- """
- if name is not None:
- return self.setResultsName(name)
- else:
- return self.copy()
-
- def suppress( self ):
- """
- Suppresses the output of this C{ParserElement}; useful to keep punctuation from
- cluttering up returned output.
- """
- return Suppress( self )
-
- def leaveWhitespace( self ):
- """
- Disables the skipping of whitespace before matching the characters in the
- C{ParserElement}'s defined pattern. This is normally only used internally by
- the pyparsing module, but may be needed in some whitespace-sensitive grammars.
- """
- self.skipWhitespace = False
- return self
-
- def setWhitespaceChars( self, chars ):
- """
- Overrides the default whitespace chars
- """
- self.skipWhitespace = True
- self.whiteChars = chars
- self.copyDefaultWhiteChars = False
- return self
-
- def parseWithTabs( self ):
- """
- Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string.
- Must be called before C{parseString} when the input grammar contains elements that
- match C{<TAB>} characters.
- """
- self.keepTabs = True
- return self
-
- def ignore( self, other ):
- """
- Define expression to be ignored (e.g., comments) while doing pattern
- matching; may be called repeatedly, to define multiple comment or other
- ignorable patterns.
-
- Example::
- patt = OneOrMore(Word(alphas))
- patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
-
- patt.ignore(cStyleComment)
- patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
- """
- if isinstance(other, basestring):
- other = Suppress(other)
-
- if isinstance( other, Suppress ):
- if other not in self.ignoreExprs:
- self.ignoreExprs.append(other)
- else:
- self.ignoreExprs.append( Suppress( other.copy() ) )
- return self
-
- def setDebugActions( self, startAction, successAction, exceptionAction ):
- """
- Enable display of debugging messages while doing pattern matching.
- """
- self.debugActions = (startAction or _defaultStartDebugAction,
- successAction or _defaultSuccessDebugAction,
- exceptionAction or _defaultExceptionDebugAction)
- self.debug = True
- return self
-
- def setDebug( self, flag=True ):
- """
- Enable display of debugging messages while doing pattern matching.
- Set C{flag} to True to enable, False to disable.
- """
- if flag:
- self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
- else:
- self.debug = False
- return self
-
- def __str__( self ):
- return self.name
-
- def __repr__( self ):
- return _ustr(self)
-
- def streamline( self ):
- self.streamlined = True
- self.strRepr = None
- return self
-
- def checkRecursion( self, parseElementList ):
- pass
-
- def validate( self, validateTrace=[] ):
- """
- Check defined expressions for valid structure, check for infinite recursive definitions.
- """
- self.checkRecursion( [] )
-
- def parseFile( self, file_or_filename, parseAll=False ):
- """
- Execute the parse expression on the given file or filename.
- If a filename is specified (instead of a file object),
- the entire file is opened, read, and closed before parsing.
- """
- try:
- file_contents = file_or_filename.read()
- except AttributeError:
- with open(file_or_filename, "r") as f:
- file_contents = f.read()
- try:
- return self.parseString(file_contents, parseAll)
- except ParseBaseException as exc:
- if ParserElement.verbose_stacktrace:
- raise
- else:
- # catch and re-raise exception from here, clears out pyparsing internal stack trace
- raise exc
-
- def __eq__(self,other):
- if isinstance(other, ParserElement):
- return self is other or vars(self) == vars(other)
- elif isinstance(other, basestring):
- return self.matches(other)
- else:
- return super(ParserElement,self)==other
-
- def __ne__(self,other):
- return not (self == other)
-
- def __hash__(self):
- return hash(id(self))
-
- def __req__(self,other):
- return self == other
-
- def __rne__(self,other):
- return not (self == other)
-
- def matches(self, testString, parseAll=True):
- """
- Method for quick testing of a parser against a test string. Good for simple
- inline microtests of sub expressions while building up larger parser.0
-
- Parameters:
- - testString - to test against this expression for a match
- - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
-
- Example::
- expr = Word(nums)
- assert expr.matches("100")
- """
- try:
- self.parseString(_ustr(testString), parseAll=parseAll)
- return True
- except ParseBaseException:
- return False
-
- def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
- """
- Execute the parse expression on a series of test strings, showing each
- test, the parsed results or where the parse failed. Quick and easy way to
- run a parse expression against a list of sample strings.
-
- Parameters:
- - tests - a list of separate test strings, or a multiline string of test strings
- - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
- - comment - (default=C{'#'}) - expression for indicating embedded comments in the test
- string; pass None to disable comment filtering
- - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
- if False, only dump nested list
- - printResults - (default=C{True}) prints test output to stdout
- - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
-
- Returns: a (success, results) tuple, where success indicates that all tests succeeded
- (or failed if C{failureTests} is True), and the results contain a list of lines of each
- test's output
-
- Example::
- number_expr = pyparsing_common.number.copy()
-
- result = number_expr.runTests('''
- # unsigned integer
- 100
- # negative integer
- -100
- # float with scientific notation
- 6.02e23
- # integer with scientific notation
- 1e-12
- ''')
- print("Success" if result[0] else "Failed!")
-
- result = number_expr.runTests('''
- # stray character
- 100Z
- # missing leading digit before '.'
- -.100
- # too many '.'
- 3.14.159
- ''', failureTests=True)
- print("Success" if result[0] else "Failed!")
- prints::
- # unsigned integer
- 100
- [100]
-
- # negative integer
- -100
- [-100]
-
- # float with scientific notation
- 6.02e23
- [6.02e+23]
-
- # integer with scientific notation
- 1e-12
- [1e-12]
-
- Success
-
- # stray character
- 100Z
- ^
- FAIL: Expected end of text (at char 3), (line:1, col:4)
-
- # missing leading digit before '.'
- -.100
- ^
- FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
-
- # too many '.'
- 3.14.159
- ^
- FAIL: Expected end of text (at char 4), (line:1, col:5)
-
- Success
- """
- if isinstance(tests, basestring):
- tests = list(map(str.strip, tests.rstrip().splitlines()))
- if isinstance(comment, basestring):
- comment = Literal(comment)
- allResults = []
- comments = []
- success = True
- for t in tests:
- if comment is not None and comment.matches(t, False) or comments and not t:
- comments.append(t)
- continue
- if not t:
- continue
- out = ['\n'.join(comments), t]
- comments = []
- try:
- result = self.parseString(t, parseAll=parseAll)
- out.append(result.dump(full=fullDump))
- success = success and not failureTests
- except ParseBaseException as pe:
- fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
- if '\n' in t:
- out.append(line(pe.loc, t))
- out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
- else:
- out.append(' '*pe.loc + '^' + fatal)
- out.append("FAIL: " + str(pe))
- success = success and failureTests
- result = pe
-
- if printResults:
- if fullDump:
- out.append('')
- print('\n'.join(out))
-
- allResults.append((t, result))
-
- return success, allResults
-
-
-class Token(ParserElement):
- """
- Abstract C{ParserElement} subclass, for defining atomic matching patterns.
- """
- def __init__( self ):
- super(Token,self).__init__( savelist=False )
-
-
-class Empty(Token):
- """
- An empty token, will always match.
- """
- def __init__( self ):
- super(Empty,self).__init__()
- self.name = "Empty"
- self.mayReturnEmpty = True
- self.mayIndexError = False
-
-
-class NoMatch(Token):
- """
- A token that will never match.
- """
- def __init__( self ):
- super(NoMatch,self).__init__()
- self.name = "NoMatch"
- self.mayReturnEmpty = True
- self.mayIndexError = False
- self.errmsg = "Unmatchable token"
-
- def parseImpl( self, instring, loc, doActions=True ):
- raise ParseException(instring, loc, self.errmsg, self)
-
-
-class Literal(Token):
- """
- Token to exactly match a specified string.
-
- Example::
- Literal('blah').parseString('blah') # -> ['blah']
- Literal('blah').parseString('blahfooblah') # -> ['blah']
- Literal('blah').parseString('bla') # -> Exception: Expected "blah"
-
- For case-insensitive matching, use L{CaselessLiteral}.
-
- For keyword matching (force word break before and after the matched string),
- use L{Keyword} or L{CaselessKeyword}.
- """
- def __init__( self, matchString ):
- super(Literal,self).__init__()
- self.match = matchString
- self.matchLen = len(matchString)
- try:
- self.firstMatchChar = matchString[0]
- except IndexError:
- warnings.warn("null string passed to Literal; use Empty() instead",
- SyntaxWarning, stacklevel=2)
- self.__class__ = Empty
- self.name = '"%s"' % _ustr(self.match)
- self.errmsg = "Expected " + self.name
- self.mayReturnEmpty = False
- self.mayIndexError = False
-
- # Performance tuning: this routine gets called a *lot*
- # if this is a single character match string and the first character matches,
- # short-circuit as quickly as possible, and avoid calling startswith
- #~ @profile
- def parseImpl( self, instring, loc, doActions=True ):
- if (instring[loc] == self.firstMatchChar and
- (self.matchLen==1 or instring.startswith(self.match,loc)) ):
- return loc+self.matchLen, self.match
- raise ParseException(instring, loc, self.errmsg, self)
-_L = Literal
-ParserElement._literalStringClass = Literal
-
-class Keyword(Token):
- """
- Token to exactly match a specified string as a keyword, that is, it must be
- immediately followed by a non-keyword character. Compare with C{L{Literal}}:
- - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
- - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
- Accepts two optional constructor arguments in addition to the keyword string:
- - C{identChars} is a string of characters that would be valid identifier characters,
- defaulting to all alphanumerics + "_" and "$"
- - C{caseless} allows case-insensitive matching, default is C{False}.
-
- Example::
- Keyword("start").parseString("start") # -> ['start']
- Keyword("start").parseString("starting") # -> Exception
-
- For case-insensitive matching, use L{CaselessKeyword}.
- """
- DEFAULT_KEYWORD_CHARS = alphanums+"_$"
-
- def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ):
- super(Keyword,self).__init__()
- self.match = matchString
- self.matchLen = len(matchString)
- try:
- self.firstMatchChar = matchString[0]
- except IndexError:
- warnings.warn("null string passed to Keyword; use Empty() instead",
- SyntaxWarning, stacklevel=2)
- self.name = '"%s"' % self.match
- self.errmsg = "Expected " + self.name
- self.mayReturnEmpty = False
- self.mayIndexError = False
- self.caseless = caseless
- if caseless:
- self.caselessmatch = matchString.upper()
- identChars = identChars.upper()
- self.identChars = set(identChars)
-
- def parseImpl( self, instring, loc, doActions=True ):
- if self.caseless:
- if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
- (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
- (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
- return loc+self.matchLen, self.match
- else:
- if (instring[loc] == self.firstMatchChar and
- (self.matchLen==1 or instring.startswith(self.match,loc)) and
- (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
- (loc == 0 or instring[loc-1] not in self.identChars) ):
- return loc+self.matchLen, self.match
- raise ParseException(instring, loc, self.errmsg, self)
-
- def copy(self):
- c = super(Keyword,self).copy()
- c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
- return c
-
- @staticmethod
- def setDefaultKeywordChars( chars ):
- """Overrides the default Keyword chars
- """
- Keyword.DEFAULT_KEYWORD_CHARS = chars
-
-class CaselessLiteral(Literal):
- """
- Token to match a specified string, ignoring case of letters.
- Note: the matched results will always be in the case of the given
- match string, NOT the case of the input text.
-
- Example::
- OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
-
- (Contrast with example for L{CaselessKeyword}.)
- """
- def __init__( self, matchString ):
- super(CaselessLiteral,self).__init__( matchString.upper() )
- # Preserve the defining literal.
- self.returnString = matchString
- self.name = "'%s'" % self.returnString
- self.errmsg = "Expected " + self.name
-
- def parseImpl( self, instring, loc, doActions=True ):
- if instring[ loc:loc+self.matchLen ].upper() == self.match:
- return loc+self.matchLen, self.returnString
- raise ParseException(instring, loc, self.errmsg, self)
-
-class CaselessKeyword(Keyword):
- """
- Caseless version of L{Keyword}.
-
- Example::
- OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
-
- (Contrast with example for L{CaselessLiteral}.)
- """
- def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ):
- super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
-
- def parseImpl( self, instring, loc, doActions=True ):
- if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
- (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
- return loc+self.matchLen, self.match
- raise ParseException(instring, loc, self.errmsg, self)
-
-class Word(Token):
- """
- Token for matching words composed of allowed character sets.
- Defined with string containing all allowed initial characters,
- an optional string containing allowed body characters (if omitted,
- defaults to the initial character set), and an optional minimum,
- maximum, and/or exact length. The default value for C{min} is 1 (a
- minimum value < 1 is not valid); the default values for C{max} and C{exact}
- are 0, meaning no maximum or exact length restriction. An optional
- C{excludeChars} parameter can list characters that might be found in
- the input C{bodyChars} string; useful to define a word of all printables
- except for one or two characters, for instance.
-
- L{srange} is useful for defining custom character set strings for defining
- C{Word} expressions, using range notation from regular expression character sets.
-
- A common mistake is to use C{Word} to match a specific literal string, as in
- C{Word("Address")}. Remember that C{Word} uses the string argument to define
- I{sets} of matchable characters. This expression would match "Add", "AAA",
- "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
- To match an exact literal string, use L{Literal} or L{Keyword}.
-
- pyparsing includes helper strings for building Words:
- - L{alphas}
- - L{nums}
- - L{alphanums}
- - L{hexnums}
- - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
- - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
- - L{printables} (any non-whitespace character)
-
- Example::
- # a word composed of digits
- integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
-
- # a word with a leading capital, and zero or more lowercase
- capital_word = Word(alphas.upper(), alphas.lower())
-
- # hostnames are alphanumeric, with leading alpha, and '-'
- hostname = Word(alphas, alphanums+'-')
-
- # roman numeral (not a strict parser, accepts invalid mix of characters)
- roman = Word("IVXLCDM")
-
- # any string of non-whitespace characters, except for ','
- csv_value = Word(printables, excludeChars=",")
- """
- def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
- super(Word,self).__init__()
- if excludeChars:
- initChars = ''.join(c for c in initChars if c not in excludeChars)
- if bodyChars:
- bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
- self.initCharsOrig = initChars
- self.initChars = set(initChars)
- if bodyChars :
- self.bodyCharsOrig = bodyChars
- self.bodyChars = set(bodyChars)
- else:
- self.bodyCharsOrig = initChars
- self.bodyChars = set(initChars)
-
- self.maxSpecified = max > 0
-
- if min < 1:
- raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
-
- self.minLen = min
-
- if max > 0:
- self.maxLen = max
- else:
- self.maxLen = _MAX_INT
-
- if exact > 0:
- self.maxLen = exact
- self.minLen = exact
-
- self.name = _ustr(self)
- self.errmsg = "Expected " + self.name
- self.mayIndexError = False
- self.asKeyword = asKeyword
-
- if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
- if self.bodyCharsOrig == self.initCharsOrig:
- self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
- elif len(self.initCharsOrig) == 1:
- self.reString = "%s[%s]*" % \
- (re.escape(self.initCharsOrig),
- _escapeRegexRangeChars(self.bodyCharsOrig),)
- else:
- self.reString = "[%s][%s]*" % \
- (_escapeRegexRangeChars(self.initCharsOrig),
- _escapeRegexRangeChars(self.bodyCharsOrig),)
- if self.asKeyword:
- self.reString = r"\b"+self.reString+r"\b"
- try:
- self.re = re.compile( self.reString )
- except:
- self.re = None
-
- def parseImpl( self, instring, loc, doActions=True ):
- if self.re:
- result = self.re.match(instring,loc)
- if not result:
- raise ParseException(instring, loc, self.errmsg, self)
-
- loc = result.end()
- return loc, result.group()
-
- if not(instring[ loc ] in self.initChars):
- raise ParseException(instring, loc, self.errmsg, self)
-
- start = loc
- loc += 1
- instrlen = len(instring)
- bodychars = self.bodyChars
- maxloc = start + self.maxLen
- maxloc = min( maxloc, instrlen )
- while loc < maxloc and instring[loc] in bodychars:
- loc += 1
-
- throwException = False
- if loc - start < self.minLen:
- throwException = True
- if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
- throwException = True
- if self.asKeyword:
- if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
- throwException = True
-
- if throwException:
- raise ParseException(instring, loc, self.errmsg, self)
-
- return loc, instring[start:loc]
-
- def __str__( self ):
- try:
- return super(Word,self).__str__()
- except:
- pass
-
-
- if self.strRepr is None:
-
- def charsAsStr(s):
- if len(s)>4:
- return s[:4]+"..."
- else:
- return s
-
- if ( self.initCharsOrig != self.bodyCharsOrig ):
- self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
- else:
- self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
-
- return self.strRepr
-
-
-class Regex(Token):
- """
- 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.
-
- Example::
- realnum = Regex(r"[+-]?\d+\.\d*")
- ssn = Regex(r"\d\d\d-\d\d-\d\d\d\d")
- # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
- roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
- """
- compiledREtype = type(re.compile("[A-Z]"))
- def __init__( self, pattern, flags=0):
- """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
- super(Regex,self).__init__()
-
- if isinstance(pattern, basestring):
- if not pattern:
- warnings.warn("null string passed to Regex; use Empty() instead",
- SyntaxWarning, stacklevel=2)
-
- self.pattern = pattern
- self.flags = flags
-
- try:
- self.re = re.compile(self.pattern, self.flags)
- self.reString = self.pattern
- except sre_constants.error:
- warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
- SyntaxWarning, stacklevel=2)
- raise
-
- elif isinstance(pattern, Regex.compiledREtype):
- self.re = pattern
- self.pattern = \
- self.reString = str(pattern)
- self.flags = flags
-
- else:
- raise ValueError("Regex may only be constructed with a string or a compiled RE object")
-
- self.name = _ustr(self)
- self.errmsg = "Expected " + self.name
- self.mayIndexError = False
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- result = self.re.match(instring,loc)
- if not result:
- raise ParseException(instring, loc, self.errmsg, self)
-
- loc = result.end()
- d = result.groupdict()
- ret = ParseResults(result.group())
- if d:
- for k in d:
- ret[k] = d[k]
- return loc,ret
-
- def __str__( self ):
- try:
- return super(Regex,self).__str__()
- except:
- pass
-
- if self.strRepr is None:
- self.strRepr = "Re:(%s)" % repr(self.pattern)
-
- return self.strRepr
-
-
-class QuotedString(Token):
- r"""
- Token for matching strings that are delimited by quoting characters.
-
- Defined with the following parameters:
- - quoteChar - string of one or more characters defining the quote delimiting string
- - escChar - character to escape quotes, typically backslash (default=C{None})
- - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
- - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
- - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
- - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
- - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
-
- Example::
- qs = QuotedString('"')
- print(qs.searchString('lsjdf "This is the quote" sldjf'))
- complex_qs = QuotedString('{{', endQuoteChar='}}')
- print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
- sql_qs = QuotedString('"', escQuote='""')
- print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
- prints::
- [['This is the quote']]
- [['This is the "quote"']]
- [['This is the quote with "embedded" quotes']]
- """
- def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
- super(QuotedString,self).__init__()
-
- # remove white space from quote chars - wont work anyway
- quoteChar = quoteChar.strip()
- if not quoteChar:
- warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
- raise SyntaxError()
-
- if endQuoteChar is None:
- endQuoteChar = quoteChar
- else:
- endQuoteChar = endQuoteChar.strip()
- if not endQuoteChar:
- warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
- raise SyntaxError()
-
- self.quoteChar = quoteChar
- self.quoteCharLen = len(quoteChar)
- self.firstQuoteChar = quoteChar[0]
- self.endQuoteChar = endQuoteChar
- self.endQuoteCharLen = len(endQuoteChar)
- self.escChar = escChar
- self.escQuote = escQuote
- self.unquoteResults = unquoteResults
- self.convertWhitespaceEscapes = convertWhitespaceEscapes
-
- if multiline:
- self.flags = re.MULTILINE | re.DOTALL
- self.pattern = r'%s(?:[^%s%s]' % \
- ( re.escape(self.quoteChar),
- _escapeRegexRangeChars(self.endQuoteChar[0]),
- (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
- else:
- self.flags = 0
- self.pattern = r'%s(?:[^%s\n\r%s]' % \
- ( re.escape(self.quoteChar),
- _escapeRegexRangeChars(self.endQuoteChar[0]),
- (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
- if len(self.endQuoteChar) > 1:
- self.pattern += (
- '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
- _escapeRegexRangeChars(self.endQuoteChar[i]))
- for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
- )
- if escQuote:
- self.pattern += (r'|(?:%s)' % re.escape(escQuote))
- if escChar:
- self.pattern += (r'|(?:%s.)' % re.escape(escChar))
- self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
- self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
-
- try:
- self.re = re.compile(self.pattern, self.flags)
- self.reString = self.pattern
- except sre_constants.error:
- warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
- SyntaxWarning, stacklevel=2)
- raise
-
- self.name = _ustr(self)
- self.errmsg = "Expected " + self.name
- self.mayIndexError = False
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
- if not result:
- raise ParseException(instring, loc, self.errmsg, self)
-
- loc = result.end()
- ret = result.group()
-
- if self.unquoteResults:
-
- # strip off quotes
- ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
-
- if isinstance(ret,basestring):
- # replace escaped whitespace
- if '\\' in ret and self.convertWhitespaceEscapes:
- ws_map = {
- r'\t' : '\t',
- r'\n' : '\n',
- r'\f' : '\f',
- r'\r' : '\r',
- }
- for wslit,wschar in ws_map.items():
- ret = ret.replace(wslit, wschar)
-
- # replace escaped characters
- if self.escChar:
- ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
-
- # replace escaped quotes
- if self.escQuote:
- ret = ret.replace(self.escQuote, self.endQuoteChar)
-
- return loc, ret
-
- def __str__( self ):
- try:
- return super(QuotedString,self).__str__()
- except:
- pass
-
- if self.strRepr is None:
- self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
-
- return self.strRepr
-
-
-class CharsNotIn(Token):
- """
- Token for matching words composed of characters *not* in a given set (will
- include whitespace in matched characters if not listed in the provided exclusion set - see example).
- Defined with string containing all disallowed characters, and an optional
- minimum, maximum, and/or exact length. The default value for C{min} is 1 (a
- minimum value < 1 is not valid); the default values for C{max} and C{exact}
- are 0, meaning no maximum or exact length restriction.
-
- Example::
- # define a comma-separated-value as anything that is not a ','
- csv_value = CharsNotIn(',')
- print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
- prints::
- ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
- """
- def __init__( self, notChars, min=1, max=0, exact=0 ):
- super(CharsNotIn,self).__init__()
- self.skipWhitespace = False
- self.notChars = notChars
-
- if min < 1:
- raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
-
- self.minLen = min
-
- if max > 0:
- self.maxLen = max
- else:
- self.maxLen = _MAX_INT
-
- if exact > 0:
- self.maxLen = exact
- self.minLen = exact
-
- self.name = _ustr(self)
- self.errmsg = "Expected " + self.name
- self.mayReturnEmpty = ( self.minLen == 0 )
- self.mayIndexError = False
-
- def parseImpl( self, instring, loc, doActions=True ):
- if instring[loc] in self.notChars:
- raise ParseException(instring, loc, self.errmsg, self)
-
- start = loc
- loc += 1
- notchars = self.notChars
- maxlen = min( start+self.maxLen, len(instring) )
- while loc < maxlen and \
- (instring[loc] not in notchars):
- loc += 1
-
- if loc - start < self.minLen:
- raise ParseException(instring, loc, self.errmsg, self)
-
- return loc, instring[start:loc]
-
- def __str__( self ):
- try:
- return super(CharsNotIn, self).__str__()
- except:
- pass
-
- if self.strRepr is None:
- if len(self.notChars) > 4:
- self.strRepr = "!W:(%s...)" % self.notChars[:4]
- else:
- self.strRepr = "!W:(%s)" % self.notChars
-
- return self.strRepr
-
-class White(Token):
- """
- Special matching class for matching whitespace. Normally, whitespace is ignored
- by pyparsing grammars. This class is included when some whitespace structures
- are significant. Define with a string containing the whitespace characters to be
- matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments,
- as defined for the C{L{Word}} class.
- """
- whiteStrs = {
- " " : "<SPC>",
- "\t": "<TAB>",
- "\n": "<LF>",
- "\r": "<CR>",
- "\f": "<FF>",
- }
- def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
- super(White,self).__init__()
- self.matchWhite = ws
- self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
- #~ self.leaveWhitespace()
- self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
- self.mayReturnEmpty = True
- self.errmsg = "Expected " + self.name
-
- self.minLen = min
-
- if max > 0:
- self.maxLen = max
- else:
- self.maxLen = _MAX_INT
-
- if exact > 0:
- self.maxLen = exact
- self.minLen = exact
-
- def parseImpl( self, instring, loc, doActions=True ):
- if not(instring[ loc ] in self.matchWhite):
- raise ParseException(instring, loc, self.errmsg, self)
- start = loc
- loc += 1
- maxloc = start + self.maxLen
- maxloc = min( maxloc, len(instring) )
- while loc < maxloc and instring[loc] in self.matchWhite:
- loc += 1
-
- if loc - start < self.minLen:
- raise ParseException(instring, loc, self.errmsg, self)
-
- return loc, instring[start:loc]
-
-
-class _PositionToken(Token):
- def __init__( self ):
- super(_PositionToken,self).__init__()
- self.name=self.__class__.__name__
- self.mayReturnEmpty = True
- self.mayIndexError = False
-
-class GoToColumn(_PositionToken):
- """
- Token to advance to a specific column of input text; useful for tabular report scraping.
- """
- def __init__( self, colno ):
- super(GoToColumn,self).__init__()
- self.col = colno
-
- def preParse( self, instring, loc ):
- if col(loc,instring) != self.col:
- instrlen = len(instring)
- if self.ignoreExprs:
- loc = self._skipIgnorables( instring, loc )
- while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
- loc += 1
- return loc
-
- def parseImpl( self, instring, loc, doActions=True ):
- thiscol = col( loc, instring )
- if thiscol > self.col:
- raise ParseException( instring, loc, "Text not in expected column", self )
- newloc = loc + self.col - thiscol
- ret = instring[ loc: newloc ]
- return newloc, ret
-
-class LineStart(_PositionToken):
- """
- Matches if current position is at the beginning of a line within the parse string
- """
- def __init__( self ):
- super(LineStart,self).__init__()
- self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
- self.errmsg = "Expected start of line"
-
- def preParse( self, instring, loc ):
- preloc = super(LineStart,self).preParse(instring,loc)
- if instring[preloc] == "\n":
- loc += 1
- return loc
-
- def parseImpl( self, instring, loc, doActions=True ):
- if not( loc==0 or
- (loc == self.preParse( instring, 0 )) or
- (instring[loc-1] == "\n") ): #col(loc, instring) != 1:
- raise ParseException(instring, loc, self.errmsg, self)
- return loc, []
-
-class LineEnd(_PositionToken):
- """
- Matches if current position is at the end of a line within the parse string
- """
- def __init__( self ):
- super(LineEnd,self).__init__()
- self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
- self.errmsg = "Expected end of line"
-
- def parseImpl( self, instring, loc, doActions=True ):
- if loc<len(instring):
- if instring[loc] == "\n":
- return loc+1, "\n"
- else:
- raise ParseException(instring, loc, self.errmsg, self)
- elif loc == len(instring):
- return loc+1, []
- else:
- raise ParseException(instring, loc, self.errmsg, self)
-
-class StringStart(_PositionToken):
- """
- Matches if current position is at the beginning of the parse string
- """
- def __init__( self ):
- super(StringStart,self).__init__()
- self.errmsg = "Expected start of text"
-
- def parseImpl( self, instring, loc, doActions=True ):
- if loc != 0:
- # see if entire string up to here is just whitespace and ignoreables
- if loc != self.preParse( instring, 0 ):
- raise ParseException(instring, loc, self.errmsg, self)
- return loc, []
-
-class StringEnd(_PositionToken):
- """
- Matches if current position is at the end of the parse string
- """
- def __init__( self ):
- super(StringEnd,self).__init__()
- self.errmsg = "Expected end of text"
-
- def parseImpl( self, instring, loc, doActions=True ):
- if loc < len(instring):
- raise ParseException(instring, loc, self.errmsg, self)
- elif loc == len(instring):
- return loc+1, []
- elif loc > len(instring):
- return loc, []
- else:
- raise ParseException(instring, loc, self.errmsg, self)
-
-class WordStart(_PositionToken):
- """
- Matches if the current position is at the beginning of a Word, and
- is not preceded by any character in a given set of C{wordChars}
- (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
- use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
- the string being parsed, or at the beginning of a line.
- """
- def __init__(self, wordChars = printables):
- super(WordStart,self).__init__()
- self.wordChars = set(wordChars)
- self.errmsg = "Not at the start of a word"
-
- def parseImpl(self, instring, loc, doActions=True ):
- if loc != 0:
- if (instring[loc-1] in self.wordChars or
- instring[loc] not in self.wordChars):
- raise ParseException(instring, loc, self.errmsg, self)
- return loc, []
-
-class WordEnd(_PositionToken):
- """
- Matches if the current position is at the end of a Word, and
- is not followed by any character in a given set of C{wordChars}
- (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
- use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
- the string being parsed, or at the end of a line.
- """
- def __init__(self, wordChars = printables):
- super(WordEnd,self).__init__()
- self.wordChars = set(wordChars)
- self.skipWhitespace = False
- self.errmsg = "Not at the end of a word"
-
- def parseImpl(self, instring, loc, doActions=True ):
- instrlen = len(instring)
- if instrlen>0 and loc<instrlen:
- if (instring[loc] in self.wordChars or
- instring[loc-1] not in self.wordChars):
- raise ParseException(instring, loc, self.errmsg, self)
- return loc, []
-
-
-class ParseExpression(ParserElement):
- """
- Abstract subclass of ParserElement, for combining and post-processing parsed tokens.
- """
- def __init__( self, exprs, savelist = False ):
- super(ParseExpression,self).__init__(savelist)
- if isinstance( exprs, _generatorType ):
- exprs = list(exprs)
-
- if isinstance( exprs, basestring ):
- self.exprs = [ ParserElement._literalStringClass( exprs ) ]
- elif isinstance( exprs, collections.Sequence ):
- # if sequence of strings provided, wrap with Literal
- if all(isinstance(expr, basestring) for expr in exprs):
- exprs = map(ParserElement._literalStringClass, exprs)
- self.exprs = list(exprs)
- else:
- try:
- self.exprs = list( exprs )
- except TypeError:
- self.exprs = [ exprs ]
- self.callPreparse = False
-
- def __getitem__( self, i ):
- return self.exprs[i]
-
- def append( self, other ):
- self.exprs.append( other )
- self.strRepr = None
- return self
-
- def leaveWhitespace( self ):
- """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on
- all contained expressions."""
- self.skipWhitespace = False
- self.exprs = [ e.copy() for e in self.exprs ]
- for e in self.exprs:
- e.leaveWhitespace()
- return self
-
- def ignore( self, other ):
- if isinstance( other, Suppress ):
- if other not in self.ignoreExprs:
- super( ParseExpression, self).ignore( other )
- for e in self.exprs:
- e.ignore( self.ignoreExprs[-1] )
- else:
- super( ParseExpression, self).ignore( other )
- for e in self.exprs:
- e.ignore( self.ignoreExprs[-1] )
- return self
-
- def __str__( self ):
- try:
- return super(ParseExpression,self).__str__()
- except:
- pass
-
- if self.strRepr is None:
- self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
- return self.strRepr
-
- def streamline( self ):
- super(ParseExpression,self).streamline()
-
- for e in self.exprs:
- e.streamline()
-
- # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
- # but only if there are no parse actions or resultsNames on the nested And's
- # (likewise for Or's and MatchFirst's)
- if ( len(self.exprs) == 2 ):
- other = self.exprs[0]
- if ( isinstance( other, self.__class__ ) and
- not(other.parseAction) and
- other.resultsName is None and
- not other.debug ):
- self.exprs = other.exprs[:] + [ self.exprs[1] ]
- self.strRepr = None
- self.mayReturnEmpty |= other.mayReturnEmpty
- self.mayIndexError |= other.mayIndexError
-
- other = self.exprs[-1]
- if ( isinstance( other, self.__class__ ) and
- not(other.parseAction) and
- other.resultsName is None and
- not other.debug ):
- self.exprs = self.exprs[:-1] + other.exprs[:]
- self.strRepr = None
- self.mayReturnEmpty |= other.mayReturnEmpty
- self.mayIndexError |= other.mayIndexError
-
- self.errmsg = "Expected " + _ustr(self)
-
- return self
-
- def setResultsName( self, name, listAllMatches=False ):
- ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
- return ret
-
- def validate( self, validateTrace=[] ):
- tmp = validateTrace[:]+[self]
- for e in self.exprs:
- e.validate(tmp)
- self.checkRecursion( [] )
-
- def copy(self):
- ret = super(ParseExpression,self).copy()
- ret.exprs = [e.copy() for e in self.exprs]
- return ret
-
-class And(ParseExpression):
- """
- Requires all given C{ParseExpression}s to be found in the given order.
- Expressions may be separated by whitespace.
- May be constructed using the C{'+'} operator.
- May also be constructed using the C{'-'} 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")
- """
-
- class _ErrorStop(Empty):
- def __init__(self, *args, **kwargs):
- super(And._ErrorStop,self).__init__(*args, **kwargs)
- self.name = '-'
- self.leaveWhitespace()
-
- def __init__( self, exprs, savelist = True ):
- super(And,self).__init__(exprs, savelist)
- self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
- self.setWhitespaceChars( self.exprs[0].whiteChars )
- self.skipWhitespace = self.exprs[0].skipWhitespace
- self.callPreparse = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- # pass False as last arg to _parse for first element, since we already
- # pre-parsed the string as part of our And pre-parsing
- loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
- errorStop = False
- for e in self.exprs[1:]:
- if isinstance(e, And._ErrorStop):
- errorStop = True
- continue
- if errorStop:
- try:
- loc, exprtokens = e._parse( instring, loc, doActions )
- except ParseSyntaxException:
- raise
- except ParseBaseException as pe:
- pe.__traceback__ = None
- raise ParseSyntaxException(pe)
- except IndexError:
- raise ParseSyntaxException( ParseException(instring, len(instring), self.errmsg, self) )
- else:
- loc, exprtokens = e._parse( instring, loc, doActions )
- if exprtokens or exprtokens.haskeys():
- resultlist += exprtokens
- return loc, resultlist
-
- def __iadd__(self, other ):
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- return self.append( other ) #And( [ self, other ] )
-
- def checkRecursion( self, parseElementList ):
- subRecCheckList = parseElementList[:] + [ self ]
- for e in self.exprs:
- e.checkRecursion( subRecCheckList )
- if not e.mayReturnEmpty:
- break
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}"
-
- return self.strRepr
-
-
-class Or(ParseExpression):
- """
- Requires that at least one C{ParseExpression} is found.
- If two expressions match, the expression that matches the longest string will be used.
- May be constructed using the C{'^'} 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']]
- """
- def __init__( self, exprs, savelist = False ):
- super(Or,self).__init__(exprs, savelist)
- if self.exprs:
- self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
- else:
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- maxExcLoc = -1
- maxException = None
- matches = []
- for e in self.exprs:
- try:
- loc2 = e.tryParse( instring, loc )
- except ParseException as err:
- err.__traceback__ = None
- if err.loc > maxExcLoc:
- maxException = err
- maxExcLoc = err.loc
- except IndexError:
- if len(instring) > maxExcLoc:
- maxException = ParseException(instring,len(instring),e.errmsg,self)
- maxExcLoc = len(instring)
- else:
- # save match among all matches, to retry longest to shortest
- matches.append((loc2, e))
-
- if matches:
- matches.sort(key=lambda x: -x[0])
- for _,e in matches:
- try:
- return e._parse( instring, loc, doActions )
- except ParseException as err:
- err.__traceback__ = None
- if err.loc > maxExcLoc:
- maxException = err
- maxExcLoc = err.loc
-
- if maxException is not None:
- maxException.msg = self.errmsg
- raise maxException
- else:
- raise ParseException(instring, loc, "no defined alternatives to match", self)
-
-
- def __ixor__(self, other ):
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- return self.append( other ) #Or( [ self, other ] )
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
-
- return self.strRepr
-
- def checkRecursion( self, parseElementList ):
- subRecCheckList = parseElementList[:] + [ self ]
- for e in self.exprs:
- e.checkRecursion( subRecCheckList )
-
-
-class MatchFirst(ParseExpression):
- """
- Requires that at least one C{ParseExpression} is found.
- If two expressions match, the first one listed is the one that will match.
- May be constructed using the C{'|'} operator.
-
- Example::
- # construct MatchFirst using '|' operator
-
- # watch the order of expressions to match
- number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
- print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']]
-
- # put more selective expression first
- number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
- print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']]
- """
- def __init__( self, exprs, savelist = False ):
- super(MatchFirst,self).__init__(exprs, savelist)
- if self.exprs:
- self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
- else:
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- maxExcLoc = -1
- maxException = None
- for e in self.exprs:
- try:
- ret = e._parse( instring, loc, doActions )
- return ret
- except ParseException as err:
- if err.loc > maxExcLoc:
- maxException = err
- maxExcLoc = err.loc
- except IndexError:
- if len(instring) > maxExcLoc:
- maxException = ParseException(instring,len(instring),e.errmsg,self)
- maxExcLoc = len(instring)
-
- # only got here if no expression matched, raise exception for match that made it the furthest
- else:
- if maxException is not None:
- maxException.msg = self.errmsg
- raise maxException
- else:
- raise ParseException(instring, loc, "no defined alternatives to match", self)
-
- def __ior__(self, other ):
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass( other )
- return self.append( other ) #MatchFirst( [ self, other ] )
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
-
- return self.strRepr
-
- def checkRecursion( self, parseElementList ):
- subRecCheckList = parseElementList[:] + [ self ]
- for e in self.exprs:
- e.checkRecursion( subRecCheckList )
-
-
-class Each(ParseExpression):
- """
- Requires all given C{ParseExpression}s to be found, but in any order.
- Expressions may be separated by whitespace.
- May be constructed using the C{'&'} operator.
-
- Example::
- color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
- shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
- integer = Word(nums)
- shape_attr = "shape:" + shape_type("shape")
- posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
- color_attr = "color:" + color("color")
- size_attr = "size:" + integer("size")
-
- # use Each (using operator '&') to accept attributes in any order
- # (shape and posn are required, color and size are optional)
- shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
-
- shape_spec.runTests('''
- shape: SQUARE color: BLACK posn: 100, 120
- shape: CIRCLE size: 50 color: BLUE posn: 50,80
- color:GREEN size:20 shape:TRIANGLE posn:20,40
- '''
- )
- prints::
- shape: SQUARE color: BLACK posn: 100, 120
- ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
- - color: BLACK
- - posn: ['100', ',', '120']
- - x: 100
- - y: 120
- - shape: SQUARE
-
-
- shape: CIRCLE size: 50 color: BLUE posn: 50,80
- ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
- - color: BLUE
- - posn: ['50', ',', '80']
- - x: 50
- - y: 80
- - shape: CIRCLE
- - size: 50
-
-
- color: GREEN size: 20 shape: TRIANGLE posn: 20,40
- ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
- - color: GREEN
- - posn: ['20', ',', '40']
- - x: 20
- - y: 40
- - shape: TRIANGLE
- - size: 20
- """
- def __init__( self, exprs, savelist = True ):
- super(Each,self).__init__(exprs, savelist)
- self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
- self.skipWhitespace = True
- self.initExprGroups = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- if self.initExprGroups:
- self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
- opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
- opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
- self.optionals = opt1 + opt2
- self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
- self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
- self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
- self.required += self.multirequired
- self.initExprGroups = False
- tmpLoc = loc
- tmpReqd = self.required[:]
- tmpOpt = self.optionals[:]
- matchOrder = []
-
- keepMatching = True
- while keepMatching:
- tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
- failed = []
- for e in tmpExprs:
- try:
- tmpLoc = e.tryParse( instring, tmpLoc )
- except ParseException:
- failed.append(e)
- else:
- matchOrder.append(self.opt1map.get(id(e),e))
- if e in tmpReqd:
- tmpReqd.remove(e)
- elif e in tmpOpt:
- tmpOpt.remove(e)
- if len(failed) == len(tmpExprs):
- keepMatching = False
-
- if tmpReqd:
- missing = ", ".join(_ustr(e) for e in tmpReqd)
- raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
-
- # add any unmatched Optionals, in case they have default values defined
- matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
-
- resultlist = []
- for e in matchOrder:
- loc,results = e._parse(instring,loc,doActions)
- resultlist.append(results)
-
- finalResults = ParseResults()
- for r in resultlist:
- dups = {}
- for k in r.keys():
- if k in finalResults:
- tmp = ParseResults(finalResults[k])
- tmp += ParseResults(r[k])
- dups[k] = tmp
- finalResults += ParseResults(r)
- for k,v in dups.items():
- finalResults[k] = v
- return loc, finalResults
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
-
- return self.strRepr
-
- def checkRecursion( self, parseElementList ):
- subRecCheckList = parseElementList[:] + [ self ]
- for e in self.exprs:
- e.checkRecursion( subRecCheckList )
-
-
-class ParseElementEnhance(ParserElement):
- """
- Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
- """
- def __init__( self, expr, savelist=False ):
- super(ParseElementEnhance,self).__init__(savelist)
- if isinstance( expr, basestring ):
- expr = ParserElement._literalStringClass(expr)
- self.expr = expr
- self.strRepr = None
- if expr is not None:
- self.mayIndexError = expr.mayIndexError
- self.mayReturnEmpty = expr.mayReturnEmpty
- self.setWhitespaceChars( expr.whiteChars )
- self.skipWhitespace = expr.skipWhitespace
- self.saveAsList = expr.saveAsList
- self.callPreparse = expr.callPreparse
- self.ignoreExprs.extend(expr.ignoreExprs)
-
- def parseImpl( self, instring, loc, doActions=True ):
- if self.expr is not None:
- return self.expr._parse( instring, loc, doActions, callPreParse=False )
- else:
- raise ParseException("",loc,self.errmsg,self)
-
- def leaveWhitespace( self ):
- self.skipWhitespace = False
- self.expr = self.expr.copy()
- if self.expr is not None:
- self.expr.leaveWhitespace()
- return self
-
- def ignore( self, other ):
- if isinstance( other, Suppress ):
- if other not in self.ignoreExprs:
- super( ParseElementEnhance, self).ignore( other )
- if self.expr is not None:
- self.expr.ignore( self.ignoreExprs[-1] )
- else:
- super( ParseElementEnhance, self).ignore( other )
- if self.expr is not None:
- self.expr.ignore( self.ignoreExprs[-1] )
- return self
-
- def streamline( self ):
- super(ParseElementEnhance,self).streamline()
- if self.expr is not None:
- self.expr.streamline()
- return self
-
- def checkRecursion( self, parseElementList ):
- if self in parseElementList:
- raise RecursiveGrammarException( parseElementList+[self] )
- subRecCheckList = parseElementList[:] + [ self ]
- if self.expr is not None:
- self.expr.checkRecursion( subRecCheckList )
-
- def validate( self, validateTrace=[] ):
- tmp = validateTrace[:]+[self]
- if self.expr is not None:
- self.expr.validate(tmp)
- self.checkRecursion( [] )
-
- def __str__( self ):
- try:
- return super(ParseElementEnhance,self).__str__()
- except:
- pass
-
- if self.strRepr is None and self.expr is not None:
- self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
- return self.strRepr
-
-
-class FollowedBy(ParseElementEnhance):
- """
- Lookahead matching of the given parse expression. C{FollowedBy}
- does *not* advance the parsing position within the input string, it only
- verifies that the specified parse expression matches at the current
- position. C{FollowedBy} always returns a null token list.
-
- Example::
- # use FollowedBy to match a label only if it is followed by a ':'
- data_word = Word(alphas)
- label = data_word + FollowedBy(':')
- attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
-
- OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
- prints::
- [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
- """
- def __init__( self, expr ):
- super(FollowedBy,self).__init__(expr)
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- self.expr.tryParse( instring, loc )
- return loc, []
-
-
-class NotAny(ParseElementEnhance):
- """
- Lookahead to disallow matching with the given parse expression. C{NotAny}
- does *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, C{NotAny} does *not* skip over leading whitespace. C{NotAny}
- always returns a null token list. May be constructed using the '~' operator.
-
- Example::
-
- """
- def __init__( self, expr ):
- super(NotAny,self).__init__(expr)
- #~ self.leaveWhitespace()
- self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
- self.mayReturnEmpty = True
- self.errmsg = "Found unwanted token, "+_ustr(self.expr)
-
- def parseImpl( self, instring, loc, doActions=True ):
- if self.expr.canParseNext(instring, loc):
- raise ParseException(instring, loc, self.errmsg, self)
- return loc, []
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "~{" + _ustr(self.expr) + "}"
-
- return self.strRepr
-
-
-class OneOrMore(ParseElementEnhance):
- """
- Repetition of one or more of the given expression.
-
- Parameters:
- - expr - expression that must match one or more times
- - stopOn - (default=C{None}) - expression for a terminating sentinel
- (only required if the sentinel would ordinarily match the repetition
- expression)
-
- Example::
- data_word = Word(alphas)
- label = data_word + FollowedBy(':')
- attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
-
- text = "shape: SQUARE posn: upper left color: BLACK"
- OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
-
- # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
- attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
- OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
-
- # could also be written as
- (attr_expr * (1,)).parseString(text).pprint()
- """
- def __init__( self, expr, stopOn=None):
- super(OneOrMore, self).__init__(expr)
- ender = stopOn
- if isinstance(ender, basestring):
- ender = ParserElement._literalStringClass(ender)
- self.not_ender = ~ender if ender is not None else None
-
- def parseImpl( self, instring, loc, doActions=True ):
- self_expr_parse = self.expr._parse
- self_skip_ignorables = self._skipIgnorables
- check_ender = self.not_ender is not None
- if check_ender:
- try_not_ender = self.not_ender.tryParse
-
- # must be at least one (but first see if we are the stopOn sentinel;
- # if so, fail)
- if check_ender:
- try_not_ender(instring, loc)
- loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
- try:
- hasIgnoreExprs = (not not self.ignoreExprs)
- while 1:
- if check_ender:
- try_not_ender(instring, loc)
- if hasIgnoreExprs:
- preloc = self_skip_ignorables( instring, loc )
- else:
- preloc = loc
- loc, tmptokens = self_expr_parse( instring, preloc, doActions )
- if tmptokens or tmptokens.haskeys():
- tokens += tmptokens
- except (ParseException,IndexError):
- pass
-
- return loc, tokens
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "{" + _ustr(self.expr) + "}..."
-
- return self.strRepr
-
- def setResultsName( self, name, listAllMatches=False ):
- ret = super(OneOrMore,self).setResultsName(name,listAllMatches)
- ret.saveAsList = True
- return ret
-
-class ZeroOrMore(OneOrMore):
- """
- Optional repetition of zero or more of the given expression.
-
- Parameters:
- - expr - expression that must match zero or more times
- - stopOn - (default=C{None}) - expression for a terminating sentinel
- (only required if the sentinel would ordinarily match the repetition
- expression)
-
- Example: similar to L{OneOrMore}
- """
- def __init__( self, expr, stopOn=None):
- super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- try:
- return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
- except (ParseException,IndexError):
- return loc, []
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "[" + _ustr(self.expr) + "]..."
-
- return self.strRepr
-
-class _NullToken(object):
- def __bool__(self):
- return False
- __nonzero__ = __bool__
- def __str__(self):
- return ""
-
-_optionalNotMatched = _NullToken()
-class Optional(ParseElementEnhance):
- """
- Optional matching of the given expression.
-
- Parameters:
- - expr - expression that must match zero or more times
- - default (optional) - value to be returned if the optional expression is not found.
-
- Example::
- # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
- zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
- zip.runTests('''
- # traditional ZIP code
- 12345
-
- # ZIP+4 form
- 12101-0001
-
- # invalid ZIP
- 98765-
- ''')
- prints::
- # traditional ZIP code
- 12345
- ['12345']
-
- # ZIP+4 form
- 12101-0001
- ['12101-0001']
-
- # invalid ZIP
- 98765-
- ^
- FAIL: Expected end of text (at char 5), (line:1, col:6)
- """
- def __init__( self, expr, default=_optionalNotMatched ):
- super(Optional,self).__init__( expr, savelist=False )
- self.defaultValue = default
- self.mayReturnEmpty = True
-
- def parseImpl( self, instring, loc, doActions=True ):
- try:
- loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
- except (ParseException,IndexError):
- if self.defaultValue is not _optionalNotMatched:
- if self.expr.resultsName:
- tokens = ParseResults([ self.defaultValue ])
- tokens[self.expr.resultsName] = self.defaultValue
- else:
- tokens = [ self.defaultValue ]
- else:
- tokens = []
- return loc, tokens
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
-
- if self.strRepr is None:
- self.strRepr = "[" + _ustr(self.expr) + "]"
-
- return self.strRepr
-
-class SkipTo(ParseElementEnhance):
- """
- Token for skipping over all undefined text until the matched expression is found.
-
- Parameters:
- - expr - target expression marking the end of the data to be skipped
- - include - (default=C{False}) if True, the target expression is also parsed
- (the skipped text and target expression are returned as a 2-element list).
- - ignore - (default=C{None}) used to define grammars (typically quoted strings and
- comments) that might contain false matches to the target expression
- - failOn - (default=C{None}) define expressions that are not allowed to be
- included in the skipped test; if found before the target expression is found,
- the SkipTo is not a match
-
- Example::
- report = '''
- Outstanding Issues Report - 1 Jan 2000
-
- # | Severity | Description | Days Open
- -----+----------+-------------------------------------------+-----------
- 101 | Critical | Intermittent system crash | 6
- 94 | Cosmetic | Spelling error on Login ('log|n') | 14
- 79 | Minor | System slow when running too many reports | 47
- '''
- integer = Word(nums)
- SEP = Suppress('|')
- # use SkipTo to simply match everything up until the next SEP
- # - ignore quoted strings, so that a '|' character inside a quoted string does not match
- # - parse action will call token.strip() for each matched token, i.e., the description body
- string_data = SkipTo(SEP, ignore=quotedString)
- string_data.setParseAction(tokenMap(str.strip))
- ticket_expr = (integer("issue_num") + SEP
- + string_data("sev") + SEP
- + string_data("desc") + SEP
- + integer("days_open"))
-
- for tkt in ticket_expr.searchString(report):
- print tkt.dump()
- prints::
- ['101', 'Critical', 'Intermittent system crash', '6']
- - days_open: 6
- - desc: Intermittent system crash
- - issue_num: 101
- - sev: Critical
- ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
- - days_open: 14
- - desc: Spelling error on Login ('log|n')
- - issue_num: 94
- - sev: Cosmetic
- ['79', 'Minor', 'System slow when running too many reports', '47']
- - days_open: 47
- - desc: System slow when running too many reports
- - issue_num: 79
- - sev: Minor
- """
- def __init__( self, other, include=False, ignore=None, failOn=None ):
- super( SkipTo, self ).__init__( other )
- self.ignoreExpr = ignore
- self.mayReturnEmpty = True
- self.mayIndexError = False
- self.includeMatch = include
- self.asList = False
- if isinstance(failOn, basestring):
- self.failOn = ParserElement._literalStringClass(failOn)
- else:
- self.failOn = failOn
- self.errmsg = "No match found for "+_ustr(self.expr)
-
- def parseImpl( self, instring, loc, doActions=True ):
- startloc = loc
- instrlen = len(instring)
- expr = self.expr
- expr_parse = self.expr._parse
- self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
- self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
-
- tmploc = loc
- while tmploc <= instrlen:
- if self_failOn_canParseNext is not None:
- # break if failOn expression matches
- if self_failOn_canParseNext(instring, tmploc):
- break
-
- if self_ignoreExpr_tryParse is not None:
- # advance past ignore expressions
- while 1:
- try:
- tmploc = self_ignoreExpr_tryParse(instring, tmploc)
- except ParseBaseException:
- break
-
- try:
- expr_parse(instring, tmploc, doActions=False, callPreParse=False)
- except (ParseException, IndexError):
- # no match, advance loc in string
- tmploc += 1
- else:
- # matched skipto expr, done
- break
-
- else:
- # ran off the end of the input string without matching skipto expr, fail
- raise ParseException(instring, loc, self.errmsg, self)
-
- # build up return values
- loc = tmploc
- skiptext = instring[startloc:loc]
- skipresult = ParseResults(skiptext)
-
- if self.includeMatch:
- loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
- skipresult += mat
-
- return loc, skipresult
-
-class Forward(ParseElementEnhance):
- """
- Forward declaration of an expression to be defined later -
- used for recursive grammars, such as algebraic infix notation.
- When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
-
- Note: take care when assigning to C{Forward} not to overlook precedence of operators.
- Specifically, '|' has a lower precedence than '<<', so that::
- fwdExpr << a | b | c
- will actually be evaluated as::
- (fwdExpr << a) | b | c
- thereby leaving b and c out as parseable alternatives. It is recommended that you
- explicitly group the values inserted into the C{Forward}::
- fwdExpr << (a | b | c)
- Converting to use the '<<=' operator instead will avoid this problem.
-
- See L{ParseResults.pprint} for an example of a recursive parser created using
- C{Forward}.
- """
- def __init__( self, other=None ):
- super(Forward,self).__init__( other, savelist=False )
-
- def __lshift__( self, other ):
- if isinstance( other, basestring ):
- other = ParserElement._literalStringClass(other)
- self.expr = other
- self.strRepr = None
- self.mayIndexError = self.expr.mayIndexError
- self.mayReturnEmpty = self.expr.mayReturnEmpty
- self.setWhitespaceChars( self.expr.whiteChars )
- self.skipWhitespace = self.expr.skipWhitespace
- self.saveAsList = self.expr.saveAsList
- self.ignoreExprs.extend(self.expr.ignoreExprs)
- return self
-
- def __ilshift__(self, other):
- return self << other
-
- def leaveWhitespace( self ):
- self.skipWhitespace = False
- return self
-
- def streamline( self ):
- if not self.streamlined:
- self.streamlined = True
- if self.expr is not None:
- self.expr.streamline()
- return self
-
- def validate( self, validateTrace=[] ):
- if self not in validateTrace:
- tmp = validateTrace[:]+[self]
- if self.expr is not None:
- self.expr.validate(tmp)
- self.checkRecursion([])
-
- def __str__( self ):
- if hasattr(self,"name"):
- return self.name
- return self.__class__.__name__ + ": ..."
-
- # stubbed out for now - creates awful memory and perf issues
- self._revertClass = self.__class__
- self.__class__ = _ForwardNoRecurse
- try:
- if self.expr is not None:
- retString = _ustr(self.expr)
- else:
- retString = "None"
- finally:
- self.__class__ = self._revertClass
- return self.__class__.__name__ + ": " + retString
-
- def copy(self):
- if self.expr is not None:
- return super(Forward,self).copy()
- else:
- ret = Forward()
- ret <<= self
- return ret
-
-class _ForwardNoRecurse(Forward):
- def __str__( self ):
- return "..."
-
-class TokenConverter(ParseElementEnhance):
- """
- Abstract subclass of C{ParseExpression}, for converting parsed results.
- """
- def __init__( self, expr, savelist=False ):
- super(TokenConverter,self).__init__( expr )#, savelist )
- self.saveAsList = False
-
-class Combine(TokenConverter):
- """
- Converter to concatenate all matching tokens to a single string.
- By default, the matching patterns must also be contiguous in the input string;
- this can be disabled by specifying C{'adjacent=False'} in the constructor.
-
- Example::
- real = Word(nums) + '.' + Word(nums)
- print(real.parseString('3.1416')) # -> ['3', '.', '1416']
- # will also erroneously match the following
- print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
-
- real = Combine(Word(nums) + '.' + Word(nums))
- print(real.parseString('3.1416')) # -> ['3.1416']
- # no match when there are internal spaces
- print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
- """
- def __init__( self, expr, joinString="", adjacent=True ):
- super(Combine,self).__init__( expr )
- # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
- if adjacent:
- self.leaveWhitespace()
- self.adjacent = adjacent
- self.skipWhitespace = True
- self.joinString = joinString
- self.callPreparse = True
-
- def ignore( self, other ):
- if self.adjacent:
- ParserElement.ignore(self, other)
- else:
- super( Combine, self).ignore( other )
- return self
-
- def postParse( self, instring, loc, tokenlist ):
- retToks = tokenlist.copy()
- del retToks[:]
- retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
-
- if self.resultsName and retToks.haskeys():
- return [ retToks ]
- else:
- return retToks
-
-class Group(TokenConverter):
- """
- Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
-
- Example::
- ident = Word(alphas)
- num = Word(nums)
- term = ident | num
- func = ident + Optional(delimitedList(term))
- print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100']
-
- func = ident + Group(Optional(delimitedList(term)))
- print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']]
- """
- def __init__( self, expr ):
- super(Group,self).__init__( expr )
- self.saveAsList = True
-
- def postParse( self, instring, loc, tokenlist ):
- return [ tokenlist ]
-
-class Dict(TokenConverter):
- """
- Converter to return a repetitive expression as a list, but also as a dictionary.
- Each element can also be referenced using the first token in the expression as its key.
- Useful for tabular report scraping when the first column can be used as a item key.
-
- Example::
- data_word = Word(alphas)
- label = data_word + FollowedBy(':')
- attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
-
- text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
- attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
-
- # print attributes as plain groups
- print(OneOrMore(attr_expr).parseString(text).dump())
-
- # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
- result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
- print(result.dump())
-
- # access named fields as dict entries, or output as dict
- print(result['shape'])
- print(result.asDict())
- prints::
- ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
-
- [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
- - color: light blue
- - posn: upper left
- - shape: SQUARE
- - texture: burlap
- SQUARE
- {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
- See more examples at L{ParseResults} of accessing fields by results name.
- """
- def __init__( self, expr ):
- super(Dict,self).__init__( expr )
- self.saveAsList = True
-
- def postParse( self, instring, loc, tokenlist ):
- for i,tok in enumerate(tokenlist):
- if len(tok) == 0:
- continue
- ikey = tok[0]
- if isinstance(ikey,int):
- ikey = _ustr(tok[0]).strip()
- if len(tok)==1:
- tokenlist[ikey] = _ParseResultsWithOffset("",i)
- elif len(tok)==2 and not isinstance(tok[1],ParseResults):
- tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
- else:
- dictvalue = tok.copy() #ParseResults(i)
- del dictvalue[0]
- if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
- tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
- else:
- tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
-
- if self.resultsName:
- return [ tokenlist ]
- else:
- return tokenlist
-
-
-class Suppress(TokenConverter):
- """
- Converter for ignoring the results of a parsed expression.
-
- Example::
- source = "a, b, c,d"
- wd = Word(alphas)
- wd_list1 = wd + ZeroOrMore(',' + wd)
- print(wd_list1.parseString(source))
-
- # often, delimiters that are useful during parsing are just in the
- # way afterward - use Suppress to keep them out of the parsed output
- wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
- print(wd_list2.parseString(source))
- prints::
- ['a', ',', 'b', ',', 'c', ',', 'd']
- ['a', 'b', 'c', 'd']
- (See also L{delimitedList}.)
- """
- def postParse( self, instring, loc, tokenlist ):
- return []
-
- def suppress( self ):
- return self
-
-
-class OnlyOnce(object):
- """
- Wrapper for parse actions, to ensure they are only called once.
- """
- def __init__(self, methodCall):
- self.callable = _trim_arity(methodCall)
- self.called = False
- def __call__(self,s,l,t):
- if not self.called:
- results = self.callable(s,l,t)
- self.called = True
- return results
- raise ParseException(s,l,"")
- def reset(self):
- self.called = False
-
-def traceParseAction(f):
- """
- Decorator for debugging parse actions.
-
- 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']
- """
- f = _trim_arity(f)
- def z(*paArgs):
- thisFunc = f.__name__
- s,l,t = paArgs[-3:]
- if len(paArgs)>3:
- thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
- sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
- try:
- ret = f(*paArgs)
- except Exception as exc:
- sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
- raise
- sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
- return ret
- try:
- z.__name__ = f.__name__
- except AttributeError:
- pass
- return z
-
-#
-# global helpers
-#
-def delimitedList( expr, delim=",", combine=False ):
- """
- 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 C{combine=True} in the constructor.
- If C{combine} is set to C{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']
- """
- dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
- if combine:
- return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
- else:
- return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
-
-def countedArray( expr, intExpr=None ):
- """
- Helper to define a counted list of expressions.
- This helper defines a pattern of the form::
- integer expr expr expr...
- where the leading integer tells how many expr expressions follow.
- The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
-
- Example::
- countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd']
- """
- arrayExpr = Forward()
- def countFieldParseAction(s,l,t):
- n = t[0]
- arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
- return []
- if intExpr is None:
- intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
- else:
- intExpr = intExpr.copy()
- intExpr.setName("arrayLen")
- intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
- return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
-
-def _flatten(L):
- ret = []
- for i in L:
- if isinstance(i,list):
- ret.extend(_flatten(i))
- else:
- ret.append(i)
- return ret
-
-def matchPreviousLiteral(expr):
- """
- Helper to define an expression that is indirectly defined from
- the tokens matched in a previous expression, that is, it looks
- for a 'repeat' of a previous expression. For example::
- first = Word(nums)
- second = matchPreviousLiteral(first)
- matchExpr = first + ":" + second
- will match C{"1:1"}, but not C{"1:2"}. Because this matches a
- previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
- If this is not desired, use C{matchPreviousExpr}.
- Do *not* use with packrat parsing enabled.
- """
- rep = Forward()
- def copyTokenToRepeater(s,l,t):
- if t:
- if len(t) == 1:
- rep << t[0]
- else:
- # flatten t tokens
- tflat = _flatten(t.asList())
- rep << And(Literal(tt) for tt in tflat)
- else:
- rep << Empty()
- expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
- rep.setName('(prev) ' + _ustr(expr))
- return rep
-
-def matchPreviousExpr(expr):
- """
- Helper to define an expression that is indirectly defined from
- the tokens matched in a previous expression, that is, it looks
- for a 'repeat' of a previous expression. For example::
- first = Word(nums)
- second = matchPreviousExpr(first)
- matchExpr = first + ":" + second
- will match C{"1:1"}, but not C{"1:2"}. Because this matches by
- expressions, will *not* match the leading C{"1:1"} in C{"1:10"};
- the expressions are evaluated first, and then compared, so
- C{"1"} is compared with C{"10"}.
- Do *not* use with packrat parsing enabled.
- """
- rep = Forward()
- e2 = expr.copy()
- rep <<= e2
- def copyTokenToRepeater(s,l,t):
- matchTokens = _flatten(t.asList())
- def mustMatchTheseTokens(s,l,t):
- theseTokens = _flatten(t.asList())
- if theseTokens != matchTokens:
- raise ParseException("",0,"")
- rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
- expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
- rep.setName('(prev) ' + _ustr(expr))
- return rep
-
-def _escapeRegexRangeChars(s):
- #~ escape these chars: ^-]
- for c in r"\^-]":
- s = s.replace(c,_bslash+c)
- s = s.replace("\n",r"\n")
- s = s.replace("\t",r"\t")
- return _ustr(s)
-
-def oneOf( strs, caseless=False, useRegex=True ):
- """
- Helper to quickly define a set of alternative Literals, and makes sure to do
- longest-first testing when there is a conflict, regardless of the input order,
- but returns a C{L{MatchFirst}} for best performance.
-
- Parameters:
- - strs - a string of space-delimited literals, or a list of string literals
- - caseless - (default=C{False}) - treat all literals as caseless
- - useRegex - (default=C{True}) - as an optimization, will generate a Regex
- object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
- if creating a C{Regex} raises an exception)
-
- Example::
- comp_oper = oneOf("< = > <= >= !=")
- var = Word(alphas)
- number = Word(nums)
- term = var | number
- comparison_expr = term + comp_oper + term
- print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12"))
- prints::
- [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
- """
- if caseless:
- isequal = ( lambda a,b: a.upper() == b.upper() )
- masks = ( lambda a,b: b.upper().startswith(a.upper()) )
- parseElementClass = CaselessLiteral
- else:
- isequal = ( lambda a,b: a == b )
- masks = ( lambda a,b: b.startswith(a) )
- parseElementClass = Literal
-
- symbols = []
- if isinstance(strs,basestring):
- symbols = strs.split()
- elif isinstance(strs, collections.Sequence):
- symbols = list(strs[:])
- elif isinstance(strs, _generatorType):
- symbols = list(strs)
- else:
- warnings.warn("Invalid argument to oneOf, expected string or list",
- SyntaxWarning, stacklevel=2)
- if not symbols:
- return NoMatch()
-
- i = 0
- while i < len(symbols)-1:
- cur = symbols[i]
- for j,other in enumerate(symbols[i+1:]):
- if ( isequal(other, cur) ):
- del symbols[i+j+1]
- break
- elif ( masks(cur, other) ):
- del symbols[i+j+1]
- symbols.insert(i,other)
- cur = other
- break
- else:
- i += 1
-
- if not caseless and useRegex:
- #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
- try:
- if len(symbols)==len("".join(symbols)):
- return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
- else:
- return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
- except:
- warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
- SyntaxWarning, stacklevel=2)
-
-
- # last resort, just use MatchFirst
- return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
-
-def dictOf( key, value ):
- """
- Helper to easily and clearly define a dictionary by specifying the respective patterns
- for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
- in the proper order. The key pattern can include delimiting markers or punctuation,
- as long as they are suppressed, thereby leaving the significant key text. The value
- pattern can include named results, so that the C{Dict} results can include named token
- fields.
-
- Example::
- text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
- attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
- print(OneOrMore(attr_expr).parseString(text).dump())
-
- attr_label = label
- attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
-
- # similar to Dict, but simpler call format
- result = dictOf(attr_label, attr_value).parseString(text)
- print(result.dump())
- print(result['shape'])
- print(result.shape) # object attribute access works too
- print(result.asDict())
- prints::
- [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
- - color: light blue
- - posn: upper left
- - shape: SQUARE
- - texture: burlap
- SQUARE
- SQUARE
- {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
- """
- return Dict( ZeroOrMore( Group ( key + value ) ) )
-
-def originalTextFor(expr, asString=True):
- """
- Helper to return the original, untokenized text for a given expression. Useful to
- restore the parsed fields of an HTML start tag into the raw tag text itself, or to
- revert separate tokens with intervening whitespace back to the original matching
- input text. By default, returns astring containing the original parsed text.
-
- If the optional C{asString} argument is passed as C{False}, then the return value is a
- C{L{ParseResults}} containing any results names that were originally matched, and a
- single token containing the original matched text from the input string. So if
- the expression passed to C{L{originalTextFor}} contains expressions with defined
- results names, you must set C{asString} to C{False} if you want to preserve those
- results name values.
-
- Example::
- src = "this is test <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>']
- """
- locMarker = Empty().setParseAction(lambda s,loc,t: loc)
- endlocMarker = locMarker.copy()
- endlocMarker.callPreparse = False
- matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
- if asString:
- extractText = lambda s,l,t: s[t._original_start:t._original_end]
- else:
- def extractText(s,l,t):
- t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
- matchExpr.setParseAction(extractText)
- matchExpr.ignoreExprs = expr.ignoreExprs
- return matchExpr
-
-def ungroup(expr):
- """
- Helper to undo pyparsing's default grouping of And expressions, even
- if all but one are non-empty.
- """
- return TokenConverter(expr).setParseAction(lambda t:t[0])
-
-def locatedExpr(expr):
- """
- Helper to decorate a returned token with its starting and ending locations in the input string.
- This helper adds the following results names:
- - locn_start = location where matched expression begins
- - locn_end = location where matched expression ends
- - value = the actual parsed results
-
- Be careful if the input text contains C{<TAB>} characters, you may want to call
- C{L{ParserElement.parseWithTabs}}
-
- Example::
- wd = Word(alphas)
- for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
- print(match)
- prints::
- [[0, 'ljsdf', 5]]
- [[8, 'lksdjjf', 15]]
- [[18, 'lkkjj', 23]]
- """
- locator = Empty().setParseAction(lambda s,l,t: l)
- return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
-
-
-# convenience constants for positional expressions
-empty = Empty().setName("empty")
-lineStart = LineStart().setName("lineStart")
-lineEnd = LineEnd().setName("lineEnd")
-stringStart = StringStart().setName("stringStart")
-stringEnd = StringEnd().setName("stringEnd")
-
-_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
-_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
-_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
-_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
-_charRange = Group(_singleChar + Suppress("-") + _singleChar)
-_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
-
-def srange(s):
- r"""
- Helper to easily define string ranges for use in Word construction. Borrows
- syntax from regexp '[]' string range definitions::
- srange("[0-9]") -> "0123456789"
- srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz"
- srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
- The input string must be enclosed in []'s, and the returned string is the expanded
- character set joined into a single string.
- The values enclosed in the []'s may be:
- - a single character
- - an escaped character with a leading backslash (such as C{\-} or C{\]})
- - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character)
- (C{\0x##} is also supported for backwards compatibility)
- - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
- - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
- - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
- """
- _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
- try:
- return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
- except:
- return ""
-
-def matchOnlyAtCol(n):
- """
- Helper method for defining parse actions that require matching at a specific
- column in the input text.
- """
- def verifyCol(strg,locn,toks):
- if col(locn,strg) != n:
- raise ParseException(strg,locn,"matched token not at column %d" % n)
- return verifyCol
-
-def replaceWith(replStr):
- """
- Helper method for common parse actions that simply return a literal value. Especially
- useful when used with C{L{transformString<ParserElement.transformString>}()}.
-
- Example::
- num = Word(nums).setParseAction(lambda toks: int(toks[0]))
- na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
- term = na | num
-
- OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
- """
- return lambda s,l,t: [replStr]
-
-def removeQuotes(s,l,t):
- """
- Helper parse action for removing quotation marks from parsed quoted strings.
-
- Example::
- # by default, quotation marks are included in parsed results
- quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
-
- # use removeQuotes to strip quotation marks from parsed results
- quotedString.setParseAction(removeQuotes)
- quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
- """
- return t[0][1:-1]
-
-def tokenMap(func, *args):
- """
- Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional
- args are passed, they are forwarded to the given function as additional arguments after
- the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
- parsed data to an integer using base 16.
-
- Example (compare the last to example in L{ParserElement.transformString}::
- hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
- hex_ints.runTests('''
- 00 11 22 aa FF 0a 0d 1a
- ''')
-
- upperword = Word(alphas).setParseAction(tokenMap(str.upper))
- OneOrMore(upperword).runTests('''
- my kingdom for a horse
- ''')
-
- wd = Word(alphas).setParseAction(tokenMap(str.title))
- OneOrMore(wd).setParseAction(' '.join).runTests('''
- now is the winter of our discontent made glorious summer by this sun of york
- ''')
- prints::
- 00 11 22 aa FF 0a 0d 1a
- [0, 17, 34, 170, 255, 10, 13, 26]
-
- my kingdom for a horse
- ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
-
- now is the winter of our discontent made glorious summer by this sun of york
- ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
- """
- def pa(s,l,t):
- return [func(tokn, *args) for tokn in t]
-
- try:
- func_name = getattr(func, '__name__',
- getattr(func, '__class__').__name__)
- except Exception:
- func_name = str(func)
- pa.__name__ = func_name
-
- return pa
-
-upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
-"""Helper parse action to convert tokens to upper case."""
-
-downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
-"""Helper parse action to convert tokens to lower case."""
-
-def _makeTags(tagStr, xml):
- """Internal helper to construct opening and closing tag expressions, given a tag name"""
- if isinstance(tagStr,basestring):
- resname = tagStr
- tagStr = Keyword(tagStr, caseless=not xml)
- else:
- resname = tagStr.name
-
- tagAttrName = Word(alphas,alphanums+"_-:")
- if (xml):
- tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
- openTag = Suppress("<") + tagStr("tag") + \
- Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
- Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
- else:
- printablesLessRAbrack = "".join(c for c in printables if c not in ">")
- tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
- openTag = Suppress("<") + tagStr("tag") + \
- Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
- Optional( Suppress("=") + tagAttrValue ) ))) + \
- Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
- closeTag = Combine(_L("</") + tagStr + ">")
-
- openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
- closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname)
- openTag.tag = resname
- closeTag.tag = resname
- return openTag, closeTag
-
-def makeHTMLTags(tagStr):
- """
- Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
- tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
-
- Example::
- text = '<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
- """
- return _makeTags( tagStr, False )
-
-def makeXMLTags(tagStr):
- """
- Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
- tags only in the given upper/lower case.
-
- Example: similar to L{makeHTMLTags}
- """
- return _makeTags( tagStr, True )
-
-def withAttribute(*args,**attrDict):
- """
- Helper to create a validating parse action to be used with start tags created
- with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
- with a required attribute value, to avoid false matches on common tags such as
- C{<TD>} or C{<DIV>}.
-
- Call C{withAttribute} with a series of attribute names and values. Specify the list
- of filter attributes names and values as:
- - keyword arguments, as in C{(align="right")}, or
- - as an explicit dict with C{**} operator, when an attribute name is also a Python
- reserved word, as in C{**{"class":"Customer", "align":"right"}}
- - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
- For attribute names with a namespace prefix, you must use the second form. Attribute
- names are matched insensitive to upper/lower case.
-
- If just testing for C{class} (with or without a namespace), use C{L{withClass}}.
-
- To verify that the attribute exists, but without specifying a value, pass
- C{withAttribute.ANY_VALUE} as the value.
-
- Example::
- html = '''
- <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
- """
- if args:
- attrs = args[:]
- else:
- attrs = attrDict.items()
- attrs = [(k,v) for k,v in attrs]
- def pa(s,l,tokens):
- for attrName,attrValue in attrs:
- if attrName not in tokens:
- raise ParseException(s,l,"no matching attribute " + attrName)
- if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
- raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
- (attrName, tokens[attrName], attrValue))
- return pa
-withAttribute.ANY_VALUE = object()
-
-def withClass(classname, namespace=''):
- """
- Simplified version of C{L{withAttribute}} when matching on a div class - made
- difficult because C{class} is a reserved word in Python.
-
- Example::
- html = '''
- <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
- """
- classattr = "%s:class" % namespace if namespace else "class"
- return withAttribute(**{classattr : classname})
-
-opAssoc = _Constants()
-opAssoc.LEFT = object()
-opAssoc.RIGHT = object()
-
-def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
- """
- Helper method for constructing grammars of expressions made up of
- operators working in a precedence hierarchy. Operators may be unary or
- binary, left- or right-associative. Parse actions can also be attached
- to operator expressions.
-
- Parameters:
- - baseExpr - expression representing the most basic element for the nested
- - opList - list of tuples, one for each operator precedence level in the
- expression grammar; each tuple is of the form
- (opExpr, numTerms, rightLeftAssoc, parseAction), where:
- - opExpr is the pyparsing expression for the operator;
- may also be a string, which will be converted to a Literal;
- if numTerms is 3, opExpr is a tuple of two expressions, for the
- two operators separating the 3 terms
- - numTerms is the number of terms for this operator (must
- be 1, 2, or 3)
- - rightLeftAssoc is the indicator whether the operator is
- right or left associative, using the pyparsing-defined
- constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
- - parseAction is the parse action to be associated with
- expressions matching this operator expression (the
- parse action tuple member may be omitted)
- - lpar - expression for matching left-parentheses (default=C{Suppress('(')})
- - rpar - expression for matching right-parentheses (default=C{Suppress(')')})
-
- Example::
- # simple example of four-function arithmetic with ints and variable names
- integer = pyparsing_common.signedInteger
- varname = pyparsing_common.identifier
-
- arith_expr = infixNotation(integer | varname,
- [
- ('-', 1, opAssoc.RIGHT),
- (oneOf('* /'), 2, opAssoc.LEFT),
- (oneOf('+ -'), 2, opAssoc.LEFT),
- ])
-
- arith_expr.runTests('''
- 5+3*6
- (5+3)*6
- -2--11
- ''', fullDump=False)
- prints::
- 5+3*6
- [[5, '+', [3, '*', 6]]]
-
- (5+3)*6
- [[[5, '+', 3], '*', 6]]
-
- -2--11
- [[['-', 2], '-', ['-', 11]]]
- """
- ret = Forward()
- lastExpr = baseExpr | ( lpar + ret + rpar )
- for i,operDef in enumerate(opList):
- opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
- termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr
- if arity == 3:
- if opExpr is None or len(opExpr) != 2:
- raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
- opExpr1, opExpr2 = opExpr
- thisExpr = Forward().setName(termName)
- if rightLeftAssoc == opAssoc.LEFT:
- if arity == 1:
- matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
- elif arity == 2:
- if opExpr is not None:
- matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
- else:
- matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
- elif arity == 3:
- matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
- Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
- else:
- raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
- elif rightLeftAssoc == opAssoc.RIGHT:
- if arity == 1:
- # try to avoid LR with this extra test
- if not isinstance(opExpr, Optional):
- opExpr = Optional(opExpr)
- matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
- elif arity == 2:
- if opExpr is not None:
- matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
- else:
- matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
- elif arity == 3:
- matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
- Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
- else:
- raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
- else:
- raise ValueError("operator must indicate right or left associativity")
- if pa:
- matchExpr.setParseAction( pa )
- thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
- lastExpr = thisExpr
- ret <<= lastExpr
- return ret
-
-operatorPrecedence = infixNotation
-"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release."""
-
-dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes")
-sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes")
-quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'|
- Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes")
-unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal")
-
-def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()):
- """
- Helper method for defining nested lists enclosed in opening and closing
- delimiters ("(" and ")" are the default).
-
- Parameters:
- - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression
- - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression
- - content - expression for items within the nested lists (default=C{None})
- - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString})
-
- If an expression is not provided for the content argument, the nested
- expression will capture all whitespace-delimited content between delimiters
- as a list of separate values.
-
- Use the C{ignoreExpr} argument to define expressions that may contain
- opening or closing characters that should not be treated as opening
- or closing characters for nesting, such as quotedString or a comment
- expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}.
- The default is L{quotedString}, but if no expressions are to be ignored,
- then pass C{None} for this argument.
-
- Example::
- data_type = oneOf("void int short long char float double")
- decl_data_type = Combine(data_type + Optional(Word('*')))
- ident = Word(alphas+'_', alphanums+'_')
- number = pyparsing_common.number
- arg = Group(decl_data_type + ident)
- LPAR,RPAR = map(Suppress, "()")
-
- code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment))
-
- c_function = (decl_data_type("type")
- + ident("name")
- + LPAR + Optional(delimitedList(arg), [])("args") + RPAR
- + code_body("body"))
- c_function.ignore(cStyleComment)
-
- source_code = '''
- int is_odd(int x) {
- return (x%2);
- }
-
- int dec_to_hex(char hchar) {
- if (hchar >= '0' && hchar <= '9') {
- return (ord(hchar)-ord('0'));
- } else {
- return (10+ord(hchar)-ord('A'));
- }
- }
- '''
- for func in c_function.searchString(source_code):
- print("%(name)s (%(type)s) args: %(args)s" % func)
-
- prints::
- is_odd (int) args: [['int', 'x']]
- dec_to_hex (int) args: [['char', 'hchar']]
- """
- if opener == closer:
- raise ValueError("opening and closing strings cannot be the same")
- if content is None:
- if isinstance(opener,basestring) and isinstance(closer,basestring):
- if len(opener) == 1 and len(closer)==1:
- if ignoreExpr is not None:
- content = (Combine(OneOrMore(~ignoreExpr +
- CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
- ).setParseAction(lambda t:t[0].strip()))
- else:
- content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS
- ).setParseAction(lambda t:t[0].strip()))
- else:
- if ignoreExpr is not None:
- content = (Combine(OneOrMore(~ignoreExpr +
- ~Literal(opener) + ~Literal(closer) +
- CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
- ).setParseAction(lambda t:t[0].strip()))
- else:
- content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) +
- CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
- ).setParseAction(lambda t:t[0].strip()))
- else:
- raise ValueError("opening and closing arguments must be strings if no content expression is given")
- ret = Forward()
- if ignoreExpr is not None:
- ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
- else:
- ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) )
- ret.setName('nested %s%s expression' % (opener,closer))
- return ret
-
-def indentedBlock(blockStatementExpr, indentStack, indent=True):
- """
- Helper method for defining space-delimited indentation blocks, such as
- those used to define block statements in Python source code.
-
- Parameters:
- - blockStatementExpr - expression defining syntax of statement that
- is repeated within the indented block
- - indentStack - list created by caller to manage indentation stack
- (multiple statementWithIndentedBlock expressions within a single grammar
- should share a common indentStack)
- - indent - boolean indicating whether block must be indented beyond the
- the current level; set to False for block of left-most statements
- (default=C{True})
-
- A valid block must contain at least one C{blockStatement}.
-
- Example::
- data = '''
- def A(z):
- A1
- B = 100
- G = A2
- A2
- A3
- B
- def BB(a,b,c):
- BB1
- def BBA():
- bba1
- bba2
- bba3
- C
- D
- def spam(x,y):
- def eggs(z):
- pass
- '''
-
-
- indentStack = [1]
- stmt = Forward()
-
- identifier = Word(alphas, alphanums)
- funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":")
- func_body = indentedBlock(stmt, indentStack)
- funcDef = Group( funcDecl + func_body )
-
- rvalue = Forward()
- funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")")
- rvalue << (funcCall | identifier | Word(nums))
- assignment = Group(identifier + "=" + rvalue)
- stmt << ( funcDef | assignment | identifier )
-
- module_body = OneOrMore(stmt)
-
- parseTree = module_body.parseString(data)
- parseTree.pprint()
- prints::
- [['def',
- 'A',
- ['(', 'z', ')'],
- ':',
- [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]],
- 'B',
- ['def',
- 'BB',
- ['(', 'a', 'b', 'c', ')'],
- ':',
- [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]],
- 'C',
- 'D',
- ['def',
- 'spam',
- ['(', 'x', 'y', ')'],
- ':',
- [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]]
- """
- def checkPeerIndent(s,l,t):
- if l >= len(s): return
- curCol = col(l,s)
- if curCol != indentStack[-1]:
- if curCol > indentStack[-1]:
- raise ParseFatalException(s,l,"illegal nesting")
- raise ParseException(s,l,"not a peer entry")
-
- def checkSubIndent(s,l,t):
- curCol = col(l,s)
- if curCol > indentStack[-1]:
- indentStack.append( curCol )
- else:
- raise ParseException(s,l,"not a subentry")
-
- def checkUnindent(s,l,t):
- if l >= len(s): return
- curCol = col(l,s)
- if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
- raise ParseException(s,l,"not an unindent")
- indentStack.pop()
-
- NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
- INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
- PEER = Empty().setParseAction(checkPeerIndent).setName('')
- UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
- if indent:
- smExpr = Group( Optional(NL) +
- #~ FollowedBy(blockStatementExpr) +
- INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
- else:
- smExpr = Group( Optional(NL) +
- (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
- blockStatementExpr.ignore(_bslash + LineEnd())
- return smExpr.setName('indented block')
-
-alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
-punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
-
-anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag'))
-_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\''))
-commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity")
-def replaceHTMLEntity(t):
- """Helper parser action to replace common HTML entities with their special characters"""
- return _htmlEntityMap.get(t.entity)
-
-# it's easy to get these comment structures wrong - they're very common, so may as well make them available
-cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment")
-"Comment of the form C{/* ... */}"
-
-htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment")
-"Comment of the form C{<!-- ... -->}"
-
-restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line")
-dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment")
-"Comment of the form C{// ... (to end of line)}"
-
-cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment")
-"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}"
-
-javaStyleComment = cppStyleComment
-"Same as C{L{cppStyleComment}}"
-
-pythonStyleComment = Regex(r"#.*").setName("Python style comment")
-"Comment of the form C{# ... (to end of line)}"
-
-_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') +
- Optional( Word(" \t") +
- ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
-commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList")
-"""Predefined expression of 1 or more printable words or quoted strings, separated by commas."""
-
-# some other useful expressions - using lower-case class name since we are really using this as a namespace
-class pyparsing_common:
- """
- Here are some common low-level expressions that may be useful in jump-starting parser development:
- - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sciReal>})
- - common L{programming identifiers<identifier>}
- - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>})
- - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>}
- - L{UUID<uuid>}
- Parse actions:
- - C{L{convertToInteger}}
- - C{L{convertToFloat}}
- - C{L{convertToDate}}
- - C{L{convertToDatetime}}
- - C{L{stripHTMLTags}}
-
- Example::
- pyparsing_common.number.runTests('''
- # any int or real number, returned as the appropriate type
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- ''')
-
- pyparsing_common.fnumber.runTests('''
- # any int or real number, returned as float
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- ''')
-
- pyparsing_common.hex_integer.runTests('''
- # hex numbers
- 100
- FF
- ''')
-
- pyparsing_common.fraction.runTests('''
- # fractions
- 1/2
- -3/4
- ''')
-
- pyparsing_common.mixed_integer.runTests('''
- # mixed fractions
- 1
- 1/2
- -3/4
- 1-3/4
- ''')
-
- import uuid
- pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
- pyparsing_common.uuid.runTests('''
- # uuid
- 12345678-1234-5678-1234-567812345678
- ''')
- prints::
- # any int or real number, returned as the appropriate type
- 100
- [100]
-
- -100
- [-100]
-
- +100
- [100]
-
- 3.14159
- [3.14159]
-
- 6.02e23
- [6.02e+23]
-
- 1e-12
- [1e-12]
-
- # any int or real number, returned as float
- 100
- [100.0]
-
- -100
- [-100.0]
-
- +100
- [100.0]
-
- 3.14159
- [3.14159]
-
- 6.02e23
- [6.02e+23]
-
- 1e-12
- [1e-12]
-
- # hex numbers
- 100
- [256]
-
- FF
- [255]
-
- # fractions
- 1/2
- [0.5]
-
- -3/4
- [-0.75]
-
- # mixed fractions
- 1
- [1]
-
- 1/2
- [0.5]
-
- -3/4
- [-0.75]
-
- 1-3/4
- [1.75]
-
- # uuid
- 12345678-1234-5678-1234-567812345678
- [UUID('12345678-1234-5678-1234-567812345678')]
- """
-
- convertToInteger = tokenMap(int)
- """
- Parse action for converting parsed integers to Python int
- """
-
- convertToFloat = tokenMap(float)
- """
- Parse action for converting parsed numbers to Python float
- """
-
- integer = Word(nums).setName("integer").setParseAction(convertToInteger)
- """expression that parses an unsigned integer, returns an int"""
-
- hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16))
- """expression that parses a hexadecimal integer, returns an int"""
-
- signedInteger = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger)
- """expression that parses an integer with optional leading sign, returns an int"""
-
- fraction = (signedInteger().setParseAction(convertToFloat) + '/' + signedInteger().setParseAction(convertToFloat)).setName("fraction")
- """fractional expression of an integer divided by an integer, returns a float"""
- fraction.addParseAction(lambda t: t[0]/t[-1])
-
- mixed_integer = (fraction | signedInteger + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction")
- """mixed integer of the form 'integer - fraction', with optional leading integer, returns float"""
- mixed_integer.addParseAction(sum)
-
- real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat)
- """expression that parses a floating point number and returns a float"""
-
- sciReal = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat)
- """expression that parses a floating point number with optional scientific notation and returns a float"""
-
- # streamlining this expression makes the docs nicer-looking
- number = (sciReal | real | signedInteger).streamline()
- """any numeric expression, returns the corresponding Python type"""
-
- fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat)
- """any int or real number, returned as float"""
-
- identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
- """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')"""
-
- ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
- "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
-
- _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer")
- _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address")
- _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address")
- _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
- _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address")
- ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address")
- "IPv6 address (long, short, or mixed form)"
-
- mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
- "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
-
- @staticmethod
- def convertToDate(fmt="%Y-%m-%d"):
- """
- Helper to create a parse action for converting parsed date string to Python datetime.date
-
- Params -
- - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"})
-
- Example::
- date_expr = pyparsing_common.iso8601_date.copy()
- date_expr.setParseAction(pyparsing_common.convertToDate())
- print(date_expr.parseString("1999-12-31"))
- prints::
- [datetime.date(1999, 12, 31)]
- """
- return lambda s,l,t: datetime.strptime(t[0], fmt).date()
-
- @staticmethod
- def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"):
- """
- Helper to create a parse action for converting parsed datetime string to Python datetime.datetime
-
- Params -
- - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"})
-
- Example::
- dt_expr = pyparsing_common.iso8601_datetime.copy()
- dt_expr.setParseAction(pyparsing_common.convertToDatetime())
- print(dt_expr.parseString("1999-12-31T23:59:59.999"))
- prints::
- [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)]
- """
- return lambda s,l,t: datetime.strptime(t[0], fmt)
-
- iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date")
- "ISO8601 date (C{yyyy-mm-dd})"
-
- 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")
- "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}"
-
- uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID")
- "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})"
-
- _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
- @staticmethod
- def stripHTMLTags(s, l, tokens):
- """
- Parse action to remove HTML tags from web page HTML source
-
- Example::
- # strip HTML links from normal text
- text = '<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'
- """
- return pyparsing_common._html_stripper.transformString(tokens[0])
-
-if __name__ == "__main__":
-
- selectToken = CaselessLiteral("select")
- fromToken = CaselessLiteral("from")
-
- ident = Word(alphas, alphanums + "_$")
-
- columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
- columnNameList = Group(delimitedList(columnName)).setName("columns")
- columnSpec = ('*' | columnNameList)
-
- tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
- tableNameList = Group(delimitedList(tableName)).setName("tables")
-
- simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables")
-
- # demo runTests method, including embedded comments in test string
- simpleSQL.runTests("""
- # '*' as column list and dotted table name
- select * from SYS.XYZZY
-
- # caseless match on "SELECT", and casts back to "select"
- SELECT * from XYZZY, ABC
-
- # list of column names, and mixed case SELECT keyword
- Select AA,BB,CC from Sys.dual
-
- # multiple tables
- Select A, B, C from Sys.dual, Table2
-
- # invalid SELECT keyword - should fail
- Xelect A, B, C from Sys.dual
-
- # incomplete command - should fail
- Select
-
- # invalid column name - should fail
- Select ^^^ frox Sys.dual
-
- """)
-
- pyparsing_common.number.runTests("""
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- """)
-
- # any int or real number, returned as float
- pyparsing_common.fnumber.runTests("""
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- """)
-
- pyparsing_common.hex_integer.runTests("""
- 100
- FF
- """)
-
- import uuid
- pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
- pyparsing_common.uuid.runTests("""
- 12345678-1234-5678-1234-567812345678
- """)
diff --git a/trunk/src/pyparsingClassDiagram.JPG b/trunk/src/pyparsingClassDiagram.JPG
deleted file mode 100644
index ef10424..0000000
--- a/trunk/src/pyparsingClassDiagram.JPG
+++ /dev/null
Binary files differ
diff --git a/trunk/src/pyparsingClassDiagram.PNG b/trunk/src/pyparsingClassDiagram.PNG
deleted file mode 100644
index f59baaf..0000000
--- a/trunk/src/pyparsingClassDiagram.PNG
+++ /dev/null
Binary files differ
diff --git a/trunk/src/setup.cfg b/trunk/src/setup.cfg
deleted file mode 100644
index 981e089..0000000
--- a/trunk/src/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[bdist_wheel]
-universal = 1
-
-[wheel]
-universal = 1
diff --git a/trunk/src/setup.py b/trunk/src/setup.py
deleted file mode 100644
index 82061c6..0000000
--- a/trunk/src/setup.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-
-"""Setup script for the pyparsing module distribution."""
-from setuptools import setup
-
-import sys
-import os
-
-from pyparsing import __version__ as pyparsing_version
-
-modules = ["pyparsing",]
-
-setup(# Distribution meta-data
- name = "pyparsing",
- version = pyparsing_version,
- description = "Python parsing module",
- author = "Paul McGuire",
- author_email = "ptmcg@users.sourceforge.net",
- url = "http://pyparsing.wikispaces.com/",
- download_url = "http://sourceforge.net/project/showfiles.php?group_id=97203",
- license = "MIT License",
- py_modules = modules,
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Information Technology',
- 'License :: OSI Approved :: MIT License',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2.6',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.3',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
- ]
- )
diff --git a/trunk/src/test/__init__.py b/trunk/src/test/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/trunk/src/test/__init__.py
+++ /dev/null
diff --git a/trunk/src/test/jsonParserTests.py b/trunk/src/test/jsonParserTests.py
deleted file mode 100644
index c8a42bb..0000000
--- a/trunk/src/test/jsonParserTests.py
+++ /dev/null
@@ -1,360 +0,0 @@
-# jsonParser.py
-#
-# Copyright (c) 2006, Paul McGuire
-#
-
-test1 = """
-{
- "glossary": {
- "title": "example glossary",
- "GlossDiv": {
- "title": "S",
- "GlossList": [{
- "ID": "SGML",
- "SortAs": "SGML",
- "GlossTerm": "Standard Generalized Markup Language",
- "Acronym": "SGML",
- "LargestPrimeLessThan100": 97,
- "AvogadroNumber": 6.02E23,
- "EvenPrimesGreaterThan2": null,
- "PrimesLessThan10" : [2,3,5,7],
- "WMDsFound" : false,
- "IraqAlQaedaConnections" : null,
- "Abbrev": "ISO 8879:1986",
- "GlossDef":
-"A meta-markup language, used to create markup languages such as DocBook.",
- "GlossSeeAlso": ["GML", "XML", "markup"],
- "EmptyDict" : {},
- "EmptyList" : []
- }]
- }
- }
-}
-"""
-
-test2 = """
-{"menu": {
- "id": "file",
- "value": "File:",
- "popup": {
- "menuitem": [
- {"value": "New", "onclick": "CreateNewDoc()"},
- {"value": "Open", "onclick": "OpenDoc()"},
- {"value": "Close", "onclick": "CloseDoc()"}
- ]
- }
-}}
-"""
-test3 = """
-{"widget": {
- "debug": "on",
- "window": {
- "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500
- }, "image": {
- "src": "Images/Sun.png",
- "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center"
- }, "text": {
- "data": "Click Here",
- "size": 36,
- "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center",
- "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
- }
-}}
-"""
-test4 = """
-{"web-app": {
- "servlet": [ // Defines the CDSServlet
- {
- "servlet-name": "cofaxCDS",
- "servlet-class": "org.cofax.cds.CDSServlet",
-/*
- Defines glossary variables that template designers
- can use across the site. You can add new
- variables to this set by creating a new init-param, with
- the param-name prefixed with "configGlossary:".
-*/
- "init-param": {
- "configGlossary:installationAt": "Philadelphia, PA",
- "configGlossary:adminEmail": "ksm@pobox.com",
- "configGlossary:poweredBy": "Cofax",
- "configGlossary:poweredByIcon": "/images/cofax.gif",
- "configGlossary:staticPath": "/content/static",
-/*
- Defines the template loader and template processor
- classes. These are implementations of org.cofax.TemplateProcessor
- and org.cofax.TemplateLoader respectively. Simply create new
- implementation of these classes and set them here if the default
- implementations do not suit your needs. Leave these alone
- for the defaults.
-*/
- "templateProcessorClass": "org.cofax.WysiwygTemplate",
- "templateLoaderClass": "org.cofax.FilesTemplateLoader",
- "templatePath": "templates",
- "templateOverridePath": "",
-/*
- Defines the names of the default templates to look for
- when acquiring WYSIWYG templates. Leave these at their
- defaults for most usage.
-*/
- "defaultListTemplate": "listTemplate.htm",
- "defaultFileTemplate": "articleTemplate.htm",
-/*
- New! useJSP switches on JSP template processing.
- jspListTemplate and jspFileTemplate are the names
- of the default templates to look for when aquiring JSP
- templates. Cofax currently in production at KR has useJSP
- set to false, since our sites currently use WYSIWYG
- templating exclusively.
-*/
- "useJSP": false,
- "jspListTemplate": "listTemplate.jsp",
- "jspFileTemplate": "articleTemplate.jsp",
-/*
- Defines the packageTag cache. This cache keeps
- Cofax from needing to interact with the database
- to look up packageTag commands.
-*/
- "cachePackageTagsTrack": 200,
- "cachePackageTagsStore": 200,
- "cachePackageTagsRefresh": 60,
-/*
- Defines the template cache. Keeps Cofax from needing
- to go to the file system to load a raw template from
- the file system.
-*/
- "cacheTemplatesTrack": 100,
- "cacheTemplatesStore": 50,
- "cacheTemplatesRefresh": 15,
-/*
- Defines the page cache. Keeps Cofax from processing
- templates to deliver to users.
-*/
- "cachePagesTrack": 200,
- "cachePagesStore": 100,
- "cachePagesRefresh": 10,
- "cachePagesDirtyRead": 10,
-/*
- Defines the templates Cofax will use when
- being browsed by a search engine identified in
- searchEngineRobotsDb
-*/
- "searchEngineListTemplate": "forSearchEnginesList.htm",
- "searchEngineFileTemplate": "forSearchEngines.htm",
- "searchEngineRobotsDb": "WEB-INF/robots.db",
-/*
- New! useDataStore enables/disables the Cofax database pool
-*/
- "useDataStore": true,
-/*
- Defines the implementation of org.cofax.DataStore that Cofax
- will use. If this DataStore class does not suit your needs
- simply implement a new DataStore class and set here.
-*/
- "dataStoreClass": "org.cofax.SqlDataStore",
-/*
- Defines the implementation of org.cofax.Redirection that
- Cofax will use. If this Redirection class does not suit
- your needs simply implenet a new Redirection class
- and set here.
-*/
- "redirectionClass": "org.cofax.SqlRedirection",
-/*
- Defines the data store name. Keep this at the default
-*/
- "dataStoreName": "cofax",
-/*
- Defines the JDBC driver that Cofax's database pool will use
-*/
- "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
-/*
- Defines the JDBC connection URL to connect to the database
-*/
- "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
-/*
- Defines the user name to connect to the database
-*/
- "dataStoreUser": "sa",
-/*
- Defines the password to connect to the database
-*/
- "dataStorePassword": "dataStoreTestQuery",
-/*
- A query that will run to test the validity of the
- connection in the pool.
-*/
- "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
-/*
- A log file to print out database information
-*/
- "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
-/*
- The number of connection to initialize on startup
-*/
- "dataStoreInitConns": 10,
-/*
- The maximum number of connection to use in the pool
-*/
- "dataStoreMaxConns": 100,
-/*
- The number of times a connection will be utilized from the
- pool before disconnect
-*/
- "dataStoreConnUsageLimit": 100,
-/*
- The level of information to print to the log
-*/
- "dataStoreLogLevel": "debug",
-/*
- The maximum URL length allowable by the CDS Servlet
- Helps to prevent hacking
-*/
- "maxUrlLength": 500}},
-/*
- Defines the Email Servlet
-*/
- {
- "servlet-name": "cofaxEmail",
- "servlet-class": "org.cofax.cds.EmailServlet",
- "init-param": {
-/*
- The mail host to be used by the mail servlet
-*/
- "mailHost": "mail1",
-/*
- An override
-*/
- "mailHostOverride": "mail2"}},
-/*
- Defines the Admin Servlet - used to refresh cache on
- demand and see statistics
-*/
- {
- "servlet-name": "cofaxAdmin",
- "servlet-class": "org.cofax.cds.AdminServlet"},
-/*
- Defines the File Servlet - used to display files like Apache
-*/
- {
- "servlet-name": "fileServlet",
- "servlet-class": "org.cofax.cds.FileServlet"},
- {
- "servlet-name": "cofaxTools",
- "servlet-class": "org.cofax.cms.CofaxToolsServlet",
- "init-param": {
-/*
- Path to the template folder relative to the tools tomcat installation.
-*/
- "templatePath": "toolstemplates/",
-/*
- Logging boolean 1 = on, 0 = off
-*/
- "log": 1,
-/*
- Location of log. If empty, log will be written System.out
-*/
- "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
-/*
- Max size of log in BITS. If size is empty, no limit to log.
- If size is defined, log will be overwritten upon reaching defined size.
-*/
- "logMaxSize": "",
-/*
- DataStore logging boolean 1 = on, 0 = off
-*/
- "dataLog": 1,
-/*
- DataStore location of log. If empty, log will be written System.out
-*/
- "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
-/*
- Max size of log in BITS. If size is empty, no limit to log.
- If size is defined, log will be overwritten upon reaching defined size.
-*/
- "dataLogMaxSize": "",
-/*
- Http string relative to server root to call for page cache
- removal to Cofax Servlet.
-*/
- "removePageCache": "/content/admin/remove?cache=pages&id=",
-/*
- Http string relative to server root to call for template
- cache removal to Cofax Servlet.
-*/
- "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
-/*
- Location of folder from root of drive that will be used for
- ftp transfer from beta server or user hard drive to live servers.
- Note that Edit Article will not function without this variable
- set correctly. MultiPart request relies upon access to this folder.
-*/
- "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
-/*
- Defines whether the Server should look in another path for
- config files or variables.
-*/
- "lookInContext": 1,
-/*
- Number of the ID of the top level administration group in tblPermGroups.
-*/
- "adminGroupID": 4,
-/*
- Is the tools app running on the 'beta server'.
-*/
- "betaServer": true}}],
- "servlet-mapping": {
-/*
- URL mapping for the CDS Servlet
-*/
- "cofaxCDS": "/",
-/*
- URL mapping for the Email Servlet
-*/
- "cofaxEmail": "/cofaxutil/aemail/*",
-/*
- URL mapping for the Admin servlet
-*/
- "cofaxAdmin": "/admin/*",
-/*
- URL mapping for the Files servlet
-*/
- "fileServlet": "/static/*",
- "cofaxTools": "/tools/*"},
-/*
- New! The cofax taglib descriptor file
-*/
- "taglib": {
- "taglib-uri": "cofax.tld",
- "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
-
-"""
-
-test5 = """
-{"menu": {
- "header": "SVG Viewer",
- "items": [
- {"id": "Open"},
- {"id": "OpenNew", "label": "Open New"},
- null,
- {"id": "ZoomIn", "label": "Zoom In"},
- {"id": "ZoomOut", "label": "Zoom Out"},
- {"id": "OriginalView", "label": "Original View"},
- null,
- {"id": "Quality"},
- {"id": "Pause"},
- {"id": "Mute"},
- null,
- {"id": "Find", "label": "Find..."},
- {"id": "FindAgain", "label": "Find Again"},
- {"id": "Copy"},
- {"id": "CopyAgain", "label": "Copy Again"},
- {"id": "CopySVG", "label": "Copy SVG"},
- {"id": "ViewSVG", "label": "View SVG"},
- {"id": "ViewSource", "label": "View Source"},
- {"id": "SaveAs", "label": "Save As"},
- null,
- {"id": "Help"},
- {"id": "About", "label": "About Adobe CVG Viewer..."}
- ]
-}}
-"""
-
diff --git a/trunk/src/test/karthik.ini b/trunk/src/test/karthik.ini
deleted file mode 100644
index 0a7f594..0000000
--- a/trunk/src/test/karthik.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-[users]
-source_dir = '/home/karthik/Projects/python'
-data_dir = '/home/karthik/Projects/data'
-result_dir = '/home/karthik/Projects/Results'
-param_file = $result_dir/param_file
-res_file = $result_dir/result_file
-comment = 'this is a comment'
-; a line starting with ';' is a comment
-K = 8
-simulate_K = 0
-N = 4000
-mod_scheme = 'QPSK'
-
-Na = K+2 \ No newline at end of file
diff --git a/trunk/src/test/parsefiletest_input_file.txt b/trunk/src/test/parsefiletest_input_file.txt
deleted file mode 100644
index 022837a..0000000
--- a/trunk/src/test/parsefiletest_input_file.txt
+++ /dev/null
@@ -1 +0,0 @@
-123 456 789 \ No newline at end of file
diff --git a/trunk/src/unitTests.py b/trunk/src/unitTests.py
deleted file mode 100644
index a4c651f..0000000
--- a/trunk/src/unitTests.py
+++ /dev/null
@@ -1,3169 +0,0 @@
-# -*- coding: UTF-8 -*-
-from unittest import TestCase, TestSuite, TextTestRunner
-import unittest
-import datetime
-
-from pyparsing import ParseException
-#~ import HTMLTestRunner
-
-import sys
-import pdb
-
-PY_3 = sys.version.startswith('3')
-if PY_3:
- import builtins
- print_ = getattr(builtins, "print")
-
- from io import StringIO
-else:
- def _print(*args, **kwargs):
- if 'end' in kwargs:
- sys.stdout.write(' '.join(map(str,args)) + kwargs['end'])
- else:
- sys.stdout.write(' '.join(map(str,args)) + '\n')
- print_ = _print
- from cStringIO import StringIO
-
-
-# see which Python implementation we are running
-CPYTHON_ENV = (sys.platform == "win32")
-IRON_PYTHON_ENV = (sys.platform == "cli")
-JYTHON_ENV = sys.platform.startswith("java")
-
-TEST_USING_PACKRAT = True
-#~ TEST_USING_PACKRAT = False
-
-VERBOSE = False
-#~ VERBOSE = True
-
-# simple utility for flattening nested lists
-def flatten(L):
- if type(L) is not list: return [L]
- if L == []: return L
- return flatten(L[0]) + flatten(L[1:])
-
-"""
-class ParseTest(TestCase):
- def setUp(self):
- pass
-
- def runTest(self):
- assert 1==1, "we've got bigger problems..."
-
- def tearDown(self):
- pass
-"""
-
-class ParseTestCase(TestCase):
- def setUp(self):
- print_(">>>> Starting test",str(self))
-
- def runTest(self):
- pass
-
- def tearDown(self):
- print_("<<<< End of test",str(self))
- print_()
-
- def __str__(self):
- return self.__class__.__name__
-
-class PyparsingTestInit(ParseTestCase):
- def setUp(self):
- from pyparsing import __version__ as pyparsingVersion
- print_("Beginning test of pyparsing, version", pyparsingVersion)
- print_("Python version", sys.version)
- def tearDown(self):
- pass
-
-if 0:
- class ParseASMLTest(ParseTestCase):
- def runTest(self):
- import parseASML
- files = [ ("A52759.txt", 2150, True, True, 0.38, 25, "21:47:17", "22:07:32", 235),
- ("24141506_P5107RM59_399A1457N1_PHS04", 373,True, True, 0.5, 1, "11:35:25", "11:37:05", 183),
- ("24141506_P5107RM59_399A1457N1_PHS04B", 373, True, True, 0.5, 1, "01:02:54", "01:04:49", 186),
- ("24157800_P5107RM74_399A1828M1_PHS04", 1141, True, False, 0.5, 13, "00:00:54", "23:59:48", 154) ]
- for testFile,numToks,trkInpUsed,trkOutpUsed,maxDelta,numWafers,minProcBeg,maxProcEnd,maxLevStatsIV in files:
- print_("Parsing",testFile,"...", end=' ')
- #~ text = "\n".join( [ line for line in file(testFile) ] )
- #~ results = parseASML.BNF().parseString( text )
- results = parseASML.BNF().parseFile( testFile )
- #~ pprint.pprint( results.asList() )
- #~ pprint.pprint( results.batchData.asList() )
- #~ print results.batchData.keys()
-
- allToks = flatten( results.asList() )
- assert len(allToks) == numToks, \
- "wrong number of tokens parsed (%s), got %d, expected %d" % (testFile, len(allToks),numToks)
- assert results.batchData.trackInputUsed == trkInpUsed, "error evaluating results.batchData.trackInputUsed"
- assert results.batchData.trackOutputUsed == trkOutpUsed, "error evaluating results.batchData.trackOutputUsed"
- assert results.batchData.maxDelta == maxDelta,"error evaluating results.batchData.maxDelta"
- assert len(results.waferData) == numWafers, "did not read correct number of wafers"
- assert min([wd.procBegin for wd in results.waferData]) == minProcBeg, "error reading waferData.procBegin"
- assert max([results.waferData[k].procEnd for k in range(len(results.waferData))]) == maxProcEnd, "error reading waferData.procEnd"
- assert sum(results.levelStatsIV['MAX']) == maxLevStatsIV, "error reading levelStatsIV"
- assert sum(results.levelStatsIV.MAX) == maxLevStatsIV, "error reading levelStatsIV"
- print_("OK")
- print_(testFile,len(allToks))
- #~ print "results.batchData.trackInputUsed =",results.batchData.trackInputUsed
- #~ print "results.batchData.trackOutputUsed =",results.batchData.trackOutputUsed
- #~ print "results.batchData.maxDelta =",results.batchData.maxDelta
- #~ print len(results.waferData)," wafers"
- #~ print min([wd.procBegin for wd in results.waferData])
- #~ print max([results.waferData[k].procEnd for k in range(len(results.waferData))])
- #~ print sum(results.levelStatsIV['MAX.'])
-
-
-class ParseFourFnTest(ParseTestCase):
- def runTest(self):
- import examples.fourFn as fourFn
- def test(s,ans):
- fourFn.exprStack = []
- results = fourFn.BNF().parseString( s )
- resultValue = fourFn.evaluateStack( fourFn.exprStack )
- assert resultValue == ans, "failed to evaluate %s, got %f" % ( s, resultValue )
- print_(s, "->", resultValue)
-
- from math import pi,exp
- e = exp(1)
-
- test( "9", 9 )
- test( "9 + 3 + 6", 18 )
- test( "9 + 3 / 11", 9.0+3.0/11.0)
- test( "(9 + 3)", 12 )
- test( "(9+3) / 11", (9.0+3.0)/11.0 )
- test( "9 - (12 - 6)", 3)
- test( "2*3.14159", 6.28318)
- test( "3.1415926535*3.1415926535 / 10", 3.1415926535*3.1415926535/10.0 )
- test( "PI * PI / 10", pi*pi/10.0 )
- test( "PI*PI/10", pi*pi/10.0 )
- test( "6.02E23 * 8.048", 6.02E23 * 8.048 )
- test( "e / 3", e/3.0 )
- test( "sin(PI/2)", 1.0 )
- test( "trunc(E)", 2.0 )
- test( "E^PI", e**pi )
- test( "2^3^2", 2**3**2)
- test( "2^3+2", 2**3+2)
- test( "2^9", 2**9 )
- test( "sgn(-2)", -1 )
- test( "sgn(0)", 0 )
- test( "sgn(0.1)", 1 )
-
-class ParseSQLTest(ParseTestCase):
- def runTest(self):
- import examples.simpleSQL as simpleSQL
-
- def test(s, numToks, errloc=-1 ):
- try:
- sqlToks = flatten( simpleSQL.simpleSQL.parseString(s).asList() )
- print_(s,sqlToks,len(sqlToks))
- assert len(sqlToks) == numToks
- except ParseException as e:
- if errloc >= 0:
- assert e.loc == errloc
-
-
- test( "SELECT * from XYZZY, ABC", 6 )
- test( "select * from SYS.XYZZY", 5 )
- test( "Select A from Sys.dual", 5 )
- test( "Select A,B,C from Sys.dual", 7 )
- test( "Select A, B, C from Sys.dual", 7 )
- test( "Select A, B, C from Sys.dual, Table2 ", 8 )
- test( "Xelect A, B, C from Sys.dual", 0, 0 )
- test( "Select A, B, C frox Sys.dual", 0, 15 )
- test( "Select", 0, 6 )
- test( "Select &&& frox Sys.dual", 0, 7 )
- test( "Select A from Sys.dual where a in ('RED','GREEN','BLUE')", 12 )
- test( "Select A from Sys.dual where a in ('RED','GREEN','BLUE') and b in (10,20,30)", 20 )
- test( "Select A,b from table1,table2 where table1.id eq table2.id -- test out comparison operators", 10 )
-
-class ParseConfigFileTest(ParseTestCase):
- def runTest(self):
- from examples import configParse
-
- def test(fnam,numToks,resCheckList):
- print_("Parsing",fnam,"...", end=' ')
- iniFileLines = "\n".join(open(fnam).read().splitlines())
- iniData = configParse.inifile_BNF().parseString( iniFileLines )
- print_(len(flatten(iniData.asList())))
- #~ pprint.pprint( iniData.asList() )
- #~ pprint.pprint( repr(iniData) )
- #~ print len(iniData), len(flatten(iniData.asList()))
- print_(list(iniData.keys()))
- #~ print iniData.users.keys()
- #~ print
- assert len(flatten(iniData.asList())) == numToks, "file %s not parsed correctly" % fnam
- for chk in resCheckList:
- print_(chk[0], eval("iniData."+chk[0]), chk[1])
- assert eval("iniData."+chk[0]) == chk[1]
- print_("OK")
-
- test("test/karthik.ini", 23,
- [ ("users.K","8"),
- ("users.mod_scheme","'QPSK'"),
- ("users.Na", "K+2") ]
- )
- test("examples/Setup.ini", 125,
- [ ("Startup.audioinf", "M3i"),
- ("Languages.key1", "0x0003"),
- ("test.foo","bar") ] )
-
-class ParseJSONDataTest(ParseTestCase):
- def runTest(self):
- from examples.jsonParser import jsonObject
- from test.jsonParserTests import test1,test2,test3,test4,test5
- from test.jsonParserTests import test1,test2,test3,test4,test5
-
- expected = [
- [],
- [],
- [],
- [],
- [],
- ]
-
- import pprint
- for t,exp in zip((test1,test2,test3,test4,test5),expected):
- result = jsonObject.parseString(t)
-## print result.dump()
- result.pprint()
- print_()
-## if result.asList() != exp:
-## print "Expected %s, parsed results as %s" % (exp, result.asList())
-
-class ParseCommaSeparatedValuesTest(ParseTestCase):
- def runTest(self):
- from pyparsing import commaSeparatedList
- import string
-
- 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 ",
- "",
- ]
- testVals = [
- [ (3,'100.2'), (4,''), (5, '3') ],
- [ (2, 'j k'), (3, 'm') ],
- [ (0, "'Hello, World'"), (2, 'g'), (3, '') ],
- [ (0,'John Doe'), (1, '123 Main St.'), (2, 'Cleveland'), (3, 'Ohio') ],
- [ (0,'Jane Doe'), (1, '456 St. James St.'), (2, 'Los Angeles'), (3, 'California') ]
- ]
- for line,tests in zip(testData, testVals):
- print_("Parsing: \""+line+"\" ->", end=' ')
- results = commaSeparatedList.parseString(line)
- print_(results.asList())
- for t in tests:
- if not(len(results)>t[0] and results[t[0]] == t[1]):
- print_("$$$", results.dump())
- print_("$$$", results[0])
- assert len(results)>t[0] and results[t[0]] == t[1],"failed on %s, item %d s/b '%s', got '%s'" % ( line, t[0], t[1], str(results.asList()) )
-
-class ParseEBNFTest(ParseTestCase):
- def runTest(self):
- from examples import ebnf
- from pyparsing import Word, quotedString, alphas, nums,ParserElement
-
- print_('Constructing EBNF parser with pyparsing...')
-
- 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['terminal_string'] = quotedString
- 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']
- #~ print ",\n ".join( str(parsers.keys()).split(", ") )
- print_("-","\n- ".join( list(parsers.keys()) ))
- assert len(list(parsers.keys())) == 13, "failed to construct syntax grammar"
-
- print_('Parsing EBNF grammar with generated EBNF parser...')
- parsed_chars = ebnf_parser.parseString(grammar)
- parsed_char_len = len(parsed_chars)
-
- print_("],\n".join(str( parsed_chars.asList() ).split("],")))
- assert len(flatten(parsed_chars.asList())) == 98, "failed to tokenize grammar correctly"
-
-
-class ParseIDLTest(ParseTestCase):
- def runTest(self):
- from examples import idlParse
-
- def test( strng, numToks, errloc=0 ):
- print_(strng)
- try:
- bnf = idlParse.CORBA_IDL_BNF()
- tokens = bnf.parseString( strng )
- print_("tokens = ")
- tokens.pprint()
- tokens = flatten( tokens.asList() )
- print_(len(tokens))
- assert len(tokens) == numToks, "error matching IDL string, %s -> %s" % (strng, str(tokens) )
- except ParseException as err:
- print_(err.line)
- print_(" "*(err.column-1) + "^")
- print_(err)
- assert numToks == 0, "unexpected ParseException while parsing %s, %s" % (strng, str(err) )
- assert err.loc == errloc, "expected ParseException at %d, found exception at %d" % (errloc, err.loc)
-
- test(
- """
- /*
- * a block comment *
- */
- typedef string[10] tenStrings;
- typedef sequence<string> stringSeq;
- typedef sequence< sequence<string> > stringSeqSeq;
-
- interface QoSAdmin {
- stringSeq method1( in string arg1, inout long arg2 );
- stringSeqSeq method2( in string arg1, inout long arg2, inout long arg3);
- string method3();
- };
- """, 59
- )
- test(
- """
- /*
- * a block comment *
- */
- typedef string[10] tenStrings;
- typedef
- /** ** *** **** *
- * a block comment *
- */
- sequence<string> /*comment inside an And */ stringSeq;
- /* */ /**/ /***/ /****/
- typedef sequence< sequence<string> > stringSeqSeq;
-
- interface QoSAdmin {
- stringSeq method1( in string arg1, inout long arg2 );
- stringSeqSeq method2( in string arg1, inout long arg2, inout long arg3);
- string method3();
- };
- """, 59
- )
- 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<string> dataStrings;
- };
-
- interface TestInterface
- {
- void method1( in string arg1, inout long arg2 );
- };
- """, 60
- )
- test(
- """
- module Test1
- {
- exception TestException
- {
- string msg;
- ];
-
- interface TestInterface
- {
- void method1( in string arg1, inout long arg2 )
- raises ( TestException );
- };
- };
- """, 0, 57
- )
- test(
- """
- module Test1
- {
- exception TestException
- {
- string msg;
- };
-
- };
- """, 13
- )
-
-class ParseVerilogTest(ParseTestCase):
- def runTest(self):
- pass
-
-class RunExamplesTest(ParseTestCase):
- def runTest(self):
- pass
-
-class ScanStringTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, Combine, Suppress, CharsNotIn, nums, StringEnd
- testdata = """
- <table border="0" cellpadding="3" cellspacing="3" frame="" width="90%">
- <tr align="left" valign="top">
- <td><b>Name</b></td>
- <td><b>IP Address</b></td>
- <td><b>Location</b></td>
- </tr>
- <tr align="left" valign="top" bgcolor="#c7efce">
- <td>time-a.nist.gov</td>
- <td>129.6.15.28</td>
- <td>NIST, Gaithersburg, Maryland</td>
- </tr>
- <tr align="left" valign="top">
- <td>time-b.nist.gov</td>
- <td>129.6.15.29</td>
- <td>NIST, Gaithersburg, Maryland</td>
- </tr>
- <tr align="left" valign="top" bgcolor="#c7efce">
- <td>time-a.timefreq.bldrdoc.gov</td>
- <td>132.163.4.101</td>
- <td>NIST, Boulder, Colorado</td>
- </tr>
- <tr align="left" valign="top">
- <td>time-b.timefreq.bldrdoc.gov</td>
- <td>132.163.4.102</td>
- <td>NIST, Boulder, Colorado</td>
- </tr>
- <tr align="left" valign="top" bgcolor="#c7efce">
- <td>time-c.timefreq.bldrdoc.gov</td>
- <td>132.163.4.103</td>
- <td>NIST, Boulder, Colorado</td>
- </tr>
- </table>
- """
- integer = Word(nums)
- ipAddress = Combine( integer + "." + integer + "." + integer + "." + integer )
- tdStart = Suppress("<td>")
- tdEnd = Suppress("</td>")
- timeServerPattern = tdStart + ipAddress.setResultsName("ipAddr") + tdEnd + \
- tdStart + CharsNotIn("<").setResultsName("loc") + tdEnd
- servers = \
- [ srvr.ipAddr for srvr,startloc,endloc in timeServerPattern.scanString( testdata ) ]
-
- print_(servers)
- assert servers == ['129.6.15.28', '129.6.15.29', '132.163.4.101', '132.163.4.102', '132.163.4.103'], \
- "failed scanString()"
-
- # test for stringEnd detection in scanString
- foundStringEnds = [ r for r in StringEnd().scanString("xyzzy") ]
- print_(foundStringEnds)
- assert foundStringEnds, "Failed to find StringEnd in scanString"
-
-class QuotedStringsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import sglQuotedString,dblQuotedString,quotedString,QuotedString
- testData = \
- """
- 'a valid single quoted string'
- 'an invalid single quoted string
- because it spans lines'
- "a valid double quoted string"
- "an invalid double quoted string
- because it spans lines"
- """
- print_(testData)
- sglStrings = [ (t[0],b,e) for (t,b,e) in sglQuotedString.scanString(testData) ]
- print_(sglStrings)
- assert len(sglStrings) == 1 and (sglStrings[0][1]==17 and sglStrings[0][2]==47), \
- "single quoted string failure"
- dblStrings = [ (t[0],b,e) for (t,b,e) in dblQuotedString.scanString(testData) ]
- print_(dblStrings)
- assert len(dblStrings) == 1 and (dblStrings[0][1]==154 and dblStrings[0][2]==184), \
- "double quoted string failure"
- allStrings = [ (t[0],b,e) for (t,b,e) in quotedString.scanString(testData) ]
- print_(allStrings)
- assert len(allStrings) == 2 and (allStrings[0][1]==17 and allStrings[0][2]==47) and \
- (allStrings[1][1]==154 and allStrings[1][2]==184), \
- "quoted string failure"
-
- escapedQuoteTest = \
- r"""
- 'This string has an escaped (\') quote character'
- "This string has an escaped (\") quote character"
- """
- sglStrings = [ (t[0],b,e) for (t,b,e) in sglQuotedString.scanString(escapedQuoteTest) ]
- print_(sglStrings)
- assert len(sglStrings) == 1 and (sglStrings[0][1]==17 and sglStrings[0][2]==66), \
- "single quoted string escaped quote failure (%s)" % str(sglStrings[0])
- dblStrings = [ (t[0],b,e) for (t,b,e) in dblQuotedString.scanString(escapedQuoteTest) ]
- print_(dblStrings)
- assert len(dblStrings) == 1 and (dblStrings[0][1]==83 and dblStrings[0][2]==132), \
- "double quoted string escaped quote failure (%s)" % str(dblStrings[0])
- allStrings = [ (t[0],b,e) for (t,b,e) in quotedString.scanString(escapedQuoteTest) ]
- print_(allStrings)
- assert len(allStrings) == 2 and (allStrings[0][1]==17 and allStrings[0][2]==66 and
- allStrings[1][1]==83 and allStrings[1][2]==132), \
- "quoted string escaped quote failure (%s)" % ([str(s[0]) for s in allStrings])
-
- dblQuoteTest = \
- r"""
- 'This string has an doubled ('') quote character'
- "This string has an doubled ("") quote character"
- """
- sglStrings = [ (t[0],b,e) for (t,b,e) in sglQuotedString.scanString(dblQuoteTest) ]
- print_(sglStrings)
- assert len(sglStrings) == 1 and (sglStrings[0][1]==17 and sglStrings[0][2]==66), \
- "single quoted string escaped quote failure (%s)" % str(sglStrings[0])
- dblStrings = [ (t[0],b,e) for (t,b,e) in dblQuotedString.scanString(dblQuoteTest) ]
- print_(dblStrings)
- assert len(dblStrings) == 1 and (dblStrings[0][1]==83 and dblStrings[0][2]==132), \
- "double quoted string escaped quote failure (%s)" % str(dblStrings[0])
- allStrings = [ (t[0],b,e) for (t,b,e) in quotedString.scanString(dblQuoteTest) ]
- print_(allStrings)
- assert len(allStrings) == 2 and (allStrings[0][1]==17 and allStrings[0][2]==66 and
- allStrings[1][1]==83 and allStrings[1][2]==132), \
- "quoted string escaped quote failure (%s)" % ([str(s[0]) for s in allStrings])
-
- print_("testing catastrophic RE backtracking in implementation of dblQuotedString")
- for expr, test_string in [
- (dblQuotedString, '"' + '\\xff' * 500),
- (sglQuotedString, "'" + '\\xff' * 500),
- (quotedString, '"' + '\\xff' * 500),
- (quotedString, "'" + '\\xff' * 500),
- (QuotedString('"'), '"' + '\\xff' * 500),
- (QuotedString("'"), "'" + '\\xff' * 500),
- ]:
- expr.parseString(test_string+test_string[0])
- try:
- expr.parseString(test_string)
- except Exception:
- continue
-
-class CaselessOneOfTest(ParseTestCase):
- def runTest(self):
- from pyparsing import oneOf,ZeroOrMore
-
- caseless1 = oneOf("d a b c aA B A C", caseless=True)
- caseless1str = str( caseless1 )
- print_(caseless1str)
- caseless2 = oneOf("d a b c Aa B A C", caseless=True)
- caseless2str = str( caseless2 )
- print_(caseless2str)
- assert caseless1str.upper() == caseless2str.upper(), "oneOf not handling caseless option properly"
- assert caseless1str != caseless2str, "Caseless option properly sorted"
-
- res = ZeroOrMore(caseless1).parseString("AAaaAaaA")
- print_(res)
- assert len(res) == 4, "caseless1 oneOf failed"
- assert "".join(res) == "aA"*4,"caseless1 CaselessLiteral return failed"
-
- res = ZeroOrMore(caseless2).parseString("AAaaAaaA")
- print_(res)
- assert len(res) == 4, "caseless2 oneOf failed"
- assert "".join(res) == "Aa"*4,"caseless1 CaselessLiteral return failed"
-
-
-class AsXMLTest(ParseTestCase):
- def runTest(self):
-
- import pyparsing
- # test asXML()
-
- aaa = pyparsing.Word("a").setResultsName("A")
- bbb = pyparsing.Group(pyparsing.Word("b")).setResultsName("B")
- ccc = pyparsing.Combine(":" + pyparsing.Word("c")).setResultsName("C")
- g1 = "XXX>&<" + pyparsing.ZeroOrMore( aaa | bbb | ccc )
- teststring = "XXX>&< b b a b b a b :c b a"
- #~ print teststring
- print_("test including all items")
- xml = g1.parseString(teststring).asXML("TEST",namedItemsOnly=False)
- assert xml=="\n".join(["",
- "<TEST>",
- " <ITEM>XXX&gt;&amp;&lt;</ITEM>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <C>:c</C>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- "</TEST>",
- ] ), \
- "failed to generate XML correctly showing all items: \n[" + xml + "]"
- print_("test filtering unnamed items")
- xml = g1.parseString(teststring).asXML("TEST",namedItemsOnly=True)
- assert xml=="\n".join(["",
- "<TEST>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <C>:c</C>",
- " <B>",
- " <ITEM>b</ITEM>",
- " </B>",
- " <A>a</A>",
- "</TEST>",
- ] ), \
- "failed to generate XML correctly, filtering unnamed items: " + xml
-
-class AsXMLTest2(ParseTestCase):
- def runTest(self):
- from pyparsing import Suppress,Optional,CharsNotIn,Combine,ZeroOrMore,Word,\
- Group,Literal,alphas,alphanums,delimitedList,OneOrMore
-
- EndOfLine = Word("\n").setParseAction(lambda s,l,t: [' '])
- whiteSpace=Word('\t ')
- Mexpr = Suppress(Optional(whiteSpace)) + CharsNotIn('\\"\t \n') + Optional(" ") + \
- Suppress(Optional(whiteSpace))
- reducedString = Combine(Mexpr + ZeroOrMore(EndOfLine + Mexpr))
- _bslash = "\\"
- _escapables = "tnrfbacdeghijklmopqsuvwxyz" + _bslash + "'" + '"'
- _octDigits = "01234567"
- _escapedChar = ( Word( _bslash, _escapables, exact=2 ) |
- Word( _bslash, _octDigits, min=2, max=4 ) )
- _sglQuote = Literal("'")
- _dblQuote = Literal('"')
- QuotedReducedString = Combine( Suppress(_dblQuote) + ZeroOrMore( reducedString |
- _escapedChar ) + \
- Suppress(_dblQuote )).streamline()
-
- Manifest_string = QuotedReducedString.setResultsName('manifest_string')
-
- Identifier = Word( alphas, alphanums+ '_$' ).setResultsName("identifier")
- Index_string = CharsNotIn('\\";\n')
- Index_string.setName('index_string')
- Index_term_list = (
- Group(delimitedList(Manifest_string, delim=',')) | \
- Index_string
- ).setResultsName('value')
-
- IndexKey = Identifier.setResultsName('key')
- IndexKey.setName('key')
- Index_clause = Group(IndexKey + Suppress(':') + Optional(Index_term_list))
- Index_clause.setName('index_clause')
- Index_list = Index_clause.setResultsName('index')
- Index_list.setName('index_list')
- Index_block = Group('indexing' + Group(OneOrMore(Index_list + Suppress(';')))).setResultsName('indexes')
-
-
-class CommentParserTest(ParseTestCase):
- def runTest(self):
- import pyparsing
- print_("verify processing of C and HTML comments")
- testdata = """
- /* */
- /** **/
- /**/
- /***/
- /****/
- /* /*/
- /** /*/
- /*** /*/
- /*
- ablsjdflj
- */
- """
- foundLines = [ pyparsing.lineno(s,testdata)
- for t,s,e in pyparsing.cStyleComment.scanString(testdata) ]
- assert foundLines == list(range(11))[2:],"only found C comments on lines "+str(foundLines)
- testdata = """
- <!-- -->
- <!--- --->
- <!---->
- <!----->
- <!------>
- <!-- /-->
- <!--- /-->
- <!---- /-->
- <!---- /- ->
- <!---- / -- >
- <!--
- ablsjdflj
- -->
- """
- foundLines = [ pyparsing.lineno(s,testdata)
- for t,s,e in pyparsing.htmlComment.scanString(testdata) ]
- assert foundLines == list(range(11))[2:],"only found HTML comments on lines "+str(foundLines)
-
- # test C++ single line comments that have line terminated with '\' (should continue comment to following line)
- testSource = r"""
- // comment1
- // comment2 \
- still comment 2
- // comment 3
- """
- assert len(pyparsing.cppStyleComment.searchString(testSource)[1][0]) == 41, r"failed to match single-line comment with '\' at EOL"
-
-class ParseExpressionResultsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word,alphas,OneOrMore,Optional,Group
-
- a = Word("a",alphas).setName("A")
- b = Word("b",alphas).setName("B")
- c = Word("c",alphas).setName("C")
- ab = (a + b).setName("AB")
- abc = (ab + c).setName("ABC")
- word = Word(alphas).setName("word")
-
- #~ words = OneOrMore(word).setName("words")
- words = Group(OneOrMore(~a + word)).setName("words")
-
- #~ phrase = words.setResultsName("Head") + \
- #~ ( abc ^ ab ^ a ).setResultsName("ABC") + \
- #~ words.setResultsName("Tail")
- #~ phrase = words.setResultsName("Head") + \
- #~ ( abc | ab | a ).setResultsName("ABC") + \
- #~ words.setResultsName("Tail")
- phrase = words.setResultsName("Head") + \
- Group( a + Optional(b + Optional(c)) ).setResultsName("ABC") + \
- words.setResultsName("Tail")
-
- results = phrase.parseString("xavier yeti alpha beta charlie will beaver")
- print_(results,results.Head, results.ABC,results.Tail)
- for key,ln in [("Head",2), ("ABC",3), ("Tail",2)]:
- #~ assert len(results[key]) == ln,"expected %d elements in %s, found %s" % (ln, key, str(results[key].asList()))
- assert len(results[key]) == ln,"expected %d elements in %s, found %s" % (ln, key, str(results[key]))
-
-
-class ParseKeywordTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Literal,Keyword
-
- kw = Keyword("if")
- lit = Literal("if")
-
- def test(s,litShouldPass,kwShouldPass):
- print_("Test",s)
- print_("Match Literal", end=' ')
- try:
- print_(lit.parseString(s))
- except:
- print_("failed")
- if litShouldPass: assert False, "Literal failed to match %s, should have" % s
- else:
- if not litShouldPass: assert False, "Literal matched %s, should not have" % s
-
- print_("Match Keyword", end=' ')
- try:
- print_(kw.parseString(s))
- except:
- print_("failed")
- if kwShouldPass: assert False, "Keyword failed to match %s, should have" % s
- else:
- if not kwShouldPass: assert False, "Keyword matched %s, should not have" % s
-
- test("ifOnlyIfOnly", True, False)
- test("if(OnlyIfOnly)", True, True)
- test("if (OnlyIf Only)", True, True)
-
- kw = Keyword("if",caseless=True)
-
- test("IFOnlyIfOnly", False, False)
- test("If(OnlyIfOnly)", False, True)
- test("iF (OnlyIf Only)", False, True)
-
-
-
-class ParseExpressionResultsAccumulateTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word,delimitedList,Combine,alphas,nums
-
- num=Word(nums).setName("num").setResultsName("base10", listAllMatches=True)
- hexnum=Combine("0x"+ Word(nums)).setName("hexnum").setResultsName("hex", listAllMatches=True)
- name = Word(alphas).setName("word").setResultsName("word", listAllMatches=True)
- list_of_num=delimitedList( hexnum | num | name, "," )
-
- tokens = list_of_num.parseString('1, 0x2, 3, 0x4, aaa')
- for k,llen,lst in ( ("base10",2,['1','3']),
- ("hex",2,['0x2','0x4']),
- ("word",1,['aaa']) ):
- print_(k,tokens[k])
- assert len(tokens[k]) == llen, "Wrong length for key %s, %s" % (k,str(tokens[k].asList()))
- assert lst == tokens[k].asList(), "Incorrect list returned for key %s, %s" % (k,str(tokens[k].asList()))
- assert tokens.base10.asList() == ['1','3'], "Incorrect list for attribute base10, %s" % str(tokens.base10.asList())
- assert tokens.hex.asList() == ['0x2','0x4'], "Incorrect list for attribute hex, %s" % str(tokens.hex.asList())
- assert tokens.word.asList() == ['aaa'], "Incorrect list for attribute word, %s" % str(tokens.word.asList())
-
- from pyparsing import Literal, Word, nums, Group, Dict, alphas, \
- quotedString, oneOf, delimitedList, removeQuotes, alphanums
-
- lbrack = Literal("(").suppress()
- rbrack = Literal(")").suppress()
- integer = Word( nums ).setName("int")
- variable = Word( alphas, max=1 ).setName("variable")
- relation_body_item = variable | integer | quotedString.copy().setParseAction(removeQuotes)
- relation_name = Word( alphas+"_", alphanums+"_" )
- relation_body = lbrack + Group(delimitedList(relation_body_item)) + rbrack
- Goal = Dict(Group( relation_name + relation_body ))
- Comparison_Predicate = Group(variable + oneOf("< >") + integer).setResultsName("pred",listAllMatches=True)
- Query = Goal.setResultsName("head") + ":-" + delimitedList(Goal | Comparison_Predicate)
-
- test="""Q(x,y,z):-Bloo(x,"Mitsis",y),Foo(y,z,1243),y>28,x<12,x>3"""
-
- queryRes = Query.parseString(test)
- print_("pred",queryRes.pred)
- assert queryRes.pred.asList() == [['y', '>', '28'], ['x', '<', '12'], ['x', '>', '3']], "Incorrect list for attribute pred, %s" % str(queryRes.pred.asList())
- print_(queryRes.dump())
-
-class ReStringRangeTest(ParseTestCase):
- def runTest(self):
- import pyparsing
- testCases = (
- (r"[A-Z]"),
- (r"[A-A]"),
- (r"[A-Za-z]"),
- (r"[A-z]"),
- (r"[\ -\~]"),
- (r"[\0x20-0]"),
- (r"[\0x21-\0x7E]"),
- (r"[\0xa1-\0xfe]"),
- (r"[\040-0]"),
- (r"[A-Za-z0-9]"),
- (r"[A-Za-z0-9_]"),
- (r"[A-Za-z0-9_$]"),
- (r"[A-Za-z0-9_$\-]"),
- (r"[^0-9\\]"),
- (r"[a-zA-Z]"),
- (r"[/\^~]"),
- (r"[=\+\-!]"),
- (r"[A-]"),
- (r"[-A]"),
- (r"[\x21]"),
- #(r"[а-ÑÐ-ЯёÐA-Z$_\041α-ω]".decode('utf-8')),
- (u'[\u0430-\u044f\u0410-\u042f\u0451\u0401ABCDEFGHIJKLMNOPQRSTUVWXYZ$_\041\u03b1-\u03c9]'),
- )
- expectedResults = (
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "A",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz",
- " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~",
- " !\"#$%&'()*+,-./0",
- "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~",
- #~ "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ",
- u'\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe',
- " !\"#$%&'()*+,-./0",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$-",
- "0123456789\\",
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "/^~",
- "=+-!",
- "A-",
- "-A",
- "!",
- u"абвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯёÐABCDEFGHIJKLMNOPQRSTUVWXYZ$_!αβγδεζηθικλμνξοπÏςστυφχψω",
- )
- for test in zip( testCases, expectedResults ):
- t,exp = test
- res = pyparsing.srange(t)
- #print_(t,"->",res)
- assert res == exp, "srange error, srange(%r)->'%r', expected '%r'" % (t, res, exp)
-
-class SkipToParserTests(ParseTestCase):
- def runTest(self):
-
- from pyparsing import Literal, SkipTo, NotAny, cStyleComment, ParseBaseException
-
- thingToFind = Literal('working')
- testExpr = SkipTo(Literal(';'), include=True, ignore=cStyleComment) + thingToFind
-
- def tryToParse (someText, fail_expected=False):
- try:
- print_(testExpr.parseString(someText))
- assert not fail_expected, "expected failure but no exception raised"
- except Exception as e:
- print_("Exception %s while parsing string %s" % (e,repr(someText)))
- assert fail_expected and isinstance(e,ParseBaseException), "Exception %s while parsing string %s" % (e,repr(someText))
-
- # This first test works, as the SkipTo expression is immediately following the ignore expression (cStyleComment)
- tryToParse('some text /* comment with ; in */; working')
- # This second test previously failed, as there is text following the ignore expression, and before the SkipTo expression.
- tryToParse('some text /* comment with ; in */some other stuff; working')
-
- # tests for optional failOn argument
- testExpr = SkipTo(Literal(';'), include=True, ignore=cStyleComment, failOn='other') + thingToFind
- tryToParse('some text /* comment with ; in */; working')
- tryToParse('some text /* comment with ; in */some other stuff; working', fail_expected=True)
-
-class CustomQuotesTest(ParseTestCase):
- def runTest(self):
- from pyparsing import QuotedString
-
- testString = r"""
- sdlfjs :sdf\:jls::djf: sl:kfsjf
- sdlfjs -sdf\:jls::--djf: sl-kfsjf
- sdlfjs -sdf\:::jls::--djf: sl:::-kfsjf
- sdlfjs ^sdf\:jls^^--djf^ sl-kfsjf
- sdlfjs ^^^==sdf\:j=lz::--djf: sl=^^=kfsjf
- sdlfjs ==sdf\:j=ls::--djf: sl==kfsjf^^^
- """
- colonQuotes = QuotedString(':','\\','::')
- dashQuotes = QuotedString('-','\\', '--')
- hatQuotes = QuotedString('^','\\')
- hatQuotes1 = QuotedString('^','\\','^^')
- dblEqQuotes = QuotedString('==','\\')
-
- def test(quoteExpr, expected):
- print_(quoteExpr.pattern)
- print_(quoteExpr.searchString(testString))
- print_(quoteExpr.searchString(testString)[0][0])
- print_(expected)
- assert quoteExpr.searchString(testString)[0][0] == expected, \
- "failed to match %s, expected '%s', got '%s'" % \
- (quoteExpr,expected,quoteExpr.searchString(testString)[0])
- print_()
-
- test(colonQuotes, r"sdf:jls:djf")
- test(dashQuotes, r"sdf:jls::-djf: sl")
- test(hatQuotes, r"sdf:jls")
- test(hatQuotes1, r"sdf:jls^--djf")
- test(dblEqQuotes, r"sdf:j=ls::--djf: sl")
- test( QuotedString(':::'), 'jls::--djf: sl')
- test( QuotedString('==',endQuoteChar='--'), r'sdf\:j=lz::')
- test( QuotedString('^^^',multiline=True), r"""==sdf\:j=lz::--djf: sl=^^=kfsjf
- sdlfjs ==sdf\:j=ls::--djf: sl==kfsjf""")
- try:
- bad1 = QuotedString('','\\')
- except SyntaxError as se:
- pass
- else:
- assert False,"failed to raise SyntaxError with empty quote string"
-
-class RepeaterTest(ParseTestCase):
- def runTest(self):
- from pyparsing import matchPreviousLiteral,matchPreviousExpr, Forward, Literal, Word, alphas, nums, ParserElement
-
- if ParserElement._packratEnabled:
- print_("skipping this test, not compatible with packratting")
- return
-
- first = Word("abcdef").setName("word1")
- bridge = Word(nums).setName("number")
- second = matchPreviousLiteral(first).setName("repeat(word1Literal)")
-
- seq = first + bridge + second
-
- tests = [
- ( "abc12abc", True ),
- ( "abc12aabc", False ),
- ( "abc12cba", True ),
- ( "abc12bca", True ),
- ]
-
- for tst,result in tests:
- found = False
- for tokens,start,end in seq.scanString(tst):
- f,b,s = tokens
- print_(f,b,s)
- found = True
- if not found:
- print_("No literal match in", tst)
- assert found == result, "Failed repeater for test: %s, matching %s" % (tst, str(seq))
- print_()
-
- # retest using matchPreviousExpr instead of matchPreviousLiteral
- second = matchPreviousExpr(first).setName("repeat(word1expr)")
- seq = first + bridge + second
-
- tests = [
- ( "abc12abc", True ),
- ( "abc12cba", False ),
- ( "abc12abcdef", False ),
- ]
-
- for tst,result in tests:
- found = False
- for tokens,start,end in seq.scanString(tst):
- print_(tokens.asList())
- found = True
- if not found:
- print_("No expression match in", tst)
- assert found == result, "Failed repeater for test: %s, matching %s" % (tst, str(seq))
-
- print_()
-
- first = Word("abcdef").setName("word1")
- bridge = Word(nums).setName("number")
- second = matchPreviousExpr(first).setName("repeat(word1)")
- seq = first + bridge + second
- csFirst = seq.setName("word-num-word")
- csSecond = matchPreviousExpr(csFirst)
- compoundSeq = csFirst + ":" + csSecond
- compoundSeq.streamline()
- print_(compoundSeq)
-
- tests = [
- ( "abc12abc:abc12abc", True ),
- ( "abc12cba:abc12abc", False ),
- ( "abc12abc:abc12abcdef", False ),
- ]
-
- #~ for tst,result in tests:
- #~ print tst,
- #~ try:
- #~ compoundSeq.parseString(tst)
- #~ print "MATCH"
- #~ assert result, "matched when shouldn't have matched"
- #~ except ParseException:
- #~ print "NO MATCH"
- #~ assert not result, "didnt match but should have"
-
- #~ for tst,result in tests:
- #~ print tst,
- #~ if compoundSeq == tst:
- #~ print "MATCH"
- #~ assert result, "matched when shouldn't have matched"
- #~ else:
- #~ print "NO MATCH"
- #~ assert not result, "didnt match but should have"
-
- for tst,result in tests:
- found = False
- for tokens,start,end in compoundSeq.scanString(tst):
- print_("match:", tokens.asList())
- found = True
- break
- if not found:
- print_("No expression match in", tst)
- assert found == result, "Failed repeater for test: %s, matching %s" % (tst, str(seq))
-
- print_()
- eFirst = Word(nums)
- eSecond = matchPreviousExpr(eFirst)
- eSeq = eFirst + ":" + eSecond
-
- tests = [
- ( "1:1A", True ),
- ( "1:10", False ),
- ]
-
- for tst,result in tests:
- found = False
- for tokens,start,end in eSeq.scanString(tst):
- #~ f,b,s = tokens
- #~ print f,b,s
- print_(tokens.asList())
- found = True
- if not found:
- print_("No match in", tst)
- assert found == result, "Failed repeater for test: %s, matching %s" % (tst, str(seq))
-
-class RecursiveCombineTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Forward,Word,alphas,nums,Optional,Combine
-
- testInput = "myc(114)r(11)dd"
- Stream=Forward()
- Stream << Optional(Word(alphas))+Optional("("+Word(nums)+")"+Stream)
- expected = Stream.parseString(testInput).asList()
- print_(["".join(expected)])
-
- Stream=Forward()
- Stream << Combine(Optional(Word(alphas))+Optional("("+Word(nums)+")"+Stream))
- testVal = Stream.parseString(testInput).asList()
- print_(testVal)
-
- assert "".join(testVal) == "".join(expected), "Failed to process Combine with recursive content"
-
-class InfixNotationGrammarTest1(ParseTestCase):
- def runTest(self):
- from pyparsing import Word,nums,alphas,Literal,oneOf,infixNotation,opAssoc
-
- 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('!')
-
- 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",
- "(9 + -2) * 3^2^2",
- "(9! + -2) * 3^2^2",
- "M*X + B",
- "M*(X + B)",
- "1+2*-3^4*5+-+-6",
- "3!!"]
- expected = """[[9, '+', 2, '+', 3]]
- [[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]]]]]
- [[3, '!', '!']]""".split('\n')
- expected = [eval(x) for x in expected]
- for t,e in zip(test,expected):
- print_(t,"->",e, "got", expr.parseString(t).asList())
- assert expr.parseString(t).asList() == e,"mismatched results for infixNotation: got %s, expected %s" % (expr.parseString(t).asList(),e)
-
-class InfixNotationGrammarTest2(ParseTestCase):
- def runTest(self):
-
- from pyparsing import infixNotation, Word, alphas, oneOf, opAssoc
-
- boolVars = { "True":True, "False":False }
- class BoolOperand(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)) + ")"
-
- class BoolAnd(BoolOperand):
- reprsymbol = '&'
- def __bool__(self):
- for a in self.args:
- if isinstance(a,str):
- v = boolVars[a]
- else:
- v = bool(a)
- if not v:
- return False
- return True
-
- class BoolOr(BoolOperand):
- reprsymbol = '|'
- def __bool__(self):
- for a in self.args:
- if isinstance(a,str):
- v = boolVars[a]
- else:
- v = bool(a)
- if v:
- return True
- return False
-
- class BoolNot(BoolOperand):
- def __init__(self,t):
- self.arg = t[0][1]
- def __str__(self):
- return "~" + str(self.arg)
- def __bool__(self):
- if isinstance(self.arg,str):
- v = boolVars[self.arg]
- else:
- v = bool(self.arg)
- return not v
-
- boolOperand = Word(alphas,max=1) | oneOf("True False")
- boolExpr = infixNotation( boolOperand,
- [
- ("not", 1, opAssoc.RIGHT, BoolNot),
- ("and", 2, opAssoc.LEFT, BoolAnd),
- ("or", 2, opAssoc.LEFT, BoolOr),
- ])
- test = ["p and not q",
- "not not p",
- "not(p and q)",
- "q or not p and r",
- "q or not p or not r",
- "q or not (p and r)",
- "p or q or r",
- "p or q or r and False",
- "(p or q or r) and False",
- ]
-
- boolVars["p"] = True
- boolVars["q"] = False
- boolVars["r"] = True
- print_("p =", boolVars["p"])
- print_("q =", boolVars["q"])
- print_("r =", boolVars["r"])
- print_()
- for t in test:
- res = boolExpr.parseString(t)[0]
- print_(t,'\n', res, '=', bool(res),'\n')
-
-
-class InfixNotationGrammarTest3(ParseTestCase):
- def runTest(self):
-
- from pyparsing import infixNotation, Word, alphas, oneOf, opAssoc, nums, Literal
-
- global count
- count = 0
-
- def evaluate_int(t):
- global count
- value = int(t[0])
- print_("evaluate_int", value)
- count += 1
- return value
-
- integer = Word(nums).setParseAction(evaluate_int)
- variable = Word(alphas,exact=1)
- operand = integer | variable
-
- expop = Literal('^')
- signop = oneOf('+ -')
- multop = oneOf('* /')
- plusop = oneOf('+ -')
- factop = Literal('!')
-
- expr = infixNotation( operand,
- [
- ("!", 1, opAssoc.LEFT),
- ("^", 2, opAssoc.RIGHT),
- (signop, 1, opAssoc.RIGHT),
- (multop, 2, opAssoc.LEFT),
- (plusop, 2, opAssoc.LEFT),
- ])
-
- test = ["9"]
- for t in test:
- count = 0
- print_("%s => %s" % (t, expr.parseString(t)))
- assert count == 1, "count evaluated too many times!"
-
-class InfixNotationGrammarTest4(ParseTestCase):
- def runTest(self):
-
- import pyparsing
-
- word = pyparsing.Word(pyparsing.alphas)
-
- def supLiteral(s):
- """Returns the suppressed literal s"""
- return pyparsing.Literal(s).suppress()
-
- def booleanExpr(atom):
- ops = [
- (supLiteral("!"), 1, pyparsing.opAssoc.RIGHT, lambda s, l, t: ["!", t[0][0]]),
- (pyparsing.oneOf("= !="), 2, pyparsing.opAssoc.LEFT, ),
- (supLiteral("&"), 2, pyparsing.opAssoc.LEFT, lambda s, l, t: ["&", t[0]]),
- (supLiteral("|"), 2, pyparsing.opAssoc.LEFT, lambda s, l, t: ["|", t[0]])]
- return pyparsing.infixNotation(atom, ops)
-
- f = booleanExpr(word) + pyparsing.StringEnd()
-
- tests = [
- ("bar = foo", "[['bar', '=', 'foo']]"),
- ("bar = foo & baz = fee", "['&', [['bar', '=', 'foo'], ['baz', '=', 'fee']]]"),
- ]
- for test,expected in tests:
- print_(test)
- results = f.parseString(test)
- print_(results)
- assert str(results) == expected, "failed to match expected results, got '%s'" % str(results)
- print_()
-
-
-class PickleTest_Greeting():
- def __init__(self, toks):
- self.salutation = toks[0]
- self.greetee = toks[1]
-
- def __repr__(self):
- return "%s: {%s}" % (self.__class__.__name__,
- ', '.join('%r: %r' % (k, getattr(self,k)) for k in sorted(self.__dict__)))
-
-class ParseResultsPickleTest(ParseTestCase):
- def runTest(self):
- from pyparsing import makeHTMLTags, ParseResults
- import pickle
-
- # test 1
- body = makeHTMLTags("BODY")[0]
- result = body.parseString("<BODY BGCOLOR='#00FFBB' FGCOLOR=black>")
- if VERBOSE:
- print_(result.dump())
- print_()
-
- for protocol in range(pickle.HIGHEST_PROTOCOL+1):
- print_("Test pickle dump protocol", protocol)
- try:
- pickleString = pickle.dumps(result, protocol)
- except Exception as e:
- print_("dumps exception:", e)
- newresult = ParseResults()
- else:
- newresult = pickle.loads(pickleString)
- if VERBOSE:
- print_(newresult.dump())
- print_()
-
- assert result.dump() == newresult.dump(), "Error pickling ParseResults object (protocol=%d)" % protocol
-
- # test 2
- import pyparsing as pp
-
- word = pp.Word(pp.alphas+"'.")
- salutation = pp.OneOrMore(word)
- comma = pp.Literal(",")
- greetee = pp.OneOrMore(word)
- endpunc = pp.oneOf("! ?")
- greeting = salutation + pp.Suppress(comma) + greetee + pp.Suppress(endpunc)
- greeting.setParseAction(PickleTest_Greeting)
-
- string = 'Good morning, Miss Crabtree!'
-
- result = greeting.parseString(string)
-
- for protocol in range(pickle.HIGHEST_PROTOCOL+1):
- print_("Test pickle dump protocol", protocol)
- try:
- pickleString = pickle.dumps(result, protocol)
- except Exception as e:
- print_("dumps exception:", e)
- newresult = ParseResults()
- else:
- newresult = pickle.loads(pickleString)
- print_(newresult.dump())
- assert newresult.dump() == result.dump(), "failed to pickle/unpickle ParseResults: expected %r, got %r" % (result, newresult)
-
-
-
-class ParseResultsWithNamedTupleTest(ParseTestCase):
- def runTest(self):
-
- from pyparsing import Literal,replaceWith
-
- expr = Literal("A")
- expr.setParseAction(replaceWith(tuple(["A","Z"])))
- expr = expr.setResultsName("Achar")
-
- res = expr.parseString("A")
- print_(repr(res))
- print_(res.Achar)
- assert res.Achar == ("A","Z"), "Failed accessing named results containing a tuple, got " + res.Achar
-
-
-class ParseHTMLTagsTest(ParseTestCase):
- def runTest(self):
- import pyparsing
- test = """
- <BODY>
- <BODY BGCOLOR="#00FFCC">
- <BODY BGCOLOR="#00FFAA"/>
- <BODY BGCOLOR='#00FFBB' FGCOLOR=black>
- <BODY/>
- </BODY>
- """
- results = [
- ("startBody", False, "", ""),
- ("startBody", False, "#00FFCC", ""),
- ("startBody", True, "#00FFAA", ""),
- ("startBody", False, "#00FFBB", "black"),
- ("startBody", True, "", ""),
- ("endBody", False, "", ""),
- ]
-
- bodyStart, bodyEnd = pyparsing.makeHTMLTags("BODY")
- resIter = iter(results)
- for t,s,e in (bodyStart | bodyEnd).scanString( test ):
- print_(test[s:e], "->", t.asList())
- (expectedType, expectedEmpty, expectedBG, expectedFG) = next(resIter)
-
- tType = t.getName()
- #~ print tType,"==",expectedType,"?"
- assert tType in "startBody endBody".split(), "parsed token of unknown type '%s'" % tType
- assert tType == expectedType, "expected token of type %s, got %s" % (expectedType, tType)
- if tType == "startBody":
- assert bool(t.empty) == expectedEmpty, "expected %s token, got %s" % ( expectedEmpty and "empty" or "not empty",
- t.empty and "empty" or "not empty" )
- assert t.bgcolor == expectedBG, "failed to match BGCOLOR, expected %s, got %s" % ( expectedBG, t.bgcolor )
- assert t.fgcolor == expectedFG, "failed to match FGCOLOR, expected %s, got %s" % ( expectedFG, t.bgcolor )
- elif tType == "endBody":
- #~ print "end tag"
- pass
- else:
- print_("BAD!!!")
-
-class UpcaseDowncaseUnicode(ParseTestCase):
- def runTest(self):
-
- import pyparsing as pp
- import sys
- if PY_3:
- unichr = chr
- else:
- from __builtin__ import unichr
-
- a = '\u00bfC\u00f3mo esta usted?'
- if not JYTHON_ENV:
- ualphas = "".join( unichr(i) for i in range(sys.maxunicode)
- if unichr(i).isalpha() )
- else:
- ualphas = "".join( unichr(i) for i in list(range(0xd800)) + list(range(0xe000,sys.maxunicode))
- if unichr(i).isalpha() )
- uword = pp.Word(ualphas).setParseAction(pp.upcaseTokens)
-
- print_ = lambda *args: None
- print_(uword.searchString(a))
-
- uword = pp.Word(ualphas).setParseAction(pp.downcaseTokens)
-
- print_(uword.searchString(a))
-
- kw = pp.Keyword('mykey', caseless=True).setParseAction(pp.upcaseTokens).setResultsName('rname')
- ret = kw.parseString('mykey')
- print(ret.rname)
- assert ret.rname=='MYKEY', "failed to upcase with named result"
-
- if not IRON_PYTHON_ENV:
- #test html data
- html = "<TR class=maintxt bgColor=#ffffff> \
- <TD vAlign=top>Производитель, модель</TD> \
- <TD vAlign=top><STRONG>BenQ-Siemens CF61</STRONG></TD> \
- "#.decode('utf-8')
-
- # u'Manufacturer, model
- text_manuf = 'Производитель, модель'
- manufacturer = pp.Literal(text_manuf)
-
- td_start, td_end = pp.makeHTMLTags("td")
- manuf_body = td_start.suppress() + manufacturer + pp.SkipTo(td_end)("cells*") + td_end.suppress()
-
- #~ manuf_body.setDebug()
-
- #~ for tokens in manuf_body.scanString(html):
- #~ print_(tokens)
-
-class ParseUsingRegex(ParseTestCase):
- def runTest(self):
-
- import re
- import pyparsing
-
- signedInt = pyparsing.Regex(r'[-+][0-9]+')
- unsignedInt = pyparsing.Regex(r'[0-9]+')
- simpleString = pyparsing.Regex(r'("[^\"]*")|(\'[^\']*\')')
- namedGrouping = pyparsing.Regex(r'("(?P<content>[^\"]*)")')
- compiledRE = pyparsing.Regex(re.compile(r'[A-Z]+'))
-
- def testMatch (expression, instring, shouldPass, expectedString=None):
- if shouldPass:
- try:
- result = expression.parseString(instring)
- print_('%s correctly matched %s' % (repr(expression), repr(instring)))
- if expectedString != result[0]:
- print_('\tbut failed to match the pattern as expected:')
- print_('\tproduced %s instead of %s' % \
- (repr(result[0]), repr(expectedString)))
- return True
- except pyparsing.ParseException:
- print_('%s incorrectly failed to match %s' % \
- (repr(expression), repr(instring)))
- else:
- try:
- result = expression.parseString(instring)
- print_('%s incorrectly matched %s' % (repr(expression), repr(instring)))
- print_('\tproduced %s as a result' % repr(result[0]))
- except pyparsing.ParseException:
- print_('%s correctly failed to match %s' % \
- (repr(expression), repr(instring)))
- return True
- return False
-
- # These should fail
- assert testMatch(signedInt, '1234 foo', False), "Re: (1) passed, expected fail"
- assert testMatch(signedInt, ' +foo', False), "Re: (2) passed, expected fail"
- assert testMatch(unsignedInt, 'abc', False), "Re: (3) passed, expected fail"
- assert testMatch(unsignedInt, '+123 foo', False), "Re: (4) passed, expected fail"
- assert testMatch(simpleString, 'foo', False), "Re: (5) passed, expected fail"
- assert testMatch(simpleString, '"foo bar\'', False), "Re: (6) passed, expected fail"
- assert testMatch(simpleString, '\'foo bar"', False), "Re: (7) passed, expected fail"
-
- # These should pass
- assert testMatch(signedInt, ' +123', True, '+123'), "Re: (8) failed, expected pass"
- assert testMatch(signedInt, '+123', True, '+123'), "Re: (9) failed, expected pass"
- assert testMatch(signedInt, '+123 foo', True, '+123'), "Re: (10) failed, expected pass"
- assert testMatch(signedInt, '-0 foo', True, '-0'), "Re: (11) failed, expected pass"
- assert testMatch(unsignedInt, '123 foo', True, '123'), "Re: (12) failed, expected pass"
- assert testMatch(unsignedInt, '0 foo', True, '0'), "Re: (13) failed, expected pass"
- assert testMatch(simpleString, '"foo"', True, '"foo"'), "Re: (14) failed, expected pass"
- assert testMatch(simpleString, "'foo bar' baz", True, "'foo bar'"), "Re: (15) failed, expected pass"
-
- assert testMatch(compiledRE, 'blah', False), "Re: (16) passed, expected fail"
- assert testMatch(compiledRE, 'BLAH', True, 'BLAH'), "Re: (17) failed, expected pass"
-
- assert testMatch(namedGrouping, '"foo bar" baz', True, '"foo bar"'), "Re: (16) failed, expected pass"
- ret = namedGrouping.parseString('"zork" blah')
- print_(ret.asList())
- print_(list(ret.items()))
- print_(ret.content)
- assert ret.content == 'zork', "named group lookup failed"
- assert ret[0] == simpleString.parseString('"zork" blah')[0], "Regex not properly returning ParseResults for named vs. unnamed groups"
-
- try:
- #~ print "lets try an invalid RE"
- invRe = pyparsing.Regex('("[^\"]*")|(\'[^\']*\'')
- except Exception as e:
- print_("successfully rejected an invalid RE:", end=' ')
- print_(e)
- else:
- assert False, "failed to reject invalid RE"
-
- invRe = pyparsing.Regex('')
-
-class CountedArrayTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word,nums,OneOrMore,countedArray
-
- testString = "2 5 7 6 0 1 2 3 4 5 0 3 5 4 3"
-
- integer = Word(nums).setParseAction(lambda t: int(t[0]))
- countedField = countedArray(integer)
-
- r = OneOrMore(countedField).parseString( testString )
- print_(testString)
- print_(r.asList())
-
- assert r.asList() == [[5,7],[0,1,2,3,4,5],[],[5,4,3]], \
- "Failed matching countedArray, got " + str(r.asList())
-
-class CountedArrayTest2(ParseTestCase):
- # addresses bug raised by Ralf Vosseler
- def runTest(self):
- from pyparsing import Word,nums,OneOrMore,countedArray
-
- testString = "2 5 7 6 0 1 2 3 4 5 0 3 5 4 3"
-
- integer = Word(nums).setParseAction(lambda t: int(t[0]))
- countedField = countedArray(integer)
-
- dummy = Word("A")
- r = OneOrMore(dummy ^ countedField).parseString( testString )
- print_(testString)
- print_(r.asList())
-
- assert r.asList() == [[5,7],[0,1,2,3,4,5],[],[5,4,3]], \
- "Failed matching countedArray, got " + str(r.asList())
-
-class CountedArrayTest3(ParseTestCase):
- # test case where counter is not a decimal integer
- def runTest(self):
- from pyparsing import Word,nums,OneOrMore,countedArray,alphas
- int_chars = "_"+alphas
- array_counter = Word(int_chars).setParseAction(lambda t: int_chars.index(t[0]))
-
- # 123456789012345678901234567890
- testString = "B 5 7 F 0 1 2 3 4 5 _ C 5 4 3"
-
- integer = Word(nums).setParseAction(lambda t: int(t[0]))
- countedField = countedArray(integer, intExpr=array_counter)
-
- r = OneOrMore(countedField).parseString( testString )
- print_(testString)
- print_(r.asList())
-
- assert r.asList() == [[5,7],[0,1,2,3,4,5],[],[5,4,3]], \
- "Failed matching countedArray, got " + str(r.asList())
-
-class LineAndStringEndTest(ParseTestCase):
- def runTest(self):
- from pyparsing import OneOrMore,lineEnd,alphanums,Word,stringEnd,delimitedList,SkipTo
-
- NLs = OneOrMore(lineEnd)
- bnf1 = delimitedList(Word(alphanums).leaveWhitespace(), NLs)
- bnf2 = Word(alphanums) + stringEnd
- bnf3 = Word(alphanums) + SkipTo(stringEnd)
- tests = [
- ("testA\ntestB\ntestC\n", ['testA', 'testB', 'testC']),
- ("testD\ntestE\ntestF", ['testD', 'testE', 'testF']),
- ("a", ['a']),
- ]
-
- for test,expected in tests:
- res1 = bnf1.parseString(test)
- print_(res1,'=?',expected)
- assert res1.asList() == expected, "Failed lineEnd/stringEnd test (1): "+repr(test)+ " -> "+str(res1.asList())
-
- res2 = bnf2.searchString(test)[0]
- print_(res2.asList(),'=?',expected[-1:])
- assert res2.asList() == expected[-1:], "Failed lineEnd/stringEnd test (2): "+repr(test)+ " -> "+str(res2.asList())
-
- res3 = bnf3.parseString(test)
- first = res3[0]
- rest = res3[1]
- #~ print res3.dump()
- print_(repr(rest),'=?',repr(test[len(first)+1:]))
- assert rest == test[len(first)+1:]#, "Failed lineEnd/stringEnd test (3): " +repr(test)+ " -> "+str(res3[1].asList())
- print_()
-
- from pyparsing import Regex
- import re
-
- k = Regex(r'a+',flags=re.S+re.M)
- k = k.parseWithTabs()
- k = k.leaveWhitespace()
-
- tests = [
- (r'aaa',['aaa']),
- (r'\naaa',None),
- (r'a\naa',None),
- (r'aaa\n',None),
- ]
- for i,(src,expected) in enumerate(tests):
- print_(i, repr(src).replace('\\\\','\\'), end=' ')
- try:
- res = k.parseString(src, parseAll=True).asList()
- except ParseException as pe:
- res = None
- print_(res)
- assert res == expected, "Failed on parseAll=True test %d" % i
-
-class VariableParseActionArgsTest(ParseTestCase):
- def runTest(self):
-
- pa3 = lambda s,l,t: t
- pa2 = lambda l,t: t
- pa1 = lambda t: t
- pa0 = lambda : None
- class Callable3(object):
- def __call__(self,s,l,t):
- return t
- class Callable2(object):
- def __call__(self,l,t):
- return t
- class Callable1(object):
- def __call__(self,t):
- return t
- class Callable0(object):
- def __call__(self):
- return
- class CallableS3(object):
- #~ @staticmethod
- def __call__(s,l,t):
- return t
- __call__=staticmethod(__call__)
- class CallableS2(object):
- #~ @staticmethod
- def __call__(l,t):
- return t
- __call__=staticmethod(__call__)
- class CallableS1(object):
- #~ @staticmethod
- def __call__(t):
- return t
- __call__=staticmethod(__call__)
- class CallableS0(object):
- #~ @staticmethod
- def __call__():
- return
- __call__=staticmethod(__call__)
- class CallableC3(object):
- #~ @classmethod
- def __call__(cls,s,l,t):
- return t
- __call__=classmethod(__call__)
- class CallableC2(object):
- #~ @classmethod
- def __call__(cls,l,t):
- return t
- __call__=classmethod(__call__)
- class CallableC1(object):
- #~ @classmethod
- def __call__(cls,t):
- return t
- __call__=classmethod(__call__)
- class CallableC0(object):
- #~ @classmethod
- def __call__(cls):
- return
- __call__=classmethod(__call__)
-
- class parseActionHolder(object):
- #~ @staticmethod
- def pa3(s,l,t):
- return t
- pa3=staticmethod(pa3)
- #~ @staticmethod
- def pa2(l,t):
- return t
- pa2=staticmethod(pa2)
- #~ @staticmethod
- def pa1(t):
- return t
- pa1=staticmethod(pa1)
- #~ @staticmethod
- def pa0():
- return
- pa0=staticmethod(pa0)
-
- def paArgs(*args):
- print_(args)
- return args[2]
-
- class ClassAsPA0(object):
- def __init__(self):
- pass
- def __str__(self):
- return "A"
-
- class ClassAsPA1(object):
- def __init__(self,t):
- print_("making a ClassAsPA1")
- self.t = t
- def __str__(self):
- return self.t[0]
-
- class ClassAsPA2(object):
- def __init__(self,l,t):
- self.t = t
- def __str__(self):
- return self.t[0]
-
- class ClassAsPA3(object):
- def __init__(self,s,l,t):
- self.t = t
- def __str__(self):
- return self.t[0]
-
- class ClassAsPAStarNew(tuple):
- def __new__(cls, *args):
- print_("make a ClassAsPAStarNew", args)
- return tuple.__new__(cls, *args[2].asList())
- def __str__(self):
- return ''.join(self)
-
- #~ def ClassAsPANew(object):
- #~ def __new__(cls, t):
- #~ return object.__new__(cls, t)
- #~ def __init__(self,t):
- #~ self.t = t
- #~ def __str__(self):
- #~ return self.t
-
- from pyparsing import Literal,OneOrMore
-
- A = Literal("A").setParseAction(pa0)
- B = Literal("B").setParseAction(pa1)
- C = Literal("C").setParseAction(pa2)
- D = Literal("D").setParseAction(pa3)
- E = Literal("E").setParseAction(Callable0())
- F = Literal("F").setParseAction(Callable1())
- G = Literal("G").setParseAction(Callable2())
- H = Literal("H").setParseAction(Callable3())
- I = Literal("I").setParseAction(CallableS0())
- J = Literal("J").setParseAction(CallableS1())
- K = Literal("K").setParseAction(CallableS2())
- L = Literal("L").setParseAction(CallableS3())
- M = Literal("M").setParseAction(CallableC0())
- N = Literal("N").setParseAction(CallableC1())
- O = Literal("O").setParseAction(CallableC2())
- P = Literal("P").setParseAction(CallableC3())
- Q = Literal("Q").setParseAction(paArgs)
- R = Literal("R").setParseAction(parseActionHolder.pa3)
- S = Literal("S").setParseAction(parseActionHolder.pa2)
- T = Literal("T").setParseAction(parseActionHolder.pa1)
- U = Literal("U").setParseAction(parseActionHolder.pa0)
- V = Literal("V")
-
- gg = OneOrMore( A | C | D | E | F | G | H |
- I | J | K | L | M | N | O | P | Q | R | S | U | V | B | T)
- testString = "VUTSRQPONMLKJIHGFEDCBA"
- res = gg.parseString(testString)
- print_(res.asList())
- assert res.asList()==list(testString), "Failed to parse using variable length parse actions"
-
- A = Literal("A").setParseAction(ClassAsPA0)
- B = Literal("B").setParseAction(ClassAsPA1)
- C = Literal("C").setParseAction(ClassAsPA2)
- D = Literal("D").setParseAction(ClassAsPA3)
- E = Literal("E").setParseAction(ClassAsPAStarNew)
-
- gg = OneOrMore( A | B | C | D | E | F | G | H |
- I | J | K | L | M | N | O | P | Q | R | S | T | U | V)
- testString = "VUTSRQPONMLKJIHGFEDCBA"
- res = gg.parseString(testString)
- print_(list(map(str,res)))
- assert list(map(str,res))==list(testString), "Failed to parse using variable length parse actions using class constructors as parse actions"
-
-class EnablePackratParsing(ParseTestCase):
- def runTest(self):
- from pyparsing import ParserElement
- ParserElement.enablePackrat()
-
-class SingleArgExceptionTest(ParseTestCase):
- def runTest(self):
- from pyparsing import ParseBaseException,ParseFatalException
-
- msg = ""
- raisedMsg = ""
- testMessage = "just one arg"
- try:
- raise ParseFatalException(testMessage)
- except ParseBaseException as pbe:
- print_("Received expected exception:", pbe)
- raisedMsg = pbe.msg
- assert raisedMsg == testMessage, "Failed to get correct exception message"
-
-
-class OriginalTextForTest(ParseTestCase):
- def runTest(self):
- from pyparsing import makeHTMLTags, originalTextFor
-
- def rfn(t):
- return "%s:%d" % (t.src, len("".join(t)))
-
- makeHTMLStartTag = lambda tag: originalTextFor(makeHTMLTags(tag)[0], asString=False)
-
- # use the lambda, Luke
- #~ start, imge = makeHTMLTags('IMG')
- start = makeHTMLStartTag('IMG')
-
- # don't replace our fancy parse action with rfn,
- # append rfn to the list of parse actions
- #~ start.setParseAction(rfn)
- start.addParseAction(rfn)
-
- #start.setParseAction(lambda s,l,t:t.src)
- text = '''_<img src="images/cal.png"
- alt="cal image" width="16" height="15">_'''
- s = start.transformString(text)
- if VERBOSE:
- print_(s)
- assert s.startswith("_images/cal.png:"), "failed to preserve input s properly"
- assert s.endswith("77_"),"failed to return full original text properly"
-
- tag_fields = makeHTMLStartTag("IMG").searchString(text)[0]
- if VERBOSE:
- print_(sorted(tag_fields.keys()))
- assert sorted(tag_fields.keys()) == ['alt', 'empty', 'height', 'src', 'startImg', 'tag', 'width'], 'failed to preserve results names in originalTextFor'
-
-
-class PackratParsingCacheCopyTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word,nums,ParserElement,delimitedList,Literal,Optional,alphas,alphanums,ZeroOrMore,empty
-
- integer = Word(nums).setName("integer")
- id = Word(alphas+'_',alphanums+'_')
- simpleType = Literal('int');
- arrayType= simpleType+ZeroOrMore('['+delimitedList(integer)+']')
- varType = arrayType | simpleType
- varDec = varType + delimitedList(id + Optional('='+integer))+';'
-
- codeBlock = Literal('{}')
-
- funcDef = Optional(varType | 'void')+id+'('+(delimitedList(varType+id)|'void'|empty)+')'+codeBlock
-
- program = varDec | funcDef
- input = 'int f(){}'
- results = program.parseString(input)
- print_("Parsed '%s' as %s" % (input, results.asList()))
- assert results.asList() == ['int', 'f', '(', ')', '{}'], "Error in packrat parsing"
-
-class PackratParsingCacheCopyTest2(ParseTestCase):
- def runTest(self):
- from pyparsing import Keyword,Word,Suppress,Forward,Optional,delimitedList,ParserElement,Group
-
- DO,AA = list(map(Keyword, "DO AA".split()))
- LPAR,RPAR = list(map(Suppress,"()"))
- identifier = ~AA + Word("Z")
-
- function_name = identifier.copy()
- #~ function_name = ~AA + Word("Z") #identifier.copy()
- expr = Forward().setName("expr")
- expr << (Group(function_name + LPAR + Optional(delimitedList(expr)) + RPAR).setName("functionCall") |
- identifier.setName("ident")#.setDebug()#.setBreak()
- )
-
- stmt = DO + Group(delimitedList(identifier + ".*" | expr))
- result = stmt.parseString("DO Z")
- print_(result.asList())
- assert len(result[1]) == 1, "packrat parsing is duplicating And term exprs"
-
-class ParseResultsDelTest(ParseTestCase):
- def runTest(self):
- from pyparsing import OneOrMore, Word, alphas, nums
-
- grammar = OneOrMore(Word(nums))("ints") + OneOrMore(Word(alphas))("words")
- res = grammar.parseString("123 456 ABC DEF")
- print_(res.dump())
- origInts = res.ints.asList()
- origWords = res.words.asList()
- del res[1]
- del res["words"]
- print_(res.dump())
- assert res[1]=='ABC',"failed to delete 0'th element correctly"
- assert res.ints.asList()==origInts, "updated named attributes, should have updated list only"
- assert res.words=="", "failed to update named attribute correctly"
- assert res[-1]=='DEF', "updated list, should have updated named attributes only"
-
-class WithAttributeParseActionTest(ParseTestCase):
- def runTest(self):
- """
- This unit test checks withAttribute in these ways:
-
- * Argument forms as keywords and tuples
- * Selecting matching tags by attribute
- * Case-insensitive attribute matching
- * Correctly matching tags having the attribute, and rejecting tags not having the attribute
-
- (Unit test written by voigts as part of the Google Highly Open Participation Contest)
- """
-
- from pyparsing import makeHTMLTags, Word, withAttribute, withClass, nums
-
- data = """
- <a>1</a>
- <a b="x">2</a>
- <a B="x">3</a>
- <a b="X">4</a>
- <a b="y">5</a>
- <a class="boo">8</a>
- """
- tagStart, tagEnd = makeHTMLTags("a")
-
- expr = tagStart + Word(nums).setResultsName("value") + tagEnd
-
- expected = ([['a', ['b', 'x'], False, '2', '</a>'],
- ['a', ['b', 'x'], False, '3', '</a>']],
- [['a', ['b', 'x'], False, '2', '</a>'],
- ['a', ['b', 'x'], False, '3', '</a>']],
- [['a', ['class', 'boo'], False, '8', '</a>']],
- )
-
- for attrib, exp in zip([
- withAttribute(b="x"),
- #withAttribute(B="x"),
- withAttribute(("b","x")),
- #withAttribute(("B","x")),
- withClass("boo"),
- ], expected):
-
- tagStart.setParseAction(attrib)
- result = expr.searchString(data)
-
- print_(result.dump())
- assert result.asList() == exp, "Failed test, expected %s, got %s" % (expected, result.asList())
-
-class NestedExpressionsTest(ParseTestCase):
- def runTest(self):
- """
- This unit test checks nestedExpr in these ways:
- - use of default arguments
- - use of non-default arguments (such as a pyparsing-defined comment
- expression in place of quotedString)
- - use of a custom content expression
- - use of a pyparsing expression for opener and closer is *OPTIONAL*
- - use of input data containing nesting delimiters
- - correct grouping of parsed tokens according to nesting of opening
- and closing delimiters in the input string
-
- (Unit test written by christoph... as part of the Google Highly Open Participation Contest)
- """
- from pyparsing import nestedExpr, Literal, Regex, restOfLine, quotedString
-
- #All defaults. Straight out of the example script. Also, qualifies for
- #the bonus: note the fact that (Z | (E^F) & D) is not parsed :-).
- # Tests for bug fixed in 1.4.10
- print_("Test defaults:")
- teststring = "(( ax + by)*C) (Z | (E^F) & D)"
-
- expr = nestedExpr()
-
- expected = [[['ax', '+', 'by'], '*C']]
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected, "Defaults didn't work. That's a bad sign. Expected: %s, got: %s" % (expected, result)
-
- #Going through non-defaults, one by one; trying to think of anything
- #odd that might not be properly handled.
-
- #Change opener
- print_("\nNon-default opener")
- opener = "["
- teststring = test_string = "[[ ax + by)*C)"
- expected = [[['ax', '+', 'by'], '*C']]
- expr = nestedExpr("[")
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected, "Non-default opener didn't work. Expected: %s, got: %s" % (expected, result)
-
- #Change closer
- print_("\nNon-default closer")
-
- teststring = test_string = "(( ax + by]*C]"
- expected = [[['ax', '+', 'by'], '*C']]
- expr = nestedExpr(closer="]")
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected, "Non-default closer didn't work. Expected: %s, got: %s" % (expected, result)
-
- # #Multicharacter opener, closer
- # opener = "bar"
- # closer = "baz"
- print_("\nLiteral expressions for opener and closer")
-
- opener,closer = list(map(Literal, "bar baz".split()))
- expr = nestedExpr(opener, closer,
- content=Regex(r"([^b ]|b(?!a)|ba(?![rz]))+"))
-
- teststring = "barbar ax + bybaz*Cbaz"
- expected = [[['ax', '+', 'by'], '*C']]
- # expr = nestedExpr(opener, closer)
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected, "Multicharacter opener and closer didn't work. Expected: %s, got: %s" % (expected, result)
-
- #Lisp-ish comments
- print_("\nUse ignore expression (1)")
- comment = Regex(r";;.*")
- teststring = \
- """
- (let ((greeting "Hello, world!")) ;;(foo bar
- (display greeting))
- """
-
- expected = [['let', [['greeting', '"Hello,', 'world!"']], ';;(foo bar',\
- ['display', 'greeting']]]
- expr = nestedExpr(ignoreExpr=comment)
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected , "Lisp-ish comments (\";; <...> $\") didn't work. Expected: %s, got: %s" % (expected, result)
-
-
- #Lisp-ish comments, using a standard bit of pyparsing, and an Or.
- print_("\nUse ignore expression (2)")
- comment = ';;' + restOfLine
-
- teststring = \
- """
- (let ((greeting "Hello, )world!")) ;;(foo bar
- (display greeting))
- """
-
- expected = [['let', [['greeting', '"Hello, )world!"']], ';;', '(foo bar',
- ['display', 'greeting']]]
- expr = nestedExpr(ignoreExpr=(comment ^ quotedString))
- result = expr.parseString(teststring)
- print_(result.dump())
- assert result.asList() == expected , "Lisp-ish comments (\";; <...> $\") and quoted strings didn't work. Expected: %s, got: %s" % (expected, result)
-
-class WordExcludeTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, printables
- allButPunc = Word(printables, excludeChars=".,:;-_!?")
-
- test = "Hello, Mr. Ed, it's Wilbur!"
- result = allButPunc.searchString(test).asList()
- print_(result)
- assert result == [['Hello'], ['Mr'], ['Ed'], ["it's"], ['Wilbur']]
-
-class ParseAllTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, cppStyleComment
-
- testExpr = Word("A")
-
- tests = [
- ("AAAAA", False, True),
- ("AAAAA", True, True),
- ("AAABB", False, True),
- ("AAABB", True, False),
- ]
- for s,parseAllFlag,shouldSucceed in tests:
- try:
- print_("'%s' parseAll=%s (shouldSuceed=%s)" % (s, parseAllFlag, shouldSucceed))
- testExpr.parseString(s,parseAllFlag)
- assert shouldSucceed, "successfully parsed when should have failed"
- except ParseException as pe:
- assert not shouldSucceed, "failed to parse when should have succeeded"
-
- # add test for trailing comments
- testExpr.ignore(cppStyleComment)
-
- tests = [
- ("AAAAA //blah", False, True),
- ("AAAAA //blah", True, True),
- ("AAABB //blah", False, True),
- ("AAABB //blah", True, False),
- ]
- for s,parseAllFlag,shouldSucceed in tests:
- try:
- print_("'%s' parseAll=%s (shouldSucceed=%s)" % (s, parseAllFlag, shouldSucceed))
- testExpr.parseString(s,parseAllFlag)
- assert shouldSucceed, "successfully parsed when should have failed"
- except ParseException as pe:
- assert not shouldSucceed, "failed to parse when should have succeeded"
-
-class GreedyQuotedStringsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import QuotedString, sglQuotedString, dblQuotedString, quotedString, delimitedList
-
- src = """\
- "string1", "strin""g2"
- 'string1', 'string2'
- ^string1^, ^string2^
- <string1>, <string2>"""
-
- testExprs = (sglQuotedString, dblQuotedString, quotedString,
- QuotedString('"', escQuote='""'), QuotedString("'", escQuote="''"),
- QuotedString("^"), QuotedString("<",endQuoteChar=">"))
- for expr in testExprs:
- strs = delimitedList(expr).searchString(src)
- print_(strs)
- assert bool(strs), "no matches found for test expression '%s'" % expr
- for lst in strs:
- assert len(lst) == 2, "invalid match found for test expression '%s'" % expr
-
- from pyparsing import alphas, nums, Word
- src = """'ms1',1,0,'2009-12-22','2009-12-22 10:41:22') ON DUPLICATE KEY UPDATE sent_count = sent_count + 1, mtime = '2009-12-22 10:41:22';"""
- tok_sql_quoted_value = (
- QuotedString("'", "\\", "''", True, False) ^
- QuotedString('"', "\\", '""', True, False))
- tok_sql_computed_value = Word(nums)
- tok_sql_identifier = Word(alphas)
-
- val = tok_sql_quoted_value | tok_sql_computed_value | tok_sql_identifier
- vals = delimitedList(val)
- print_(vals.parseString(src))
- assert len(vals.parseString(src)) == 5, "error in greedy quote escaping"
-
-
-class WordBoundaryExpressionsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import WordEnd, WordStart, oneOf
-
- ws = WordStart()
- we = WordEnd()
- vowel = oneOf(list("AEIOUY"))
- consonant = oneOf(list("BCDFGHJKLMNPQRSTVWXZ"))
-
- leadingVowel = ws + vowel
- trailingVowel = vowel + we
- leadingConsonant = ws + consonant
- trailingConsonant = consonant + we
- internalVowel = ~ws + vowel + ~we
-
- bnf = leadingVowel | trailingVowel
-
- tests = """\
- ABC DEF GHI
- JKL MNO PQR
- STU VWX YZ """.splitlines()
- tests.append( "\n".join(tests) )
-
- expectedResult = [
- [['D', 'G'], ['A'], ['C', 'F'], ['I'], ['E'], ['A', 'I']],
- [['J', 'M', 'P'], [], ['L', 'R'], ['O'], [], ['O']],
- [['S', 'V'], ['Y'], ['X', 'Z'], ['U'], [], ['U', 'Y']],
- [['D', 'G', 'J', 'M', 'P', 'S', 'V'],
- ['A', 'Y'],
- ['C', 'F', 'L', 'R', 'X', 'Z'],
- ['I', 'O', 'U'],
- ['E'],
- ['A', 'I', 'O', 'U', 'Y']],
- ]
-
- for t,expected in zip(tests, expectedResult):
- print_(t)
- results = [flatten(e.searchString(t).asList()) for e in [
- leadingConsonant,
- leadingVowel,
- trailingConsonant,
- trailingVowel,
- internalVowel,
- bnf,
- ]]
- print_(results)
- assert results==expected,"Failed WordBoundaryTest, expected %s, got %s" % (expected,results)
- print_()
-
-class RequiredEachTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Keyword
-
- parser = Keyword('bam') & Keyword('boo')
- try:
- res1 = parser.parseString('bam boo')
- print_(res1.asList())
- res2 = parser.parseString('boo bam')
- print_(res2.asList())
- except ParseException:
- failed = True
- else:
- failed = False
- assert not failed, "invalid logic in Each"
-
- assert set(res1) == set(res2), "Failed RequiredEachTest, expected " + \
- str(res1.asList()) + " and " + str(res2.asList()) + "to contain same words in any order"
-
-class OptionalEachTest(ParseTestCase):
- def runTest1(self):
- from pyparsing import Optional, Keyword
-
- the_input = "Major Tal Weiss"
- parser1 = (Optional('Tal') + Optional('Weiss')) & Keyword('Major')
- parser2 = Optional(Optional('Tal') + Optional('Weiss')) & Keyword('Major')
- p1res = parser1.parseString( the_input)
- p2res = parser2.parseString( the_input)
- assert p1res.asList() == p2res.asList(), "Each failed to match with nested Optionals, " + \
- str(p1res.asList()) + " should match " + str(p2res.asList())
-
-
- def runTest2(self):
- from pyparsing import Word, alphanums, Suppress, OneOrMore, Group, Regex, Optional
-
- word = Word(alphanums + '_').setName("word")
- with_stmt = 'with' + OneOrMore(Group(word('key') + '=' + word('value')))('overrides')
- using_stmt = 'using' + Regex('id-[0-9a-f]{8}')('id')
- modifiers = Optional(with_stmt('with_stmt')) & Optional(using_stmt('using_stmt'))
-
- assert modifiers == "with foo=bar bing=baz using id-deadbeef"
- assert not modifiers == "with foo=bar bing=baz using id-deadbeef using id-feedfeed"
-
- def runTest(self):
- self.runTest1()
- self.runTest2()
-
-class SumParseResultsTest(ParseTestCase):
- def runTest(self):
-
- 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"
-
- res1 = "ID:PARI12345678 DOB:10-10-2010 INFO:"
- res2 = "ID:PARI12345678 DOB:10-10-2010 INFO:"
- res3 = "ID: DOB:10-10-2010 INFO:"
- res4 = "ID:PARI12345678 DOB: INFO: I am cool"
-
- from pyparsing import Regex, Word, alphanums, restOfLine
- 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
-
- tests = (samplestr1,samplestr2,samplestr3,samplestr4,)
- results = (res1, res2, res3, res4,)
- for test,expected in zip(tests, results):
- person = sum(person_data.searchString(test))
- result = "ID:%s DOB:%s INFO:%s" % (person.id, person.dob, person.info)
- print_(test)
- print_(expected)
- print_(result)
- for pd in person_data.searchString(test):
- print_(pd.dump())
- print_()
- assert expected == result, \
- "Failed to parse '%s' correctly, \nexpected '%s', got '%s'" % (test,expected,result)
-
-class MarkInputLineTest(ParseTestCase):
- def runTest(self):
-
- samplestr1 = "DOB 100-10-2010;more garbage\nID PARI12345678;more garbage"
-
- from pyparsing import Regex, Word, alphanums, restOfLine
- dob_ref = "DOB" + Regex(r"\d{2}-\d{2}-\d{4}")("dob")
-
- try:
- res = dob_ref.parseString(samplestr1)
- except ParseException as pe:
- outstr = pe.markInputline()
- print_(outstr)
- assert outstr == "DOB >!<100-10-2010;more garbage", "did not properly create marked input line"
- else:
- assert False, "test construction failed - should have raised an exception"
-
-class LocatedExprTest(ParseTestCase):
- def runTest(self):
-
- # 012345678901234567890123456789012345678901234567890
- samplestr1 = "DOB 10-10-2010;more garbage;ID PARI12345678 ;more garbage"
-
- from pyparsing import Regex, Word, alphanums, restOfLine, locatedExpr
- id_ref = locatedExpr("ID" + Word(alphanums,exact=12)("id"))
-
- res = id_ref.searchString(samplestr1)[0][0]
- print_(res.dump())
- assert samplestr1[res.locn_start:res.locn_end] == 'ID PARI12345678', "incorrect location calculation"
-
-
-class PopTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, alphas, nums
-
- source = "AAA 123 456 789 234"
- patt = Word(alphas)("name") + Word(nums)*(1,)
-
- result = patt.parseString(source)
- tests = [
- (0, 'AAA', ['123', '456', '789', '234']),
- (None, '234', ['123', '456', '789']),
- ('name', 'AAA', ['123', '456', '789']),
- (-1, '789', ['123', '456']),
- ]
- for test in tests:
- idx, val, remaining = test
- if idx is not None:
- ret = result.pop(idx)
- else:
- ret = result.pop()
- print_("EXP:", val, remaining)
- print_("GOT:", ret, result.asList())
- print_(ret, result.asList())
- assert ret == val, "wrong value returned, got %r, expected %r" % (ret, val)
- assert remaining == result.asList(), "list is in wrong state after pop, got %r, expected %r" % (result.asList(), remaining)
- print_()
-
- prevlist = result.asList()
- ret = result.pop('name', default="noname")
- print_(ret)
- print_(result.asList())
- assert ret == "noname", "default value not successfully returned, got %r, expected %r" % (ret, "noname")
- assert result.asList() == prevlist, "list is in wrong state after pop, got %r, expected %r" % (result.asList(), remaining)
-
-
-class AddConditionTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, alphas, nums, Suppress, ParseFatalException
-
- numParser = Word(nums)
- numParser.addParseAction(lambda s,l,t: int(t[0]))
- numParser.addCondition(lambda s,l,t: t[0] % 2)
- numParser.addCondition(lambda s,l,t: t[0] >= 7)
-
- result = numParser.searchString("1 2 3 4 5 6 7 8 9 10")
- print_(result.asList())
- assert result.asList() == [[7],[9]], "failed to properly process conditions"
-
- numParser = Word(nums)
- numParser.addParseAction(lambda s,l,t: int(t[0]))
- rangeParser = (numParser("from_") + Suppress('-') + numParser("to"))
-
- result = rangeParser.searchString("1-4 2-4 4-3 5 6 7 8 9 10")
- print_(result.asList())
- assert result.asList() == [[1, 4], [2, 4], [4, 3]], "failed to properly process conditions"
-
- rangeParser.addCondition(lambda t: t.to > t.from_, message="from must be <= to", fatal=False)
- result = rangeParser.searchString("1-4 2-4 4-3 5 6 7 8 9 10")
- print_(result.asList())
- assert result.asList() == [[1, 4], [2, 4]], "failed to properly process conditions"
-
- rangeParser = (numParser("from_") + Suppress('-') + numParser("to"))
- rangeParser.addCondition(lambda t: t.to > t.from_, message="from must be <= to", fatal=True)
- try:
- result = rangeParser.searchString("1-4 2-4 4-3 5 6 7 8 9 10")
- assert False, "failed to interrupt parsing on fatal condition failure"
- except ParseFatalException:
- print_("detected fatal condition")
-
-class PatientOrTest(ParseTestCase):
- def runTest(self):
- import pyparsing as pp
-
- # Two expressions and a input string which could - syntactically - be matched against
- # both expressions. The "Literal" expression is considered invalid though, so this PE
- # should always detect the "Word" expression.
- def validate(token):
- if token[0] == "def":
- raise pp.ParseException("signalling invalid token")
- return token
-
- a = pp.Word("de").setName("Word")#.setDebug()
- b = pp.Literal("def").setName("Literal").setParseAction(validate)#.setDebug()
- c = pp.Literal("d").setName("d")#.setDebug()
-
- # The "Literal" expressions's ParseAction is not executed directly after syntactically
- # detecting the "Literal" Expression but only after the Or-decision has been made
- # (which is too late)...
- try:
- result = (a ^ b ^ c).parseString("def")
- assert result.asList() == ['de'], "failed to select longest match, chose %s" % result
- except ParseException:
- failed = True
- else:
- failed = False
- assert not failed, "invalid logic in Or, fails on longest match with exception in parse action"
-
-class EachWithOptionalWithResultsNameTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Optional
-
- result = (Optional('foo')('one') & Optional('bar')('two')).parseString('bar foo')
- print_(result.dump())
- assert sorted(result.keys()) == ['one','two']
-
-class UnicodeExpressionTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Literal, ParseException
-
- z = 'a' | Literal(u'\u1111')
- z.streamline()
- try:
- z.parseString('b')
- except ParseException as pe:
- if not PY_3:
- assert pe.msg == r'''Expected {"a" | "\u1111"}''', "Invalid error message raised, got %r" % pe.msg
-
-class SetNameTest(ParseTestCase):
- def runTest(self):
- from pyparsing import (oneOf,infixNotation,Word,nums,opAssoc,delimitedList,countedArray,
- nestedExpr,makeHTMLTags,anyOpenTag,anyCloseTag,commonHTMLEntity,replaceHTMLEntity)
-
- a = oneOf("a b c")
- b = oneOf("d e f")
- arith_expr = infixNotation(Word(nums),
- [
- (oneOf('* /'),2,opAssoc.LEFT),
- (oneOf('+ -'),2,opAssoc.LEFT),
- ])
- arith_expr2 = infixNotation(Word(nums),
- [
- (('?',':'),3,opAssoc.LEFT),
- ])
-
- tests = [
- a,
- b,
- (a | b),
- arith_expr,
- arith_expr.expr,
- arith_expr2,
- arith_expr2.expr,
- delimitedList(Word(nums).setName("int")),
- countedArray(Word(nums).setName("int")),
- nestedExpr(),
- makeHTMLTags('Z'),
- (anyOpenTag,anyCloseTag),
- commonHTMLEntity,
- commonHTMLEntity.setParseAction(replaceHTMLEntity).transformString("lsdjkf &lt;lsdjkf&gt;&amp;&apos;&quot;&xyzzy;"),
- ]
-
- expected = map(str.strip, """\
- a | b | c
- d | e | f
- {a | b | c | d | e | f}
- Forward: ...
- + | - term
- Forward: ...
- ?: term
- int [, int]...
- (len) int...
- nested () expression
- (<Z>, </Z>)
- (<any tag>, </any tag>)
- common HTML entity
- lsdjkf <lsdjkf>&'"&xyzzy;""".splitlines())
-
- for t,e in zip(tests, expected):
- tname = str(t)
- assert tname==e, "expression name mismatch, expected {} got {}".format(e, tname)
-
-class TrimArityExceptionMaskingTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word
-
- invalid_message = [
- "<lambda>() takes exactly 1 argument (0 given)",
- "<lambda>() missing 1 required positional argument: 't'"
- ][PY_3]
- try:
- Word('a').setParseAction(lambda t: t[0]+1).parseString('aaa')
- except Exception as e:
- exc_msg = str(e)
- assert exc_msg != invalid_message, "failed to catch TypeError thrown in _trim_arity"
-
-class OneOrMoreStopTest(ParseTestCase):
- def runTest(self):
- from pyparsing import (Word, OneOrMore, alphas, Keyword, CaselessKeyword,
- nums, alphanums)
-
- test = "BEGIN aaa bbb ccc END"
- BEGIN,END = map(Keyword, "BEGIN,END".split(','))
- body_word = Word(alphas).setName("word")
- for ender in (END, "END", CaselessKeyword("END")):
- expr = BEGIN + OneOrMore(body_word, stopOn=ender) + END
- assert test == expr, "Did not successfully stop on ending expression %r" % ender
-
- number = Word(nums+',.()').setName("number with optional commas")
- parser= (OneOrMore(Word(alphanums+'-/.'), stopOn=number)('id').setParseAction(' '.join)
- + number('data'))
- result = parser.parseString(' XXX Y/123 1,234.567890')
- assert result.asList() == ['XXX Y/123', '1,234.567890'], "Did not successfully stop on ending expression %r" % number
-
-class ZeroOrMoreStopTest(ParseTestCase):
- def runTest(self):
- from pyparsing import (Word, ZeroOrMore, alphas, Keyword, CaselessKeyword)
-
- test = "BEGIN END"
- BEGIN,END = map(Keyword, "BEGIN,END".split(','))
- body_word = Word(alphas).setName("word")
- for ender in (END, "END", CaselessKeyword("END")):
- expr = BEGIN + ZeroOrMore(body_word, stopOn=ender) + END
- assert test == expr, "Did not successfully stop on ending expression %r" % ender
-
-class NestedAsDictTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Literal, Forward, alphanums, Group, delimitedList, Dict, Word, Optional
-
- equals = Literal("=").suppress()
- lbracket = Literal("[").suppress()
- rbracket = Literal("]").suppress()
- lbrace = Literal("{").suppress()
- rbrace = Literal("}").suppress()
-
- value_dict = Forward()
- value_list = Forward()
- value_string = Word(alphanums + "@. ")
-
- value = value_list ^ value_dict ^ value_string
- values = Group(delimitedList(value, ","))
- #~ values = delimitedList(value, ",").setParseAction(lambda toks: [toks.asList()])
-
- value_list << lbracket + values + rbracket
-
- identifier = Word(alphanums + "_.")
-
- assignment = Group(identifier + equals + Optional(value))
- assignments = Dict(delimitedList(assignment, ';'))
- value_dict << lbrace + assignments + rbrace
-
- response = assignments
-
- rsp = 'username=goat; errors={username=[already taken, too short]}; empty_field='
- result_dict = response.parseString(rsp).asDict()
- print_(result_dict)
- assert result_dict['username'] == 'goat', "failed to process string in ParseResults correctly"
- assert result_dict['errors']['username'] == ['already taken', 'too short'], "failed to process nested ParseResults correctly"
-
-class TraceParseActionDecoratorTest(ParseTestCase):
- def runTest(self):
- from pyparsing import traceParseAction, Word, nums
-
- @traceParseAction
- def convert_to_int(t):
- return int(t[0])
-
- class Z(object):
- def __call__(self, other):
- return other[0] * 1000
-
- integer = Word(nums).addParseAction(convert_to_int)
- integer.addParseAction(traceParseAction(lambda t: t[0]*10))
- integer.addParseAction(traceParseAction(Z()))
- integer.parseString("132")
-
-class RunTestsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import Word, nums, delimitedList
-
- integer = Word(nums).setParseAction(lambda t : int(t[0]))
- intrange = integer("start") + '-' + integer("end")
- intrange.addCondition(lambda t: t.end > t.start, message="invalid range, start must be <= end", fatal=True)
- intrange.addParseAction(lambda t: list(range(t.start, t.end+1)))
-
- indices = delimitedList(intrange | integer)
- indices.addParseAction(lambda t: sorted(set(t)))
-
- tests = """\
- # normal data
- 1-3,2-4,6,8-10,16
-
- # lone integer
- 11"""
- results = indices.runTests(tests, printResults=False)[1]
-
- expectedResults = [
- [1, 2, 3, 4, 6, 8, 9, 10, 16],
- [11],
- ]
- for res,expected in zip(results, expectedResults):
- print_(res[1].asList())
- print_(expected)
- assert res[1].asList() == expected, "failed test: " + expected[0][2:]
-
-
- tests = """\
- # invalid range
- 1-2, 3-1, 4-6, 7, 12
- """
- success = indices.runTests(tests, printResults=False, failureTests=True)[0]
- assert success, "failed to raise exception on improper range test"
-
-class CommonExpressionsTest(ParseTestCase):
- def runTest(self):
- from pyparsing import pyparsing_common
-
- success = pyparsing_common.mac_address.runTests("""
- AA:BB:CC:DD:EE:FF
- AA.BB.CC.DD.EE.FF
- AA-BB-CC-DD-EE-FF
- """)[0]
- assert success, "error in parsing valid MAC address"
-
- success = pyparsing_common.mac_address.runTests("""
- # mixed delimiters
- AA.BB:CC:DD:EE:FF
- """, failureTests=True)[0]
- assert success, "error in detecting invalid mac address"
-
- success = pyparsing_common.ipv4_address.runTests("""
- 0.0.0.0
- 1.1.1.1
- 127.0.0.1
- 1.10.100.199
- 255.255.255.255
- """)[0]
- assert success, "error in parsing valid IPv4 address"
-
- success = pyparsing_common.ipv4_address.runTests("""
- # out of range value
- 256.255.255.255
- """, failureTests=True)[0]
- assert success, "error in detecting invalid IPv4 address"
-
- success = pyparsing_common.ipv6_address.runTests("""
- 2001:0db8:85a3:0000:0000:8a2e:0370:7334
- 2134::1234:4567:2468:1236:2444:2106
- 0:0:0:0:0:0:A00:1
- 1080::8:800:200C:417A
- ::A00:1
-
- # loopback address
- ::1
-
- # the null address
- ::
-
- # ipv4 compatibility form
- ::ffff:192.168.0.1
- """)[0]
- assert success, "error in parsing valid IPv6 address"
-
- success = pyparsing_common.ipv6_address.runTests("""
- # too few values
- 1080:0:0:0:8:800:200C
-
- # too many ::'s, only 1 allowed
- 2134::1234:4567::2444:2106
- """, failureTests=True)[0]
- assert success, "error in detecting invalid IPv6 address"
-
- success = pyparsing_common.number.runTests("""
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- """)[0]
- assert success, "error in parsing valid numerics"
-
- # any int or real number, returned as float
- success = pyparsing_common.fnumber.runTests("""
- 100
- -100
- +100
- 3.14159
- 6.02e23
- 1e-12
- """)[0]
- assert success, "error in parsing valid numerics"
-
- success, results = pyparsing_common.iso8601_date.runTests("""
- 1997
- 1997-07
- 1997-07-16
- """)
- assert success, "error in parsing valid iso8601_date"
- expected = [
- ('1997', None, None),
- ('1997', '07', None),
- ('1997', '07', '16'),
- ]
- for r,exp in zip(results, expected):
- assert (r[1].year,r[1].month,r[1].day,) == exp, "failed to parse date into fields"
-
- success, results = pyparsing_common.iso8601_date().addParseAction(pyparsing_common.convertToDate()).runTests("""
- 1997-07-16
- """)
- assert success, "error in parsing valid iso8601_date with parse action"
- assert results[0][1][0] == datetime.date(1997, 7, 16)
-
- success, results = pyparsing_common.iso8601_datetime.runTests("""
- 1997-07-16T19:20+01:00
- 1997-07-16T19:20:30+01:00
- 1997-07-16T19:20:30.45Z
- 1997-07-16 19:20:30.45
- """)
- assert success, "error in parsing valid iso8601_datetime"
-
- success, results = pyparsing_common.iso8601_datetime().addParseAction(pyparsing_common.convertToDatetime()).runTests("""
- 1997-07-16T19:20:30.45
- """)
- assert success, "error in parsing valid iso8601_datetime"
- assert results[0][1][0] == datetime.datetime(1997, 7, 16, 19, 20, 30, 450000)
-
- success = pyparsing_common.uuid.runTests("""
- 123e4567-e89b-12d3-a456-426655440000
- """)[0]
- assert success, "failed to parse valid uuid"
-
-
- success = pyparsing_common.fraction.runTests("""
- 1/2
- -15/16
- -3/-4
- """)[0]
- assert success, "failed to parse valid fraction"
-
-
- success = pyparsing_common.mixed_integer.runTests("""
- 1/2
- -15/16
- -3/-4
- 1 1/2
- 2 -15/16
- 0 -3/-4
- 12
- """)[0]
- assert success, "failed to parse valid mixed integer"
-
- success, results = pyparsing_common.number.runTests("""
- 100
- -3
- 1.732
- -3.14159
- 6.02e23""")
- assert success, "failed to parse numerics"
- for test,result in results:
- expected = eval(test)
- assert result[0] == expected, "numeric parse failed (wrong value) (%s should be %s)" % (result[0], expected)
- assert type(result[0]) == type(expected), "numeric parse failed (wrong type) (%s should be %s)" % (type(result[0]), type(expected))
-
-
-class TokenMapTest(ParseTestCase):
- def runTest(self):
- from pyparsing import tokenMap, Word, hexnums, OneOrMore
-
- parser = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
- success, results = parser.runTests("""
- 00 11 22 aa FF 0a 0d 1a
- """, printResults=False)
- assert success, "failed to parse hex integers"
- print_(results)
- assert results[0][-1].asList() == [0, 17, 34, 170, 255, 10, 13, 26], "tokenMap parse action failed"
-
-
-class ParseFileTest(ParseTestCase):
- def runTest(self):
- from pyparsing import pyparsing_common, OneOrMore
- s = """
- 123 456 789
- """
- input_file = StringIO(s)
- integer = pyparsing_common.integer
-
- results = OneOrMore(integer).parseFile(input_file)
- print_(results)
-
- results = OneOrMore(integer).parseFile('test/parsefiletest_input_file.txt')
- print_(results)
-
-
-class HTMLStripperTest(ParseTestCase):
- def runTest(self):
- from pyparsing import pyparsing_common, originalTextFor, OneOrMore, Word, printables
-
- sample = """
- <html>
- Here is some sample <i>HTML</i> text.
- </html>
- """
- read_everything = originalTextFor(OneOrMore(Word(printables)))
- read_everything.addParseAction(pyparsing_common.stripHTMLTags)
-
- result = read_everything.parseString(sample)
- assert result[0].strip() == 'Here is some sample HTML text.'
-
-class ExprSplitterTest(ParseTestCase):
- def runTest(self):
-
- from pyparsing import Literal, quotedString, pythonStyleComment, Empty
-
- expr = Literal(';') + Empty()
- expr.ignore(quotedString)
- expr.ignore(pythonStyleComment)
-
-
- sample = """
- def main():
- this_semi_does_nothing();
- neither_does_this_but_there_are_spaces_afterward();
- a = "a;b"; return a # this is a comment; it has a semicolon!
-
- def b():
- if False:
- z=1000;b("; in quotes"); c=200;return z
- return ';'
-
- class Foo(object):
- def bar(self):
- '''a docstring; with a semicolon'''
- a = 10; b = 11; c = 12
-
- # this comment; has several; semicolons
- if self.spam:
- x = 12; return x # so; does; this; one
- x = 15;;; y += x; return y
-
- def baz(self):
- return self.bar
- """
- expected = [
- [' this_semi_does_nothing()', ''],
- [' neither_does_this_but_there_are_spaces_afterward()', ''],
- [' a = "a;b"', 'return a # this is a comment; it has a semicolon!'],
- [' z=1000', 'b("; in quotes")', 'c=200', 'return z'],
- [" return ';'"],
- [" '''a docstring; with a semicolon'''"],
- [' a = 10', 'b = 11', 'c = 12'],
- [' # this comment; has several; semicolons'],
- [' x = 12', 'return x # so; does; this; one'],
- [' x = 15', '', '', 'y += x', 'return y'],
- ]
-
- exp_iter = iter(expected)
- for line in filter(lambda ll: ';' in ll, sample.splitlines()):
- print_(str(list(expr.split(line)))+',')
- assert list(expr.split(line)) == next(exp_iter), "invalid split on expression"
-
- print_()
-
- expected = [
- [' this_semi_does_nothing()', ';', ''],
- [' neither_does_this_but_there_are_spaces_afterward()', ';', ''],
- [' a = "a;b"', ';', 'return a # this is a comment; it has a semicolon!'],
- [' z=1000', ';', 'b("; in quotes")', ';', 'c=200', ';', 'return z'],
- [" return ';'"],
- [" '''a docstring; with a semicolon'''"],
- [' a = 10', ';', 'b = 11', ';', 'c = 12'],
- [' # this comment; has several; semicolons'],
- [' x = 12', ';', 'return x # so; does; this; one'],
- [' x = 15', ';', '', ';', '', ';', 'y += x', ';', 'return y'],
- ]
- exp_iter = iter(expected)
- for line in filter(lambda ll: ';' in ll, sample.splitlines()):
- print_(str(list(expr.split(line, includeSeparators=True)))+',')
- assert list(expr.split(line, includeSeparators=True)) == next(exp_iter), "invalid split on expression"
-
- print_()
-
-
- expected = [
- [' this_semi_does_nothing()', ''],
- [' neither_does_this_but_there_are_spaces_afterward()', ''],
- [' a = "a;b"', 'return a # this is a comment; it has a semicolon!'],
- [' z=1000', 'b("; in quotes"); c=200;return z'],
- [' a = 10', 'b = 11; c = 12'],
- [' x = 12', 'return x # so; does; this; one'],
- [' x = 15', ';; y += x; return y'],
- ]
- exp_iter = iter(expected)
- for line in sample.splitlines():
- pieces = list(expr.split(line, maxsplit=1))
- print_(str(pieces)+',')
- if len(pieces) == 2:
- exp = next(exp_iter)
- assert pieces == exp, "invalid split on expression with maxSplits=1"
- elif len(pieces) == 1:
- assert len(expr.searchString(line)) == 0, "invalid split with maxSplits=1 when expr not present"
- else:
- print_("\n>>> " + line)
- assert False, "invalid split on expression with maxSplits=1, corner case"
-
-
-class MiscellaneousParserTests(ParseTestCase):
- def runTest(self):
- import pyparsing
-
- runtests = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- if IRON_PYTHON_ENV:
- runtests = "ABCDEGHIJKLMNOPQRSTUVWXYZ"
-
- # test making oneOf with duplicate symbols
- if "A" in runtests:
- print_("verify oneOf handles duplicate symbols")
- try:
- test1 = pyparsing.oneOf("a b c d a")
- except RuntimeError:
- assert False,"still have infinite loop in oneOf with duplicate symbols"
-
- # test MatchFirst bugfix
- if "B" in runtests:
- print_("verify MatchFirst iterates properly")
- results = pyparsing.quotedString.parseString("'this is a single quoted string'")
- assert len(results) > 0, "MatchFirst error - not iterating over all choices"
-
- # verify streamline of subexpressions
- if "C" in runtests:
- print_("verify proper streamline logic")
- compound = pyparsing.Literal("A") + "B" + "C" + "D"
- assert len(compound.exprs) == 2,"bad test setup"
- print_(compound)
- compound.streamline()
- print_(compound)
- assert len(compound.exprs) == 4,"streamline not working"
-
- # test for Optional with results name and no match
- if "D" in runtests:
- print_("verify Optional's do not cause match failure if have results name")
- testGrammar = pyparsing.Literal("A") + pyparsing.Optional("B").setResultsName("gotB") + pyparsing.Literal("C")
- try:
- testGrammar.parseString("ABC")
- testGrammar.parseString("AC")
- except pyparsing.ParseException as pe:
- print_(pe.pstr,"->",pe)
- assert False, "error in Optional matching of string %s" % pe.pstr
-
- # test return of furthest exception
- if "E" in runtests:
- testGrammar = ( pyparsing.Literal("A") |
- ( pyparsing.Optional("B") + pyparsing.Literal("C") ) |
- pyparsing.Literal("D") )
- try:
- testGrammar.parseString("BC")
- testGrammar.parseString("BD")
- except pyparsing.ParseException as pe:
- print_(pe.pstr,"->",pe)
- assert pe.pstr == "BD", "wrong test string failed to parse"
- assert pe.loc == 1, "error in Optional matching, pe.loc="+str(pe.loc)
-
- # test validate
- if "F" in runtests:
- print_("verify behavior of validate()")
- def testValidation( grmr, gnam, isValid ):
- try:
- grmr.streamline()
- grmr.validate()
- assert isValid,"validate() accepted invalid grammar " + gnam
- except pyparsing.RecursiveGrammarException as e:
- print_(grmr)
- assert not isValid, "validate() rejected valid grammar " + gnam
-
- fwd = pyparsing.Forward()
- g1 = pyparsing.OneOrMore( ( pyparsing.Literal("A") + "B" + "C" ) | fwd )
- g2 = pyparsing.ZeroOrMore("C" + g1)
- fwd << pyparsing.Group(g2)
- testValidation( fwd, "fwd", isValid=True )
-
- fwd2 = pyparsing.Forward()
- fwd2 << pyparsing.Group("A" | fwd2)
- testValidation( fwd2, "fwd2", isValid=False )
-
- fwd3 = pyparsing.Forward()
- fwd3 << pyparsing.Optional("A") + fwd3
- testValidation( fwd3, "fwd3", isValid=False )
-
- # test getName
- if "G" in runtests:
- print_("verify behavior of getName()")
- aaa = pyparsing.Group(pyparsing.Word("a")).setResultsName("A")
- bbb = pyparsing.Group(pyparsing.Word("b")).setResultsName("B")
- ccc = pyparsing.Group(":" + pyparsing.Word("c")).setResultsName("C")
- g1 = "XXX" + pyparsing.ZeroOrMore( aaa | bbb | ccc )
- teststring = "XXX b b a b b a b :c b a"
- names = []
- print_(g1.parseString(teststring).dump())
- for t in g1.parseString(teststring):
- print_(t, repr(t))
- try:
- names.append( t[0].getName() )
- except:
- try:
- names.append( t.getName() )
- except:
- names.append( None )
- print_(teststring)
- print_(names)
- assert names==[None, 'B', 'B', 'A', 'B', 'B', 'A', 'B', 'C', 'B', 'A'], \
- "failure in getting names for tokens"
-
- # test ParseResults.get() method
- if "H" in runtests:
- print_("verify behavior of ParseResults.get()")
- res = g1.parseString(teststring)
- print_(res.get("A","A not found")[0])
- print_(res.get("D","!D"))
- assert res.get("A","A not found")[0] == "a", "get on existing key failed"
- assert res.get("D","!D") == "!D", "get on missing key failed"
-
- if "I" in runtests:
- print_("verify handling of Optional's beyond the end of string")
- testGrammar = "A" + pyparsing.Optional("B") + pyparsing.Optional("C") + pyparsing.Optional("D")
- testGrammar.parseString("A")
- testGrammar.parseString("AB")
-
- # test creating Literal with empty string
- if "J" in runtests:
- print_('verify non-fatal usage of Literal("")')
- e = pyparsing.Literal("")
- try:
- e.parseString("SLJFD")
- except Exception as e:
- assert False, "Failed to handle empty Literal"
-
- # test line() behavior when starting at 0 and the opening line is an \n
- if "K" in runtests:
- print_('verify correct line() behavior when first line is empty string')
- assert pyparsing.line(0, "\nabc\ndef\n") == '', "Error in line() with empty first line in text"
- txt = "\nabc\ndef\n"
- results = [ pyparsing.line(i,txt) for i in range(len(txt)) ]
- assert results == ['', 'abc', 'abc', 'abc', 'abc', 'def', 'def', 'def', 'def'], "Error in line() with empty first line in text"
- txt = "abc\ndef\n"
- results = [ pyparsing.line(i,txt) for i in range(len(txt)) ]
- assert results == ['abc', 'abc', 'abc', 'abc', 'def', 'def', 'def', 'def'], "Error in line() with non-empty first line in text"
-
- # test bugfix with repeated tokens when packrat parsing enabled
- if "L" in runtests:
- a = pyparsing.Literal("a")
- b = pyparsing.Literal("b")
- c = pyparsing.Literal("c")
-
- abb = a + b + b
- abc = a + b + c
- aba = a + b + a
- grammar = abb | abc | aba
-
- assert ''.join(grammar.parseString( "aba" )) == 'aba', "Packrat ABA failure!"
-
-def makeTestSuite():
- import inspect
- suite = TestSuite()
- suite.addTest( PyparsingTestInit() )
-
- test_case_classes = ParseTestCase.__subclasses__()
- # put classes in order as they are listed in the source code
- test_case_classes.sort(key=lambda cls: inspect.getsourcelines(cls)[1])
-
- test_case_classes.remove(PyparsingTestInit)
- # test_case_classes.remove(ParseASMLTest)
- test_case_classes.remove(EnablePackratParsing)
- if IRON_PYTHON_ENV:
- test_case_classes.remove(OriginalTextForTest)
-
- suite.addTests(T() for T in test_case_classes)
-
- if TEST_USING_PACKRAT:
- # retest using packrat parsing (disable those tests that aren't compatible)
- suite.addTest( EnablePackratParsing() )
-
- unpackrattables = [ EnablePackratParsing, RepeaterTest, ]
-
- # add tests to test suite a second time, to run with packrat parsing
- # (leaving out those that we know wont work with packrat)
- packratTests = [t.__class__() for t in suite._tests
- if t.__class__ not in unpackrattables]
- suite.addTests( packratTests )
-
- return suite
-
-def makeTestSuiteTemp(classes):
- suite = TestSuite()
- suite.addTest( PyparsingTestInit() )
- for cls in classes:
- suite.addTest( cls() )
- return suite
-
-console = False
-console = True
-
-#~ from line_profiler import LineProfiler
-#~ from pyparsing import ParseResults
-#~ lp = LineProfiler(ParseResults.__setitem__)
-lp = None
-
-#~ if __name__ == '__main__':
- #~ unittest.main()
-if console:
- #~ # console mode
- testRunner = TextTestRunner()
-
- testclasses = []
- #~ testclasses.append(put_test_class_here)
- #~ testclasses.append(RequiredEachTest)
- if not testclasses:
- testRunner.run( makeTestSuite() )
- else:
- if lp is None:
- testRunner.run( makeTestSuiteTemp(testclasses) )
- else:
- lp.run("testRunner.run( makeTestSuite(%s) )" % testclass.__name__)
-else:
- # HTML mode
- outfile = "testResults.html"
- outstream = file(outfile,"w")
- testRunner = HTMLTestRunner.HTMLTestRunner( stream=outstream )
- testRunner.run( makeTestSuite() )
- outstream.close()
-
- import os
- os.system(r'"C:\Program Files\Internet Explorer\iexplore.exe" file://' + outfile)
-
-#~ lp.print_stats()
diff --git a/trunk/src/update_pyparsing_timestamp.py b/trunk/src/update_pyparsing_timestamp.py
deleted file mode 100644
index 80ea3d4..0000000
--- a/trunk/src/update_pyparsing_timestamp.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from pyparsing import quotedString
-from datetime import datetime
-
-nw = datetime.utcnow()
-nowstring = '"%s"' % (nw.strftime("%d %b %Y %X")[:-3] + " UTC")
-print (nowstring)
-
-quoted_time = quotedString()
-quoted_time.setParseAction(lambda: nowstring)
-
-version_time = "__versionTime__ = " + quoted_time
-with open('pyparsing.py') as oldpp:
- new_code = version_time.transformString(oldpp.read())
-
-with open('pyparsing.py','w') as newpp:
- newpp.write(new_code)
-