#include #include "../lib/Lexer.hpp" #include "../lib/Parser.hpp" #include "lib/SrcLoc.hpp" #include "lib/StatusLog.hpp" class ParserTest { public: explicit ParserTest() {} virtual ~ParserTest() {} void test_node(std::string const& oracle, std::string const& source) { roza::SrcLoc loc {"parser_tests"}; roza::StatusLog log; roza::Lexer lexer {log, loc}; roza::Parser parser {lexer, log}; lexer.scan(source); auto node = parser.parse(); REQUIRE(oracle == node->string()); } void test_node_err(std::string const& oracle) { roza::SrcLoc loc {"parser_tests"}; roza::StatusLog log; roza::Lexer lexer {log, loc}; roza::Parser parser {lexer, log}; lexer.scan(oracle); REQUIRE_THROWS(parser.parse()); } protected: }; TEST_CASE_METHOD(ParserTest, "Parser_integers") { test_node("PROG", ""); test_node("PROG(INT[27])", " 27 "); test_node("PROG(INT[27])", " 27 "); test_node("PROG(INT[27]," "INT[9]," "USUB(INT[99]))", "27 \n 9 \n -99"); test_node_err("32 14 -12"); } TEST_CASE_METHOD(ParserTest, "Parser_int_arith") { test_node("PROG(ADD(ADD(INT[1],INT[2]),INT[3]))", "1 + 2 + 3"); test_node("PROG(SUB(SUB(INT[1],INT[2]),INT[3]))", "1 - 2 - 3"); test_node("PROG(ADD(INT[1],MUL(INT[2],INT[3])))", "1 + 2 * 3"); test_node("PROG(MUL(ADD(INT[1],INT[2]),INT[3]))", "(1 + 2) * 3"); test_node("PROG(SUB(INT[1],DIV(INT[2],INT[3])))", "1 - 2 / 3"); test_node("PROG(DIV(SUB(INT[1],INT[2]),INT[3]))", "(1 - 2) / 3"); test_node("PROG(ADD(INT[1],MOD(INT[2],INT[3])))", "1 + 2 % 3"); test_node("PROG(ADD(USUB(INT[2]),INT[3]))", "-2 + 3"); test_node("PROG(ADD(UADD(INT[2]),INT[3]))", "+ 2 + 3"); test_node("PROG(USUB(ADD(INT[2],INT[3])))", " -(2 + 3)"); test_node("PROG(USUB(POW(INT[2],INT[7])))", " -2^7 "); } TEST_CASE_METHOD(ParserTest, "Parser_bool") { test_node("PROG(BOOL[true])", "true"); test_node("PROG(AND(BOOL[true],BOOL[false]))", "true and false"); test_node("PROG(OR(BOOL[true],BOOL[false]))", "true or false"); test_node("PROG(NOT(BOOL[false]))", "not false"); test_node("PROG(NOT(OR(BOOL[false],BOOL[true])))", "not (false or true)"); test_node("PROG(IMP(BOOL[true],BOOL[false]))", "true => false"); }