diff options
author | Paul McGuire <ptmcg@users.noreply.github.com> | 2021-08-08 13:06:41 -0500 |
---|---|---|
committer | Paul McGuire <ptmcg@users.noreply.github.com> | 2021-08-08 13:06:41 -0500 |
commit | f28e4ac920454b34d6290959eba650702d08fd85 (patch) | |
tree | a9957f7ee2966ce40546bd443bd3f257c6c5db1a /examples | |
parent | 2d20decaf42db510f42811f404fcdd446fce21c5 (diff) | |
download | pyparsing-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.py | 72 |
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) |