Files
knot/api/noose.hpp
2025-11-28 19:14:43 +00:00

103 lines
1.8 KiB
C++

#ifndef NOOSE_HPP
#define NOOSE_HPP
#include "../api/rope.hpp"
#include <string>
struct Exp;
enum class ExpKind { RANGE, OR, SEQ, ANY, NONE };
struct ExRange {
bool negate = false;
char start;
char end;
};
struct OpOr {
Exp *left;
Exp *right;
};
struct OpSeq {
Exp *left;
Exp *right;
};
struct Exp {
bool capture;
ExpKind kind;
union {
OpOr *opor;
OpSeq *opseq;
std::vector<ExRange> ranges;
};
Exp() {
capture = false;
kind = ExpKind::NONE;
}
};
struct Parser {
std::string s;
size_t i;
Parser(std::string str) : s(str), i(0) {}
};
enum Op {
// These jump around
JMP = 0, // Jump to j.x
FRK = 1, // Fork to j.x and j.y (with priority to x)
// These consume 1 char from the input, if not then fail thread
// (failuire of main thread is not successfull match)
MCH = 2, // match with range object
NMC = 3, // not match with range object
ANY = 4, // Anything
// Used to save offsets
SVS = 5, // Start save for i cap group
SVE = 6, // End save for i cap group
// Match is successful if main thread reaches the end
END = 7
};
struct Range { // use start == end to match a particular char
char start;
char end;
};
struct Inst {
Op op;
union {
struct {
Range *ranges;
int len;
} r;
struct {
int x, y;
} j;
};
int idx;
};
struct Thread {
Inst *pc;
uint32_t saved[40]; /* $0 through $9 */
};
struct ThreadList {
Thread *t;
int n;
};
Exp *regex_to_ast(std::string pattern);
void free_exp(Exp *exp);
Inst *compile_ast(Exp *root);
Inst *compile_regex(std::string pattern);
int proglen(Inst *prog);
void free_program(Inst *instructions);
int next_match(Inst *prog, ByteIterator *it, uint32_t *saved, ThreadList *clist,
ThreadList *nlist);
void print_program(Inst *program);
#endif