#include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParserParse) { std::stringstream s(" identifier 5 \n-51\t 0 1 100 200 -300 -400"); plasp::utils::Parser<> p("input", s); ASSERT_EQ(p.parse(), "identifier"); ASSERT_EQ(p.parse(), 5u); ASSERT_EQ(p.parse(), -51); ASSERT_EQ(p.parse(), false); ASSERT_EQ(p.parse(), true); ASSERT_EQ(p.parse(), 100); ASSERT_EQ(p.parse(), 200u); ASSERT_EQ(p.parse(), -300); ASSERT_THROW(p.parse(), plasp::utils::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParserExpect) { std::stringstream s(" identifier 5 \n-51\t 0 1 100 200 -300 -400"); plasp::utils::Parser<> p("input", s); ASSERT_NO_THROW(p.expect("identifier")); ASSERT_NO_THROW(p.expect(5u)); ASSERT_NO_THROW(p.expect(-51)); ASSERT_NO_THROW(p.expect(false)); ASSERT_NO_THROW(p.expect(true)); ASSERT_NO_THROW(p.expect(100)); ASSERT_NO_THROW(p.expect(200u)); ASSERT_NO_THROW(p.expect(-300)); ASSERT_THROW(p.expect(-400), plasp::utils::ParserException); p.seek(0); ASSERT_THROW(p.expect("error"), plasp::utils::ParserException); p.seek(14); ASSERT_THROW(p.expect(6u), plasp::utils::ParserException); p.seek(17); ASSERT_THROW(p.expect(-50), plasp::utils::ParserException); p.seek(24); ASSERT_THROW(p.expect(true), plasp::utils::ParserException); p.seek(26); ASSERT_THROW(p.expect(false), plasp::utils::ParserException); p.seek(28); ASSERT_THROW(p.expect(101), plasp::utils::ParserException); p.seek(31); ASSERT_THROW(p.expect(201), plasp::utils::ParserException); p.seek(34); ASSERT_THROW(p.expect(-299), plasp::utils::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParserTest) { std::stringstream s(" identifier 5 \n-51\t 0 1"); plasp::utils::Parser<> p("input", s); plasp::utils::Parser<>::Position pos; pos = p.position(); ASSERT_EQ(p.testAndReturn("error"), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndReturn("identifier"), true); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip("error"), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip("identifier"), true); ASSERT_EQ(p.position(), 12); pos = p.position(); ASSERT_EQ(p.testAndReturn(6u), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndReturn(5u), true); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(6u), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(5u), true); ASSERT_EQ(p.position(), 15); pos = p.position(); ASSERT_EQ(p.testAndReturn(-50), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndReturn(-51), true); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(-50), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(-51), true); ASSERT_EQ(p.position(), 22); pos = p.position(); ASSERT_EQ(p.testAndReturn(true), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndReturn(false), true); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(true), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(false), true); ASSERT_EQ(p.position(), 25); pos = p.position(); ASSERT_EQ(p.testAndReturn(false), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndReturn(true), true); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(false), false); ASSERT_EQ(p.position(), pos); ASSERT_EQ(p.testAndSkip(true), true); ASSERT_EQ(p.position(), 27); } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParseEndOfFile) { std::stringstream s1("test"); plasp::utils::Parser<> p1("input", s1); ASSERT_NO_THROW(p1.expect("test")); ASSERT_THROW(p1.parse(), plasp::utils::ParserException); std::stringstream s2("test1 test2 test3"); plasp::utils::Parser<> p2("input", s2); ASSERT_NO_THROW(p2.expect("test1")); ASSERT_NO_THROW(p2.expect("test2")); ASSERT_NO_THROW(p2.expect("test3")); ASSERT_THROW(p2.parse(), plasp::utils::ParserException); std::stringstream s3("-127"); plasp::utils::Parser<> p3("input", s3); p3.expect(-127); ASSERT_THROW(p3.parse(), plasp::utils::ParserException); std::stringstream s4("128 -1023 -4095"); plasp::utils::Parser<> p4("input", s4); ASSERT_NO_THROW(p4.expect(128)); ASSERT_NO_THROW(p4.expect(-1023)); ASSERT_NO_THROW(p4.expect(-4095)); ASSERT_THROW(p4.parse(), plasp::utils::ParserException); std::stringstream s5("0"); plasp::utils::Parser<> p5("input", s5); p5.expect(false); ASSERT_THROW(p5.parse(), plasp::utils::ParserException); std::stringstream s6("0 1 0"); plasp::utils::Parser<> p6("input", s6); ASSERT_NO_THROW(p6.expect(false)); ASSERT_NO_THROW(p6.expect(true)); ASSERT_NO_THROW(p6.expect(false)); ASSERT_THROW(p6.parse(), plasp::utils::ParserException); } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParserPosition) { std::stringstream s("123 \n4\ntest1\n test2\ntest3 \ntest4\n\n\n\n"); plasp::utils::Parser<> p("input", s); const auto startPosition = p.position(); plasp::utils::StreamCoordinate c; c = p.coordinate(); ASSERT_EQ(c.row, 1u); ASSERT_EQ(c.column, 1u); ASSERT_EQ(p.currentCharacter(), '1'); ASSERT_NO_THROW(p.advance()); c = p.coordinate(); ASSERT_EQ(c.row, 1u); ASSERT_EQ(c.column, 2u); ASSERT_EQ(p.currentCharacter(), '2'); ASSERT_NO_THROW(p.advance()); c = p.coordinate(); ASSERT_EQ(c.row, 1u); ASSERT_EQ(c.column, 3u); ASSERT_EQ(p.currentCharacter(), '3'); ASSERT_NO_THROW(p.advance()); c = p.coordinate(); ASSERT_EQ(c.row, 1u); ASSERT_EQ(c.column, 4u); ASSERT_EQ(p.currentCharacter(), ' '); ASSERT_NO_THROW(p.advance()); c = p.coordinate(); ASSERT_EQ(c.row, 1u); ASSERT_EQ(c.column, 5u); ASSERT_EQ(p.currentCharacter(), '\n'); ASSERT_NO_THROW(p.advance()); c = p.coordinate(); ASSERT_EQ(c.row, 2u); ASSERT_EQ(c.column, 1u); ASSERT_EQ(p.currentCharacter(), '4'); ASSERT_NO_THROW(p.advance()); ASSERT_NO_THROW(p.expect("test1")); c = p.coordinate(); ASSERT_EQ(c.row, 3u); ASSERT_EQ(c.column, 6u); ASSERT_NO_THROW(p.expect("test2")); c = p.coordinate(); ASSERT_EQ(c.row, 4u); ASSERT_EQ(c.column, 7u); ASSERT_NO_THROW(p.expect("test3")); c = p.coordinate(); ASSERT_EQ(c.row, 5u); ASSERT_EQ(c.column, 6u); ASSERT_NO_THROW(p.skipLine()); c = p.coordinate(); ASSERT_EQ(c.row, 6u); ASSERT_EQ(c.column, 1u); ASSERT_NO_THROW(p.skipLine()); c = p.coordinate(); ASSERT_EQ(c.row, 7u); ASSERT_EQ(c.column, 1u); ASSERT_NO_THROW(p.skipWhiteSpace()); c = p.coordinate(); ASSERT_EQ(c.row, 10u); ASSERT_EQ(c.column, 1u); ASSERT_TRUE(p.atEnd()); p.reset(); ASSERT_EQ(p.position(), startPosition); ASSERT_FALSE(p.atEnd()); for (size_t i = 0; i < 5; i++) p.advance(); ASSERT_EQ(p.position(), static_cast(5)); p.seek(static_cast(7)); ASSERT_EQ(p.position(), static_cast(7)); ASSERT_NO_THROW(p.expect("test1")); // TODO: test parser with multiple sections } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(UtilsTests, ParserRemoveComments) { std::stringstream s1("; comment at beginning\ntest1; comment in between\ntest2; comment at end"); plasp::utils::Parser<> p1("input", s1); p1.removeComments(";", "\n", false); plasp::utils::StreamCoordinate c; ASSERT_NO_THROW(p1.expect("test1")); c = p1.coordinate(); ASSERT_EQ(c.row, 2u); ASSERT_EQ(c.column, 6u); ASSERT_NO_THROW(p1.expect("test2")); c = p1.coordinate(); ASSERT_EQ(c.row, 3u); ASSERT_EQ(c.column, 6u); p1.skipWhiteSpace(); ASSERT_TRUE(p1.atEnd()); std::stringstream s2("test;"); plasp::utils::Parser<> p2("input", s2); p2.removeComments(";", "\n", false); ASSERT_NO_THROW(p2.expect("test")); p2.skipWhiteSpace(); ASSERT_TRUE(p2.atEnd()); std::stringstream s3("/* comment at start */ test1 /* comment in between */ test2 /*"); plasp::utils::Parser<> p3("input", s3); p3.removeComments("/*", "*/", true); ASSERT_NO_THROW(p3.expect("test1")); ASSERT_NO_THROW(p3.expect("test2")); p3.skipWhiteSpace(); ASSERT_TRUE(p3.atEnd()); }