def test_file(test_dir, filename): cparser = Cparser() parser = yacc.yacc(module=cparser) try: file_path = os.path.join(test_dir, filename) file = open(file_path, "r") except IOError: print("Cannot open {0} file".format(file_path)) sys.exit(0) old_stdout = sys.stdout sys.stdout = mystdout = StringIO() text = file.read() ast = parser.parse(text, lexer=cparser.scanner, debug=False) typeChecker = TypeChecker() typeChecker.visit(ast) sys.stdout = old_stdout name = os.path.join(test_dir, os.path.splitext(filename)[0]) file_expected = "{0}.expected".format(name) actual_content = mystdout.getvalue() expected_content = open(file_expected).read().replace("\r", "") res = cmp(actual_content, expected_content) assert res == 0, "test output and file {0} differ\n---ACTUAL---\n{1}\n---EXPECTED---\n{2}\n---".format( file_expected, actual_content, expected_content) print("Passed test for file '%s'." % filename)
def __init__(self, AST): TypeChecker.__init__(self, AST) self.register(DuplicateQuestions()) self.register(UndefinedQuestions()) self.register(NonBooleanTypes()) self.check()
def __init__(self, start="program", outputdir="logs", tabmodule="baseparsetab"): create_dir(outputdir) self.ast = False self.type_check = False self.scanner = Scanner() self.type_checker = TypeChecker() self.parser = yacc.yacc(module=self, start=start, tabmodule=tabmodule, outputdir=outputdir) self.error = False
def run(filename, output=True): file = open(filename, "r") prsr = parser.parser text = file.read() ast = prsr.parse(text, lexer=scanner.lexer) # if ast is not None: # ast.printTree() # print() typeChecker = TypeChecker() checkRes = typeChecker.visit(ast) if output: print(checkRes) if isinstance(checkRes, Success): return ast.accept(Interpreter.Interpreter(output))
def compile(self, source, env=None, library=False): if env == None: env = Environment() # parse input (definitions, errors) = Parser().parse(source) # check for errors if len(errors) > 0: return ("", errors) # type checking for definition in definitions: TypeChecker().check(errors, env, definition) # check for errors if len(errors) > 0: return ("", errors) # code generation code = "" generator = CodeGenerator() for node in definitions: symbol = node[0].value() code += generator.generateDefinition(env, symbol, template) # generate library if library: code += generator.generateLibrary(template) return (code, errors)
def testFirstFunctionApplyBug(self): (definitions, errors) = Parser().parse(""" //def bug(x) = get([x], 0) def test(x) = [x] def test2(x) = test(x) def test3(x) = get(test(x), 0) """) env = Environment() type1 = TypeChecker().check(errors, env, definitions[0]) type2 = TypeChecker().check(errors, env, definitions[1]) type3 = TypeChecker().check(errors, env, definitions[2]) self.assertEqual(errors, []) self.assertEqual(str(type1), "a -> [a]") self.assertEqual(str(type2), "a -> [a]") self.assertEqual(str(type3), "a -> a")
def testFunctionApplication(self): (definitions, errors) = Parser().parse(""" def id(x) = x def value = id(11) """) env = Environment() id_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(id_type), "a -> a") # assert correct parsing self.assertEqual(str(value_type), "Int")
def testBooleanExpressionXor(self): (definitions, errors ) = Parser().parse("def xor(a, b) = (a and not b) or (not a and b)") env = Environment() type = TypeChecker().check(errors, env, definitions[0]) self.assertEqual(errors, []) self.assertEqual(str(type), "(Bool, Bool) -> Bool")
def testRecursiveFunction(self): (definitions, errors) = Parser().parse(""" def rec(x) = rec(x) def value = rec(5) """) env = Environment() id_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(id_type), "a -> b") # assert correct parsing self.assertEqual(str(value_type), "a")
def testFirstElementFunction(self): (definitions, errors) = Parser().parse(""" def first(x) = get(x, 0) def value = first([5, 6, 6]) """) env = Environment() first_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(first_type), "[a] -> a") # assert correct parsing self.assertEqual(str(value_type), "Int")
def testFunctionComposition(self): (definitions, errors) = Parser().parse(""" def composition(f, g) = lambda(x) f( g(x) ) def app = composition(lambda(x) x + 3, lambda(x) x - 4)(10) """) env = Environment() composition_type = TypeChecker().check(errors, env, definitions[0]) app_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(composition_type), "(a -> b, c -> a) -> c -> b") # assert correct parsing self.assertEqual(str(app_type), "Int")
def testMultipleFunctionApplication(self): (definitions, errors) = Parser().parse(""" def prod = lambda(x) lambda(y) lambda(z) z * y * x def value = prod(8)(5)(3) """) env = Environment() prod_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(prod_type), "Int -> Int -> Int -> Int") # assert correct parsing self.assertEqual(str(value_type), "Int")
def testPartialFunctionApplication(self): (definitions, errors) = Parser().parse(""" def sum(a) = lambda(b) a + b def inc = sum(1) """) env = Environment() sum_type = TypeChecker().check(errors, env, definitions[0]) inc_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(sum_type), "Int -> Int -> Int") # assert correct parsing self.assertEqual(str(inc_type), "Int -> Int")
def testFunctionApplicationWithTwoArguments(self): (definitions, errors) = Parser().parse(""" def id(x,y) = y def value = id(11, true) """) env = Environment() id_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(id_type), "(a, b) -> b") # assert correct parsing self.assertEqual(str(value_type), "Bool")
def testFunctionApplicationWithConstantExpression(self): (definitions, errors) = Parser().parse(""" def id(x,y) = 20 def value = id(false, true) """) env = Environment() id_type = TypeChecker().check(errors, env, definitions[0]) value_type = TypeChecker().check(errors, env, definitions[1]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(id_type), "(a, b) -> Int") # assert correct parsing self.assertEqual(str(value_type), "Int")
def testVariableType(self): (definitions, errors) = Parser().parse("def x = 10") type = TypeChecker().check(errors, Environment(), definitions[0]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(type), "Int")
def testListType(self): (definitions, errors) = Parser().parse("def t = [1, 5, 6]") type = TypeChecker().check(errors, Environment(), definitions[0]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(type), "[Int]")
def testLambdaType(self): (definitions, errors) = Parser().parse("def f(x) = lambda(y) x") type = TypeChecker().check(errors, Environment(), definitions[0]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(type), "a -> b -> a")
def testNegativeIntegerTest(self): (definitions, errors) = Parser().parse("def number = -103") type = TypeChecker().check(errors, Environment(), definitions[0]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(type), "Int")
def testFalseTest(self): (definitions, errors) = Parser().parse("def boolean = false") type = TypeChecker().check(errors, Environment(), definitions[0]) # assert that no error occured self.assertEqual(errors, []) # assert correct parsing self.assertEqual(str(type), "Bool")
def run(): filename = None try: filename = sys.argv[1] if len(sys.argv) > 1 else "example1" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) parser = Mparser.parser text = file.read() lexer.input(text) ast = parser.parse(text, lexer=lexer) print(ast.printTree()) typeChecker = TypeChecker() typeChecker.visit(ast) # or alternatively ast.accept(typeChecker) print('Checked') ast.accept(Interpreter())
def run_pipeline(text): ret_text = '\n' + '=================== TEXT ======================' ret_text += '\n' + text ret_text += '\n' + '================== TOKENS =====================' tokens = tokenize_text(text) ret_text += '\n' + pprint_tokens(tokens) ret_text += '\n' + '=================== PARSE =====================' ret_text += '\n' parser = Serializer.load(os.getcwd() + '/parser') #parser = LR1Parser(G) ret_parser = parser([t.token_type for t in tokens]) parse, operations = ret_parser if parse is None: return ret_text + "\nParsing Error at " + operations ret_text += '\n'.join(repr(x) for x in parse) ret_text += '\n' + '==================== AST ======================' ast = evaluate_reverse_parse(parse, operations, tokens) formatter = FormatVisitor() tree = formatter.visit(ast) ret_text += '\n' + tree ret_text += '\n' + '============== COLLECTING TYPES ===============' errors = [] collector = TypeCollector(errors) collector.visit(ast) context = collector.context ret_text += '\n' + 'Errors:' for error in errors: ret_text += '\n' + error ret_text += '\n' + 'Context:' ret_text += '\n' + str(context) ret_text += '\n' + '=============== BUILDING TYPES ================' builder = TypeBuilder(context, errors) builder.visit(ast) ret_text += '\n' + 'Errors: [' for error in errors: ret_text += '\n' + '\t' ret_text += '\n' + error ret_text += '\n' + ']' ret_text += '\n' + 'Context:' ret_text += '\n' + str(context) ret_text += '\n' + '=============== CHECKING TYPES ================' checker = TypeChecker(context, errors) try: scope, errors = checker.visit(ast) while(checker.changed): scope, errors = checker.visit(ast) except SemanticError as e: errors = [e.text] ret_text += '\n' + 'Errors: [' for error in errors: ret_text += '\n' + '\t' ret_text += '\n' + error ret_text += '\n' + ']' if len(errors) == 0: checker.printer(ast) return ret_text
def run(self, sourceCode, filename, optimize=True, llvmdump=True, astDump=True): print(formatMessageBoldTitle(f'Compiling {filename}')) print(sourceCode) try: ast = LALRParser(sourceCode) TypeChecker(ast).typecheck() if astDump is True: ast.printFancyTree() irModule = LLVMCodeGenerator().generateIR(ast) # irModule = exampleIR if llvmdump is True: print(formatMessageBoldTitle('Unoptimized IR')) print(str(irModule)) outputFilename = './build/output.ll' with open(outputFilename, 'w') as llFile: llFile.write(str(irModule)) # Convert LLVM IR into in-memory representation llvmmod = llvm.parse_assembly(str(irModule)) # Optimize the module if optimize: pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(llvmmod) if llvmdump is True: print(formatMessageBoldTitle('Optimized IR')) print(str(llvmmod)) outputFilename = './build/output.o' with open(outputFilename, 'wb') as objectFile: target_machine = self.target.create_target_machine( codemodel='small') # Convert LLVM IR into in-memory representation objectCode = target_machine.emit_object(llvmmod) objectFile.write(objectCode) except CompilationFailure as failure: failure.printTrace()
def __init__(self): self.commands = { ":type": self.printType, ":list": self.printList, ":show": self.printDefinition, ":code": self.printGeneratedCode, ":string": self.setString, ":help": lambda x: None, "def": self.addDefinition, } self.printString = False self.env = Environment() self.checker = TypeChecker() self.ghci = GHCI() # imports self.ghci.execute("import Data.Char")
import sys import ply.yacc as yacc from Mparser import Mparser from TreePrinter import TreePrinter from TypeChecker import TypeChecker if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Mparser = Mparser() parser = yacc.yacc(module=Mparser) text = file.read() ast = parser.parse(text, lexer=Mparser.scanner) typeChecker = TypeChecker() typeChecker.visit(ast) # or alternatively ast.accept(typeChecker)
import sys import ply.lex as lex import scanner # scanner.py is a file you create, (it is not an external library) import ply.yacc as yacc from Mparser import Mparser from TreePrinter import TreePrinter from TypeChecker import TypeChecker if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "examples/example4.txt" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Mparser = Mparser() parser = yacc.yacc(module=Mparser) text = file.read() ast = parser.parse(text, lexer=Mparser.scanner) typeChecker = TypeChecker() typeChecker.visit(ast) print(typeChecker.isValid)
import sys import ply.yacc as yacc from Cparser import Cparser from TypeChecker import TypeChecker from Interpreter import Interpreter if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" input_file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Cparser = Cparser() parser = yacc.yacc(module=Cparser) text = input_file.read() ast = parser.parse(text, lexer=Cparser.scanner) checker = TypeChecker() types_ok = checker.generic_visit(ast) #~ print(ast) if(types_ok): interpreter = Interpreter() interpreter.generic_execute(ast)
import os import sys import ply.yacc as yacc from Cparser import Cparser from TreePrinter import TreePrinter from TypeChecker import TypeChecker if __name__ == '__main__': filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" with open(filename, "r+") as file: try: _Cparser = Cparser() parser = yacc.yacc(module=_Cparser) text = file.read() ast = parser.parse(text, lexer=_Cparser.scanner) typeChecker = TypeChecker() if ast: typeChecker.visit(ast) except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0)
import sys import ply.yacc as yacc from Cparser import Cparser from TypeChecker import TypeChecker from Interpreter import Interpreter if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Cparser = Cparser() parser = yacc.yacc(module=Cparser) text = file.read() ast = parser.parse(text, lexer=Cparser.scanner) if ast.accept(TypeChecker()): # jesli wizytor TypeChecker z implementacji w poprzednim lab korzystal z funkcji accept # to nazwa tej ostatniej dla Interpretera powinna zostac zmieniona, np. na accept2 ( ast.accept2(Interpreter()) ) # tak aby rozne funkcje accept z roznych implementacji wizytorow nie kolidowaly ze soba ast.accept(Interpreter()) # in future # ast.accept(OptimizationPass1()) # ast.accept(OptimizationPass2()) # ast.accept(CodeGenerator())
from Interpreter import Interpreter if __name__ == '__main__': sys.setrecursionlimit(10000) try: filename = sys.argv[1] if len(sys.argv) > 1 else "tests/loops.in" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Cparser = Cparser() parser = yacc.yacc(module=Cparser) text = file.read() ast = parser.parse(text, lexer=Cparser.scanner) typeChecker = TypeChecker() #print ast for str in ast.accept2(typeChecker): pass #print str if typeChecker.isValid: # print " " # print "Interpretacion: " ast.accept(Interpreter()) else: print "ERRORS FOUND"
Parser = Parser() parser = yacc.yacc(module=Parser) text = file.read() parsed = parser.parse(text, lexer=Parser.scanner) #tr.TreePrinter.printAST(parsed) if parsed is not None: #print "Compiling {}".format(filename) #print ch = VisibilityChecker() ch.visit(parsed) typeChecker = TypeChecker() typeChecker.visit(parsed) errors = sorted(ch.errors + typeChecker.errors, key=lambda el: el.line) warnings = sorted(ch.warnings + typeChecker.warnings, key=lambda el: el.line) msg = "successful" if len(errors) == 0 else "failed" for error in errors: print error for warning in warnings: print warning #print #print "Compilation {} ({} errors, {} warnings)".format(msg, len(errors), len(warnings)) if len(errors) == 0:
class Parser(object): tokens = Scanner.tokens precedence = ( # Higher position will be executed later in case of conflicts ('right', 'ASSIGN', 'ADDASSIGN', 'SUBASSIGN', 'MULASSIGN', 'DIVASSIGN'), ('nonassoc', 'GE', 'GEQ', 'LE', 'LEQ', 'EQ', 'NEQ'), ('left', 'ADD', 'SUB', 'DOTADD', 'DOTSUB'), ('left', 'MUL', 'DIV', 'DOTMUL', 'DOTDIV'), ('left', 'TRANS'), ('right', 'UMINUS'), ('nonassoc', 'IFX'), ('nonassoc', 'ELSE')) def __init__(self, start="program", outputdir="logs", tabmodule="baseparsetab"): create_dir(outputdir) self.ast = False self.type_check = False self.scanner = Scanner() self.type_checker = TypeChecker() self.parser = yacc.yacc(module=self, start=start, tabmodule=tabmodule, outputdir=outputdir) self.error = False def parse(self, text, ast=False, type_check=False): self.ast = ast self.type_check = type_check self.error = False self.parser.parse(text) def p_error(self, p): if p: print( f"Syntax error at line {p.lineno}, column {self.scanner.find_tok_column(p)}:" f"LexToken({p.type}, {p.value})") else: print("Unexpected end of input") self.error = True def p_empty(self, p): """empty :""" pass def p_program(self, p): """program : statements""" p[0] = p[1] if self.ast: if not self.error: p[0].printTree() else: print( f"Provided program has Syntax error, AST Tree won't be printed" ) if self.type_check: if not self.error: self.type_checker.visit( p[0] ) # Prints all Type Errors (Syntax Errors are not allowed here) else: print( f"Provided program has Syntax error, Type Check won't be executed" ) def p_statements(self, p): """statements : empty | LCURLY statements RCURLY statements | statement statements """ if len(p) == 2: p[0] = Statements([]) elif len(p) == 3: sts = p[2] if p[2] else Statements([]) sts.statements = [p[1]] + sts.statements p[0] = sts else: outer = p[4] if p[4] else Statements([]) inner = p[2] if p[2] else Statements([]) outer.statements = [inner] + outer.statements p[0] = outer def p_block(self, p): """block : statement | LCURLY statements RCURLY """ if len(p) == 2: p[0] = p[1] else: p[0] = Statements([p[2]]) def p_statement(self, p): """statement : IF expression block %prec IFX | IF expression block ELSE block | WHILE expression block | FOR for_expression block | PRINT expressions SEMICOL | control_expression SEMICOL """ if p[1] == "if": p[0] = If(p[2], Block(p[3])) if len(p) == 4 else If( p[2], Block(p[3]), Block(p[5]), lineno=self.scanner.lexer.lineno) elif p[1] == "while": p[0] = While(p[2], Block(p[3]), lineno=self.scanner.lexer.lineno) elif p[1] == "for": p[0] = For(p[2], Block(p[3]), lineno=self.scanner.lexer.lineno) elif p[1] == "print": p[0] = Print(p[2], lineno=self.scanner.lexer.lineno) else: # control expression p[0] = p[1] def p_statement_assignments(self, p): """statement : assignments SEMICOL""" p[0] = Assignments(p[1], lineno=self.scanner.lexer.lineno) def p_expression(self, p): """expression : expression ADD expression | expression SUB expression | expression DIV expression | expression MUL expression | expression DOTADD expression | expression DOTSUB expression | expression DOTDIV expression | expression DOTMUL expression | expression GE expression | expression GEQ expression | expression LE expression | expression LEQ expression | expression EQ expression | expression NEQ expression """ p[0] = BinOp(p[1], p[2], p[3], lineno=self.scanner.lexer.lineno) def p_expression_group(self, p): """expression : LPAREN expression RPAREN""" p[0] = p[2] def p_expression_variable(self, p): """expression : variable""" p[0] = p[1] def p_variable(self, p): """variable : const | matrix """ p[0] = Variable(p[1], lineno=self.scanner.lexer.lineno) def p_variable_id(self, p): """variable : ID""" p[0] = Variable(Id(p[1]), lineno=self.scanner.lexer.lineno) def p_variable_uminus(self, p): """variable : SUB variable %prec UMINUS""" p[0] = Variable(p[2].value, p[2].minus + 1, p[2].trans, lineno=self.scanner.lexer.lineno) def p_variable_trans(self, p): """variable : variable TRANS""" p[0] = Variable(p[1].value, p[1].minus, p[1].trans + 1, lineno=self.scanner.lexer.lineno) def p_const(self, p): """const : STRING | FLOATNUM | INTNUM """ p[0] = p[1] def p_for_expression(self, p): """ for_expression : ID ASSIGN expression RANGE expression""" p[0] = ForExpr(Id(p[1]), p[3], p[5], lineno=self.scanner.lexer.lineno) def p_expressions(self, p): """ expressions : expression COMMA expressions | expression """ if len(p) == 2: p[0] = [p[1]] else: p[0] = [p[1]] + p[3] def p_expressions_empty(self, p): """ expressions : empty """ p[0] = [] def p_control_expression(self, p): """control_expression : BREAK | CONTINUE | RETURN expressions """ if p[1] == "break": p[0] = Break(lineno=self.scanner.lexer.lineno) elif p[1] == "continue": p[0] = Continue(lineno=self.scanner.lexer.lineno) else: # RETURN p[0] = Return(p[2], lineno=self.scanner.lexer.lineno) def p_assignments(self, p): """assignments : assignment COMMA assignments | assignment """ if len(p) == 2: p[0] = [p[1]] else: p[0] = [p[1]] + p[3] def p_assignments_empty(self, p): """assignments : empty """ p[0] = [] def p_assignment(self, p): """assignment : ID assign_op expression | ID LBRACKET expressions RBRACKET assign_op expression """ if len(p) == 7: p[0] = Assignment(Id(p[1]), p[5], p[6], p[3], lineno=self.scanner.lexer.lineno) else: p[0] = Assignment(Id(p[1]), p[2], p[3], lineno=self.scanner.lexer.lineno) def p_assign_op(self, p): """assign_op : ASSIGN | ADDASSIGN | SUBASSIGN | MULASSIGN | DIVASSIGN """ p[0] = p[1] def p_matrix_special(self, p): """matrix : EYE LPAREN expressions RPAREN | ZEROS LPAREN expressions RPAREN | ONES LPAREN expressions RPAREN """ p[0] = SpecialMatrix(p[1], p[3], lineno=self.scanner.lexer.lineno) def p_matrix(self, p): """matrix : vector""" p[0] = SimpleMatrix(p[1], lineno=self.scanner.lexer.lineno) def p_vector(self, p): """vector : LBRACKET outer_list RBRACKET""" p[0] = p[2] def p_outerlist(self, p): """outer_list : outer_list SEMICOL inner_list | inner_list """ if len(p) == 2: p[0] = p[1] else: p[0] = p[1] + [ ';' ] + p[3] # Keep track of SEMICOL, for inputs like [1;2,3,4] def p_innerlist(self, p): """inner_list : inner_list COMMA elem | elem """ if len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] + [p[3]] def p_innerlist_empty(self, p): """inner_list : empty """ p[0] = [] def p_elem(self, p): """elem : const | vector """ p[0] = p[1] def p_elem_id(self, p): """elem : ID""" p[0] = Id(p[1], lineno=self.scanner.lexer.lineno)
from Cparser import Cparser from TypeChecker import TypeChecker from Interpreter import Interpreter if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Cparser = Cparser() parser = yacc.yacc(module=Cparser) text = file.read() ast = parser.parse(text, lexer=Cparser.scanner) if ast: typeChecker = TypeChecker() typeChecker.visit(ast) # or alternatively ast.accept(typeChecker) if typeChecker.isValid: print "Type check finished" ast.accept(Interpreter()) print "Interpretation finished" else: sys.stderr.write("Type check failed -> no interpretation") else: sys.stderr.write("Syntax check failed -> no type check & interpretation")
def typechecker_passes(text: str): ast = parser.parse(text) typechecker = TypeChecker() typechecker.visit(ast) return typechecker.errorok
import sys import ply.yacc as yacc from Cparser import Cparser from TreePrinter import TreePrinter from TypeChecker import TypeChecker if __name__ == '__main__': try: filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt" file = open(filename, "r") except IOError: print("Cannot open {0} file".format(filename)) sys.exit(0) Cparser = Cparser() parser = yacc.yacc(module=Cparser) text = file.read() ast = parser.parse(text, lexer=Cparser.scanner) # ast.print_tree(0) typeChecker = TypeChecker() typeChecker.visit(ast)