summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@austin.rr.com>2020-06-27 08:26:16 -0500
committerptmcg <ptmcg@austin.rr.com>2020-06-27 08:26:16 -0500
commit20dfaac6b80ad42851d82f9d2be376e098f0a5ba (patch)
tree2cf9ef8ceee535a069a05399575ef763b2a6e066
parentb3edef08a38b45c3a5fe74968e3589996761660c (diff)
downloadpyparsing-git-20dfaac6b80ad42851d82f9d2be376e098f0a5ba.tar.gz
Add make_diagram.py to examples to demonstrate creating railroad diags for selected examples
-rw-r--r--CHANGES5
-rw-r--r--examples/TAP.py6
-rw-r--r--examples/delta_time.py6
-rw-r--r--examples/idlParse.py51
-rw-r--r--examples/jsonParser.py6
-rw-r--r--examples/lucene_grammar.py8
-rw-r--r--examples/make_diagram.py34
-rw-r--r--examples/oc.py104
-rw-r--r--examples/parsePythonValue.py22
-rw-r--r--examples/protobuf_parser.py90
-rw-r--r--examples/select_parser.py8
-rw-r--r--examples/sexpParser.py140
-rw-r--r--tests/test_examples.py3
13 files changed, 279 insertions, 204 deletions
diff --git a/CHANGES b/CHANGES
index 65abb30..eacd7db 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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")