Exemple #1
0
def main(filename):
    # get the root of the parse tree of the input file
    parseTreeRoot = parseFile(filename)

    # the errorHandler which will group all of the errors
    errorHandler = ErrorHandler(filename)

    try:
        # create an AST an attach it to a listener so the listener can fill in the tree
        abstractSyntaxTree = buildAST(parseTreeRoot)

        firstPassDecoration(abstractSyntaxTree)

        # create a symbol table and symbol table filler, fill in the table and check if everything is declared before it is used in the c file
        symbolTable = SymbolTable()
        scopeCheck(abstractSyntaxTree, errorHandler, symbolTable)

        # do the type checking
        typeCheck(abstractSyntaxTree, errorHandler)

        output(str(abstractSyntaxTree))
        output(str(symbolTable))

        # generate code
        if not errorHandler.errorCount():
            generateCode(abstractSyntaxTree, symbolTable)

    except Exception as e:
        ex_type, ex, tb = sys.exc_info()
        traceback.print_exception(ex_type, ex, tb)

    if errorHandler.errorCount() or errorHandler.warningCount():
        print(str(errorHandler.errorCount()) + " error" + ("s" if errorHandler.errorCount() != 1 else ""))
        print(str(errorHandler.warningCount()) + " warning" + ("s" if errorHandler.warningCount() != 1 else ""))
        errorHandler.printErrors()
Exemple #2
0
class ASTTest():
    def setUp(self):
        self.errorHandler = None

    def parseFile(self, filename):
        input_file = FileStream(filename)
        lexer = CLexer(input_file)
        stream = CommonTokenStream(lexer)
        parser = CParser(stream)
        programContext = parser.program()

        if parser._syntaxErrors > 0:
            raise Exception("error parsing file " + filename)

        walker = ParseTreeWalker()
        abstractSyntaxTree = AbstractSyntaxTree();
        self.errorHandler = ErrorHandler(filename)
        listener = Listener(abstractSyntaxTree)
        walker.walk(listener, programContext)

        decorator = VisitorDecorator()
        decorator.visitProgramNode(abstractSyntaxTree.root)

        symbolTable = SymbolTable()
        functionFiller = VisitorSymbolTableFiller(symbolTable, self.errorHandler)
        functionFiller.visitProgramNode(abstractSyntaxTree.root)

        tableFiller = VisitorDeclarationProcessor(symbolTable, self.errorHandler)
        tableFiller.visitProgramNode(abstractSyntaxTree.root)

        typeCheck = VisitorTypeChecker(self.errorHandler)
        typeCheck.visitProgramNode(abstractSyntaxTree.root)

        if self.errorHandler.errorCount() == 0:
            pFilename = os.path.splitext(filename)[0] + ".p"
            codeGenerator = VisitorCodeGenerator(symbolTable, pFilename)
            codeGenerator.visitProgramNode(abstractSyntaxTree.root)

    def generateErrorsAndCompare(self, filename):
        self.parseFile(filename + ".c")
        self.assertTrue(self.errorHandler.errorCount() or self.errorHandler.warningCount())

        # if there is error output generated, compare with txt file
        try:
            with open(filename + ".txt", "r") as myfile:
                correctOutputOriginal = myfile.read()
        except:
            with open(filename + ".txt", "w") as myfile:
                correctOutputOriginal = ""

        errorMessage = self.errorHandler.errorsToString()
        errorMessageWithWhitespace = copy.copy(errorMessage)

        # remove all whitespace
        errorMessage  = re.sub("[ \t\n\r]", "", errorMessage)
        correctOutput = re.sub("[ \t\n\r]", "", correctOutputOriginal)

        # expectedOutputFound = errorMessage.find(correctOutput) != -1
        expectedOutputFound = errorMessage == correctOutput

        if setTxtFiles and not expectedOutputFound:
            f = open(filename + ".txt", "w")
            f.write(errorMessageWithWhitespace)
            f.close()

        if not expectedOutputFound:
            print("\nEXPECTED:\n" + correctOutputOriginal + "\nGOT:\n" + errorMessageWithWhitespace + "\n\n\n\n")

        self.assertTrue(expectedOutputFound)

    def generateNoError(self, filename):
        self.parseFile(filename + ".c")
        self.assertTrue(self.errorHandler.errorCount() == 0)

        # open the newly generated p code file
        try:
            with open(filename + ".p", "r") as myfile:
                pCodeGeneratedOriginal = myfile.read()
        except:
            with open(filename + ".p", "w") as myfile:
                pCodeGeneratedOriginal = ""

        # open the file with the correct p code
        try:
            with open(filename + ".p_correct", "r") as myfile:
                pCodeCorrectOriginal = myfile.read()
        except:
            with open(filename + ".p_correct", "w") as myfile:
                pCodeCorrectOriginal = ""

        # remove all whitespace
        pCodeGenerated  = re.sub("[ \t\n\r]", "", pCodeGeneratedOriginal)
        pCodeCorrect    = re.sub("[ \t\n\r]", "", pCodeCorrectOriginal)

        # expectedOutputFound = errorMessage.find(correctOutput) != -1
        expectedCodeFound = pCodeGenerated == pCodeCorrect

        if setPCode and not expectedCodeFound:
            f = open(filename + ".p_correct", "w")
            f.write(pCodeGeneratedOriginal)
            f.close()

        if not expectedCodeFound:
            print("\nEXPECTED:\n" + pCodeGeneratedOriginal + "\nGOT:\n" + pCodeCorrectOriginal + "\n\n\n\n")

        # os.system("gcc -std=c99 " + filename + ".c -w -o " + filename + ".testbin")

        self.assertTrue(expectedCodeFound)