Skip to content

Instantly share code, notes, and snippets.

@pib
Created November 23, 2009 07:57
  • Star 16 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pib/240957 to your computer and use it in GitHub Desktop.
A simple Python s-expression parser.
from string import whitespace
atom_end = set('()"\'') | set(whitespace)
def parse(sexp):
stack, i, length = [[]], 0, len(sexp)
while i < length:
c = sexp[i]
print c, stack
reading = type(stack[-1])
if reading == list:
if c == '(': stack.append([])
elif c == ')':
stack[-2].append(stack.pop())
if stack[-1][0] == ('quote',): stack[-2].append(stack.pop())
elif c == '"': stack.append('')
elif c == "'": stack.append([('quote',)])
elif c in whitespace: pass
else: stack.append((c,))
elif reading == str:
if c == '"':
stack[-2].append(stack.pop())
if stack[-1][0] == ('quote',): stack[-2].append(stack.pop())
elif c == '\\':
i += 1
stack[-1] += sexp[i]
else: stack[-1] += c
elif reading == tuple:
if c in atom_end:
atom = stack.pop()
if atom[0][0].isdigit(): stack[-1].append(eval(atom[0]))
else: stack[-1].append(atom)
if stack[-1][0] == ('quote',): stack[-2].append(stack.pop())
continue
else: stack[-1] = ((stack[-1][0] + c),)
i += 1
return stack.pop()
Copy link

ghost commented Apr 14, 2017

Works for me.

@leoheck
Copy link

leoheck commented Jun 23, 2021

Yeah, pretty nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment