3
# Parse S-expressions output by the Panel Editor
4
# (which is written in Scheme so it can't help writing S-expressions).
6
# See notes at end of file.
11
separators = operators + whitespace + ';' + '"'
15
# Return a list of tokens (strings).
17
def tokenize_string(s):
42
if s[i] in separators: break
49
# Tokenize a whole file (given as file object, not as file name).
50
# Return a list of tokens (strings).
52
def tokenize_file(fp):
57
tokens = tokens + tokenize_string(line)
61
# Exception raised by parse_exr.
63
syntax_error = 'syntax error'
66
# Parse an S-expression.
67
# Input is a list of tokens as returned by tokenize_*().
68
# Return a pair (expr, tokens)
69
# where expr is a list representing the s-expression,
70
# and tokens contains the remaining tokens.
71
# May raise syntax_error.
73
def parse_expr(tokens):
74
if (not tokens) or tokens[0] != '(':
75
raise syntax_error, 'expected "("'
80
raise syntax_error, 'missing ")"'
82
return expr, tokens[1:]
83
elif tokens[0] == '(':
84
subexpr, tokens = parse_expr(tokens)
87
expr.append(tokens[0])
91
# Parse a file (given as file object, not as file name).
92
# Return a list of parsed S-expressions found at the top level.
95
tokens = tokenize_file(fp)
98
expr, tokens = parse_expr(tokens)
106
# '(hip (hop hur-ray))'
108
# passed to tokenize_string() returns the token list
109
# ['(', 'hip', '(', 'hop', 'hur-ray', ')', ')']
111
# When this is passed to parse_expr() it returns the expression
112
# ['hip', ['hop', 'hur-ray']]
113
# plus an empty token list (because there are no tokens left.
115
# When a file containing the example is passed to parse_file() it returns
116
# a list whose only element is the output of parse_expr() above:
117
# [['hip', ['hop', 'hur-ray']]]
122
# Comments start with semicolon (;) and continue till the end of the line.
124
# Tokens are separated by whitespace, except the following characters
125
# always form a separate token (outside strings):
127
# Strings are enclosed in double quotes (") and backslash (\) is used
128
# as escape character in strings.