Zeroth

TinyTwitterv2.2

Apr 20th, 2011
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.84 KB | None | 0 0
  1. from lepl import *
  2. from operator import add, sub, mul, truediv
  3.  
  4. # ast nodes
  5. class Op(List):
  6.     def __float__(self):
  7.         return self._op(float(self[0]), float(self[1]))
  8.  
  9. class Add(Op): _op = add
  10.  
  11. class Sub(Op): _op = sub
  12.  
  13. class Mul(Op): _op = mul
  14.  
  15. class Div(Op): _op = truediv
  16.  
  17. class        Assign(List): pass
  18. class     AssignMul(List): pass
  19. class     AssignDiv(List): pass
  20. class     AssignAdd(List): pass
  21. class     AssignSub(List): pass
  22. class            Eq(List): pass
  23. class           NEq(List): pass
  24. class  GreaterEqual(List): pass
  25. class   GreaterThan(List): pass
  26. class      LessThan(List): pass
  27. class     LessEqual(List): pass
  28. class           AND(List): pass
  29. class            OR(List): pass
  30. class          Expr(List): pass
  31. class          Args(Node): pass
  32. class      Function(List): pass
  33. class   FuncDefHead(List): pass
  34. class FuncDefParams(List): pass
  35. class       FuncDef(List): pass
  36. class         Block(List): pass
  37. class         EqMul(List): pass
  38. class         EqDiv(List): pass
  39. class         EqSub(List): pass
  40. class        EqPlus(List): pass
  41. class      LoopHead(List): pass
  42. class     LoopBlock(List): pass
  43. class      UnarySub(List): pass
  44. class     UnaryPlus(List): pass
  45. class       IfBlock(List): pass
  46. class     ElifBlock(List): pass
  47. class     ElseBlock(List): pass
  48. class    OutputCall(List): pass
  49. class     InputCall(List): pass
  50. #basic tokens
  51. value              = Token(UnsignedReal())
  52. int_               = Token('[0-9]')[1:,...]
  53.  
  54. symbol             = Token('[^0-9a-zA-Z \t\r\n]')
  55.  
  56. none               = Token('No')  >> (lambda x: None)
  57.  
  58. bool               = (Token('T') | Token('F'))   >> (lambda x: x == 'T')
  59. ident              = Token("[a-zA-Z][a-zA-Z0-9_ ]*")[1:,...]
  60.  
  61. singlequotestr     = Token("'[a-zA-Z0-9\.\?:!~@#\$%\^&\*\(\)-_=\+\{\}\[\]\|;\"<>,/ \n\r\t]+'")[1:1,...]
  62. doublequotestr     = Token('"[a-zA-Z0-9\.\?:!~@#\$%\^&\*\(\)-_=\+\{\}\[\]\|;\'<>,/ \n\r\t]+"')[1:1,...]
  63.  
  64. #delayed symbols
  65. group2              = Delayed()
  66. group3              = Delayed()
  67. expr                = Delayed()
  68. lexpr               = Delayed()
  69. list_tuple_item     = Delayed()
  70. funccall            = Delayed()
  71. block               = Delayed()
  72. operation           = Delayed()
  73. outcall             = Delayed()
  74. incall              = Delayed()
  75.  
  76. #simple but non-basic symbols
  77. float_              = (Optional(symbol('-')) & int_ & symbol('.')[0:1] & int_[0:]) >  (lambda x: float("%s" % ''.join(x)))
  78. number              = float_
  79. comma               = ~symbol(',')
  80.                    
  81. str_                =  singlequotestr | doublequotestr #needs stringify function
  82. item                = str_ | number | none | bool | ident
  83.  
  84. #comparison symbols
  85. NEQ                 = symbol("!") & symbol("=")
  86. EQ                  = symbol("=")[2:2,...]
  87. GT                  = symbol(">")
  88. GE                  = symbol(">") & symbol("=")
  89. LT                  = symbol("<")
  90. LE                  = symbol("<") & symbol("=")
  91.  
  92. #syntactical symbols
  93. lparens             = symbol('(')
  94. rparens             = symbol(')')
  95. ifsym               = symbol('~')
  96. elsesym             = symbol('#')
  97. lcurly              = symbol('{')
  98. rcurly              = symbol('}')
  99. EOL                 = symbol(';')
  100.  
  101. #assignment operations
  102. eqMul               = symbol('*') & symbol('=') > EqMul
  103. eqDiv               = symbol('/') & symbol('=') > EqDiv
  104. eqPlus              = symbol('+') & symbol('=') > EqPlus
  105. eqSub               = symbol('-') & symbol('=') > EqSub
  106.  
  107. equal               = symbol('=')
  108.  
  109. #unary ops
  110. unPlus              = symbol('+') & symbol('+')
  111. unSub               = symbol('-') & symbol('-')
  112. operPlus            = ident & ~unPlus > UnaryPlus
  113. operSub             = ident & ~unSub  > UnarySub
  114.  
  115. operation          += operPlus | operSub
  116.  
  117. #statement operations
  118. ###################################################################
  119. # basic handling for mathematical operations
  120. # first layer, most tightly grouped, is parens, numbers, and items
  121. parens              = ~symbol('(') & group3 & ~symbol(')')
  122. group1              = parens | item | funccall | operation | outcall | incall
  123.  
  124. # second layer, next most tightly grouped, is multiplication
  125. mul_                = group1 & ~symbol('*') & group2 > Mul
  126. div_                = group1 & ~symbol('/') & group2 > Div
  127. group2             += mul_ | div_ | group1
  128.  
  129. # third layer, least tightly grouped, is addition
  130. add_                = group2 & ~symbol('+') & group3 > Add
  131. sub_                = group2 & ~symbol('-') & group3 > Sub
  132. group3             += add_ | sub_ | group2
  133. ####################################################################
  134.  
  135.      
  136.  
  137. #########################################################################
  138. #argument list handling
  139. # handles infinite inner lists/tuples, as well as argument amounts.
  140.  
  141. # first one handles lists
  142. list_               = ~symbol('[') & list_tuple_item[:, comma] & ~symbol(']') > list
  143.  
  144. #third is an Or of list, and item
  145. list_tuple_item    +=  item | group3 | list_ | funccall
  146.  
  147. #rename list_tuple_item to arg for shortness
  148. arg                 = list_tuple_item   >> 'arg'
  149.  
  150. #gather a comma-delimited list of arguments
  151. arg_expr            = (arg)[1:, comma]     > Args
  152. ############################################################################
  153.  
  154. ####
  155. #expression handling.
  156. #Use a series of progressively wider expressions to simplify recursion.
  157. #Starts with AND/OR expressions
  158. #then to comparison expressions
  159. #to equality expressions
  160. #boolean expressions
  161. bool_expr = Or(
  162.     lexpr & ~symbol('&') & expr > AND,
  163.     lexpr & ~symbol('?') & expr > OR
  164.     )
  165.    
  166. #comparison expressions
  167. ot_expr = Or(
  168.     bool_expr,
  169.     lexpr & ~GT & expr > GreaterThan,
  170.     lexpr & ~GE & expr > GreaterEqual,
  171.     lexpr & ~LT & expr > LessThan,
  172.     lexpr & ~LE & expr > LessEqual
  173.     )
  174. #equality expressions
  175. eq_expr = Or(
  176.     ot_expr,
  177.     lexpr & ~EQ & expr > Eq,
  178.     lexpr & ~NEQ & expr > NEq
  179.     )
  180.    
  181. #renames all the sub_expr types to be cond
  182. cond                = eq_expr
  183.  
  184. #function calls: func(a, b=10)
  185. funccall           += Or((ident & ~lparens & arg_expr & ~rparens),  (ident & ~lparens & ~rparens)) > Function #'function'
  186.  
  187. #function definitions: separate the head, the params, and the block.
  188. funcdef_head        = ~symbol('^') & ident > FuncDefHead
  189. funcdef_params      = ~symbol(':') & arg_expr > FuncDefParams
  190. funcdef             = funcdef_head & funcdef_params & block > FuncDef
  191.  
  192. #loops:
  193. # [cond;operation]{}
  194. # [cond;]{}
  195.  
  196. loophead            = ~symbol('[') & cond & ~symbol(';') & operation[0:] & ~symbol(']') >LoopHead
  197. loopblock           = loophead & block > LoopBlock
  198.  
  199. #if, else if, and else construction
  200. ifblock             = ~ifsym & ~lparens & cond & ~rparens & block > IfBlock
  201. elseifblock         = ~elsesym & ~lparens & cond & ~rparens & block > ElifBlock
  202. elseblock           = ~elsesym & block > ElseBlock
  203.  
  204. ifstruct            = ifblock & elseifblock[0:] & elseblock[0:]
  205.  
  206. #input/output calls
  207. #@<var containing string with account name>(output)
  208. #$<var containing string with account name>(interogative to ask for input)
  209. outcall            += ~symbol('@') & ident & ~lparens & (str_ | ident) & ~rparens > OutputCall
  210. incall             += ~symbol('$') & ident & ~lparens & (str_ | ident) & ~rparens > InputCall
  211.  
  212. #finally define expr
  213. expr               += Or( cond , funccall , outcall, incall, group3 , operation, number , ident , str_)    > Expr
  214. lexpr              += Or( item, operation, group3) > Expr
  215.  
  216. #assignment statement
  217. assgn_mul           = ident & ~eqMul & expr & ~EOL  > AssignMul
  218. assgn_div           = ident & ~eqDiv & expr & ~EOL  > AssignDiv
  219. assgn_add           = ident & ~eqPlus & expr & ~EOL  > AssignAdd
  220. assgn_sub           = ident & ~eqSub & expr & ~EOL  > AssignSub
  221. assgn_eq            = ident & ~equal & expr & ~EOL  > Assign
  222.  
  223. assgn_mulb          = ident & ~eqMul & expr & ~rcurly  > AssignMul
  224. assgn_divb          = ident & ~eqDiv & expr & ~rcurly  > AssignDiv
  225. assgn_addb          = ident & ~eqPlus & expr & ~rcurly  > AssignAdd
  226. assgn_subb          = ident & ~eqSub & expr & ~rcurly  > AssignSub
  227. assgn_eqb           = ident & ~equal & expr & ~rcurly  > Assign
  228.  
  229. assgn_stmt          = Or(assgn_mul, assgn_div, assgn_add, assgn_sub, assgn_eq)
  230. assgn_stmt_blockend = Or(assgn_mulb, assgn_divb, assgn_addb, assgn_subb, assgn_eqb)
  231. #generic statement construction
  232. stmt                = operation & ~EOL | assgn_stmt | funccall & ~EOL | funcdef | loopblock | ifstruct | incall & ~EOL | outcall & ~EOL
  233. stmt_blockend       = assgn_stmt_blockend | funccall & ~rcurly | operation & ~rcurly | funcdef | loopblock | ifstruct | incall & ~rcurly | outcall & ~rcurly
  234. #string of statements
  235. multi_stmt = stmt[0:]
  236.  
  237. block += ~lcurly & multi_stmt & ~rcurly | ~lcurly & multi_stmt & stmt_blockend[1:1] > Block
  238.  
  239. #block.config.no_full_first_match()
  240. #ast = block.parse('{c=0;b=rnd();[c==0;]{a=$slf("Guess a number: ");~(a<b){@slf("Too low")}#(a>b){@slf("Too high!")}#{@slf("Just right.");c=1}}')
  241. #print List(ast)
  242. #for i in list(ast):
  243. #    print List(i)
  244. ##########################################
  245. #test code
  246. ##########################################    
  247. if __name__ == '__main__':
  248.     #testing code
  249.     ast = none.parse("No")
  250.     print "None Test:                  ", ast[0]==None
  251.    
  252.     ast  = bool.parse("T")
  253.     ast2 = bool.parse("F")
  254.     print "Boolean Test:               ", ast[0]==True, ast2[0]==False
  255.    
  256.     ast  = ident.parse("abc")
  257.     ast2 = ident.parse("abc6")
  258.     ast3 = ident.parse("a_bc")
  259.     ast4 = ident.parse("a_b6_c")
  260.     print "Ident Test:                 ", ast[0]=='abc', ast2[0]=='abc6', ast3[0]=='a_bc', ast4[0]=='a_b6_c'
  261.    
  262.     ast  = str_.parse('"testing     ut87st8st867.?s"')
  263.     ast2 = str_.parse("'testing     ut87st8st867.?s'")
  264.     print "String Test:                ", ast[0]=='"testing     ut87st8st867.?s"', ast2[0]=="'testing     ut87st8st867.?s'"
  265.    
  266.     ast  = number.parse('10')
  267.     ast2 = number.parse('10.0')
  268.     ast3 = number.parse('-10')
  269.     ast4 = number.parse('-10.0  ')
  270.     print "Number Test:                ", ast[0]==10.0, ast2[0]==10.0, ast3[0]==-10.0, ast4[0]==-10.0
  271.    
  272.     ast  = item.parse("'test'")
  273.     ast2 = item.parse('-10.0')
  274.     ast3 = item.parse('No')
  275.     ast4 = item.parse('T')
  276.     ast5 = item.parse('abc')
  277.     print "Item Test:                  ", ast[0]=="'test'", ast2[0]==-10.0, ast3[0]==None, ast4[0]==True, ast5[0]=='abc'
  278.    
  279.     ast = group3.parse('1+2*(3-4)+5/6+7')
  280.     print "Numerical Evaluation Test:  ", float(ast[0])== 1.0+2.0*(3.0-4.0)+5.0/6.0+7.0
  281.    
  282.     ast = arg_expr.parse("a, b, 10, -10.0, [1, a, b, [[c, d], [[a]]]]")
  283.     #print str(List(ast))
  284.     print "Argument Evaluation Test:   ", str(List(ast))=="""List
  285. `- Args
  286.     +- 'a'
  287.     +- 'b'
  288.     +- 10.0
  289.     +- -10.0
  290.     `- list
  291.         +- 1.0
  292.         +- 'a'
  293.         +- 'b'
  294.         `- list
  295.             +- list
  296.             |   +- 'c'
  297.             |   `- 'd'
  298.             `- list
  299.                 `- list
  300.                     `- 'a'"""
  301.     ast  = expr.parse("a==b")
  302.     ast2 = expr.parse("a>=b")
  303.     ast3 = expr.parse("a&b")
  304.     ast4 = expr.parse("4+5")
  305.     print "Expression Evaluation Test: ", str(List(ast))=="""List
  306. `- Expr
  307.     `- Eq
  308.         +- Expr
  309.         |   `- 'a'
  310.         `- Expr
  311.             `- 'b'""",
  312.     print str(List(ast2))=="""List
  313. `- Expr
  314.     `- GreaterEqual
  315.         +- Expr
  316.         |   `- 'a'
  317.         `- Expr
  318.             `- 'b'""",
  319.     print str(List(ast3))=="""List
  320. `- Expr
  321.     `- AND
  322.         +- Expr
  323.         |   `- 'a'
  324.         `- Expr
  325.             `- 'b'""",
  326.     print str(List(ast4))=="""List
  327. `- Expr
  328.     `- Add
  329.         +- 4.0
  330.         `- 5.0"""
  331.     ast = funccall.parse("test(test3(), test4(b), test5(b, c), a)")
  332.     #print str(List(ast))
  333.     print "Function Call Test:         ", str(List(ast))=="""List
  334. `- Function
  335.     +- 'test'
  336.     `- Args
  337.         +- Function
  338.         |   `- 'test3'
  339.         +- Function
  340.         |   +- 'test4'
  341.         |   `- Args
  342.         |       `- 'b'
  343.         +- Function
  344.         |   +- 'test5'
  345.         |   `- Args
  346.         |       +- 'b'
  347.         |       `- 'c'
  348.         `- 'a'"""
  349.     #test suite for statement
  350.     ast  = stmt.parse("a=10;")
  351.     ast3 = stmt.parse("^test: a,b{a=20;b=10}")
  352.     ast2 = stmt.parse("a=func(a, 10, 'hello')+5;")
  353.     #print(List(ast2))
  354.     print "Statement Test:             ", str(List(ast))=="""List
  355. `- Assign
  356.     +- 'a'
  357.     `- Expr
  358.         `- 10.0""",
  359.     print str(List(ast2))=="""List
  360. `- Assign
  361.     +- 'a'
  362.     `- Expr
  363.         `- Add
  364.             +- Function
  365.             |   +- 'func'
  366.             |   `- Args
  367.             |       +- 'a'
  368.             |       +- 10.0
  369.             |       `- "'hello'"
  370.             `- 5.0""",
  371.     print str(List(ast3))=="""List
  372. `- FuncDef
  373.     +- FuncDefHead
  374.     |   `- 'test'
  375.     +- FuncDefParams
  376.     |   `- Args
  377.     |       +- 'a'
  378.     |       `- 'b'
  379.     `- Block
  380.         +- Assign
  381.         |   +- 'a'
  382.         |   `- Expr
  383.         |       `- 20.0
  384.         `- Assign
  385.             +- 'b'
  386.             `- Expr
  387.                 `- 10.0"""
  388.     #test suite for multi_statement
  389.     ast = multi_stmt.parse("a=10;b=20+c;f=test(a,b);[f<100;f++]{a=func(f)}")
  390.     #print List(ast)
  391.     print "Multiple Statement Test:    ", str(List(ast))=="""List
  392. +- Assign
  393. |   +- 'a'
  394. |   `- Expr
  395. |       `- 10.0
  396. +- Assign
  397. |   +- 'b'
  398. |   `- Expr
  399. |       `- Add
  400. |           +- 20.0
  401. |           `- 'c'
  402. +- Assign
  403. |   +- 'f'
  404. |   `- Expr
  405. |       `- Function
  406. |           +- 'test'
  407. |           `- Args
  408. |               +- 'a'
  409. |               `- 'b'
  410. `- LoopBlock
  411.     +- LoopHead
  412.     |   +- LessThan
  413.     |   |   +- Expr
  414.     |   |   |   `- 'f'
  415.     |   |   `- Expr
  416.     |   |       `- 100.0
  417.     |   `- UnaryPlus
  418.     |       `- 'f'
  419.     `- Block
  420.         `- Assign
  421.             +- 'a'
  422.             `- Expr
  423.                 `- Function
  424.                     +- 'func'
  425.                     `- Args
  426.                         `- 'f'"""
  427.                
  428.     #for i in ast:
  429.     #    print List(i)
  430.     #test suite for block
  431.     ast  = block.parse("{b=test3(c, b);a=0;test4()}")
  432.     ast2 = block.parse("{a++}")
  433.     #print str(List(ast2))
  434.     print "Block Test:                 ", str(List(ast))=="""List
  435. `- Block
  436.     +- Assign
  437.     |   +- 'b'
  438.     |   `- Expr
  439.     |       `- Function
  440.     |           +- 'test3'
  441.     |           `- Args
  442.     |               +- 'c'
  443.     |               `- 'b'
  444.     +- Assign
  445.     |   +- 'a'
  446.     |   `- Expr
  447.     |       `- 0.0
  448.     `- Function
  449.         `- 'test4'""",
  450.     print str(List(ast2))=="""List
  451. `- Block
  452.     `- UnaryPlus
  453.         `- 'a'"""
  454.  
  455.     ast = operation.parse('a++')
  456.     #print List(ast)
  457.     #for i in list(ast):
  458.     #    print List(i)
  459.     print "Unary Operation Test:       ", str(List(ast))=="""List
  460. `- UnaryPlus
  461.     `- 'a'"""
  462.      
  463.     ast = loopblock.parse("[a<10;a++]{out(a)}")
  464.     #print List(ast)
  465.     print "Loop Test:                  ", str(List(ast))=="""List
  466. `- LoopBlock
  467.     +- LoopHead
  468.     |   +- LessThan
  469.     |   |   +- Expr
  470.     |   |   |   `- 'a'
  471.     |   |   `- Expr
  472.     |   |       `- 10.0
  473.     |   `- UnaryPlus
  474.     |       `- 'a'
  475.     `- Block
  476.         `- Function
  477.             +- 'out'
  478.             `- Args
  479.                 `- 'a'"""
  480.     ast = ifstruct.parse("~(a<10){out(a)}#(a>10){out(b)}#{out(c)}")
  481.     #print(List(ast))
  482.     print "If Block Test:              ", str(List(ast))=="""List
  483. +- IfBlock
  484. |   +- LessThan
  485. |   |   +- Expr
  486. |   |   |   `- 'a'
  487. |   |   `- Expr
  488. |   |       `- 10.0
  489. |   `- Block
  490. |       `- Function
  491. |           +- 'out'
  492. |           `- Args
  493. |               `- 'a'
  494. +- ElifBlock
  495. |   +- GreaterThan
  496. |   |   +- Expr
  497. |   |   |   `- 'a'
  498. |   |   `- Expr
  499. |   |       `- 10.0
  500. |   `- Block
  501. |       `- Function
  502. |           +- 'out'
  503. |           `- Args
  504. |               `- 'b'
  505. `- ElseBlock
  506.     `- Block
  507.         `- Function
  508.             +- 'out'
  509.             `- Args
  510.                 `- 'c'"""
Advertisement
Add Comment
Please, Sign In to add comment