36 Node(
const Rule* r=
nullptr,
double _lp=0.0,
bool cr=
true) :
37 BaseNode(r==nullptr?0:r->
N), rule(r==nullptr ?
NullRule : r), lp(_lp), can_resample(cr) {
46 BaseNode(n), rule(n.rule), lp(n.lp), can_resample(n.can_resample) {
49 BaseNode(n), rule(n.rule), lp(n.lp), can_resample(n.can_resample) {
70 this->can_resample = n.can_resample;
106 print(
"### Error in set_child: ", n.string(),
" does not match required type", rule->
type(i), n.nt(),
string());
131 this->can_resample = n.can_resample;
134 auto operator<=>(
const Node& other)
const {
138 if(*rule != *other.
rule) {
139 return (*rule) <=> (*other.
rule);
147 for(
size_t i=0;i<other.
children.size();i++) {
152 return std::strong_ordering::equal;
162 return this->rule->
nt;
180 size_t n = 1*(not this->
is_null());
182 n += c.count_nonnull();
194 if(this->
is_null())
return false;
198 if(c.is_null())
return false;
199 if(not c.is_complete())
return false;
201 return this->children.size() == rule->
N;
205 virtual std::string
string(
bool usedot=
true)
const override {
214 if(this->rule->
N == 0) {
215 assert(this->
children.size() == 0 &&
"*** Should have zero children -- did you accidentally add children to a null node (that doesn't have a format)?");
216 return this->rule->
format;
220 std::vector<std::string> childStrings(this->
children.size());
222 for(
size_t i=0;i<this->rule->
N;i++) {
223 childStrings[i] = this->
children[i].string();
227 std::string s = this->rule->
format;
228 if(usedot and not this->can_resample) s =
"\u2022"+s;
230 for(
size_t i=0;i<this->rule->
N;i++) {
235 std::string numstr =
"%"+
str(i+1);
236 auto numpos = s.find(numstr);
237 if(numpos != std::string::npos){
238 s.replace(numpos, numstr.length(), childStrings[i]);
244 if(pos == std::string::npos and silpos == std::string::npos) {
246 assert(
false &&
"Node format must contain one ChildStr (typically='%s') for each argument");
249 if(pos < silpos or silpos == std::string::npos) {
251 assert(pos != std::string::npos);
256 assert(silpos != std::string::npos);
275 std::string out =
str(this->
nt()) + NTDelimiter + this->rule->
format;
277 out += RuleDelimiter + c.parseable();
287 template<
typename VirtualMachineState_t,
typename Grammar_t>
308 assert(rule !=
NullRule &&
"*** Cannot linearize if there is a null rule");
309 for(
size_t i=0;i<this->rule->
N;i++) {
310 assert(not this->
children[i].
is_null() &&
"Cannot linearize a Node with null children");
311 assert(this->
children[i].rule->
nt == rule->
type(i) &&
"Somehow the child has incorrect types -- this is bad news for you.");
317 assert(rule->
N == 3 &&
"BuiltinOp::op_IF require three arguments");
319 int ysize =
children[2].linearize<VirtualMachineState_t,Grammar_t>(program);
322 program.
push(Builtins::Jmp<Grammar_t>.makeInstruction(ysize));
324 int xsize =
children[1].linearize<VirtualMachineState_t,Grammar_t>(program)+1;
330 int boolsize =
children[0].linearize<VirtualMachineState_t,Grammar_t>(program);
332 return ysize + xsize + boolsize + 1;
338 assert(rule->
N == 2 and
children.size() == 2 &&
"BuiltinOp::op_AND and BuiltinOp::op_OR require two arguments");
341 int ysize =
children[1].linearize<VirtualMachineState_t,Grammar_t>(program);
351 return children[0].linearize<VirtualMachineState_t,Grammar_t>(program)+ysize+1;
362 for(
int i=this->rule->
N-1;i>=0;i--) {
363 mysize += this->
children[i].linearize<VirtualMachineState_t,Grammar_t>(program);
377 if(not (*rule == *n.
rule))
383 for(
size_t i=0;i<this->
children.size();i++){
398 for(
size_t i=0;i<this->
children.size();i++) {
411 for(
size_t i=0;i<tab;i++) tb +=
"\t";
414 for(
size_t i=0;i<
children.size();i++) {
416 if(
children[i].
parent !=
this)
print(
"*** Warning child above does not have correct parent pointer.");
417 if(
children[i].
pi != i)
print(
"*** Warning child above does not have correct parent index.");
The Primitive type just stores a function pointer and an Op command.
void operator=(const Node &n)
Definition: Node.h:114
double lp
Definition: Node.h:33
virtual ~Node()
Definition: Node.h:52
void push(const Instruction &val)
Push val onto the stack.
Definition: Stack.h:49
size_t pi
Definition: BaseNode.h:27
void set_child(const size_t i, Node &&n)
Definition: Node.h:98
void assign(Node &&n)
Definition: Node.h:66
std::vector< Node > children
Definition: BaseNode.h:23
void operator=(Node &&n)
Definition: Node.h:125
This is a general tree class, which we are adding because there are currently at least 3 different tr...
const std::string & format() const
Definition: Node.h:74
virtual std::string string(bool usedot=true) const override
Definition: Node.h:205
void fix_child_info()
Definition: BaseNode.h:238
#define TAB
Definition: IO.h:19
bool is_a(Op o) const
Definition: Rule.h:74
nonterminal_t type(size_t i) const
Definition: Rule.h:152
virtual std::string parseable() const
Definition: Node.h:268
void set_child(const size_t i, this_t &n)
Definition: BaseNode.h:283
nonterminal_t type(const size_t i) const
Definition: Node.h:78
static const std::string ChildStr
Definition: Rule.h:24
size_t get_hash() const
Definition: Rule.h:139
const Rule * NullRule
Definition: Rule.h:186
std::string str(BindingTree *t)
Definition: BindingTree.h:195
virtual bool is_complete() const
Definition: Node.h:188
static const char RuleDelimiter
Definition: Node.h:29
size_t N
Definition: Rule.h:29
void print(FIRST f, ARGS... args)
Lock output_lock and print to std:cout.
Definition: IO.h:53
bool is_null() const
Definition: Node.h:165
Definition: BaseNode.h:20
static const char NTDelimiter
Definition: Node.h:28
std::string format
Definition: Rule.h:28
void assign(Node &n)
Assign will set everything to n BUT it will not copy the parent pointer etc since we're assuming this...
Definition: Node.h:59
#define CERR
Definition: IO.h:23
nonterminal_t nt() const
Definition: Node.h:156
Node & child(const size_t i)
Definition: BaseNode.h:175
const Rule * rule
Definition: Node.h:32
unsigned short nonterminal_t
Definition: Nonterminal.h:4
A Rule stores one possible expansion in the grammar, specifying a nonterminal type, an instruction that gets executed, a forma string, a number of children, and an array of types of each child. Here we "emulate" a type system using t_nonterminal to store an integer for the types. *.
void set_child(const size_t i, Node &n)
Definition: Node.h:88
Node * parent
Definition: BaseNode.h:26
virtual void fullprint(size_t tab=0)
A function to print out everything, for debugging purposes.
Definition: Node.h:408
int linearize(Program< VirtualMachineState_t > &program) const
Definition: Node.h:288
#define ENDL
Definition: IO.h:21
virtual size_t count_nonnull() const
Definition: Node.h:174
virtual bool operator==(const Node &n) const override
Definition: Node.h:370
static const std::string SilentChildStr
Definition: Rule.h:25
void operator=(const this_t &t)
Definition: BaseNode.h:51
bool can_resample
Definition: Node.h:34
nonterminal_t nt
Definition: Rule.h:27
size_t depth() const
Definition: BaseNode.h:230
Node(const Rule *r=nullptr, double _lp=0.0, bool cr=true)
Definition: Node.h:36
Instruction makeInstruction(int a) const
Definition: Rule.h:92
A program here stores just a stack of instructions which can be executed by the VirtualMachineState_t...
Node(const Node &n)
Definition: Node.h:45
Node(Node &&n)
Definition: Node.h:48
virtual size_t hash(size_t depth=0) const
Definition: Node.h:390