1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
#ifndef _INCLUDED_NONTERMINAL_
#define _INCLUDED_NONTERMINAL_
#include <iomanip>
#include <vector>
#include <string>
#include "../symbol/symbol.h"
#include "../production/production.h"
#include "../firstset/firstset.h"
class NonTerminal: public Symbol
{
public:
using Vector = std::vector<NonTerminal *>;
private:
Production::Vector d_production; // production rules in a vector
// of ptrs to Production objects
FirstSet d_first; // set of terminals that can be
// encountered at this NonTerminal
size_t d_nr; // the NonTerminal's number
static size_t s_counter; // counts the number of symbols in first
// sets. May be reset to 0 by
// resetCounter()
static size_t s_number; // incremented at each call of setNr()
static bool s_unused; // prevents multiple unused warnings
static bool s_undefined; // set to true once at least one
// nonterminal is not used.
static std::ostream &(NonTerminal::*s_insertPtr)(std::ostream &out)
const;
// pointer to the insertion function to be
// used.
public:
NonTerminal(std::string const &name, std::string const &stype = "",
Type type = NON_TERMINAL);
~NonTerminal();
Production::Vector &productions();
Production::Vector const &productions() const; // f
size_t firstSize() const; // f
size_t nProductions() const; // f
std::set<Element const *> const &firstTerminals() const; // f
void addEpsilon(); // f
void addProduction(Production *next); // f
static NonTerminal *downcast(Symbol *sp); // f
static NonTerminal const *downcast(Symbol const *sp); // f
static size_t counter(); // f
static void resetCounter(); // f
static void setFirst(NonTerminal *nonTerminal);
static void setFirstNr(size_t nr); // f
static void setNonTerminal(NonTerminal *nonTerminal); // f
static void setNr(NonTerminal *np); // f
static void undefined(NonTerminal const *nonTerminal);
static void unused(NonTerminal const *nonTerminal);
static bool notUsed(); // f
static bool notDefined(); // f
static void inserter(std::ostream &(NonTerminal::*insertPtr) // f
(std::ostream &out) const);
// plain name
std::ostream &plainName(std::ostream &out) const; // f
std::ostream &nameAndFirstset(std::ostream &out) const; // f
// the N's value
std::ostream &value(std::ostream &out) const; // f
using Symbol::value;
private:
virtual std::ostream &insert(std::ostream &out) const;
virtual size_t v_value() const;
virtual FirstSet const &v_firstSet() const;
std::ostream &insName(std::ostream &out) const;
};
// operator<< is already available through Element
#include "nonterminal.f"
#endif
|