quiz about symbolic manipulation
Bengt Richter
bokr at oz.net
Tue Dec 17 08:52:02 EST 2002
On Mon, 16 Dec 2002 14:24:59 GMT, Michael Hudson <mwh at python.net> wrote:
>bokr at oz.net (Bengt Richter) writes:
>
>> Well, for a toy problem, parsing according to python grammar is probably
>> overkill. I.e.,
>>
>> 'square(square(x+y)+z)+square(x+w)'
>>
>> becomes
>>
>> ['eval_input',
>> ['testlist',
>> ['test',
>> ['and_test',
>> ['not_test',
>> ['comparison',
>> ['expr',
>> ['xor_expr',
>[... and on and on and on ...]
>
>Bengt probably knows this, but you can use the compiler package to
>make this very much pleasanter...
>
Christmas is here early ;-)
>>>> compiler.transformer.parse('square(square(x+y)+z)+square(x+w)')
>Module(None, Stmt([Discard(Add((CallFunc(Name('square'),
>[Add((CallFunc(Name('square'), [Add((Name('x'), Name('y')))], None,
>None), Name('z')))], None, None), CallFunc(Name('square'),
>[Add((Name('x'), Name('w')))], None, None))))]))
>>>> _.node.nodes[0].expr
>Add((CallFunc(Name('square'), [Add((CallFunc(Name('square'),
>[Add((Name('x'), Name('y')))], None, None), Name('z')))], None, None),
>CallFunc(Name('square'), [Add((Name('x'), Name('w')))], None, None)))
>
>Hmm, well the fact that pprint.pprint doesn't know how to deal with
>these thigns doesn't help, but these really are nicer to work with :)
>
How about this as relatively simple prettyprinting for this kind of output?
[ 5:49] C:\pywk\clp>ppcomp.py -h
Usage: python ppcomp.py [-i | -h | -f filename | expression ]
(nothing specified reads stdin, -i prompts, -h prints this, else the obvious)
[ 5:49] C:\pywk\clp>ppcomp.py square(square(x+y)+z)+square(x+w)
Module(
None,
Stmt(
[
Discard(
Add(
(
CallFunc(
| Name(
| | 'square'),
| [
| | Add(
| | (
| | CallFunc(
| | | Name(
| | | | 'square'),
| | | [
| | | | Add(
| | | | (
| | | | Name(
| | | | | 'x'),
| | | | Name(
| | | | 'y')))],
| | | None,
| | | None),
| | Name(
| | 'z')))],
| None,
| None),
CallFunc(
Name(
| 'square'),
[
| Add(
| (
| Name(
| | 'x'),
| Name(
| 'w')))],
None,
None))))]))
[ 5:50] C:\pywk\clp>ppcomp.py -i
Enter expression (or just press Enter to quit):
Expr> a,b,c = 1,2,3
Module(
None,
Stmt(
[
Assign(
[
| AssTuple(
| [
| AssName(
| | 'a',
| | 'OP_ASSIGN'),
| AssName(
| | 'b',
| | 'OP_ASSIGN'),
| AssName(
| 'c',
| 'OP_ASSIGN')])],
Tuple(
[
Const(
| 1),
Const(
| 2),
Const(
3)]))]))
(not very tested, but not too bad? ;-)
====< ppcomp.py >====================================================
# ppcomp.py
# pretty print some compiler output -- bokr at oz.net 2002-12-17
import compiler, re, sys
rxb = re.compile(r'([\[\](),])')
IND = ' '
def ppcomp(s):
out = []; wrout = out.append # sys.stdout.write
sp = [s.strip() for s in rxb.split(`compiler.transformer.parse(s)`)]
nest = 0
for t in sp:
if not t: continue
if t in ['(','[']:
wrout(t)
nest += 1
wrout('\n'); wrout(IND*nest)
elif t in [')',']']:
wrout(t)
nest -= 1
else:
wrout(t)
if t == ',': wrout('\n'); wrout(IND*nest)
# make vertical connecting lines
out = ''.join(out).splitlines()
nl = len(out)
linewd=[]
for y in range(nl):
linewd.append(len(out[y])-len(out[y].lstrip()))
lastwd = 0
for y in range(nl):
w = linewd[y];
if w>=lastwd:
lastwd=w; continue
# draw line upwards if spaces above when indent decreases
ydraw = y-1
while ydraw>=0 and w<linewd[ydraw] and out[ydraw][w]==' ':
s = out[ydraw]
out[ydraw] = s[:w] + '|' + s[w+1:]
ydraw -= 1
return '\n'.join(out)
if __name__ == '__main__':
import sys
s=''
if len(sys.argv)<2:
print 'Enter Python source and end with ^Z'
s = sys.stdin.read()
elif sys.argv[1]=='-f' and len(sys.argv)>2:
f = file(sys.argv[2])
s = f.read()
f.close()
elif sys.argv[1]=='-i':
s='anything'
print 'Enter expression (or just press Enter to quit):'
while s:
s = raw_input('Expr> ').rstrip()
if s: print ppcomp(s)
elif sys.argv[1]=='-h':
print """
Usage: python ppcomp.py [-i | -h | -f filename | expression ]
(nothing specified reads stdin, -i prompts, -h prints this, else the obvious)
"""
else:
s = sys.argv[1]
if s: print ppcomp(s)
=====================================================================
Regards,
Bengt Richter
More information about the Python-list
mailing list