Ejemplo n.º 1
0
	def init(self, f):
		'''
		Init parser
		@param f: FILE or a string to init parser from
		@type f: FILE or a string
		@return: None
		@rtype: None
		'''
		self.token_list = SpecTokenList(f)
Ejemplo n.º 2
0
	def parse(cls, token_list, parent, allowed, ctx):
		'''
		Parse section from token list
		@param token_list: a token list to be used
		@type token_list: L{SpecTokenList}
		@param parent: parent section or None
		@type parent: L{SpecSection}
		@param allowed: allowed sections within the section
		@type allowed: list of L{SpecSection}
		@param ctx: parsing context
		@type ctx: L{SpecModelParser}
		@return: parsed section
		@rtype: L{SpecSection}
		'''
		ret = SpecExpressionParser.obj(parent)

		tokens = SpecTokenList()
		# let's assume, that the very first token is a part of an expression
		tokens.token_list_append(token_list.get())

		while True:
			tkn = token_list.touch()
			if str(tkn) == '>=' or str(tkn) == '<=' \
					or str(tkn) == '<' or str(tkn) == '>' \
					or str(tkn) == '!=' or str(tkn) == '==' \
					or str(tkn) == '&&' or str(tkn) == '||':
				tokens.token_list_append(token_list.get())
				if token_list.touch().is_eof():
					raise SpecBadToken("Unexpected EOF, expected expression termination")
				tokens.token_list_append(token_list.get())
				continue
			else:
				break

		ret.set_tokens(tokens)
		return ret
Ejemplo n.º 3
0
	def parse_entry(cls, token_list, parent, ctx):
		'''
		Parse a changelog entry
		@param token_list: a token list to be used
		@type token_list: L{SpecTokenList}
		@param parent: parent section or None
		@type parent: L{SpecSection}
		@param ctx: parsing context
		@type ctx: L{SpecModelParser}
		@return: parsed section
		@rtype: L{SpecSection}

		'''
		def parse_date(date):
			s = str(date[0]) + ' ' + str(date[1]) + ' ' + str(date[2]) + ' ' + str(date[3])
			return datetime.datetime.strptime(s, '%a %b %d %Y')

		def changelog_entry_beginning_callback(obj, token_list):
			# is there some section?
			if obj.section_beginning_callback(obj, token_list):
				# changelog message can consist of keyword like:
				# - Add missing Requires: golang(github.com/gorilla/mux) to devel
				tkn = token_list.touch()
				if not tkn.same_line(token_list[token_list.get_pointer() - 1]):
					return True

			# or is there another changelog entry?
			return str(token_list.touch()) == '*'

		entry = SpecChangelogParser.obj.SpecStChangelogEntry(parent)

		star = token_list.get()
		if str(star) != '*':
			token_list.unget()
			raise SpecBadToken("Expected token '*', got '%s'" % star)
		entry.set_star(star)

		date = SpecTokenList()
		for _ in xrange(0, 4):
			date.token_list_append(token_list.get())
		entry.set_date(date)

		date_parsed = parse_date(date)
		entry.set_date_parsed(date_parsed)

		user = SpecTokenList()
		while not str(token_list.touch()).startswith('<'):
			user.token_list_append(token_list.get())
		entry.set_user(user)

		user_email = token_list.get()
		entry.set_user_email(user_email)

		# version delim is optional here, if not stated, let's skip it
		if str(token_list.touch()) == '-':
			entry.set_version_delim(token_list.get())

		version = token_list.get()
		entry.set_version(version)

		entry.set_message(token_list.get_while_not(
									functools.partial(changelog_entry_beginning_callback, ctx)
									)
								)

		return entry
Ejemplo n.º 4
0
class SpecFileParser(SpecModelParser):
	'''
	A spec parser
	'''
	def __init__(self, writer):
		self.token_list = None
		self.set_model_writer(writer)
		self.MANIPULATORS = [
				SpecIfParser,
				SpecDefinitionParser,
				SpecGlobalParser,
				SpecDefineParser,
				SpecBuildParser,
				SpecChangelogParser,
				SpecCheckParser,
				SpecCleanParser,
				SpecDescriptionParser,
				SpecFilesParser,
				SpecInstallParser,
				SpecPackageParser,
				SpecPrepParser,
				SpecPreParser,
				SpecPostParser,
				SpecPreunParser,
				SpecPostunParser,
				SpecPretransParser,
				SpecPosttransParser,
				SpecTriggerParser,
				SpecTriggerinParser,
				SpecTriggerpreinParser,
				SpecTriggerunParser,
				SpecTriggerpostunParser,
				SpecVerifyscriptParser
			]

	def init(self, f):
		'''
		Init parser
		@param f: FILE or a string to init parser from
		@type f: FILE or a string
		@return: None
		@rtype: None
		'''
		self.token_list = SpecTokenList(f)

	@staticmethod
	def section_beginning_callback(obj, token_list):
		'''
		A callback for L{SpecTokenList} used to check whether next token is
		a section token
		@param obj: self instance
		@type obj: L{SpecModelParser} instance
		@param token_list: token list to be used
		@type token_list: L{SpecTokenList}
		@return: section parser to be used for parsing the upcoming section
		@rtype: L{SpecModelParser}
		'''
		return obj.section_beginning(token_list)

	def section_beginning(self, token_list):
		'''
		Check whether next token is a section token
		@param token_list: token list to be used
		@type token_list: L{SpecTokenList}
		@return: section parser to be used to parse the upcoming section
		@rtype: L{SpecModelParser}
		'''
		for parser in self.MANIPULATORS:
			ret = parser.section_beginning(token_list)
			if ret is not None:
				return parser

		return None # Not found

	@staticmethod
	def section_beginning_callback_no_if(obj, token_list):
		'''
		A callback for L{SpecTokenList} used to check whether next token is
		a section token, skip %ifs
		@param obj: self instance
		@type obj: L{SpecModelParser} instance
		@param token_list: token list to be used
		@type token_list: L{SpecTokenList}
		@return: section parser to be used for parsing the upcoming section
		@rtype: L{SpecModelParser}
		'''
		return obj.section_beginning_no_if(token_list)

	def section_beginning_no_if(self, token_list):
		'''
		Check whether next token is a section token, skip %if
		@param token_list: token list to be used
		@type token_list: L{SpecTokenList}
		@return: section parser to be used to parse the upcoming section
		@rtype: L{SpecModelParser}
		'''
		for parser in self.MANIPULATORS:
			ret = parser.section_beginning(token_list)
			if ret is not None and not issubclass(ret, SpecStIf):
				return parser

		return None # Not found

	def parse_loop(self, token_list, parent, allowed):
		'''
		Main parse loop to get list of parsed sections
		@param token_list: a list of tokens to be used
		@type token_list: L{SpecTokenList}
		@param parent: parent section
		@type parent: L{SpecSection}
		@param allowed: allowed sections to be parsed, section parsers
		@type allowed: list of L{SpecSectionParser}
		@return: list of parsed sections
		@rtype: L{SpecSection}
		'''
		ret = []

		found = True
		while found:
			found = False
			token = token_list.touch()
			SpecDebug.debug("- parsing round: '%s'" % str(token))

			if token.is_eof():
				break

			for t in allowed:
				section = t.parse(token_list, parent, allowed, self)
				if section:
					found = True
					SpecDebug.debug("- adding parsed section '%s'" % type(section))
					ret.append(section)
					break

			if not found:
				SpecDebug.debug("- unparsed token '%s' on line %s" % (str(token), str(token.line)))

		return ret

	def parse_preamble(self):
		'''
		Parse preamble of a spec file
		@return: parsed sections in preamble
		@rtype: list of L{SpecSection}
		'''
		allowed = [ SpecIfParser, SpecDefinitionParser, SpecGlobalParser ]

		ret = self.parse_loop(self.token_list, None, allowed)
		unparsed = self.token_list.touch()
		SpecDebug.debug("-- preamble finished with token '%s' on line %d" % (str(unparsed), unparsed.line))
		return ret

	def parse_loop_section(self):
		'''
		Parse sections after preamble
		@return: list of parsed sections
		@rtype: list of L{SpecSection}
		'''
		allowed = copy.deepcopy(self.MANIPULATORS)
		return self.parse_loop(self.token_list, None, allowed)

	def parse(self):
		'''
		Main parser entry point - parse provided spec file
		@return: None
		@rtype:
		@raise SpecBadToken: when an unexpected token is reached
		'''
		self.get_model_writer().append_items(self.parse_preamble())
		self.get_model_writer().append_items(self.parse_loop_section())

		eof = self.token_list.touch()
		if not eof.is_eof():
			raise SpecBadToken("Unexpected symbol '" + str(eof.token) + "' on line " + str(eof.line))