Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env python26
- # coding: utf-8
- class SSexpr:
- """
- A Simple Simplified Sexprs Reader.
- Author
- ee.zsy
- Date
- Mar,2012
- Type
- type SSexpr = Symbol of string | Block of SSexpr list ;
- function parse : string - > SSexpr .
- Syntax
- SSexpr -> {' '} + Symbol | String | Block + {' '};
- Block -> '(' + {SSexpr} + ')' .
- Usage
- >>> parse(r'(1 2 "3\" 4"( 1 2 3))')
- ['1', '2', '3" 4', ['1', '2', '3']]
- Implementation
- Notice that Python evaluates expressions from left to right.
- """
- ############ Interface #############
- def read(s):
- try:return s.exp()
- except RuntimeError as e:raise SyntaxError(e)
- @classmethod
- def parse(c,code):
- return c(code).read()
- ######### Implementation ###########
- w = " \n\t"
- e = " \n\t,()[]"
- b = (lambda i:lambda s,x:i(x).pop())(set(')]').difference)
- m = 'Brackets or Parentheses do not match.'
- a = dict(zip('\"\'nt\\','\"\'\n\t\\'))
- f = 'Escape character is not recognised'
- def __init__(s,code):
- s.s, s.p, s.d = code, 0 ,0
- def c(s):
- x, s.d = s.d, 0; return x
- def r(s,t):
- s.d = 1;return t
- def peek(s):
- return s.s[s.p] if s.p<len(s.s) else None
- def eat(s):
- s.p += 1; return s.s[s.p-1]
- def exp(s):
- c = s.peek()
- if c is None:return None
- elif c in s.w:return s.eat() and s.exp()
- elif c == '(':return s.eat() and s.blk(')')
- elif c == '[':return s.eat() and s.blk(']')
- elif c == '"':return s.eat() and s.str()
- elif c == ',':return s.eat() and [str,s.exp][s.c()]()
- else:return s.sym()
- def sym(s):
- c = s.peek()
- if c is None or c in s.e:return s.r('')
- else:return s.eat() and c+s.sym()
- def str(s):
- c = s.peek()
- if c is None:raise EOFError
- elif c =='\\':return s.eat() and s.esc(s.eat())+s.str()
- elif c == '"':return s.eat() and s.r('')
- else:return s.eat() and c+s.str()
- def esc(s,c):
- if c in s.a:return s.a[c]
- else:raise SyntaxError(s.f)
- def blk(s,end):
- c = s.peek()
- if c is None:raise EOFError
- elif c == s.b(end):raise SyntaxError(s.m)
- elif c in s.w:return s.eat() and s.blk(end)
- elif c == end:return s.eat() and s.r(tuple())
- elif c == ',' and s.c():return s.eat() and s.blk(end)
- else:return tuple([s.exp()])+s.blk(end)
- if 1:
- assert SSexpr("""123 12""").read() == '123'
- assert SSexpr("""(1 2 3 4(1 2 3))""").read() == ('1', '2', '3', '4', ('1', '2', '3'))
- assert SSexpr("""(1 2 "3 4"( 1 2 3))""").read() == ('1', '2', '3 4', ('1', '2', '3'))
- assert SSexpr.parse(r"""(1 2 "3\" 4"( 1 2 3))""") == ('1', '2', '3" 4', ('1', '2', '3'))
- assert SSexpr.parse(r"""[]""") == tuple()
- assert SSexpr.parse(r"""[,]""") == ('',)
- assert SSexpr.parse(r"""[1,2,]""") == ('1', '2')
- assert SSexpr.parse(r"""[,1,2]""") == ('', '1', '2')
- assert SSexpr.parse(r"""[,,1,2]""") == ('', '', '1', '2')
- assert SSexpr.parse(r"""[1,2,,]""") == ('1', '2', '')
- if __name__ == '__main__':
- print SSexpr("""(hello world)""").read()
- print SSexpr("""[hello,world]""").read()
- while 1:
- print SSexpr(raw_input()).read()
Add Comment
Please, Sign In to add comment