summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorPaul McGuire <ptmcg@users.noreply.github.com>2021-08-08 13:06:41 -0500
committerPaul McGuire <ptmcg@users.noreply.github.com>2021-08-08 13:06:41 -0500
commitf28e4ac920454b34d6290959eba650702d08fd85 (patch)
treea9957f7ee2966ce40546bd443bd3f257c6c5db1a /examples
parent2d20decaf42db510f42811f404fcdd446fce21c5 (diff)
downloadpyparsing-git-f28e4ac920454b34d6290959eba650702d08fd85.tar.gz
Add simplified 1-99 example, extracted from number_words.py
Diffstat (limited to 'examples')
-rw-r--r--examples/one_to_ninety_nine.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/examples/one_to_ninety_nine.py b/examples/one_to_ninety_nine.py
new file mode 100644
index 0000000..6f5520f
--- /dev/null
+++ b/examples/one_to_ninety_nine.py
@@ -0,0 +1,72 @@
+#
+# one_to_ninety_nine.py
+#
+# Copyright 2021, Paul McGuire
+#
+# Parser/evaluator for expressions of numbers as written out in words:
+# - one
+# - seven
+# - twelve
+# - twenty six
+# - forty-two
+#
+# BNF:
+# units ::= one | two | three | ... | nine
+# teens ::= ten | eleven | twelve | ... | nineteen
+# tens ::= twenty | thirty | ... | ninety
+# one_to_99 ::= units | teens | (tens [["-"] units])
+#
+import pyparsing as pp
+
+
+def define_numeric_word_range(
+ names: str,
+ from_: int,
+ to_: int,
+ step: int = 1) -> pp.MatchFirst:
+ """
+ Compose a MatchFirst of CaselessKeywords, given their names and values,
+ which when parsed, are converted to their value
+ """
+
+ def define_numeric_word(nm: str, val: int):
+ return pp.CaselessKeyword(nm).add_parse_action(lambda: val)
+
+ names = names.split()
+ values = range(from_, to_ + 1, step)
+ return pp.MatchFirst(
+ define_numeric_word(name, value) for name, value in zip(names, values)
+ )
+
+
+units = define_numeric_word_range(
+ "one two three four five six seven eight nine", 1, 9
+).set_name("units")
+teens = define_numeric_word_range(
+ "ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen", 10, 19
+).set_name("teens")
+tens = define_numeric_word_range(
+ "twenty thirty forty fifty sixty seventy eighty ninety", 20, 90, step=10
+).set_name("tens")
+
+opt_dash = pp.Opt(pp.Suppress("-"))
+twenty_to_99 = tens + pp.Opt(opt_dash + units)
+
+one_to_99 = (units | teens | twenty_to_99).set_name("1-99")
+one_to_99.add_parse_action(sum)
+
+numeric_expression = one_to_99
+
+if __name__ == "__main__":
+ numeric_expression.run_tests(
+ """
+ one
+ seven
+ twelve
+ twenty six
+ forty-two
+ """
+ )
+
+ # create railroad diagram
+ numeric_expression.create_diagram("one_to_99_diagram.html", vertical=5)