def expect_enum(self, parent, line, indent, step): # we know the line begins with INDENT + 'enum'. This # should be followed by the enum's name, and then a sequence # of pairs at a deeper indent from_ = len(indent) + len('enum') string = line[from_:] # s should begin with one or more spaces, followed by one # simple name if string[0] != ' ': raise ParserError("can't find enum name in '%s'" % line) name = string.strip() validate_simple_name(name) pairs = [] line = self.get_line() # we require at least one pair pair = self.accept_enum_pair(line, indent + step, step) if pair is None: raise ParserError("expected enum pair, found '%s'" % line) pairs.append(pair) # we have one pair, let's see if there are any more line = self.get_line() pair = self.accept_enum_pair(line, indent + step, step) while pair is not None: pairs.append(pair) line = self.get_line() pair = self.accept_enum_pair(line, indent + step, step) e_spec = EnumSpec(name, pairs) # XXX we need to verify that the enum's name is not already # in us; simplest thing to do is to have addEnum() verify # this, parent.add_enum(e_spec) # parent is ProtoSpec or MsgSpec print("DEBUG expectEnum: adding %s to parent registry" % e_spec.name) parent.reg.add_enum(e_spec) return line
def expect_msg_spec_name(self, line, indent='', step=' '): """ on a line beginning 'message ' """ starter = indent + 'message ' if not line or not line.startswith(starter): raise ParserError("badly formatted message name line '%s'" % line) line = line[len(starter):] words = line.split() self.expect_token_count(words, 'message name', 1) name = words[0] if name[-1] == ':': name = name[:-1] validate_simple_name(name) # print "DEBUG: msgSpec name is '%s'" % str(name) return name
def expect_field(self, msg_spec, line, indent, step): if not line.startswith(indent): raise ParserError( "wrong indent for field declaration: '%s'" % line) # DEBUG print("expectField: line = '%s'" % line) # END line = line[len(indent):] # from here we are very sloppy about the indent # accept NAME FTYPE(Q)? (@N)? (=DEFAULT)? words = line.split() word_count = len(words) # DEBUG print(" found %d tokens: %s" % (word_count, words)) # END if word_count < 2: raise ParserError("too few tokens in field def '%s'" % line) if word_count > 5: raise ParserError("too many tokens in field def '%s'" % line) # -- field name ------------------------- f_name = words[0] validate_simple_name(f_name) # -- quantifier ------------------------- qqq = words[1][-1] if qqq == '?' or qqq == '*' or qqq == '+': words[1] = words[1][:-1] if qqq == '?': quantifier = Q_OPTIONAL elif qqq == '*': quantifier = Q_STAR else: quantifier = Q_PLUS else: quantifier = Q_REQUIRED # -- field type -------------------------- type_name = words[1] validate_dotted_name(type_name) field_type = None # DEBUG ### print(" field '%s' type '%s' quant %d" % ( f_name, type_name, quantifier)) # END ##### # first check against list of names of field types f_types = FieldStr() try: field_type = f_types.ndx(type_name) # DEBUG print( "LIST type_name is '%s', index is '%s'" % (type_name, field_type)) # END except KeyError: # DEBUG print("NOT IN LIST type_name '%s'" % type_name) # END field_type = None if field_type is None: # check at the message level field_type = msg_spec.reg.name2reg_id(type_name) # DEBUG print( "MSG type_name is '%s', index is '%s'" % (type_name, field_type)) # END if field_type is None: # ask the parent to resolve field_type = msg_spec.parent.reg.name2reg_id(type_name) # DEBUG print( "PARENT type_name is '%s', index is '%s'" % (type_name, field_type)) # END if field_type is None: err_msg = "type_name = '%s'; can't determine field type in line: '%s'" % ( type_name, line) raise ParserError(err_msg) # -- field number ----------------------- field_nbr = -1 if word_count > 2: if words[2].startswith('@'): field_nbr = int(words[2][1:]) # could use some validation # if fieldNbr < nextFieldNbr: # raise ValueError('field number <= last field number') # -- default ---------------------------- # XXX STUB - NOT IMPLEMENTED YET msg_spec.add_field( FieldSpec(msg_spec.reg, f_name, field_type, quantifier, field_nbr))