cdecl.py challenge

Simon Burton simonb at webone.com.au
Sun Dec 8 19:48:10 EST 2002


Here is progress so far.

$ ./cdecl.py "unsigned char (*f)();"
f is pointer to function returning char unsigned
$ ./cdecl.py "char * const *(*next)();"
next is pointer to function returning pointer to const * char

Not quite there yet.

Simon Burton.

#!/usr/bin/env python

import sys
from string import *

type_list = "void char signed unsigned short int long float double struct union enum".split()
qual_list = "const volatile".split()
def classify(s):
  if s in type_list: return "TYPE"
  if s in qual_list: return "QUAL"
  else: return "ID"

class CDecl:
  def find_token(self):
    i=0
    tok, kind, s = "", "", self.s
    while i < len(s):
      if s[i].isalnum():
        j=i+1
        while j<len(s):
          if s[j].isalnum():
            j=j+1
            continue
          else:
            break
        tok = s[i:j]
        s = s[j:]
        kind = classify(tok)
        break
      if s[i] in '*()[];,':
        tok = s[i]
        s=s[i+1:]
        kind = "PUNCT"
        break
      i=i+1
    if self.verbose:
      print "['%s',%s,'%s']"%(tok, kind, s),
    self.tok,self.kind,self.s = tok, kind, s
  def find_id(self):
    self.find_token()
    while self.tok and self.kind!="ID":
      self.push()
      #print tok, kind
      self.find_token()
  def find_array(self):
    while self.tok == '[':
      print "array",
      self.find_token() # a number or ']'
      if self.tok.isdigit():
        print "0..%s"%(int(tok)-1),
        self.find_token() # read the ']'
      self.find_token() # read past the ']'
      print "of",
  def find_args(self):
    while self.tok != ')':
      self.find_token()
    self.find_token()
    print "function returning",
  def find_pointers(self):
    #print "find_pointers"
    while self:
      tok, kind = self.peek()
      if tok == '*':
        self.pop()
        print "pointer to",
      else:
        return
  def find_decl(self):
    #tok, kind = self.peek()
    if self.tok == '[' :
      self.find_array()
    if self.tok == '(' :
      self.find_args()
    self.find_pointers()
    while self:
      tok, kind = self.peek()
      if tok == '(':
        self.pop()
        assert self.tok == ')'
        self.find_token()
        self.find_decl()
      else:
        print self.pop()[0],
  def __init__(self,s):
    self.verbose = 0
    self.stack = []
    self.tok = ""
    self.kind = ""
    self.s = s
    self.find_id()
    #print self.stack
    print self.tok,"is",
    self.find_token()
    self.find_decl()
    print
  def __len__(self):
    return len(self.stack)
  def push(self):
    self.stack.append( (self.tok,self.kind) )
  def peek(self):
    return self.stack[-1]
  def pop(self):
    return self.stack.pop()
     
#sys.stdout.write(">>> ")
if not sys.argv[1:]:
  s = sys.stdin.readline()
else:
  s = join(sys.argv[1:])
CDecl( s )




More information about the Python-list mailing list