class Compiler(): #valid token types which can comprise a <Statement> valid_statement_tokens = [ Token.LBLOCK, Token.VAR, Token.CONST, Token.IDENTIFIER, Token.IF, Token.INPUT, Token.OUTPUT, Token.WHILE, Token.SEMI] #valid token types which can comprise an <Expression> valid_expression_tokens = [ Token.NUMBER, Token.IDENTIFIER, Token.LPAREN, Token.RPAREN, Token.PLUS, Token.MINUS, Token.DIV, Token.MUL, Token.TRUE, Token.FALSE] #valid token types which can comprise a <Comparison> token valid_comparison_tokens = [ Token.LTEQ, Token.GTEQ, Token.GT, Token.LT, Token.EQUAL, Token.NOTEQUAL] def __init__(self, tokens): """ Compiler initializer. tokens (list): Tokens produced by the parser """ self.tokens = tokens self.compiled = list() #compiled code generated by run() def run(self): """ Compiles the code """ if len(self.tokens) == 0: #case when the program is empty self.compiled = ['.'] return preserved_tokens = self.tokens[:] #preserve the tokens because they're consumed during compilation self.program = Program(self).build() #begin recursive descent parsing self.tokens = preserved_tokens #restore the tokens self.program.clean() #begin the recursive clean/modification process (to translate to PL/0) self.program.compile() #generate the compiled PL/0 code def error(self, text): """ The compiler found a grammar error and will report it to the user. All errors are fatal text (string): Error message to report to user. """ quit('LINE ' + str(self.tokens[0].line) + ' (Token: "' + self.tokens[0].text + '") ERROR <' + callee().lstrip('_').upper() + '> : ' + text) def next(self, pos = 0): """ Return the type of token pos positions ahead in the token list. pos (int, optional): The position to lookup within the tokens. """ return "<NONE>" if len(self.tokens) <= pos else self.tokens[pos].type def skip(self, pos = 1): """ Tell the compiler to skip/discard pos number of tokens. pos (int, optional): The number of tokens to skip/discard. """ self.tokens = self.tokens[pos:] def __str__(self): """ String representation of the compiler """ return ''.join([str(i) for i in self.compiled])