gzdoom-gles/tools/re2c/dfa.h

367 lines
6.1 KiB
C++

/* $Id: dfa.h 569 2006-06-05 22:14:00Z helly $ */
#ifndef _dfa_h
#define _dfa_h
#include <iosfwd>
#include <map>
#include "re.h"
namespace re2c
{
extern void prtCh(std::ostream&, uint, bool useTalx = true);
extern void prtHex(std::ostream&, uint, bool useTalx = true);
extern void prtChOrHex(std::ostream&, uint, bool useTalx = true);
extern void printSpan(std::ostream&, uint, uint);
class DFA;
class State;
class Action
{
public:
State *state;
public:
Action(State*);
virtual ~Action();
virtual void emit(std::ostream&, uint, bool&) const = 0;
virtual bool isRule() const;
virtual bool isMatch() const;
virtual bool isInitial() const;
virtual bool readAhead() const;
#ifdef PEDANTIC
protected:
Action(const Action& oth)
: state(oth.state)
{
}
Action& operator = (const Action& oth)
{
state = oth.state;
return *this;
}
#endif
};
class Match: public Action
{
public:
Match(State*);
void emit(std::ostream&, uint, bool&) const;
bool isMatch() const;
};
class Enter: public Action
{
public:
uint label;
public:
Enter(State*, uint);
void emit(std::ostream&, uint, bool&) const;
};
class Initial: public Enter
{
public:
bool setMarker;
public:
Initial(State*, uint, bool);
void emit(std::ostream&, uint, bool&) const;
bool isInitial() const;
};
class Save: public Match
{
public:
uint selector;
public:
Save(State*, uint);
void emit(std::ostream&, uint, bool&) const;
bool isMatch() const;
};
class Move: public Action
{
public:
Move(State*);
void emit(std::ostream&, uint, bool&) const;
};
class Accept: public Action
{
public:
typedef std::map<uint, State*> RuleMap;
uint nRules;
uint *saves;
State **rules;
RuleMap mapRules;
public:
Accept(State*, uint, uint*, State**);
void emit(std::ostream&, uint, bool&) const;
void emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const;
void genRuleMap();
#ifdef PEDANTIC
private:
Accept(const Accept& oth)
: Action(oth)
, nRules(oth.nRules)
, saves(oth.saves)
, rules(oth.rules)
{
}
Accept& operator=(const Accept& oth)
{
new(this) Accept(oth);
return *this;
}
#endif
};
class Rule: public Action
{
public:
RuleOp *rule;
public:
Rule(State*, RuleOp*);
void emit(std::ostream&, uint, bool&) const;
bool isRule() const;
#ifdef PEDANTIC
private:
Rule (const Rule& oth)
: Action(oth)
, rule(oth.rule)
{
}
Rule& operator=(const Rule& oth)
{
new(this) Rule(oth);
return *this;
}
#endif
};
class Span
{
public:
uint ub;
State *to;
public:
uint show(std::ostream&, uint) const;
};
class Go
{
public:
Go()
: nSpans(0)
, wSpans(~0u)
, lSpans(~0u)
, dSpans(~0u)
, lTargets(~0u)
, span(NULL)
{
}
public:
uint nSpans; // number of spans
uint wSpans; // number of spans in wide mode
uint lSpans; // number of low (non wide) spans
uint dSpans; // number of decision spans (decide between g and b mode)
uint lTargets;
Span *span;
public:
void genGoto( std::ostream&, uint ind, const State *from, const State *next, bool &readCh);
void genBase( std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const;
void genLinear(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const;
void genBinary(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const;
void genSwitch(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const;
void genCpGoto(std::ostream&, uint ind, const State *from, const State *next, bool &readCh) const;
void compact();
void unmap(Go*, const State*);
};
class State
{
public:
uint label;
RuleOp *rule;
State *next;
State *link;
uint depth; // for finding SCCs
uint kCount;
Ins **kernel;
bool isPreCtxt;
bool isBase;
Go go;
Action *action;
public:
State();
~State();
void emit(std::ostream&, uint, bool&) const;
friend std::ostream& operator<<(std::ostream&, const State&);
friend std::ostream& operator<<(std::ostream&, const State*);
#ifdef PEDANTIC
private:
State(const State& oth)
: label(oth.label)
, rule(oth.rule)
, next(oth.next)
, link(oth.link)
, depth(oth.depth)
, kCount(oth.kCount)
, kernel(oth.kernel)
, isBase(oth.isBase)
, go(oth.go)
, action(oth.action)
{
}
State& operator = (const State& oth)
{
new(this) State(oth);
return *this;
}
#endif
};
class DFA
{
public:
uint lbChar;
uint ubChar;
uint nStates;
State *head, **tail;
State *toDo;
public:
DFA(Ins*, uint, uint, uint, Char*);
~DFA();
void addState(State**, State*);
State *findState(Ins**, uint);
void split(State*);
void findSCCs();
void findBaseState();
void emit(std::ostream&, uint);
friend std::ostream& operator<<(std::ostream&, const DFA&);
friend std::ostream& operator<<(std::ostream&, const DFA*);
#ifdef PEDANTIC
DFA(const DFA& oth)
: lbChar(oth.lbChar)
, ubChar(oth.ubChar)
, nStates(oth.nStates)
, head(oth.head)
, tail(oth.tail)
, toDo(oth.toDo)
{
}
DFA& operator = (const DFA& oth)
{
new(this) DFA(oth);
return *this;
}
#endif
};
inline Action::Action(State *s) : state(s)
{
delete s->action;
s->action = this;
}
inline Action::~Action()
{
}
inline bool Action::isRule() const
{
return false;
}
inline bool Action::isMatch() const
{
return false;
}
inline bool Action::isInitial() const
{
return false;
}
inline bool Action::readAhead() const
{
return !isMatch() || (state && state->next && state->next->action && !state->next->action->isRule());
}
inline Match::Match(State *s) : Action(s)
{ }
inline bool Match::isMatch() const
{
return true;
}
inline Enter::Enter(State *s, uint l) : Action(s), label(l)
{ }
inline Initial::Initial(State *s, uint l, bool b) : Enter(s, l), setMarker(b)
{ }
inline bool Initial::isInitial() const
{
return true;
}
inline Save::Save(State *s, uint i) : Match(s), selector(i)
{ }
inline bool Save::isMatch() const
{
return false;
}
inline bool Rule::isRule() const
{
return true;
}
inline std::ostream& operator<<(std::ostream &o, const State *s)
{
return o << *s;
}
inline std::ostream& operator<<(std::ostream &o, const DFA *dfa)
{
return o << *dfa;
}
} // end namespace re2c
#endif