All pastes #1343186 Raw Edit

timmeh

public python v1 · immutable
#1343186 ·published 2009-02-20 21:08 UTC
rendered paste body
###################################################################	File: lexer.py# 	Author: Timothy Wakeham (timmeh)#	Date: 21/02/09##	Todo:#	-Create token descriptor class#	-Fix token descriptors#	-Token and token descriptors should subclass Collection#	-Do callback functions#	-Fix error handling#	-Error recovery##################################################################import reempty = ''digits = '0123456789'lchars = 'abcdefghijklmnopqrstuvwxyz'uchars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'chars = lchars + ucharsunderscore = '_'operators = '+-/*<>=!'class LexicalError(Exception):	def __init__(self, msg, lexer=None):		self.msg = msg		self.lexer = lexer	def __str__(self):		return self.msg		class Token:	def __init__(self, **kwargs):		for key, val in kwargs.iteritems():			setattr(self, key, val)		self.kwargs = kwargs.copy()	def __str__(self):		buffer = '-----------------------------\n'		for key, val in self.kwargs.iteritems():			buffer += '%s:%s\n' % (key, val)		#buffer += '-----------------------------'		return buffer[:-1]class Lexer:	def __init__(self, input_stream):		self.input_stream = input_stream		self.token_descriptors = {}			def register(self, type, initial, final=empty, callback=None):		self.token_descriptors[type] = [initial, final, callback]			def tokenise(self):		char_pos = 0		stream_len = len(self.input_stream)		token_list = []		token_pos = 1		while(char_pos <= stream_len):			lexical_error = 0			for token_type, token_descriptor in self.token_descriptors.iteritems():				lexical_error += 1				if char_pos >= stream_len: return token_list				if self.input_stream[char_pos] in token_descriptor[0]:					token_start = char_pos					while(self.input_stream[char_pos + token_pos] in token_descriptor[1]):						token_pos += 1						if char_pos + token_pos >= stream_len: break					token_end = char_pos + token_pos					token_value = self.input_stream[token_start:token_end]					token_list.append(Token(type=token_type, value=token_value, start=token_start, end=token_end, length=token_end-token_start))					char_pos += token_pos					token_pos = 1					break				print self.input_stream[char_pos]				#raise LexicalError('Unrecognised character - %s' % self.input_stream[char_pos])	lexer = Lexer('12+4-abc/80345')lexer.register('NUM', digits, digits)lexer.register('IDENT', chars, chars + digits + underscore)lexer.register('OPERATOR', operators)lexer.register('LBRACE', '(', empty)lexer.register('RBRACE', ')', empty)for token in lexer.tokenise():	print token