1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# parsePythonValue.py
#
# Copyright, 2006, by Paul McGuire
#
import pyparsing as pp
cvtBool = lambda t: t[0] == "True"
cvtInt = lambda toks: int(toks[0])
cvtReal = lambda toks: float(toks[0])
cvtTuple = lambda toks: tuple(toks.as_list())
cvtSet = lambda toks: set(toks.as_list())
cvtDict = lambda toks: dict(toks.as_list())
cvtList = lambda toks: [toks.as_list()]
# define punctuation as suppressed literals
lparen, rparen, lbrack, rbrack, lbrace, rbrace, colon, comma = pp.Suppress.using_each("()[]{}:,")
integer = pp.Regex(r"[+-]?\d+").set_name("integer").add_parse_action(cvtInt)
real = pp.Regex(r"[+-]?\d+\.\d*([Ee][+-]?\d+)?").set_name("real").add_parse_action(cvtReal)
tuple_str = pp.Forward().set_name("tuple_expr")
list_str = pp.Forward().set_name("list_expr")
set_str = pp.Forward().set_name("set_expr")
dict_str = pp.Forward().set_name("dict_expr")
unistr = pp.unicodeString().add_parse_action(lambda t: t[0][2:-1])
quoted_str = pp.quotedString().add_parse_action(lambda t: t[0][1:-1])
bool_literal = pp.oneOf("True False", as_keyword=True).add_parse_action(cvtBool)
none_literal = pp.Keyword("None").add_parse_action(pp.replace_with(None))
list_item = (
real
| integer
| quoted_str
| unistr
| bool_literal
| none_literal
| pp.Group(list_str)
| tuple_str
| set_str
| dict_str
).set_name("list_item")
tuple_str <<= (
lparen + pp.Opt(pp.DelimitedList(list_item, allow_trailing_delim=True)) + rparen
)
tuple_str.add_parse_action(cvtTuple)
set_str <<= (
lbrace + pp.DelimitedList(list_item, allow_trailing_delim=True) + rbrace
)
set_str.add_parse_action(cvtSet)
list_str <<= (
lbrack + pp.Opt(pp.DelimitedList(list_item, allow_trailing_delim=True)) + rbrack
)
list_str.add_parse_action(cvtList, lambda t: t[0])
dict_entry = pp.Group(list_item + colon + list_item).set_name("dict_entry")
dict_str <<= (
lbrace + pp.Opt(pp.DelimitedList(dict_entry, allow_trailing_delim=True)) + rbrace
)
dict_str.add_parse_action(cvtDict)
if __name__ == "__main__":
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} }
{ 1, 2, 11, "blah" }
{ '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'"""
list_item.run_tests(tests)
list_item.create_diagram("parse_python_value.html")
|