def testIdentifierWithNumbers(self): lines = ['var s1: string:= "Hello";'] src = MockSource(lines) scanner = Scanner(src) lexemes = [] while not src.eof(): token = scanner.scanNextToken() lexemes.append(token.lexeme) self.assertIn('s1', lexemes)
def testMultilineComment(self): lines = [ "/* multi", "line", "comment */\n", "/* multi", "line", "comment */\n" ] src = MockSource(lines) scanner = Scanner(src) token = scanner.scanNextToken() self.assertEqual('eof', token.tokenType)
def testIdentifierWithUnderScore(self): lines = ['var hello_str: string:= "Hello";'] src = MockSource(lines) scanner = Scanner(src) lexemes = [] while not src.eof(): token = scanner.scanNextToken() lexemes.append(token.lexeme) self.assertIn('hello_str', lexemes)
def testLoneDotError(self): lines = ['for i in 1.5 do\n'] src = MockSource(lines) scanner = Scanner(src) types = [] while not src.eof(): token = scanner.scanNextToken() types.append(token.tokenType) self.assertTrue('error' in types) self.assertTrue('eof' in types)
def testEscapeCharacters(self): lines = ['"\\"Donkey Kong!\\""'] src = MockSource(lines) scanner = Scanner(src) lexemes = [] while not src.eof(): token = scanner.scanNextToken() lexemes.append(token.lexeme) self.assertTrue(len(lexemes) == 1) self.assertEqual('"\"Donkey Kong!\""', lexemes[0])
def testStringLiteral(self): lines = ['"Hello World!"'] src = MockSource(lines) scanner = Scanner(src) lexemes = [] while not src.eof(): token = scanner.scanNextToken() lexemes.append(token.lexeme) self.assertTrue(len(lexemes) == 1) self.assertEqual(lines[0], lexemes[0])
def testNestedComments(self): lines = ['/* Yes /* No */ */'] src = MockSource(lines) scanner = Scanner(src) types = [] while not src.eof(): token = scanner.scanNextToken() types.append(token.tokenType) self.assertTrue(len(types) == 1) self.assertIn('eof', types)
def testLexicalError(self): lines = ['var i : int := 3 $ x;\n'] src = MockSource(lines) scanner = Scanner(src) types = [] while not src.eof(): token = scanner.scanNextToken() types.append(token.tokenType) self.assertTrue('error' in types) self.assertTrue('eof' in types)
def testScanNextToken(self): lines = ["var X : int : 4 + (6 * 2);", "print X;"] src = MockSource(lines) tokens = [('var', 'var'), ('identifier', 'X'), (':', ':'), ('int', 'int'), (':', ':'), ('integer', '4'), ('+', '+'), ('(', '('), ('integer', '6'), ('*', '*'), ('integer', '2'), (')', ')'), (';', ';')] scanner = Scanner(src) for t in tokens: token = scanner.scanNextToken() tokenType, lexeme = t self.assertEqual(token.tokenType, tokenType) self.assertEqual(token.lexeme, lexeme)
def testPrintVisitor(self): src = Source('./tests/test.minipl') scanner = Scanner(src) parser = Parser(scanner) ast = parser.program() pv = PrintVisitor() ast.accept(pv)
def testTypeCheckVisitor(self): return src = Source('./tests/test.minipl') scanner = Scanner(src) parser = Parser(scanner) ast = parser.program() tc = TypeCheck() ast.accept(tc)
def testScanNextToken2(self): lines = [ "var x : int;\n", "for x in 0..5 do\n", "print x;\n", "end for;\n" ] src = MockSource(lines) scanner = Scanner(src) tokens = [('var', 'var'), ('identifier', 'x'), (':', ':'), ('int', 'int'), (';', ';'), ('for', 'for'), ('identifier', 'x'), ('in', 'in'), ('integer', '0'), ('..', '..'), ('integer', '5'), ('do', 'do'), ('print', 'print'), ('identifier', 'x'), (';', ';'), ('end', 'end'), ('for', 'for'), (';', ';')] for t in tokens: token = scanner.scanNextToken() tokenType, lexeme = t self.assertEqual(token.tokenType, tokenType) self.assertEqual(token.lexeme, lexeme)
def __createAstAndVisitor__(self, lines): src = MockSource(lines) scanner = Scanner(src) parser = Parser(scanner) ast = parser.program() tc = TypeCheck() ast.accept(tc) iv = InterpretingVisitor(tc.symbolTable) return ast, iv
def testInterpretingVisitorWithAFile(self, output, input): src = Source('./tests/test.minipl') scanner = Scanner(src) parser = Parser(scanner) ast = parser.program() tc = TypeCheck() ast.accept(tc) iv = InterpretingVisitor(tc.symbolTable) ast.accept(iv) output.assert_called_with('120')
class Interpreter(QObject): interpreted = pyqtSignal(str) def __init__(self): super(Interpreter, self).__init__() self.scanner = Scanner() self.parser = Parser() self.was_retry = False def interpret(self, text: str): text = text.replace('<', '<').replace('>', '>') try: tokens, had_error = self.scanner.scan(text) except Error as err: self.print(err.__str__()) return # for token in tokens: print(token) exprs = self.parser.parse(tokens) if exprs is not None: for expr in exprs: if isinstance(expr, Expr): # print(expr.__str__()) try: ans = expr.evaluate() # TODO loaded script compatible with 'ans' self.parser.environment.vars['ans'] = ans if type(ans) is bool and not expr.mute: if ans is True: self.print("true") else: self.print("false") else: trimmed = self.trim_trailing_zero(ans) if not expr.mute: self.print(trimmed) except Error as err: self.print(err.__str__()) elif isinstance(expr, Error): print(expr.__str__()) # flexibility about unmatched ')' : allow "a = log(10" by adding a ')' at the end of the text if (expr.__str__() == "ParseError - Expect ')' after arguments." or expr.__str__() == "ParseError - Expect ')' after expression.") \ and not self.was_retry: try: self.was_retry = True self.interpret(text + ')') except Error: self.print(expr) else: self.print(expr) elif isinstance(expr, Files): loaded = expr.exec() if loaded is not None: self.interpret(loaded) # TODO correct history for loaded scripts self.was_retry = False def print(self, res): self.interpreted.emit(res.__str__()) # print(res) @staticmethod def trim_trailing_zero(text): text = str(text) if text.endswith('.0'): text = text[:text.index('.0')] return text
def testSingleLineComment(self): lines = ["// Single line comment \n", 'var x : int := 0;'] src = MockSource(lines) scanner = Scanner(src) token = scanner.scanNextToken() self.assertEqual('var', token.tokenType)
def __initparser__(self, lines): src = MockSource(lines) scanner = Scanner(src) return Parser(scanner)
def setup(filename): src = Source(filename) scanner = Scanner(src) parser = Parser(scanner) ast = parser.program() return ast, parser.errors
def testParser(self): src = Source('./tests/test.minipl') scanner = Scanner(src) parser = Parser(scanner) parser.program()
def testRunawayMultilineComment(self): lines = ["/* multi", "line", "comment \n", "var x : int : 3;\n"] src = MockSource(lines) scanner = Scanner(src) token = scanner.scanNextToken() self.assertEqual('error', token.tokenType)
def __createAST__(self, lines): src = MockSource(lines) scanner = Scanner(src) parser = Parser(scanner) return parser.program(), parser
def __init__(self): super(Interpreter, self).__init__() self.scanner = Scanner() self.parser = Parser() self.was_retry = False
def testReal(self): src = Source('./tests/test.minipl') scanner = Scanner(src) symbol = scanner.scanNextToken() while symbol.tokenType != 'eof': symbol = scanner.scanNextToken()