mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
43abfba723
re2c instead of "Linking X". - Updated lemon and re2c to the latest versions and ported dehsupp to use them for code generation. (Xlatcc is next.) - Added function level linking for Makefile.mingw. SVN r144 (trunk)
424 lines
5.7 KiB
C++
424 lines
5.7 KiB
C++
/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */
|
|
#ifndef _re_h
|
|
#define _re_h
|
|
|
|
#include <iostream>
|
|
#include "token.h"
|
|
#include "ins.h"
|
|
#include "globals.h"
|
|
|
|
namespace re2c
|
|
{
|
|
|
|
typedef struct extop
|
|
{
|
|
char op;
|
|
int minsize;
|
|
int maxsize;
|
|
}
|
|
|
|
ExtOp;
|
|
|
|
struct CharPtn
|
|
{
|
|
uint card;
|
|
CharPtn *fix;
|
|
CharPtn *nxt;
|
|
};
|
|
|
|
typedef CharPtn *CharPtr;
|
|
|
|
struct CharSet
|
|
{
|
|
CharSet();
|
|
~CharSet();
|
|
|
|
CharPtn *fix;
|
|
CharPtn *freeHead, **freeTail;
|
|
CharPtr *rep;
|
|
CharPtn *ptn;
|
|
};
|
|
|
|
class Range
|
|
{
|
|
|
|
public:
|
|
Range *next;
|
|
uint lb, ub; // [lb,ub)
|
|
|
|
public:
|
|
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
|
|
{ }
|
|
|
|
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
|
|
{ }
|
|
|
|
friend std::ostream& operator<<(std::ostream&, const Range&);
|
|
friend std::ostream& operator<<(std::ostream&, const Range*);
|
|
};
|
|
|
|
inline std::ostream& operator<<(std::ostream &o, const Range *r)
|
|
{
|
|
return r ? o << *r : o;
|
|
}
|
|
|
|
class RegExp
|
|
{
|
|
|
|
public:
|
|
uint size;
|
|
|
|
public:
|
|
RegExp() : size(0)
|
|
{
|
|
}
|
|
|
|
virtual ~RegExp() {}
|
|
virtual const char *typeOf() = 0;
|
|
RegExp *isA(const char *t)
|
|
{
|
|
return typeOf() == t ? this : NULL;
|
|
}
|
|
|
|
virtual void split(CharSet&) = 0;
|
|
virtual void calcSize(Char*) = 0;
|
|
virtual uint fixedLength();
|
|
virtual void compile(Char*, Ins*) = 0;
|
|
virtual void display(std::ostream&) const = 0;
|
|
friend std::ostream& operator<<(std::ostream&, const RegExp&);
|
|
friend std::ostream& operator<<(std::ostream&, const RegExp*);
|
|
};
|
|
|
|
inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
|
|
{
|
|
re.display(o);
|
|
return o;
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
|
|
{
|
|
return o << *re;
|
|
}
|
|
|
|
class NullOp: public RegExp
|
|
{
|
|
|
|
public:
|
|
static const char *type;
|
|
|
|
public:
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
uint fixedLength();
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << "_";
|
|
}
|
|
};
|
|
|
|
class MatchOp: public RegExp
|
|
{
|
|
|
|
public:
|
|
static const char *type;
|
|
Range *match;
|
|
|
|
public:
|
|
MatchOp(Range *m) : match(m)
|
|
{
|
|
}
|
|
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
uint fixedLength();
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream&) const;
|
|
|
|
#ifdef PEDANTIC
|
|
private:
|
|
MatchOp(const MatchOp& oth)
|
|
: RegExp(oth)
|
|
, match(oth.match)
|
|
{
|
|
}
|
|
|
|
MatchOp& operator = (const MatchOp& oth)
|
|
{
|
|
new(this) MatchOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
class RuleOp: public RegExp
|
|
{
|
|
public:
|
|
static const char *type;
|
|
|
|
private:
|
|
RegExp *exp;
|
|
|
|
public:
|
|
RegExp *ctx;
|
|
Ins *ins;
|
|
uint accept;
|
|
Token *code;
|
|
uint line;
|
|
|
|
public:
|
|
RuleOp(RegExp*, RegExp*, Token*, uint);
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << exp << "/" << ctx << ";";
|
|
}
|
|
|
|
#ifdef PEDANTIC
|
|
private:
|
|
RuleOp(const RuleOp& oth)
|
|
: RegExp(oth)
|
|
, exp(oth.exp)
|
|
, ctx(oth.ctx)
|
|
, ins(oth.ins)
|
|
, accept(oth.accept)
|
|
, code(oth.code)
|
|
, line(oth.line)
|
|
{
|
|
}
|
|
RuleOp& operator = (const RuleOp& oth)
|
|
{
|
|
new(this) RuleOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
class RuleLine: public line_number
|
|
{
|
|
public:
|
|
|
|
RuleLine(const RuleOp& _op)
|
|
: op(_op)
|
|
{
|
|
}
|
|
|
|
uint get_line() const
|
|
{
|
|
return op.code->line;
|
|
}
|
|
|
|
const RuleOp& op;
|
|
};
|
|
|
|
class AltOp: public RegExp
|
|
{
|
|
|
|
private:
|
|
RegExp *exp1, *exp2;
|
|
|
|
public:
|
|
static const char *type;
|
|
|
|
public:
|
|
AltOp(RegExp *e1, RegExp *e2)
|
|
: exp1(e1)
|
|
, exp2(e2)
|
|
{
|
|
}
|
|
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
uint fixedLength();
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << exp1 << "|" << exp2;
|
|
}
|
|
|
|
friend RegExp *mkAlt(RegExp*, RegExp*);
|
|
|
|
#ifdef PEDANTIC
|
|
private:
|
|
AltOp(const AltOp& oth)
|
|
: RegExp(oth)
|
|
, exp1(oth.exp1)
|
|
, exp2(oth.exp2)
|
|
{
|
|
}
|
|
AltOp& operator = (const AltOp& oth)
|
|
{
|
|
new(this) AltOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
class CatOp: public RegExp
|
|
{
|
|
|
|
private:
|
|
RegExp *exp1, *exp2;
|
|
|
|
public:
|
|
static const char *type;
|
|
|
|
public:
|
|
CatOp(RegExp *e1, RegExp *e2)
|
|
: exp1(e1)
|
|
, exp2(e2)
|
|
{
|
|
}
|
|
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
uint fixedLength();
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << exp1 << exp2;
|
|
}
|
|
|
|
#ifdef PEDANTIC
|
|
private:
|
|
CatOp(const CatOp& oth)
|
|
: RegExp(oth)
|
|
, exp1(oth.exp1)
|
|
, exp2(oth.exp2)
|
|
{
|
|
}
|
|
CatOp& operator = (const CatOp& oth)
|
|
{
|
|
new(this) CatOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
class CloseOp: public RegExp
|
|
{
|
|
|
|
private:
|
|
RegExp *exp;
|
|
|
|
public:
|
|
static const char *type;
|
|
|
|
public:
|
|
CloseOp(RegExp *e)
|
|
: exp(e)
|
|
{
|
|
}
|
|
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << exp << "+";
|
|
}
|
|
|
|
#ifdef PEDANTIC
|
|
private:
|
|
CloseOp(const CloseOp& oth)
|
|
: RegExp(oth)
|
|
, exp(oth.exp)
|
|
{
|
|
}
|
|
CloseOp& operator = (const CloseOp& oth)
|
|
{
|
|
new(this) CloseOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
class CloseVOp: public RegExp
|
|
{
|
|
|
|
private:
|
|
RegExp *exp;
|
|
int min;
|
|
int max;
|
|
|
|
public:
|
|
static const char *type;
|
|
|
|
public:
|
|
CloseVOp(RegExp *e, int lb, int ub)
|
|
: exp(e)
|
|
, min(lb)
|
|
, max(ub)
|
|
{
|
|
}
|
|
|
|
const char *typeOf()
|
|
{
|
|
return type;
|
|
}
|
|
|
|
void split(CharSet&);
|
|
void calcSize(Char*);
|
|
void compile(Char*, Ins*);
|
|
void display(std::ostream &o) const
|
|
{
|
|
o << exp << "+";
|
|
}
|
|
#ifdef PEDANTIC
|
|
private:
|
|
CloseVOp(const CloseVOp& oth)
|
|
: RegExp(oth)
|
|
, exp(oth.exp)
|
|
, min(oth.min)
|
|
, max(oth.max)
|
|
{
|
|
}
|
|
CloseVOp& operator = (const CloseVOp& oth)
|
|
{
|
|
new(this) CloseVOp(oth);
|
|
return *this;
|
|
}
|
|
#endif
|
|
};
|
|
|
|
extern void genCode(std::ostream&, RegExp*);
|
|
extern void genCode(std::ostream&, uint, RegExp*);
|
|
extern void genGetState(std::ostream&, uint&, uint);
|
|
extern RegExp *mkDiff(RegExp*, RegExp*);
|
|
extern RegExp *mkAlt(RegExp*, RegExp*);
|
|
|
|
} // end namespace re2c
|
|
|
|
#endif
|