// The ParRule and ParNode classes allow the representation of BNF
// rules. A rule is denoted by a rule head and associated body
// sequences consisting of a sequence of nodes.
class ParRule;
class ParNode;
// The following classes are specialisations of ParNode and provide
// details of each body constituent.
class ParNonTermNode;
class ParSelectNode;
class ParActionNode;
class ParEndNode;
// The LConfList class is forward-declared. The processing of the
// internal rule representation produces a cognate list from which
// configuration sets with appropriate transitions are ultimately
// constructed.
class LConfList;
// The ParRuleList class represents a list of ParRule items. The find()
// member functions allow for searches given rule name.
class ParRuleList : public list<ParRule *> {
public:
ParRule *find(char *);
};
class ParRule {
public:
static int RuleId;
static ParRuleList ruleSet;
static ParRule *systemRoot;
static void makeParser();
private:
int _id;
char *_name;
ParNode *_rhs;
bool _hasDefinition; // ensures that forward definitions
bool _isNonTerm; // are you are terminal or nonterminal
public:
char *name() { return(_name); }
int id() { return _id; }
ParNode *rhs() { return(_rhs); }
bool hasDefinition() { return _hasDefinition; }
bool isNonTerm() { return _isNonTerm; }
void defTerm() {
_hasDefinition = TRUE; _isNonTerm = FALSE;
}
void defn(ParNode *b) {
_rhs = b; _hasDefinition = TRUE;
}
list<ParRule *> starters;
int maybeEmpty;
int precedence;
int associativity;
char *attributes;
ParRule(char *n) {
_name = strdup(n);
_id = RuleId++;
_isNonTerm = TRUE;
_hasDefinition = FALSE;
maybeEmpty = FALSE;
_rhs = 0; attributes = 0;
precedence = associativity = 0;
ruleSet.append(this);
}
void show(FILE *);
};
class ParNode {
ParNode *_next;
char *_alias;
public:
ParNode() { _next = 0; _alias = 0; }
void nextIs(ParNode *n) { _next = n; }
void aliasIs(char *n) {
_alias = allocate(strlen(n)+1);
strcpy(_alias, n);
}
char *alias() { return(_alias ? _alias : nontermRule()->name()); }
ParNode *next() { return(_next); }
virtual ParNode *inhNode() { return(next()->inhNode()); }
virtual ParNode *parseItem() { return this; }
virtual void show(ParNode *, FILE *) {
error(INTERNAL, "ParNode: show\n");
}
virtual ParNode* leadsTo(ParNode *);
virtual int parseItems() { return(1+next()->parseItems()); }
virtual int inhItems() { return(next()->inhItems()); }
virtual void order(int &n) { next()->order(n); }
virtual int reduceOrder() { return next()->reduceOrder(); }
virtual ParNode *condNode() { return(next()->condNode()); }
virtual ParNode *actionNode() { return(next()->actionNode()); }
virtual ParRule *nontermRule() {
error(INTERNAL, "ParNode: nontermRule\n");
return(0);
}
virtual int maybeEmpty() { return(next()->maybeEmpty()); }
virtual void starters(list<ParRule *> *sym) { next()->starters(sym); }
virtual int precedence() { return(next()->precedence()); }
virtual int associativity() { return(next()->associativity()); }
int closure(ParRule *, LConfList *);
virtual void findClosure(ParRule *, LConfList *) {
error(INTERNAL, "ParNode: findClosure\n");
}
};
class ParNonTermNode : public ParNode {
ParRule *_nonterm;
public:
ParNonTermNode(ParRule *n) : ParNode() { _nonterm = n; }
ParRule *nonterm() { return(_nonterm); }
virtual ParRule* nontermRule() { return nonterm(); }
virtual int maybeEmpty();
virtual void starters(list<ParRule *> *sym);
virtual int precedence();
virtual int associativity();
virtual void show(ParNode *, FILE *);
virtual void findClosure(ParRule *head, LConfList *);
};
class ParSelectNode : public ParNode {
ParNode *_alt1;
ParNode *_alt2;
public:
virtual ParNode *sigItem() {
error(INTERNAL, "ParSelectNode: sigItem\n");
return(0);
}
virtual ParNode *sigConfig() {
error(INTERNAL, "ParSelectNode: sigConfig\n");
return(0);
}
ParSelectNode(ParNode* a1, ParNode* a2) : ParNode() {
_alt1 = a1; _alt2 = a2;
}
ParNode *alt1() { return(_alt1); }
ParNode *alt2() { return(_alt2); }
virtual void show(ParNode *, FILE *);
virtual ParNode* leadsTo(ParNode *);
virtual void order(int &n) { alt1()->order(n); alt2()->order(n); }
virtual int maybeEmpty() {
return(alt1()->maybeEmpty() || alt2()->maybeEmpty());
}
virtual void starters(list<ParRule *> *sym) {
alt1()->starters(sym); alt2()->starters(sym);
}
virtual void findClosure(ParRule *head, LConfList *);
};
class ParEndNode : public ParNode {
int declOrder;
char *_code, *_cond;
public:
ParEndNode() : ParNode() { _cond = _code = 0; declOrder = 0; }
ParEndNode(char *p) : ParNode()
{ _cond = 0; _code = p; declOrder = 0; }
ParEndNode(char *p, char *p2) : ParNode()
{ _code = p; _cond = p2; declOrder = 0; }
char *code() { return _code; }
char *condCode() { return _cond; }
virtual ParNode *parseItem() { return 0; }
virtual void show(ParNode *, FILE *);
virtual int parseItems() { return 0; }
virtual int inhItems() { return(0); }
virtual void order(int &n) { declOrder = n++; }
virtual int reduceOrder() { return declOrder; }
virtual ParNode *actionNode() { return(_code ? this : 0); }
virtual ParNode *condNode() { return(_cond ? this : 0); }
virtual ParNode *leadsTo(ParNode *);
virtual int maybeEmpty() { return TRUE; }
virtual void starters(list<ParRule *> *sym) { }
virtual int precedence() { return(0); }
virtual int associativity() { return(0); }
virtual void findClosure(ParRule *head, LConfList *);
};
class ParActionNode : public ParNode {
char *_code;
ParRule *genName;
public:
ParActionNode(char *p) : ParNode() { _code = p; genName = 0; }
virtual ParNode *inhNode() { return this; }
char *code() { return _code; }
virtual ParRule* nontermRule();
virtual ParNode *parseItem() { return(next()->parseItem()); }
virtual int inhItems() { return(1+next()->inhItems()); }
virtual void show(ParNode *, FILE *);
virtual void findClosure(ParRule *head, LConfList *l);
};
class InhMarker : public ParRule {
public:
ParNode *context;
InhMarker(char *n, ParNode *c) : ParRule(n) { context = c; }
};
#define SYSROOT "%SYSTEM_ROOT%"
#define SYSEOF "%EOF_MARK%"
#define ASSOC_LEFT 1
#define ASSOC_RIGHT 2
#define ASSOC_NONE 3
syntax highlighted by Code2HTML, v. 0.9.1