xiiregexbuilder
FPGA-Accelerated Regular Expression Matching Enginesrc/parser_tester.cpp (3305B)
1#include <iostream>
2#include <fstream>
3#include <string>
4#include <vector>
5#include <algorithm>
6#include "lexer.h"
7#include "parser.h"
8#include "nfa.h"
9
10std::string trim(const std::string &str)
11{
12 size_t first = str.find_first_not_of(" \t\r\n");
13 if (first == std::string::npos)
14 return "";
15 size_t last = str.find_last_not_of(" \t\r\n");
16 return str.substr(first, (last - first + 1));
17}
18
19int main(int argc, char *argv[])
20{
21 if (argc < 2)
22 {
23 std::cerr << "Usage: " << argv[0] << " <regex_file> [test_strings_file]" << std::endl;
24 return 1;
25 }
26
27 std::string regexFilename = argv[1];
28 std::ifstream regexFile(regexFilename);
29 if (!regexFile.is_open())
30 {
31 std::cerr << "Failed to open " << regexFilename << std::endl;
32 return 1;
33 }
34
35 // Optional: Test strings for validation
36 std::string testFilename = (argc > 2) ? argv[2] : "";
37 std::vector<std::string> testStrings;
38 if (!testFilename.empty())
39 {
40 std::ifstream testFile(testFilename);
41 if (testFile.is_open())
42 {
43 std::string testLine;
44 while (std::getline(testFile, testLine))
45 {
46 std::string trimmed = trim(testLine);
47 if (trimmed.empty() || trimmed[0] == '#')
48 continue;
49 testStrings.push_back(trimmed);
50 }
51 }
52 }
53
54 std::string line;
55 int lineNum = 0;
56 int regexIdx = 0;
57 std::vector<std::unique_ptr<NFA>> nfas;
58 std::vector<std::string> originalRegexes;
59
60 // Core Pipeline: Regex -> Tokens -> AST -> NFA
61 while (std::getline(regexFile, line))
62 {
63 lineNum++;
64 std::string trimmedLine = trim(line);
65 if (trimmedLine.empty() || trimmedLine[0] == '#')
66 continue;
67
68 originalRegexes.push_back(trimmedLine);
69 Lexer lexer(trimmedLine, lineNum);
70 try
71 {
72 std::vector<Token> tokens = lexer.tokenize();
73 Parser parser(tokens);
74 auto ast = parser.parse();
75
76 // Glushkov NFA construction
77 auto nfa = NFABuilder::build(ast.get(), regexIdx++);
78 if (nfa)
79 {
80 nfas.push_back(std::move(nfa));
81 }
82 }
83 catch (const std::exception &e)
84 {
85 std::cerr << "Error processing regex '" << trimmedLine << "': " << e.what() << std::endl;
86 }
87 }
88
89 std::cout << "Successfully built " << nfas.size() << " NFAs." << std::endl;
90
91 // Optional Validation: NFA Simulation
92 if (!testStrings.empty())
93 {
94 std::cout << "\n--- NFA Simulation Results ---" << std::endl;
95 for (const auto &testStr : testStrings)
96 {
97 std::cout << "String: \"" << testStr << "\"" << std::endl;
98 for (size_t i = 0; i < nfas.size(); ++i)
99 {
100 bool matches = nfas[i]->simulate(testStr);
101 std::cout << " Regex [" << i << "] (" << originalRegexes[i] << "): "
102 << (matches ? "MATCH" : "NO MATCH") << std::endl;
103 }
104 std::cout << std::endl;
105 }
106 }
107
108 // Future: Stage 3 - Verilog Emitter
109 // if (!nfas.empty()) {
110 // Emitter emitter(nfas);
111 // emitter.emit("output/");
112 // }
113
114 return 0;
115}