summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorptmcg <ptmcg@austin.rr.com>2021-09-23 18:18:58 -0500
committerptmcg <ptmcg@austin.rr.com>2021-09-23 18:18:58 -0500
commitc8174e7d0d07da6f5183903e26baba9c18a3bd6c (patch)
tree4e8a64da17aaced1ed64916caf46d71e486c1e60 /examples
parent911b85da6a012c779e5d2f7a81090fe5a0c900e0 (diff)
downloadpyparsing-git-c8174e7d0d07da6f5183903e26baba9c18a3bd6c.tar.gz
Add cuneiform_python.py example
Diffstat (limited to 'examples')
-rw-r--r--examples/cuneiform_python.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/examples/cuneiform_python.py b/examples/cuneiform_python.py
new file mode 100644
index 0000000..c51a676
--- /dev/null
+++ b/examples/cuneiform_python.py
@@ -0,0 +1,101 @@
+#
+# cuneiform_python.py
+#
+# Example showing how to create a custom Unicode set for parsing
+#
+# Copyright Paul McGuire, 2021
+#
+from typing import List, Tuple
+import pyparsing as pp
+
+
+class Cuneiform(pp.unicode_set):
+ """Unicode set for Cuneiform Character Range"""
+
+ _ranges: List[Tuple[int, ...]] = [
+ (0x12000, 0x123FF),
+ ]
+
+
+# list out all valid identifier characters
+# print(Cuneiform.identchars)
+
+
+"""
+Simple Cuneiform Python language transformer
+
+Define Cuneiform "words"
+ print: π’„‘π’‰Ώπ’…”π’‹«
+ hello: π’€„π’‚–π’†·π’Ž
+ world: π’Ÿπ’Žπ’‰Ώπ’†·π’€³
+ def: π’΄π’ˆ«
+"""
+
+# uncomment to show parse-time debugging
+# pp.enable_diag(pp.Diagnostics.enable_debug_on_named_expressions)
+
+# define a MINIMAL Python parser
+LPAR, RPAR, COLON, EQ = map(pp.Suppress, "():=")
+def_ = pp.Keyword("π’΄π’ˆ«", ident_chars=Cuneiform.identbodychars).set_name("def")
+any_keyword = def_
+ident = (~any_keyword) + pp.Word(
+ Cuneiform.identchars, Cuneiform.identbodychars, asKeyword=True
+)
+str_expr = pp.infix_notation(
+ pp.QuotedString('"') | pp.common.integer,
+ [
+ ("*", 2, pp.OpAssoc.LEFT),
+ ("+", 2, pp.OpAssoc.LEFT),
+ ],
+)
+
+rvalue = pp.Forward()
+fn_call = (ident + pp.Group(LPAR + pp.Optional(rvalue) + RPAR)).set_name("fn_call")
+
+rvalue <<= fn_call | ident | str_expr | pp.common.number
+assignment_stmt = ident + EQ + rvalue
+
+stmt = pp.Group(fn_call | assignment_stmt).set_name("stmt")
+
+fn_def = pp.Group(
+ def_ + ident + pp.Group(LPAR + pp.Optional(rvalue) + RPAR) + COLON
+).set_name("fn_def")
+fn_body = pp.IndentedBlock(stmt).set_name("fn_body")
+fn_expr = pp.Group(fn_def + pp.Group(fn_body))
+
+script = fn_expr[...] + stmt[...]
+
+
+# parse some Python written in Cuneiform
+cuneiform_hello_world = r"""
+π’΄π’ˆ« π’€„π’‚–π’†·π’Ž():
+ 𒀁 = "π’€„π’‚–π’†·π’Ž, π’Ÿπ’Žπ’‰Ώπ’†·π’€³!\n" * 3
+ π’„‘π’‰Ώπ’…”π’‹«(𒀁)
+
+π’€„π’‚–π’†·π’Ž()"""
+script.parseString(cuneiform_hello_world).pprint(width=30)
+
+
+# use transform_string to convert keywords and builtins to runnable Python
+names_map = {
+ "π’„‘π’‰Ώπ’…”π’‹«": "print",
+}
+ident.add_parse_action(lambda t: names_map.get(t[0], t[0]))
+def_.add_parse_action(lambda: "def")
+
+print("\nconvert Cuneiform Python to executable Python")
+transformed = (
+ (ident | def_)
+ .ignore(pp.quoted_string)
+ .transform_string(cuneiform_hello_world)
+ .strip()
+)
+print(
+ "=================\n"
+ + cuneiform_hello_world.strip()
+ + "\n=================\n"
+ + transformed
+ + "\n=================\n"
+)
+print("# run transformed Python")
+exec(transformed)