QSIG fully implemented
[obnox/wireshark/wip.git] / tools / asn2wrs.py
index 6d72f6e55ecbb24ca776acfab9d5bc9b3f6f9f2e..e4757202d37d32e5e30309f6a16e2d09968521b6 100755 (executable)
@@ -327,7 +327,7 @@ def t_QSTRING (t):
 def t_UCASE_IDENT (t):
     r"[A-Z](-[a-zA-Z0-9]|[a-zA-Z0-9])*" # can't end w/ '-'
     if (is_class_ident(t.value)): t.type = 'CLASS_IDENT'
-    if (is_x880_syntax(t.value)): t.type = t.value
+    if (is_class_syntax(t.value)): t.type = t.value
     t.type = reserved_words.get(t.value, t.type)
     return t
 
@@ -551,6 +551,7 @@ class EthCtx:
     self.default_containing_variant = '_pdu_new'
     self.default_embedded_pdv_cb = None
     self.default_external_type_cb = None
+    self.emitted_pdu = {}
     self.module = {}
     self.module_ord = []
     self.all_type_attr = {}
@@ -609,10 +610,12 @@ class EthCtx:
       pass
     return "MIN((%s),(%s))" % (a, b) 
 
-  def value_get_eth(self, nm):
-    ethname = nm
-    if self.value.has_key(nm):
-      ethname = self.value[nm]['ethname']
+  def value_get_eth(self, val):
+    if isinstance(val, Value):
+      return val.to_str(self)
+    ethname = val
+    if self.value.has_key(val):
+      ethname = self.value[val]['ethname']
     return ethname
 
   def value_get_val(self, nm):
@@ -674,8 +677,18 @@ class EthCtx:
       val = self.all_vals[module][nm]
     return val
 
-
   def get_obj_repr(self, ident, restr):
+    def set_type_fn(cls, field, fnfield):
+      obj[fnfield + '_fn'] = 'NULL'
+      obj[fnfield + '_pdu'] = 'NULL'
+      if val.has_key(field) and isinstance(val[field], Type_Ref):
+        p = val[field].eth_type_default_pars(self, '')
+        obj[fnfield + '_fn'] = p['TYPE_REF_FN']
+        obj[fnfield + '_fn'] = obj[fnfield + '_fn'] % p  # one iteration
+        if (self.conform.check_item('PDU', cls + '.' + field)):
+          obj[fnfield + '_pdu'] = 'dissect_' + self.field[val[field].val]['ethname']
+      return
+    # end of get_type_fn()
     obj = { '_name' : ident, '_ident' : asn2c(ident)}
     obj['_class'] = self.oassign[ident].cls
     val = self.oassign[ident].val
@@ -698,6 +711,13 @@ class EthCtx:
         obj[f] = val[f].fld_obj_repr(self)
       else:
         obj[f] = str(val[f])
+    if (obj['_class'] == 'TYPE-IDENTIFIER') or (obj['_class'] == 'ABSTRACT-SYNTAX'):
+      set_type_fn(obj['_class'], '&Type', '_type')
+    if (obj['_class'] == 'OPERATION'):
+      set_type_fn(obj['_class'], '&ArgumentType', '_argument')
+      set_type_fn(obj['_class'], '&ResultType', '_result')
+    if (obj['_class'] == 'ERROR'):
+      set_type_fn(obj['_class'], '&ParameterType', '_parameter')
     return obj
 
   #--- eth_reg_module -----------------------------------------------------------
@@ -754,7 +774,10 @@ class EthCtx:
     ident = oassign.ident
     #print "eth_reg_oassign(ident='%s')" % (ident)
     if self.oassign.has_key(ident):
-      raise "Duplicate information object assignment for " + ident
+      if self.oassign[ident] == oassign:
+        return  # OK - already defined
+      else:
+        raise "Duplicate information object assignment for " + ident
     self.oassign[ident] = oassign
     self.oassign_ord.append(ident)
     self.oassign_cls.setdefault(oassign.cls, []).append(ident)
@@ -870,6 +893,9 @@ class EthCtx:
                                    'STRINGS' : val.eth_strings(), 'BITMASK' : '0' }
     self.type[ident]['attr'].update(self.conform.use_item('TYPE_ATTR', ident))
     self.type_ord.append(ident)
+    # PDU
+    if (self.conform.check_item('PDU', ident)):
+      self.eth_reg_field(ident, ident, impl=val.HasImplicitTag(self), pdu=self.conform.use_item('PDU', ident))
 
   #--- eth_reg_objectclass ----------------------------------------------------------
   def eth_reg_objectclass(self, ident, val):
@@ -915,7 +941,10 @@ class EthCtx:
   def eth_reg_field(self, ident, type, idx='', parent=None, impl=False, pdu=None):
     #print "eth_reg_field(ident='%s', type='%s')" % (ident, type)
     if self.field.has_key(ident):
-      raise "Duplicate field for " + ident
+      if pdu and (type == self.field[ident]['type']):
+        pass  # OK already created PDU
+      else:
+        raise "Duplicate field for " + ident
     self.field[ident] = {'type' : type, 'idx' : idx, 'impl' : impl, 'pdu' : pdu,
                          'modified' : '', 'attr' : {} , 'create_field' : False }
     name = ident.split('/')[-1]
@@ -1162,6 +1191,8 @@ class EthCtx:
       nm = asn2c(nm)
       if (self.field[f]['pdu']): 
         nm += '_PDU'
+        if (not self.merge_modules):
+          nm = self.eproto + '_' + nm
       t = self.field[f]['type']
       if self.type.has_key(t):
         ethtype = self.type[t]['ethname']
@@ -1197,7 +1228,7 @@ class EthCtx:
         self.eth_hfpdu_ord.append(nm)
       else:
         self.eth_hf_ord.append(nm)
-      fullname = "hf_%s_%s" % (self.eproto, nm)
+      fullname = 'hf_%s_%s' % (self.eproto, nm)
       attr = self.eth_get_type_attr(self.field[f]['type']).copy()
       attr.update(self.field[f]['attr'])
       if (self.NAPI() and attr.has_key('NAME')):
@@ -1700,7 +1731,11 @@ class EthCtx:
       fx.write('/*--- PDUs ---*/\n\n')
       for f in self.eth_hfpdu_ord:
         if (self.eth_hf[f]['pdu']):
-          fx.write(out_pdu(f))
+          if (self.emitted_pdu.has_key(f)):
+            fx.write("  /* %s already emitted */\n" % (f))
+          else:
+            fx.write(out_pdu(f))
+            self.emitted_pdu[f] = True
       fx.write('\n')
     fempty = pos == fx.tell()
     self.output.file_close(fx, discard=fempty)
@@ -2670,7 +2705,9 @@ class EthOut:
       fx.write('\n')
       mstr = "--- "
       if self.ectx.groups():
-        mstr += "Modules"
+        mstr += "Module"
+        if (len(self.ectx.modules) > 1):
+          mstr += "s"
         for (m, p) in self.ectx.modules:
           mstr += " %s" % (m)
       else:
@@ -2823,9 +2860,46 @@ class ObjectAssignment (Node):
   def __init__(self,*args, **kw) :
     Node.__init__ (self,*args, **kw)
 
+  def __eq__(self, other):
+    if self.cls != other.cls:
+      return False
+    if len(self.val) != len(other.val):
+      return False
+    for f in (self.val.keys()):
+      if not other.val.has_key(f):
+        return False
+      if isinstance(self.val[f], Node) and isinstance(other.val[f], Node):
+        if not self.val[f].fld_obj_eq(other.val[f]):
+          return False
+      else:
+        if str(self.val[f]) != str(other.val[f]):
+          return False
+    return True
+
   def eth_reg(self, ident, ectx):
+    def make_virtual_type(cls, field, prefix):
+      if isinstance(self.val, str): return
+      if self.val.has_key(field) and not isinstance(self.val[field], Type_Ref):
+        vnm = prefix + '-' + self.ident
+        virtual_tr = Type_Ref(val = vnm)
+        t = self.val[field]
+        self.val[field] = virtual_tr
+        ectx.eth_reg_assign(vnm, t, virt=True)
+        ectx.eth_reg_type(vnm, t)
+        t.eth_reg_sub(vnm, ectx)
+      if self.val.has_key(field) and ectx.conform.check_item('PDU', cls + '.' + field):
+        ectx.eth_reg_field(self.val[field].val, self.val[field].val, impl=self.val[field].HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', cls + '.' + field))
+      return
+    # end of make_virtual_type()
     if ectx.conform.omit_assignment('V', self.ident, ectx.Module()): return # Assignment to omit
     ectx.eth_reg_oassign(self)
+    if (self.cls == 'TYPE-IDENTIFIER') or (self.cls == 'ABSTRACT-SYNTAX'):
+      make_virtual_type(self.cls, '&Type', 'TYPE')
+    if (self.cls == 'OPERATION'):
+      make_virtual_type(self.cls, '&ArgumentType', 'ARG')
+      make_virtual_type(self.cls, '&ResultType', 'RES')
+    if (self.cls == 'ERROR'):
+      make_virtual_type(self.cls, '&ParameterType', 'PAR')
 
 
 #--- Type ---------------------------------------------------------------------
@@ -2930,6 +3004,9 @@ class Type (Node):
     print "#Selection '%s' required for non-CHOICE type %s" % (sel, self.type)
     print self.str_depth(1)
     
+  def fld_obj_eq(self, other):
+    return isinstance(other, Type) and (self.eth_tname() == other.eth_tname())
+
   def eth_reg(self, ident, ectx, tstrip=0, tagflag=False, selflag=False, idx='', parent=None):
     #print "eth_reg(): %s, ident=%s, tstrip=%d, tagflag=%s, selflag=%s, parent=%s" %(self.type, ident, tstrip, str(tagflag), str(selflag), str(parent))
     if (ectx.Tag() and (len(self.tags) > tstrip)):
@@ -2952,8 +3029,6 @@ class Type (Node):
       ectx.eth_reg_assign(nm, self)
       if self.type == 'Type_Ref':
         ectx.eth_reg_type(nm, self)
-      if (ectx.conform.check_item('PDU', nm)):
-        ectx.eth_reg_field(nm, nm, impl=self.HasImplicitTag(ectx), pdu=ectx.conform.use_item('PDU', nm))
     virtual_tr = Type_Ref(val=ectx.conform.use_item('SET_TYPE', nm))
     if (self.type == 'Type_Ref') or ectx.conform.check_item('SET_TYPE', nm):
       if ident and (ectx.conform.check_item('TYPE_RENAME', nm) or ectx.conform.get_fn_presence(nm) or selflag):
@@ -3059,8 +3134,10 @@ class Type (Node):
     }
     if (ectx.eth_type[tname]['tree']):
       pars['ETT_INDEX'] = ectx.eth_type[tname]['tree']
-    if (not ectx.Per()):
-      pars['PINFO'] = 'pinfo'
+    if (ectx.merge_modules):
+      pars['PROTOP'] = ''
+    else:
+      pars['PROTOP'] = ectx.eth_type[tname]['proto'] + '_'
     return pars
 
   def eth_type_fn(self, proto, tname, ectx):
@@ -3072,7 +3149,11 @@ class Type (Node):
       pars.update(ectx.conform.use_item('FN_PARS', ectx.eth_type[tname]['ref'][0]))
     pars['DEFAULT_BODY'] = body
     for i in range(4):
-      for k in pars.keys(): pars[k] = pars[k] % pars
+      for k in pars.keys(): 
+        try:
+          pars[k] = pars[k] % pars
+        except (TypeError):
+          raise sys.exc_type, "%s\n%s" % (str(pars), sys.exc_value)
     out = '\n'
     out += self.eth_type_default_table(ectx, tname) % pars
     out += ectx.eth_type_fn_hdr(tname)
@@ -3098,6 +3179,11 @@ class Value (Node):
   def fld_obj_repr(self, ectx):
     return self.to_str(ectx)
 
+#--- Value_Ref -----------------------------------------------------------------
+class Value_Ref (Value):
+  def to_str(self, ectx):
+    return asn2c(self.val)
+
 #--- ObjectClass ---------------------------------------------------------------------
 class ObjectClass (Node):
   def __init__(self,*args, **kw) :
@@ -3274,7 +3360,7 @@ class Constraint (Node):
 
   def IsNegativ(self):
     def is_neg(sval):
-      return sval[0] == '-'
+      return isinstance(sval, str) and (sval[0] == '-')
     if self.type == 'SingleValue':
       return is_neg(self.subtype)
     elif self.type == 'ValueRange':
@@ -3284,6 +3370,8 @@ class Constraint (Node):
 
   def eth_constrname(self):
     def int2str(val):
+      if isinstance(val, Value_Ref):
+        return asn2c(val.val)
       try:
         if (int(val) < 0):
           return 'M' + str(-int(val))
@@ -3346,10 +3434,13 @@ class Module_Body (Node):
       for s in i.symbol_list:
         if isinstance(s, Type_Ref):
           ectx.eth_import_type(s.val, mod, proto)
+        elif isinstance(s, Value_Ref):
+          ectx.eth_import_value(s.val, mod, proto)
         elif isinstance(s, Class_Ref):
           ectx.eth_import_class(s.val, mod, proto)
         else:
-          ectx.eth_import_value(s, mod, proto)
+          msg = 'Unknown kind of imported symbol %s from %s' % (str(s), mod)
+          warnings.warn_explicit(msg, UserWarning, '', '')
     # AssignmentList
     for a in self.assign_list:
       a.eth_reg('', ectx)
@@ -3411,6 +3502,9 @@ class Type_Ref (Type):
   def eth_tname(self):
     return asn2c(self.val)
 
+  def fld_obj_repr(self, ectx):
+    return self.val
+
   def get_components(self, ectx):
     if not ectx.type.has_key(self.val) or ectx.type[self.val]['import']:
       msg = "Can not get COMPONENTS OF %s which is imported type" % (self.val)
@@ -3440,7 +3534,10 @@ class Type_Ref (Type):
       return ectx.type[self.val]['val'].IndetermTag(ectx)
 
   def eth_type_default_pars(self, ectx, tname):
-    pars = Type.eth_type_default_pars(self, ectx, tname)
+    if tname:
+      pars = Type.eth_type_default_pars(self, ectx, tname)
+    else:
+      pars = {}
     t = ectx.type[self.val]['ethname']
     pars['TYPE_REF_PROTO'] = ectx.eth_type[t]['proto']
     pars['TYPE_REF_TNAME'] = t
@@ -3739,7 +3836,7 @@ class SequenceOfType (SeqOfType):
   def eth_type_default_pars(self, ectx, tname):
     pars = Type.eth_type_default_pars(self, ectx, tname)
     (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
-    pars['TABLE'] = '%(TNAME)s_sequence_of'
+    pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence_of'
     return pars
 
   def eth_type_default_body(self, ectx, tname):
@@ -3796,7 +3893,7 @@ class SetOfType (SeqOfType):
   def eth_type_default_pars(self, ectx, tname):
     pars = Type.eth_type_default_pars(self, ectx, tname)
     (pars['MIN_VAL'], pars['MAX_VAL'], pars['EXT']) = self.eth_get_size_constr(ectx)
-    pars['TABLE'] = '%(TNAME)s_set_of'
+    pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set_of'
     return pars
 
   def eth_type_default_body(self, ectx, tname):
@@ -3901,7 +3998,7 @@ class SequenceType (SeqType):
 
   def eth_type_default_pars(self, ectx, tname):
     pars = Type.eth_type_default_pars(self, ectx, tname)
-    pars['TABLE'] = '%(TNAME)s_sequence'
+    pars['TABLE'] = '%(PROTOP)s%(TNAME)s_sequence'
     return pars
 
   def eth_type_default_body(self, ectx, tname):
@@ -3946,7 +4043,7 @@ class SetType(SeqType):
 
   def eth_type_default_pars(self, ectx, tname):
     pars = Type.eth_type_default_pars(self, ectx, tname)
-    pars['TABLE'] = '%(TNAME)s_set'
+    pars['TABLE'] = '%(PROTOP)s%(TNAME)s_set'
     return pars
 
   def eth_type_default_body(self, ectx, tname):
@@ -4122,7 +4219,7 @@ class ChoiceType (Type):
 
   def eth_type_default_pars(self, ectx, tname):
     pars = Type.eth_type_default_pars(self, ectx, tname)
-    pars['TABLE'] = '%(TNAME)s_choice'
+    pars['TABLE'] = '%(PROTOP)s%(TNAME)s_choice'
     return pars
 
   def eth_type_default_table(self, ectx, tname):
@@ -4234,6 +4331,9 @@ class ChoiceValue (Value):
   def to_str(self, ectx):
     return self.val.to_str(ectx)
 
+  def fld_obj_eq(self, other):
+    return isinstance(other, ChoiceValue) and (self.choice == other.choice) and (str(self.val.val) == str(other.val.val))
+
 #--- EnumeratedType -----------------------------------------------------------
 class EnumeratedType (Type):
   def to_python (self, ctx):
@@ -4329,7 +4429,7 @@ class EnumeratedType (Type):
     pars['EXT'] = ext
     pars['EXT_NUM'] = str(ext_num)
     if (map_table):
-      pars['TABLE'] = '%(TNAME)s_value_map'
+      pars['TABLE'] = '%(PROTOP)s%(TNAME)s_value_map'
     else:
       pars['TABLE'] = 'NULL'
     return pars
@@ -5034,7 +5134,7 @@ class BitStringType (Type):
       pars['ETT_INDEX'] = '-1'
     pars['TABLE'] = 'NULL'
     if self.eth_named_bits():
-      pars['TABLE'] = '%(TNAME)s_bits'
+      pars['TABLE'] = '%(PROTOP)s%(TNAME)s_bits'
     if self.HasContentsConstraint():
       pars['FN_VARIANT'] = ectx.default_containing_variant
       t = self.constr.GetContents(ectx)
@@ -5109,6 +5209,12 @@ class BStringValue (Value):
       vv += bstring_tab[v[i:i+4]]
     return vv
 
+#--- HStringValue ------------------------------------------------------------
+class HStringValue (Value):
+  def to_str(self, ectx):
+    vv = '0x'
+    vv += self.val[1:-2]
+    return vv
 
 #--- FieldSpec ----------------------------------------------------------------
 class FieldSpec (Node):
@@ -5179,7 +5285,7 @@ def p_identifier (t):
 # 11.4 Value references
 def p_valuereference (t):
   'valuereference : LCASE_IDENT'
-  t[0] = t[1]
+  t[0] = Value_Ref(val=t[1])
 
 # 11.5 Module references
 def p_modulereference (t):
@@ -5295,7 +5401,7 @@ def p_SymbolsFromModule (t):
   'SymbolsFromModule : SymbolList FROM GlobalModuleReference'
   t[0] = Node ('SymbolList', symbol_list = t[1], module = t[3])
   for s in (t[0].symbol_list): 
-    if (isinstance(s, str) and s[0].islower()): lcase_ident_assigned[s] = t[3]
+    if (isinstance(s, Value_Ref)): lcase_ident_assigned[s.val] = t[3]
   if t[0].module.val == 'Remote-Operations-Information-Objects':
     for i in range(len(t[0].symbol_list)):
       s = t[0].symbol_list[i]
@@ -5333,13 +5439,16 @@ def p_Symbol (t):
             | ParameterizedReference'''
   t[0] = t[1]
 
-def p_Reference (t):
+def p_Reference_1 (t):
   '''Reference : type_ref
                | valuereference
-               | objectclassreference
-               | LCASE_IDENT_ASSIGNED'''
+               | objectclassreference '''
   t[0] = t[1]
 
+def p_Reference_2 (t):
+  '''Reference : LCASE_IDENT_ASSIGNED'''
+  t[0] = Value_Ref (val=t[1])
+
 def p_AssignmentList_1 (t):
   'AssignmentList : AssignmentList Assignment'
   t[0] = t[1] + [t[2]]
@@ -5375,7 +5484,7 @@ def p_DefinedType (t):
 
 def p_DefinedValue(t):
   '''DefinedValue : ExternalValueReference
-                  | identifier'''
+                  | valuereference'''
   t[0] = t[1]
 
 # 13.6
@@ -5398,7 +5507,7 @@ def p_TypeAssignment (t):
 
 # 15.2
 def p_ValueAssignment (t):
-  'ValueAssignment : valuereference ValueType ASSIGNMENT Value'
+  'ValueAssignment : LCASE_IDENT ValueType ASSIGNMENT Value'
   t[0] = ValueAssignment(ident = t[1], typ = t[2], val = t[4])
 
 # only "simple" types are supported to simplify grammer
@@ -6363,12 +6472,12 @@ def p_ExceptionIdentification (t):
 
 
 def p_binary_string (t):
-    'binary_string : BSTRING'
-    t[0] = BStringValue(val = t[1])
+  'binary_string : BSTRING'
+  t[0] = BStringValue(val = t[1])
 
 def p_hex_string (t):
-    'hex_string : HSTRING'
-    t[0] = t[1]
+  'hex_string : HSTRING'
+  t[0] = HStringValue(val = t[1])
 
 def p_char_string (t):
     'char_string : QSTRING'
@@ -6607,7 +6716,8 @@ def p_lbraceobject(t):
 def p_braceobjectbegin(t):
   'braceobjectbegin : '
   global lexer
-  if set_x880_syntax(obj_class):
+  global obj_class
+  if set_class_syntax(obj_class):
     state = 'INITIAL'
   else:
     lexer.level = 1
@@ -6622,27 +6732,37 @@ def p_braceobjectend(t):
   'braceobjectend : '
   global lexer
   lexer.pop_state()
-  set_x880_syntax(None)
+  set_class_syntax(None)
 
 def p_bodyobject_1 (t):
   'bodyobject : '
   t[0] = { }
 
 def p_bodyobject_2 (t):
-  'bodyobject : x880_syntax_list'
+  'bodyobject : cls_syntax_list'
   t[0] = t[1]
 
-def p_x880_syntax_list_1 (t):
-  'x880_syntax_list : x880_syntax_list x880_syntax'
+def p_cls_syntax_list_1 (t):
+  'cls_syntax_list : cls_syntax_list cls_syntax'
   t[0] = t[1]
   t[0].update(t[2])
 
-def p_x880_syntax_list_2 (t):
-  'x880_syntax_list : x880_syntax'
+def p_cls_syntax_list_2 (t):
+  'cls_syntax_list : cls_syntax'
   t[0] = t[1]
 
-def p_x880_syntax_1 (t):
-  '''x880_syntax : ERRORS ObjectSet
+# X.681
+def p_cls_syntax_1 (t):
+  'cls_syntax : Type IDENTIFIED BY Value'
+  t[0] = { get_class_fieled(' ') : t[1], get_class_fieled(' '.join((t[2], t[3]))) : t[4] }
+
+def p_cls_syntax_2 (t):
+  'cls_syntax : HAS PROPERTY Value'
+  t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
+
+# X.880
+def p_cls_syntax_3 (t):
+  '''cls_syntax : ERRORS ObjectSet
                  | LINKED ObjectSet
                  | RETURN RESULT BooleanValue 
                  | SYNCHRONOUS BooleanValue
@@ -6651,20 +6771,20 @@ def p_x880_syntax_1 (t):
                  | PRIORITY Value 
                  | ALWAYS RESPONDS BooleanValue
                  | IDEMPOTENT BooleanValue '''
-  t[0] = { get_x880_fieled(' '.join(t[1:-1])) : t[-1:][0] }
+  t[0] = { get_class_fieled(' '.join(t[1:-1])) : t[-1:][0] }
 
-def p_x880_syntax_2 (t):
-  '''x880_syntax : ARGUMENT Type
+def p_cls_syntax_4 (t):
+  '''cls_syntax : ARGUMENT Type
                  | RESULT Type
                  | PARAMETER Type
                  | CODE Value '''
-  t[0] = { get_x880_fieled(t[1]) : t[2] }
+  t[0] = { get_class_fieled(t[1]) : t[2] }
 
-def p_x880_syntax_3 (t):
-  '''x880_syntax : ARGUMENT Type OPTIONAL BooleanValue
+def p_cls_syntax_5 (t):
+  '''cls_syntax : ARGUMENT Type OPTIONAL BooleanValue
                  | RESULT Type OPTIONAL BooleanValue
                  | PARAMETER Type OPTIONAL BooleanValue '''
-  t[0] = { get_x880_fieled(t[1]) : t[2], get_x880_fieled(' '.join((t[1], t[3]))) : t[4] }
+  t[0] = { get_class_fieled(t[1]) : t[2], get_class_fieled(' '.join((t[1], t[3]))) : t[4] }
 
 # 12 Information object set definition and assignment
 
@@ -6740,6 +6860,71 @@ class_types_creator = {
 
 class_names = { }
 
+x681_syntaxes = {
+  'TYPE-IDENTIFIER' : {
+    ' '             : '&Type',
+    'IDENTIFIED'    : 'IDENTIFIED',
+    #'BY'            : 'BY',         
+    'IDENTIFIED BY' : '&id',         
+  },
+  'ABSTRACT-SYNTAX' : {
+    ' '             : '&Type',
+    'IDENTIFIED'    : 'IDENTIFIED',
+    #'BY'            : 'BY',         
+    'IDENTIFIED BY' : '&id',         
+    'HAS'           : 'HAS',
+    'PROPERTY'      : 'PROPERTY',         
+    'HAS PROPERTY'  : '&property',         
+  },
+}
+
+class_syntaxes_enabled = { 
+  'TYPE-IDENTIFIER' : True,
+  'ABSTRACT-SYNTAX' : True,
+}
+
+class_syntaxes = {
+  'TYPE-IDENTIFIER' : x681_syntaxes['TYPE-IDENTIFIER'],
+  'ABSTRACT-SYNTAX' : x681_syntaxes['ABSTRACT-SYNTAX'],
+}
+
+class_current_syntax = None
+
+def get_syntax_tokens(syntaxes):
+  tokens = { }
+  for s in (syntaxes):
+    for k in (syntaxes[s].keys()):
+      if k.find(' ') < 0:
+        tokens[k] = k
+        tokens[k] = tokens[k].replace('-', '_')
+  return tokens.values()
+
+tokens = tokens + get_syntax_tokens(x681_syntaxes)
+
+def set_class_syntax(syntax):
+  global class_syntaxes_enabled
+  global class_current_syntax
+  #print "set_class_syntax", syntax, class_current_syntax
+  if class_syntaxes_enabled.get(syntax, False):
+    class_current_syntax = syntax
+    return True
+  else:
+    class_current_syntax = None
+    return False
+
+def is_class_syntax(name):
+  global class_syntaxes
+  global class_current_syntax
+  #print "is_class_syntax", name, class_current_syntax
+  if not class_current_syntax:
+    return False
+  return class_syntaxes[class_current_syntax].has_key(name)
+
+def get_class_fieled(name):
+  if not class_current_syntax:
+    return None
+  return class_syntaxes[class_current_syntax][name]
+
 def is_class_ident(name):
   return class_names.has_key(name)
 
@@ -6842,7 +7027,7 @@ def p_UserDefinedConstraintParameterList_3 (t):
 
 # 9.3
 def p_UserDefinedConstraintParameter (t):
-  'UserDefinedConstraintParameter : type_ref'
+  'UserDefinedConstraintParameter : Type'
   t[0] = t[1]
 
 # 10 Table constraints, including component relation constraints --------------
@@ -6920,14 +7105,14 @@ def p_ParameterizedTypeAssignment (t):
   t[0].SetName(t[1])  # t[0].SetName(t[1] + 'xxx')
 
 def p_ParameterizedObjectAssignment (t):
-  'ParameterizedObjectAssignment : objectreference ParameterList CLASS_IDENT ASSIGNMENT Object'
-  t[0] = ObjectAssignment (ident = t[1], cls=t[3], val=t[5])
+  'ParameterizedObjectAssignment : objectreference ParameterList DefinedObjectClass ASSIGNMENT Object'
+  t[0] = ObjectAssignment (ident = t[1], cls=t[3].val, val=t[5])
   global obj_class
   obj_class = None
 
 def p_ParameterizedObjectSetAssignment (t):
-  'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList CLASS_IDENT ASSIGNMENT ObjectSet'
-  t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3], val=t[5])
+  'ParameterizedObjectSetAssignment : UCASE_IDENT ParameterList DefinedObjectClass ASSIGNMENT ObjectSet'
+  t[0] = Node('ObjectSetAssignment', name=t[1], cls=t[3].val, val=t[5])
 
 # 8.3
 def p_ParameterList (t):
@@ -7067,52 +7252,16 @@ x880_syntaxes = {
 #  },
 }
 
-x880_syntaxes_enabled = { }
-x880_current_syntax = None
-
 def x880_import(name):
   if x880_syntaxes.has_key(name):
-    x880_syntaxes_enabled[name] = True
+    class_syntaxes_enabled[name] = True
+    class_syntaxes[name] = x880_syntaxes[name]
   if x880_classes.has_key(name):
     add_class_ident(name)
     for f in (x880_classes[name].keys()):
       set_type_to_class(name, f, x880_classes[name][f])
 
-def set_x880_syntax(syntax):
-  global x880_syntaxes_enabled
-  global x880_current_syntax
-  #print "set_x880_syntax", syntax, x880_current_syntax
-  if x880_syntaxes_enabled.get(syntax, False):
-    x880_current_syntax = syntax
-    return True
-  else:
-    x880_current_syntax = None
-    return False
-
-def is_x880_syntax(name):
-  global x880_syntaxes
-  global x880_current_syntax
-  #print "is_x880_syntax", name, x880_current_syntax
-  if not x880_current_syntax:
-    return False
-  return x880_syntaxes[x880_current_syntax].has_key(name)
-
-def get_x880_fieled(name):
-  if not x880_current_syntax:
-    return None
-  return x880_syntaxes[x880_current_syntax][name]
-
-def get_x880_tokens():
-  global x880_syntaxes
-  tokens = { }
-  for s in (x880_syntaxes):
-    for k in (x880_syntaxes[s].keys()):
-      if k.find(' ') < 0:
-        tokens[k] = k
-        tokens[k] = tokens[k].replace('-', '_')
-  return tokens.values()
-
-tokens = tokens + get_x880_tokens()
+tokens = tokens + get_syntax_tokens(x880_syntaxes)
 
 #  {...} OID value
 #def p_lbrace_oid(t):