[grammar test] Store production depth on MD_PtrMap.

This commit is contained in:
Miguel Lechon
2021-03-16 11:20:18 +01:00
parent fed011fc52
commit 7645afbcc1
+46 -28
View File
@@ -81,10 +81,9 @@ static MD_Node * NewChild(MD_Node *parent)
#define OPTIONAL_TAG "optional" #define OPTIONAL_TAG "optional"
// TODO(mal): Use data table instead of smuggling depth as file_contents #define GET_DEPTH(depth_map, node) ((MD_u64)MD_PtrMap_Lookup(depth_map, node)->value)
#define GET_DEPTH(node) ((MD_u64)((node)->file_contents)) #define SET_DEPTH(depth_map, node, depth) MD_PtrMap_Insert(depth_map, MD_NodeTableCollisionRule_Overwrite, node, (void *)(depth))
#define SET_DEPTH(node, v) (node)->file_contents = (MD_u8 *)(v); static void PrintRule(MD_PtrMap *depth_map, MD_Node *rule)
static void PrintRule(MD_Node *rule)
{ {
MD_b32 is_literal_char = rule->flags & MD_NodeFlag_CharLiteral; MD_b32 is_literal_char = rule->flags & MD_NodeFlag_CharLiteral;
@@ -115,8 +114,8 @@ static void PrintRule(MD_Node *rule)
for(MD_EachNode(rule_element, rule->first_child)) for(MD_EachNode(rule_element, rule->first_child))
{ {
PrintRule(rule_element); PrintRule(depth_map, rule_element);
printf(" (%lu) ", (unsigned long)GET_DEPTH(rule_element)); printf(" (%lu) ", (unsigned long)GET_DEPTH(depth_map, rule_element));
if(!MD_NodeIsNil(rule_element->next)) if(!MD_NodeIsNil(rule_element->next))
{ {
@@ -154,10 +153,11 @@ static void Extend(MD_String8 *s, char c)
} }
static void ExpandProduction(MD_Node *production, MD_String8List *out, MD_Node *cur_node, static void ExpandProduction(MD_Node *production, MD_String8List *out, MD_Node *cur_node,
OperationFlags op_flags, MD_u32 max_depth, MD_u32 depth); OperationFlags op_flags, MD_PtrMap *depth_map,
MD_u32 max_depth, MD_u32 depth);
static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_node, OperationFlags op_flags, static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_node, OperationFlags op_flags,
MD_u32 max_depth, MD_u32 depth) MD_PtrMap *depth_map, MD_u32 max_depth, MD_u32 depth)
{ {
for(MD_EachNode(rule_element, rule->first_child)) for(MD_EachNode(rule_element, rule->first_child))
{ {
@@ -168,7 +168,7 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_
if(expand) if(expand)
{ {
if(GET_DEPTH(rule_element) + depth >= max_depth) if(GET_DEPTH(depth_map, rule_element) + depth >= max_depth)
{ {
expand = 0; expand = 0;
} }
@@ -216,7 +216,7 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_
MD_b32 has_children = !MD_NodeIsNil(rule_element->first_child); MD_b32 has_children = !MD_NodeIsNil(rule_element->first_child);
if(has_children) if(has_children)
{ {
ExpandRule(rule_element, out_strings, cur_node, op_flags, max_depth, depth+1); ExpandRule(rule_element, out_strings, cur_node, op_flags, depth_map, max_depth, depth+1);
} }
else else
{ {
@@ -253,7 +253,7 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_
{ {
MD_Node * production = MD_NodeTable_Lookup(globals.production_table, rule_element->string)->value; MD_Node * production = MD_NodeTable_Lookup(globals.production_table, rule_element->string)->value;
MD_Assert(production); MD_Assert(production);
ExpandProduction(production, out_strings, cur_node, op_flags, max_depth, depth+1); ExpandProduction(production, out_strings, cur_node, op_flags, depth_map, max_depth, depth+1);
} }
} }
@@ -269,19 +269,20 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_
} }
static void ExpandProduction(MD_Node *production, MD_String8List *out, MD_Node *cur_node, static void ExpandProduction(MD_Node *production, MD_String8List *out, MD_Node *cur_node,
OperationFlags op_flags, MD_u32 max_depth, MD_u32 depth) OperationFlags op_flags, MD_PtrMap *depth_map,
MD_u32 max_depth, MD_u32 depth)
{ {
MD_i64 rule_count = MD_ChildCountFromNode(production); MD_i64 rule_count = MD_ChildCountFromNode(production);
MD_Assert(GET_DEPTH(production)+depth <= max_depth); MD_Assert(GET_DEPTH(depth_map, production)+depth <= max_depth);
MD_Node *rule = 0; MD_Node *rule = 0;
do{ do{
int rule_number = rand_U32(globals.random_series)%rule_count; int rule_number = rand_U32(globals.random_series)%rule_count;
rule = MD_ChildFromIndex(production, rule_number); rule = MD_ChildFromIndex(production, rule_number);
}while(GET_DEPTH(rule)+depth > max_depth); }while(GET_DEPTH(depth_map, rule)+depth > max_depth);
ExpandRule(rule, out, cur_node, op_flags, max_depth, depth); ExpandRule(rule, out, cur_node, op_flags, depth_map, max_depth, depth);
} }
static MD_Node * FindNonTerminalProduction(MD_Node *node, MD_NodeTable *visited) static MD_Node * FindNonTerminalProduction(MD_Node *node, MD_NodeTable *visited)
@@ -405,7 +406,7 @@ struct Test
Test *next; Test *next;
}; };
static void ComputeElementDepth(MD_Node *re) static void ComputeElementDepth(MD_PtrMap *depth_map, MD_Node *re)
{ {
MD_u64 result = 0; MD_u64 result = 0;
MD_b32 has_children = !MD_NodeIsNil(re->first_child); MD_b32 has_children = !MD_NodeIsNil(re->first_child);
@@ -413,8 +414,8 @@ static void ComputeElementDepth(MD_Node *re)
{ {
for(MD_EachNode(sub_re, re->first_child)) for(MD_EachNode(sub_re, re->first_child))
{ {
ComputeElementDepth(sub_re); ComputeElementDepth(depth_map, sub_re);
MD_u64 depth = GET_DEPTH(sub_re); MD_u64 depth = GET_DEPTH(depth_map, sub_re);
if(result < depth) if(result < depth)
{ {
result = depth; result = depth;
@@ -430,11 +431,11 @@ static void ComputeElementDepth(MD_Node *re)
else else
{ {
MD_Node * production = MD_NodeTable_Lookup(globals.production_table, re->string)->value; MD_Node * production = MD_NodeTable_Lookup(globals.production_table, re->string)->value;
result = GET_DEPTH(production)+1; result = GET_DEPTH(depth_map, production)+1;
} }
} }
SET_DEPTH(re, result); SET_DEPTH(depth_map, re, result);
} }
// NOTE(mal): Compares first by size then alphabetically // NOTE(mal): Compares first by size then alphabetically
@@ -619,6 +620,23 @@ int main(int argument_count, char **arguments)
} }
// NOTE(mal): Compute depth of productions, rules, rule elements // NOTE(mal): Compute depth of productions, rules, rule elements
// NOTE(mal): Init all MD_Node depths to 0
MD_PtrMap depth_map_ = {0};
MD_PtrMap *depth_map = &depth_map_;
for(MD_EachNode(production, productions->first_child))
{
SET_DEPTH(depth_map, production, 0);
for(MD_EachNode(rule, production->first_child))
{
SET_DEPTH(depth_map, rule, 0);
for(MD_EachNode(rule_element, rule->first_child))
{
SET_DEPTH(depth_map, rule_element, 0);
}
}
}
MD_b32 progress = 1; MD_b32 progress = 1;
while(progress) while(progress)
{ {
@@ -632,8 +650,8 @@ int main(int argument_count, char **arguments)
MD_u64 max_mandatory_rule_element_depth = 0; MD_u64 max_mandatory_rule_element_depth = 0;
for(MD_EachNode(rule_element, rule->first_child)) for(MD_EachNode(rule_element, rule->first_child))
{ {
ComputeElementDepth(rule_element); ComputeElementDepth(depth_map, rule_element);
MD_u64 depth = GET_DEPTH(rule_element); MD_u64 depth = GET_DEPTH(depth_map, rule_element);
if(!MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG))) if(!MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG)))
{ {
@@ -642,7 +660,7 @@ int main(int argument_count, char **arguments)
if(!(rule_element->flags & MD_NodeFlag_CharLiteral)) if(!(rule_element->flags & MD_NodeFlag_CharLiteral))
{ {
MD_Node * production = MD_NodeTable_Lookup(globals.production_table, rule_element->string)->value; MD_Node * production = MD_NodeTable_Lookup(globals.production_table, rule_element->string)->value;
depth = GET_DEPTH(production); depth = GET_DEPTH(depth_map, production);
} }
depth += 1; depth += 1;
@@ -658,10 +676,10 @@ int main(int argument_count, char **arguments)
} }
} }
if(max_mandatory_rule_element_depth > GET_DEPTH(rule)) if(max_mandatory_rule_element_depth > GET_DEPTH(depth_map, rule))
{ {
progress = 1; progress = 1;
SET_DEPTH(rule, max_mandatory_rule_element_depth); SET_DEPTH(depth_map, rule, max_mandatory_rule_element_depth);
} }
if(max_mandatory_rule_element_depth < min_rule_depth) if(max_mandatory_rule_element_depth < min_rule_depth)
@@ -670,10 +688,10 @@ int main(int argument_count, char **arguments)
} }
} }
if(min_rule_depth > GET_DEPTH(production)) if(min_rule_depth > GET_DEPTH(depth_map, production))
{ {
progress = 1; progress = 1;
SET_DEPTH(production, min_rule_depth); SET_DEPTH(depth_map, production, min_rule_depth);
} }
} }
} }
@@ -710,7 +728,7 @@ int main(int argument_count, char **arguments)
MD_String8List string_list = {0}; MD_String8List string_list = {0};
// NOTE(mal): Generate a random MD file // NOTE(mal): Generate a random MD file
ExpandProduction(file_production_node, &string_list, test.expected_output, 0, max_production_depth, 0); ExpandProduction(file_production_node, &string_list, test.expected_output, 0, depth_map, max_production_depth, 0);
test.input = MD_JoinStringList(string_list); test.input = MD_JoinStringList(string_list);
Test *prev = 0; Test *prev = 0;