// The following LexRule and LexNode classes allow for rule
// representation in LexGen.
class LexRule;
class LexNode;
// The processing of the internal representation generates an FSA with
// nodes represented as fsaState instances. The fsaState class is
// currently forward defined and will be elaborated subsequently.
class fsaState;
// LexRuleList is a list of LexRule pointers for organising rules into a
// collection.
class LexRuleList : public list<LexRule *> {
public:
LexRule *find(char *);
};
// The LexRule class allows for the representation of rules. Each rule
// has a rule name and a definition which consist of a sequence of
// LexNode instances.
// The _hasDefinition flag indicates whether the rule has an appropriate
// definition and is not just forward defined. The _isIgnored flag
// indicates rules which are considered as whitespaces and comments.
// These must be recognised in the generated lexer, but are not
// significant in terms of tokens returned. On ther other hand, the
// _isToken flag indicates that the rule should result in a final state
// in the generated lexer. The _filter reference contains the code
// block to be invoked when the rule is recognised. This allows for
// extra flexiblity when additional processing is required.
class LexRule {
public:
static LexRuleList ruleSet;
private:
char *_name;
LexNode *_body;
bool _hasDefinition;
bool _isIgnored;
bool _isToken;
char *_filter;
public:
void defn(LexNode *b)
{
if (hasDefinition())
error(ERROR, "`%s' has been redefined\n", name());
_body = b;
_hasDefinition = TRUE;
}
char *name() { return _name; }
LexNode *body() { return _body; }
bool hasDefinition() { return _hasDefinition; }
bool isIgnored() { return _isIgnored; }
bool isToken() { return _isToken; }
void ignored() { _isIgnored = TRUE; }
void token() { _isToken = TRUE; }
char *filter() { return _filter; }
void filterIs(char *f) { _filter = f; }
LexRule(char *);
fsaState *process(fsaState *);
};
// The LexNode abstract class merely contains a reference to another
// node for sequence representation, as well as a stub process()
// specification for generating the equivalent FSA. LexNodeTermNode,
// LexCharNode, LexSelectNode and LexRepeatNode class definitions are
// derived from LexNode.
class LexNode {
public:
LexNode *next;
LexNode() { next = 0; }
virtual fsaState *process(fsaState *);
};
class LexNonTermNode : public LexNode {
LexRule *_nonterm;
public:
LexRule *nonterm() { return _nonterm; }
LexNonTermNode(LexRule *r) { _nonterm = r; }
fsaState *process(fsaState *);
};
class LexCharNode : public LexNode {
char _ch1, _ch2;
public:
char ch1() { return _ch1; }
char ch2() { return _ch2; }
LexCharNode(char c) : LexNode() { _ch1 = _ch2 = c; }
LexCharNode(char c1, char c2) : LexNode() { _ch1 = c1; _ch2 = c2; }
fsaState *process(fsaState *);
};
class LexSelectNode : public LexNode {
LexNode *_alt1;
LexNode *_alt2;
public:
LexNode *alt1() { return _alt1; }
LexNode *alt2() { return _alt2; }
LexSelectNode(LexNode *a1, LexNode *a2) : LexNode() {
_alt1 = a1; _alt2 = a2;
}
fsaState *process(fsaState *);
};
class LexRepeatNode : public LexNode {
LexNode *_repetition;
LexNode *_separator;
bool _atLeastOne;
public:
LexNode *repetition() { return _repetition; }
LexNode *separator() { return _separator; }
bool atLeastOne() { return _atLeastOne; }
LexRepeatNode(LexNode *rep, LexNode *sep, bool v) : LexNode() {
_repetition = rep; _separator = sep; _atLeastOne = v;
}
fsaState *process(fsaState *);
};
syntax highlighted by Code2HTML, v. 0.9.1