diff --git a/mkdot.py b/mkdot.py
index ce4cff4bad12de772c7cdc54cbed1db88d3bb948..b9a9afba9b40bed24de4a20f74b182c6002ac7a1 100644
--- a/mkdot.py
+++ b/mkdot.py
@@ -89,6 +89,7 @@ def test_ba():
 	print mk_balanced_atts([str(i) for i in xrange(34)])
 
 	print mk_balanced_atts(['check-model','to-ilp','ilp-objective','ilp-nego','ilp-binary-vars','clauses-met?','every-container','every-pe','every-res-type','every-comp','every-impl','every-mode','every-sw-clause','every-hw-clause','lookup-property','objective-name','objective-value','get-request','get-root','search-comp','search-pe','target','type'])
+	print mk_balanced_atts(dict2list({'comp': 'eq', 'value': '#<procedure:...st-generation.ss:28:39>'}))
 
 @task(default=True)
 def run():
@@ -147,3 +148,95 @@ def convert(f, balance_atts, *atts):
 				fd.write('{0} -> {1}[arrowtail = diamond, dir = back, {2}]\n'.format(lhand, child, options))
 		fd.write(footer)
 	local_quiet('dot {0} -Tpdf > {0}.pdf'.format(output))
+
+t_new_nt   = '-\\'
+t_new_list = '-*'
+t_level    = ' |'
+t_terminal = '|- '
+t_attr     = '| <'
+s_list     = '>*'
+debugging  = False
+
+def dict2list(d, sep=':'):
+	return ['{0}{1}{2}'.format(key,sep,value) for key,value in d.iteritems()]
+
+def clean(value):
+	return value.strip().replace('{', '(').replace('}', ')')
+
+@task
+def mkast(f):
+	output = f + '.dot'
+	d = {} # node-name -> [(terminal-value-list, attribut-value-list)]
+	with open(f) as fd:
+		lines = fd.readlines()
+	level = 0  # current, expected indendation level
+	nid   = 0  # node id
+	stack = [] # stack of node-names
+	current_node = ''
+	for i, line in enumerate(lines):
+		try:
+			read_level = line.count(t_level)
+			if read_level < level:
+				# some node was finished, do something
+				if debugging:
+					print '> Level adaptation at line', i+1
+					print line.rstrip()
+					print stack
+					print "read_level:", read_level, "level:", level, "current:", current_node
+				for _ in xrange(level - read_level): ## FIXME: maybe add 1 to this
+					current_node = stack.pop()
+				level = read_level
+#				if current_node.startswith(s_list):
+#					print '>> List-Hack for', current_node
+#					level -= 1
+#					current_node = stack.pop()
+			if t_new_nt in line:
+				# TODO: also make a link to previous node
+				stack.append(current_node)
+				current_node = '{0}-{1}'.format(line[line.find(t_new_nt)+2:].strip(),nid)
+				nid   += 1
+				level += 1
+				d.setdefault(current_node, [{},{},stack[-1]])
+				if debugging:
+					print '> new node:', current_node, 'stack:', stack
+			elif t_new_list in line:
+				# TODO: somehow remember current name of list nonterminal
+				stack.append(current_node)
+				level += 1
+				name = line[line.find(t_new_list)+3:].strip()
+#				stack.append(s_list + name)
+				if debugging:
+					print '> found list in', current_node, ':', name, 'stack:', stack
+				pass
+			elif t_terminal in line:
+				key, _, value = line[line.find(t_terminal)+3:].partition(':')
+				if debugging:
+					print '> found terminal in', current_node, ':', key.strip(), '==', value.strip()
+				d[current_node][0][key.strip()] = clean(value)
+			elif t_attr in line:
+				key, _, value = line[line.find(t_attr)+3:].partition('>')
+				if debugging:
+					print '> found attribute in', current_node, ':', key, '=>', value.strip()
+				d[current_node][1][key] = clean(value)
+		except:
+			if debugging:
+				print ">> Error in line", i+1
+				print stack
+			raise
+
+	if debugging:
+		print(d)
+	with open(output, 'w') as fd:
+		fd.write(header)
+		for nodename,values in d.iteritems():
+			# define the hierachy
+			nodename = nodename.replace('-', '_')
+			if values[2]:
+				parent = values[2].replace('-', '_')
+				fd.write('{0} -> {1}\n'.format(parent, nodename))
+			terminal_string  = '{ ' + ' } | { '.join([' | '.join(l) for l in mk_balanced_atts(dict2list(values[0]))]) + ' }'
+			attribute_string = '{ ' + ' } | { '.join([' | '.join(l) for l in mk_balanced_atts(dict2list(values[1]))]) + ' }'
+			# define the node
+			fd.write('{0} [label = "{{{0} | {{ t | {1} }} | {{ a | {2} }} }}"]\n'.format(nodename, terminal_string, attribute_string))
+		fd.write(footer)
+	local_quiet('dot {0} -Tpdf > {0}.pdf'.format(output))