def parse(self): print "parse:", self.fd.fileName with open(self.fd.fullPath, "r") as f: self.lexer = PLexer.PLexer(f.read(), self.fd.fileName) tokenHandler = { ';': self.parseEmpty, } token = self.nextToken() while token is not None: handler = None if is_keyword_token(token) or token in (PLexer.T_ATTRIBUTE, ): funName = "parse_" + token2str(token) handler = getattr(self, funName, None) if handler is None: handler = tokenHandler.get(token) if handler is None: self.error("Parser", "invalid token '%s'" % token2str(token)) handler(self.fd) token = self.nextToken() self.lexer = None
def matchToken(self, given, expected, desc): ok = is_expected_token(given, expected) if ok: return tokeName = None if isinstance(expected, int): tokeName = token2str(expected) else: names = [token2str(tk) for tk in expected] tokeName = "|".join(names) self.error( desc, "token '%s' expected, but '%s' was given." % (tokeName, token2str(given))) return
def matchIdentity(self, token, desc): if not is_identity_token(token): self.error( desc, "identity expected, but '%s' was given" % token2str(token)) return
def parse_message(self, parent=None, extend=False): desc = "message" attributes = self.lastAttributes self.lastAttributes = [] name = self._parseFullIdentity(desc) cls = None if extend: cls = parent.findType(name) if cls is None: if parent.isTypeExist(name): self.error(desc, "type '%s' has been exist." % name) cls = PCodes.ClassDescriptor(name, parent) parent.addType(cls) self.matchNext('{', desc) token = self.nextToken() while token != None and token != '}': if token == ';': pass elif token == PLexer.T_MESSAGE: self.parse_message(parent=cls) elif token == PLexer.T_ENUM: self.parse_enum(parent=cls) elif token == PLexer.T_OPTION: self.parse_option(cls) elif token in VALID_QUALIFIER_TOKENS: self._parseMessageVarField(cls, desc) elif token == PLexer.T_MAP: self._parseMessageMapField(cls, desc) elif token == PLexer.T_EXTENSIONS: self._parseExtensions(cls) elif token == PLexer.T_RESERVED: self._parseReserved(cls) elif token == PLexer.T_EXTEND: self.parse_extend(parent=cls) else: self.error(desc, "invalid token '%s'" % token2str(token)) token = self.nextToken() self.matchToken(token, '}', desc) self.lastAttributes = [] cls.setAttributes(attributes)
def parse_attribute(self, parent=None): desc = "attribute" attr = PCodes.Attribute(self.module.allocateAttrID()) self.matchNext('[', desc) token = self.nextToken() while token != ']': if token not in VALID_VALUE_TOKENS: self.error(desc, "invalid token '%s'" % token2str(token)) value = self.tokenInfo.value token = self.nextToken() if token == '=': # `key = value` token = self.nextToken() if token not in VALID_VALUE_TOKENS: self.error(desc, "invalid token '%s'" % token2str(token)) value2 = self.tokenInfo.value attr.addPairValue(value, value2) token = self.nextToken() else: # `value, ` attr.addSingleValue(value) if token == ']': break elif token == ',': token = self.nextToken() else: self.error( desc, "token ',' was expected, but '%s' was given" % token2str(token)) # print attr.attributes self.lastAttributes.append(attr)
def _parseMessageVarField(self, cls, desc): token = self.tokenInfo.token varQualifier = token2str(token) varType = self._parseFullIdentity(desc) varTemplateArgs = None varName = self._parseIdentity(desc) self.matchNext('=', desc) self.matchNext(PLexer.T_NUMBER, desc) varOrder = self.tokenInfo.value token = self.lookAhead() if token == '[': self._parseFiledOption(desc) self.matchNext(';', desc) cls.addMember(varOrder, varQualifier, varName, varType, varTemplateArgs)
def _parseRange(self, parent, desc): while True: self.matchNext(PLexer.T_NUMBER, desc) litMin = self.tokenInfo.value litMax = None token = self.nextToken() if token == PLexer.T_TO: token = self.nextToken() if token == PLexer.T_NUMBER: litMax = self.tokenInfo.value elif token == PLexer.T_IDENTITY and self.tokenInfo.value == "max": pass else: self.error(desc, "invalid token '%s'" % token2str(token)) token = self.nextToken() if token == ';': break self.matchToken(token, ',', desc) return