xiiregexbuilder

FPGA-Accelerated Regular Expression Matching Engine
commit f49928c22a00c08d06453648856f90d4d2abf537
parent 6f7343019c63029335be0494abf485190a017509
Author: Achuthan TM <achuthantm05@gmail.com>
Date:   Sun, 29 Mar 2026 07:13:50 +0530

Week 2: Implement Glushkov NFA Builder (Part 3: Finalizing)

Diffstat:
Msrc/nfa.cpp | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/nfa.h | 11+++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/src/nfa.cpp b/src/nfa.cpp @@ -204,3 +204,64 @@ void NFABuilder::computeNullableFirstLast(ASTNode* node) { n->lastpos = n->inner->lastpos; break; } + case ASTNodeType::PLUS: { + auto n = static_cast<PlusNode*>(node); + computeNullableFirstLast(n->inner.get()); + n->nullable = n->inner->nullable; + n->firstpos = n->inner->firstpos; + n->lastpos = n->inner->lastpos; + break; + } + case ASTNodeType::OPTIONAL: { + auto n = static_cast<OptionalNode*>(node); + computeNullableFirstLast(n->inner.get()); + n->nullable = true; + n->firstpos = n->inner->firstpos; + n->lastpos = n->inner->lastpos; + break; + } + } +} + +void NFABuilder::computeFollowpos(ASTNode* node, std::map<int, std::set<int>>& followpos) { + if (!node) return; + switch (node->type) { + case ASTNodeType::CONCATENATION: { + auto n = static_cast<ConcatenationNode*>(node); + computeFollowpos(n->left.get(), followpos); + computeFollowpos(n->right.get(), followpos); + for (int p : n->left->lastpos) { + followpos[p].insert(n->right->firstpos.begin(), n->right->firstpos.end()); + } + break; + } + case ASTNodeType::STAR: { + auto n = static_cast<StarNode*>(node); + computeFollowpos(n->inner.get(), followpos); + for (int p : n->inner->lastpos) { + followpos[p].insert(n->inner->firstpos.begin(), n->inner->firstpos.end()); + } + break; + } + case ASTNodeType::PLUS: { + auto n = static_cast<PlusNode*>(node); + computeFollowpos(n->inner.get(), followpos); + for (int p : n->inner->lastpos) { + followpos[p].insert(n->inner->firstpos.begin(), n->inner->firstpos.end()); + } + break; + } + case ASTNodeType::UNION: { + auto n = static_cast<UnionNode*>(node); + computeFollowpos(n->left.get(), followpos); + computeFollowpos(n->right.get(), followpos); + break; + } + case ASTNodeType::OPTIONAL: { + auto n = static_cast<OptionalNode*>(node); + computeFollowpos(n->inner.get(), followpos); + break; + } + default: break; + } +} diff --git a/src/nfa.h b/src/nfa.h @@ -31,3 +31,14 @@ public: class NFABuilder { public: // Global state counter to ensure unique IDs across all NFAs + static int globalStateCounter; + + static std::unique_ptr<NFA> build(ASTNode* root, int regexIdx); + +private: + static void linearize(ASTNode* node, int& posCounter, std::map<int, unsigned char>& posToChar, std::set<int>& dotPositions); + static void computeNullableFirstLast(ASTNode* node); + static void computeFollowpos(ASTNode* node, std::map<int, std::set<int>>& followpos); +}; + +#endif // NFA_H