Safetensors
GGUF
Turkish
llama
Llama-3
instruct
finetune
chatml
gpt4
synthetic data
distillation
function calling
json mode
axolotl
roleplaying
chat
Instructions to use tda45/TdAI with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use tda45/TdAI with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="tda45/TdAI", filename="llama.cpp/models/ggml-vocab-aquila.gguf", )
output = llm( "Once upon a time,", max_tokens=512, echo=True ) print(output)
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use tda45/TdAI with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./llama-cli -hf tda45/TdAI
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./build/bin/llama-cli -hf tda45/TdAI
Use Docker
docker model run hf.co/tda45/TdAI
- LM Studio
- Jan
- Ollama
How to use tda45/TdAI with Ollama:
ollama run hf.co/tda45/TdAI
- Unsloth Studio
How to use tda45/TdAI with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for tda45/TdAI to start chatting
- Atomic Chat new
- Docker Model Runner
How to use tda45/TdAI with Docker Model Runner:
docker model run hf.co/tda45/TdAI
- Lemonade
How to use tda45/TdAI with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull tda45/TdAI
Run and chat with the model
lemonade run user.TdAI-{{QUANT_TAG}}List all available models
lemonade list
| static void assert_result_equal(testing & t, common_peg_parse_result_type expected, common_peg_parse_result_type actual) { | |
| t.assert_equal(common_peg_parse_result_type_name(expected), common_peg_parse_result_type_name(actual)); | |
| } | |
| static std::string hex_dump(const std::string& str) { | |
| std::ostringstream oss; | |
| for (unsigned char c : str) { | |
| if (std::isprint(c)) { | |
| oss << c; | |
| } else { | |
| oss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(c); | |
| } | |
| } | |
| return oss.str(); | |
| } | |
| void test_unicode(testing &t) { | |
| struct test_case { | |
| std::string input; | |
| std::string expected_text; | |
| common_peg_parse_result_type expected_result; | |
| }; | |
| t.test("any", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Valid UTF-8 sequences | |
| {"Hello", "Hello", COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| {std::string("Caf\xC3\xA9"), std::string("Caf\xC3\xA9"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| {std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| {std::string("\xF0\x9F\x9A\x80"), std::string("\xF0\x9F\x9A\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Incomplete UTF-8 sequences (partial bytes at end) | |
| {std::string("Caf\xC3"), "Caf", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| {std::string("\xE4\xBD"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| {std::string("\xF0\x9F\x9A"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Invalid/malformed UTF-8 sequences | |
| {std::string("\xFF\xFE"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| {std::string("Hello\x80World"), "Hello", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| {std::string("\xC3\x28"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.one_or_more(p.any()), p.end()}); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| // Assert result type matches | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| // Assert matched text if success or need_more_input | |
| if (result.success() || result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("char classes", [](testing &t) { | |
| t.test("unicode range U+4E00-U+9FFF (CJK)", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Within range - CJK Unified Ideographs | |
| {std::string("\xE4\xB8\x80"), std::string("\xE4\xB8\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+4E00 | |
| {std::string("\xE4\xBD\xA0"), std::string("\xE4\xBD\xA0"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+4F60 | |
| {std::string("\xE5\xA5\xBD"), std::string("\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+597D | |
| {std::string("\xE9\xBF\xBF"), std::string("\xE9\xBF\xBF"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+9FFF | |
| // Outside range - should fail | |
| {"a", "", COMMON_PEG_PARSE_RESULT_FAIL}, // ASCII | |
| {std::string("\xE4\xB7\xBF"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+4DFF (before range) | |
| {std::string("\xEA\x80\x80"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+A000 (after range) | |
| // Incomplete sequences in range | |
| {std::string("\xE4\xB8"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, // Incomplete U+4E00 | |
| {std::string("\xE5\xA5"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, // Incomplete U+597D | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.chars(R"([\u4E00-\u9FFF])"), p.end()}); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| // Assert result type matches | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| // Assert matched text if success or need_more_input | |
| if (result.success() || result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("unicode range U+1F600-U+1F64F (emoticons)", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Within range - Emoticons (all 4-byte UTF-8) | |
| {std::string("\xF0\x9F\x98\x80"), std::string("\xF0\x9F\x98\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+1F600 | |
| {std::string("\xF0\x9F\x98\x81"), std::string("\xF0\x9F\x98\x81"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+1F601 | |
| {std::string("\xF0\x9F\x99\x8F"), std::string("\xF0\x9F\x99\x8F"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+1F64F | |
| // Outside range | |
| {std::string("\xF0\x9F\x97\xBF"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+1F5FF (before range) | |
| {std::string("\xF0\x9F\x99\x90"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+1F650 (after range) | |
| {std::string("\xF0\x9F\x9A\x80"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+1F680 (outside range) | |
| // Incomplete sequences | |
| {std::string("\xF0\x9F\x98"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, // Incomplete emoji | |
| {std::string("\xF0\x9F"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, // Very incomplete | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.chars(R"([\U0001F600-\U0001F64F])"), p.end()}); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| // Assert result type matches | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| // Assert matched text if success or need_more_input | |
| if (result.success() || result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("mixed unicode ranges", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Match CJK | |
| {std::string("\xE4\xB8\x80"), std::string("\xE4\xB8\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+4E00 | |
| {std::string("\xE4\xBD\xA0"), std::string("\xE4\xBD\xA0"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+4F60 | |
| // Match emoticons | |
| {std::string("\xF0\x9F\x98\x80"), std::string("\xF0\x9F\x98\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, // U+1F600 | |
| // Match ASCII digits | |
| {"5", "5", COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Don't match outside any range | |
| {"a", "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| {std::string("\xF0\x9F\x9A\x80"), "", COMMON_PEG_PARSE_RESULT_FAIL}, // U+1F680 | |
| // Incomplete | |
| {std::string("\xE4\xB8"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| {std::string("\xF0\x9F\x98"), "", COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.chars(R"([\u4E00-\u9FFF\U0001F600-\U0001F64F0-9])"), p.end()}); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| // Assert result type matches | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| // Assert matched text if success or need_more_input | |
| if (result.success() || result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| }); | |
| t.test("until parser", [](testing &t) { | |
| t.test("ASCII delimiter with Unicode content", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // CJK characters before delimiter | |
| {std::string("\xE4\xBD\xA0\xE5\xA5\xBD</tag>"), std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Emoji before delimiter | |
| {std::string("\xF0\x9F\x98\x80</tag>"), std::string("\xF0\x9F\x98\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Mixed content | |
| {std::string("Hello \xE4\xB8\x96\xE7\x95\x8C!</tag>"), std::string("Hello \xE4\xB8\x96\xE7\x95\x8C!"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.until("</tag>"); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| if (result.success()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("incomplete UTF-8 at end", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Incomplete emoji at end, no delimiter | |
| {std::string("content\xF0\x9F\x98"), std::string("content"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Incomplete CJK at end, no delimiter | |
| {std::string("hello\xE4\xB8"), std::string("hello"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Complete content, no delimiter (should consume all valid UTF-8) | |
| {std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.until("</tag>"); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| if (result.success() || result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("malformed UTF-8", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Invalid UTF-8 bytes | |
| {std::string("Hello\xFF\xFE"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| // Continuation byte without lead byte | |
| {std::string("Hello\x80World"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| // Invalid continuation byte | |
| {std::string("\xC3\x28"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| }; | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.until("</tag>"); | |
| }); | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| common_peg_parse_context ctx(tc.input); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| }); | |
| } | |
| }); | |
| }); | |
| t.test("json_string parser", [](testing &t) { | |
| t.test("valid UTF-8 characters", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // ASCII only | |
| {"Hello World\"", "Hello World", COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // 2-byte UTF-8 (accented characters) | |
| {std::string("Caf\xC3\xA9\""), std::string("Caf\xC3\xA9"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // 3-byte UTF-8 (CJK) | |
| {std::string("\xE4\xBD\xA0\xE5\xA5\xBD\""), std::string("\xE4\xBD\xA0\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // 4-byte UTF-8 (emoji) | |
| {std::string("\xF0\x9F\x98\x80\""), std::string("\xF0\x9F\x98\x80"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Mixed content | |
| {std::string("Hello \xE4\xB8\x96\xE7\x95\x8C!\""), std::string("Hello \xE4\xB8\x96\xE7\x95\x8C!"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| }; | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.string_content('"'), p.literal("\"")}); | |
| }); | |
| common_peg_parse_context ctx(tc.input); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| if (result.success()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start - 1); // -1 to exclude closing quote | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("incomplete UTF-8", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Incomplete 2-byte sequence | |
| {std::string("Caf\xC3"), std::string("Caf"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Incomplete 3-byte sequence | |
| {std::string("Hello\xE4\xB8"), std::string("Hello"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Incomplete 4-byte sequence | |
| {std::string("Text\xF0\x9F\x98"), std::string("Text"), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| // Incomplete at very start | |
| {std::string("\xE4\xBD"), std::string(""), COMMON_PEG_PARSE_RESULT_NEED_MORE_INPUT}, | |
| }; | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.string_content('"'); | |
| }); | |
| common_peg_parse_context ctx(tc.input, COMMON_PEG_PARSE_FLAG_LENIENT); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| if (result.need_more_input()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start); | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| t.test("malformed UTF-8", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Invalid UTF-8 bytes | |
| {std::string("Hello\xFF\xFE"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| // Continuation byte without lead byte | |
| {std::string("Hello\x80World"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| // Invalid continuation byte | |
| {std::string("\xC3\x28"), "", COMMON_PEG_PARSE_RESULT_FAIL}, | |
| }; | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.string_content('"'); | |
| }); | |
| common_peg_parse_context ctx(tc.input); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| }); | |
| } | |
| }); | |
| t.test("escape sequences with UTF-8", [](testing &t) { | |
| std::vector<test_case> test_cases { | |
| // Unicode escape sequence | |
| {"Hello\\u0041\"", "Hello\\u0041", COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Mix of UTF-8 and escape sequences | |
| {std::string("\xE4\xBD\xA0\\n\xE5\xA5\xBD\""), std::string("\xE4\xBD\xA0\\n\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| // Escaped quote in UTF-8 string | |
| {std::string("\xE4\xBD\xA0\\\"\xE5\xA5\xBD\""), std::string("\xE4\xBD\xA0\\\"\xE5\xA5\xBD"), COMMON_PEG_PARSE_RESULT_SUCCESS}, | |
| }; | |
| for (size_t i = 0; i < test_cases.size(); i++) { | |
| const auto & tc = test_cases[i]; | |
| std::string test_name = "case " + std::to_string(i) + ": " + hex_dump(tc.input); | |
| t.test(test_name, [&](testing &t) { | |
| auto parser = build_peg_parser([](common_peg_parser_builder& p) { | |
| return p.sequence({p.string_content('"'), p.literal("\"")}); | |
| }); | |
| common_peg_parse_context ctx(tc.input); | |
| auto result = parser.parse(ctx); | |
| assert_result_equal(t, tc.expected_result, result.type); | |
| if (result.success()) { | |
| std::string matched = tc.input.substr(result.start, result.end - result.start - 1); // -1 to exclude closing quote | |
| t.assert_equal(tc.expected_text, matched); | |
| } | |
| }); | |
| } | |
| }); | |
| }); | |
| } | |