// 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