summaryrefslogtreecommitdiff
path: root/docutils/test/test_readers/test_python/showast
blob: e7d8463071314ac51d0c10c5f52d733ccf31d956 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#! /usr/bin/env python

"""
This is a tool for exploring abstract syntax trees generated by
``compiler.parse()`` from test data in
docutils/test/test_readers/test_python/test_parser or stdin.

Usage::

    showast <key> <index>

    showast < <module.py>

Where ``<key>`` is the key to the ``totest`` dictionary, and ``<index>`` is
the index of the list ``totest[key]``.  If no arguments are given, stdin is
used for input.
"""

import sys
import compiler
from compiler.ast import Node
import test_parser

def pformat(ast, indent='    ', level=0):
    assert isinstance(ast, Node), 'ast is not a Node: %r' % (ast,)
    atts = {}
    for name, value in vars(ast).items():
        if not value or isinstance(value, Node):
            continue
        if isinstance(value, list):
            if isinstance(value[0], Node):
                continue
            if isinstance(value[0], tuple) and value[0] \
                   and isinstance(value[0][0], Node):
                continue
        atts[name] = str(value).encode('unicode-escape')
    attlist = atts.items()
    attlist.sort()
    parts = [ast.__class__.__name__]
    for name, value in attlist:
        parts.append('%s="%s"' % (name, value))
    result = ['%s<%s>\n' % (indent * level, ' '.join(parts))]
    for node in ast.getChildNodes():
        result.extend(pformat(node, level=level+1))
    return result

if len(sys.argv) > 1:
    key, caseno = sys.argv[1:]
    print 'totest["%s"][%s][0]:\n' % (key, caseno)
    input_text = test_parser.totest[key][int(caseno)][0]
else:
    input_text = sys.stdin.read()
print input_text
module = compiler.parse(input_text)
print module
print
print ''.join(pformat(module)),