예제 #1
0
        public void ShouldConflictWithMainClassTest()
        {
            var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0);
            var mainClass = ClassDeclaration.CreateMainClassDeclaration("Foo", mainMethod, 0, 0);
            var otherClass = new ClassDeclaration("Foo", null, new List<Declaration>(), 2, 0);
            var program = new Program(mainClass, new List<ClassDeclaration>(
                new ClassDeclaration[] { otherClass }));

            var errorReporter = new ErrorLogger();
            var builder = new SymbolTableBuilder(program, errorReporter);
            Assert.AreEqual(SymbolTableBuilder.ExitCode.FatalError, builder.BuildSymbolTable());
            var errors = errorReporter.Errors;
            Assert.AreEqual(errors.Count, 1);
            Assert.AreEqual("Conflicting definitions for Foo.", errors[0].Content);
            Assert.AreEqual(errors[0].Row, 2);
        }
        public static SemanticsChecker SetUpTypeAndReferenceChecker(string program, out IErrorReporter errorLog)
        {
            var reader = new StringReader(program);
            var scanner = new MiniJavaScanner(reader);
            var errors = new ErrorLogger();
            var parser = new Parser(scanner, errors, true);
            Program syntaxTree;
            parser.TryParse(out syntaxTree);
            reader.Close();
            Assert.That(errors.Errors, Is.Empty);

            var symbolTableBuilder = new SymbolTableBuilder(syntaxTree, errors);
            Assert.That(errors.Errors, Is.Empty);

            Assert.DoesNotThrow(() => symbolTableBuilder.BuildSymbolTable());
            errorLog = new ErrorLogger();

            return new SemanticsChecker(syntaxTree, errorLog);
        }
예제 #3
0
        public void ShouldConflictWithPredefinedTypesTest()
        {
            var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0);
            var mainClass = ClassDeclaration.CreateMainClassDeclaration("int", mainMethod, 1, 0);
            var secondClass = new ClassDeclaration("boolean", null, new List<Declaration>(), 2, 0);
            var thirdClass = new ClassDeclaration("int", null, new List<Declaration>(), 3, 0);
            var program = new Program(mainClass, new List<ClassDeclaration> (
                new [] { secondClass, thirdClass }));

            var errorReporter = new ErrorLogger();
            var builder = new SymbolTableBuilder(program, errorReporter);
            Assert.AreEqual(SymbolTableBuilder.ExitCode.FatalError, builder.BuildSymbolTable());
            var errors = errorReporter.Errors;
            Assert.AreEqual(3, errors.Count);
            Assert.AreEqual("Conflicting definitions for int.", errors[0].Content);
            Assert.AreEqual(1, errors[0].Row);
            Assert.AreEqual("Conflicting definitions for boolean.", errors[1].Content);
            Assert.AreEqual(2, errors[1].Row);
            Assert.AreEqual("Conflicting definitions for int.", errors[2].Content);
            Assert.AreEqual(3, errors[2].Row);
        }
예제 #4
0
 /* Performs semantic analysis on the program. Returns null if any of the phases
  * fails. If a fatal error is encountered in one phase, analysis will not continue,
  * but internal recovery is attempted within each phase of analysis.
  *
  * The phases are:
  * 1. Building a symbol table. This checks that there are no name clashes in
  *    type declarations or cyclic dependencies. Cyclic dependencies are treated
  *    as fatal errors and will lead to type and reference checks not being run.
  *    If name clashes are found, the compiler will not even proceed to check
  *    cyclic dependencies. This is also treated as a fatal error.
  * 2. Semantic checks. This phase checks first the validity of name references
  *    and then performs type checks on all expressions. References to possibly
  *    uninitialized variables are also detected.
  *
  * All errors are logged in the error log.
  */
 private bool ConstructSymbolTableAndCheckProgram(Program abstractSyntaxTree)
 {
     var symbolTableSuccess = new SymbolTableBuilder(abstractSyntaxTree, _errorLog).BuildSymbolTable();
     bool semanticCheckSuccess = true;
     if (symbolTableSuccess != SymbolTableBuilder.ExitCode.FatalError)
     {
         semanticCheckSuccess = new SemanticsChecker(abstractSyntaxTree, _errorLog).RunCheck();
     }
     return (symbolTableSuccess == SymbolTableBuilder.ExitCode.Success) && semanticCheckSuccess;
 }
예제 #5
0
        public void ValidTypeDefinitionsTest()
        {
            var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0);
            var mainClass = ClassDeclaration.CreateMainClassDeclaration("Foo", mainMethod, 0, 0);
            var secondClass = new ClassDeclaration("Bar", null, new List<Declaration>(), 2, 0);
            var thirdClass = new ClassDeclaration("Baz", null, new List<Declaration>(), 3, 0);
            var program = new Program(mainClass, new List<ClassDeclaration>(
                new [] { secondClass, thirdClass }));

            var errorReporter = new ErrorLogger();
            var builder = new SymbolTableBuilder(program, errorReporter);
            builder.BuildSymbolTable();
            var types = (program.Scope as GlobalScope).UserDefinedTypeNames.ToList();
            Assert.Contains("Foo", types);
            Assert.Contains("Bar", types);
            Assert.Contains("Baz", types);
            Assert.That(types, Is.Not.Contains("int"));
            Assert.That(types, Is.Not.Contains("boolean"));
            Assert.That(types.Count, Is.EqualTo(3));
        }
        private SymbolTableBuilder.ExitCode BuildSymbolTableFor(string program, out GlobalScope symbolTable)
        {
            var reader = new StringReader(program);
            var scanner = new MiniJavaScanner(reader);
            _errors = new ErrorLogger();
            var parser = new Parser(scanner, _errors, true);
            Program syntaxTree;
            parser.TryParse(out syntaxTree);
            reader.Close();
            Assert.That(_errors.Errors, Is.Empty);

            var symbolTableBuilder = new SymbolTableBuilder(syntaxTree, _errors);
            Assert.That(_errors.Errors, Is.Empty);

            var success = symbolTableBuilder.BuildSymbolTable();
            symbolTable = syntaxTree.Scope as GlobalScope;
            return success;
        }