diff options
author | ptmcg <ptmcg@austin.rr.com> | 2020-06-27 08:26:16 -0500 |
---|---|---|
committer | ptmcg <ptmcg@austin.rr.com> | 2020-06-27 08:26:16 -0500 |
commit | 20dfaac6b80ad42851d82f9d2be376e098f0a5ba (patch) | |
tree | 2cf9ef8ceee535a069a05399575ef763b2a6e066 | |
parent | b3edef08a38b45c3a5fe74968e3589996761660c (diff) | |
download | pyparsing-git-20dfaac6b80ad42851d82f9d2be376e098f0a5ba.tar.gz |
Add make_diagram.py to examples to demonstrate creating railroad diags for selected examples
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | examples/TAP.py | 6 | ||||
-rw-r--r-- | examples/delta_time.py | 6 | ||||
-rw-r--r-- | examples/idlParse.py | 51 | ||||
-rw-r--r-- | examples/jsonParser.py | 6 | ||||
-rw-r--r-- | examples/lucene_grammar.py | 8 | ||||
-rw-r--r-- | examples/make_diagram.py | 34 | ||||
-rw-r--r-- | examples/oc.py | 104 | ||||
-rw-r--r-- | examples/parsePythonValue.py | 22 | ||||
-rw-r--r-- | examples/protobuf_parser.py | 90 | ||||
-rw-r--r-- | examples/select_parser.py | 8 | ||||
-rw-r--r-- | examples/sexpParser.py | 140 | ||||
-rw-r--r-- | tests/test_examples.py | 3 |
13 files changed, 279 insertions, 204 deletions
@@ -87,6 +87,11 @@ Version 3.0.0a2 - June, 2020 - A simplified Lua parser has been added to the examples (lua_parser.py). +- Added make_diagram.py to the examples directory to demonstrate + creation of railroad diagrams for selected pyparsing examples. + Also restructured some examples to make their parsers importable + without running their embedded tests. + Version 3.0.0a1 - April, 2020 ----------------------------- diff --git a/examples/TAP.py b/examples/TAP.py index 8676e7e..788a656 100644 --- a/examples/TAP.py +++ b/examples/TAP.py @@ -169,7 +169,7 @@ class TAPSummary: tapOutputParser.setParseAction(TAPSummary)
-if __name__ == "__main__":
+def main():
test1 = """\
1..4
ok 1 - Input file opened
@@ -241,3 +241,7 @@ if __name__ == "__main__": tapResult = tapOutputParser.parseString(test)[0]
print(tapResult.summary(showAll=True))
print()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/delta_time.py b/examples/delta_time.py index 5ceff1b..5f820a9 100644 --- a/examples/delta_time.py +++ b/examples/delta_time.py @@ -309,7 +309,7 @@ time_and_day.addParseAction(save_original_string, compute_timestamp, remove_temp time_expression = time_and_day -if __name__ == "__main__": +def main(): current_time = datetime.now() # test grammar tests = """\ @@ -432,3 +432,7 @@ if __name__ == "__main__": print("(relative to %s)" % datetime.now()) time_expression.runTests(tests, postParse=verify_offset) + + +if __name__ == "__main__": + main() diff --git a/examples/idlParse.py b/examples/idlParse.py index 52ed3c3..f5398b7 100644 --- a/examples/idlParse.py +++ b/examples/idlParse.py @@ -129,7 +129,7 @@ def CORBA_IDL_BNF(): typeDef = sequenceDef | (typeName + Optional(lbrack + integer + rbrack))
typedefDef = Group(typedef_ + typeDef + identifier + semi).setName("typedef")
- moduleDef = Forward()
+ moduleDef = Forward().setName("moduleDef")
constDef = Group(
const_
+ typeDef
@@ -137,11 +137,13 @@ def CORBA_IDL_BNF(): + equals
+ (real | integer | quotedString)
+ semi
+ ).setName(
+ "constDef"
) # | quotedString )
exceptionItem = Group(typeDef + identifier + semi)
exceptionDef = (
exception_ + identifier + lbrace + ZeroOrMore(exceptionItem) + rbrace + semi
- )
+ ).setName("exceptionDef")
attributeDef = Optional(readonly_) + attribute_ + typeDef + identifier + semi
paramlist = delimitedList(
Group((inout_ | in_ | out_) + typeName + identifier)
@@ -154,7 +156,7 @@ def CORBA_IDL_BNF(): + rparen
+ Optional(raises_ + lparen + Group(delimitedList(typeName)) + rparen)
+ semi
- )
+ ).setName("operationDef")
interfaceItem = constDef | exceptionDef | attributeDef | operationDef
interfaceDef = Group(
interface_
@@ -164,8 +166,10 @@ def CORBA_IDL_BNF(): + ZeroOrMore(interfaceItem)
+ rbrace
+ semi
- ).setName("opnDef")
- moduleItem = interfaceDef | exceptionDef | constDef | typedefDef | moduleDef
+ ).setName("interfaceDef")
+ moduleItem = (
+ interfaceDef | exceptionDef | constDef | typedefDef | moduleDef
+ ).setName("moduleItem")
moduleDef << module_ + identifier + lbrace + ZeroOrMore(
moduleItem
) + rbrace + semi
@@ -179,28 +183,27 @@ def CORBA_IDL_BNF(): return bnf
-testnum = 1
-
+if __name__ == "__main__":
-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()
+ 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(
"""
/*
diff --git a/examples/jsonParser.py b/examples/jsonParser.py index 3dd9b69..cf01318 100644 --- a/examples/jsonParser.py +++ b/examples/jsonParser.py @@ -50,14 +50,14 @@ LBRACK, RBRACK, LBRACE, RBRACE, COLON = map(pp.Suppress, "[]{}:") jsonString = pp.dblQuotedString().setParseAction(pp.removeQuotes)
jsonNumber = ppc.number()
-jsonObject = pp.Forward()
-jsonValue = pp.Forward()
+jsonObject = pp.Forward().setName("jsonObject")
+jsonValue = pp.Forward().setName("jsonValue")
jsonElements = pp.delimitedList(jsonValue)
jsonArray = pp.Group(LBRACK + pp.Optional(jsonElements, []) + RBRACK)
jsonValue << (
jsonString | jsonNumber | pp.Group(jsonObject) | jsonArray | TRUE | FALSE | NULL
)
-memberDef = pp.Group(jsonString + COLON + jsonValue)
+memberDef = pp.Group(jsonString + COLON + jsonValue).setName("jsonMember")
jsonMembers = pp.delimitedList(memberDef)
jsonObject << pp.Dict(LBRACE + pp.Optional(jsonMembers) + RBRACE)
diff --git a/examples/lucene_grammar.py b/examples/lucene_grammar.py index ee4633c..39b9eb8 100644 --- a/examples/lucene_grammar.py +++ b/examples/lucene_grammar.py @@ -35,7 +35,7 @@ proximity_modifier = pp.Group(TILDE + integer("proximity")) number = ppc.fnumber() fuzzy_modifier = TILDE + pp.Optional(number, default=0.5)("fuzzy") -term = pp.Forward() +term = pp.Forward().setName("field") field_name = valid_word().setName("fieldname") incl_range_search = pp.Group(LBRACK - term("lower") + to_ + term("upper") + RBRACK) excl_range_search = pp.Group(LBRACE - term("lower") + to_ + term("upper") + RBRACE) @@ -57,7 +57,11 @@ expression << pp.infixNotation( (required_modifier | prohibit_modifier, 1, pp.opAssoc.RIGHT), ((not_ | "!").setParseAction(lambda: "NOT"), 1, pp.opAssoc.RIGHT), ((and_ | "&&").setParseAction(lambda: "AND"), 2, pp.opAssoc.LEFT), - (pp.Optional(or_ | "||").setParseAction(lambda: "OR"), 2, pp.opAssoc.LEFT), + ( + pp.Optional(or_ | "||").setName("or").setParseAction(lambda: "OR"), + 2, + pp.opAssoc.LEFT, + ), ], ) diff --git a/examples/make_diagram.py b/examples/make_diagram.py new file mode 100644 index 0000000..f1de4bf --- /dev/null +++ b/examples/make_diagram.py @@ -0,0 +1,34 @@ +# +# make_diagram.py +# +# Sample railroad diagrams of selected pyparsing examples. +# +# Copyright 2020, Paul McGuire + +from pyparsing.diagram import to_railroad, railroad_to_html + + +def make_diagram(expr): + with open("output.html", "w", encoding="utf-8") as fp: + railroad = to_railroad(expr) + fp.write(railroad_to_html(railroad)) + + +# Uncomment the related import statement, and pass the imported parser to make_diagram + +# from examples.delta_time import time_expression +# from examples.sexpParser import sexp +# from examples.ebnftest import ebnf_parser +# from examples.jsonParser import jsonObject +# from examples.lucene_grammar import expression +# from examples.invRegex import parser +# from examples.oc import program +# from examples.mozillaCalendarParser import calendars +# from examples.pgn import pgnGrammar +# from examples.idlParse import CORBA_IDL_BNF +# from examples.chemicalFormulas import formula +# from examples.romanNumerals import romanNumeral +# from examples.protobuf_parser import parser +from examples.parsePythonValue import listItem + +make_diagram(listItem) diff --git a/examples/oc.py b/examples/oc.py index f19a2b0..12fd8dd 100644 --- a/examples/oc.py +++ b/examples/oc.py @@ -151,53 +151,59 @@ for vname in ( # ~ 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;
- if(a() == 1){}
- while(i < 10)
- facpr(i++);
- return 0;
-}
-"""
-ast = program.parseString(test, parseAll=True)
-ast.pprint()
+def main():
+ 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;
+ if(a() == 1){}
+ while(i < 10)
+ facpr(i++);
+ return 0;
+ }
+ """
+
+ ast = program.parseString(test, parseAll=True)
+ ast.pprint()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/parsePythonValue.py b/examples/parsePythonValue.py index 47f9102..4f73bfe 100644 --- a/examples/parsePythonValue.py +++ b/examples/parsePythonValue.py @@ -56,14 +56,16 @@ dictStr <<= ( ) 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'""" +if __name__ == "__main__": -listItem.runTests(tests) + 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'""" + + listItem.runTests(tests) diff --git a/examples/protobuf_parser.py b/examples/protobuf_parser.py index afc8296..92f5a28 100644 --- a/examples/protobuf_parser.py +++ b/examples/protobuf_parser.py @@ -20,6 +20,7 @@ from pyparsing import ( restOfLine, quotedString, Dict, + Keyword, ) ident = Word(alphas + "_", alphanums + "_").setName("identifier") @@ -123,47 +124,48 @@ 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; -}""" - -test3 = """syntax = "proto3"; - -import "test.proto"; - -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 result_per_page = 3; -} -""" - -parser.runTests([test1, test2, test3]) +if __name__ == "__main__": + + 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; + }""" + + test3 = """syntax = "proto3"; + + import "test.proto"; + + message SearchRequest { + string query = 1; + int32 page_number = 2; + int32 result_per_page = 3; + } + """ + + parser.runTests([test1, test2, test3]) diff --git a/examples/select_parser.py b/examples/select_parser.py index 652a448..8779212 100644 --- a/examples/select_parser.py +++ b/examples/select_parser.py @@ -188,7 +188,7 @@ select_stmt << ( select_stmt.ignore(comment) -if __name__ == "__main__": +def main(): tests = """\ select * from xyzzy where z > 100 select * from xyzzy where z > 100 order by zz @@ -233,4 +233,8 @@ if __name__ == "__main__": success, _ = select_stmt.runTests(tests) print("\n{}".format("OK" if success else "FAIL")) - sys.exit(0 if success else 1) + return 0 if success else 1 + + +if __name__ == "__main__": + main() diff --git a/examples/sexpParser.py b/examples/sexpParser.py index 2a0f2c7..179e10a 100644 --- a/examples/sexpParser.py +++ b/examples/sexpParser.py @@ -97,74 +97,80 @@ sexpList = pp.Group(LPAR + 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") - () +def main(): + # 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)))) + ) + ) ) - ) - (geometry "+140+122") -) -""" -test07 = """(defun factorial (x) - (if (zerop x) 1 - (* x (factorial (- x 1))))) - """ -test51 = """(2:XX "abc" (#03# |YWJj|))""" -test51error = """(3:XX "abc" (#03# |YWJj|))""" - -test52 = """ - (and - (or (> uid 1000) - (!= gid 20) + """ + 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") + () + ) ) - (> quota 5.0e+03) + (geometry "+140+122") ) """ - -# Run tests -alltests = [ - globals()[testname] for testname in sorted(locals()) if testname.startswith("test") -] - -sexp.runTests(alltests, fullDump=False) + test07 = """(defun factorial (x) + (if (zerop x) 1 + (* x (factorial (- x 1))))) + """ + test51 = """(2:XX "abc" (#03# |YWJj|))""" + test51error = """(3:XX "abc" (#03# |YWJj|))""" + + test52 = """ + (and + (or (> uid 1000) + (!= gid 20) + ) + (> quota 5.0e+03) + ) + """ + + # Run tests + local_vars = sorted(locals().items()) + alltests = [ + test_fn for testname, test_fn in local_vars if testname.startswith("test") + ] + + sexp.runTests(alltests, fullDump=False) + + +if __name__ == "__main__": + main() diff --git a/tests/test_examples.py b/tests/test_examples.py index d18309a..0886950 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -7,7 +7,8 @@ import unittest class TestExamples(unittest.TestCase): def _run(self, name): - import_module("examples." + name) + mod = import_module("examples." + name) + getattr(mod, 'main', lambda *args, **kwargs: None)() def test_numerics(self): self._run("numerics") |