9ae083d816
Make the logic around who has priority over the final match simpler by merging the priority generation and match fields in a smarter way. Move the creation of new thread matches up to the top to avoid jumping all over the place.
103 lines
1.4 KiB
C
103 lines
1.4 KiB
C
enum {
|
|
LANY = 0,
|
|
LBOL,
|
|
LCLASS,
|
|
LEND,
|
|
LEOL,
|
|
LLPAR,
|
|
LOR,
|
|
LREP,
|
|
LRPAR,
|
|
LRUNE,
|
|
|
|
TANY = 0,
|
|
TBOL,
|
|
TCAT,
|
|
TCLASS,
|
|
TEOL,
|
|
TNOTNL,
|
|
TOR,
|
|
TPLUS,
|
|
TQUES,
|
|
TRUNE,
|
|
TSTAR,
|
|
TSUB,
|
|
|
|
NSUBEXPM = 32
|
|
};
|
|
|
|
typedef struct Parselex Parselex;
|
|
typedef struct Renode Renode;
|
|
|
|
struct Parselex {
|
|
/* Parse */
|
|
Renode *next;
|
|
Renode *nodes;
|
|
int sub;
|
|
int instrs;
|
|
jmp_buf exitenv;
|
|
/* Lex */
|
|
void (*getnextr)(Parselex*);
|
|
char *rawexp;
|
|
char *orig;
|
|
Rune rune;
|
|
Rune peek;
|
|
int peeklex;
|
|
int done;
|
|
int literal;
|
|
Rune cpairs[400+2];
|
|
int nc;
|
|
};
|
|
|
|
struct Renode {
|
|
int op;
|
|
Renode *left;
|
|
Rune r;
|
|
union
|
|
{
|
|
Rune r1;
|
|
int sub;
|
|
Renode *right;
|
|
};
|
|
int nclass;
|
|
};
|
|
|
|
struct Rethread {
|
|
Reinst *i;
|
|
Resub sem[NSUBEXPM];
|
|
Rethread *next;
|
|
int gen;
|
|
};
|
|
|
|
struct Reinst {
|
|
char op;
|
|
int gen;
|
|
Reinst *a;
|
|
union
|
|
{
|
|
Rune r;
|
|
int sub;
|
|
};
|
|
union
|
|
{
|
|
Rune r1;
|
|
Reinst *b;
|
|
};
|
|
};
|
|
|
|
static int lex(Parselex*);
|
|
static void getnextr(Parselex*);
|
|
static void getnextrlit(Parselex*);
|
|
static void getclass(Parselex*);
|
|
static Renode *e0(Parselex*);
|
|
static Renode *e1(Parselex*);
|
|
static Renode *e2(Parselex*);
|
|
static Renode *e3(Parselex*);
|
|
static Renode *buildclass(Parselex*);
|
|
static Renode *buildclassn(Parselex*);
|
|
static int pcmp(void*, void*);
|
|
static Reprog *regcomp1(char*, int, int);
|
|
static Reinst *compile(Renode*, Reprog*, int);
|
|
static Reinst *compile1(Renode*, Reinst*, int*, int);
|
|
static void prtree(Renode*, int, int);
|