145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#!/usr/bin/env python
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org"""
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com>
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgReleased under GNU LGPL license.
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org"""
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport sys
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfrom lexer import Lexer
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfrom parse_core import Symbols, Parser
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport node as node_module
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Node(node_module.Node):
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def is_typedef(self):
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for x in self:
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance(x,Node):
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if x.is_typedef():
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          return 1
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  #def explain(self):
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #l = []
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #for x in self:
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #if isinstance(x,Node):
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #l.append(x.explain())
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #else:
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #l.append(str(x))
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #return string.join(l," ")
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      ##(self.__class__.__name__,string.join(l) )
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def psource(self):
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if hasattr(self,'lines'):
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "# "+string.join(self.lines,"\n# ")+"\n"
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org###################################################################
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org###################################################################
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass BasicType(Node):
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  " int char short etc. "
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,name):
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,name)
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Qualifier(Node):
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,name):
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,name)
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.name=name
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StorageClass(Node):
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,name):
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,name)
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.name=name
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Typedef(StorageClass):
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,s='typedef'):
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,s)
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  #def explain(self):
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #return "type"
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Ellipses(Node):
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,s='...'):
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,s)
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass GCCBuiltin(BasicType):
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Identifier(Node):
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,name="",*items):
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if name or 1:
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      Node.__init__(self,name,*items)
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else:
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      Node.__init__(self)
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.name=name
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Function(Node,Parser):
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symbols = Symbols(symbols)
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    args = ''
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #lexer.get_token()
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok != ')':
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not lexer.tok:
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer)
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #lexer.unget_token() # unget start of decl
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      while lexer.tok != ')':
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = ParameterDeclaration()
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node.parse(lexer,symbols)
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( node )
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if lexer.tok != ')' and lexer.tok != ',':
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer)
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if lexer.tok == ',':
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          lexer.get_token()
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lexer.get_token()
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Pointer(Node):
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Array(Node,Parser):
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lexer.get_token() # a number or ']'
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # XX
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # HACK HACK: constant c expressions can appear in here:
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # eg. [ 15 * sizeof (int) - 2 * sizeof (void *) ]
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # XX
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    toks = []
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while lexer.tok != ']':
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #self.append( lexer.kind )
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      toks.append( lexer.tok )
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    child = " ".join(toks)
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if child == "":
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      child = None
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append( child )
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lexer.get_token() # read past the ']'
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Tag(Node):
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Compound(Node,Parser):
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  "Struct or Union"
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items,**kw):
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items,**kw)
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    symbols = Symbols(symbols)
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tag = "" # anonymous
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok != '{':
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      tag = lexer.tok
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not ( tag[0]=='_' or tag[0].isalpha() ):
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"expected tag, got '%s'"%tag )
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if tag:
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(Tag(tag))
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else:
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(Tag())
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.tag = tag
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok == '{':
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      fieldlist = []
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok != '}':
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if not lexer.tok: self.parse_error(lexer)
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while lexer.tok != '}':
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          node = StructDeclaration()
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          node.parse(lexer,symbols)
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          fieldlist.append( node )
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self += fieldlist
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.__init__() #<--"%(self)
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Struct(Compound):
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Union(Compound):
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Enum(Node,Parser):
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items,**kw):
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items,**kw)
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tag = "" # anonymous
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok != '{':
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      tag = lexer.tok
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not ( tag[0]=='_' or tag[0].isalpha() ):
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"expected tag, got '%s'"%tag )
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if tag:
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(Tag(tag))
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else:
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(Tag())
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.tag = tag
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok == '{':
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok != '}': # XX dopey control flow
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if not lexer.tok: # XX dopey control flow
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer) # XX dopey control flow
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while lexer.tok != '}': # XX dopey control flow
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if lexer.kind is not None:
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.expected_error(lexer ,"identifier" )
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          ident = Identifier(lexer.tok)
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if symbols[ident[0]] is not None:
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.parse_error(lexer,"%s already defined."%ident[0])
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          symbols[ident[0]]=ident
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.append( ident )
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          lexer.get_token()
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if lexer.tok == '=':
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            lexer.get_token()
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            # ConstantExpr
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            # XX hack hack XX
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            while lexer.tok!=',' and lexer.tok!='}':
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org              lexer.get_token()
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            if type( lexer.kind ) is not int:
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              #self.parse_error(lexer ,"expected integer" )
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              # XX hack hack XX
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              while lexer.tok!=',' and lexer.tok!='}':
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#                lexer.get_token()
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#            else:
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              # put initializer into the Identifier
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              ident.append( lexer.kind )
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#              lexer.get_token()
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if lexer.tok != '}':
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if lexer.tok != ',':
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org              self.expected_error(lexer,"}",",")
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            lexer.get_token() # ','
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.__init__() #<--"%(self)
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Declarator(Node,Parser):
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.ident = None
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #Parser.parse_enter(self,lexer)
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    stack = []
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # read up to identifier, pushing tokens onto stack
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.ident = self.parse_identifier(lexer,symbols,stack)
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.name = ''
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.ident is not None:
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append( self.ident )
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.name = self.ident.name
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    # now read outwards from identifier
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.parse_declarator(lexer,symbols,stack)
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #Parser.parse_leave(self,lexer)
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_identifier(self,lexer,symbols,stack):
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_identifier()"%self
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ident = None
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok != ';':
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      while lexer.tok and lexer.kind is not None:
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stack.append( (lexer.tok, lexer.kind) )
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok:
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ident = Identifier( lexer.tok )
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #stack.append( (ident.name, ident) )
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_identifier()=%s"%(self,repr(ident))
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return ident
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_declarator(self,lexer,symbols,stack,level=0):
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "  "*level+"%s.parse_declarator(%s) # --->"%\
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (self,stack)
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok == '[':
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      while lexer.tok == '[':
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = Array()
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node.parse(lexer,symbols)
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append(node)
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == '(':
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"array of functions" )
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    elif lexer.tok == '(':
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      node = Function()
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      node.parse(lexer,symbols)
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append( node )
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == '(':
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"function returns a function" )
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == '[':
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"function returns an array" )
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while stack:
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      tok, kind = stack[-1] # peek
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if tok == '(':
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stack.pop()
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.consume(lexer,')')
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_declarator(lexer,symbols,stack,level+1)
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif tok == '*':
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        stack.pop()
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( Pointer() )
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        tok, kind = stack.pop()
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( kind )
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "  "*level+"%s.parse_declarator(%s) # <---"%\
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (self,stack)
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass AbstractDeclarator(Declarator):
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """ used in ParameterDeclaration; may lack an identifier """
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_identifier(self,lexer,symbols,stack):
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_identifier()"%self
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ident = None
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ident = Identifier()
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while 1:
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ';':
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer)
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ')':
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ',':
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == '[':
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.kind is None:
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print "%s.new identifier"%self
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ident = Identifier( lexer.tok )
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #stack.append( (ident.name, ident) )
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      stack.append( (lexer.tok, lexer.kind) )
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_identifier()=%s"%(self,repr(ident))
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return ident
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass FieldLength(Node):
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StructDeclarator(Declarator):
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok != ':':
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      Declarator.parse(self,lexer,symbols)
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if lexer.tok == ':':
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      # ConstantExpr
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      length = int(lexer.tok)
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #print "length = ",length
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append( FieldLength(length) )
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      lexer.get_token()
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass DeclarationSpecifiers(Node,Parser):
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __eq__(self,other):
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    " unordered (set/bag) equality "
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if not isinstance(other,Node):
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return 0
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for i in range(len(self)):
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not self[i] in other:
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for i in range(len(other)):
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not other[i] in self:
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 1
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.parse_spec(lexer,symbols)
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.reverse()
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_spec(self,lexer,symbols):
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    typespec = None
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while lexer.tok:
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance( lexer.kind, TypeAlias ) or\
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        isinstance( lexer.kind, BasicType ):
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if typespec is not None:
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer ,"type already specified as %s"\
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            %typespec )
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        typespec=lexer.kind
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( lexer.kind )
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif isinstance( lexer.kind, Qualifier ):
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( lexer.kind )
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif isinstance( lexer.kind, StorageClass ):
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( lexer.kind )
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='struct':
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_struct(lexer,symbols)
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='union':
42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_union(lexer,symbols)
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='enum':
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_enum(lexer,symbols)
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.kind is None:
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # identifier
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_struct(self,lexer,symbols):
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_struct()"%(self)
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node = Struct()
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node.parse(lexer,symbols)
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    _node = None
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _node = symbols.get_tag( node.tag )
44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if _node is not None:
44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not isinstance( _node, Struct ):
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer,"tag defined as wrong kind")
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(node)>1:
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(_node)>1:
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer,"tag already defined as %s"%_node)
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #symbols.set_tag( node.tag, node )
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #else:
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # refer to the previously defined struct
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ##node = _node
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node = _node.clone()
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if 0:
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      # refer to the previously defined struct
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(node)==1:
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        _node = symbols.deep_get_tag( node.tag )
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if _node is not None:
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          node=_node
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      # But what about any future reference to the struct ?
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      symbols.set_tag( node.tag, node )
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append( node )
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_union(self,lexer,symbols):
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_union(%s)"%(self,node)
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node = Union()
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node.parse(lexer,symbols)
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    _node = None
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _node = symbols.get_tag( node.tag )
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if _node is not None:
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not isinstance( _node, Union ):
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer,"tag %s defined as wrong kind"%repr(node.tag))
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(node)>1:
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(_node)>1:
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer,"tag already defined as %s"%_node)
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #symbols.set_tag( node.tag, node )
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #else:
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node = _node
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #if len(node)==1:
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #_node = symbols.deep_get_tag( node.tag )
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #if _node is not None:
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node=_node
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      symbols.set_tag( node.tag, node )
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append( node )
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_enum(self,lexer,symbols):
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if self.verbose:
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      print "%s.parse_enum(%s)"%(self,node)
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node = Enum()
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node.parse(lexer,symbols)
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    _node = None
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _node = symbols.get_tag( node.tag )
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if _node is not None:
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if not isinstance( _node, Enum ):
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer,"tag defined as wrong kind")
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(node)>1:
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if len(_node)>1:
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer,"tag already defined as %s"%_node)
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #symbols.set_tag( node.tag, node )
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #else:
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node = _node
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #if len(node)==1:
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #_node = symbols.deep_get_tag( node.tag )
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #if _node is not None:
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node=_node
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if node.tag:
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      symbols.set_tag( node.tag, node )
51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append( node )
51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def is_typedef(self):
51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return self.find(Typedef) is not None
51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def needs_declarator(self):
51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for node in self:
51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance( node, Struct ):
52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance( node, Enum ):
52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance( node, Union ):
52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return False
52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return True
52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TypeSpecifiers(DeclarationSpecifiers):
53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  " used in ParameterDeclaration "
53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse_spec(self,lexer,symbols):
53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    typespec = None
53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while lexer.tok:
53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if isinstance( lexer.kind, TypeAlias ) or\
53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        isinstance( lexer.kind, BasicType ):
53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if typespec is not None:
53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer ,"type already specified as %s"\
53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            %typespec )
54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        typespec=lexer.kind
54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( lexer.kind )
54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif isinstance( lexer.kind, Qualifier ):
54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append( lexer.kind )
54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif isinstance( lexer.kind, StorageClass ):
54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer ,"'%s' cannot appear here"%lexer.tok )
54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='struct':
54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_struct(lexer,symbols)
55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='union':
55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_union(lexer,symbols)
55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.tok=='enum':
55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_enum(lexer,symbols)
55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break #?
56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      elif lexer.kind is None:
56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # identifier
56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Initializer(Node,Parser):
56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.parse_error(lexer,"not implemented")
57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TypeAlias(Node):
57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  " typedefed things "
57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,name,decl=None):
58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,name)#,decl)
58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.name=name
58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.decl=decl
58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass Declaration(Node,Parser):
58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items):
59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items)
59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #self.acted=False
59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if not lexer.tok:
59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return
59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Parser.parse_enter(self,lexer)
59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    declspec = DeclarationSpecifiers()
59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    declspec.parse(lexer,symbols)
59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if len(declspec)==0:
60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ';':
60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # empty declaration...
60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return
60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.parse_error(lexer,
60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        "expected specifiers, got '%s'"%lexer.tok )
60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append(declspec)
60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while 1:
60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      decl = Declarator()
60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      decl.parse(lexer,symbols)
61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(decl)==0:
61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if declspec.needs_declarator():
61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer,
61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            "expected declarator, got '%s'"%lexer.tok )
61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(decl)
61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      ident = decl.ident
61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if ident is not None:
61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #if len(ident):
61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # install symbol
61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = symbols[ident[0]]
62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if node is not None:
62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          # we allow functions to be defined (as same) again
62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          #print node.deepstr(),'\n', self.deepstr()
62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          _node = node.clone()
62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          _node.delete(Identifier)
62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          _self = self.clone()
62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          _self.delete(Identifier)
62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if _node != _self:
62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.parse_error(lexer,
62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org              "\n%s\n  already defined as \n%s\n"%\
63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org              (self.deepstr(),node.deepstr()))
63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if self.is_typedef():
63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            #lexer.mktypedef( ident[0], self )
63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            tp = TypeAlias(ident[0],decl)
63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            lexer.mktypedef( ident[0], tp )
63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          else:
63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            symbols[ident[0]] = self
63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if lexer.tok == '=':
63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          # parse initializer
64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          lexer.get_token()
64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          init = Initializer()
64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          init.parse(lexer,symbols)
64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          ident.append( init ) # as in Enum
64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #else: struct, union or enum
64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ';':
64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # no more declarators
64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == '{':
64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # ! ahhh, function body !!!
65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#        sys.stderr.write(
65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#          "WARNING: function body found at line %s\n"%lexer.lno )
65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        bcount = 1
65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        while bcount:
65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          lexer.get_brace_token()
65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if lexer.tok == '}':
65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            bcount -= 1
65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if lexer.tok == '{':
65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            bcount += 1
65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Parser.parse_leave(self,lexer)
66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return
66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.consume(lexer,',')
66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.consume(lexer,';')
66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Parser.parse_leave(self,lexer)
66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def is_typedef(self):
66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    spec=self[0]
66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    assert isinstance(spec,DeclarationSpecifiers), self.deepstr()
66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return spec.is_typedef()
67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass ParameterDeclaration(Declaration):
67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    typespec = TypeSpecifiers()
67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    typespec.parse(lexer,symbols)
67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append(typespec)
67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    decl = AbstractDeclarator()
68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    decl.parse(lexer,symbols)
68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append(decl)
68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ident = decl.ident
68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if ident is not None and ident[0]:
68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      node = symbols[ident[0]]
68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if node is not None:
68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer,
68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          "%s already defined as %s"%(ident,node))
68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        symbols[ident[0]] = self
69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass StructDeclaration(Declaration):
69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,lexer,symbols):
69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if not lexer.tok:
69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return
69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    declspec = DeclarationSpecifiers()
69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    declspec.parse(lexer,symbols)
70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.append(declspec)
70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if len(declspec)==0:
70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ';':
70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        lexer.get_token()
70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        # empty declaration...
70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return
70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.parse_error(lexer,
70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        "expected specifiers, got '%s'"%lexer.tok )
70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while 1:
70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      decl = StructDeclarator()
71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      decl.parse(lexer,symbols)
71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if len(decl)==0:
71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.parse_error(lexer,
71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          "expected declarator, got '%s'"%lexer.tok )
71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.append(decl)
71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      ident = decl.ident
71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if ident is not None:
71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        node = symbols[ident[0]]
71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if node is not None:
71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          self.parse_error(lexer ,
72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            "%s already defined as %s"%(ident,node))
72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else:
72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          if declspec.is_typedef():
72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            self.parse_error(lexer,"typedef in struct or union")
72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          else:
72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            symbols[ident[0]] = self
72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if lexer.tok == ';':
72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        break
72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      self.consume(lexer,',')
72945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.consume(lexer,';')
73045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass TransUnit(Node,Parser):
73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  """
73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def __init__(self,*items,**kw):
73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Node.__init__(self,*items,**kw)
73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def parse(self,s,verbose=0):
73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.symbols = Symbols()
74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    self.lexer = Lexer(s,verbose=verbose) #,host=__module__)
74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node = None
74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while self.lexer.tok:
74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      node=Declaration()
74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      node.parse(self.lexer,self.symbols)
74545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #sys.stderr.write( "# line %s\n"%self.lexer.lno )
74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if node:
74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.append(node)
74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node.psource()
74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #print node.deepstr(),'\n'
75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        #node.act()
75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def strip(self,files):
75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    " leave only the declarations from <files> "
75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    i=0
75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while i<len(self):
75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if self[i].file in files:
75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=i+1
75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.pop(i)
76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def strip_filter(self,cb):
76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    " leave only the declarations such that cb(file) "
76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    i=0
76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while i<len(self):
76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if cb(self[i].file):
76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        i=i+1
76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      else:
76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        self.pop(i)
76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  def assert_no_dups(self):
77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    check={}
77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for node in self.nodes():
77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      assert not check.has_key(id(node))
77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      check[id(node)]=1
77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtry:
77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  import NoModule
78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  import psyco
78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  from psyco.classes import *
78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgexcept ImportError:
78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  class _psyco:
78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def jit(self):      pass
78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def bind(self, f):  pass
78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    def proxy(self, f): return f
78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  psyco = _psyco()
78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpsyco.bind( Lexer.get_token )
78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgpsyco.bind( Node )
79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdef run0():
79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  verbose = 0
79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  if not sys.argv[1:]:
79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s = sys.stdin.read()
79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  if sys.argv[1:]:
79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s = sys.argv[1]
79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    #if sys.argv[2:]:
79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      #verbose = int(sys.argv[2])
79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  if 0:
80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    import profile
80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    profile.run('TransUnit(s)','prof.out')
80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    import pstats
80345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    p=pstats.Stats('prof.out')
80445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    p.strip_dirs().sort_stats(-1).print_stats()
80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  else:
80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node = TransUnit(verbose = 1 )
80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node.parse(s)
80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    node.act(1,1,1)
80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdef run1():
81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  cstr = "char *(*)() ,"
81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  node = AbstractDeclarator()
81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  node.parse( Lexer(cstr,True), Symbols() )
81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  print node.deepstr()
81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgif __name__=="__main__":
81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org  pass
81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
820