Exemplo n.º 1
0
        public void ConvertToASTCorrectly()
        {
            /* Alias.tang file:
             * int8 a
             * a = 2
             * int8 b
             * b = a
             * tokens:
             * int8 identifier newline
             * identifier = numeral newline
             * int8 identifier newline
             * identifier = identifier newline eof
             */

            // When running the method ParseProgram on an enumerator of these tokens, the result is a big parse tree
            // The goal of the ProgramToASTTranslator is to take this parse tree as input and output an AST
            // The AST output is written by hand from the .tang file, and then it is asserted if the output is equivalent to the expected output

            string source = System.IO.File.ReadAllText(AppContext.BaseDirectory + "/Testfiles/tang/Alias.tang");

            // File path relative to where the debug file is located which is in a land far, far away
            Lexer l = new Lexer(File.ReadAllText(AppContext.BaseDirectory + "../../../../../../docs/tang.tokens.json"));

            var           tokens          = l.Analyse(source);
            ProgramParser parser          = new ProgramParser();
            var           tokenEnumerator = tokens.Select(t => new Parsing.Data.Token()
            {
                Name = t.Name, Value = t.Value
            }).GetEnumerator();

            tokenEnumerator.MoveNext();
            var parseTree = parser.ParseProgram(tokenEnumerator);

            // Create a new instance of the ProgramToASTTranslator class
            var astTranslator = new Translation.ProgramToAST.ProgramToASTTranslator();

            // Use the ProgramToASTTranslator with parseTree as parameter to get the AST
            AST.Data.AST ast = astTranslator.TranslatetoAST(parseTree) as AST.Data.AST;

            // Below is a hardcoded tree of how the AST is expected to look
            var astExpected = new AST.Data.AST(true)
            {
                new AST.Data.GlobalStatement(true)
                {
                    new AST.Data.CompoundGlobalStatement(true)
                    {
                        new AST.Data.GlobalStatement(true)
                        {
                            new AST.Data.Statement(true)
                            {
                                new AST.Data.IntegerDeclaration(true)
                                {
                                    new AST.Data.IntType(true)
                                    {
                                        new AST.Data.Token()
                                        {
                                            Name = "int8"
                                        }
                                    },
                                    new AST.Data.Token()
                                    {
                                        Name = "identifier"
                                    }
                                }
                            }
                        },
                        new AST.Data.Token()
                        {
                            Name = "newline"
                        },
                        new AST.Data.GlobalStatement(true)
                        {
                            new AST.Data.CompoundGlobalStatement(true)
                            {
                                new AST.Data.GlobalStatement(true)
                                {
                                    new AST.Data.Statement(true)
                                    {
                                        new AST.Data.IntegerAssignment(true)
                                        {
                                            new AST.Data.Token()
                                            {
                                                Name = "identifier"
                                            },
                                            new AST.Data.Token()
                                            {
                                                Name = "="
                                            },
                                            new AST.Data.IntegerExpression(true)
                                            {
                                                new AST.Data.Token()
                                                {
                                                    Name = "numeral"
                                                }
                                            }
                                        }
                                    }
                                },
                                new AST.Data.Token()
                                {
                                    Name = "newline"
                                },
                                new AST.Data.GlobalStatement(true)
                                {
                                    new AST.Data.CompoundGlobalStatement(true)
                                    {
                                        new AST.Data.GlobalStatement(true)
                                        {
                                            new AST.Data.Statement(true)
                                            {
                                                new AST.Data.IntegerDeclaration(true)
                                                {
                                                    new AST.Data.IntType(true)
                                                    {
                                                        new AST.Data.Token()
                                                        {
                                                            Name = "int8"
                                                        }
                                                    },
                                                    new AST.Data.Token()
                                                    {
                                                        Name = "identifier"
                                                    }
                                                }
                                            }
                                        },
                                        new AST.Data.Token()
                                        {
                                            Name = "newline"
                                        },
                                        new AST.Data.GlobalStatement(true)
                                        {
                                            new AST.Data.Statement(true)
                                            {
                                                new AST.Data.IntegerAssignment(true)
                                                {
                                                    new AST.Data.Token()
                                                    {
                                                        Name = "identifier"
                                                    },
                                                    new AST.Data.Token()
                                                    {
                                                        Name = "="
                                                    },
                                                    new AST.Data.IntegerExpression(true)
                                                    {
                                                        new AST.Data.Token()
                                                        {
                                                            Name = "identifier"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                },
                new AST.Data.Token()
                {
                    Name = "eof"
                }
            };

            // Call a method to walk the tree's nodes and test if their names are equal
            TreeAsserter(ast, astExpected);
        }
Exemplo n.º 2
0
        public void AddExpressionSpecialTestAST()
        {
            // Source file to produce an AST from
            string source = System.IO.File.ReadAllText(AppContext.BaseDirectory + "/Testfiles/tang/AddExpression.tang");

            // File path relative to where the debug file is located which is in a land far, far away
            Lexer l = new Lexer(File.ReadAllText(AppContext.BaseDirectory + "../../../../../../docs/tang.tokens.json"));

            // Call the Analyse method from the Lexical Analysis class
            var tokens = l.Analyse(source);

            // Initialise a program parser
            ProgramParser parser = new ProgramParser();

            // Convert tokens to Parsing.Data.Token
            var tokenEnumerator = tokens.Select(t => new Parsing.Data.Token()
            {
                Name = t.Name, Value = t.Value
            }).GetEnumerator();

            tokenEnumerator.MoveNext();

            // Produce a parse tree by calling the ParseProgram method
            var parseTree = parser.ParseProgram(tokenEnumerator);

            // Create a new instance of the ProgramToASTTranslator class
            var astTranslator = new Translation.ProgramToAST.ProgramToASTTranslator();

            // Use the ProgramToASTTranslator with parseTree as parameter to get the AST
            AST.Data.AST ast = astTranslator.TranslatetoAST(parseTree) as AST.Data.AST;

            // Below is a hardcoded tree of how the AST is expected to look
            var astExpected = new AST.Data.AST(true)
            {
                new AST.Data.GlobalStatement(true)
                {
                    new AST.Data.Statement(true)
                    {
                        new AST.Data.IntegerDeclarationInit(true)
                        {
                            new AST.Data.IntType(true)
                            {
                                new AST.Data.Token()
                                {
                                    Name = "int8"
                                }
                            },
                            new AST.Data.Token()
                            {
                                Name = "identifier"
                            },
                            new AST.Data.Token()
                            {
                                Name = "="
                            },
                            new AST.Data.IntegerExpression(true)
                            {
                                new AST.Data.AddExpression(true)
                                {
                                    new AST.Data.IntegerExpression(true)
                                    {
                                        new AST.Data.AddExpression(true)
                                        {
                                            new AST.Data.IntegerExpression(true)
                                            {
                                                new AST.Data.Token()
                                                {
                                                    Name = "numeral"
                                                }
                                            },
                                            new AST.Data.Token()
                                            {
                                                Name = "+"
                                            },
                                            new AST.Data.IntegerExpression(true)
                                            {
                                                new AST.Data.Token()
                                                {
                                                    Name = "numeral"
                                                }
                                            }
                                        }
                                    },
                                    new AST.Data.Token()
                                    {
                                        Name = "+"
                                    },
                                    new AST.Data.IntegerExpression(true)
                                    {
                                        new AST.Data.Token()
                                        {
                                            Name = "numeral"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                new AST.Data.Token()
                {
                    Name = "eof"
                }
            };


            // Call a method to walk the tree's nodes and test if their names are equal
            TreeAsserter(ast, astExpected);
        }
Exemplo n.º 3
0
        public void AddExpressionSpecialTestCodeGenerator()
        {
            Lexer lexer           = new Lexer(File.ReadAllText(AppContext.BaseDirectory + "/../../../../../docs/tang.tokens.json"));
            var   tokens          = lexer.Analyse("int8 a = 1 + 2 + 3");
            var   tokenEnumerator = tokens.Select(t => new Parsing.Data.Token()
            {
                Name = t.Name, Value = t.Value
            }).GetEnumerator();

            tokenEnumerator.MoveNext();
            Preprocessor preprocessor = new Preprocessor();

            tokens = preprocessor.Process(lexer, null, tokens);
            ProgramParser parser        = new ProgramParser();
            var           parseTree     = parser.ParseProgram(tokenEnumerator);
            var           astTranslator = new Translation.ProgramToAST.ProgramToASTTranslator();

            AST.Data.AST ast         = astTranslator.TranslatetoAST(parseTree) as AST.Data.AST;
            var          cTranslator = new Translation.ASTToC.ASTToCTranslator();

            C.Data.C c = cTranslator.Translate(ast) as C.Data.C;

            // c is the autogenerated tree, we have to manually create one and assert their equality

            var cExpected = new C.Data.C(true)
            {
                new C.Data.Declaration(true)
                {
                    new C.Data.CompoundDeclaration(true)
                    {
                        new C.Data.Declaration(true)
                        {
                            new C.Data.CompoundDeclaration(true)
                            {
                                new C.Data.Declaration(true)
                                {
                                    new C.Data.Token()
                                    {
                                        Name = "EPSILON"
                                    }
                                },
                                new C.Data.Declaration(true)
                                {
                                    new C.Data.IntegerDeclaration(true)
                                    {
                                        new C.Data.IntType(true)
                                        {
                                            new C.Data.Token()
                                            {
                                                Name = "signed"
                                            },
                                            new C.Data.Token()
                                            {
                                                Name = "char"
                                            }
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "identifier"
                                        }
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    }
                                }
                            }
                        },
                        new C.Data.Declaration(true)
                        {
                            new C.Data.CompoundDeclaration(true)
                            {
                                new C.Data.Declaration(true)
                                {
                                    new C.Data.FunctionPrototype(true)
                                    {
                                        new C.Data.Token()
                                        {
                                            Name = "signed"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "long"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "Pow"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "("
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "signed"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "long"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "a"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = ","
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "signed"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "long"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "b"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = ")"
                                        }
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    }
                                },
                                new C.Data.Declaration(true)
                                {
                                    new C.Data.FunctionPrototype(true)
                                    {
                                        new C.Data.Type(true)
                                        {
                                            new C.Data.Token()
                                            {
                                                Name = "void"
                                            }
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "main"
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = "("
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = ")"
                                        }
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    }
                                }
                            }
                        }
                    }
                },
                new C.Data.Function(true)
                {
                    new C.Data.CompoundFunction(true)
                    {
                        new C.Data.Function(true)
                        {
                            new C.Data.CompoundFunction(true)
                            {
                                new C.Data.Function(true)
                                {
                                    new C.Data.Token()
                                    {
                                        Name = "signed"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "long"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "Pow"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "("
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "signed"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "long"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "a"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ","
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "signed"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "long"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "b"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ")"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "{"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "signed"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "long"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "r"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "="
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "1"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ","
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "i"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "for"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "("
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "i"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "="
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "0"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "i"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "<"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "b"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "i"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "++"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ")"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "{"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "r"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "*="
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "a"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "}"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "return"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "r"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = ";"
                                    },
                                    new C.Data.Token()
                                    {
                                        Name = "}"
                                    }
                                },
                                new C.Data.Function(true)
                                {
                                    new C.Data.Token()
                                    {
                                        Name = "EPSILON"
                                    }
                                }
                            }
                        },
                        new C.Data.Function(true)
                        {
                            new C.Data.Type(true)
                            {
                                new C.Data.Token()
                                {
                                    Name = "void"
                                }
                            },
                            new C.Data.Token()
                            {
                                Name = "main"
                            },
                            new C.Data.Token()
                            {
                                Name = "("
                            },
                            new C.Data.Token()
                            {
                                Name = ")"
                            },
                            new C.Data.Token()
                            {
                                Name = "{"
                            },
                            new C.Data.Declaration(true)
                            {
                                new C.Data.Token()
                                {
                                    Name = "EPSILON"
                                }
                            },
                            new C.Data.Statement(true)
                            {
                                new C.Data.CompoundStatement(true)
                                {
                                    new C.Data.Statement(true)
                                    {
                                        new C.Data.Token()
                                        {
                                            Name = "EPSILON"
                                        }
                                    },
                                    new C.Data.Statement(true)
                                    {
                                        new C.Data.IntegerAssignment(true)
                                        {
                                            new C.Data.Token()
                                            {
                                                Name = "identifier"
                                            },
                                            new C.Data.Token()
                                            {
                                                Name = "="
                                            },
                                            new C.Data.IntegerExpression(true)
                                            {
                                                new C.Data.AddExpression(true)
                                                {
                                                    new C.Data.Token()
                                                    {
                                                        Name = "("
                                                    },
                                                    new C.Data.IntegerExpression(true)
                                                    {
                                                        new C.Data.AddExpression(true)
                                                        {
                                                            new C.Data.Token()
                                                            {
                                                                Name = "("
                                                            },
                                                            new C.Data.IntegerExpression(true)
                                                            {
                                                                new C.Data.Token()
                                                                {
                                                                    Name = "numeral"
                                                                }
                                                            },
                                                            new C.Data.Token()
                                                            {
                                                                Name = "+"
                                                            },
                                                            new C.Data.IntegerExpression(true)
                                                            {
                                                                new C.Data.Token()
                                                                {
                                                                    Name = "numeral"
                                                                }
                                                            },
                                                            new C.Data.Token()
                                                            {
                                                                Name = ")"
                                                            }
                                                        }
                                                    },
                                                    new C.Data.Token()
                                                    {
                                                        Name = "+"
                                                    },
                                                    new C.Data.IntegerExpression(true)
                                                    {
                                                        new C.Data.Token()
                                                        {
                                                            Name = "numeral"
                                                        }
                                                    },
                                                    new C.Data.Token()
                                                    {
                                                        Name = ")"
                                                    }
                                                }
                                            }
                                        },
                                        new C.Data.Token()
                                        {
                                            Name = ";"
                                        }
                                    }
                                }
                            },
                            new C.Data.Token()
                            {
                                Name = "}"
                            }
                        }
                    }
                }
            };


            // Use this to print the actual tree
            //var CCC = c.Accept(new C.Visitors.TreePrintVisitor());
            //foreach (var line in CCC)
            //{
            //    Debug.WriteLine(line);
            //}

            // Call a method to walk the tree's nodes and test if their names are equal
            TreeAsserter(c, cExpected);
        }