Package qm :: Package external :: Package DocumentTemplate :: Module gparse
[hide private]
[frames] | no frames]

Source Code for Module qm.external.DocumentTemplate.gparse

  1  ############################################################################## 
  2  # 
  3  # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. 
  4  # 
  5  # This software is subject to the provisions of the Zope Public License, 
  6  # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution. 
  7  # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 
  8  # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  9  # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 
 10  # FOR A PARTICULAR PURPOSE 
 11  # 
 12  ############################################################################## 
 13  "$Id: gparse.py 1069 2008-11-13 21:55:43Z stefan $" 
 14  import sys, parser, symbol, token 
 15   
 16  from symbol import test, suite, argument, arith_expr, shift_expr 
 17  from symbol import subscriptlist, subscript, comparison, trailer, xor_expr 
 18  from symbol import term, not_test, factor, atom, expr, arglist 
 19  from symbol import power, and_test, and_expr 
 20   
 21  from token import STAR, NAME, RPAR, LPAR, NUMBER, DOT, STRING, COMMA 
 22  from token import ISTERMINAL, LSQB, COLON 
 23   
 24  from parser import sequence2ast, compileast, ast2list 
 25   
 26  ParseError='Expression Parse Error' 
 27   
28 -def munge(ast, STAR=STAR, DOT=DOT, LSQB=LSQB, COLON=COLON, trailer=trailer):
29 ast0=ast[0] 30 if ISTERMINAL(ast0): return 31 else: 32 if ast0==term and len(ast) > 2: 33 keep_going=1 34 while keep_going: 35 keep_going=0 36 start=2 37 for i in range(start,len(ast)-1): 38 if ast[i][0]==STAR: 39 ast[i-1:i+2]=[multi_munge(ast[i-1:i+2])] 40 keep_going=1 41 break 42 43 for a in ast[1:]: munge(a) 44 45 elif ast0==power: 46 keep_going=1 47 while keep_going: 48 keep_going=0 49 start=2 50 for i in range(start,len(ast)): 51 a=ast[i] 52 if a[0]==trailer: 53 if a[1][0]==DOT: 54 ast[:i+1]=dot_munge(ast,i) 55 keep_going=1 56 start=3 57 break 58 if a[1][0]==LSQB: 59 if (a[2][0] != subscriptlist or 60 a[2][1][0] != subscript): 61 raise ParseError, ( 62 'Unexpected form after left square brace') 63 64 slist=a[2] 65 if len(slist)==2: 66 # One subscript, check for range and ... 67 sub=slist[1] 68 if sub[1][0]==DOT: 69 raise ParseError, ( 70 'ellipses are not supported') 71 l=len(sub) 72 if l < 3 and sub[1][0] != COLON: 73 ast[:i+1]=item_munge(ast, i) 74 elif l < 5: ast[:i+1]=slice_munge(ast, i) 75 else: raise ParseError, 'Invalid slice' 76 77 else: ast[:i+1]=item_munge(ast, i) 78 keep_going=1 79 start=3 80 break 81 82 for a in ast[1:]: munge(a) 83 else: 84 for a in ast[1:]: munge(a) 85 return ast
86
87 -def slice_munge(ast, i):
88 # Munge a slice access into a function call 89 # Note that we must account for a[:], a[b:], a[:b], and a[b:c] 90 name=ast[i][2][1] 91 args=[arglist] 92 append=args.append 93 94 a=(factor, (power, (atom, (NAME, '_vars')))) 95 a=(argument, (test, (and_test, (not_test, (comparison, 96 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 97 (term, a))))))))))) 98 append(a) 99 append([COMMA,',']) 100 101 a=ast[:i] 102 a=(argument, (test, (and_test, (not_test, (comparison, 103 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 104 (term, (factor, a)))))))))))) 105 append(a) 106 107 sub=ast[i][2][1] 108 l=len(sub) 109 if sub[1][0]==COLON: 110 if l==3: 111 append([COMMA,',']) 112 a=(argument, (test, (and_test, (not_test, (comparison, 113 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 114 (term, (factor, (power, (atom, (NUMBER, '0'))))))))))))))) 115 append(a) 116 append([COMMA,',']) 117 append([argument, sub[2]]) 118 else: 119 append([COMMA,',']) 120 append([argument, sub[1]]) 121 if l==4: 122 append([COMMA,',']) 123 append([argument, sub[3]]) 124 125 return [power, [atom, [NAME, '__guarded_getslice__']], 126 [trailer, [LPAR, '('], args, [RPAR, ')'], 127 ] 128 ]
129
130 -def item_munge(ast, i):
131 # Munge an item access into a function call 132 name=ast[i][2][1] 133 args=[arglist] 134 append=args.append 135 136 a=(factor, (power, (atom, (NAME, '_vars')))) 137 a=(argument, (test, (and_test, (not_test, (comparison, 138 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 139 (term, a))))))))))) 140 append(a) 141 append([COMMA,',']) 142 143 a=ast[:i] 144 a=(argument, (test, (and_test, (not_test, (comparison, 145 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 146 (term, (factor, a)))))))))))) 147 append(a) 148 append([COMMA,',']) 149 150 for sub in ast[i][2][1:]: 151 if sub[0]==COMMA: append(sub) 152 else: 153 if len(sub) != 2: raise ParseError, 'Invalid slice in subscript' 154 append([argument, sub[1]]) 155 156 return [power, [atom, [NAME, '__guarded_getitem__']], 157 [trailer, [LPAR, '('], args, [RPAR, ')'], 158 ] 159 ]
160
161 -def dot_munge(ast, i):
162 # Munge an attribute access into a function call 163 name=ast[i][2][1] 164 args=[arglist] 165 append=args.append 166 167 a=(factor, (power, (atom, (NAME, '_vars')))) 168 a=(argument, (test, (and_test, (not_test, (comparison, 169 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 170 (term, a))))))))))) 171 append(a) 172 append([COMMA,',']) 173 174 a=ast[:i] 175 a=(argument, (test, (and_test, (not_test, (comparison, 176 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 177 (term, (factor, a)))))))))))) 178 append(a) 179 append([COMMA,',']) 180 181 a=(factor, (power, (atom, (STRING, `name`)))) 182 a=(argument, (test, (and_test, (not_test, (comparison, 183 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 184 (term, a))))))))))) 185 append(a) 186 187 return [power, [atom, [NAME, '__guarded_getattr__']], 188 [trailer, [LPAR, '('], args, [RPAR, ')']], 189 ]
190
191 -def multi_munge(ast):
192 # Munge a multiplication into a function call: __guarded_mul__ 193 args=[arglist] 194 195 append=args.append 196 a=(factor, (power, (atom, (NAME, '_vars')))) 197 a=(argument, (test, (and_test, (not_test, (comparison, 198 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 199 (term, a))))))))))) 200 append(a) 201 append([COMMA,',']) 202 203 for a in ast: 204 if a[0]==STAR: args.append([COMMA,',']) 205 else: 206 a=(argument, (test, (and_test, (not_test, (comparison, 207 (expr, (xor_expr, (and_expr, (shift_expr, (arith_expr, 208 (term, a))))))))))) 209 append(a) 210 211 return [factor, [power, 212 [atom, [NAME, '__guarded_mul__']], 213 [trailer, [LPAR, '('], args, [RPAR, ')'], 214 ]]]
215
216 -def compile(src, file_name, ctype):
217 if ctype=='eval': ast=parser.expr(src) 218 elif ctype=='exec': ast=parser.suite(src) 219 l=ast2list(ast) 220 l=munge(l) 221 ast=sequence2ast(l) 222 return parser.compileast(ast, file_name)
223