/** * Copyright (C) 2024 T. Zachary Laine * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #include #include #include namespace bp = boost::parser; bp::symbols const cu_escapes = {{"t", '\t'}, {"r", '\r'}, {"n", '\n'}}; bp::symbols const cp_escapes = { {"t", '\t'}, {"r", '\r'}, {"n", '\n'}}; TEST(quoted_string, basic) { constexpr auto parser = bp::quoted_string; { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { auto result = bp::parse(R"("foo")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo"); } { auto result = bp::parse(R"("foo\\")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\\"); } { auto result = bp::parse(R"("\"foo\"")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "\"foo\""); } } TEST(quoted_string, different_char) { constexpr auto parser = bp::quoted_string('\''); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { auto result = bp::parse(R"('foo')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo"); } { auto result = bp::parse(R"('foo\\')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\\"); } { auto result = bp::parse(R"('\'foo\'')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "'foo'"); } } TEST(quoted_string, different_char_with_escapes) { { auto parser = bp::quoted_string('\'', cu_escapes); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { auto result = bp::parse(R"('foo\t')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\t"); } { auto result = bp::parse(R"('foo\x')", parser, bp::ws); EXPECT_FALSE(result); } } { auto parser = bp::quoted_string('\'', cp_escapes); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { auto result = bp::parse(R"('\tfoo')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "\tfoo"); } { auto result = bp::parse(R"('f\xoo')", parser, bp::ws); EXPECT_FALSE(result); } } } TEST(quoted_string, char_set) { constexpr auto parser = bp::quoted_string("'\""); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { EXPECT_FALSE(bp::parse(R"('foo")", parser, bp::ws)); EXPECT_FALSE(bp::parse(R"("foo')", parser, bp::ws)); } { auto result = bp::parse(R"('foo')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo"); } { auto result = bp::parse(R"("foo")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo"); } { auto result = bp::parse(R"('foo\\')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\\"); } { auto result = bp::parse(R"("foo\\")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\\"); } { auto result = bp::parse(R"('\'foo\'')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "'foo'"); } { auto result = bp::parse(R"("\"foo\"")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "\"foo\""); } { // Can't escape arbitrary characters, only backslash and the quote // character. EXPECT_FALSE(bp::parse(R"("\'foo")", parser, bp::ws)); } } TEST(quoted_string, char_set_with_escapes) { { auto parser = bp::quoted_string("'\"", cu_escapes); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { EXPECT_FALSE(bp::parse(R"('foo")", parser, bp::ws)); EXPECT_FALSE(bp::parse(R"("foo')", parser, bp::ws)); } { auto result = bp::parse(R"('foo\t')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\t"); } { auto result = bp::parse(R"("\tfoo")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "\tfoo"); } { auto result = bp::parse(R"('foo\x')", parser, bp::ws); EXPECT_FALSE(result); } } { auto parser = bp::quoted_string("'\"", cp_escapes); { auto result = bp::parse("", parser, bp::ws); EXPECT_FALSE(result); } { EXPECT_FALSE(bp::parse(R"('foo")", parser, bp::ws)); EXPECT_FALSE(bp::parse(R"("foo')", parser, bp::ws)); } { auto result = bp::parse(R"('foo\t')", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "foo\t"); } { auto result = bp::parse(R"("\tfoo")", parser, bp::ws); EXPECT_TRUE(result); EXPECT_EQ(*result, "\tfoo"); } { auto result = bp::parse(R"('foo\x')", parser, bp::ws); EXPECT_FALSE(result); } } } TEST(quoted_string, doc_examples) { //[ quoted_string_example_1_2 namespace bp = boost::parser; auto result1 = bp::parse("\"some text\"", bp::quoted_string, bp::ws); assert(result1); std::cout << *result1 << "\n"; // Prints: some text auto result2 = bp::parse("\"some \\\"text\\\"\"", bp::quoted_string, bp::ws); assert(result2); std::cout << *result2 << "\n"; // Prints: some "text" //] //[ quoted_string_example_3 auto result3 = bp::parse("!some text!", bp::quoted_string('!'), bp::ws); assert(result3); std::cout << *result3 << "\n"; // Prints: some text //] //[ quoted_string_example_4 auto result4 = bp::parse("'some text'", bp::quoted_string("'\""), bp::ws); assert(result4); std::cout << *result4 << "\n"; // Prints: some text //] //[ quoted_string_example_5 // the c++ simple escapes bp::symbols const escapes = { {"'", '\''}, {"?", '\?'}, {"a", '\a'}, {"b", '\b'}, {"f", '\f'}, {"n", '\n'}, {"r", '\r'}, {"t", '\t'}, {"v", '\v'}}; auto result5 = bp::parse("\"some text\r\"", bp::quoted_string('"', escapes), bp::ws); assert(result5); std::cout << *result5 << "\n"; // Prints (with a CRLF newline): some text //] }