def add_exc(self, exc): name = exc.get_name() if exc.get_dtype_kind() != DataTypeKind.EXC: raise ParserInternalException("Type {} is not an exception".format(name)) if name in self._excs: raise ParserInternalException("Exception {} is already listed".format(name)) self._excs[name] = exc
def get_id(self): tok = self._get_tok() if not re.match(IDENTIFIER_RE, tok): raise ParserInternalException("Valid identifier name expected") if tok.startswith(RESERVED_PREFIXES): raise ParserInternalException( "Identifier begins with reserved string ({})".format( ", ".join(RESERVED_PREFIXES))) return tok
def add_field(self, field): fid = field.get_fid() if fid == _FID_STOP: raise ParserInternalException("Fid {} is reserved".format(fid)) if fid in self._fids: raise ParserInternalException("Fid {} is already defined".format(fid)) dtype = field.get_dtype() dtype.check_container_compat() name = field.get_name() if name in self._names: raise ParserInternalException("Field {} is already defined".format(name)) self._fields.append(field) self._fids[fid] = field self._names[name] = field
def _parse(self): try: f = open(self._filename, mode="rt", encoding=ENCODING) lines = f.readlines() f.close() except OSError as e: raise ParserInternalException(e) # Process IDL file. for line in lines: # Increase line number counter. self._lineno += 1 # Remove comments and skip empty lines. i = line.find("#") if i >= 0: line = line[:i] line = line.strip() if len(line) == 0: continue # Lookup and execute keyword func. self._tok = Tokenizer(self._tm, line) kws = self._kws[self._get_context()] kw = self._tok.get_kw() try: func = kws[kw] except KeyError: raise ParserInternalException("Unknown keyword {}".format(kw)) func() self._tok.eol() # At EOF, context has to be MAIN. if self._get_context() != ParserContext.MAIN: raise ParserInternalException("Unterminated context")
def _main_namespace(self): gen_name = self._tok.get_gen_name() namespace = self._tok.get_ns() if gen_name in self._namespaces: raise ParserInternalException( "Namespace for {} is already defined".format(gen_name)) self._namespaces[gen_name] = namespace
def get_dtype(self): tok = self._get_tok() try: dtype = self._tm.lookup_dtype(tok) except KeyError: raise ParserInternalException("Type {} doesn't exist".format(tok)) return dtype
def get_gen_name(self): tok = self._get_tok() try: GeneratorBase.lookup_gen(tok) except KeyError: raise ParserInternalException( "Generator {} is unknown".format(tok)) return tok
def _main_beginmethod(self): name = self._tok.get_id() if name in self._methods: raise ParserInternalException( "Method {} is already defined".format(name)) self._curr_method = Method(name) self._methods[name] = self._curr_method self._set_context(ParserContext.METHOD)
def _get_tok(self, req=True): if self._pos == len(self._toks): if req: raise ParserInternalException("Token expected") else: return None tok = self._toks[self._pos] self._pos += 1 return tok
def get_i32(self, req=True): int_min = -2147483648 int_max = 2147483647 try: i = self._get_int(int_min, int_max, req=req) except ValueError: raise ParserInternalException( "Integer expected ({} ... {})".format(int_min, int_max)) return i
def get_req(self): tok = self._get_tok() if tok == "required": r = True elif tok == "optional": r = False else: raise ParserInternalException("required/optional expected") return r
def get_fid(self): fid_min = 0 fid_max = 0xffff try: fid = self._get_int(fid_min, fid_max) except ValueError: raise ParserInternalException( "Field identifier must be numeric ({} ... {})".format( fid_min, fid_max)) return fid
def set_out(self, req, dtype): if self._out_req != None: raise ParserInternalException("Method return value is already specified") self._out_req = req self._out_dtype = dtype
def _check_dtype_name(self, name): if self._tm.has_dtype(name): raise ParserInternalException( "Type {} is already defined".format(name))
def check_container_compat(self): if not self._container_compat: raise ParserInternalException("Type {} can't be used in containers".format(self._name))
def add_entry(self, name, value): if name in self._entries: raise ParserInternalException("{} is already specified in enum".format(name)) self._entries[name] = value
def eol(self): if self._pos < len(self._toks): raise ParserInternalException("End of line expected")