diff options
author | ptmcg <ptmcg@austin.rr.com> | 2021-09-23 18:18:58 -0500 |
---|---|---|
committer | ptmcg <ptmcg@austin.rr.com> | 2021-09-23 18:18:58 -0500 |
commit | c8174e7d0d07da6f5183903e26baba9c18a3bd6c (patch) | |
tree | 4e8a64da17aaced1ed64916caf46d71e486c1e60 /examples/cuneiform_python.py | |
parent | 911b85da6a012c779e5d2f7a81090fe5a0c900e0 (diff) | |
download | pyparsing-git-c8174e7d0d07da6f5183903e26baba9c18a3bd6c.tar.gz |
Add cuneiform_python.py example
Diffstat (limited to 'examples/cuneiform_python.py')
-rw-r--r-- | examples/cuneiform_python.py | 101 |
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) |