Parsing C Preprocessor files
Pierre-Frédéric Caillaud
peufeu at free.fr
Thu Jun 24 03:27:16 EDT 2004
I thought about it and...
Here's a stackless version with #include and #if. 20 minutes in the
making...
You'll need a pen and paper to figure how the stack works though :) but
it's fun.
It uses references...
file1 = """Top level line
#if foo
on foo level
#if bar
on bar level
#endif
re foo level
#include file2
#else
not foo
#endif
top level
#ifdef bla
on bla level
#ifdef q
q
#else
not q
#endif
check
#if r
r
#endif
#endif"""
file2 = """included file:
#ifdef stuff
stuff level
#endif
"""
# simple class to process included files
class myreader( object ):
def __init__(self):
self.queue = [] # queue of iterables to be played
def __iter__(self):
return self
# insert an iterable into the current flow
def insert( self, iterator ):
self.queue.append( iterator )
def next(self):
while self.queue:
try:
return self.queue[-1].next()
except StopIteration:
self.queue.pop() # this iterable is finished, throw it away
raise StopIteration
reader = myreader()
reader.insert( iter( file1.split("\n") ))
# stackless parser !
result = []
stack = [result]
stacktop = stack[-1]
for line in reader:
ls = line.strip()
if ls.startswith( "#" ): # factor all # cases for speed
keyword = ls.split(" \t\r\n",1)[0]
if keyword == "#if":
next = []
stacktop.append( [line, next] )
stack.append( next )
stacktop = next
elif keyword == "#else":
stack.pop()
stack[-1][-1].append(line)
next = []
stack[-1][-1].append( next )
stack.append( next )
stacktop = next
elif keyword == "#endif":
stack.pop()
stack[-1][-1] = tuple( stack[-1][-1] + [line] )
elif keyword == "#include":
# I don't parse the filename... replace the iter() below by something
like open(filename)
reader.insert( iter(file2.split("\n")) )
else:
stacktop.append(line)
def printblock(block, indent=0) :
ind = "\t"*indent
for elem in block:
if type( elem ) == list:
printblock( elem, indent+1 )
elif type( elem ) == tuple:
printblock( elem, indent )
else:
print ind, elem
print result
printblock(result)
More information about the Python-list
mailing list